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:
53.LFB1:
54        pushl %ebp
55.LCFI0:
56        movl  %esp,%ebp
57	subl  $8,%esp
58	ASSERT_STACK_ALIGNED
59.LCFI1:
60	/* Make room for all of the new args.  */
61	movl  16(%ebp),%ecx
62	subl  %ecx,%esp
63
64	ASSERT_STACK_ALIGNED
65
66	movl  %esp,%eax
67
68	/* Place all of the ffi_prep_args in position  */
69	subl  $8,%esp
70	pushl 12(%ebp)
71	pushl %eax
72	call  *8(%ebp)
73
74	ASSERT_STACK_ALIGNED
75
76	/* Return stack to previous state and call the function  */
77	addl  $16,%esp
78
79	ASSERT_STACK_ALIGNED
80
81	call  *28(%ebp)
82
83	/* XXX: return returns return with 'ret $4', that upsets the stack! */
84	movl  16(%ebp),%ecx
85	addl  %ecx,%esp
86
87
88	/* Load %ecx with the return type code  */
89	movl  20(%ebp),%ecx
90
91
92	/* If the return value pointer is NULL, assume no return value.  */
93	cmpl  $0,24(%ebp)
94	jne   retint
95
96	/* Even if there is no space for the return value, we are
97	   obliged to handle floating-point values.  */
98	cmpl  $FFI_TYPE_FLOAT,%ecx
99	jne   noretval
100	fstp  %st(0)
101
102        jmp   epilogue
103
104retint:
105	cmpl  $FFI_TYPE_INT,%ecx
106	jne   retfloat
107	/* Load %ecx with the pointer to storage for the return value  */
108	movl  24(%ebp),%ecx
109	movl  %eax,0(%ecx)
110	jmp   epilogue
111
112retfloat:
113	cmpl  $FFI_TYPE_FLOAT,%ecx
114	jne   retdouble
115	/* Load %ecx with the pointer to storage for the return value  */
116	movl  24(%ebp),%ecx
117	fstps (%ecx)
118	jmp   epilogue
119
120retdouble:
121	cmpl  $FFI_TYPE_DOUBLE,%ecx
122	jne   retlongdouble
123	/* Load %ecx with the pointer to storage for the return value  */
124	movl  24(%ebp),%ecx
125	fstpl (%ecx)
126	jmp   epilogue
127
128retlongdouble:
129	cmpl  $FFI_TYPE_LONGDOUBLE,%ecx
130	jne   retint64
131	/* Load %ecx with the pointer to storage for the return value  */
132	movl  24(%ebp),%ecx
133	fstpt (%ecx)
134	jmp   epilogue
135
136retint64:
137	cmpl  $FFI_TYPE_SINT64,%ecx
138        jne   retstruct1b
139	/* Load %ecx with the pointer to storage for the return value  */
140	movl  24(%ebp),%ecx
141	movl  %eax,0(%ecx)
142	movl  %edx,4(%ecx)
143	jmp   epilogue
144
145retstruct1b:
146   cmpl $FFI_TYPE_SINT8,%ecx
147   jne  retstruct2b
148   movl 24(%ebp),%ecx
149   movb  %al,0(%ecx)
150   jmp  epilogue
151
152retstruct2b:
153   cmpl $FFI_TYPE_SINT16,%ecx
154   jne  retstruct
155   movl 24(%ebp),%ecx
156   movw %ax,0(%ecx)
157   jmp  epilogue
158
159retstruct:
160   cmpl $FFI_TYPE_STRUCT,%ecx
161   jne  noretval
162	/* Nothing to do!  */
163
164	subl $4,%esp
165
166	ASSERT_STACK_ALIGNED
167
168	addl $8,%esp
169	movl %ebp, %esp
170	popl %ebp
171	ret
172
173noretval:
174epilogue:
175	ASSERT_STACK_ALIGNED
176	addl $8, %esp
177
178
179        movl %ebp,%esp
180        popl %ebp
181        ret
182.LFE1:
183.ffi_call_SYSV_end:
184#if 0
185        .size    ffi_call_SYSV,.ffi_call_SYSV_end-ffi_call_SYSV
186#endif
187
188#if 0
189	.section	.eh_frame,EH_FRAME_FLAGS,@progbits
190.Lframe1:
191	.long	.LECIE1-.LSCIE1	/* Length of Common Information Entry */
192.LSCIE1:
193	.long	0x0	/* CIE Identifier Tag */
194	.byte	0x1	/* CIE Version */
195#ifdef __PIC__
196	.ascii "zR\0"	/* CIE Augmentation */
197#else
198	.ascii "\0"	/* CIE Augmentation */
199#endif
200	.byte	0x1	/* .uleb128 0x1; CIE Code Alignment Factor */
201	.byte	0x7c	/* .sleb128 -4; CIE Data Alignment Factor */
202	.byte	0x8	/* CIE RA Column */
203#ifdef __PIC__
204	.byte	0x1	/* .uleb128 0x1; Augmentation size */
205	.byte	0x1b	/* FDE Encoding (pcrel sdata4) */
206#endif
207	.byte	0xc	/* DW_CFA_def_cfa */
208	.byte	0x4	/* .uleb128 0x4 */
209	.byte	0x4	/* .uleb128 0x4 */
210	.byte	0x88	/* DW_CFA_offset, column 0x8 */
211	.byte	0x1	/* .uleb128 0x1 */
212	.align 4
213.LECIE1:
214.LSFDE1:
215	.long	.LEFDE1-.LASFDE1	/* FDE Length */
216.LASFDE1:
217	.long	.LASFDE1-.Lframe1	/* FDE CIE offset */
218#ifdef __PIC__
219	.long	.LFB1-.	/* FDE initial location */
220#else
221	.long	.LFB1	/* FDE initial location */
222#endif
223	.long	.LFE1-.LFB1	/* FDE address range */
224#ifdef __PIC__
225	.byte	0x0	/* .uleb128 0x0; Augmentation size */
226#endif
227	.byte	0x4	/* DW_CFA_advance_loc4 */
228	.long	.LCFI0-.LFB1
229	.byte	0xe	/* DW_CFA_def_cfa_offset */
230	.byte	0x8	/* .uleb128 0x8 */
231	.byte	0x85	/* DW_CFA_offset, column 0x5 */
232	.byte	0x2	/* .uleb128 0x2 */
233	.byte	0x4	/* DW_CFA_advance_loc4 */
234	.long	.LCFI1-.LCFI0
235	.byte	0xd	/* DW_CFA_def_cfa_register */
236	.byte	0x5	/* .uleb128 0x5 */
237	.align 4
238.LEFDE1:
239#endif
240
241#endif /* ifndef __x86_64__ */
242
243#endif /* defined __i386__ */
244