~ubuntu-branches/ubuntu/lucid/gauche-c-wrapper/lucid

« back to all changes in this revision

Viewing changes to libffi/src/x86/win32.S

  • Committer: Bazaar Package Importer
  • Author(s): NIIBE Yutaka
  • Date: 2008-04-07 09:15:03 UTC
  • Revision ID: james.westby@ubuntu.com-20080407091503-wu0h414koe95kj4i
Tags: upstream-0.5.2
ImportĀ upstreamĀ versionĀ 0.5.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -----------------------------------------------------------------------
 
2
   win32.S - Copyright (c) 1996, 1998, 2001, 2002  Red Hat, Inc.
 
3
             Copyright (c) 2001  John Beniton
 
4
             Copyright (c) 2002  Ranjit Mathew
 
5
                        
 
6
 
 
7
   X86 Foreign Function Interface
 
8
 
 
9
   Permission is hereby granted, free of charge, to any person obtaining
 
10
   a copy of this software and associated documentation files (the
 
11
   ``Software''), to deal in the Software without restriction, including
 
12
   without limitation the rights to use, copy, modify, merge, publish,
 
13
   distribute, sublicense, and/or sell copies of the Software, and to
 
14
   permit persons to whom the Software is furnished to do so, subject to
 
15
   the following conditions:
 
16
 
 
17
   The above copyright notice and this permission notice shall be included
 
18
   in all copies or substantial portions of the Software.
 
19
 
 
20
   THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS
 
21
   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 
22
   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 
23
   IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 
24
   OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 
25
   ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 
26
   OTHER DEALINGS IN THE SOFTWARE.
 
27
   ----------------------------------------------------------------------- */
 
28
 
 
29
#define LIBFFI_ASM
 
30
#include <fficonfig.h>
 
31
#include <ffi.h>
 
32
 
 
33
.text
 
34
 
 
35
.globl ffi_prep_args
 
36
 
 
37
        # This assumes we are using gas.
 
38
        .balign 16
 
39
.globl _ffi_call_SYSV
 
40
 
 
41
_ffi_call_SYSV:
 
42
        pushl %ebp
 
43
        movl  %esp,%ebp
 
44
 
 
45
        # Make room for all of the new args.
 
46
        movl  16(%ebp),%ecx                                                     
 
47
        subl  %ecx,%esp
 
48
 
 
49
        movl  %esp,%eax
 
50
 
 
51
        # Place all of the ffi_prep_args in position
 
52
        pushl 12(%ebp)
 
53
        pushl %eax
 
54
        call  *8(%ebp)
 
55
 
 
56
        # Return stack to previous state and call the function
 
57
        addl  $8,%esp
 
58
 
 
59
        # FIXME: Align the stack to a 128-bit boundary to avoid
 
60
        # potential performance hits.
 
61
 
 
62
        call  *28(%ebp)
 
63
 
 
64
        # Remove the space we pushed for the args
 
65
        movl  16(%ebp),%ecx
 
66
        addl  %ecx,%esp
 
67
 
 
68
        # Load %ecx with the return type code
 
69
        movl  20(%ebp),%ecx
 
70
 
 
71
        # If the return value pointer is NULL, assume no return value.
 
72
        cmpl  $0,24(%ebp)
 
73
        jne   retint
 
74
 
 
75
        # Even if there is no space for the return value, we are
 
76
        # obliged to handle floating-point values.
 
77
        cmpl  $FFI_TYPE_FLOAT,%ecx
 
78
        jne   noretval
 
79
        fstp  %st(0)
 
80
 
 
81
        jmp   epilogue
 
82
 
 
83
retint:
 
84
        cmpl  $FFI_TYPE_INT,%ecx
 
85
        jne   retfloat
 
86
        # Load %ecx with the pointer to storage for the return value
 
87
        movl  24(%ebp),%ecx
 
88
        movl  %eax,0(%ecx)
 
89
        jmp   epilogue
 
90
 
 
91
retfloat:
 
92
        cmpl  $FFI_TYPE_FLOAT,%ecx
 
93
        jne   retdouble   
 
94
         # Load %ecx with the pointer to storage for the return value
 
95
        movl  24(%ebp),%ecx
 
96
        fstps (%ecx)
 
97
        jmp   epilogue
 
98
 
 
99
retdouble:
 
100
        cmpl  $FFI_TYPE_DOUBLE,%ecx
 
101
        jne   retlongdouble
 
102
        # Load %ecx with the pointer to storage for the return value
 
103
        movl  24(%ebp),%ecx
 
104
        fstpl (%ecx)
 
105
        jmp   epilogue
 
106
 
 
107
retlongdouble:
 
108
        cmpl  $FFI_TYPE_LONGDOUBLE,%ecx
 
109
        jne   retint64
 
110
        # Load %ecx with the pointer to storage for the return value
 
111
        movl  24(%ebp),%ecx
 
112
        fstpt (%ecx)
 
113
        jmp   epilogue
 
114
 
 
115
retint64:
 
116
        cmpl  $FFI_TYPE_SINT64,%ecx
 
117
        jne   retstruct1b
 
118
        # Load %ecx with the pointer to storage for the return value
 
119
        movl  24(%ebp),%ecx
 
120
        movl  %eax,0(%ecx)
 
121
        movl  %edx,4(%ecx)
 
122
 
 
123
retstruct1b:
 
124
        cmpl  $FFI_TYPE_SINT8,%ecx
 
125
        jne   retstruct2b
 
126
        # Load %ecx with the pointer to storage for the return value
 
127
        movl  24(%ebp),%ecx
 
128
        movb  %al,0(%ecx)
 
129
        jmp   epilogue
 
130
 
 
131
retstruct2b:
 
132
        cmpl  $FFI_TYPE_SINT16,%ecx
 
133
        jne   retstruct
 
134
        # Load %ecx with the pointer to storage for the return value
 
135
        movl  24(%ebp),%ecx
 
136
        movw  %ax,0(%ecx)
 
137
        jmp   epilogue
 
138
 
 
139
retstruct:
 
140
        # Nothing to do!
 
141
 
 
142
noretval:
 
143
epilogue:
 
144
        movl %ebp,%esp
 
145
        popl %ebp
 
146
        ret
 
147
 
 
148
.ffi_call_SYSV_end:
 
149
 
 
150
        # This assumes we are using gas.
 
151
        .balign 16
 
152
.globl _ffi_call_STDCALL
 
153
 
 
154
_ffi_call_STDCALL:
 
155
        pushl %ebp
 
156
        movl  %esp,%ebp
 
157
 
 
158
        # Make room for all of the new args.
 
159
        movl  16(%ebp),%ecx 
 
160
        subl  %ecx,%esp
 
161
 
 
162
        movl  %esp,%eax
 
163
 
 
164
        # Place all of the ffi_prep_args in position
 
165
        pushl 12(%ebp)
 
166
        pushl %eax
 
167
        call  *8(%ebp)
 
168
 
 
169
        # Return stack to previous state and call the function
 
170
        addl  $8,%esp
 
171
 
 
172
        # FIXME: Align the stack to a 128-bit boundary to avoid
 
173
        # potential performance hits.
 
174
 
 
175
        call  *28(%ebp)
 
176
 
 
177
        # stdcall functions pop arguments off the stack themselves
 
178
 
 
179
        # Load %ecx with the return type code
 
180
        movl  20(%ebp),%ecx
 
181
 
 
182
        # If the return value pointer is NULL, assume no return value.
 
183
        cmpl  $0,24(%ebp)
 
184
        jne   sc_retint
 
185
 
 
186
        # Even if there is no space for the return value, we are
 
187
        # obliged to handle floating-point values.
 
188
        cmpl  $FFI_TYPE_FLOAT,%ecx
 
189
        jne   sc_noretval
 
190
        fstp  %st(0)
 
191
 
 
192
        jmp   sc_epilogue
 
193
 
 
194
sc_retint:
 
195
        cmpl  $FFI_TYPE_INT,%ecx
 
196
        jne   sc_retfloat
 
197
        # Load %ecx with the pointer to storage for the return value
 
198
        movl  24(%ebp),%ecx
 
199
        movl  %eax,0(%ecx)
 
200
        jmp   sc_epilogue
 
201
 
 
202
sc_retfloat:
 
203
        cmpl  $FFI_TYPE_FLOAT,%ecx
 
204
        jne   sc_retdouble
 
205
         # Load %ecx with the pointer to storage for the return value
 
206
        movl  24(%ebp),%ecx
 
207
        fstps (%ecx)
 
208
        jmp   sc_epilogue
 
209
 
 
210
sc_retdouble:
 
211
        cmpl  $FFI_TYPE_DOUBLE,%ecx
 
212
        jne   sc_retlongdouble
 
213
        # Load %ecx with the pointer to storage for the return value
 
214
        movl  24(%ebp),%ecx
 
215
        fstpl (%ecx)
 
216
        jmp   sc_epilogue
 
217
 
 
218
sc_retlongdouble:
 
219
        cmpl  $FFI_TYPE_LONGDOUBLE,%ecx
 
220
        jne   sc_retint64
 
221
        # Load %ecx with the pointer to storage for the return value
 
222
        movl  24(%ebp),%ecx
 
223
        fstpt (%ecx)
 
224
        jmp   sc_epilogue
 
225
 
 
226
sc_retint64:
 
227
        cmpl  $FFI_TYPE_SINT64,%ecx
 
228
        jne   sc_retstruct1b
 
229
        # Load %ecx with the pointer to storage for the return value
 
230
        movl  24(%ebp),%ecx
 
231
        movl  %eax,0(%ecx)
 
232
        movl  %edx,4(%ecx)
 
233
 
 
234
sc_retstruct1b:
 
235
        cmpl  $FFI_TYPE_SINT8,%ecx
 
236
        jne   sc_retstruct2b
 
237
        # Load %ecx with the pointer to storage for the return value
 
238
        movl  24(%ebp),%ecx
 
239
        movb  %al,0(%ecx)
 
240
        jmp   sc_epilogue
 
241
 
 
242
sc_retstruct2b:
 
243
        cmpl  $FFI_TYPE_SINT16,%ecx
 
244
        jne   sc_retstruct
 
245
        # Load %ecx with the pointer to storage for the return value
 
246
        movl  24(%ebp),%ecx
 
247
        movw  %ax,0(%ecx)
 
248
        jmp   sc_epilogue
 
249
 
 
250
sc_retstruct:
 
251
        # Nothing to do!
 
252
 
 
253
sc_noretval:
 
254
sc_epilogue:
 
255
        movl %ebp,%esp
 
256
        popl %ebp
 
257
        ret
 
258
 
 
259
.ffi_call_STDCALL_end:
 
260
 
 
261
        .globl _ffi_closure_SYSV
 
262
_ffi_closure_SYSV:
 
263
        pushl   %ebp
 
264
        movl    %esp, %ebp
 
265
        subl    $40, %esp
 
266
        leal    -24(%ebp), %edx
 
267
        movl    %edx, -12(%ebp) /* resp */
 
268
        leal    8(%ebp), %edx
 
269
        movl    %edx, 4(%esp)   /* args = __builtin_dwarf_cfa () */
 
270
        leal    -12(%ebp), %edx
 
271
        movl    %edx, (%esp)    /* &resp */
 
272
        call    _ffi_closure_SYSV_inner
 
273
        movl    -12(%ebp), %ecx
 
274
        cmpl    $FFI_TYPE_INT, %eax
 
275
        je      .Lcls_retint
 
276
        cmpl    $FFI_TYPE_FLOAT, %eax
 
277
        je      .Lcls_retfloat
 
278
        cmpl    $FFI_TYPE_DOUBLE, %eax
 
279
        je      .Lcls_retdouble
 
280
        cmpl    $FFI_TYPE_LONGDOUBLE, %eax
 
281
        je      .Lcls_retldouble
 
282
        cmpl    $FFI_TYPE_SINT64, %eax
 
283
        je      .Lcls_retllong
 
284
        cmpl    $FFI_TYPE_SINT8, %eax   /* 1-byte struct */
 
285
        je      .Lcls_retstruct1
 
286
        cmpl    $FFI_TYPE_SINT16, %eax  /* 2-bytes struct */
 
287
        je      .Lcls_retstruct2
 
288
.Lcls_epilogue:
 
289
        movl    %ebp, %esp
 
290
        popl    %ebp
 
291
        ret
 
292
.Lcls_retint:
 
293
        movl    (%ecx), %eax
 
294
        jmp     .Lcls_epilogue
 
295
.Lcls_retfloat:
 
296
        flds    (%ecx)
 
297
        jmp     .Lcls_epilogue
 
298
.Lcls_retdouble:
 
299
        fldl    (%ecx)
 
300
        jmp     .Lcls_epilogue
 
301
.Lcls_retldouble:
 
302
        fldt    (%ecx)
 
303
        jmp     .Lcls_epilogue
 
304
.Lcls_retllong:
 
305
        movl    (%ecx), %eax
 
306
        movl    4(%ecx), %edx
 
307
        jmp     .Lcls_epilogue
 
308
.Lcls_retstruct1:
 
309
        movsbl  (%ecx), %eax
 
310
        jmp     .Lcls_epilogue
 
311
.Lcls_retstruct2:
 
312
        movswl  (%ecx), %eax
 
313
        jmp     .Lcls_epilogue
 
314
.ffi_closure_SYSV_end:
 
315
 
 
316
#if !FFI_NO_RAW_API
 
317
 
 
318
#define RAW_CLOSURE_CIF_OFFSET ((FFI_TRAMPOLINE_SIZE + 3) & ~3)
 
319
#define RAW_CLOSURE_FUN_OFFSET (RAW_CLOSURE_CIF_OFFSET + 4)
 
320
#define RAW_CLOSURE_USER_DATA_OFFSET (RAW_CLOSURE_FUN_OFFSET + 4)
 
321
#define CIF_FLAGS_OFFSET 20
 
322
 
 
323
        .balign 16
 
324
        .globl _ffi_closure_raw_SYSV
 
325
_ffi_closure_raw_SYSV:
 
326
        pushl   %ebp
 
327
        movl    %esp, %ebp
 
328
        pushl   %esi
 
329
        subl    $36, %esp
 
330
        movl    RAW_CLOSURE_CIF_OFFSET(%eax), %esi       /* closure->cif */
 
331
        movl    RAW_CLOSURE_USER_DATA_OFFSET(%eax), %edx /* closure->user_data */
 
332
        movl    %edx, 12(%esp)  /* user_data */
 
333
        leal    8(%ebp), %edx   /* __builtin_dwarf_cfa () */
 
334
        movl    %edx, 8(%esp)   /* raw_args */
 
335
        leal    -24(%ebp), %edx
 
336
        movl    %edx, 4(%esp)   /* &res */
 
337
        movl    %esi, (%esp)    /* cif */
 
338
        call    *RAW_CLOSURE_FUN_OFFSET(%eax)            /* closure->fun */
 
339
        movl    CIF_FLAGS_OFFSET(%esi), %eax             /* rtype */
 
340
        cmpl    $FFI_TYPE_INT, %eax
 
341
        je      .Lrcls_retint
 
342
        cmpl    $FFI_TYPE_FLOAT, %eax
 
343
        je      .Lrcls_retfloat
 
344
        cmpl    $FFI_TYPE_DOUBLE, %eax
 
345
        je      .Lrcls_retdouble
 
346
        cmpl    $FFI_TYPE_LONGDOUBLE, %eax
 
347
        je      .Lrcls_retldouble
 
348
        cmpl    $FFI_TYPE_SINT64, %eax
 
349
        je      .Lrcls_retllong
 
350
.Lrcls_epilogue:
 
351
        addl    $36, %esp
 
352
        popl    %esi
 
353
        popl    %ebp
 
354
        ret
 
355
.Lrcls_retint:
 
356
        movl    -24(%ebp), %eax
 
357
        jmp     .Lrcls_epilogue
 
358
.Lrcls_retfloat:
 
359
        flds    -24(%ebp)
 
360
        jmp     .Lrcls_epilogue
 
361
.Lrcls_retdouble:
 
362
        fldl    -24(%ebp)
 
363
        jmp     .Lrcls_epilogue
 
364
.Lrcls_retldouble:
 
365
        fldt    -24(%ebp)
 
366
        jmp     .Lrcls_epilogue
 
367
.Lrcls_retllong:
 
368
        movl    -24(%ebp), %eax
 
369
        movl    -20(%ebp), %edx
 
370
        jmp     .Lrcls_epilogue
 
371
.ffi_closure_raw_SYSV_end:
 
372
 
 
373
#endif