Why does the MIPS Architecture need a new ABI?
An ABI (Application Binary Interface, though that hardly helps) is a set of rules governing compiled programs which - if followed - make the programs able to be linked together (for calling and to share data) and to be comprehensible to various useful bits of software - that includes debuggers, the Linux kernel, and run-time loaders.
Earlier MIPS ABIs were interpreted as machine-specific extensions to the cross-architecture [SVR4]; but the definition of OS services in a unix-like system now falls to POSIX and (specifically) Linux. This specification does not include the machine-indepedent parts of SVR4 ABI by reference or otherwise.
The existing MIPS ABIs were evolved substantially by Silicon Graphics Inc (SGI) for various versions of their Irix OS; they are fairly typical of ABIs for Linux and other sophisticated operating systems. At least to date most MIPS embedded systems have got by using a subset of SGI's complicated ABIs - o32, n32 and n64. So What's wrong with o32, n32 and n64?.
The MIPS ABI took shape as a set of register usage and calling conventions established from the earliest days of MIPS CPUs. It picked up the ABI acronym and a defined binding to object code with the AT&T-inspired UnixSystem V document which is rooted with SVR4.
That process had coalesced as early as 1990 into much of the o32 ABI which is widely used today. By about 1994 the ABI was expanded to encompass position-independent code and the ELF object code syntax, and there have been no substantive and intentional changes since.
SGI pioneered 64-bit operating systems for MIPS in the early 1990s, and the o32 ABI was quite unsuitable for real 64-bit computing. SGI defined a 64-bit ABI called n64 suitable for the largest applications; and then - belatedly realising that n64's 64-bit pointer and long types bloated programs and caused portability problems to many applications which didn't need them - produced the very similar standard n32, which differs primarily in having 32-bit pointers.
From 1995 or so SGI used solely 64-bit-capable MIPS CPUs, so they had no need to revisit a 32-bit ABI. As a result the embedded MIPS world is still stuck on the 20-year-old o32 standard. A series of talks five years ago failed to come up with a replacement.
Meanwhile, the perceived deficiencies of o32 have led to the proliferation of variants and more narrowly-focussed alternatives, to the point where there are now as many as 15 incompatible MIPS ABIs. It may yet prove the least worst decision for us all to continue to use o32 forever: but escaping from o32 could noticeably improve performance and ease various kinds of compatibility. So this is MIPS Technologies' proposal to do so: but this won't make sense unless we can take the community with us and end up with fewer ABIs - not just another family to add to the overlong list.
Specific Goals for NUBI
- Replace multiple existing ABIs : a new family should be good enough for all the applications we can make contact with, and a seed for consolidation on a single standard.
- Make better use of registers : o32's limit of four argument registers causes unnecessary stack shuffling, and programs would run slightly better if we reserved more. Eight argument registers has been tried with success, notably by n64/n32.
We will define more saved registers. Not only is this common for other architectures, but it is evident that the GNU C compiler would quite often generate better code with a few more of these.
- Add a thread pointer : a per-thread pointer in a reserved register makes for efficient thread-local storage.
- Avoid unnecessary trouble with MIPS16e: the MIPS16 compact-code standard uses half-size (16-bit) instructions, and one of the trade-offs made means it only has first-class access to eight general-purpose registers. We want to ensure the ABI's register use does not cause avoidable pain to MIPS16e programs (1).
- Better position-independent code (PIC) : all Linux shared libraries and applications are built PIC, so PIC efficiency matters. The general PIC code sequences for external data access and subroutine linkage are quite slow: we want to permit more optimisations of PIC calling and data referencing sequences.
- Reduce 32-/64-bit incompatibility : 64-bit hardware is already with us. It will be easier for applications to migrate to 64-bit computing if we can offer transition tools which can build applications from a mixture of 32- and 64-bit modules. This will never be seamless, but we believe it's worth making it practicable in controlled circumstances.
Want to know more? See Introducing NUBI.