GCC 3.4 fixes several cases in which earlier releases would not follow the MIPS calling conventions. This document describes each fix and the kind of code it will affect. In each case, GCC 3.4 will not be binary compatible with earlier releases.
Most of the fixes are related to the handling of structure and union types. In the summary below, "aggregate" refers to both structures and unions.
Note that IRIX 6 configurations used to work aroundB and E by providing wrappers for certain libc functions. These wrappers are not needed for 3.4 and have been removed. It should be possible to link code generated by GCC 3.4 directly with code generated by SGI's compilers.
A. Small aggregate arguments (1)
Affected ABIs
o32
Endianness
little
Conditions
An aggregate argument is passed in a register; and that argument is smaller than 4 bytes.
Old behavior
The register was padded at the least significant end.
New behavior
The register is padded at the most significant end.
Example
struct s { char c[2]; }; void f (struct s x); x is passed in argument register $4, which is laid out as follows: 7-0 15-8 23-16 31-24 Old behavior padding padding c[0] c[1] New behavior c[0] c[1] padding padding
An aggregate argument is passed in a register; and that argument is smaller than 8 bytes.
Old behavior
The register was padded at the most significant end.
New behavior
The register is padded at the least significant end.
Example
struct s { char c[2]; }; void f (struct s x); x is passed in argument register$4, which is laid out as follows: 63-56 55-48 47-40 39-32 31-24 23-16 15-8 7-0 Old behavior padding padding padding padding padding padding c[0] c[1] New behavior c[0] c[1] padding padding padding padding padding padding
C. Large aggregate arguments
Affected ABIs
n32 and n64
Endianness
big
Conditions
An aggregate argument is passed to a function; the aggregate's size is not a multiple of 8 bytes; and there are enough argument registers to hold some of the aggregate, but not enough to hold all of it.
Old behavior
The argument was passed by reference.
New behavior
The argument is passed by value.
Example
struct s { int i[17]; }; void f (struct s x); It would take 9 registers to hold x, but only 8 argument registers are available. Since x's size is not a multiple of 8, previous releases passed it by reference (that is, they passed a pointer to x in $4). The new behavior is to pass x by value. The first 8 words are passed in argument registers and the last is passed on the stack.
D. Single-field structure arguments
Affected ABIs
o32, o64, n32 and n64
Endianness
either
Conditions
A structure containing a single field is passed by value; and that field has a floating-point type.
Old behavior
The structure was treated like a scalar value of the same floating-point type. For example, a structure containing afloat field was treated in the same way as a scalar float value.
New behavior
There is no special treatment for such structures. Note however that the usual n32 and n64 rules still hold: naturally-aligned fields of type double are passed in floating-point registers.
Example
struct s { float f; }; void f (struct s x); GCC used to pass x in f12.Nowitpassesitinf12. Now it passes it in f12.Nowitpassesitin4, just like any other structure.
An aggregate is returned by value; that aggregate is smaller than 16 bytes; its size is not a multiple of 8 bytes; and if it is a structure, either: it has more than two fields; or it has at least one non-floating-point field.
Old behavior
The return register was padded at the most significant end.
New behavior
The return register is padded at the least significant end.
Example
struct s { char c[3]; }; struct s f (); f() returns its value in $2, which is laid out as follows: 63-56 55-48 47-40 39-32 31-24 23-16 15-8 7-0 Old behavior padding padding padding padding padding c[0] c[1] c[2] New behavior c[0] c[1] c[2] padding padding padding padding padding