annotate libffi/src/mips/n32.S @ 158:494b0b89df80 default tip

...
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Mon, 25 May 2020 18:13:55 +0900
parents 04ced10e8804
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
111
kono
parents:
diff changeset
1 /* -----------------------------------------------------------------------
kono
parents:
diff changeset
2 n32.S - Copyright (c) 1996, 1998, 2005, 2007, 2009, 2010 Red Hat, Inc.
kono
parents:
diff changeset
3
kono
parents:
diff changeset
4 MIPS Foreign Function Interface
kono
parents:
diff changeset
5
kono
parents:
diff changeset
6 Permission is hereby granted, free of charge, to any person obtaining
kono
parents:
diff changeset
7 a copy of this software and associated documentation files (the
kono
parents:
diff changeset
8 ``Software''), to deal in the Software without restriction, including
kono
parents:
diff changeset
9 without limitation the rights to use, copy, modify, merge, publish,
kono
parents:
diff changeset
10 distribute, sublicense, and/or sell copies of the Software, and to
kono
parents:
diff changeset
11 permit persons to whom the Software is furnished to do so, subject to
kono
parents:
diff changeset
12 the following conditions:
kono
parents:
diff changeset
13
kono
parents:
diff changeset
14 The above copyright notice and this permission notice shall be included
kono
parents:
diff changeset
15 in all copies or substantial portions of the Software.
kono
parents:
diff changeset
16
kono
parents:
diff changeset
17 THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND,
kono
parents:
diff changeset
18 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
kono
parents:
diff changeset
19 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
kono
parents:
diff changeset
20 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
kono
parents:
diff changeset
21 HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
kono
parents:
diff changeset
22 WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
kono
parents:
diff changeset
23 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
kono
parents:
diff changeset
24 DEALINGS IN THE SOFTWARE.
kono
parents:
diff changeset
25 ----------------------------------------------------------------------- */
kono
parents:
diff changeset
26
kono
parents:
diff changeset
27 #define LIBFFI_ASM
kono
parents:
diff changeset
28 #include <fficonfig.h>
kono
parents:
diff changeset
29 #include <ffi.h>
kono
parents:
diff changeset
30
kono
parents:
diff changeset
31 /* Only build this code if we are compiling for n32 */
kono
parents:
diff changeset
32
kono
parents:
diff changeset
33 #if defined(FFI_MIPS_N32)
kono
parents:
diff changeset
34
kono
parents:
diff changeset
35 #define callback a0
kono
parents:
diff changeset
36 #define bytes a2
kono
parents:
diff changeset
37 #define flags a3
kono
parents:
diff changeset
38 #define raddr a4
kono
parents:
diff changeset
39 #define fn a5
kono
parents:
diff changeset
40
kono
parents:
diff changeset
41 #define SIZEOF_FRAME ( 8 * FFI_SIZEOF_ARG )
kono
parents:
diff changeset
42
kono
parents:
diff changeset
43 #ifdef __GNUC__
kono
parents:
diff changeset
44 .abicalls
kono
parents:
diff changeset
45 #endif
kono
parents:
diff changeset
46 .set mips4
kono
parents:
diff changeset
47 .text
kono
parents:
diff changeset
48 .align 2
kono
parents:
diff changeset
49 .globl ffi_call_N32
kono
parents:
diff changeset
50 .ent ffi_call_N32
kono
parents:
diff changeset
51 ffi_call_N32:
kono
parents:
diff changeset
52 .LFB3:
kono
parents:
diff changeset
53 .frame $fp, SIZEOF_FRAME, ra
kono
parents:
diff changeset
54 .mask 0xc0000000,-FFI_SIZEOF_ARG
kono
parents:
diff changeset
55 .fmask 0x00000000,0
kono
parents:
diff changeset
56
kono
parents:
diff changeset
57 # Prologue
kono
parents:
diff changeset
58 SUBU $sp, SIZEOF_FRAME # Frame size
kono
parents:
diff changeset
59 .LCFI0:
kono
parents:
diff changeset
60 REG_S $fp, SIZEOF_FRAME - 2*FFI_SIZEOF_ARG($sp) # Save frame pointer
kono
parents:
diff changeset
61 REG_S ra, SIZEOF_FRAME - 1*FFI_SIZEOF_ARG($sp) # Save return address
kono
parents:
diff changeset
62 .LCFI1:
kono
parents:
diff changeset
63 move $fp, $sp
kono
parents:
diff changeset
64 .LCFI3:
kono
parents:
diff changeset
65 move t9, callback # callback function pointer
kono
parents:
diff changeset
66 REG_S bytes, 2*FFI_SIZEOF_ARG($fp) # bytes
kono
parents:
diff changeset
67 REG_S flags, 3*FFI_SIZEOF_ARG($fp) # flags
kono
parents:
diff changeset
68 REG_S raddr, 4*FFI_SIZEOF_ARG($fp) # raddr
kono
parents:
diff changeset
69 REG_S fn, 5*FFI_SIZEOF_ARG($fp) # fn
kono
parents:
diff changeset
70
kono
parents:
diff changeset
71 # Allocate at least 4 words in the argstack
kono
parents:
diff changeset
72 move v0, bytes
kono
parents:
diff changeset
73 bge bytes, 4 * FFI_SIZEOF_ARG, bigger
kono
parents:
diff changeset
74 LI v0, 4 * FFI_SIZEOF_ARG
kono
parents:
diff changeset
75 b sixteen
kono
parents:
diff changeset
76
kono
parents:
diff changeset
77 bigger:
kono
parents:
diff changeset
78 ADDU t4, v0, 2 * FFI_SIZEOF_ARG -1 # make sure it is aligned
kono
parents:
diff changeset
79 and v0, t4, -2 * FFI_SIZEOF_ARG # to a proper boundry.
kono
parents:
diff changeset
80
kono
parents:
diff changeset
81 sixteen:
kono
parents:
diff changeset
82 SUBU $sp, $sp, v0 # move the stack pointer to reflect the
kono
parents:
diff changeset
83 # arg space
kono
parents:
diff changeset
84
kono
parents:
diff changeset
85 move a0, $sp # 4 * FFI_SIZEOF_ARG
kono
parents:
diff changeset
86 ADDU a3, $fp, 3 * FFI_SIZEOF_ARG
kono
parents:
diff changeset
87
kono
parents:
diff changeset
88 # Call ffi_prep_args
kono
parents:
diff changeset
89 jal t9
kono
parents:
diff changeset
90
kono
parents:
diff changeset
91 # Copy the stack pointer to t9
kono
parents:
diff changeset
92 move t9, $sp
kono
parents:
diff changeset
93
kono
parents:
diff changeset
94 # Fix the stack if there are more than 8 64bit slots worth
kono
parents:
diff changeset
95 # of arguments.
kono
parents:
diff changeset
96
kono
parents:
diff changeset
97 # Load the number of bytes
kono
parents:
diff changeset
98 REG_L t6, 2*FFI_SIZEOF_ARG($fp)
kono
parents:
diff changeset
99
kono
parents:
diff changeset
100 # Is it bigger than 8 * FFI_SIZEOF_ARG?
kono
parents:
diff changeset
101 daddiu t8, t6, -(8 * FFI_SIZEOF_ARG)
kono
parents:
diff changeset
102 bltz t8, loadregs
kono
parents:
diff changeset
103
kono
parents:
diff changeset
104 ADDU t9, t9, t8
kono
parents:
diff changeset
105
kono
parents:
diff changeset
106 loadregs:
kono
parents:
diff changeset
107
kono
parents:
diff changeset
108 REG_L t6, 3*FFI_SIZEOF_ARG($fp) # load the flags word into t6.
kono
parents:
diff changeset
109
kono
parents:
diff changeset
110 and t4, t6, ((1<<FFI_FLAG_BITS)-1)
kono
parents:
diff changeset
111 REG_L a0, 0*FFI_SIZEOF_ARG(t9)
kono
parents:
diff changeset
112 beqz t4, arg1_next
kono
parents:
diff changeset
113 bne t4, FFI_TYPE_FLOAT, arg1_doublep
kono
parents:
diff changeset
114 l.s $f12, 0*FFI_SIZEOF_ARG(t9)
kono
parents:
diff changeset
115 b arg1_next
kono
parents:
diff changeset
116 arg1_doublep:
kono
parents:
diff changeset
117 l.d $f12, 0*FFI_SIZEOF_ARG(t9)
kono
parents:
diff changeset
118 arg1_next:
kono
parents:
diff changeset
119
kono
parents:
diff changeset
120 SRL t4, t6, 1*FFI_FLAG_BITS
kono
parents:
diff changeset
121 and t4, ((1<<FFI_FLAG_BITS)-1)
kono
parents:
diff changeset
122 REG_L a1, 1*FFI_SIZEOF_ARG(t9)
kono
parents:
diff changeset
123 beqz t4, arg2_next
kono
parents:
diff changeset
124 bne t4, FFI_TYPE_FLOAT, arg2_doublep
kono
parents:
diff changeset
125 l.s $f13, 1*FFI_SIZEOF_ARG(t9)
kono
parents:
diff changeset
126 b arg2_next
kono
parents:
diff changeset
127 arg2_doublep:
kono
parents:
diff changeset
128 l.d $f13, 1*FFI_SIZEOF_ARG(t9)
kono
parents:
diff changeset
129 arg2_next:
kono
parents:
diff changeset
130
kono
parents:
diff changeset
131 SRL t4, t6, 2*FFI_FLAG_BITS
kono
parents:
diff changeset
132 and t4, ((1<<FFI_FLAG_BITS)-1)
kono
parents:
diff changeset
133 REG_L a2, 2*FFI_SIZEOF_ARG(t9)
kono
parents:
diff changeset
134 beqz t4, arg3_next
kono
parents:
diff changeset
135 bne t4, FFI_TYPE_FLOAT, arg3_doublep
kono
parents:
diff changeset
136 l.s $f14, 2*FFI_SIZEOF_ARG(t9)
kono
parents:
diff changeset
137 b arg3_next
kono
parents:
diff changeset
138 arg3_doublep:
kono
parents:
diff changeset
139 l.d $f14, 2*FFI_SIZEOF_ARG(t9)
kono
parents:
diff changeset
140 arg3_next:
kono
parents:
diff changeset
141
kono
parents:
diff changeset
142 SRL t4, t6, 3*FFI_FLAG_BITS
kono
parents:
diff changeset
143 and t4, ((1<<FFI_FLAG_BITS)-1)
kono
parents:
diff changeset
144 REG_L a3, 3*FFI_SIZEOF_ARG(t9)
kono
parents:
diff changeset
145 beqz t4, arg4_next
kono
parents:
diff changeset
146 bne t4, FFI_TYPE_FLOAT, arg4_doublep
kono
parents:
diff changeset
147 l.s $f15, 3*FFI_SIZEOF_ARG(t9)
kono
parents:
diff changeset
148 b arg4_next
kono
parents:
diff changeset
149 arg4_doublep:
kono
parents:
diff changeset
150 l.d $f15, 3*FFI_SIZEOF_ARG(t9)
kono
parents:
diff changeset
151 arg4_next:
kono
parents:
diff changeset
152
kono
parents:
diff changeset
153 SRL t4, t6, 4*FFI_FLAG_BITS
kono
parents:
diff changeset
154 and t4, ((1<<FFI_FLAG_BITS)-1)
kono
parents:
diff changeset
155 REG_L a4, 4*FFI_SIZEOF_ARG(t9)
kono
parents:
diff changeset
156 beqz t4, arg5_next
kono
parents:
diff changeset
157 bne t4, FFI_TYPE_FLOAT, arg5_doublep
kono
parents:
diff changeset
158 l.s $f16, 4*FFI_SIZEOF_ARG(t9)
kono
parents:
diff changeset
159 b arg5_next
kono
parents:
diff changeset
160 arg5_doublep:
kono
parents:
diff changeset
161 l.d $f16, 4*FFI_SIZEOF_ARG(t9)
kono
parents:
diff changeset
162 arg5_next:
kono
parents:
diff changeset
163
kono
parents:
diff changeset
164 SRL t4, t6, 5*FFI_FLAG_BITS
kono
parents:
diff changeset
165 and t4, ((1<<FFI_FLAG_BITS)-1)
kono
parents:
diff changeset
166 REG_L a5, 5*FFI_SIZEOF_ARG(t9)
kono
parents:
diff changeset
167 beqz t4, arg6_next
kono
parents:
diff changeset
168 bne t4, FFI_TYPE_FLOAT, arg6_doublep
kono
parents:
diff changeset
169 l.s $f17, 5*FFI_SIZEOF_ARG(t9)
kono
parents:
diff changeset
170 b arg6_next
kono
parents:
diff changeset
171 arg6_doublep:
kono
parents:
diff changeset
172 l.d $f17, 5*FFI_SIZEOF_ARG(t9)
kono
parents:
diff changeset
173 arg6_next:
kono
parents:
diff changeset
174
kono
parents:
diff changeset
175 SRL t4, t6, 6*FFI_FLAG_BITS
kono
parents:
diff changeset
176 and t4, ((1<<FFI_FLAG_BITS)-1)
kono
parents:
diff changeset
177 REG_L a6, 6*FFI_SIZEOF_ARG(t9)
kono
parents:
diff changeset
178 beqz t4, arg7_next
kono
parents:
diff changeset
179 bne t4, FFI_TYPE_FLOAT, arg7_doublep
kono
parents:
diff changeset
180 l.s $f18, 6*FFI_SIZEOF_ARG(t9)
kono
parents:
diff changeset
181 b arg7_next
kono
parents:
diff changeset
182 arg7_doublep:
kono
parents:
diff changeset
183 l.d $f18, 6*FFI_SIZEOF_ARG(t9)
kono
parents:
diff changeset
184 arg7_next:
kono
parents:
diff changeset
185
kono
parents:
diff changeset
186 SRL t4, t6, 7*FFI_FLAG_BITS
kono
parents:
diff changeset
187 and t4, ((1<<FFI_FLAG_BITS)-1)
kono
parents:
diff changeset
188 REG_L a7, 7*FFI_SIZEOF_ARG(t9)
kono
parents:
diff changeset
189 beqz t4, arg8_next
kono
parents:
diff changeset
190 bne t4, FFI_TYPE_FLOAT, arg8_doublep
kono
parents:
diff changeset
191 l.s $f19, 7*FFI_SIZEOF_ARG(t9)
kono
parents:
diff changeset
192 b arg8_next
kono
parents:
diff changeset
193 arg8_doublep:
kono
parents:
diff changeset
194 l.d $f19, 7*FFI_SIZEOF_ARG(t9)
kono
parents:
diff changeset
195 arg8_next:
kono
parents:
diff changeset
196
kono
parents:
diff changeset
197 callit:
kono
parents:
diff changeset
198 # Load the function pointer
kono
parents:
diff changeset
199 REG_L t9, 5*FFI_SIZEOF_ARG($fp)
kono
parents:
diff changeset
200
kono
parents:
diff changeset
201 # If the return value pointer is NULL, assume no return value.
kono
parents:
diff changeset
202 REG_L t5, 4*FFI_SIZEOF_ARG($fp)
kono
parents:
diff changeset
203 beqz t5, noretval
kono
parents:
diff changeset
204
kono
parents:
diff changeset
205 # Shift the return type flag over
kono
parents:
diff changeset
206 SRL t6, 8*FFI_FLAG_BITS
kono
parents:
diff changeset
207
kono
parents:
diff changeset
208 beq t6, FFI_TYPE_SINT32, retint
kono
parents:
diff changeset
209 bne t6, FFI_TYPE_INT, retfloat
kono
parents:
diff changeset
210 retint:
kono
parents:
diff changeset
211 jal t9
kono
parents:
diff changeset
212 REG_L t4, 4*FFI_SIZEOF_ARG($fp)
kono
parents:
diff changeset
213 REG_S v0, 0(t4)
kono
parents:
diff changeset
214 b epilogue
kono
parents:
diff changeset
215
kono
parents:
diff changeset
216 retfloat:
kono
parents:
diff changeset
217 bne t6, FFI_TYPE_FLOAT, retdouble
kono
parents:
diff changeset
218 jal t9
kono
parents:
diff changeset
219 REG_L t4, 4*FFI_SIZEOF_ARG($fp)
kono
parents:
diff changeset
220 s.s $f0, 0(t4)
kono
parents:
diff changeset
221 b epilogue
kono
parents:
diff changeset
222
kono
parents:
diff changeset
223 retdouble:
kono
parents:
diff changeset
224 bne t6, FFI_TYPE_DOUBLE, retstruct_d
kono
parents:
diff changeset
225 jal t9
kono
parents:
diff changeset
226 REG_L t4, 4*FFI_SIZEOF_ARG($fp)
kono
parents:
diff changeset
227 s.d $f0, 0(t4)
kono
parents:
diff changeset
228 b epilogue
kono
parents:
diff changeset
229
kono
parents:
diff changeset
230 retstruct_d:
kono
parents:
diff changeset
231 bne t6, FFI_TYPE_STRUCT_D, retstruct_f
kono
parents:
diff changeset
232 jal t9
kono
parents:
diff changeset
233 REG_L t4, 4*FFI_SIZEOF_ARG($fp)
kono
parents:
diff changeset
234 s.d $f0, 0(t4)
kono
parents:
diff changeset
235 b epilogue
kono
parents:
diff changeset
236
kono
parents:
diff changeset
237 retstruct_f:
kono
parents:
diff changeset
238 bne t6, FFI_TYPE_STRUCT_F, retstruct_d_d
kono
parents:
diff changeset
239 jal t9
kono
parents:
diff changeset
240 REG_L t4, 4*FFI_SIZEOF_ARG($fp)
kono
parents:
diff changeset
241 s.s $f0, 0(t4)
kono
parents:
diff changeset
242 b epilogue
kono
parents:
diff changeset
243
kono
parents:
diff changeset
244 retstruct_d_d:
kono
parents:
diff changeset
245 bne t6, FFI_TYPE_STRUCT_DD, retstruct_f_f
kono
parents:
diff changeset
246 jal t9
kono
parents:
diff changeset
247 REG_L t4, 4*FFI_SIZEOF_ARG($fp)
kono
parents:
diff changeset
248 s.d $f0, 0(t4)
kono
parents:
diff changeset
249 s.d $f2, 8(t4)
kono
parents:
diff changeset
250 b epilogue
kono
parents:
diff changeset
251
kono
parents:
diff changeset
252 retstruct_f_f:
kono
parents:
diff changeset
253 bne t6, FFI_TYPE_STRUCT_FF, retstruct_d_f
kono
parents:
diff changeset
254 jal t9
kono
parents:
diff changeset
255 REG_L t4, 4*FFI_SIZEOF_ARG($fp)
kono
parents:
diff changeset
256 s.s $f0, 0(t4)
kono
parents:
diff changeset
257 s.s $f2, 4(t4)
kono
parents:
diff changeset
258 b epilogue
kono
parents:
diff changeset
259
kono
parents:
diff changeset
260 retstruct_d_f:
kono
parents:
diff changeset
261 bne t6, FFI_TYPE_STRUCT_DF, retstruct_f_d
kono
parents:
diff changeset
262 jal t9
kono
parents:
diff changeset
263 REG_L t4, 4*FFI_SIZEOF_ARG($fp)
kono
parents:
diff changeset
264 s.d $f0, 0(t4)
kono
parents:
diff changeset
265 s.s $f2, 8(t4)
kono
parents:
diff changeset
266 b epilogue
kono
parents:
diff changeset
267
kono
parents:
diff changeset
268 retstruct_f_d:
kono
parents:
diff changeset
269 bne t6, FFI_TYPE_STRUCT_FD, retstruct_d_soft
kono
parents:
diff changeset
270 jal t9
kono
parents:
diff changeset
271 REG_L t4, 4*FFI_SIZEOF_ARG($fp)
kono
parents:
diff changeset
272 s.s $f0, 0(t4)
kono
parents:
diff changeset
273 s.d $f2, 8(t4)
kono
parents:
diff changeset
274 b epilogue
kono
parents:
diff changeset
275
kono
parents:
diff changeset
276 retstruct_d_soft:
kono
parents:
diff changeset
277 bne t6, FFI_TYPE_STRUCT_D_SOFT, retstruct_f_soft
kono
parents:
diff changeset
278 jal t9
kono
parents:
diff changeset
279 REG_L t4, 4*FFI_SIZEOF_ARG($fp)
kono
parents:
diff changeset
280 sd v0, 0(t4)
kono
parents:
diff changeset
281 b epilogue
kono
parents:
diff changeset
282
kono
parents:
diff changeset
283 retstruct_f_soft:
kono
parents:
diff changeset
284 bne t6, FFI_TYPE_STRUCT_F_SOFT, retstruct_d_d_soft
kono
parents:
diff changeset
285 jal t9
kono
parents:
diff changeset
286 REG_L t4, 4*FFI_SIZEOF_ARG($fp)
kono
parents:
diff changeset
287 sw v0, 0(t4)
kono
parents:
diff changeset
288 b epilogue
kono
parents:
diff changeset
289
kono
parents:
diff changeset
290 retstruct_d_d_soft:
kono
parents:
diff changeset
291 bne t6, FFI_TYPE_STRUCT_DD_SOFT, retstruct_f_f_soft
kono
parents:
diff changeset
292 jal t9
kono
parents:
diff changeset
293 REG_L t4, 4*FFI_SIZEOF_ARG($fp)
kono
parents:
diff changeset
294 sd v0, 0(t4)
kono
parents:
diff changeset
295 sd v1, 8(t4)
kono
parents:
diff changeset
296 b epilogue
kono
parents:
diff changeset
297
kono
parents:
diff changeset
298 retstruct_f_f_soft:
kono
parents:
diff changeset
299 bne t6, FFI_TYPE_STRUCT_FF_SOFT, retstruct_d_f_soft
kono
parents:
diff changeset
300 jal t9
kono
parents:
diff changeset
301 REG_L t4, 4*FFI_SIZEOF_ARG($fp)
kono
parents:
diff changeset
302 sw v0, 0(t4)
kono
parents:
diff changeset
303 sw v1, 4(t4)
kono
parents:
diff changeset
304 b epilogue
kono
parents:
diff changeset
305
kono
parents:
diff changeset
306 retstruct_d_f_soft:
kono
parents:
diff changeset
307 bne t6, FFI_TYPE_STRUCT_DF_SOFT, retstruct_f_d_soft
kono
parents:
diff changeset
308 jal t9
kono
parents:
diff changeset
309 REG_L t4, 4*FFI_SIZEOF_ARG($fp)
kono
parents:
diff changeset
310 sd v0, 0(t4)
kono
parents:
diff changeset
311 sw v1, 8(t4)
kono
parents:
diff changeset
312 b epilogue
kono
parents:
diff changeset
313
kono
parents:
diff changeset
314 retstruct_f_d_soft:
kono
parents:
diff changeset
315 bne t6, FFI_TYPE_STRUCT_FD_SOFT, retstruct_small
kono
parents:
diff changeset
316 jal t9
kono
parents:
diff changeset
317 REG_L t4, 4*FFI_SIZEOF_ARG($fp)
kono
parents:
diff changeset
318 sw v0, 0(t4)
kono
parents:
diff changeset
319 sd v1, 8(t4)
kono
parents:
diff changeset
320 b epilogue
kono
parents:
diff changeset
321
kono
parents:
diff changeset
322 retstruct_small:
kono
parents:
diff changeset
323 bne t6, FFI_TYPE_STRUCT_SMALL, retstruct_small2
kono
parents:
diff changeset
324 jal t9
kono
parents:
diff changeset
325 REG_L t4, 4*FFI_SIZEOF_ARG($fp)
kono
parents:
diff changeset
326 REG_S v0, 0(t4)
kono
parents:
diff changeset
327 b epilogue
kono
parents:
diff changeset
328
kono
parents:
diff changeset
329 retstruct_small2:
kono
parents:
diff changeset
330 bne t6, FFI_TYPE_STRUCT_SMALL2, retstruct
kono
parents:
diff changeset
331 jal t9
kono
parents:
diff changeset
332 REG_L t4, 4*FFI_SIZEOF_ARG($fp)
kono
parents:
diff changeset
333 REG_S v0, 0(t4)
kono
parents:
diff changeset
334 REG_S v1, 8(t4)
kono
parents:
diff changeset
335 b epilogue
kono
parents:
diff changeset
336
kono
parents:
diff changeset
337 retstruct:
kono
parents:
diff changeset
338 noretval:
kono
parents:
diff changeset
339 jal t9
kono
parents:
diff changeset
340
kono
parents:
diff changeset
341 # Epilogue
kono
parents:
diff changeset
342 epilogue:
kono
parents:
diff changeset
343 move $sp, $fp
kono
parents:
diff changeset
344 REG_L $fp, SIZEOF_FRAME - 2*FFI_SIZEOF_ARG($sp) # Restore frame pointer
kono
parents:
diff changeset
345 REG_L ra, SIZEOF_FRAME - 1*FFI_SIZEOF_ARG($sp) # Restore return address
kono
parents:
diff changeset
346 ADDU $sp, SIZEOF_FRAME # Fix stack pointer
kono
parents:
diff changeset
347 j ra
kono
parents:
diff changeset
348
kono
parents:
diff changeset
349 .LFE3:
kono
parents:
diff changeset
350 .end ffi_call_N32
kono
parents:
diff changeset
351
kono
parents:
diff changeset
352 /* ffi_closure_N32. Expects address of the passed-in ffi_closure in t0
kono
parents:
diff changeset
353 ($12). Stores any arguments passed in registers onto the stack,
kono
parents:
diff changeset
354 then calls ffi_closure_mips_inner_N32, which then decodes
kono
parents:
diff changeset
355 them.
kono
parents:
diff changeset
356
kono
parents:
diff changeset
357 Stack layout:
kono
parents:
diff changeset
358
kono
parents:
diff changeset
359 20 - Start of parameters, original sp
kono
parents:
diff changeset
360 19 - Called function a7 save
kono
parents:
diff changeset
361 18 - Called function a6 save
kono
parents:
diff changeset
362 17 - Called function a5 save
kono
parents:
diff changeset
363 16 - Called function a4 save
kono
parents:
diff changeset
364 15 - Called function a3 save
kono
parents:
diff changeset
365 14 - Called function a2 save
kono
parents:
diff changeset
366 13 - Called function a1 save
kono
parents:
diff changeset
367 12 - Called function a0 save
kono
parents:
diff changeset
368 11 - Called function f19
kono
parents:
diff changeset
369 10 - Called function f18
kono
parents:
diff changeset
370 9 - Called function f17
kono
parents:
diff changeset
371 8 - Called function f16
kono
parents:
diff changeset
372 7 - Called function f15
kono
parents:
diff changeset
373 6 - Called function f14
kono
parents:
diff changeset
374 5 - Called function f13
kono
parents:
diff changeset
375 4 - Called function f12
kono
parents:
diff changeset
376 3 - return value high (v1 or $f2)
kono
parents:
diff changeset
377 2 - return value low (v0 or $f0)
kono
parents:
diff changeset
378 1 - ra save
kono
parents:
diff changeset
379 0 - gp save our sp points here
kono
parents:
diff changeset
380 */
kono
parents:
diff changeset
381
kono
parents:
diff changeset
382 #define SIZEOF_FRAME2 (20 * FFI_SIZEOF_ARG)
kono
parents:
diff changeset
383
kono
parents:
diff changeset
384 #define A7_OFF2 (19 * FFI_SIZEOF_ARG)
kono
parents:
diff changeset
385 #define A6_OFF2 (18 * FFI_SIZEOF_ARG)
kono
parents:
diff changeset
386 #define A5_OFF2 (17 * FFI_SIZEOF_ARG)
kono
parents:
diff changeset
387 #define A4_OFF2 (16 * FFI_SIZEOF_ARG)
kono
parents:
diff changeset
388 #define A3_OFF2 (15 * FFI_SIZEOF_ARG)
kono
parents:
diff changeset
389 #define A2_OFF2 (14 * FFI_SIZEOF_ARG)
kono
parents:
diff changeset
390 #define A1_OFF2 (13 * FFI_SIZEOF_ARG)
kono
parents:
diff changeset
391 #define A0_OFF2 (12 * FFI_SIZEOF_ARG)
kono
parents:
diff changeset
392
kono
parents:
diff changeset
393 #define F19_OFF2 (11 * FFI_SIZEOF_ARG)
kono
parents:
diff changeset
394 #define F18_OFF2 (10 * FFI_SIZEOF_ARG)
kono
parents:
diff changeset
395 #define F17_OFF2 (9 * FFI_SIZEOF_ARG)
kono
parents:
diff changeset
396 #define F16_OFF2 (8 * FFI_SIZEOF_ARG)
kono
parents:
diff changeset
397 #define F15_OFF2 (7 * FFI_SIZEOF_ARG)
kono
parents:
diff changeset
398 #define F14_OFF2 (6 * FFI_SIZEOF_ARG)
kono
parents:
diff changeset
399 #define F13_OFF2 (5 * FFI_SIZEOF_ARG)
kono
parents:
diff changeset
400 #define F12_OFF2 (4 * FFI_SIZEOF_ARG)
kono
parents:
diff changeset
401
kono
parents:
diff changeset
402 #define V1_OFF2 (3 * FFI_SIZEOF_ARG)
kono
parents:
diff changeset
403 #define V0_OFF2 (2 * FFI_SIZEOF_ARG)
kono
parents:
diff changeset
404
kono
parents:
diff changeset
405 #define RA_OFF2 (1 * FFI_SIZEOF_ARG)
kono
parents:
diff changeset
406 #define GP_OFF2 (0 * FFI_SIZEOF_ARG)
kono
parents:
diff changeset
407
kono
parents:
diff changeset
408 .align 2
kono
parents:
diff changeset
409 .globl ffi_closure_N32
kono
parents:
diff changeset
410 .ent ffi_closure_N32
kono
parents:
diff changeset
411 ffi_closure_N32:
kono
parents:
diff changeset
412 .LFB2:
kono
parents:
diff changeset
413 .frame $sp, SIZEOF_FRAME2, ra
kono
parents:
diff changeset
414 .mask 0x90000000,-(SIZEOF_FRAME2 - RA_OFF2)
kono
parents:
diff changeset
415 .fmask 0x00000000,0
kono
parents:
diff changeset
416 SUBU $sp, SIZEOF_FRAME2
kono
parents:
diff changeset
417 .LCFI5:
kono
parents:
diff changeset
418 .cpsetup t9, GP_OFF2, ffi_closure_N32
kono
parents:
diff changeset
419 REG_S ra, RA_OFF2($sp) # Save return address
kono
parents:
diff changeset
420 .LCFI6:
kono
parents:
diff changeset
421 # Store all possible argument registers. If there are more than
kono
parents:
diff changeset
422 # fit in registers, then they were stored on the stack.
kono
parents:
diff changeset
423 REG_S a0, A0_OFF2($sp)
kono
parents:
diff changeset
424 REG_S a1, A1_OFF2($sp)
kono
parents:
diff changeset
425 REG_S a2, A2_OFF2($sp)
kono
parents:
diff changeset
426 REG_S a3, A3_OFF2($sp)
kono
parents:
diff changeset
427 REG_S a4, A4_OFF2($sp)
kono
parents:
diff changeset
428 REG_S a5, A5_OFF2($sp)
kono
parents:
diff changeset
429 REG_S a6, A6_OFF2($sp)
kono
parents:
diff changeset
430 REG_S a7, A7_OFF2($sp)
kono
parents:
diff changeset
431
kono
parents:
diff changeset
432 # Store all possible float/double registers.
kono
parents:
diff changeset
433 s.d $f12, F12_OFF2($sp)
kono
parents:
diff changeset
434 s.d $f13, F13_OFF2($sp)
kono
parents:
diff changeset
435 s.d $f14, F14_OFF2($sp)
kono
parents:
diff changeset
436 s.d $f15, F15_OFF2($sp)
kono
parents:
diff changeset
437 s.d $f16, F16_OFF2($sp)
kono
parents:
diff changeset
438 s.d $f17, F17_OFF2($sp)
kono
parents:
diff changeset
439 s.d $f18, F18_OFF2($sp)
kono
parents:
diff changeset
440 s.d $f19, F19_OFF2($sp)
kono
parents:
diff changeset
441
kono
parents:
diff changeset
442 # Call ffi_closure_mips_inner_N32 to do the real work.
kono
parents:
diff changeset
443 LA t9, ffi_closure_mips_inner_N32
kono
parents:
diff changeset
444 move a0, $12 # Pointer to the ffi_closure
kono
parents:
diff changeset
445 ADDU a1, $sp, V0_OFF2
kono
parents:
diff changeset
446 ADDU a2, $sp, A0_OFF2
kono
parents:
diff changeset
447 ADDU a3, $sp, F12_OFF2
kono
parents:
diff changeset
448 jalr t9
kono
parents:
diff changeset
449
kono
parents:
diff changeset
450 # Return flags are in v0
kono
parents:
diff changeset
451 bne v0, FFI_TYPE_SINT32, cls_retint
kono
parents:
diff changeset
452 lw v0, V0_OFF2($sp)
kono
parents:
diff changeset
453 b cls_epilogue
kono
parents:
diff changeset
454
kono
parents:
diff changeset
455 cls_retint:
kono
parents:
diff changeset
456 bne v0, FFI_TYPE_INT, cls_retfloat
kono
parents:
diff changeset
457 REG_L v0, V0_OFF2($sp)
kono
parents:
diff changeset
458 b cls_epilogue
kono
parents:
diff changeset
459
kono
parents:
diff changeset
460 cls_retfloat:
kono
parents:
diff changeset
461 bne v0, FFI_TYPE_FLOAT, cls_retdouble
kono
parents:
diff changeset
462 l.s $f0, V0_OFF2($sp)
kono
parents:
diff changeset
463 b cls_epilogue
kono
parents:
diff changeset
464
kono
parents:
diff changeset
465 cls_retdouble:
kono
parents:
diff changeset
466 bne v0, FFI_TYPE_DOUBLE, cls_retstruct_d
kono
parents:
diff changeset
467 l.d $f0, V0_OFF2($sp)
kono
parents:
diff changeset
468 b cls_epilogue
kono
parents:
diff changeset
469
kono
parents:
diff changeset
470 cls_retstruct_d:
kono
parents:
diff changeset
471 bne v0, FFI_TYPE_STRUCT_D, cls_retstruct_f
kono
parents:
diff changeset
472 l.d $f0, V0_OFF2($sp)
kono
parents:
diff changeset
473 b cls_epilogue
kono
parents:
diff changeset
474
kono
parents:
diff changeset
475 cls_retstruct_f:
kono
parents:
diff changeset
476 bne v0, FFI_TYPE_STRUCT_F, cls_retstruct_d_d
kono
parents:
diff changeset
477 l.s $f0, V0_OFF2($sp)
kono
parents:
diff changeset
478 b cls_epilogue
kono
parents:
diff changeset
479
kono
parents:
diff changeset
480 cls_retstruct_d_d:
kono
parents:
diff changeset
481 bne v0, FFI_TYPE_STRUCT_DD, cls_retstruct_f_f
kono
parents:
diff changeset
482 l.d $f0, V0_OFF2($sp)
kono
parents:
diff changeset
483 l.d $f2, V1_OFF2($sp)
kono
parents:
diff changeset
484 b cls_epilogue
kono
parents:
diff changeset
485
kono
parents:
diff changeset
486 cls_retstruct_f_f:
kono
parents:
diff changeset
487 bne v0, FFI_TYPE_STRUCT_FF, cls_retstruct_d_f
kono
parents:
diff changeset
488 l.s $f0, V0_OFF2($sp)
kono
parents:
diff changeset
489 l.s $f2, V1_OFF2($sp)
kono
parents:
diff changeset
490 b cls_epilogue
kono
parents:
diff changeset
491
kono
parents:
diff changeset
492 cls_retstruct_d_f:
kono
parents:
diff changeset
493 bne v0, FFI_TYPE_STRUCT_DF, cls_retstruct_f_d
kono
parents:
diff changeset
494 l.d $f0, V0_OFF2($sp)
kono
parents:
diff changeset
495 l.s $f2, V1_OFF2($sp)
kono
parents:
diff changeset
496 b cls_epilogue
kono
parents:
diff changeset
497
kono
parents:
diff changeset
498 cls_retstruct_f_d:
kono
parents:
diff changeset
499 bne v0, FFI_TYPE_STRUCT_FD, cls_retstruct_small2
kono
parents:
diff changeset
500 l.s $f0, V0_OFF2($sp)
kono
parents:
diff changeset
501 l.d $f2, V1_OFF2($sp)
kono
parents:
diff changeset
502 b cls_epilogue
kono
parents:
diff changeset
503
kono
parents:
diff changeset
504 cls_retstruct_small2:
kono
parents:
diff changeset
505 REG_L v0, V0_OFF2($sp)
kono
parents:
diff changeset
506 REG_L v1, V1_OFF2($sp)
kono
parents:
diff changeset
507
kono
parents:
diff changeset
508 # Epilogue
kono
parents:
diff changeset
509 cls_epilogue:
kono
parents:
diff changeset
510 REG_L ra, RA_OFF2($sp) # Restore return address
kono
parents:
diff changeset
511 .cpreturn
kono
parents:
diff changeset
512 ADDU $sp, SIZEOF_FRAME2
kono
parents:
diff changeset
513 j ra
kono
parents:
diff changeset
514 .LFE2:
kono
parents:
diff changeset
515 .end ffi_closure_N32
kono
parents:
diff changeset
516
kono
parents:
diff changeset
517 #ifdef __GNUC__
kono
parents:
diff changeset
518 .section .eh_frame,"aw",@progbits
kono
parents:
diff changeset
519 .Lframe1:
kono
parents:
diff changeset
520 .4byte .LECIE1-.LSCIE1 # length
kono
parents:
diff changeset
521 .LSCIE1:
kono
parents:
diff changeset
522 .4byte 0x0 # CIE
kono
parents:
diff changeset
523 .byte 0x1 # Version 1
kono
parents:
diff changeset
524 .ascii "\000" # Augmentation
kono
parents:
diff changeset
525 .uleb128 0x1 # Code alignment 1
kono
parents:
diff changeset
526 .sleb128 -4 # Data alignment -4
kono
parents:
diff changeset
527 .byte 0x1f # Return Address $31
kono
parents:
diff changeset
528 .byte 0xc # DW_CFA_def_cfa
kono
parents:
diff changeset
529 .uleb128 0x1d # in $sp
kono
parents:
diff changeset
530 .uleb128 0x0 # offset 0
kono
parents:
diff changeset
531 .align EH_FRAME_ALIGN
kono
parents:
diff changeset
532 .LECIE1:
kono
parents:
diff changeset
533
kono
parents:
diff changeset
534 .LSFDE1:
kono
parents:
diff changeset
535 .4byte .LEFDE1-.LASFDE1 # length.
kono
parents:
diff changeset
536 .LASFDE1:
kono
parents:
diff changeset
537 .4byte .LASFDE1-.Lframe1 # CIE_pointer.
kono
parents:
diff changeset
538 FDE_ADDR_BYTES .LFB3 # initial_location.
kono
parents:
diff changeset
539 FDE_ADDR_BYTES .LFE3-.LFB3 # address_range.
kono
parents:
diff changeset
540 .byte 0x4 # DW_CFA_advance_loc4
kono
parents:
diff changeset
541 .4byte .LCFI0-.LFB3 # to .LCFI0
kono
parents:
diff changeset
542 .byte 0xe # DW_CFA_def_cfa_offset
kono
parents:
diff changeset
543 .uleb128 SIZEOF_FRAME # adjust stack.by SIZEOF_FRAME
kono
parents:
diff changeset
544 .byte 0x4 # DW_CFA_advance_loc4
kono
parents:
diff changeset
545 .4byte .LCFI1-.LCFI0 # to .LCFI1
kono
parents:
diff changeset
546 .byte 0x9e # DW_CFA_offset of $fp
kono
parents:
diff changeset
547 .uleb128 2*FFI_SIZEOF_ARG/4 #
kono
parents:
diff changeset
548 .byte 0x9f # DW_CFA_offset of ra
kono
parents:
diff changeset
549 .uleb128 1*FFI_SIZEOF_ARG/4 #
kono
parents:
diff changeset
550 .byte 0x4 # DW_CFA_advance_loc4
kono
parents:
diff changeset
551 .4byte .LCFI3-.LCFI1 # to .LCFI3
kono
parents:
diff changeset
552 .byte 0xd # DW_CFA_def_cfa_register
kono
parents:
diff changeset
553 .uleb128 0x1e # in $fp
kono
parents:
diff changeset
554 .align EH_FRAME_ALIGN
kono
parents:
diff changeset
555 .LEFDE1:
kono
parents:
diff changeset
556 .LSFDE3:
kono
parents:
diff changeset
557 .4byte .LEFDE3-.LASFDE3 # length
kono
parents:
diff changeset
558 .LASFDE3:
kono
parents:
diff changeset
559 .4byte .LASFDE3-.Lframe1 # CIE_pointer.
kono
parents:
diff changeset
560 FDE_ADDR_BYTES .LFB2 # initial_location.
kono
parents:
diff changeset
561 FDE_ADDR_BYTES .LFE2-.LFB2 # address_range.
kono
parents:
diff changeset
562 .byte 0x4 # DW_CFA_advance_loc4
kono
parents:
diff changeset
563 .4byte .LCFI5-.LFB2 # to .LCFI5
kono
parents:
diff changeset
564 .byte 0xe # DW_CFA_def_cfa_offset
kono
parents:
diff changeset
565 .uleb128 SIZEOF_FRAME2 # adjust stack.by SIZEOF_FRAME
kono
parents:
diff changeset
566 .byte 0x4 # DW_CFA_advance_loc4
kono
parents:
diff changeset
567 .4byte .LCFI6-.LCFI5 # to .LCFI6
kono
parents:
diff changeset
568 .byte 0x9c # DW_CFA_offset of $gp ($28)
kono
parents:
diff changeset
569 .uleb128 (SIZEOF_FRAME2 - GP_OFF2)/4
kono
parents:
diff changeset
570 .byte 0x9f # DW_CFA_offset of ra ($31)
kono
parents:
diff changeset
571 .uleb128 (SIZEOF_FRAME2 - RA_OFF2)/4
kono
parents:
diff changeset
572 .align EH_FRAME_ALIGN
kono
parents:
diff changeset
573 .LEFDE3:
kono
parents:
diff changeset
574 #endif /* __GNUC__ */
kono
parents:
diff changeset
575
kono
parents:
diff changeset
576 #endif