Open main menu
Home
Random
Recent changes
Special pages
Community portal
Preferences
About Wikipedia
Disclaimers
Incubator escapee wiki
Search
User menu
Talk
Dark mode
Contributions
Create account
Log in
Editing
MIPS architecture
(section)
Warning:
You are not logged in. Your IP address will be publicly visible if you make any edits. If you
log in
or
create an account
, your edits will be attributed to your username, along with other benefits.
Anti-spam check. Do
not
fill this in!
== Calling conventions == MIPS has had several calling conventions, especially on the 32-bit platform. The O32 ABI is the most commonly-used ABI, owing to its status as the original [[System V]] [[Application binary interface|ABI]] for MIPS.<ref name=Sweetman>{{cite book|last=Sweetman|first=Dominic|title=See MIPS Run, 2nd edition|year=2007|publisher=Morgan Kaufmann|isbn=978-0-12088-421-6}}</ref><ref name="O32">{{cite web|url=https://www.mips.com/?do-download=mips32-instruction-set-quick-reference-v1-01|title=MIPS32 Instruction Set Quick Reference|access-date=August 17, 2020|archive-date=January 25, 2022|archive-url=https://web.archive.org/web/20220125121442/https://s3-eu-west-1.amazonaws.com/downloads-mips/documents/MD00565-2B-MIPS32-QRC-01.01.pdf|url-status=live}}</ref> It is strictly stack-based, with only four registers {{mono|$a0}}-{{mono|$a3}} available to pass arguments. Space on the stack is reserved in case the callee needs to save its arguments, but the registers are not stored there by the caller. The return value is stored in register {{mono|$v0}}; a second return value may be stored in {{mono|$v1}}. The ABI took shape in 1990 and was last updated in 1994. This perceived slowness, along with an antique floating-point model with only 16 registers, has encouraged the proliferation of many other calling conventions. It is only defined for 32-bit MIPS, but [[GNU compiler collection|GCC]] has created a 64-bit variation called O64.<ref name="linux-mips">{{cite web |title=MIPS ABI History |url=https://www.linux-mips.org/wiki/MIPS_ABI_History |archive-url=https://web.archive.org/web/20180826012735/https://www.linux-mips.org/wiki/MIPS_ABI_History |archive-date=August 26, 2018}}</ref> For 64-bit, the N64 ABI by Silicon Graphics is most commonly used. The most important improvement is that eight registers are now available for argument passing; it also increases the number of floating-point registers to 32. There is also an [[ILP32]] version called N32, which uses 32-bit pointers for smaller code, analogous to the [[x32 ABI]]. Both run under the 64-bit mode of the CPU.<ref name="linux-mips"/> The N32 and N64 ABIs pass the first eight arguments to a function in the registers {{mono|$a0}}-{{mono|$a7}}; subsequent arguments are passed on the stack. The return value (or a pointer to it) is stored in the registers {{mono|$v0}}; a second return value may be stored in {{mono|$v1}}. In both the N32 and N64 ABIs all registers are considered to be 64-bits wide. A few attempts have been made to replace O32 with a 32-bit ABI that resembles N32 more. A 1995 conference came up with MIPS EABI, for which the 32-bit version was quite similar.<ref>{{cite mailing list |url=https://sourceware.org/legacy-ml/binutils/2003-06/msg00436.html |author=Eric Christopher |title=mips eabi documentation |mailing-list=binutils@sources.redhat.com |date=June 11, 2003 |access-date=June 19, 2020 |archive-date=May 7, 2020 |archive-url=https://web.archive.org/web/20200507151411/https://sourceware.org/legacy-ml/binutils/2003-06/msg00436.html |url-status=live }}</ref> EABI inspired MIPS Technologies to propose a more radical "NUBI" ABI additionally reuse argument registers for the return value.<ref>{{cite web |title=NUBI |url=https://www.linux-mips.org/wiki/NUBI |access-date=August 17, 2020 |archive-date=July 29, 2021 |archive-url=https://web.archive.org/web/20210729025259/https://www.linux-mips.org/wiki/NUBI |url-status=dead }}</ref> MIPS EABI is supported by GCC but not LLVM, and neither supports NUBI. For all of O32 and N32/N64, the return address is stored in a {{mono|$ra}} register. This is automatically set with the use of the JAL (jump and link) or JALR (jump and link register) instructions. The function prologue of a (non-leaf) MIPS subroutine pushes the return address (in {{mono|$ra}}) to the stack.<ref>{{cite web|author=Karen Miller|url=http://pages.cs.wisc.edu/~markhill/cs354/Fall2008/beyond354/conventions.html|title=The MIPS Register Usage Conventions|date=2006|archive-url=https://web.archive.org/web/20201025120512/http://pages.cs.wisc.edu/~markhill/cs354/Fall2008/beyond354/conventions.html|archive-date=October 25, 2020|url-status=live}}</ref><ref>{{cite web|author=Hal Perkins|url=https://courses.cs.washington.edu/courses/cse410/09sp/examples/MIPSCallingConventionsSummary.pdf|title=MIPS Calling Convention|date=2006|archive-url=https://web.archive.org/web/20200930165249/https://courses.cs.washington.edu/courses/cse410/09sp/examples/MIPSCallingConventionsSummary.pdf|archive-date=September 30, 2020|url-status=live}}</ref> On both O32 and N32/N64 the stack grows downwards, but the N32/N64 ABIs require 64-bit alignment for all stack entries. The frame pointer ({{mono|$30}}) is optional and in practice rarely used except when the stack allocation in a function is determined at runtime, for example, by calling <code>alloca()</code>. For N32 and N64, the return address is typically stored 8 bytes before the [[stack pointer]] although this may be optional. For the N32 and N64 ABIs, a function must preserve the {{mono|$s0}}-{{mono|$s7}} registers, the global pointer ({{mono|$gp}} or {{mono|$28}}), the stack pointer ({{mono|$sp}} or {{mono|$29}}) and the frame pointer ({{mono|$30}}). The O32 ABI is the same except the calling function is required to save the {{mono|$gp}} register instead of the called function. For multi-threaded code, the thread local storage pointer is typically stored in special hardware register {{mono|$29}} and is accessed by using the mfhw (move from hardware) instruction. At least one vendor is known to store this information in the {{mono|$k0}} register which is normally reserved for kernel use, but this is not standard. The {{mono|$k0}} and {{mono|$k1}} registers ({{mono|$26}}β{{mono|$27}}) are reserved for kernel use and should not be used by applications since these registers can be changed at any time by the kernel due to interrupts, context switches or other events. {| class="wikitable" |+ Registers for O32 calling convention ! Name || Number || Use || Callee must preserve? |- ! {{mono|$zero}} | {{mono|$0}} || constant 0 || {{N/A}} |- ! {{mono|$at}} | {{mono|$1}} || assembler temporary || {{no}} |- ! {{mono|$v0}}β{{mono|$v1}} | {{mono|$2}}β{{mono|$3}} || values for function returns and expression evaluation || {{no}} |- ! {{mono|$a0}}β{{mono|$a3}} | {{mono|$4}}β{{mono|$7}} || function arguments || {{no}} |- ! {{mono|$t0}}β{{mono|$t7}} | {{mono|$8}}β{{mono|$15}} || temporaries || {{no}} |- ! {{mono|$s0}}β{{mono|$s7}} | {{mono|$16}}β{{mono|$23}} || saved temporaries || {{yes}} |- ! {{mono|$t8}}β{{mono|$t9}} | {{mono|$24}}β{{mono|$25}} || temporaries || {{no}} |- ! {{mono|$k0}}β{{mono|$k1}} | {{mono|$26}}β{{mono|$27}} || reserved for OS kernel || {{N/A}} |- ! {{mono|$gp}} | {{mono|$28}} || global pointer || {{yes}} (except PIC code) |- ! {{mono|$sp}} | {{mono|$29}} || [[Stack-based memory allocation|stack pointer]] || {{yes}} |- ! {{mono|$fp}} | {{mono|$30}} || [[frame pointer]] || {{yes}} |- ! {{mono|$ra}} | {{mono|$31}} || [[return statement|return address]] || {{N/A}} |} {| class="wikitable" |+ Registers for N32 and N64 calling conventions<ref>{{cite book|url=https://www.linux-mips.org/pub/linux/mips/doc/ABI/MIPS-N32-ABI-Handbook.pdf|title=MIPSpro N32 ABI Handbook|publisher=[[Silicon Graphics]]|access-date=August 17, 2020|archive-date=December 17, 2021|archive-url=https://web.archive.org/web/20211217075522/https://www.linux-mips.org/pub/linux/mips/doc/ABI/MIPS-N32-ABI-Handbook.pdf|url-status=dead}}</ref> ! Name || Number || Use || Callee must preserve? |- ! {{mono|$zero}} | {{mono|$0}} || constant 0 || {{N/A}} |- ! {{mono|$at}} | {{mono|$1}} || assembler temporary || {{no}} |- ! {{mono|$v0}}β{{mono|$v1}} | {{mono|$2}}β{{mono|$3}} || values for function returns and expression evaluation || {{no}} |- ! {{mono|$a0}}β{{mono|$a7}} | {{mono|$4}}β{{mono|$11}} || function arguments || {{no}} |- ! {{mono|$t4}}β{{mono|$t7}} | {{mono|$12}}β{{mono|$15}} || temporaries || {{no}} |- ! {{mono|$s0}}β{{mono|$s7}} | {{mono|$16}}β{{mono|$23}} || saved temporaries || {{yes}} |- ! {{mono|$t8}}β{{mono|$t9}} | {{mono|$24}}β{{mono|$25}} || temporaries || {{no}} |- ! {{mono|$k0}}β{{mono|$k1}} | {{mono|$26}}β{{mono|$27}} || reserved for OS kernel || {{N/A}} |- ! {{mono|$gp}} | {{mono|$28}} || global pointer || {{yes}} |- ! {{mono|$sp}} | {{mono|$29}} || [[Stack-based memory allocation|stack pointer]] || {{yes}} |- ! {{mono|$s8}} | {{mono|$30}} || [[frame pointer]] || {{yes}} |- ! {{mono|$ra}} | {{mono|$31}} || [[return statement|return address]] || {{N/A}} |} Registers that are preserved across a call are registers that (by convention) will not be changed by a system call or procedure (function) call. For example, $s-registers must be saved to the stack by a procedure that needs to use them, and {{mono|$sp}} and {{mono|$fp}} are always incremented by constants, and decremented back after the procedure is done with them (and the memory they point to). By contrast, {{mono|$ra}} is changed automatically by any normal function call (ones that use jal), and $t-registers must be saved by the program before any procedure call (if the program needs the values inside them after the call). The userspace calling convention of position-independent code on Linux additionally requires that when a function is called the {{mono|$t9}} register must contain the address of that function.<ref>{{Cite web|url=https://www.linux-mips.org/wiki/PIC_code|title=PIC code β LinuxMIPS|website=www.linux-mips.org|language=en|access-date=September 21, 2018|archive-date=September 21, 2018|archive-url=https://web.archive.org/web/20180921153220/https://www.linux-mips.org/wiki/PIC_code|url-status=dead}}</ref> This convention dates back to the System V ABI supplement for MIPS.<ref>{{cite web|url=http://math-atlas.sourceforge.net/devel/assembly/mipsabi32.pdf|title=System V Application Binary Interface MIPS RISC Processor Supplement, 3rd Edition|pages=3β12|access-date=August 17, 2020|archive-date=November 12, 2020|archive-url=https://web.archive.org/web/20201112032803/http://math-atlas.sourceforge.net/devel/assembly/mipsabi32.pdf|url-status=live}}</ref>
Edit summary
(Briefly describe your changes)
By publishing changes, you agree to the
Terms of Use
, and you irrevocably agree to release your contribution under the
CC BY-SA 4.0 License
and the
GFDL
. You agree that a hyperlink or URL is sufficient attribution under the Creative Commons license.
Cancel
Editing help
(opens in new window)