GNU CC is normally configured to use the same function calling convention normally in use on the target system. This is done with the machine-description macros described (see Target Macros).
However, returning of structure and union values is done differently on some target machines. As a result, functions compiled with PCC returning such types cannot be called from code compiled with GNU CC, and vice versa. This does not cause trouble often because few Unix library routines return structures or unions.
GNU CC code returns structures and unions that are 1, 2, 4 or 8 bytes
long in the same registers used for int
or double
return
values. (GNU CC typically allocates variables of such types in
registers also.) Structures and unions of other sizes are returned by
storing them into an address passed by the caller (usually in a
register). The machine-description macros STRUCT_VALUE
and
STRUCT_INCOMING_VALUE
tell GNU CC where to pass this address.
By contrast, PCC on most target machines returns structures and unions of any size by copying the data into an area of static storage, and then returning the address of that storage as if it were a pointer value. The caller must copy the data from that memory area to the place where the value is wanted. This is slower than the method used by GNU CC, and fails to be reentrant.
On some target machines, such as RISC machines and the 80386, the standard system convention is to pass to the subroutine the address of where to return the value. On these machines, GNU CC has been configured to be compatible with the standard compiler, when this method is used. It may not be compatible for structures of 1, 2, 4 or 8 bytes.
GNU CC uses the system's standard convention for passing arguments. On some machines, the first few arguments are passed in registers; in others, all are passed on the stack. It would be possible to use registers for argument passing on any machine, and this would probably result in a significant speedup. But the result would be complete incompatibility with code that follows the standard convention. So this change is practical only if you are switching to GNU CC as the sole C compiler for the system. We may implement register argument passing on certain machines once we have a complete GNU system so that we can compile the libraries with GNU CC.
On some machines (particularly the Sparc), certain types of arguments are passed ``by invisible reference''. This means that the value is stored in memory, and the address of the memory location is passed to the subroutine.
If you use longjmp
, beware of automatic variables. ANSI C says that
automatic variables that are not declared volatile
have undefined
values after a longjmp
. And this is all GNU CC promises to do,
because it is very difficult to restore register variables correctly, and
one of GNU CC's features is that it can put variables in registers without
your asking it to.
If you want a variable to be unaltered by longjmp
, and you don't
want to write volatile
because old C compilers don't accept it,
just take the address of the variable. If a variable's address is ever
taken, even if just to compute it and ignore it, then the variable cannot
go in a register:
{ int careful; &careful; ... }
Code compiled with GNU CC may call certain library routines. Most of
them handle arithmetic for which there are no instructions. This
includes multiply and divide on some machines, and floating point
operations on any machine for which floating point support is disabled
with `-msoft-float
'. Some standard parts of the C library, such as
bcopy
or memcpy
, are also called automatically. The usual
function call interface is used for calling the library routines.
These library routines should be defined in the library `libgcc.a
',
which GNU CC automatically searches whenever it links a program. On
machines that have multiply and divide instructions, if hardware
floating point is in use, normally `libgcc.a
' is not needed, but it
is searched just in case.
Each arithmetic function is defined in `libgcc1.c
' to use the
corresponding C arithmetic operator. As long as the file is compiled
with another C compiler, which supports all the C arithmetic operators,
this file will work portably. However, `libgcc1.c
' does not work if
compiled with GNU CC, because each arithmetic function would compile
into a call to itself!