What's wrong with o32, n32 and n64?
Linux/MIPS (up to now, Autumn 2005) has made progress using recognisable dialects of standards defined originally by MIPS Corporation and SGI:
- o32 is for 32-bit CPUs, or 64-bit CPUs running only a 32-bit subset of the instruction set.
- n32/n64 are for 64-bit CPUs only. n64 has 64-bit pointers and long integers, whereas n32 has 32-bit pointers and long integers. (Other than that they're pretty much the same and will be considered together).
o32 is fairly different from n32/n64, so we'll pull out individual problems in separate sections. But it's certainly true that o32 is much more obviously troublesome than n64...
These problems motivated us to propose a new ABI, NUBI.
What's wrong with all of them?
- Inefficient PIC code is resistant to optimisation.
- No general-purpose register available as a thread pointer for efficient thread-local storage.
- Not enough "saved" ("callee-saved") registers, limiting the compiler's ability to keep variables in registers.
- The calling and register conventions make it very hard to build gaskets to allow 32-bit code to intercall 64-bit code and vice versa. MIPS Technologies thinks such gaskets would help embedded systems builders make the transition to using real 64-bit code.
What's wrong with o32?
o32 has been an orphan for a long time. Somewhere in the mid-1990s SGI dropped it completely, because all their systems had been using real 64-bit CPUs for some time.
- Committed to the obsolete MIPS I floating point model, which hides 16 of the FP registers.
- Only four argument registers, which means arguments are too often passed on the stack.
- Many recent improvements to the o32 standard as used by GNU tools and Linux are undocumented: DWARF debug format, for example. So a great deal of undocumented folklore is required to build a compatible implementation. In practice, few implementations are compatible at debug level. Historically, many are incompatible even for interlinking object code.
What's wrong with n32/n64?
- The GNU dialect is probably not quite the same as SGI's, but any differences are undocumented. There are dozens of ill-documented object code section types and other magic numbers.
- n64's history (and its fate as the product of pioneering by SGI, who were so early with 64-bit work) has made it complicated and very different from other ABIs. That means an awful lot of effort has been put into making it work as well as it does now with GNU tools and Linux - but that probably also means it will be expensive to maintain going forward.
- n32/n64 have only ever been Irix/Linux standards. There's no established "bare-iron" version of the object code for embedded use.
- n64 as defined by SGI used their own (early, unique) extensions to DWARF debug information.
- n32/n64 are annoyingly different from each other for reasons which probably made sense at the time, but certainly don't now.
That last bullet point has led to some people asking "do we need n32 (or equivalent) at all?"