OSDN Git Service

b43f9658fceaf65d1853fdcb71a0fefebb6c527f
[pf3gnuchains/gcc-fork.git] / libffi / src / powerpc / darwin_closure.S
1 /* -----------------------------------------------------------------------
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