Merged with mainline at revision 128810.
[official-gcc.git] / libffi / src / x86 / sysv.S
blobf22c939c0a8943180500bfb9ddf8fc258ef3a0c6
1 /* -----------------------------------------------------------------------
2    sysv.S - Copyright (c) 1996, 1998, 2001, 2002, 2003, 2005  Red Hat, Inc.
3    
4    X86 Foreign Function Interface 
6    Permission is hereby granted, free of charge, to any person obtaining
7    a copy of this software and associated documentation files (the
8    ``Software''), to deal in the Software without restriction, including
9    without limitation the rights to use, copy, modify, merge, publish,
10    distribute, sublicense, and/or sell copies of the Software, and to
11    permit persons to whom the Software is furnished to do so, subject to
12    the following conditions:
14    The above copyright notice and this permission notice shall be included
15    in all copies or substantial portions of the Software.
17    THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
18    OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20    IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
21    OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
22    ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23    OTHER DEALINGS IN THE SOFTWARE.
24    ----------------------------------------------------------------------- */
26 #ifndef __x86_64__
28 #define LIBFFI_ASM      
29 #include <fficonfig.h>
30 #include <ffi.h>
32 .text
34 .globl ffi_prep_args
36         .align 4
37 .globl ffi_call_SYSV
38         .type    ffi_call_SYSV,@function
40 ffi_call_SYSV:
41 .LFB1:
42         pushl %ebp
43 .LCFI0:
44         movl  %esp,%ebp
45 .LCFI1:
46         /* Make room for all of the new args.  */
47         movl  16(%ebp),%ecx
48         subl  %ecx,%esp
50         movl  %esp,%eax
52         /* Place all of the ffi_prep_args in position  */
53         pushl 12(%ebp)
54         pushl %eax
55         call  *8(%ebp)
57         /* Return stack to previous state and call the function  */
58         addl  $8,%esp   
60         call  *28(%ebp)
62         /* Load %ecx with the return type code  */
63         movl  20(%ebp),%ecx     
65         /* Protect %esi.  We're going to pop it in the epilogue.  */
66         pushl %esi
68         /* If the return value pointer is NULL, assume no return value.  */
69         cmpl  $0,24(%ebp)
70         jne  0f
72         /* Even if there is no space for the return value, we are 
73            obliged to handle floating-point values.  */
74         cmpl  $FFI_TYPE_FLOAT,%ecx
75         jne   noretval
76         fstp  %st(0)
78         jmp   epilogue
81         call  1f
83 .Lstore_table:
84         .long   noretval-.Lstore_table  /* FFI_TYPE_VOID */
85         .long   retint-.Lstore_table    /* FFI_TYPE_INT */
86         .long   retfloat-.Lstore_table  /* FFI_TYPE_FLOAT */
87         .long   retdouble-.Lstore_table /* FFI_TYPE_DOUBLE */
88         .long   retlongdouble-.Lstore_table     /* FFI_TYPE_LONGDOUBLE */
89         .long   retuint8-.Lstore_table  /* FFI_TYPE_UINT8 */
90         .long   retsint8-.Lstore_table  /* FFI_TYPE_SINT8 */
91         .long   retuint16-.Lstore_table /* FFI_TYPE_UINT16 */
92         .long   retsint16-.Lstore_table /* FFI_TYPE_SINT16 */
93         .long   retint-.Lstore_table    /* FFI_TYPE_UINT32 */
94         .long   retint-.Lstore_table    /* FFI_TYPE_SINT32 */
95         .long   retint64-.Lstore_table  /* FFI_TYPE_UINT64 */
96         .long   retint64-.Lstore_table  /* FFI_TYPE_SINT64 */
97         .long   retstruct-.Lstore_table /* FFI_TYPE_STRUCT */
98         .long   retint-.Lstore_table    /* FFI_TYPE_POINTER */
101         pop  %esi
102         add  (%esi, %ecx, 4), %esi
103         jmp  *%esi
105         /* Sign/zero extend as appropriate.  */
106 retsint8:
107         movsbl  %al, %eax
108         jmp  retint
110 retsint16:
111         movswl  %ax, %eax
112         jmp  retint
114 retuint8:
115         movzbl  %al, %eax
116         jmp  retint
118 retuint16:
119         movzwl  %ax, %eax
120         jmp  retint
122 retfloat:
123         /* Load %ecx with the pointer to storage for the return value  */
124         movl  24(%ebp),%ecx     
125         fstps (%ecx)
126         jmp   epilogue
128 retdouble:
129         /* Load %ecx with the pointer to storage for the return value  */
130         movl  24(%ebp),%ecx     
131         fstpl (%ecx)
132         jmp   epilogue
134 retlongdouble:
135         /* Load %ecx with the pointer to storage for the return value  */
136         movl  24(%ebp),%ecx     
137         fstpt (%ecx)
138         jmp   epilogue
139         
140 retint64:       
141         /* Load %ecx with the pointer to storage for the return value  */
142         movl  24(%ebp),%ecx     
143         movl  %eax,0(%ecx)
144         movl  %edx,4(%ecx)
145         jmp   epilogue
146         
147 retint:
148         /* Load %ecx with the pointer to storage for the return value  */
149         movl  24(%ebp),%ecx     
150         movl  %eax,0(%ecx)
152 retstruct:
153         /* Nothing to do!  */
155 noretval:
156 epilogue:
157         popl %esi
158         movl %ebp,%esp
159         popl %ebp
160         ret
161 .LFE1:
162 .ffi_call_SYSV_end:
163         .size    ffi_call_SYSV,.ffi_call_SYSV_end-ffi_call_SYSV
165         .align  4
166 FFI_HIDDEN (ffi_closure_SYSV)
167 .globl ffi_closure_SYSV
168         .type   ffi_closure_SYSV, @function
170 ffi_closure_SYSV:
171 .LFB2:
172         pushl   %ebp
173 .LCFI2:
174         movl    %esp, %ebp
175 .LCFI3:
176         subl    $40, %esp
177         leal    -24(%ebp), %edx
178         movl    %edx, -12(%ebp) /* resp */
179         leal    8(%ebp), %edx
180         movl    %edx, 4(%esp)   /* args = __builtin_dwarf_cfa () */
181         leal    -12(%ebp), %edx
182         movl    %edx, (%esp)    /* &resp */
183 #if defined HAVE_HIDDEN_VISIBILITY_ATTRIBUTE || !defined __PIC__
184         call    ffi_closure_SYSV_inner
185 #else
186         movl    %ebx, 8(%esp)
187 .LCFI7:
188         call    1f
189 1:      popl    %ebx
190         addl    $_GLOBAL_OFFSET_TABLE_+[.-1b], %ebx
191         call    ffi_closure_SYSV_inner@PLT
192         movl    8(%esp), %ebx
193 #endif
194         movl    -12(%ebp), %ecx
195         cmpl    $FFI_TYPE_INT, %eax
196         je      .Lcls_retint
198         /* Handle FFI_TYPE_UINT8, FFI_TYPE_SINT8, FFI_TYPE_UINT16,
199            FFI_TYPE_SINT16, FFI_TYPE_UINT32, FFI_TYPE_SINT32.  */
200         cmpl    $FFI_TYPE_UINT64, %eax
201         jge     0f
202         cmpl    $FFI_TYPE_UINT8, %eax
203         jge     .Lcls_retint
204         
205 0:      cmpl    $FFI_TYPE_FLOAT, %eax
206         je      .Lcls_retfloat
207         cmpl    $FFI_TYPE_DOUBLE, %eax
208         je      .Lcls_retdouble
209         cmpl    $FFI_TYPE_LONGDOUBLE, %eax
210         je      .Lcls_retldouble
211         cmpl    $FFI_TYPE_SINT64, %eax
212         je      .Lcls_retllong
213 .Lcls_epilogue:
214         movl    %ebp, %esp
215         popl    %ebp
216         ret
217 .Lcls_retint:
218         movl    (%ecx), %eax
219         jmp     .Lcls_epilogue
220 .Lcls_retfloat:
221         flds    (%ecx)
222         jmp     .Lcls_epilogue
223 .Lcls_retdouble:
224         fldl    (%ecx)
225         jmp     .Lcls_epilogue
226 .Lcls_retldouble:
227         fldt    (%ecx)
228         jmp     .Lcls_epilogue
229 .Lcls_retllong:
230         movl    (%ecx), %eax
231         movl    4(%ecx), %edx
232         jmp     .Lcls_epilogue
233 .LFE2:
234         .size   ffi_closure_SYSV, .-ffi_closure_SYSV
236 #if !FFI_NO_RAW_API
238 #define RAW_CLOSURE_CIF_OFFSET ((FFI_TRAMPOLINE_SIZE + 3) & ~3)
239 #define RAW_CLOSURE_FUN_OFFSET (RAW_CLOSURE_CIF_OFFSET + 4)
240 #define RAW_CLOSURE_USER_DATA_OFFSET (RAW_CLOSURE_FUN_OFFSET + 4)
241 #define CIF_FLAGS_OFFSET 20
243         .align  4
244 FFI_HIDDEN (ffi_closure_raw_SYSV)
245 .globl ffi_closure_raw_SYSV
246         .type   ffi_closure_raw_SYSV, @function
248 ffi_closure_raw_SYSV:
249 .LFB3:
250         pushl   %ebp
251 .LCFI4:
252         movl    %esp, %ebp
253 .LCFI5:
254         pushl   %esi
255 .LCFI6:
256         subl    $36, %esp
257         movl    RAW_CLOSURE_CIF_OFFSET(%eax), %esi       /* closure->cif */
258         movl    RAW_CLOSURE_USER_DATA_OFFSET(%eax), %edx /* closure->user_data */
259         movl    %edx, 12(%esp)  /* user_data */
260         leal    8(%ebp), %edx   /* __builtin_dwarf_cfa () */
261         movl    %edx, 8(%esp)   /* raw_args */
262         leal    -24(%ebp), %edx
263         movl    %edx, 4(%esp)   /* &res */
264         movl    %esi, (%esp)    /* cif */
265         call    *RAW_CLOSURE_FUN_OFFSET(%eax)            /* closure->fun */
266         movl    CIF_FLAGS_OFFSET(%esi), %eax             /* rtype */
267         cmpl    $FFI_TYPE_INT, %eax
268         je      .Lrcls_retint
270         /* Handle FFI_TYPE_UINT8, FFI_TYPE_SINT8, FFI_TYPE_UINT16,
271            FFI_TYPE_SINT16, FFI_TYPE_UINT32, FFI_TYPE_SINT32.  */
272         cmpl    $FFI_TYPE_UINT64, %eax
273         jge     0f
274         cmpl    $FFI_TYPE_UINT8, %eax
275         jge     .Lrcls_retint
277         cmpl    $FFI_TYPE_FLOAT, %eax
278         je      .Lrcls_retfloat
279         cmpl    $FFI_TYPE_DOUBLE, %eax
280         je      .Lrcls_retdouble
281         cmpl    $FFI_TYPE_LONGDOUBLE, %eax
282         je      .Lrcls_retldouble
283         cmpl    $FFI_TYPE_SINT64, %eax
284         je      .Lrcls_retllong
285 .Lrcls_epilogue:
286         addl    $36, %esp
287         popl    %esi
288         popl    %ebp
289         ret
290 .Lrcls_retint:
291         movl    -24(%ebp), %eax
292         jmp     .Lrcls_epilogue
293 .Lrcls_retfloat:
294         flds    -24(%ebp)
295         jmp     .Lrcls_epilogue
296 .Lrcls_retdouble:
297         fldl    -24(%ebp)
298         jmp     .Lrcls_epilogue
299 .Lrcls_retldouble:
300         fldt    -24(%ebp)
301         jmp     .Lrcls_epilogue
302 .Lrcls_retllong:
303         movl    -24(%ebp), %eax
304         movl    -20(%ebp), %edx
305         jmp     .Lrcls_epilogue
306 .LFE3:
307         .size   ffi_closure_raw_SYSV, .-ffi_closure_raw_SYSV
308 #endif
310         .section        .eh_frame,EH_FRAME_FLAGS,@progbits
311 .Lframe1:
312         .long   .LECIE1-.LSCIE1 /* Length of Common Information Entry */
313 .LSCIE1:
314         .long   0x0     /* CIE Identifier Tag */
315         .byte   0x1     /* CIE Version */
316 #ifdef __PIC__
317         .ascii "zR\0"   /* CIE Augmentation */
318 #else
319         .ascii "\0"     /* CIE Augmentation */
320 #endif
321         .byte   0x1     /* .uleb128 0x1; CIE Code Alignment Factor */
322         .byte   0x7c    /* .sleb128 -4; CIE Data Alignment Factor */
323         .byte   0x8     /* CIE RA Column */
324 #ifdef __PIC__
325         .byte   0x1     /* .uleb128 0x1; Augmentation size */
326         .byte   0x1b    /* FDE Encoding (pcrel sdata4) */
327 #endif
328         .byte   0xc     /* DW_CFA_def_cfa */
329         .byte   0x4     /* .uleb128 0x4 */
330         .byte   0x4     /* .uleb128 0x4 */
331         .byte   0x88    /* DW_CFA_offset, column 0x8 */
332         .byte   0x1     /* .uleb128 0x1 */
333         .align 4
334 .LECIE1:
335 .LSFDE1:
336         .long   .LEFDE1-.LASFDE1        /* FDE Length */
337 .LASFDE1:
338         .long   .LASFDE1-.Lframe1       /* FDE CIE offset */
339 #ifdef __PIC__
340         .long   .LFB1-. /* FDE initial location */
341 #else
342         .long   .LFB1   /* FDE initial location */
343 #endif
344         .long   .LFE1-.LFB1     /* FDE address range */
345 #ifdef __PIC__
346         .byte   0x0     /* .uleb128 0x0; Augmentation size */
347 #endif
348         .byte   0x4     /* DW_CFA_advance_loc4 */
349         .long   .LCFI0-.LFB1
350         .byte   0xe     /* DW_CFA_def_cfa_offset */
351         .byte   0x8     /* .uleb128 0x8 */
352         .byte   0x85    /* DW_CFA_offset, column 0x5 */
353         .byte   0x2     /* .uleb128 0x2 */
354         .byte   0x4     /* DW_CFA_advance_loc4 */
355         .long   .LCFI1-.LCFI0
356         .byte   0xd     /* DW_CFA_def_cfa_register */
357         .byte   0x5     /* .uleb128 0x5 */
358         .align 4
359 .LEFDE1:
360 .LSFDE2:
361         .long   .LEFDE2-.LASFDE2        /* FDE Length */
362 .LASFDE2:
363         .long   .LASFDE2-.Lframe1       /* FDE CIE offset */
364 #ifdef __PIC__
365         .long   .LFB2-. /* FDE initial location */
366 #else
367         .long   .LFB2
368 #endif
369         .long   .LFE2-.LFB2     /* FDE address range */
370 #ifdef __PIC__
371         .byte   0x0     /* .uleb128 0x0; Augmentation size */
372 #endif
373         .byte   0x4     /* DW_CFA_advance_loc4 */
374         .long   .LCFI2-.LFB2
375         .byte   0xe     /* DW_CFA_def_cfa_offset */
376         .byte   0x8     /* .uleb128 0x8 */
377         .byte   0x85    /* DW_CFA_offset, column 0x5 */
378         .byte   0x2     /* .uleb128 0x2 */
379         .byte   0x4     /* DW_CFA_advance_loc4 */
380         .long   .LCFI3-.LCFI2
381         .byte   0xd     /* DW_CFA_def_cfa_register */
382         .byte   0x5     /* .uleb128 0x5 */
383 #if !defined HAVE_HIDDEN_VISIBILITY_ATTRIBUTE && defined __PIC__
384         .byte   0x4     /* DW_CFA_advance_loc4 */
385         .long   .LCFI7-.LCFI3
386         .byte   0x83    /* DW_CFA_offset, column 0x3 */
387         .byte   0xa     /* .uleb128 0xa */
388 #endif
389         .align 4
390 .LEFDE2:
392 #if !FFI_NO_RAW_API
394 .LSFDE3:
395         .long   .LEFDE3-.LASFDE3        /* FDE Length */
396 .LASFDE3:
397         .long   .LASFDE3-.Lframe1       /* FDE CIE offset */
398 #ifdef __PIC__
399         .long   .LFB3-. /* FDE initial location */
400 #else
401         .long   .LFB3
402 #endif
403         .long   .LFE3-.LFB3     /* FDE address range */
404 #ifdef __PIC__
405         .byte   0x0     /* .uleb128 0x0; Augmentation size */
406 #endif
407         .byte   0x4     /* DW_CFA_advance_loc4 */
408         .long   .LCFI4-.LFB3
409         .byte   0xe     /* DW_CFA_def_cfa_offset */
410         .byte   0x8     /* .uleb128 0x8 */
411         .byte   0x85    /* DW_CFA_offset, column 0x5 */
412         .byte   0x2     /* .uleb128 0x2 */
413         .byte   0x4     /* DW_CFA_advance_loc4 */
414         .long   .LCFI5-.LCFI4
415         .byte   0xd     /* DW_CFA_def_cfa_register */
416         .byte   0x5     /* .uleb128 0x5 */
417         .byte   0x4     /* DW_CFA_advance_loc4 */
418         .long   .LCFI6-.LCFI5
419         .byte   0x86    /* DW_CFA_offset, column 0x6 */
420         .byte   0x3     /* .uleb128 0x3 */
421         .align 4
422 .LEFDE3:
424 #endif
426 #endif /* ifndef __x86_64__ */