• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/* -----------------------------------------------------------------------
2   darwin.S - Copyright (c) 1996, 1998, 2001, 2002, 2003, 2005  Red Hat, Inc.
3	Copyright (C) 2008  Free Software Foundation, Inc.
4
5   X86 Foreign Function Interface
6
7   Permission is hereby granted, free of charge, to any person obtaining
8   a copy of this software and associated documentation files (the
9   ``Software''), to deal in the Software without restriction, including
10   without limitation the rights to use, copy, modify, merge, publish,
11   distribute, sublicense, and/or sell copies of the Software, and to
12   permit persons to whom the Software is furnished to do so, subject to
13   the following conditions:
14
15   The above copyright notice and this permission notice shall be included
16   in all copies or substantial portions of the Software.
17
18   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
19   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
21   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
22	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#ifndef __x86_64__
29
30#define LIBFFI_ASM
31#include <fficonfig.h>
32#include <ffi.h>
33
34.text
35
36.globl _ffi_prep_args
37
38	.align 4
39.globl _ffi_call_SYSV
40
41_ffi_call_SYSV:
42.LFB1:
43        pushl %ebp
44.LCFI0:
45        movl  %esp,%ebp
46.LCFI1:
47        subl $8,%esp
48	/* Make room for all of the new args.  */
49	movl  16(%ebp),%ecx
50	subl  %ecx,%esp
51
52	movl  %esp,%eax
53
54	/* Place all of the ffi_prep_args in position  */
55	subl  $8,%esp
56	pushl 12(%ebp)
57	pushl %eax
58	call  *8(%ebp)
59
60	/* Return stack to previous state and call the function  */
61	addl  $16,%esp
62
63	call  *28(%ebp)
64
65	/* Load %ecx with the return type code  */
66	movl  20(%ebp),%ecx
67
68	/* Protect %esi.  We're going to pop it in the epilogue.  */
69	pushl %esi
70
71	/* If the return value pointer is NULL, assume no return value.  */
72	cmpl  $0,24(%ebp)
73	jne  0f
74
75	/* Even if there is no space for the return value, we are
76	   obliged to handle floating-point values.  */
77	cmpl  $FFI_TYPE_FLOAT,%ecx
78	jne   noretval
79	fstp  %st(0)
80
81	jmp   epilogue
820:
83	.align 4
84	call 1f
85.Lstore_table:
86	.long   noretval-.Lstore_table		/* FFI_TYPE_VOID */
87	.long   retint-.Lstore_table		/* FFI_TYPE_INT */
88	.long   retfloat-.Lstore_table		/* FFI_TYPE_FLOAT */
89	.long   retdouble-.Lstore_table		/* FFI_TYPE_DOUBLE */
90	.long   retlongdouble-.Lstore_table     /* FFI_TYPE_LONGDOUBLE */
91	.long   retuint8-.Lstore_table		/* FFI_TYPE_UINT8 */
92	.long   retsint8-.Lstore_table		/* FFI_TYPE_SINT8 */
93	.long   retuint16-.Lstore_table		/* FFI_TYPE_UINT16 */
94	.long   retsint16-.Lstore_table		/* FFI_TYPE_SINT16 */
95	.long   retint-.Lstore_table		/* FFI_TYPE_UINT32 */
96	.long   retint-.Lstore_table		/* FFI_TYPE_SINT32 */
97	.long   retint64-.Lstore_table		/* FFI_TYPE_UINT64 */
98	.long   retint64-.Lstore_table		/* FFI_TYPE_SINT64 */
99	.long   retstruct-.Lstore_table		/* FFI_TYPE_STRUCT */
100	.long   retint-.Lstore_table		/* FFI_TYPE_POINTER */
101	.long   retstruct1b-.Lstore_table	/* FFI_TYPE_SMALL_STRUCT_1B */
102	.long   retstruct2b-.Lstore_table	/* FFI_TYPE_SMALL_STRUCT_2B */
1031:
104	pop  %esi
105	add  (%esi, %ecx, 4), %esi
106	jmp  *%esi
107
108	/* Sign/zero extend as appropriate.  */
109retsint8:
110	movsbl  %al, %eax
111	jmp  retint
112
113retsint16:
114	movswl  %ax, %eax
115	jmp  retint
116
117retuint8:
118	movzbl  %al, %eax
119	jmp  retint
120
121retuint16:
122	movzwl  %ax, %eax
123	jmp  retint
124
125retfloat:
126	/* Load %ecx with the pointer to storage for the return value  */
127	movl  24(%ebp),%ecx
128	fstps (%ecx)
129	jmp   epilogue
130
131retdouble:
132	/* Load %ecx with the pointer to storage for the return value  */
133	movl  24(%ebp),%ecx
134	fstpl (%ecx)
135	jmp   epilogue
136
137retlongdouble:
138	/* Load %ecx with the pointer to storage for the return value  */
139	movl  24(%ebp),%ecx
140	fstpt (%ecx)
141	jmp   epilogue
142
143retint64:
144	/* Load %ecx with the pointer to storage for the return value  */
145	movl  24(%ebp),%ecx
146	movl  %eax,0(%ecx)
147	movl  %edx,4(%ecx)
148	jmp   epilogue
149
150retstruct1b:
151	/* Load %ecx with the pointer to storage for the return value  */
152	movl  24(%ebp),%ecx
153	movb  %al,0(%ecx)
154	jmp   epilogue
155
156retstruct2b:
157	/* Load %ecx with the pointer to storage for the return value  */
158	movl  24(%ebp),%ecx
159	movw  %ax,0(%ecx)
160	jmp   epilogue
161
162retint:
163	/* Load %ecx with the pointer to storage for the return value  */
164	movl  24(%ebp),%ecx
165	movl  %eax,0(%ecx)
166
167retstruct:
168	/* Nothing to do!  */
169
170noretval:
171epilogue:
172	popl %esi
173	movl %ebp,%esp
174	popl %ebp
175	ret
176
177.LFE1:
178.ffi_call_SYSV_end:
179
180	.align	4
181FFI_HIDDEN (ffi_closure_SYSV)
182.globl _ffi_closure_SYSV
183
184_ffi_closure_SYSV:
185.LFB2:
186	pushl	%ebp
187.LCFI2:
188	movl	%esp, %ebp
189.LCFI3:
190	subl	$40, %esp
191	leal	-24(%ebp), %edx
192	movl	%edx, -12(%ebp)	/* resp */
193	leal	8(%ebp), %edx
194	movl	%edx, 4(%esp)	/* args = __builtin_dwarf_cfa () */
195	leal	-12(%ebp), %edx
196	movl	%edx, (%esp)	/* &resp */
197	movl	%ebx, 8(%esp)
198.LCFI7:
199	call	L_ffi_closure_SYSV_inner$stub
200	movl	8(%esp), %ebx
201	movl	-12(%ebp), %ecx
202	cmpl	$FFI_TYPE_INT, %eax
203	je	.Lcls_retint
204
205	/* Handle FFI_TYPE_UINT8, FFI_TYPE_SINT8, FFI_TYPE_UINT16,
206	   FFI_TYPE_SINT16, FFI_TYPE_UINT32, FFI_TYPE_SINT32.  */
207	cmpl	$FFI_TYPE_UINT64, %eax
208	jge	0f
209	cmpl	$FFI_TYPE_UINT8, %eax
210	jge	.Lcls_retint
211
2120:	cmpl	$FFI_TYPE_FLOAT, %eax
213	je	.Lcls_retfloat
214	cmpl	$FFI_TYPE_DOUBLE, %eax
215	je	.Lcls_retdouble
216	cmpl	$FFI_TYPE_LONGDOUBLE, %eax
217	je	.Lcls_retldouble
218	cmpl	$FFI_TYPE_SINT64, %eax
219	je	.Lcls_retllong
220	cmpl	$FFI_TYPE_SMALL_STRUCT_1B, %eax
221	je	.Lcls_retstruct1b
222	cmpl	$FFI_TYPE_SMALL_STRUCT_2B, %eax
223	je	.Lcls_retstruct2b
224	cmpl	$FFI_TYPE_STRUCT, %eax
225	je	.Lcls_retstruct
226.Lcls_epilogue:
227	movl	%ebp, %esp
228	popl	%ebp
229	ret
230.Lcls_retint:
231	movl	(%ecx), %eax
232	jmp	.Lcls_epilogue
233.Lcls_retfloat:
234	flds	(%ecx)
235	jmp	.Lcls_epilogue
236.Lcls_retdouble:
237	fldl	(%ecx)
238	jmp	.Lcls_epilogue
239.Lcls_retldouble:
240	fldt	(%ecx)
241	jmp	.Lcls_epilogue
242.Lcls_retllong:
243	movl	(%ecx), %eax
244	movl	4(%ecx), %edx
245	jmp	.Lcls_epilogue
246.Lcls_retstruct1b:
247	movsbl	(%ecx), %eax
248	jmp	.Lcls_epilogue
249.Lcls_retstruct2b:
250	movswl	(%ecx), %eax
251	jmp	.Lcls_epilogue
252.Lcls_retstruct:
253	lea -8(%ebp),%esp
254	movl	%ebp, %esp
255	popl	%ebp
256	ret $4
257.LFE2:
258
259#if !FFI_NO_RAW_API
260
261#define RAW_CLOSURE_CIF_OFFSET ((FFI_TRAMPOLINE_SIZE + 3) & ~3)
262#define RAW_CLOSURE_FUN_OFFSET (RAW_CLOSURE_CIF_OFFSET + 4)
263#define RAW_CLOSURE_USER_DATA_OFFSET (RAW_CLOSURE_FUN_OFFSET + 4)
264#define CIF_FLAGS_OFFSET 20
265
266	.align	4
267FFI_HIDDEN (ffi_closure_raw_SYSV)
268.globl _ffi_closure_raw_SYSV
269
270_ffi_closure_raw_SYSV:
271.LFB3:
272	pushl	%ebp
273.LCFI4:
274	movl	%esp, %ebp
275.LCFI5:
276	pushl	%esi
277.LCFI6:
278	subl	$36, %esp
279	movl	RAW_CLOSURE_CIF_OFFSET(%eax), %esi	 /* closure->cif */
280	movl	RAW_CLOSURE_USER_DATA_OFFSET(%eax), %edx /* closure->user_data */
281	movl	%edx, 12(%esp)	/* user_data */
282	leal	8(%ebp), %edx	/* __builtin_dwarf_cfa () */
283	movl	%edx, 8(%esp)	/* raw_args */
284	leal	-24(%ebp), %edx
285	movl	%edx, 4(%esp)	/* &res */
286	movl	%esi, (%esp)	/* cif */
287	call	*RAW_CLOSURE_FUN_OFFSET(%eax)		 /* closure->fun */
288	movl	CIF_FLAGS_OFFSET(%esi), %eax		 /* rtype */
289	cmpl	$FFI_TYPE_INT, %eax
290	je	.Lrcls_retint
291
292	/* Handle FFI_TYPE_UINT8, FFI_TYPE_SINT8, FFI_TYPE_UINT16,
293	   FFI_TYPE_SINT16, FFI_TYPE_UINT32, FFI_TYPE_SINT32.  */
294	cmpl	$FFI_TYPE_UINT64, %eax
295	jge	0f
296	cmpl	$FFI_TYPE_UINT8, %eax
297	jge	.Lrcls_retint
2980:
299	cmpl	$FFI_TYPE_FLOAT, %eax
300	je	.Lrcls_retfloat
301	cmpl	$FFI_TYPE_DOUBLE, %eax
302	je	.Lrcls_retdouble
303	cmpl	$FFI_TYPE_LONGDOUBLE, %eax
304	je	.Lrcls_retldouble
305	cmpl	$FFI_TYPE_SINT64, %eax
306	je	.Lrcls_retllong
307.Lrcls_epilogue:
308	addl	$36, %esp
309	popl	%esi
310	popl	%ebp
311	ret
312.Lrcls_retint:
313	movl	-24(%ebp), %eax
314	jmp	.Lrcls_epilogue
315.Lrcls_retfloat:
316	flds	-24(%ebp)
317	jmp	.Lrcls_epilogue
318.Lrcls_retdouble:
319	fldl	-24(%ebp)
320	jmp	.Lrcls_epilogue
321.Lrcls_retldouble:
322	fldt	-24(%ebp)
323	jmp	.Lrcls_epilogue
324.Lrcls_retllong:
325	movl	-24(%ebp), %eax
326	movl	-20(%ebp), %edx
327	jmp	.Lrcls_epilogue
328.LFE3:
329#endif
330
331.section __IMPORT,__jump_table,symbol_stubs,self_modifying_code+pure_instructions,5
332L_ffi_closure_SYSV_inner$stub:
333	.indirect_symbol _ffi_closure_SYSV_inner
334	hlt ; hlt ; hlt ; hlt ; hlt
335
336
337.section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support
338EH_frame1:
339	.set	L$set$0,LECIE1-LSCIE1
340	.long	L$set$0
341LSCIE1:
342	.long	0x0
343	.byte	0x1
344	.ascii "zR\0"
345	.byte	0x1
346	.byte	0x7c
347	.byte	0x8
348	.byte	0x1
349	.byte	0x10
350	.byte	0xc
351	.byte	0x5
352	.byte	0x4
353	.byte	0x88
354	.byte	0x1
355	.align 2
356LECIE1:
357.globl _ffi_call_SYSV.eh
358_ffi_call_SYSV.eh:
359LSFDE1:
360	.set	L$set$1,LEFDE1-LASFDE1
361	.long	L$set$1
362LASFDE1:
363	.long	LASFDE1-EH_frame1
364	.long	.LFB1-.
365	.set L$set$2,.LFE1-.LFB1
366	.long L$set$2
367	.byte	0x0
368	.byte	0x4
369	.set L$set$3,.LCFI0-.LFB1
370	.long L$set$3
371	.byte	0xe
372	.byte	0x8
373	.byte	0x84
374	.byte	0x2
375	.byte	0x4
376	.set L$set$4,.LCFI1-.LCFI0
377	.long L$set$4
378	.byte	0xd
379	.byte	0x4
380	.align 2
381LEFDE1:
382.globl _ffi_closure_SYSV.eh
383_ffi_closure_SYSV.eh:
384LSFDE2:
385	.set	L$set$5,LEFDE2-LASFDE2
386	.long	L$set$5
387LASFDE2:
388	.long	LASFDE2-EH_frame1
389	.long	.LFB2-.
390	.set L$set$6,.LFE2-.LFB2
391	.long L$set$6
392	.byte	0x0
393	.byte	0x4
394	.set L$set$7,.LCFI2-.LFB2
395	.long L$set$7
396	.byte	0xe
397	.byte	0x8
398	.byte	0x84
399	.byte	0x2
400	.byte	0x4
401	.set L$set$8,.LCFI3-.LCFI2
402	.long L$set$8
403	.byte	0xd
404	.byte	0x4
405	.align 2
406LEFDE2:
407
408#if !FFI_NO_RAW_API
409
410.globl _ffi_closure_raw_SYSV.eh
411_ffi_closure_raw_SYSV.eh:
412LSFDE3:
413	.set	L$set$10,LEFDE3-LASFDE3
414	.long	L$set$10
415LASFDE3:
416	.long	LASFDE3-EH_frame1
417	.long	.LFB3-.
418	.set L$set$11,.LFE3-.LFB3
419	.long L$set$11
420	.byte	0x0
421	.byte	0x4
422	.set L$set$12,.LCFI4-.LFB3
423	.long L$set$12
424	.byte	0xe
425	.byte	0x8
426	.byte	0x84
427	.byte	0x2
428	.byte	0x4
429	.set L$set$13,.LCFI5-.LCFI4
430	.long L$set$13
431	.byte	0xd
432	.byte	0x4
433	.byte	0x4
434	.set L$set$14,.LCFI6-.LCFI5
435	.long L$set$14
436	.byte	0x85
437	.byte	0x3
438	.align 2
439LEFDE3:
440
441#endif
442
443#endif /* ifndef __x86_64__ */
444