[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Gcl-devel] Re: ceteris paribus
[Gcl-devel] Re: ceteris paribus
22 Sep 2005 16:37:30 -0400
Gnus/5.09 (Gnus v5.9.0) Emacs/21.2
Is the idea of putting NIL in a global register asking for trouble?
5.37.1 Defining Global Register Variables
You can define a global register variable in GNU C like this:
register int *foo asm ("a5");
Here `a5' is the name of the register which should be used. Choose a
register which is normally saved and restored by function calls on your
machine, so that library routines will not clobber it.
Naturally the register name is cpu-dependent, so you would need to
conditionalize your program according to cpu type. The register `a5'
would be a good choice on a 68000 for a variable of pointer type. On
machines with register windows, be sure to choose a "global" register
that is not affected magically by the function call mechanism.
In addition, operating systems on one type of cpu may differ in how
they name the registers; then you would need additional conditionals.
For example, some 68000 operating systems call this register `%a5'.
Eventually there may be a way of asking the compiler to choose a
register automatically, but first we need to figure out how it should
choose and how to enable you to guide the choice. No solution is
Defining a global register variable in a certain register reserves that
register entirely for this use, at least within the current compilation.
The register will not be allocated for any other purpose in the
functions in the current compilation. The register will not be saved
and restored by these functions. Stores into this register are never
deleted even if they would appear to be dead, but references may be
deleted or moved or simplified.
It is not safe to access the global register variables from signal
handlers, or from more than one thread of control, because the system
library routines may temporarily use the register for other things
(unless you recompile them specially for the task at hand).
It is not safe for one function that uses a global register variable to
call another such function `foo' by way of a third function `lose' that
was compiled without knowledge of this variable (i.e. in a different
source file in which the variable wasn't declared). This is because
`lose' might save the register and put some other value there. For
example, you can't expect a global register variable to be available in
the comparison-function that you pass to `qsort', since `qsort' might
have put something else in that register. (If you are prepared to
recompile `qsort' with the same global register variable, you can solve
If you want to recompile `qsort' or other source files which do not
actually use your global register variable, so that they will not use
that register for any other purpose, then it suffices to specify the
compiler option `-ffixed-REG'. You need not actually add a global
register declaration to their source code.
A function which can alter the value of a global register variable
cannot safely be called from a function compiled without this variable,
because it could clobber the value the caller expects to find there on
return. Therefore, the function which is the entry point into the part
of the program that uses the global register variable must explicitly
save and restore the value which belongs to its caller.
On most machines, `longjmp' will restore to each global register
variable the value it had at the time of the `setjmp'. On some
machines, however, `longjmp' will not change the value of global
register variables. To be portable, the function that called `setjmp'
should make other arrangements to save the values of the global register
variables, and to restore them in a `longjmp'. This way, the same
thing will happen regardless of what `longjmp' does.
All global register variable declarations must precede all function
definitions. If such a declaration could appear after function
definitions, the declaration would be too late to prevent the register
from being used for other purposes in the preceding functions.
Global register variables may not have initial values, because an
executable file has no means to supply initial contents for a register.
On the SPARC, there are reports that g3 ... g7 are suitable registers,
but certain library functions, such as `getwd', as well as the
subroutines for division and remainder, modify g3 and g4. g1 and g2
are local temporaries.
On the 68000, a2 ... a5 should be suitable, as should d2 ... d7. Of
course, it will not do to use more than a few of those.
Camm Maguire address@hidden
"The earth is but one country, and mankind its citizens." -- Baha'u'llah