diff options
author | Anthony Green <green@moxielogic.com> | 2018-03-18 12:32:10 -0400 |
---|---|---|
committer | Anthony Green <green@moxielogic.com> | 2018-03-18 12:32:10 -0400 |
commit | 9bc40d87ea5950969b234ed56cd2c6acd883fa0e (patch) | |
tree | e23479e94418c56c77f06298cc4ba8e85fa55ce3 | |
parent | d46406088d28b038a0a0f7396d9621f431482f6a (diff) | |
download | libffi-9bc40d87ea5950969b234ed56cd2c6acd883fa0e.tar.gz |
Add FFI_GWIN64 ABI for GNU 80-bit long double support
-rw-r--r-- | README.md | 4 | ||||
-rw-r--r-- | src/x86/ffitarget.h | 9 | ||||
-rw-r--r-- | src/x86/ffiw64.c | 39 |
3 files changed, 40 insertions, 12 deletions
@@ -190,9 +190,11 @@ History See the git log for details at http://github.com/libffi/libffi. 3.3 TBD + Default to Microsoft's 64 bit long double ABI with Visual C++. + GNU compiler uses 80 bits (128 in memory) FFI_GNUW64 ABI. New API in support of GO closures. Add RISC-V support. - Many bug fixes. + Many bug fixes. 3.2.1 Nov-12-14 Build fix for non-iOS AArch64 targets. diff --git a/src/x86/ffitarget.h b/src/x86/ffitarget.h index 25e3f4f..3a0efa5 100644 --- a/src/x86/ffitarget.h +++ b/src/x86/ffitarget.h @@ -1,5 +1,5 @@ /* -----------------------------------------------------------------*-C-*- - ffitarget.h - Copyright (c) 2012, 2014 Anthony Green + ffitarget.h - Copyright (c) 2012, 2014, 2018 Anthony Green Copyright (c) 1996-2003, 2010 Red Hat, Inc. Copyright (C) 2008 Free Software Foundation, Inc. @@ -80,9 +80,14 @@ typedef signed long ffi_sarg; typedef enum ffi_abi { #if defined(X86_WIN64) FFI_FIRST_ABI = 0, - FFI_WIN64, + FFI_WIN64, /* sizeof(long double) == 8 - microsoft compilers */ + FFI_GNUW64, /* sizeof(long double) == 16 - GNU compilers */ FFI_LAST_ABI, +#ifdef __GNUC__ + FFI_DEFAULT_ABI = FFI_GNUW64 +#else FFI_DEFAULT_ABI = FFI_WIN64 +#endif #elif defined(X86_64) || (defined (__x86_64__) && defined (X86_DARWIN)) FFI_FIRST_ABI = 1, diff --git a/src/x86/ffiw64.c b/src/x86/ffiw64.c index fd47c58..f787525 100644 --- a/src/x86/ffiw64.c +++ b/src/x86/ffiw64.c @@ -1,5 +1,6 @@ /* ----------------------------------------------------------------------- - ffiw64.c - Copyright (c) 2014 Red Hat, Inc. + ffiw64.c - Copyright (c) 2018 Anthony Green + Copyright (c) 2014 Red Hat, Inc. x86 win64 Foreign Function Interface @@ -52,8 +53,14 @@ EFI64(ffi_prep_cif_machdep)(ffi_cif *cif) { int flags, n; - if (cif->abi != FFI_WIN64) - return FFI_BAD_ABI; + switch (cif->abi) + { + case FFI_WIN64: + case FFI_GNUW64: + break; + default: + return FFI_BAD_ABI; + } flags = cif->rtype->type; switch (flags) @@ -61,7 +68,9 @@ EFI64(ffi_prep_cif_machdep)(ffi_cif *cif) default: break; case FFI_TYPE_LONGDOUBLE: - flags = FFI_TYPE_STRUCT; + /* GCC returns long double values by reference, like a struct */ + if (cif->abi == FFI_GNUW64) + flags = FFI_TYPE_STRUCT; break; case FFI_TYPE_COMPLEX: flags = FFI_TYPE_STRUCT; @@ -106,7 +115,7 @@ ffi_call_int (ffi_cif *cif, void (*fn)(void), void *rvalue, size_t rsize; struct win64_call_frame *frame; - FFI_ASSERT(cif->abi == FFI_WIN64); + FFI_ASSERT(cif->abi == FFI_GNUW64 || cif->abi == FFI_WIN64); flags = cif->flags; rsize = 0; @@ -196,8 +205,14 @@ EFI64(ffi_prep_closure_loc)(ffi_closure* closure, }; char *tramp = closure->tramp; - if (cif->abi != FFI_WIN64) - return FFI_BAD_ABI; + switch (cif->abi) + { + case FFI_WIN64: + case FFI_GNUW64: + break; + default: + return FFI_BAD_ABI; + } memcpy (tramp, trampoline, sizeof(trampoline)); *(UINT64 *)(tramp + 16) = (uintptr_t)ffi_closure_win64; @@ -213,8 +228,14 @@ ffi_status EFI64(ffi_prep_go_closure)(ffi_go_closure* closure, ffi_cif* cif, void (*fun)(ffi_cif*, void*, void**, void*)) { - if (cif->abi != FFI_WIN64) - return FFI_BAD_ABI; + switch (cif->abi) + { + case FFI_WIN64: + case FFI_GNUW64: + break; + default: + return FFI_BAD_ABI; + } closure->tramp = ffi_go_closure_win64; closure->cif = cif; |