diff options
author | bstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-02-10 09:19:02 +0000 |
---|---|---|
committer | bstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-02-10 09:19:02 +0000 |
commit | 652cd6cb0c05beda207c196311f6325ddb7ff363 (patch) | |
tree | 45734f85050b1de673fb8968f0f13406670db738 /libffi/src/x86/ffi.c | |
parent | 0c371dfad594c22f8062f7cd9f831ec60998d0b3 (diff) | |
download | gcc-652cd6cb0c05beda207c196311f6325ddb7ff363.tar.gz |
2012-02-10 Basile Starynkevitch <basile@starynkevitch.net>
MELT branch merged with trunk rev 184083 using svnmerge
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/melt-branch@184084 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libffi/src/x86/ffi.c')
-rw-r--r-- | libffi/src/x86/ffi.c | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/libffi/src/x86/ffi.c b/libffi/src/x86/ffi.c index bbfd95e5ec1..7c01c57c4db 100644 --- a/libffi/src/x86/ffi.c +++ b/libffi/src/x86/ffi.c @@ -449,6 +449,8 @@ void FFI_HIDDEN ffi_closure_raw_SYSV (ffi_raw_closure *) #ifdef X86_WIN32 void FFI_HIDDEN ffi_closure_STDCALL (ffi_closure *) __attribute__ ((regparm(1))); +void FFI_HIDDEN ffi_closure_THISCALL (ffi_closure *) + __attribute__ ((regparm(1))); #endif #ifdef X86_WIN64 void FFI_HIDDEN ffi_closure_win64 (ffi_closure *); @@ -608,6 +610,33 @@ ffi_prep_incoming_args_SYSV(char *stack, void **rvalue, void **avalue, *(unsigned int*) &__tramp[6] = __dis; /* jmp __fun */ \ } +#define FFI_INIT_TRAMPOLINE_THISCALL(TRAMP,FUN,CTX,SIZE) \ +{ unsigned char *__tramp = (unsigned char*)(TRAMP); \ + unsigned int __fun = (unsigned int)(FUN); \ + unsigned int __ctx = (unsigned int)(CTX); \ + unsigned int __dis = __fun - (__ctx + 22); \ + unsigned short __size = (unsigned short)(SIZE); \ + *(unsigned int *) &__tramp[0] = 0x8324048b; /* mov (%esp), %eax */ \ + *(unsigned int *) &__tramp[4] = 0x4c890cec; /* sub $12, %esp */ \ + *(unsigned int *) &__tramp[8] = 0x04890424; /* mov %ecx, 4(%esp) */ \ + *(unsigned char*) &__tramp[12] = 0x24; /* mov %eax, (%esp) */ \ + *(unsigned char*) &__tramp[13] = 0xb8; \ + *(unsigned int *) &__tramp[14] = __size; /* mov __size, %eax */ \ + *(unsigned int *) &__tramp[18] = 0x08244c8d; /* lea 8(%esp), %ecx */ \ + *(unsigned int *) &__tramp[22] = 0x4802e8c1; /* shr $2, %eax ; dec %eax */ \ + *(unsigned short*) &__tramp[26] = 0x0b74; /* jz 1f */ \ + *(unsigned int *) &__tramp[28] = 0x8908518b; /* 2b: mov 8(%ecx), %edx */ \ + *(unsigned int *) &__tramp[32] = 0x04c18311; /* mov %edx, (%ecx) ; add $4, %ecx */ \ + *(unsigned char*) &__tramp[36] = 0x48; /* dec %eax */ \ + *(unsigned short*) &__tramp[37] = 0xf575; /* jnz 2b ; 1f: */ \ + *(unsigned char*) &__tramp[39] = 0xb8; \ + *(unsigned int*) &__tramp[40] = __ctx; /* movl __ctx, %eax */ \ + *(unsigned char *) &__tramp[44] = 0xe8; \ + *(unsigned int*) &__tramp[45] = __dis; /* call __fun */ \ + *(unsigned char*) &__tramp[49] = 0xc2; /* ret */ \ + *(unsigned short*) &__tramp[50] = (__size + 8); /* ret (__size + 8) */ \ + } + #define FFI_INIT_TRAMPOLINE_STDCALL(TRAMP,FUN,CTX,SIZE) \ { unsigned char *__tramp = (unsigned char*)(TRAMP); \ unsigned int __fun = (unsigned int)(FUN); \ @@ -650,6 +679,13 @@ ffi_prep_closure_loc (ffi_closure* closure, (void*)codeloc); } #ifdef X86_WIN32 + else if (cif->abi == FFI_THISCALL) + { + FFI_INIT_TRAMPOLINE_THISCALL (&closure->tramp[0], + &ffi_closure_THISCALL, + (void*)codeloc, + cif->bytes); + } else if (cif->abi == FFI_STDCALL) { FFI_INIT_TRAMPOLINE_STDCALL (&closure->tramp[0], |