OSDN Git Service

PR libgcj/38396
[pf3gnuchains/gcc-fork.git] / libffi / src / x86 / sysv.S
1 /* -----------------------------------------------------------------------
2    sysv.S - Copyright (c) 1996, 1998, 2001, 2002, 2003, 2005  Red Hat, Inc.
3    
4    X86 Foreign Function Interface 
5
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:
13
14    The above copyright notice and this permission notice shall be included
15    in all copies or substantial portions of the Software.
16
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    ----------------------------------------------------------------------- */
25
26 #ifndef __x86_64__
27
28 #define LIBFFI_ASM      
29 #include <fficonfig.h>
30 #include <ffi.h>
31
32 .text
33
34 .globl ffi_prep_args
35
36         .align 4
37 .globl ffi_call_SYSV
38         .type    ffi_call_SYSV,@function
39
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
49
50         movl  %esp,%eax
51
52         /* Place all of the ffi_prep_args in position  */
53         pushl 12(%ebp)
54         pushl %eax
55         call  *8(%ebp)
56
57         /* Return stack to previous state and call the function  */
58         addl  $8,%esp   
59
60         call  *28(%ebp)
61
62         /* Load %ecx with the return type code  */
63         movl  20(%ebp),%ecx     
64
65         /* Protect %esi.  We're going to pop it in the epilogue.  */
66         pushl %esi
67
68         /* If the return value pointer is NULL, assume no return value.  */
69         cmpl  $0,24(%ebp)
70         jne  0f
71
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)
77
78         jmp   epilogue
79
80 0:
81         call  1f
82
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 */
99
100 1:
101         pop  %esi
102         add  (%esi, %ecx, 4), %esi
103         jmp  *%esi
104
105         /* Sign/zero extend as appropriate.  */
106 retsint8:
107         movsbl  %al, %eax
108         jmp  retint
109
110 retsint16:
111         movswl  %ax, %eax
112         jmp  retint
113
114 retuint8:
115         movzbl  %al, %eax
116         jmp  retint
117
118 retuint16:
119         movzwl  %ax, %eax
120         jmp  retint
121
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
127
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
133
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)
151
152 retstruct:
153         /* Nothing to do!  */
154
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
164
165         .align  4
166 FFI_HIDDEN (ffi_closure_SYSV)
167 .globl ffi_closure_SYSV
168         .type   ffi_closure_SYSV, @function
169
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
197
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         cmpl    $FFI_TYPE_STRUCT, %eax
214         je      .Lcls_retstruct
215 .Lcls_epilogue:
216         movl    %ebp, %esp
217         popl    %ebp
218         ret
219 .Lcls_retint:
220         movl    (%ecx), %eax
221         jmp     .Lcls_epilogue
222 .Lcls_retfloat:
223         flds    (%ecx)
224         jmp     .Lcls_epilogue
225 .Lcls_retdouble:
226         fldl    (%ecx)
227         jmp     .Lcls_epilogue
228 .Lcls_retldouble:
229         fldt    (%ecx)
230         jmp     .Lcls_epilogue
231 .Lcls_retllong:
232         movl    (%ecx), %eax
233         movl    4(%ecx), %edx
234         jmp     .Lcls_epilogue
235 .Lcls_retstruct:
236         movl    %ebp, %esp
237         popl    %ebp
238         ret     $4
239 .LFE2:
240         .size   ffi_closure_SYSV, .-ffi_closure_SYSV
241
242 #if !FFI_NO_RAW_API
243
244 #define RAW_CLOSURE_CIF_OFFSET ((FFI_TRAMPOLINE_SIZE + 3) & ~3)
245 #define RAW_CLOSURE_FUN_OFFSET (RAW_CLOSURE_CIF_OFFSET + 4)
246 #define RAW_CLOSURE_USER_DATA_OFFSET (RAW_CLOSURE_FUN_OFFSET + 4)
247 #define CIF_FLAGS_OFFSET 20
248
249         .align  4
250 FFI_HIDDEN (ffi_closure_raw_SYSV)
251 .globl ffi_closure_raw_SYSV
252         .type   ffi_closure_raw_SYSV, @function
253
254 ffi_closure_raw_SYSV:
255 .LFB3:
256         pushl   %ebp
257 .LCFI4:
258         movl    %esp, %ebp
259 .LCFI5:
260         pushl   %esi
261 .LCFI6:
262         subl    $36, %esp
263         movl    RAW_CLOSURE_CIF_OFFSET(%eax), %esi       /* closure->cif */
264         movl    RAW_CLOSURE_USER_DATA_OFFSET(%eax), %edx /* closure->user_data */
265         movl    %edx, 12(%esp)  /* user_data */
266         leal    8(%ebp), %edx   /* __builtin_dwarf_cfa () */
267         movl    %edx, 8(%esp)   /* raw_args */
268         leal    -24(%ebp), %edx
269         movl    %edx, 4(%esp)   /* &res */
270         movl    %esi, (%esp)    /* cif */
271         call    *RAW_CLOSURE_FUN_OFFSET(%eax)            /* closure->fun */
272         movl    CIF_FLAGS_OFFSET(%esi), %eax             /* rtype */
273         cmpl    $FFI_TYPE_INT, %eax
274         je      .Lrcls_retint
275
276         /* Handle FFI_TYPE_UINT8, FFI_TYPE_SINT8, FFI_TYPE_UINT16,
277            FFI_TYPE_SINT16, FFI_TYPE_UINT32, FFI_TYPE_SINT32.  */
278         cmpl    $FFI_TYPE_UINT64, %eax
279         jge     0f
280         cmpl    $FFI_TYPE_UINT8, %eax
281         jge     .Lrcls_retint
282 0:
283         cmpl    $FFI_TYPE_FLOAT, %eax
284         je      .Lrcls_retfloat
285         cmpl    $FFI_TYPE_DOUBLE, %eax
286         je      .Lrcls_retdouble
287         cmpl    $FFI_TYPE_LONGDOUBLE, %eax
288         je      .Lrcls_retldouble
289         cmpl    $FFI_TYPE_SINT64, %eax
290         je      .Lrcls_retllong
291 .Lrcls_epilogue:
292         addl    $36, %esp
293         popl    %esi
294         popl    %ebp
295         ret
296 .Lrcls_retint:
297         movl    -24(%ebp), %eax
298         jmp     .Lrcls_epilogue
299 .Lrcls_retfloat:
300         flds    -24(%ebp)
301         jmp     .Lrcls_epilogue
302 .Lrcls_retdouble:
303         fldl    -24(%ebp)
304         jmp     .Lrcls_epilogue
305 .Lrcls_retldouble:
306         fldt    -24(%ebp)
307         jmp     .Lrcls_epilogue
308 .Lrcls_retllong:
309         movl    -24(%ebp), %eax
310         movl    -20(%ebp), %edx
311         jmp     .Lrcls_epilogue
312 .LFE3:
313         .size   ffi_closure_raw_SYSV, .-ffi_closure_raw_SYSV
314 #endif
315
316         .section        .eh_frame,EH_FRAME_FLAGS,@progbits
317 .Lframe1:
318         .long   .LECIE1-.LSCIE1 /* Length of Common Information Entry */
319 .LSCIE1:
320         .long   0x0     /* CIE Identifier Tag */
321         .byte   0x1     /* CIE Version */
322 #ifdef __PIC__
323         .ascii "zR\0"   /* CIE Augmentation */
324 #else
325         .ascii "\0"     /* CIE Augmentation */
326 #endif
327         .byte   0x1     /* .uleb128 0x1; CIE Code Alignment Factor */
328         .byte   0x7c    /* .sleb128 -4; CIE Data Alignment Factor */
329         .byte   0x8     /* CIE RA Column */
330 #ifdef __PIC__
331         .byte   0x1     /* .uleb128 0x1; Augmentation size */
332         .byte   0x1b    /* FDE Encoding (pcrel sdata4) */
333 #endif
334         .byte   0xc     /* DW_CFA_def_cfa */
335         .byte   0x4     /* .uleb128 0x4 */
336         .byte   0x4     /* .uleb128 0x4 */
337         .byte   0x88    /* DW_CFA_offset, column 0x8 */
338         .byte   0x1     /* .uleb128 0x1 */
339         .align 4
340 .LECIE1:
341 .LSFDE1:
342         .long   .LEFDE1-.LASFDE1        /* FDE Length */
343 .LASFDE1:
344         .long   .LASFDE1-.Lframe1       /* FDE CIE offset */
345 #ifdef __PIC__
346         .long   .LFB1-. /* FDE initial location */
347 #else
348         .long   .LFB1   /* FDE initial location */
349 #endif
350         .long   .LFE1-.LFB1     /* FDE address range */
351 #ifdef __PIC__
352         .byte   0x0     /* .uleb128 0x0; Augmentation size */
353 #endif
354         .byte   0x4     /* DW_CFA_advance_loc4 */
355         .long   .LCFI0-.LFB1
356         .byte   0xe     /* DW_CFA_def_cfa_offset */
357         .byte   0x8     /* .uleb128 0x8 */
358         .byte   0x85    /* DW_CFA_offset, column 0x5 */
359         .byte   0x2     /* .uleb128 0x2 */
360         .byte   0x4     /* DW_CFA_advance_loc4 */
361         .long   .LCFI1-.LCFI0
362         .byte   0xd     /* DW_CFA_def_cfa_register */
363         .byte   0x5     /* .uleb128 0x5 */
364         .align 4
365 .LEFDE1:
366 .LSFDE2:
367         .long   .LEFDE2-.LASFDE2        /* FDE Length */
368 .LASFDE2:
369         .long   .LASFDE2-.Lframe1       /* FDE CIE offset */
370 #ifdef __PIC__
371         .long   .LFB2-. /* FDE initial location */
372 #else
373         .long   .LFB2
374 #endif
375         .long   .LFE2-.LFB2     /* FDE address range */
376 #ifdef __PIC__
377         .byte   0x0     /* .uleb128 0x0; Augmentation size */
378 #endif
379         .byte   0x4     /* DW_CFA_advance_loc4 */
380         .long   .LCFI2-.LFB2
381         .byte   0xe     /* DW_CFA_def_cfa_offset */
382         .byte   0x8     /* .uleb128 0x8 */
383         .byte   0x85    /* DW_CFA_offset, column 0x5 */
384         .byte   0x2     /* .uleb128 0x2 */
385         .byte   0x4     /* DW_CFA_advance_loc4 */
386         .long   .LCFI3-.LCFI2
387         .byte   0xd     /* DW_CFA_def_cfa_register */
388         .byte   0x5     /* .uleb128 0x5 */
389 #if !defined HAVE_HIDDEN_VISIBILITY_ATTRIBUTE && defined __PIC__
390         .byte   0x4     /* DW_CFA_advance_loc4 */
391         .long   .LCFI7-.LCFI3
392         .byte   0x83    /* DW_CFA_offset, column 0x3 */
393         .byte   0xa     /* .uleb128 0xa */
394 #endif
395         .align 4
396 .LEFDE2:
397
398 #if !FFI_NO_RAW_API
399
400 .LSFDE3:
401         .long   .LEFDE3-.LASFDE3        /* FDE Length */
402 .LASFDE3:
403         .long   .LASFDE3-.Lframe1       /* FDE CIE offset */
404 #ifdef __PIC__
405         .long   .LFB3-. /* FDE initial location */
406 #else
407         .long   .LFB3
408 #endif
409         .long   .LFE3-.LFB3     /* FDE address range */
410 #ifdef __PIC__
411         .byte   0x0     /* .uleb128 0x0; Augmentation size */
412 #endif
413         .byte   0x4     /* DW_CFA_advance_loc4 */
414         .long   .LCFI4-.LFB3
415         .byte   0xe     /* DW_CFA_def_cfa_offset */
416         .byte   0x8     /* .uleb128 0x8 */
417         .byte   0x85    /* DW_CFA_offset, column 0x5 */
418         .byte   0x2     /* .uleb128 0x2 */
419         .byte   0x4     /* DW_CFA_advance_loc4 */
420         .long   .LCFI5-.LCFI4
421         .byte   0xd     /* DW_CFA_def_cfa_register */
422         .byte   0x5     /* .uleb128 0x5 */
423         .byte   0x4     /* DW_CFA_advance_loc4 */
424         .long   .LCFI6-.LCFI5
425         .byte   0x86    /* DW_CFA_offset, column 0x6 */
426         .byte   0x3     /* .uleb128 0x3 */
427         .align 4
428 .LEFDE3:
429
430 #endif
431
432 #endif /* ifndef __x86_64__ */
433
434 #if defined __ELF__ && defined __linux__
435         .section        .note.GNU-stack,"",@progbits
436 #endif