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.