Next | Prev | Up | Top | Contents | Index

Native 64-Bit (N64) and N32 Subprogram Interface for MIPS Architectures

This section describes the internal subprogram interface for native 64-bit (n64) and n32 programs. This section assumes some familiarity with the current 32-bit interface conventions as specified in the MIPS application binary interface (ABI). The transition to native 64-bit code on the MIPS R8000 requires subprogram interface changes due to the changes in register and address size.

The principal interface for 64-bit native code is similar to the 32-bit ABI standard, with all 32-bit objects replaced by 64-bit objects. Note that square brackets [ ] indicate different n32-bit and o32-bit ABI conventions.

In particular, this implies:

In more detail, the 64-bit native calling sequence has the following characteristics.

There is no restriction on which register must be used to hold the return address in exit blocks. The .mdebug format was unable to cope with return addresses in different places, but the DWARF format can. [The 32-bit ABI specifies $3, but the implementation supports .mask as an alternative.]

PIC (position-independent code, for DSO support) is generated from the compiler directly, rather than converting it later with a separate tool. This allows better compiler control for instruction scheduling and other optimizations, and provides greater robustness.

In the 64-bit interface, gp becomes a callee-saved register. [The 32-bit ABI makes gp a caller-saved register.]

Table 2-1 specifies the use of registers in native 64-bit mode. Note that "Caller-saved" means only that the caller may not assume that the value in the register is preserved across the call.

Native 64-Bit and N32 Interface Register Conventions
Register NameSoftware NameUseSaver
$0 zeroHardware zero 
$1 or $atatAssembler temporaryCaller-saved
$2..$3v0..v1Function resultsCaller-saved
$4..$11a0..a7Subprogram argumentsCaller-saved
$12..$15t4..t7TemporariesCaller-saved
$16..$23s0..s7SavedCallee-saved
$24t8TemporaryCaller-saved
$25t9TemporaryCaller-saved
$26..$27kt0..kt1Reserved for kernel 
$28 or $gpgpGlobal pointerCallee-saved
$29 or $spspStack pointerCallee-saved
$30s8Frame pointer (if needed)Callee-saved
$31raReturn addressCaller-saved
hi, lo Multiply/divide special registersCaller-saved
$f0, $f2 Floating point function resultsCaller-saved
$f1, $f3 Floating point temporariesCaller-saved
$f4..$f11 Floating point temporariesCaller-saved
$f12..$f19 Floating point argumentsCaller-saved
$f20..$f23 (32-bit) Floating point temporariesCaller-saved
$f24..$f31 (64-bit) Floating pointCallee-saved
$f20..$f31 even (n32) Floating point temporariesCallee-saved
$f20..$f31 odd (n32) Floating pointCaller-saved

Table 2-2 shows several examples of parameter passing. It illustrates that at most eight values can be passed through registers. In the table note that:



Next | Prev | Up | Top | Contents | Index