Mercurial > pub > dyncall > dyncall
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:\\ |