comparison doc/manual/callconvs/callconv_mips64.tex @ 477:75c19f11b86a

- mips64 doc and more disas examples (fbsd big endian w/ -mhard-float flag)
author Tassilo Philipp
date Sun, 27 Feb 2022 13:53:18 +0100
parents 3c6bc720bc1f
children fc614cb865c6
comparison
equal deleted inserted replaced
476:c73c59c8b553 477:75c19f11b86a
1 %////////////////////////////////////////////////////////////////////////////// 1 %//////////////////////////////////////////////////////////////////////////////
2 % 2 %
3 % Copyright (c) 2007-2019 Daniel Adler <dadler@uni-goettingen.de>, 3 % Copyright (c) 2007-2022 Daniel Adler <dadler@uni-goettingen.de>,
4 % Tassilo Philipp <tphilipp@potion-studios.com> 4 % Tassilo Philipp <tphilipp@potion-studios.com>
5 % 5 %
6 % Permission to use, copy, modify, and distribute this software for any 6 % Permission to use, copy, modify, and distribute this software for any
7 % purpose with or without fee is hereby granted, provided that the above 7 % purpose with or without fee is hereby granted, provided that the above
8 % copyright notice and this permission notice appear in all copies. 8 % copyright notice and this permission notice appear in all copies.
44 \begin{tabular*}{0.95\textwidth}{lll} 44 \begin{tabular*}{0.95\textwidth}{lll}
45 Name & Alias & Brief description\\ 45 Name & Alias & Brief description\\
46 \hline 46 \hline
47 {\bf \$0} & {\bf \$zero} & hardware zero \\ 47 {\bf \$0} & {\bf \$zero} & hardware zero \\
48 {\bf \$1} & {\bf \$at} & assembler temporary, scratch \\ 48 {\bf \$1} & {\bf \$at} & assembler temporary, scratch \\
49 {\bf \$2-\$3} & {\bf \$v0-\$v1} & return value (only integer on hard-float targets), scratch \\ 49 {\bf \$2-\$3} & {\bf \$v0-\$v1} & return value (only integers on hard-float targets), scratch \\
50 {\bf \$4-\$11} & {\bf \$a0-\$a7} & first arguments (only integer on hard-float targets), scratch \\ 50 {\bf \$4-\$11} & {\bf \$a0-\$a7} & first arguments (only integers on hard-float targets), scratch \\
51 {\bf \$12-\$15,\$24} & {\bf \$t4-\$t7,\$t8} & temporaries, scratch \\ 51 {\bf \$12-\$15,\$24} & {\bf \$t4-\$t7,\$t8} & temporaries, scratch \\
52 {\bf \$25} & {\bf \$t9} & temporary, address callee for all PIC calls (by convention), scratch \\ 52 {\bf \$25} & {\bf \$t9} & temporary, address callee for all PIC calls (by convention), scratch \\
53 {\bf \$16-\$23} & {\bf \$s0-\$s7} & preserve \\ 53 {\bf \$16-\$23} & {\bf \$s0-\$s7} & preserve \\
54 {\bf \$26,\$27} & {\bf \$kt0,\$kt1} & reserved for kernel \\ 54 {\bf \$26,\$27} & {\bf \$kt0,\$kt1} & reserved for kernel \\
55 {\bf \$28} & {\bf \$gp} & global pointer, preserve \\ 55 {\bf \$28} & {\bf \$gp} & global pointer, preserve \\
56 {\bf \$29} & {\bf \$sp} & stack pointer, preserve \\ 56 {\bf \$29} & {\bf \$sp} & stack pointer, preserve \\
57 {\bf \$30} & {\bf \$s8} & frame pointer, preserve \\ 57 {\bf \$30} & {\bf \$s8} & frame pointer, preserve \\
58 {\bf \$31} & {\bf \$ra} & return address, preserve \\ 58 {\bf \$31} & {\bf \$ra} & return address, preserve \\
59 {\bf hi, lo} & & multiply/divide special registers \\ 59 {\bf hi, lo} & & multiply/divide special registers \\
60 {\bf \$f0,\$f2} & & only on hard-float targets: float results, scratch \\ 60 {\bf \$f0,\$f2} & & only on hard-float targets: float return values, scratch \\
61 {\bf \$f1,\$f3,\$f4-\$f11} & & only on hard-float targets: float temporaries, scratch \\ 61 {\bf \$f1,\$f3,\$f4-\$f11} & & only on hard-float targets: float temporaries, scratch \\
62 {\bf \$f12-\$f19} & & only on hard-float targets: float arguments, scratch \\ 62 {\bf \$f12-\$f19} & & only on hard-float targets: float arguments, scratch \\
63 {\bf \$f20-\$f23} & & only on hard-float targets: float temporaries, scratch \\ 63 {\bf \$f20-\$f23} & & only on hard-float targets: float temporaries, scratch \\
64 {\bf \$f24-\$f31} & & only on hard-float targets: preserved \\ 64 {\bf \$f24-\$f31} & & only on hard-float targets: preserved \\
65 \end{tabular*} 65 \end{tabular*}
76 \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.) 76 \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.)
77 \item for soft-float targets: register arguments are passed via \$a0-\$a7 77 \item for soft-float targets: register arguments are passed via \$a0-\$a7
78 \item subsequent arguments are pushed onto the stack 78 \item subsequent arguments are pushed onto the stack
79 \item all stack entries are 64-bit aligned 79 \item all stack entries are 64-bit aligned
80 \item all stack regions are 16-byte aligned 80 \item all stack regions are 16-byte aligned
81 \item results are returned in \$v0, and for a second one \$v1 is used
82 \item only on hard-float targets: floating point results are returned in \$f0
83 \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 81 \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
84 \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 82 \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
85 \item quad precision float arguments are passed in even-odd register pairs, skipping one register if needed 83 \item quad precision float arguments are passed in even-odd register pairs, skipping one register if needed
86 \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 84 \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
87 \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 implementations seem to use what is described here) 85 \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 implementations seem to use what is described here)
86 \item aggregates (struct, union) are passed as a sequence of dwords in (integer registers and the stack), with the following particularities:
87 \begin{itemize}
88 \item if a dword happens to be a double precision floating point struct field, it is passed in a floating point register
89 \item array and union fields are always passed like integers (even if their type is float or double)
90 \item splitting an argument across registers and the stack is fine
91 \end{itemize}
92 %spec
93 %Structs, unions, or other composite types are treated as a sequence of doublewords,
94 %and are passed in integer or floating point registers as though they were simple
95 %scalar parameters to the extent that they fit, with any excess on the stack packed
96 %according to the normal memory layout of the object. More specifically:
97 %- Regardless of the struct field structure, it is treated as a sequence of 64-bit
98 %chunks. If a chunk consists solely of a double float field (but not a double,
99 %which is part of a union), it is passed in a floating point register. Any other
100 %chunk is passed in an integer register.
101 %- A union, either as the parameter itself or as a struct parameter field, is treated
102 %as a sequence of integer doublewords for purposes of assignment to integer
103 %parameter registers. No attempt is made to identify floating point components
104 %for passing in floating point registers.
105 %- Array fields of structs are passed like unions. Array parameters are passed by
106 %reference (unless the relevant language standard requires otherwise).
107 %- Right-justifying small scalar parameters in their save area slots
108 %notwithstanding, struct parameters are always left-justified. This applies both
109 %to the case of a struct smaller than 64 bits, and to the final chunk of a struct
110 %which is not an integral multiple of 64 bits in size. The implication of this rule is
111 %that the address of the first chunk’s save area slot is the address of the struct,
112 %and the struct is laid out in the save area memory exactly as if it were allocated
113 %normally (once any part in registers has been stored to the save area). [These
114 %rules are analogous to the o32-bit ABI treatment – only the chunk size and the
115 %ability to pass double fields in floating point registers are different.
88 \end{itemize} 116 \end{itemize}
89 % maybe note somewhere that "prolog-based" spilling is neat for dyncall, as we don't have to care 117 % maybe note somewhere that "prolog-based" spilling is neat for dyncall, as we don't have to care
118
119
120 \paragraph{Return values}
121
122 \begin{itemize}
123 \item results are returned in \$v0, and for a second one \$v1 is used
124 \item only on hard-float targets: floating point results are returned in \$f0 (and \$f2 if needed)
125 \item only on hard-float targets: structs with only one or two floating point fields are returned in \$f0 (and \$f2 if necessary), field-by-field
126 \item any other aggregates (struct, union) \textless= 16 bytes are returned via registers \$v0 (and \$v1 if necessary), dword-by-dword
127 \item all other aggregates (struct, union) \textgreater 16 bytes are returned in a space allocated by the caller, with a pointer to it
128 passed as first parameter to the function called (meaning in \%a0)
129 %spec;
130 %Composite results (struct, union, or array) are returned in
131 %$2/$f0 and $3/$f2 according to the following rules:
132 %- A struct with only one or two floating point fields is returned in $f0 (and $f2 if
133 %necessary). This is a generalization of the Fortran COMPLEX case.
134 %- Any other struct or union results of at most 128 bits are returned in $2 (first 64
135 %bits) and $3 (remainder, if necessary).
136 %- Larger composite results are handled by converting the function to a procedure
137 %with an implicit first parameter, which is a pointer to an area reserved by the
138 %caller to receive the result. [The o32-bit ABI requires that all composite results
139 %be handled by conversion to implicit first parameters. The MIPS/SGI Fortran
140 %implementation has always made a specific exception to return COMPLEX
141 %results in the floating point registers.]
142 \end{itemize}
143
90 144
91 \paragraph{Stack layout} 145 \paragraph{Stack layout}
92 146
93 % verified/amended: TP nov 2019 (see also doc/disas_examples/mips64.n64.disas) 147 % verified/amended: TP nov 2019 (see also doc/disas_examples/mips64.n64.disas)
94 Stack directly after function prolog:\\ 148 Stack directly after function prolog:\\