blob: 6c85ea61d6249d6752bf9e201e20b9da5ec156c3 [file] [log] [blame]
Thomas Heller8bdf81d2008-03-04 20:09:11 +00001#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
Ronald Oussoren16766d72009-09-20 18:54:16 +000049 .align 4
Thomas Heller8bdf81d2008-03-04 20:09:11 +000050.globl _ffi_call_SYSV
51
52_ffi_call_SYSV:
Ronald Oussoren16766d72009-09-20 18:54:16 +000053LFB1:
Thomas Heller8bdf81d2008-03-04 20:09:11 +000054 pushl %ebp
Ronald Oussoren16766d72009-09-20 18:54:16 +000055LCFI0:
Thomas Heller8bdf81d2008-03-04 20:09:11 +000056 movl %esp,%ebp
Ronald Oussoren16766d72009-09-20 18:54:16 +000057LCFI1:
58 subl $8,%esp
Thomas Heller8bdf81d2008-03-04 20:09:11 +000059 /* Make room for all of the new args. */
60 movl 16(%ebp),%ecx
61 subl %ecx,%esp
62
Thomas Heller8bdf81d2008-03-04 20:09:11 +000063 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
Thomas Heller8bdf81d2008-03-04 20:09:11 +000071 /* Return stack to previous state and call the function */
Ronald Oussoren16766d72009-09-20 18:54:16 +000072 addl $16,%esp
Thomas Heller8bdf81d2008-03-04 20:09:11 +000073
74 call *28(%ebp)
Ronald Oussoren16766d72009-09-20 18:54:16 +000075
76 /* Remove the space we pushed for the args */
Thomas Heller8bdf81d2008-03-04 20:09:11 +000077 movl 16(%ebp),%ecx
78 addl %ecx,%esp
79
Thomas Heller8bdf81d2008-03-04 20:09:11 +000080 /* Load %ecx with the return type code */
81 movl 20(%ebp),%ecx
82
Thomas Heller8bdf81d2008-03-04 20:09:11 +000083 /* If the return value pointer is NULL, assume no return value. */
84 cmpl $0,24(%ebp)
Ronald Oussoren16766d72009-09-20 18:54:16 +000085 jne Lretint
Thomas Heller8bdf81d2008-03-04 20:09:11 +000086
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
Ronald Oussoren16766d72009-09-20 18:54:16 +000090 jne Lnoretval
Thomas Heller8bdf81d2008-03-04 20:09:11 +000091 fstp %st(0)
92
Ronald Oussoren16766d72009-09-20 18:54:16 +000093 jmp Lepilogue
Thomas Heller8bdf81d2008-03-04 20:09:11 +000094
Ronald Oussoren16766d72009-09-20 18:54:16 +000095Lretint:
Thomas Heller8bdf81d2008-03-04 20:09:11 +000096 cmpl $FFI_TYPE_INT,%ecx
Ronald Oussoren16766d72009-09-20 18:54:16 +000097 jne Lretfloat
Thomas Heller8bdf81d2008-03-04 20:09:11 +000098 /* Load %ecx with the pointer to storage for the return value */
99 movl 24(%ebp),%ecx
100 movl %eax,0(%ecx)
Ronald Oussoren16766d72009-09-20 18:54:16 +0000101 jmp Lepilogue
Thomas Heller8bdf81d2008-03-04 20:09:11 +0000102
Ronald Oussoren16766d72009-09-20 18:54:16 +0000103Lretfloat:
Thomas Heller8bdf81d2008-03-04 20:09:11 +0000104 cmpl $FFI_TYPE_FLOAT,%ecx
Ronald Oussoren16766d72009-09-20 18:54:16 +0000105 jne Lretdouble
Thomas Heller8bdf81d2008-03-04 20:09:11 +0000106 /* Load %ecx with the pointer to storage for the return value */
107 movl 24(%ebp),%ecx
108 fstps (%ecx)
Ronald Oussoren16766d72009-09-20 18:54:16 +0000109 jmp Lepilogue
Thomas Heller8bdf81d2008-03-04 20:09:11 +0000110
Ronald Oussoren16766d72009-09-20 18:54:16 +0000111Lretdouble:
Thomas Heller8bdf81d2008-03-04 20:09:11 +0000112 cmpl $FFI_TYPE_DOUBLE,%ecx
Ronald Oussoren16766d72009-09-20 18:54:16 +0000113 jne Lretlongdouble
Thomas Heller8bdf81d2008-03-04 20:09:11 +0000114 /* Load %ecx with the pointer to storage for the return value */
115 movl 24(%ebp),%ecx
116 fstpl (%ecx)
Ronald Oussoren16766d72009-09-20 18:54:16 +0000117 jmp Lepilogue
Thomas Heller8bdf81d2008-03-04 20:09:11 +0000118
Ronald Oussoren16766d72009-09-20 18:54:16 +0000119Lretlongdouble:
Thomas Heller8bdf81d2008-03-04 20:09:11 +0000120 cmpl $FFI_TYPE_LONGDOUBLE,%ecx
Ronald Oussoren16766d72009-09-20 18:54:16 +0000121 jne Lretint64
Thomas Heller8bdf81d2008-03-04 20:09:11 +0000122 /* Load %ecx with the pointer to storage for the return value */
123 movl 24(%ebp),%ecx
124 fstpt (%ecx)
Ronald Oussoren16766d72009-09-20 18:54:16 +0000125 jmp Lepilogue
Thomas Heller8bdf81d2008-03-04 20:09:11 +0000126
Ronald Oussoren16766d72009-09-20 18:54:16 +0000127Lretint64:
Thomas Heller8bdf81d2008-03-04 20:09:11 +0000128 cmpl $FFI_TYPE_SINT64,%ecx
Ronald Oussoren16766d72009-09-20 18:54:16 +0000129 jne Lretstruct1b
Thomas Heller8bdf81d2008-03-04 20:09:11 +0000130 /* 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)
Ronald Oussoren16766d72009-09-20 18:54:16 +0000134 jmp Lepilogue
Thomas Heller8bdf81d2008-03-04 20:09:11 +0000135
Ronald Oussoren16766d72009-09-20 18:54:16 +0000136Lretstruct1b:
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
Thomas Heller8bdf81d2008-03-04 20:09:11 +0000155 /* Nothing to do! */
Ronald Oussoren16766d72009-09-20 18:54:16 +0000156 addl $4,%esp
157 popl %ebp
158 ret
Thomas Heller8bdf81d2008-03-04 20:09:11 +0000159
Ronald Oussoren16766d72009-09-20 18:54:16 +0000160Lnoretval:
161Lepilogue:
162 addl $8,%esp
Thomas Heller8bdf81d2008-03-04 20:09:11 +0000163 movl %ebp,%esp
164 popl %ebp
165 ret
Ronald Oussoren16766d72009-09-20 18:54:16 +0000166LFE1:
Thomas Heller8bdf81d2008-03-04 20:09:11 +0000167.ffi_call_SYSV_end:
Ronald Oussoren16766d72009-09-20 18:54:16 +0000168
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:
Thomas Heller8bdf81d2008-03-04 20:09:11 +0000302#endif
303
Ronald Oussoren16766d72009-09-20 18:54:16 +0000304.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
Thomas Heller8bdf81d2008-03-04 20:09:11 +0000414#endif
415
416#endif /* ifndef __x86_64__ */
417
418#endif /* defined __i386__ */