Dyn

 view release on metacpan or  search on metacpan

dyncall/doc/manual/callconvs/callconv_mips64.tex  view on Meta::CPAN

%//////////////////////////////////////////////////////////////////////////////
%
% Copyright (c) 2007-2022 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 ILP32 as programming model (32-bit pointers and long integers), whereas
N64 uses LP64 (64-bit pointers and long integers). 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 integers on hard-float targets), scratch \\
{\bf \$4-\$11}             & {\bf \$a0-\$a7}      & first arguments (only integers 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 return values, scratch \\
{\bf \$f1,\$f3,\$f4-\$f11} &                      & only on hard-float targets: float temporaries, scratch \\
{\bf \$f12-\$f19}          &                      & only on hard-float targets: float arguments, scratch \\
{\bf \$f20-\$f23}          &                      & only on hard-float targets: float temporaries, scratch \\
{\bf \$f24-\$f31}          &                      & only on hard-float targets: preserved \\
\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 \$f...
\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 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...
\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 (actually, official docs says "undecided", but real world im...
\item aggregates (struct, union) are passed as a sequence of dwords in (integer registers and the stack), with the following particularities:
\item {\it non-trivial} C++ aggregates (as defined by the language) of any size, are passed indirectly via a pointer to a copy of the aggregate
\begin{itemize}
\item if a dword happens to be a double precision floating point struct field, it is passed in a floating point register
\item array and union fields are always passed like integers (even if their type is float or double)
\item splitting an argument across registers and the stack is fine
\end{itemize}
%spec
%Structs, unions, or other composite types are treated as a sequence of doublewords,
%and are passed in integer or floating point registers as though they were simple
%scalar parameters to the extent that they fit, with any excess on the stack packed



( run in 0.580 second using v1.01-cache-2.11-cpan-39bf76dae61 )