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:
135LFB1:
136Lstartcode:
137	mflr	r0			/* extract return address  */
138	sg	r0,SAVED_LR_OFFSET(r1)	/* save the return address  */
139LCFI0:
140	sgu	r1,-SAVE_SIZE(r1)	/* skip over caller save area
141					keep stack aligned to 16.  */
142LCFI1:
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 structure 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.  */
208LFE1:
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
218Lget_ret_type0_addr:
219	blrl
220
221/* case FFI_TYPE_VOID  */
222Lret_type0:
223	b	Lfinish
224	nop
225	nop
226	nop
227
228/* case FFI_TYPE_INT  */
229Lret_type1:
230	lg	r3,0(r5)
231	b	Lfinish
232	nop
233	nop
234
235/* case FFI_TYPE_FLOAT  */
236Lret_type2:
237	lfs	f1,0(r5)
238	b	Lfinish
239	nop
240	nop
241
242/* case FFI_TYPE_DOUBLE  */
243Lret_type3:
244	lfd	f1,0(r5)
245	b	Lfinish
246	nop
247	nop
248
249/* case FFI_TYPE_LONGDOUBLE  */
250Lret_type4:
251	lfd	f1,0(r5)
252	lfd	f2,8(r5)
253	b	Lfinish
254	nop
255
256/* case FFI_TYPE_UINT8  */
257Lret_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  */
268Lret_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  */
279Lret_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  */
290Lret_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  */
301Lret_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  */
312Lret_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  */
323Lret_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  */
336Lret_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  */
349Lret_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  */
362Lret_type14:
363	lg	r3,0(r5)
364	b	Lfinish
365	nop
366	nop
367
368#if defined(__ppc64__)
369Lsmallstruct:
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
379Lfour:
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
389Lfourint:
390	srdi	r3,r3,32		; four bytes.
391	b 	Lfinish
392
393Lstructend:
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.  */
441Lstructints:
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  */
454Lfinish:
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
459Lendcode:
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	.section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support
471EH_frame1:
472	.set	L$set$0,LECIE1-LSCIE1
473	.long	L$set$0	; Length of Common Information Entry
474LSCIE1:
475	.long	0x0	; CIE Identifier Tag
476	.byte	0x1	; CIE Version
477	.ascii	"zR\0"	; CIE Augmentation
478	.byte	0x1	; uleb128 0x1; CIE Code Alignment Factor
479	.byte	EH_DATA_ALIGN_FACT ; sleb128 -4; CIE Data Alignment Factor
480	.byte	0x41	; CIE RA Column
481	.byte	0x1	; uleb128 0x1; Augmentation size
482	.byte	0x10	; FDE Encoding (pcrel)
483	.byte	0xc	; DW_CFA_def_cfa
484	.byte	0x1	; uleb128 0x1
485	.byte	0x0	; uleb128 0x0
486	.align	LOG2_GPR_BYTES
487LECIE1:
488	.globl _ffi_closure_ASM.eh
489_ffi_closure_ASM.eh:
490LSFDE1:
491	.set	L$set$1,LEFDE1-LASFDE1
492	.long	L$set$1	; FDE Length
493
494LASFDE1:
495	.long	LASFDE1-EH_frame1	; FDE CIE offset
496	.g_long	Lstartcode-.	; FDE initial location
497	.set	L$set$3,LFE1-Lstartcode
498	.g_long	L$set$3	; FDE address range
499	.byte   0x0     ; uleb128 0x0; Augmentation size
500	.byte	0x4	; DW_CFA_advance_loc4
501	.set	L$set$3,LCFI1-LCFI0
502	.long	L$set$3
503	.byte	0xe	; DW_CFA_def_cfa_offset
504	.byte	EH_FRAME_OFFSETA,EH_FRAME_OFFSETB	; uleb128 176,1/190,3
505	.byte	0x4	; DW_CFA_advance_loc4
506	.set	L$set$4,LCFI0-Lstartcode
507	.long	L$set$4
508	.byte   0x11    ; DW_CFA_offset_extended_sf
509	.byte	0x41	; uleb128 0x41
510	.byte   0x7e    ; sleb128 -2
511	.align	LOG2_GPR_BYTES
512LEFDE1:
513	.align 	1
514
515#ifdef WANT_STUB
516	.section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32
517	.align 5
518L_ffi_closure_helper_DARWIN$stub:
519	.indirect_symbol _ffi_closure_helper_DARWIN
520	mflr r0
521	bcl 20,31,"L1$spb"
522"L1$spb":
523	mflr r11
524	addis r11,r11,ha16(L_ffi_closure_helper_DARWIN$lazy_ptr-"L1$spb")
525	mtlr r0
526	lwzu r12,lo16(L_ffi_closure_helper_DARWIN$lazy_ptr-"L1$spb")(r11)
527	mtctr r12
528	bctr
529	.lazy_symbol_pointer
530L_ffi_closure_helper_DARWIN$lazy_ptr:
531	.indirect_symbol _ffi_closure_helper_DARWIN
532	.g_long	dyld_stub_binding_helper
533
534#if defined(__ppc64__)
535	.section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32
536	.align 5
537L_darwin64_struct_ret_by_value_p$stub:
538	.indirect_symbol _darwin64_struct_ret_by_value_p
539	mflr r0
540	bcl 20,31,"L2$spb"
541"L2$spb":
542	mflr r11
543	addis r11,r11,ha16(L_darwin64_struct_ret_by_value_p$lazy_ptr-"L2$spb")
544	mtlr r0
545	lwzu r12,lo16(L_darwin64_struct_ret_by_value_p$lazy_ptr-"L2$spb")(r11)
546	mtctr r12
547	bctr
548	.lazy_symbol_pointer
549L_darwin64_struct_ret_by_value_p$lazy_ptr:
550	.indirect_symbol _darwin64_struct_ret_by_value_p
551	.g_long	dyld_stub_binding_helper
552
553	.section __TEXT,__picsymbolstub1,symbol_stubs,pure_instructions,32
554	.align 5
555L_darwin64_pass_struct_floats$stub:
556	.indirect_symbol _darwin64_pass_struct_floats
557	mflr r0
558	bcl 20,31,"L3$spb"
559"L3$spb":
560	mflr r11
561	addis r11,r11,ha16(L_darwin64_pass_struct_floats$lazy_ptr-"L3$spb")
562	mtlr r0
563	lwzu r12,lo16(L_darwin64_pass_struct_floats$lazy_ptr-"L3$spb")(r11)
564	mtctr r12
565	bctr
566	.lazy_symbol_pointer
567L_darwin64_pass_struct_floats$lazy_ptr:
568	.indirect_symbol _darwin64_pass_struct_floats
569	.g_long	dyld_stub_binding_helper
570#  endif
571#endif
572