1 |
732 |
jeremybenn |
/* -----------------------------------------------------------------------
|
2 |
|
|
darwin_closure.S - Copyright (c) 2002, 2003, 2004, 2010,
|
3 |
|
|
Free Software Foundation, Inc.
|
4 |
|
|
based on ppc_closure.S
|
5 |
|
|
|
6 |
|
|
PowerPC Assembly glue.
|
7 |
|
|
|
8 |
|
|
Permission is hereby granted, free of charge, to any person obtaining
|
9 |
|
|
a copy of this software and associated documentation files (the
|
10 |
|
|
``Software''), to deal in the Software without restriction, including
|
11 |
|
|
without limitation the rights to use, copy, modify, merge, publish,
|
12 |
|
|
distribute, sublicense, and/or sell copies of the Software, and to
|
13 |
|
|
permit persons to whom the Software is furnished to do so, subject to
|
14 |
|
|
the following conditions:
|
15 |
|
|
|
16 |
|
|
The above copyright notice and this permission notice shall be included
|
17 |
|
|
in all copies or substantial portions of the Software.
|
18 |
|
|
|
19 |
|
|
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
20 |
|
|
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
21 |
|
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
22 |
|
|
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
23 |
|
|
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
24 |
|
|
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
25 |
|
|
OTHER DEALINGS IN THE SOFTWARE.
|
26 |
|
|
----------------------------------------------------------------------- */
|
27 |
|
|
|
28 |
|
|
#define LIBFFI_ASM
|
29 |
|
|
#define L(x) x
|
30 |
|
|
|
31 |
|
|
#if defined(__ppc64__)
|
32 |
|
|
#define MODE_CHOICE(x, y) y
|
33 |
|
|
#else
|
34 |
|
|
#define MODE_CHOICE(x, y) x
|
35 |
|
|
#endif
|
36 |
|
|
|
37 |
|
|
#define machine_choice MODE_CHOICE(ppc7400,ppc64)
|
38 |
|
|
|
39 |
|
|
; Define some pseudo-opcodes for size-independent load & store of GPRs ...
|
40 |
|
|
#define lgu MODE_CHOICE(lwzu, ldu)
|
41 |
|
|
#define lg MODE_CHOICE(lwz,ld)
|
42 |
|
|
#define sg MODE_CHOICE(stw,std)
|
43 |
|
|
#define sgu MODE_CHOICE(stwu,stdu)
|
44 |
|
|
|
45 |
|
|
; ... and the size of GPRs and their storage indicator.
|
46 |
|
|
#define GPR_BYTES MODE_CHOICE(4,8)
|
47 |
|
|
#define LOG2_GPR_BYTES MODE_CHOICE(2,3) /* log2(GPR_BYTES) */
|
48 |
|
|
#define g_long MODE_CHOICE(long, quad) /* usage is ".g_long" */
|
49 |
|
|
|
50 |
|
|
; From the ABI doc: "Mac OS X ABI Function Call Guide" Version 2009-02-04.
|
51 |
|
|
#define LINKAGE_SIZE MODE_CHOICE(24,48)
|
52 |
|
|
#define PARAM_AREA MODE_CHOICE(32,64)
|
53 |
|
|
|
54 |
|
|
#define SAVED_CR_OFFSET MODE_CHOICE(4,8) /* save position for CR */
|
55 |
|
|
#define SAVED_LR_OFFSET MODE_CHOICE(8,16) /* save position for lr */
|
56 |
|
|
|
57 |
|
|
/* WARNING: if ffi_type is changed... here be monsters.
|
58 |
|
|
Offsets of items within the result type. */
|
59 |
|
|
#define FFI_TYPE_TYPE MODE_CHOICE(6,10)
|
60 |
|
|
#define FFI_TYPE_ELEM MODE_CHOICE(8,16)
|
61 |
|
|
|
62 |
|
|
#define SAVED_FPR_COUNT 13
|
63 |
|
|
#define FPR_SIZE 8
|
64 |
|
|
/* biggest m64 struct ret is 8GPRS + 13FPRS = 168 bytes - rounded to 16bytes = 176. */
|
65 |
|
|
#define RESULT_BYTES MODE_CHOICE(16,176)
|
66 |
|
|
|
67 |
|
|
; The whole stack frame **MUST** be 16byte-aligned.
|
68 |
|
|
#define SAVE_SIZE (((LINKAGE_SIZE+PARAM_AREA+SAVED_FPR_COUNT*FPR_SIZE+RESULT_BYTES)+15) & -16LL)
|
69 |
|
|
#define PAD_SIZE (SAVE_SIZE-(LINKAGE_SIZE+PARAM_AREA+SAVED_FPR_COUNT*FPR_SIZE+RESULT_BYTES))
|
70 |
|
|
|
71 |
|
|
#define PARENT_PARM_BASE (SAVE_SIZE+LINKAGE_SIZE)
|
72 |
|
|
#define FP_SAVE_BASE (LINKAGE_SIZE+PARAM_AREA)
|
73 |
|
|
|
74 |
|
|
#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 1050
|
75 |
|
|
; We no longer need the pic symbol stub for Darwin >= 9.
|
76 |
|
|
#define BLCLS_HELP _ffi_closure_helper_DARWIN
|
77 |
|
|
#define STRUCT_RETVALUE_P _darwin64_struct_ret_by_value_p
|
78 |
|
|
#define PASS_STR_FLOATS _darwin64_pass_struct_floats
|
79 |
|
|
#undef WANT_STUB
|
80 |
|
|
#else
|
81 |
|
|
#define BLCLS_HELP L_ffi_closure_helper_DARWIN$stub
|
82 |
|
|
#define STRUCT_RETVALUE_P L_darwin64_struct_ret_by_value_p$stub
|
83 |
|
|
#define PASS_STR_FLOATS L_darwin64_pass_struct_floats$stub
|
84 |
|
|
#define WANT_STUB
|
85 |
|
|
#endif
|
86 |
|
|
|
87 |
|
|
/* m32/m64
|
88 |
|
|
|
89 |
|
|
The stack layout looks like this:
|
90 |
|
|
|
91 |
|
|
| Additional params... | | Higher address
|
92 |
|
|
~ ~ ~
|
93 |
|
|
| Parameters (at least 8*4/8=32/64) | | NUM_GPR_ARG_REGISTERS
|
94 |
|
|
|--------------------------------------------| |
|
95 |
|
|
| TOC=R2 (AIX) Reserved (Darwin) 4/8 | |
|
96 |
|
|
|--------------------------------------------| |
|
97 |
|
|
| Reserved 2*4/8 | |
|
98 |
|
|
|--------------------------------------------| |
|
99 |
|
|
| Space for callee`s LR 4/8 | |
|
100 |
|
|
|--------------------------------------------| |
|
101 |
|
|
| Saved CR [low word for m64] 4/8 | |
|
102 |
|
|
|--------------------------------------------| |
|
103 |
|
|
| Current backchain pointer 4/8 |-/ Parent`s frame.
|
104 |
|
|
|--------------------------------------------| <+ <<< on entry to
|
105 |
|
|
| Result Bytes 16/176 | |
|
106 |
|
|
|--------------------------------------------| |
|
107 |
|
|
~ padding to 16-byte alignment ~ ~
|
108 |
|
|
|--------------------------------------------| |
|
109 |
|
|
| NUM_FPR_ARG_REGISTERS slots | |
|
110 |
|
|
| here fp13 .. fp1 13*8 | |
|
111 |
|
|
|--------------------------------------------| |
|
112 |
|
|
| R3..R10 8*4/8=32/64 | | NUM_GPR_ARG_REGISTERS
|
113 |
|
|
|--------------------------------------------| |
|
114 |
|
|
| TOC=R2 (AIX) Reserved (Darwin) 4/8 | |
|
115 |
|
|
|--------------------------------------------| | stack |
|
116 |
|
|
| Reserved [compiler,binder] 2*4/8 | | grows |
|
117 |
|
|
|--------------------------------------------| | down V
|
118 |
|
|
| Space for callees LR 4/8 | |
|
119 |
|
|
|--------------------------------------------| | lower addresses
|
120 |
|
|
| Saved CR [low word for m64] 4/8 | |
|
121 |
|
|
|--------------------------------------------| | stack pointer here
|
122 |
|
|
| Current backchain pointer 4/8 |-/ during
|
123 |
|
|
|--------------------------------------------| <<< call.
|
124 |
|
|
|
125 |
|
|
*/
|
126 |
|
|
|
127 |
|
|
.file "darwin_closure.S"
|
128 |
|
|
|
129 |
|
|
.machine machine_choice
|
130 |
|
|
|
131 |
|
|
.text
|
132 |
|
|
.globl _ffi_closure_ASM
|
133 |
|
|
.align LOG2_GPR_BYTES
|
134 |
|
|
_ffi_closure_ASM:
|
135 |
|
|
LFB1:
|
136 |
|
|
Lstartcode:
|
137 |
|
|
mflr r0 /* extract return address */
|
138 |
|
|
sg r0,SAVED_LR_OFFSET(r1) /* save the return address */
|
139 |
|
|
LCFI0:
|
140 |
|
|
sgu r1,-SAVE_SIZE(r1) /* skip over caller save area
|
141 |
|
|
keep stack aligned to 16. */
|
142 |
|
|
LCFI1:
|
143 |
|
|
/* We want to build up an area for the parameters passed
|
144 |
|
|
in registers. (both floating point and integer) */
|
145 |
|
|
|
146 |
|
|
/* Put gpr 3 to gpr 10 in the parents outgoing area...
|
147 |
|
|
... the remainder of any params that overflowed the regs will
|
148 |
|
|
follow here. */
|
149 |
|
|
sg r3, (PARENT_PARM_BASE )(r1)
|
150 |
|
|
sg r4, (PARENT_PARM_BASE + GPR_BYTES )(r1)
|
151 |
|
|
sg r5, (PARENT_PARM_BASE + GPR_BYTES * 2)(r1)
|
152 |
|
|
sg r6, (PARENT_PARM_BASE + GPR_BYTES * 3)(r1)
|
153 |
|
|
sg r7, (PARENT_PARM_BASE + GPR_BYTES * 4)(r1)
|
154 |
|
|
sg r8, (PARENT_PARM_BASE + GPR_BYTES * 5)(r1)
|
155 |
|
|
sg r9, (PARENT_PARM_BASE + GPR_BYTES * 6)(r1)
|
156 |
|
|
sg r10,(PARENT_PARM_BASE + GPR_BYTES * 7)(r1)
|
157 |
|
|
|
158 |
|
|
/* We save fpr 1 to fpr 14 in our own save frame. */
|
159 |
|
|
stfd f1, (FP_SAVE_BASE )(r1)
|
160 |
|
|
stfd f2, (FP_SAVE_BASE + FPR_SIZE )(r1)
|
161 |
|
|
stfd f3, (FP_SAVE_BASE + FPR_SIZE * 2 )(r1)
|
162 |
|
|
stfd f4, (FP_SAVE_BASE + FPR_SIZE * 3 )(r1)
|
163 |
|
|
stfd f5, (FP_SAVE_BASE + FPR_SIZE * 4 )(r1)
|
164 |
|
|
stfd f6, (FP_SAVE_BASE + FPR_SIZE * 5 )(r1)
|
165 |
|
|
stfd f7, (FP_SAVE_BASE + FPR_SIZE * 6 )(r1)
|
166 |
|
|
stfd f8, (FP_SAVE_BASE + FPR_SIZE * 7 )(r1)
|
167 |
|
|
stfd f9, (FP_SAVE_BASE + FPR_SIZE * 8 )(r1)
|
168 |
|
|
stfd f10,(FP_SAVE_BASE + FPR_SIZE * 9 )(r1)
|
169 |
|
|
stfd f11,(FP_SAVE_BASE + FPR_SIZE * 10)(r1)
|
170 |
|
|
stfd f12,(FP_SAVE_BASE + FPR_SIZE * 11)(r1)
|
171 |
|
|
stfd f13,(FP_SAVE_BASE + FPR_SIZE * 12)(r1)
|
172 |
|
|
|
173 |
|
|
/* Set up registers for the routine that actually does the work
|
174 |
|
|
get the context pointer from the trampoline. */
|
175 |
|
|
mr r3,r11
|
176 |
|
|
|
177 |
|
|
/* Now load up the pointer to the result storage. */
|
178 |
|
|
addi r4,r1,(SAVE_SIZE-RESULT_BYTES)
|
179 |
|
|
|
180 |
|
|
/* Now load up the pointer to the saved gpr registers. */
|
181 |
|
|
addi r5,r1,PARENT_PARM_BASE
|
182 |
|
|
|
183 |
|
|
/* Now load up the pointer to the saved fpr registers. */
|
184 |
|
|
addi r6,r1,FP_SAVE_BASE
|
185 |
|
|
|
186 |
|
|
/* Make the call. */
|
187 |
|
|
bl BLCLS_HELP
|
188 |
|
|
|
189 |
|
|
/* r3 contains the rtype pointer... save it since we will need
|
190 |
|
|
it later. */
|
191 |
|
|
sg r3,LINKAGE_SIZE(r1) ; ffi_type * result_type
|
192 |
|
|
lg r0,0(r3) ; size => r0
|
193 |
|
|
lhz r3,FFI_TYPE_TYPE(r3) ; type => r3
|
194 |
|
|
|
195 |
|
|
/* The helper will have intercepted struture returns and inserted
|
196 |
|
|
the caller`s destination address for structs returned by ref. */
|
197 |
|
|
|
198 |
|
|
/* r3 contains the return type so use it to look up in a table
|
199 |
|
|
so we know how to deal with each type. */
|
200 |
|
|
|
201 |
|
|
addi r5,r1,(SAVE_SIZE-RESULT_BYTES) /* Otherwise, our return is here. */
|
202 |
|
|
bl Lget_ret_type0_addr /* Get pointer to Lret_type0 into LR. */
|
203 |
|
|
mflr r4 /* Move to r4. */
|
204 |
|
|
slwi r3,r3,4 /* Now multiply return type by 16. */
|
205 |
|
|
add r3,r3,r4 /* Add contents of table to table address. */
|
206 |
|
|
mtctr r3
|
207 |
|
|
bctr /* Jump to it. */
|
208 |
|
|
LFE1:
|
209 |
|
|
/* Each of the ret_typeX code fragments has to be exactly 16 bytes long
|
210 |
|
|
(4 instructions). For cache effectiveness we align to a 16 byte boundary
|
211 |
|
|
first. */
|
212 |
|
|
|
213 |
|
|
.align 4
|
214 |
|
|
|
215 |
|
|
nop
|
216 |
|
|
nop
|
217 |
|
|
nop
|
218 |
|
|
Lget_ret_type0_addr:
|
219 |
|
|
blrl
|
220 |
|
|
|
221 |
|
|
/* case FFI_TYPE_VOID */
|
222 |
|
|
Lret_type0:
|
223 |
|
|
b Lfinish
|
224 |
|
|
nop
|
225 |
|
|
nop
|
226 |
|
|
nop
|
227 |
|
|
|
228 |
|
|
/* case FFI_TYPE_INT */
|
229 |
|
|
Lret_type1:
|
230 |
|
|
lg r3,0(r5)
|
231 |
|
|
b Lfinish
|
232 |
|
|
nop
|
233 |
|
|
nop
|
234 |
|
|
|
235 |
|
|
/* case FFI_TYPE_FLOAT */
|
236 |
|
|
Lret_type2:
|
237 |
|
|
lfs f1,0(r5)
|
238 |
|
|
b Lfinish
|
239 |
|
|
nop
|
240 |
|
|
nop
|
241 |
|
|
|
242 |
|
|
/* case FFI_TYPE_DOUBLE */
|
243 |
|
|
Lret_type3:
|
244 |
|
|
lfd f1,0(r5)
|
245 |
|
|
b Lfinish
|
246 |
|
|
nop
|
247 |
|
|
nop
|
248 |
|
|
|
249 |
|
|
/* case FFI_TYPE_LONGDOUBLE */
|
250 |
|
|
Lret_type4:
|
251 |
|
|
lfd f1,0(r5)
|
252 |
|
|
lfd f2,8(r5)
|
253 |
|
|
b Lfinish
|
254 |
|
|
nop
|
255 |
|
|
|
256 |
|
|
/* case FFI_TYPE_UINT8 */
|
257 |
|
|
Lret_type5:
|
258 |
|
|
#if defined(__ppc64__)
|
259 |
|
|
lbz r3,7(r5)
|
260 |
|
|
#else
|
261 |
|
|
lbz r3,3(r5)
|
262 |
|
|
#endif
|
263 |
|
|
b Lfinish
|
264 |
|
|
nop
|
265 |
|
|
nop
|
266 |
|
|
|
267 |
|
|
/* case FFI_TYPE_SINT8 */
|
268 |
|
|
Lret_type6:
|
269 |
|
|
#if defined(__ppc64__)
|
270 |
|
|
lbz r3,7(r5)
|
271 |
|
|
#else
|
272 |
|
|
lbz r3,3(r5)
|
273 |
|
|
#endif
|
274 |
|
|
extsb r3,r3
|
275 |
|
|
b Lfinish
|
276 |
|
|
nop
|
277 |
|
|
|
278 |
|
|
/* case FFI_TYPE_UINT16 */
|
279 |
|
|
Lret_type7:
|
280 |
|
|
#if defined(__ppc64__)
|
281 |
|
|
lhz r3,6(r5)
|
282 |
|
|
#else
|
283 |
|
|
lhz r3,2(r5)
|
284 |
|
|
#endif
|
285 |
|
|
b Lfinish
|
286 |
|
|
nop
|
287 |
|
|
nop
|
288 |
|
|
|
289 |
|
|
/* case FFI_TYPE_SINT16 */
|
290 |
|
|
Lret_type8:
|
291 |
|
|
#if defined(__ppc64__)
|
292 |
|
|
lha r3,6(r5)
|
293 |
|
|
#else
|
294 |
|
|
lha r3,2(r5)
|
295 |
|
|
#endif
|
296 |
|
|
b Lfinish
|
297 |
|
|
nop
|
298 |
|
|
nop
|
299 |
|
|
|
300 |
|
|
/* case FFI_TYPE_UINT32 */
|
301 |
|
|
Lret_type9:
|
302 |
|
|
#if defined(__ppc64__)
|
303 |
|
|
lwz r3,4(r5)
|
304 |
|
|
#else
|
305 |
|
|
lwz r3,0(r5)
|
306 |
|
|
#endif
|
307 |
|
|
b Lfinish
|
308 |
|
|
nop
|
309 |
|
|
nop
|
310 |
|
|
|
311 |
|
|
/* case FFI_TYPE_SINT32 */
|
312 |
|
|
Lret_type10:
|
313 |
|
|
#if defined(__ppc64__)
|
314 |
|
|
lwz r3,4(r5)
|
315 |
|
|
#else
|
316 |
|
|
lwz r3,0(r5)
|
317 |
|
|
#endif
|
318 |
|
|
b Lfinish
|
319 |
|
|
nop
|
320 |
|
|
nop
|
321 |
|
|
|
322 |
|
|
/* case FFI_TYPE_UINT64 */
|
323 |
|
|
Lret_type11:
|
324 |
|
|
#if defined(__ppc64__)
|
325 |
|
|
lg r3,0(r5)
|
326 |
|
|
b Lfinish
|
327 |
|
|
nop
|
328 |
|
|
#else
|
329 |
|
|
lwz r3,0(r5)
|
330 |
|
|
lwz r4,4(r5)
|
331 |
|
|
b Lfinish
|
332 |
|
|
#endif
|
333 |
|
|
nop
|
334 |
|
|
|
335 |
|
|
/* case FFI_TYPE_SINT64 */
|
336 |
|
|
Lret_type12:
|
337 |
|
|
#if defined(__ppc64__)
|
338 |
|
|
lg r3,0(r5)
|
339 |
|
|
b Lfinish
|
340 |
|
|
nop
|
341 |
|
|
#else
|
342 |
|
|
lwz r3,0(r5)
|
343 |
|
|
lwz r4,4(r5)
|
344 |
|
|
b Lfinish
|
345 |
|
|
#endif
|
346 |
|
|
nop
|
347 |
|
|
|
348 |
|
|
/* case FFI_TYPE_STRUCT */
|
349 |
|
|
Lret_type13:
|
350 |
|
|
#if defined(__ppc64__)
|
351 |
|
|
lg r3,0(r5) ; we need at least this...
|
352 |
|
|
cmpi 0,r0,4
|
353 |
|
|
bgt Lstructend ; not a special small case
|
354 |
|
|
b Lsmallstruct ; see if we need more.
|
355 |
|
|
#else
|
356 |
|
|
cmpi 0,r0,4
|
357 |
|
|
bgt Lfinish ; not by value
|
358 |
|
|
lg r3,0(r5)
|
359 |
|
|
b Lfinish
|
360 |
|
|
#endif
|
361 |
|
|
/* case FFI_TYPE_POINTER */
|
362 |
|
|
Lret_type14:
|
363 |
|
|
lg r3,0(r5)
|
364 |
|
|
b Lfinish
|
365 |
|
|
nop
|
366 |
|
|
nop
|
367 |
|
|
|
368 |
|
|
#if defined(__ppc64__)
|
369 |
|
|
Lsmallstruct:
|
370 |
|
|
beq Lfour ; continuation of Lret13.
|
371 |
|
|
cmpi 0,r0,3
|
372 |
|
|
beq Lfinish ; don`t adjust this - can`t be any floats here...
|
373 |
|
|
srdi r3,r3,48
|
374 |
|
|
cmpi 0,r0,2
|
375 |
|
|
beq Lfinish ; .. or here ..
|
376 |
|
|
srdi r3,r3,8
|
377 |
|
|
b Lfinish ; .. or here.
|
378 |
|
|
|
379 |
|
|
Lfour:
|
380 |
|
|
lg r6,LINKAGE_SIZE(r1) ; get the result type
|
381 |
|
|
lg r6,FFI_TYPE_ELEM(r6) ; elements array pointer
|
382 |
|
|
lg r6,0(r6) ; first element
|
383 |
|
|
lhz r0,FFI_TYPE_TYPE(r6) ; OK go the type
|
384 |
|
|
cmpi 0,r0,2 ; FFI_TYPE_FLOAT
|
385 |
|
|
bne Lfourint
|
386 |
|
|
lfs f1,0(r5) ; just one float in the struct.
|
387 |
|
|
b Lfinish
|
388 |
|
|
|
389 |
|
|
Lfourint:
|
390 |
|
|
srdi r3,r3,32 ; four bytes.
|
391 |
|
|
b Lfinish
|
392 |
|
|
|
393 |
|
|
Lstructend:
|
394 |
|
|
lg r3,LINKAGE_SIZE(r1) ; get the result type
|
395 |
|
|
bl STRUCT_RETVALUE_P
|
396 |
|
|
cmpi 0,r3,0
|
397 |
|
|
beq Lfinish ; nope.
|
398 |
|
|
/* Recover a pointer to the results. */
|
399 |
|
|
addi r11,r1,(SAVE_SIZE-RESULT_BYTES)
|
400 |
|
|
lg r3,0(r11) ; we need at least this...
|
401 |
|
|
lg r4,8(r11)
|
402 |
|
|
cmpi 0,r0,16
|
403 |
|
|
beq Lfinish ; special case 16 bytes we don't consider floats.
|
404 |
|
|
|
405 |
|
|
/* OK, frustratingly, the process of saving the struct to mem might have
|
406 |
|
|
messed with the FPRs, so we have to re-load them :(.
|
407 |
|
|
We`ll use our FPRs space again - calling:
|
408 |
|
|
void darwin64_pass_struct_floats (ffi_type *s, char *src,
|
409 |
|
|
unsigned *nfpr, double **fprs)
|
410 |
|
|
We`ll temporarily pinch the first two slots of the param area for local
|
411 |
|
|
vars used by the routine. */
|
412 |
|
|
xor r6,r6,r6
|
413 |
|
|
addi r5,r1,PARENT_PARM_BASE ; some space
|
414 |
|
|
sg r6,0(r5) ; *nfpr zeroed.
|
415 |
|
|
addi r6,r5,8 ; **fprs
|
416 |
|
|
addi r3,r1,FP_SAVE_BASE ; pointer to FPRs space
|
417 |
|
|
sg r3,0(r6)
|
418 |
|
|
mr r4,r11 ; the struct is here...
|
419 |
|
|
lg r3,LINKAGE_SIZE(r1) ; ffi_type * result_type.
|
420 |
|
|
bl PASS_STR_FLOATS ; get struct floats into FPR save space.
|
421 |
|
|
/* See if we used any floats */
|
422 |
|
|
lwz r0,(SAVE_SIZE-RESULT_BYTES)(r1)
|
423 |
|
|
cmpi 0,r0,0
|
424 |
|
|
beq Lstructints ; nope.
|
425 |
|
|
/* OK load `em up... */
|
426 |
|
|
lfd f1, (FP_SAVE_BASE )(r1)
|
427 |
|
|
lfd f2, (FP_SAVE_BASE + FPR_SIZE )(r1)
|
428 |
|
|
lfd f3, (FP_SAVE_BASE + FPR_SIZE * 2 )(r1)
|
429 |
|
|
lfd f4, (FP_SAVE_BASE + FPR_SIZE * 3 )(r1)
|
430 |
|
|
lfd f5, (FP_SAVE_BASE + FPR_SIZE * 4 )(r1)
|
431 |
|
|
lfd f6, (FP_SAVE_BASE + FPR_SIZE * 5 )(r1)
|
432 |
|
|
lfd f7, (FP_SAVE_BASE + FPR_SIZE * 6 )(r1)
|
433 |
|
|
lfd f8, (FP_SAVE_BASE + FPR_SIZE * 7 )(r1)
|
434 |
|
|
lfd f9, (FP_SAVE_BASE + FPR_SIZE * 8 )(r1)
|
435 |
|
|
lfd f10,(FP_SAVE_BASE + FPR_SIZE * 9 )(r1)
|
436 |
|
|
lfd f11,(FP_SAVE_BASE + FPR_SIZE * 10)(r1)
|
437 |
|
|
lfd f12,(FP_SAVE_BASE + FPR_SIZE * 11)(r1)
|
438 |
|
|
lfd f13,(FP_SAVE_BASE + FPR_SIZE * 12)(r1)
|
439 |
|
|
|
440 |
|
|
/* point back at our saved struct. */
|
441 |
|
|
Lstructints:
|
442 |
|
|
addi r11,r1,(SAVE_SIZE-RESULT_BYTES)
|
443 |
|
|
lg r3,0(r11) ; we end up picking the
|
444 |
|
|
lg r4,8(r11) ; first two again.
|
445 |
|
|
lg r5,16(r11)
|
446 |
|
|
lg r6,24(r11)
|
447 |
|
|
lg r7,32(r11)
|
448 |
|
|
lg r8,40(r11)
|
449 |
|
|
lg r9,48(r11)
|
450 |
|
|
lg r10,56(r11)
|
451 |
|
|
#endif
|
452 |
|
|
|
453 |
|
|
/* case done */
|
454 |
|
|
Lfinish:
|
455 |
|
|
addi r1,r1,SAVE_SIZE /* Restore stack pointer. */
|
456 |
|
|
lg r0,SAVED_LR_OFFSET(r1) /* Get return address. */
|
457 |
|
|
mtlr r0 /* Reset link register. */
|
458 |
|
|
blr
|
459 |
|
|
Lendcode:
|
460 |
|
|
.align 1
|
461 |
|
|
|
462 |
|
|
/* END(ffi_closure_ASM) */
|
463 |
|
|
|
464 |
|
|
/* EH frame stuff. */
|
465 |
|
|
#define EH_DATA_ALIGN_FACT MODE_CHOICE(0x7c,0x78)
|
466 |
|
|
/* 176, 400 */
|
467 |
|
|
#define EH_FRAME_OFFSETA MODE_CHOICE(176,0x90)
|
468 |
|
|
#define EH_FRAME_OFFSETB MODE_CHOICE(1,3)
|
469 |
|
|
|
470 |
|
|
.static_data
|
471 |
|
|
.align LOG2_GPR_BYTES
|
472 |
|
|
LLFB1$non_lazy_ptr:
|
473 |
|
|
.g_long Lstartcode
|
474 |
|
|
|
475 |
|
|
.section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support
|
476 |
|
|
EH_frame1:
|
477 |
|
|
.set L$set$0,LECIE1-LSCIE1
|
478 |
|
|
.long L$set$0 ; Length of Common Information Entry
|
479 |
|
|
LSCIE1:
|
480 |
|
|
.long 0x0 ; CIE Identifier Tag
|
481 |
|
|
.byte 0x1 ; CIE Version
|
482 |
|
|
.ascii "zR\0" ; CIE Augmentation
|
483 |
|
|
.byte 0x1 ; uleb128 0x1; CIE Code Alignment Factor
|
484 |
|
|
.byte EH_DATA_ALIGN_FACT ; sleb128 -4; CIE Data Alignment Factor
|
485 |
|
|
.byte 0x41 ; CIE RA Column
|
486 |
|
|
.byte 0x1 ; uleb128 0x1; Augmentation size
|
487 |
|
|
.byte 0x90 ; FDE Encoding (indirect pcrel)
|
488 |
|
|
.byte 0xc ; DW_CFA_def_cfa
|
489 |
|
|
.byte 0x1 ; uleb128 0x1
|
490 |
|
|
.byte 0x0 ; uleb128 0x0
|
491 |
|
|
.align LOG2_GPR_BYTES
|
492 |
|
|
LECIE1:
|
493 |
|
|
.globl _ffi_closure_ASM.eh
|
494 |
|
|
_ffi_closure_ASM.eh:
|
495 |
|
|
LSFDE1:
|
496 |
|
|
.set L$set$1,LEFDE1-LASFDE1
|
497 |
|
|
.long L$set$1 ; FDE Length
|
498 |
|
|
|
499 |
|
|
LASFDE1:
|
500 |
|
|
.long LASFDE1-EH_frame1 ; FDE CIE offset
|
501 |
|
|
.g_long LLFB1$non_lazy_ptr-. ; FDE initial location
|
502 |
|
|
.set L$set$3,LFE1-Lstartcode
|
503 |
|
|
.g_long L$set$3 ; FDE address range
|
504 |
|
|
.byte 0x0 ; uleb128 0x0; Augmentation size
|
505 |
|
|
.byte 0x4 ; DW_CFA_advance_loc4
|
506 |
|
|
.set L$set$3,LCFI1-LCFI0
|
507 |
|
|
.long L$set$3
|
508 |
|
|
.byte 0xe ; DW_CFA_def_cfa_offset
|
509 |
|
|
.byte EH_FRAME_OFFSETA,EH_FRAME_OFFSETB ; uleb128 176,1/190,3
|
510 |
|
|
.byte 0x4 ; DW_CFA_advance_loc4
|
511 |
|
|
.set L$set$4,LCFI0-Lstartcode
|
512 |
|
|
.long L$set$4
|
513 |
|
|
.byte 0x11 ; DW_CFA_offset_extended_sf
|
514 |
|
|
.byte 0x41 ; uleb128 0x41
|
515 |
|
|
.byte 0x7e ; sleb128 -2
|
516 |
|
|
.align LOG2_GPR_BYTES
|
517 |
|
|
LEFDE1:
|
518 |
|
|
.align 1
|
519 |
|
|
|
520 |
|
|
#ifdef WANT_STUB
|
521 |
|
|
.section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32
|
522 |
|
|
.align 5
|
523 |
|
|
L_ffi_closure_helper_DARWIN$stub:
|
524 |
|
|
.indirect_symbol _ffi_closure_helper_DARWIN
|
525 |
|
|
mflr r0
|
526 |
|
|
bcl 20,31,"L00000000001$spb"
|
527 |
|
|
"L00000000001$spb":
|
528 |
|
|
mflr r11
|
529 |
|
|
addis r11,r11,ha16(L_ffi_closure_helper_DARWIN$lazy_ptr-"L00000000001$spb")
|
530 |
|
|
mtlr r0
|
531 |
|
|
lwzu r12,lo16(L_ffi_closure_helper_DARWIN$lazy_ptr-"L00000000001$spb")(r11)
|
532 |
|
|
mtctr r12
|
533 |
|
|
bctr
|
534 |
|
|
.lazy_symbol_pointer
|
535 |
|
|
L_ffi_closure_helper_DARWIN$lazy_ptr:
|
536 |
|
|
.indirect_symbol _ffi_closure_helper_DARWIN
|
537 |
|
|
.g_long dyld_stub_binding_helper
|
538 |
|
|
|
539 |
|
|
#if defined(__ppc64__)
|
540 |
|
|
.section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32
|
541 |
|
|
.align 5
|
542 |
|
|
L_darwin64_struct_ret_by_value_p$stub:
|
543 |
|
|
.indirect_symbol _darwin64_struct_ret_by_value_p
|
544 |
|
|
mflr r0
|
545 |
|
|
bcl 20,31,"L00000000002$spb"
|
546 |
|
|
"L00000000002$spb":
|
547 |
|
|
mflr r11
|
548 |
|
|
addis r11,r11,ha16(L_darwin64_struct_ret_by_value_p$lazy_ptr-"L00000000002$spb")
|
549 |
|
|
mtlr r0
|
550 |
|
|
lwzu r12,lo16(L_darwin64_struct_ret_by_value_p$lazy_ptr-"L00000000002$spb")(r11)
|
551 |
|
|
mtctr r12
|
552 |
|
|
bctr
|
553 |
|
|
.lazy_symbol_pointer
|
554 |
|
|
L_darwin64_struct_ret_by_value_p$lazy_ptr:
|
555 |
|
|
.indirect_symbol _darwin64_struct_ret_by_value_p
|
556 |
|
|
.g_long dyld_stub_binding_helper
|
557 |
|
|
|
558 |
|
|
.section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32
|
559 |
|
|
.align 5
|
560 |
|
|
L_darwin64_pass_struct_floats$stub:
|
561 |
|
|
.indirect_symbol _darwin64_pass_struct_floats
|
562 |
|
|
mflr r0
|
563 |
|
|
bcl 20,31,"L00000000003$spb"
|
564 |
|
|
"L00000000003$spb":
|
565 |
|
|
mflr r11
|
566 |
|
|
addis r11,r11,ha16(L_darwin64_pass_struct_floats$lazy_ptr-"L00000000003$spb")
|
567 |
|
|
mtlr r0
|
568 |
|
|
lwzu r12,lo16(L_darwin64_pass_struct_floats$lazy_ptr-"L00000000003$spb")(r11)
|
569 |
|
|
mtctr r12
|
570 |
|
|
bctr
|
571 |
|
|
.lazy_symbol_pointer
|
572 |
|
|
L_darwin64_pass_struct_floats$lazy_ptr:
|
573 |
|
|
.indirect_symbol _darwin64_pass_struct_floats
|
574 |
|
|
.g_long dyld_stub_binding_helper
|
575 |
|
|
# endif
|
576 |
|
|
#endif
|