SPARC ABI Changes in GCC 3.4
GCC 3.4 fixes several cases in which earlier releases would not follow the SPARC 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 small structure and union types in 64-bit mode.
A. Small structure arguments and return values (1)
| Affected ABI | 64-bit |
|---|---|
| Conditions | A small structure is passed or returned in a register; and it contains a unique field of type float . |
| Old behavior | The register was odd-numbered. |
| New behavior | The register is even-numbered. |
| Example | struct s { float f; }; void g (struct s x); x is passed in floating-point register %f0, instead of %f1. |
B. Small structure arguments and return values (2)
| Affected ABI | 64-bit |
|---|---|
| Conditions | A small structure is passed or returned in registers; its size in bytes is not a multiple of 8 and is greater than 8; its last field is of integral type; and its last but one field is smaller than a word. |
| Old behavior | The last used register was padded at the most significant end. |
| New behavior | The last used register is padded at the least significant end. |
| Example | struct s { float f; int i; int j; }; void g (struct s x); x is passed in several registers, which are laid out as follows: %f0 %o0 (high) %o0 (low) %o1 (high) %o1 (low) Old behavior f padding i padding j New behavior f padding i j padding |
C. Small unions arguments and return values
| Affected ABI | 64-bit |
|---|---|
| Conditions | A small union is passed or returned in a register; and its size in bytes is less than 8. |
| Old behavior | The register was padded at the most significant end. |
| New behavior | The register is padded at the least significant end. |
| Example | union u { int i; float f; }; void g (union u x); x is passed in register %o0, which is laid out as follows: %o0 (high) %o0 (low) Old behavior padding i/f New behavior i/f padding |
D. Small structure arguments (1)
| Affected ABI | 64-bit |
|---|---|
| Conditions | A small structure is passed past the 6th argument slot and prior to the last one; and it contains a complex floating-point field. |
| Old behavior | The complex floating-point field was passed on the stack. |
| New behavior | The complex floating-point field is passed in registers. |
| Example | struct s { _Complex float cf; }; void g (struct s x1, struct s x2, struct s x3, struct s x4, struct s x5, struct s x6, struct s x7); x7 is passed in floating-point registers %f12-%f13, instead of on the stack. |
E. Small structure arguments (2)
| Affected ABI | 64-bit |
|---|---|
| Conditions | A small structure is passed past the 6th argument slot and prior to the last one; it contains a nested structure; and the nested structure contains a floating-point field. |
| Old behavior | The floating-point field was passed on the stack. |
| New behavior | The floating-point field is passed in registers. |
| Example | struct s { struct { double d; } ns; }; void g (struct s x1, struct s x2, struct s x3, struct s x4, struct s x5, struct s x6, struct s x7); x7 is passed in floating-point registers %f12-%f13, instead of on the stack. |
F. Complex floating-point arguments and return values
| Affected ABI | 32-bit |
|---|---|
| Conditions | A complex floating-point value is passed to or returned from a function. |
| Old behavior | The complex floating-point value was passed or returned according to the following table: argument return value _Complex float integer registers integer registers _Complex double integer registers integer registers _Complex long double memory memory |
| New behavior | The complex floating-point value is passed or returned according to the following table: argument return value _Complex float memory floating-point registers _Complex double memory floating-point registers _Complex long double memory floating-point registers |
| Example | _Complex float g (void); The return value is returned in floating-point registers %f0-%f1, instead of registers %o0-%o1. |
G. TI mode integral arguments (GCC extension)
| Affected ABI | 64-bit |
|---|---|
| Conditions | A TI mode integral value is passed to a function. |
| Old behavior | The TI mode integral value was not aligned on a 16-byte boundary in the parameter array. |
| New behavior | The TI mode integral value is aligned on a 16-byte boundary in the parameter array. |
| Example | typedef int TItype __attribute__ ((mode (TI))); void g (int x1, TItype x2); x2 is passed in registers %o2-%o3, instead of %o1-%o2. |
H. Complex integral arguments (GCC extension) (1)
| Affected ABI | 32-bit |
|---|---|
| Conditions | A _Complex long long value is passed to a function. |
| Old behavior | The _Complex long long value was passed in registers. |
| New behavior | The _Complex long long value is passed in memory. |
| Example | void g (_Complex long long x1); x1 (its address) is passed in register %o0, instead of %o0-%o3. |
I. Complex integral arguments (GCC extension) (2)
| Affected ABI | 64-bit |
|---|---|
| Conditions | A complex integral value is passed in registers. |
| Old behavior | Two consecutive registers were reserved, regardless of the size of the complex integral value. |
| New behavior | Only one register is reserved if the complex integral value can fit in a single register. |
| Example | void g (_Complex int x1, _Complex int x2); x2 is passed in register %o1, instead of %o2. |