MIPS ABI Changes in GCC 3.4

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

B. Small aggregate arguments (2)

Affected ABIs n32 and n64
Endianness big
Conditions 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.

E. Structure return values

Affected ABIs n32 and n64
Endianness big
Conditions 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

F. Complex return values

Affected ABIs n32 and n64
Endianness either
Conditions A function returns a complex float ordouble.
Old behavior The value was returned in f0andf0 and f0andf1.
New behavior The value is returned in f0andf0 and f0andf2.
Example _Complex float f ();