1#ifdef __i386__
2/* -----------------------------------------------------------------------
3   darwin.S - Copyright (c) 1996, 1998, 2001, 2002, 2003  Red Hat, 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 CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
22   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
23   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
24   OTHER DEALINGS IN THE SOFTWARE.
25   ----------------------------------------------------------------------- */
26
27/*
28 * This file is based on sysv.S and then hacked up by Ronald who hasn't done
29 * assembly programming in 8 years.
30 */
31
32#ifndef __x86_64__
33
34#define LIBFFI_ASM
35#include <fficonfig.h>
36#include <ffi.h>
37
38#ifdef PyObjC_STRICT_DEBUGGING
39  /* XXX: Debugging of stack alignment, to be removed */
40#define ASSERT_STACK_ALIGNED movdqa -16(%esp), %xmm0
41#else
42#define ASSERT_STACK_ALIGNED
43#endif
44
45.text
46
47.globl _ffi_prep_args
48
49	.align 4
50.globl _ffi_call_SYSV
51
52_ffi_call_SYSV:
53LFB1:
54        pushl %ebp
55LCFI0:
56        movl  %esp,%ebp
57LCFI1:
58        subl $8,%esp
59	/* Make room for all of the new args.  */
60	movl  16(%ebp),%ecx
61	subl  %ecx,%esp
62
63	movl  %esp,%eax
64
65	/* Place all of the ffi_prep_args in position  */
66	subl  $8,%esp
67	pushl 12(%ebp)
68	pushl %eax
69	call  *8(%ebp)
70
71	/* Return stack to previous state and call the function  */
72	addl  $16,%esp
73
74	call  *28(%ebp)
75
76	/* Remove the space we pushed for the args  */
77	movl  16(%ebp),%ecx
78	addl  %ecx,%esp
79
80	/* Load %ecx with the return type code  */
81	movl  20(%ebp),%ecx
82
83	/* If the return value pointer is NULL, assume no return value.  */
84	cmpl  $0,24(%ebp)
85	jne   Lretint
86
87	/* Even if there is no space for the return value, we are
88	   obliged to handle floating-point values.  */
89	cmpl  $FFI_TYPE_FLOAT,%ecx
90	jne   Lnoretval
91	fstp  %st(0)
92
93    jmp   Lepilogue
94
95Lretint:
96	cmpl  $FFI_TYPE_INT,%ecx
97	jne   Lretfloat
98	/* Load %ecx with the pointer to storage for the return value  */
99	movl  24(%ebp),%ecx
100	movl  %eax,0(%ecx)
101	jmp   Lepilogue
102
103Lretfloat:
104	cmpl  $FFI_TYPE_FLOAT,%ecx
105	jne   Lretdouble
106	/* Load %ecx with the pointer to storage for the return value  */
107	movl  24(%ebp),%ecx
108	fstps (%ecx)
109	jmp   Lepilogue
110
111Lretdouble:
112	cmpl  $FFI_TYPE_DOUBLE,%ecx
113	jne   Lretlongdouble
114	/* Load %ecx with the pointer to storage for the return value  */
115	movl  24(%ebp),%ecx
116	fstpl (%ecx)
117	jmp   Lepilogue
118
119Lretlongdouble:
120	cmpl  $FFI_TYPE_LONGDOUBLE,%ecx
121	jne   Lretint64
122	/* Load %ecx with the pointer to storage for the return value  */
123	movl  24(%ebp),%ecx
124	fstpt (%ecx)
125	jmp   Lepilogue
126
127Lretint64:
128	cmpl  $FFI_TYPE_SINT64,%ecx
129    jne   Lretstruct1b
130	/* Load %ecx with the pointer to storage for the return value  */
131	movl  24(%ebp),%ecx
132	movl  %eax,0(%ecx)
133	movl  %edx,4(%ecx)
134	jmp   Lepilogue
135
136Lretstruct1b:
137	cmpl  $FFI_TYPE_SINT8,%ecx
138    jne   Lretstruct2b
139	/* Load %ecx with the pointer to storage for the return value  */
140	movl  24(%ebp),%ecx
141	movb  %al,0(%ecx)
142	jmp   Lepilogue
143
144Lretstruct2b:
145	cmpl  $FFI_TYPE_SINT16,%ecx
146    jne   Lretstruct
147	/* Load %ecx with the pointer to storage for the return value  */
148	movl  24(%ebp),%ecx
149	movw  %ax,0(%ecx)
150	jmp   Lepilogue
151
152Lretstruct:
153	cmpl  $FFI_TYPE_STRUCT,%ecx
154     jne   Lnoretval
155	/* Nothing to do!  */
156    addl $4,%esp
157    popl %ebp
158    ret
159
160Lnoretval:
161Lepilogue:
162        addl $8,%esp
163        movl %ebp,%esp
164        popl %ebp
165        ret
166LFE1:
167.ffi_call_SYSV_end:
168
169	.align	4
170FFI_HIDDEN (ffi_closure_SYSV)
171.globl _ffi_closure_SYSV
172
173_ffi_closure_SYSV:
174LFB2:
175	pushl	%ebp
176LCFI2:
177	movl	%esp, %ebp
178LCFI3:
179	subl	$56, %esp
180	leal	-40(%ebp), %edx
181	movl	%edx, -12(%ebp)	/* resp */
182	leal	8(%ebp), %edx
183	movl	%edx, 4(%esp)	/* args = __builtin_dwarf_cfa () */
184	leal	-12(%ebp), %edx
185	movl	%edx, (%esp)	/* &resp */
186	movl	%ebx, 8(%esp)
187LCFI7:
188	call	L_ffi_closure_SYSV_inner$stub
189	movl	8(%esp), %ebx
190	movl	-12(%ebp), %ecx
191	cmpl	$FFI_TYPE_INT, %eax
192	je	Lcls_retint
193	cmpl	$FFI_TYPE_FLOAT, %eax
194	je	Lcls_retfloat
195	cmpl	$FFI_TYPE_DOUBLE, %eax
196	je	Lcls_retdouble
197	cmpl	$FFI_TYPE_LONGDOUBLE, %eax
198	je	Lcls_retldouble
199	cmpl	$FFI_TYPE_SINT64, %eax
200	je	Lcls_retllong
201	cmpl	$FFI_TYPE_UINT8, %eax
202	je	Lcls_retstruct1
203	cmpl	$FFI_TYPE_SINT8, %eax
204	je	Lcls_retstruct1
205	cmpl	$FFI_TYPE_UINT16, %eax
206	je	Lcls_retstruct2
207	cmpl	$FFI_TYPE_SINT16, %eax
208	je	Lcls_retstruct2
209	cmpl	$FFI_TYPE_STRUCT, %eax
210	je	Lcls_retstruct
211Lcls_epilogue:
212	movl	%ebp, %esp
213	popl	%ebp
214	ret
215Lcls_retint:
216	movl	(%ecx), %eax
217	jmp	Lcls_epilogue
218Lcls_retfloat:
219	flds	(%ecx)
220	jmp	Lcls_epilogue
221Lcls_retdouble:
222	fldl	(%ecx)
223	jmp	Lcls_epilogue
224Lcls_retldouble:
225	fldt	(%ecx)
226	jmp	Lcls_epilogue
227Lcls_retllong:
228	movl	(%ecx), %eax
229	movl	4(%ecx), %edx
230	jmp	Lcls_epilogue
231Lcls_retstruct1:
232	movsbl	(%ecx), %eax
233	jmp	Lcls_epilogue
234Lcls_retstruct2:
235	movswl	(%ecx), %eax
236	jmp	Lcls_epilogue
237Lcls_retstruct:
238	lea -8(%ebp),%esp
239	movl	%ebp, %esp
240	popl	%ebp
241	ret $4
242LFE2:
243
244#if !FFI_NO_RAW_API
245
246#define RAW_CLOSURE_CIF_OFFSET ((FFI_TRAMPOLINE_SIZE + 3) & ~3)
247#define RAW_CLOSURE_FUN_OFFSET (RAW_CLOSURE_CIF_OFFSET + 4)
248#define RAW_CLOSURE_USER_DATA_OFFSET (RAW_CLOSURE_FUN_OFFSET + 4)
249#define CIF_FLAGS_OFFSET 20
250
251	.align	4
252FFI_HIDDEN (ffi_closure_raw_SYSV)
253.globl _ffi_closure_raw_SYSV
254
255_ffi_closure_raw_SYSV:
256LFB3:
257	pushl	%ebp
258LCFI4:
259	movl	%esp, %ebp
260LCFI5:
261	pushl	%esi
262LCFI6:
263	subl	$36, %esp
264	movl	RAW_CLOSURE_CIF_OFFSET(%eax), %esi	 /* closure->cif */
265	movl	RAW_CLOSURE_USER_DATA_OFFSET(%eax), %edx /* closure->user_data */
266	movl	%edx, 12(%esp)	/* user_data */
267	leal	8(%ebp), %edx	/* __builtin_dwarf_cfa () */
268	movl	%edx, 8(%esp)	/* raw_args */
269	leal	-24(%ebp), %edx
270	movl	%edx, 4(%esp)	/* &res */
271	movl	%esi, (%esp)	/* cif */
272	call	*RAW_CLOSURE_FUN_OFFSET(%eax)		 /* closure->fun */
273	movl	CIF_FLAGS_OFFSET(%esi), %eax		 /* rtype */
274	cmpl	$FFI_TYPE_INT, %eax
275	je	Lrcls_retint
276	cmpl	$FFI_TYPE_FLOAT, %eax
277	je	Lrcls_retfloat
278	cmpl	$FFI_TYPE_DOUBLE, %eax
279	je	Lrcls_retdouble
280	cmpl	$FFI_TYPE_LONGDOUBLE, %eax
281	je	Lrcls_retldouble
282	cmpl	$FFI_TYPE_SINT64, %eax
283	je	Lrcls_retllong
284Lrcls_epilogue:
285	addl	$36, %esp
286	popl	%esi
287	popl	%ebp
288	ret
289Lrcls_retint:
290	movl	-24(%ebp), %eax
291	jmp	Lrcls_epilogue
292Lrcls_retfloat:
293	flds	-24(%ebp)
294	jmp	Lrcls_epilogue
295Lrcls_retdouble:
296	fldl	-24(%ebp)
297	jmp	Lrcls_epilogue
298Lrcls_retldouble:
299	fldt	-24(%ebp)
300	jmp	Lrcls_epilogue
301Lrcls_retllong:
302	movl	-24(%ebp), %eax
303	movl	-20(%ebp), %edx
304	jmp	Lrcls_epilogue
305LFE3:
306#endif
307
308.section __IMPORT,__jump_table,symbol_stubs,self_modifying_code+pure_instructions,5
309L_ffi_closure_SYSV_inner$stub:
310	.indirect_symbol _ffi_closure_SYSV_inner
311	hlt ; hlt ; hlt ; hlt ; hlt
312
313
314.section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support
315EH_frame1:
316	.set	L$set$0,LECIE1-LSCIE1
317	.long	L$set$0
318LSCIE1:
319	.long	0x0
320	.byte	0x1
321	.ascii "zR\0"
322	.byte	0x1
323	.byte	0x7c
324	.byte	0x8
325	.byte	0x1
326	.byte	0x10
327	.byte	0xc
328	.byte	0x5
329	.byte	0x4
330	.byte	0x88
331	.byte	0x1
332	.align 2
333LECIE1:
334.globl _ffi_call_SYSV.eh
335_ffi_call_SYSV.eh:
336LSFDE1:
337	.set	L$set$1,LEFDE1-LASFDE1
338	.long	L$set$1
339LASFDE1:
340	.long	LASFDE1-EH_frame1
341	.long	LFB1-.
342	.set L$set$2,LFE1-LFB1
343	.long L$set$2
344	.byte	0x0
345	.byte	0x4
346	.set L$set$3,LCFI0-LFB1
347	.long L$set$3
348	.byte	0xe
349	.byte	0x8
350	.byte	0x84
351	.byte	0x2
352	.byte	0x4
353	.set L$set$4,LCFI1-LCFI0
354	.long L$set$4
355	.byte	0xd
356	.byte	0x4
357	.align 2
358LEFDE1:
359.globl _ffi_closure_SYSV.eh
360_ffi_closure_SYSV.eh:
361LSFDE2:
362	.set	L$set$5,LEFDE2-LASFDE2
363	.long	L$set$5
364LASFDE2:
365	.long	LASFDE2-EH_frame1
366	.long	LFB2-.
367	.set L$set$6,LFE2-LFB2
368	.long L$set$6
369	.byte	0x0
370	.byte	0x4
371	.set L$set$7,LCFI2-LFB2
372	.long L$set$7
373	.byte	0xe
374	.byte	0x8
375	.byte	0x84
376	.byte	0x2
377	.byte	0x4
378	.set L$set$8,LCFI3-LCFI2
379	.long L$set$8
380	.byte	0xd
381	.byte	0x4
382	.align 2
383LEFDE2:
384
385#if !FFI_NO_RAW_API
386
387.globl _ffi_closure_raw_SYSV.eh
388_ffi_closure_raw_SYSV.eh:
389LSFDE3:
390	.set	L$set$10,LEFDE3-LASFDE3
391	.long	L$set$10
392LASFDE3:
393	.long	LASFDE3-EH_frame1
394	.long	LFB3-.
395	.set L$set$11,LFE3-LFB3
396	.long L$set$11
397	.byte	0x0
398	.byte	0x4
399	.set L$set$12,LCFI4-LFB3
400	.long L$set$12
401	.byte	0xe
402	.byte	0x8
403	.byte	0x84
404	.byte	0x2
405	.byte	0x4
406	.set L$set$13,LCFI5-LCFI4
407	.long L$set$13
408	.byte	0xd
409	.byte	0x4
410	.byte	0x4
411	.set L$set$14,LCFI6-LCFI5
412	.long L$set$14
413	.byte	0x85
414	.byte	0x3
415	.align 2
416LEFDE3:
417
418#endif
419
420#endif /* ifndef __x86_64__ */
421
422#endif /* defined __i386__ */
423