Mercurial > pub > dyncall > dyncall
diff doc/manual/callconvs/callconv_mips64.tex @ 328:276eb8c87aa0
- review and fixes, cleanup, amendments to calling convention appendix of manual
author | Tassilo Philipp |
---|---|
date | Fri, 22 Nov 2019 23:11:56 +0100 |
parents | b104c5beec8b |
children | 3c6bc720bc1f |
line wrap: on
line diff
--- a/doc/manual/callconvs/callconv_mips64.tex Fri Nov 22 23:08:59 2019 +0100 +++ b/doc/manual/callconvs/callconv_mips64.tex Fri Nov 22 23:11:56 2019 +0100 @@ -1,121 +1,120 @@ -%////////////////////////////////////////////////////////////////////////////// -% -% Copyright (c) 2007-2016 Daniel Adler <dadler@uni-goettingen.de>, -% Tassilo Philipp <tphilipp@potion-studios.com> -% -% Permission to use, copy, modify, and distribute this software for any -% purpose with or without fee is hereby granted, provided that the above -% copyright notice and this permission notice appear in all copies. -% -% THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -% WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -% MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -% ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -% WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -% ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -% OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -% -%////////////////////////////////////////////////////////////////////////////// - -\subsection{MIPS64 Calling Convention} - -\paragraph{Overview} - -There are two main ABIs in use for MIPS64 chips, \emph{N64}\cite{MIPSn32/n64} and \emph{N32}\cite{MIPSn32/n64}. Both are -basically the same, except that N32 uses 32-bit pointers and long integers, instead of 64. All registers of a MIPS64 chip are considered -to be 64-bit wide, even for the N32 calling convention.\\ -The word size is defined to be 32 bits, a dword 64 bits. Note that this is due to historical reasons (terminology didn't change from MIPS32).\\ -Other than that there are 64-bit versions of the other ABIs found for MIPS32, e.g. the EABI\cite{MIPSeabi} and O64\cite{MIPSo64}. - -\paragraph{\product{dyncall} support} - -For MIPS 64-bit machines, dyncall supports the N64 calling conventions for calls and callbacks (for all four combinations of big/little-endian, and soft/hard-float targets). -The N32 calling convention might work - it used to, but hasn't been tested, recently. - -\subsubsection{MIPS N64 Calling Convention} - -\paragraph{Register usage} - -\begin{table}[h] -\begin{tabular*}{0.95\textwidth}{lll} -Name & Alias & Brief description\\ -\hline -{\bf \$0} & {\bf \$zero} & hardware zero \\ -{\bf \$1} & {\bf \$at} & assembler temporary \\ -{\bf \$2-\$3} & {\bf \$v0-\$v1} & return value (only integer on hard-float targets) \\ -{\bf \$4-\$11} & {\bf \$a0-\$a7} & first arguments (only integer on hard-float targets) \\ -{\bf \$12-\$15,\$24} & {\bf \$t4-\$t7,\$t8} & temporaries, scratch \\ -{\bf \$25} & {\bf \$t9} & temporary, holds the address of the called function for all PIC calls (by convention) \\ -{\bf \$16-\$23} & {\bf \$s0-\$s7} & preserved \\ -{\bf \$26,\$27} & {\bf \$kt0,\$kt1} & reserved for kernel \\ -{\bf \$28} & {\bf \$gp} & global pointer, preserve \\ -{\bf \$29} & {\bf \$sp} & stack pointer, preserve \\ -{\bf \$30} & {\bf \$s8} & frame pointer, preserve \\ -{\bf \$31} & {\bf \$ra} & return address, preserve \\ -{\bf hi, lo} & & multiply/divide special registers \\ -{\bf \$f0,\$f2} & & only on hard-float targets: float results \\ -{\bf \$f1,\$f3,\$f4-\$f11,\$f20-\$f23} & & only on hard-float targets: float temporaries \\ -{\bf \$f12-\$f19} & & only on hard-float targets: float arguments \\ -{\bf \$f24-\$f31} & & only on hard-float targets: preserved \\%@@@on N32, this changes -\end{tabular*} -\caption{Register usage on MIPS N64 calling convention} -\end{table} - -\paragraph{Parameter passing} - -\begin{itemize} -\item Stack grows down -\item Stack parameter order: right-to-left -\item Caller cleans up the stack -\item generally, first 8 params \textgreater=\ 64-bit are passed via registers -\item for hard-float targets: register arguments are passed via \$a0-\$a7 for integers and \$f12-\$f19 for floats - with mixed float and int parameters, some registers are left out (e.g. first parameter ends up in \$a0 or \$f12, second in \$a1 or \$f13, etc.) -\item for soft-float targets: register arguments are passed via \$a0-\$a7 -\item subsequent arguments are pushed onto the stack -\item all stack entries are 64-bit aligned -\item all stack regions are 16-byte aligned -\item results are returned in \$v0, and for a second one \$v1 is used -\item only on hard-float targets: floating point results are returned in \$f0 -\item float arguments passed in the variable part of a vararg call are passed like integers -\item quad precision float arguments are passed in even-odd register pairs, skipping one register if needed -\item integer parameters \textless\ 64 bit are right-justified (meaning occupy higher-address bytes) in their 8-byte slot on the stack, requiring extra-care for big-endian targets -\item single precision float parameters (32 bit) are left-justified in their 8-byte slot on the stack, but are right justified in fp-registers on big endian targets, as they aren't promoted @@@doc says "undecided", but openbsd/octeon(mipseb) has it as described here -\end{itemize} - -\paragraph{Stack layout} - -Stack directly after function prolog:\\ -@@@ might be wrong - -\begin{figure}[h] -\begin{tabular}{5|3|1 1} -\hhline{~-~~} - & \vdots & & \\ -\hhline{~=~~} -register save area & \hspace{4cm} & & \mrrbrace{5}{caller's frame} \\ -\hhline{~-~~} -local data & & & \\ -\hhline{~-~~} -\mrlbrace{3}{parameter area} & \ldots & \mrrbrace{3}{stack parameters} & \\ - & \ldots & & \\ - & \ldots & & \\ -\hhline{~=~~} -register save area & padding & & \mrrbrace{7}{current frame} \\ - & \$ra & & \\ - & \$s8 & & \\ - & \$gp & & \\ -\hhline{~-~~} -local data & & & \\ -\hhline{~-~~} -parameter area & & & \\ -\hhline{~-~~} - & \vdots & & \\ -\hhline{~-~~} -\end{tabular} -\caption{Stack layout on mips64 n64 calling convention} -\end{figure} - - -\subsubsection{MIPS N32 Calling Convention} - -@@@ - +%////////////////////////////////////////////////////////////////////////////// +% +% Copyright (c) 2007-2019 Daniel Adler <dadler@uni-goettingen.de>, +% Tassilo Philipp <tphilipp@potion-studios.com> +% +% Permission to use, copy, modify, and distribute this software for any +% purpose with or without fee is hereby granted, provided that the above +% copyright notice and this permission notice appear in all copies. +% +% THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +% WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +% MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +% ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +% WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +% ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +% OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +% +%////////////////////////////////////////////////////////////////////////////// + +\subsection{MIPS64 Calling Conventions} + +\paragraph{Overview} + +There are two main ABIs in use for MIPS64 chips, \emph{N64}\cite{MIPSn32/n64} and \emph{N32}\cite{MIPSn32/n64}. Both are +basically the same, except that N32 uses 32-bit pointers and long integers, instead of 64. All registers of a MIPS64 chip are considered +to be 64-bit wide, even for the N32 calling convention.\\ +The word size is defined to be 32 bits, a dword 64 bits. Note that this is due to historical reasons (terminology didn't change from MIPS32).\\ +Other than that there are correspoding 64-bit versions other MIPS32 ABIs, e.g. the EABI\cite{MIPSeabi} and O64\cite{MIPSo64}. + +\paragraph{\product{dyncall} support} + +For MIPS 64-bit machines, dyncall supports the N64 calling conventions for calls and callbacks (for all four combinations of big/little-endian, and soft/hard-float targets). +The N32 calling convention might work - it used to, but hasn't been tested, recently. + +\subsubsection{MIPS N64 Calling Convention} + +\paragraph{Register usage} + +\begin{table}[h] +\begin{tabular*}{0.95\textwidth}{lll} +Name & Alias & Brief description\\ +\hline +{\bf \$0} & {\bf \$zero} & hardware zero \\ +{\bf \$1} & {\bf \$at} & assembler temporary, scratch \\ +{\bf \$2-\$3} & {\bf \$v0-\$v1} & return value (only integer on hard-float targets), scratch \\ +{\bf \$4-\$11} & {\bf \$a0-\$a7} & first arguments (only integer on hard-float targets), scratch \\ +{\bf \$12-\$15,\$24} & {\bf \$t4-\$t7,\$t8} & temporaries, scratch \\ +{\bf \$25} & {\bf \$t9} & temporary, address callee for all PIC calls (by convention), scratch \\ +{\bf \$16-\$23} & {\bf \$s0-\$s7} & preserve \\ +{\bf \$26,\$27} & {\bf \$kt0,\$kt1} & reserved for kernel \\ +{\bf \$28} & {\bf \$gp} & global pointer, preserve \\ +{\bf \$29} & {\bf \$sp} & stack pointer, preserve \\ +{\bf \$30} & {\bf \$s8} & frame pointer, preserve \\ +{\bf \$31} & {\bf \$ra} & return address, preserve \\ +{\bf hi, lo} & & multiply/divide special registers \\ +{\bf \$f0,\$f2} & & only on hard-float targets: float results, scratch \\ +{\bf \$f1,\$f3,\$f4-\$f11,\$f20-\$f23} & & only on hard-float targets: float temporaries, scratch \\ +{\bf \$f12-\$f19} & & only on hard-float targets: float arguments, scratch \\ +{\bf \$f24-\$f31} & & only on hard-float targets: preserved \\%@@@on N32, this changes +\end{tabular*} +\caption{Register usage on MIPS N64 calling convention} +\end{table} + +\paragraph{Parameter passing} + +\begin{itemize} +\item Stack grows down +\item Stack parameter order: right-to-left +\item Caller cleans up the stack +\item generally, first 8 params \textgreater=\ 64-bit are passed via registers +\item for hard-float targets: register arguments are passed via \$a0-\$a7 for integers and \$f12-\$f19 for floats - with mixed float and int parameters, some registers are left out (e.g. first parameter ends up in \$a0 or \$f12, second in \$a1 or \$f13, etc.) +\item for soft-float targets: register arguments are passed via \$a0-\$a7 +\item subsequent arguments are pushed onto the stack +\item all stack entries are 64-bit aligned +\item all stack regions are 16-byte aligned +\item results are returned in \$v0, and for a second one \$v1 is used +\item only on hard-float targets: floating point results are returned in \$f0 +\item if the callee takes the address of one of the parameters and uses it to address other unnamed parameters (e.g. varargs) it has to copy - in its prolog - the the argument registers to a reserved stack area adjacent to the other parameters on the stack (only the unnamed integer parameters require saving, though) % @@@ seems to *ONLY* spill with varargs, never for any other reason +\item float arguments passed in the variable part of a vararg call are passed like integers, meaning float registers don't ever need to be saved that way, so only \$a0-\$a7 are need to be spilled +\item quad precision float arguments are passed in even-odd register pairs, skipping one register if needed +\item integer parameters \textless\ 64 bit are right-justified (meaning occupy higher-address bytes) in their 8-byte slot on the stack, requiring extra-care for big-endian targets +\item single precision float parameters (32 bit) are left-justified in their 8-byte slot on the stack, but are right justified in fp-registers on big endian targets, as they aren't promoted @@@doc says "undecided", but openbsd/octeon(mipseb) has it as described here +\end{itemize} +% maybe note somewhere that "prolog-based" spilling is neat for dyncall, as we don't have to care + +\paragraph{Stack layout} + +% verified/amended: TP nov 2019 (see also doc/disas_examples/mips64.n64.disas) +Stack directly after function prolog:\\ + +\begin{figure}[h] +\begin{tabular}{5|3|1 1} + & \vdots & & \\ +\hhline{~=~~} +register save area & \hspace{4cm} & & \mrrbrace{5}{caller's frame} \\ +\hhline{~-~~} +local data & & & \\ +\hhline{~-~~} +\mrlbrace{6}{parameter area} & arg n-1 & \mrrbrace{3}{stack parameters} & \\ + & \ldots & & \\ + & arg 8 & & \\ +\hhline{~=~~} + & \$a7 & \mrrbrace{3}{spill area (if needed)} & \mrrbrace{6}{current frame} \\ + & \ldots & & \\ + & \$a? (first unnamed reg) & & \\ +\hhline{~-~~} +register save area (with return address) & & & \\ +\hhline{~-~~} +local data & & & \\ +\hhline{~-~~} +parameter area & \vdots & & \\ +\end{tabular} +\caption{Stack layout on MIPS N64 calling convention} +\end{figure} + + +\subsubsection{MIPS N32 Calling Convention} + +@@@ +