diff options
author | Ranjit Mathew <rmathew@hotmail.com> | 2002-12-06 01:16:45 +0000 |
---|---|---|
committer | Anthony Green <green@gcc.gnu.org> | 2002-12-06 01:16:45 +0000 |
commit | eb3c46a17ebe3dfe1b374d40f8a8296a83e24751 (patch) | |
tree | 42b4b6f3ce932aab0dbf81a4fb15247efd28b464 /libffi/src/x86/win32.S | |
parent | 1fcfaf375c135079ebea8aa17e726c51c938cc61 (diff) | |
download | gcc-eb3c46a17ebe3dfe1b374d40f8a8296a83e24751.tar.gz |
ffi.h.in: Added FFI_STDCALL ffi_type enumeration for X86_WIN32.
2002-11-10 Ranjit Mathew <rmathew@hotmail.com>
* include/ffi.h.in: Added FFI_STDCALL ffi_type
enumeration for X86_WIN32.
* src/x86/win32.S: Added ffi_call_STDCALL function
definition.
* src/x86/ffi.c (ffi_call/ffi_raw_call): Added
switch cases for recognising FFI_STDCALL and
calling ffi_call_STDCALL if target is X86_WIN32.
* src/ffitest.c (my_stdcall_strlen/stdcall_many):
stdcall versions of the "my_strlen" and "many"
test functions (for X86_WIN32).
Added test cases to test stdcall invocation using
these functions.
From-SVN: r59878
Diffstat (limited to 'libffi/src/x86/win32.S')
-rw-r--r-- | libffi/src/x86/win32.S | 105 |
1 files changed, 103 insertions, 2 deletions
diff --git a/libffi/src/x86/win32.S b/libffi/src/x86/win32.S index 520d1fc0898..796af18754b 100644 --- a/libffi/src/x86/win32.S +++ b/libffi/src/x86/win32.S @@ -1,5 +1,8 @@ /* ----------------------------------------------------------------------- - win32.S - Copyright (c) 1996, 1998, 2001 Cygnus Solutions + win32.S - Copyright (c) 1996, 1998, 2001, 2002 Red Hat, Inc. + Copyright (c) 2001 John Beniton + Copyright (c) 2002 Ranjit Mathew + X86 Foreign Function Interface @@ -52,7 +55,10 @@ _ffi_call_SYSV: # Return stack to previous state and call the function addl $8,%esp - call *28(%ebp) + # FIXME: Align the stack to a 128-bit boundary to avoid + # potential performance hits. + + call *28(%ebp) # Remove the space we pushed for the args movl 16(%ebp),%ecx @@ -123,3 +129,98 @@ epilogue: ret .ffi_call_SYSV_end: + + # This assumes we are using gas. + .balign 16 +.globl _ffi_call_STDCALL + +_ffi_call_STDCALL: + pushl %ebp + movl %esp,%ebp + + # Make room for all of the new args. + movl 16(%ebp),%ecx + subl %ecx,%esp + + movl %esp,%eax + + # Place all of the ffi_prep_args in position + pushl 12(%ebp) + pushl %eax + call *8(%ebp) + + # Return stack to previous state and call the function + addl $8,%esp + + # FIXME: Align the stack to a 128-bit boundary to avoid + # potential performance hits. + + call *28(%ebp) + + # stdcall functions pop arguments off the stack themselves + + # Load %ecx with the return type code + movl 20(%ebp),%ecx + + # If the return value pointer is NULL, assume no return value. + cmpl $0,24(%ebp) + jne sc_retint + + # Even if there is no space for the return value, we are + # obliged to handle floating-point values. + cmpl $FFI_TYPE_FLOAT,%ecx + jne sc_noretval + fstp %st(0) + + jmp sc_epilogue + +sc_retint: + cmpl $FFI_TYPE_INT,%ecx + jne sc_retfloat + # Load %ecx with the pointer to storage for the return value + movl 24(%ebp),%ecx + movl %eax,0(%ecx) + jmp sc_epilogue + +sc_retfloat: + cmpl $FFI_TYPE_FLOAT,%ecx + jne sc_retdouble + # Load %ecx with the pointer to storage for the return value + movl 24(%ebp),%ecx + fstps (%ecx) + jmp sc_epilogue + +sc_retdouble: + cmpl $FFI_TYPE_DOUBLE,%ecx + jne sc_retlongdouble + # Load %ecx with the pointer to storage for the return value + movl 24(%ebp),%ecx + fstpl (%ecx) + jmp sc_epilogue + +sc_retlongdouble: + cmpl $FFI_TYPE_LONGDOUBLE,%ecx + jne sc_retint64 + # Load %ecx with the pointer to storage for the return value + movl 24(%ebp),%ecx + fstpt (%ecx) + jmp sc_epilogue + +sc_retint64: + cmpl $FFI_TYPE_SINT64,%ecx + jne sc_retstruct + # Load %ecx with the pointer to storage for the return value + movl 24(%ebp),%ecx + movl %eax,0(%ecx) + movl %edx,4(%ecx) + +sc_retstruct: + # Nothing to do! + +sc_noretval: +sc_epilogue: + movl %ebp,%esp + popl %ebp + ret + +.ffi_call_STDCALL_end: |