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_SINT8, %eax
202	je	Lcls_retstruct1
203	cmpl	$FFI_TYPE_SINT16, %eax
204	je	Lcls_retstruct2
205	cmpl	$FFI_TYPE_STRUCT, %eax
206	je	Lcls_retstruct
207Lcls_epilogue:
208	movl	%ebp, %esp
209	popl	%ebp
210	ret
211Lcls_retint:
212	movl	(%ecx), %eax
213	jmp	Lcls_epilogue
214Lcls_retfloat:
215	flds	(%ecx)
216	jmp	Lcls_epilogue
217Lcls_retdouble:
218	fldl	(%ecx)
219	jmp	Lcls_epilogue
220Lcls_retldouble:
221	fldt	(%ecx)
222	jmp	Lcls_epilogue
223Lcls_retllong:
224	movl	(%ecx), %eax
225	movl	4(%ecx), %edx
226	jmp	Lcls_epilogue
227Lcls_retstruct1:
228	movsbl	(%ecx), %eax
229	jmp	Lcls_epilogue
230Lcls_retstruct2:
231	movswl	(%ecx), %eax
232	jmp	Lcls_epilogue
233Lcls_retstruct:
234	lea -8(%ebp),%esp
235	movl	%ebp, %esp
236	popl	%ebp
237	ret $4
238LFE2:
239
240#if !FFI_NO_RAW_API
241
242#define RAW_CLOSURE_CIF_OFFSET ((FFI_TRAMPOLINE_SIZE + 3) & ~3)
243#define RAW_CLOSURE_FUN_OFFSET (RAW_CLOSURE_CIF_OFFSET + 4)
244#define RAW_CLOSURE_USER_DATA_OFFSET (RAW_CLOSURE_FUN_OFFSET + 4)
245#define CIF_FLAGS_OFFSET 20
246
247	.align	4
248FFI_HIDDEN (ffi_closure_raw_SYSV)
249.globl _ffi_closure_raw_SYSV
250
251_ffi_closure_raw_SYSV:
252LFB3:
253	pushl	%ebp
254LCFI4:
255	movl	%esp, %ebp
256LCFI5:
257	pushl	%esi
258LCFI6:
259	subl	$36, %esp
260	movl	RAW_CLOSURE_CIF_OFFSET(%eax), %esi	 /* closure->cif */
261	movl	RAW_CLOSURE_USER_DATA_OFFSET(%eax), %edx /* closure->user_data */
262	movl	%edx, 12(%esp)	/* user_data */
263	leal	8(%ebp), %edx	/* __builtin_dwarf_cfa () */
264	movl	%edx, 8(%esp)	/* raw_args */
265	leal	-24(%ebp), %edx
266	movl	%edx, 4(%esp)	/* &res */
267	movl	%esi, (%esp)	/* cif */
268	call	*RAW_CLOSURE_FUN_OFFSET(%eax)		 /* closure->fun */
269	movl	CIF_FLAGS_OFFSET(%esi), %eax		 /* rtype */
270	cmpl	$FFI_TYPE_INT, %eax
271	je	Lrcls_retint
272	cmpl	$FFI_TYPE_FLOAT, %eax
273	je	Lrcls_retfloat
274	cmpl	$FFI_TYPE_DOUBLE, %eax
275	je	Lrcls_retdouble
276	cmpl	$FFI_TYPE_LONGDOUBLE, %eax
277	je	Lrcls_retldouble
278	cmpl	$FFI_TYPE_SINT64, %eax
279	je	Lrcls_retllong
280Lrcls_epilogue:
281	addl	$36, %esp
282	popl	%esi
283	popl	%ebp
284	ret
285Lrcls_retint:
286	movl	-24(%ebp), %eax
287	jmp	Lrcls_epilogue
288Lrcls_retfloat:
289	flds	-24(%ebp)
290	jmp	Lrcls_epilogue
291Lrcls_retdouble:
292	fldl	-24(%ebp)
293	jmp	Lrcls_epilogue
294Lrcls_retldouble:
295	fldt	-24(%ebp)
296	jmp	Lrcls_epilogue
297Lrcls_retllong:
298	movl	-24(%ebp), %eax
299	movl	-20(%ebp), %edx
300	jmp	Lrcls_epilogue
301LFE3:
302#endif
303
304.section __IMPORT,__jump_table,symbol_stubs,self_modifying_code+pure_instructions,5
305L_ffi_closure_SYSV_inner$stub:
306	.indirect_symbol _ffi_closure_SYSV_inner
307	hlt ; hlt ; hlt ; hlt ; hlt
308
309
310.section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support
311EH_frame1:
312	.set	L$set$0,LECIE1-LSCIE1
313	.long	L$set$0
314LSCIE1:
315	.long	0x0
316	.byte	0x1
317	.ascii "zR\0"
318	.byte	0x1
319	.byte	0x7c
320	.byte	0x8
321	.byte	0x1
322	.byte	0x10
323	.byte	0xc
324	.byte	0x5
325	.byte	0x4
326	.byte	0x88
327	.byte	0x1
328	.align 2
329LECIE1:
330.globl _ffi_call_SYSV.eh
331_ffi_call_SYSV.eh:
332LSFDE1:
333	.set	L$set$1,LEFDE1-LASFDE1
334	.long	L$set$1
335LASFDE1:
336	.long	LASFDE1-EH_frame1
337	.long	LFB1-.
338	.set L$set$2,LFE1-LFB1
339	.long L$set$2
340	.byte	0x0
341	.byte	0x4
342	.set L$set$3,LCFI0-LFB1
343	.long L$set$3
344	.byte	0xe
345	.byte	0x8
346	.byte	0x84
347	.byte	0x2
348	.byte	0x4
349	.set L$set$4,LCFI1-LCFI0
350	.long L$set$4
351	.byte	0xd
352	.byte	0x4
353	.align 2
354LEFDE1:
355.globl _ffi_closure_SYSV.eh
356_ffi_closure_SYSV.eh:
357LSFDE2:
358	.set	L$set$5,LEFDE2-LASFDE2
359	.long	L$set$5
360LASFDE2:
361	.long	LASFDE2-EH_frame1
362	.long	LFB2-.
363	.set L$set$6,LFE2-LFB2
364	.long L$set$6
365	.byte	0x0
366	.byte	0x4
367	.set L$set$7,LCFI2-LFB2
368	.long L$set$7
369	.byte	0xe
370	.byte	0x8
371	.byte	0x84
372	.byte	0x2
373	.byte	0x4
374	.set L$set$8,LCFI3-LCFI2
375	.long L$set$8
376	.byte	0xd
377	.byte	0x4
378	.align 2
379LEFDE2:
380
381#if !FFI_NO_RAW_API
382
383.globl _ffi_closure_raw_SYSV.eh
384_ffi_closure_raw_SYSV.eh:
385LSFDE3:
386	.set	L$set$10,LEFDE3-LASFDE3
387	.long	L$set$10
388LASFDE3:
389	.long	LASFDE3-EH_frame1
390	.long	LFB3-.
391	.set L$set$11,LFE3-LFB3
392	.long L$set$11
393	.byte	0x0
394	.byte	0x4
395	.set L$set$12,LCFI4-LFB3
396	.long L$set$12
397	.byte	0xe
398	.byte	0x8
399	.byte	0x84
400	.byte	0x2
401	.byte	0x4
402	.set L$set$13,LCFI5-LCFI4
403	.long L$set$13
404	.byte	0xd
405	.byte	0x4
406	.byte	0x4
407	.set L$set$14,LCFI6-LCFI5
408	.long L$set$14
409	.byte	0x85
410	.byte	0x3
411	.align 2
412LEFDE3:
413
414#endif
415
416#endif /* ifndef __x86_64__ */
417
418#endif /* defined __i386__ */
419