Add FFI_GNUW64 ABI for GNU 80-bit long double support
This commit is contained in:
@@ -190,9 +190,11 @@ History
|
|||||||
See the git log for details at http://github.com/libffi/libffi.
|
See the git log for details at http://github.com/libffi/libffi.
|
||||||
|
|
||||||
3.3 TBD
|
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.
|
New API in support of GO closures.
|
||||||
Add RISC-V support.
|
Add RISC-V support.
|
||||||
Many bug fixes.
|
Many bug fixes.
|
||||||
|
|
||||||
3.2.1 Nov-12-14
|
3.2.1 Nov-12-14
|
||||||
Build fix for non-iOS AArch64 targets.
|
Build fix for non-iOS AArch64 targets.
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* -----------------------------------------------------------------*-C-*-
|
/* -----------------------------------------------------------------*-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) 1996-2003, 2010 Red Hat, Inc.
|
||||||
Copyright (C) 2008 Free Software Foundation, Inc.
|
Copyright (C) 2008 Free Software Foundation, Inc.
|
||||||
|
|
||||||
@@ -80,9 +80,14 @@ typedef signed long ffi_sarg;
|
|||||||
typedef enum ffi_abi {
|
typedef enum ffi_abi {
|
||||||
#if defined(X86_WIN64)
|
#if defined(X86_WIN64)
|
||||||
FFI_FIRST_ABI = 0,
|
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,
|
FFI_LAST_ABI,
|
||||||
|
#ifdef __GNUC__
|
||||||
|
FFI_DEFAULT_ABI = FFI_GNUW64
|
||||||
|
#else
|
||||||
FFI_DEFAULT_ABI = FFI_WIN64
|
FFI_DEFAULT_ABI = FFI_WIN64
|
||||||
|
#endif
|
||||||
|
|
||||||
#elif defined(X86_64) || (defined (__x86_64__) && defined (X86_DARWIN))
|
#elif defined(X86_64) || (defined (__x86_64__) && defined (X86_DARWIN))
|
||||||
FFI_FIRST_ABI = 1,
|
FFI_FIRST_ABI = 1,
|
||||||
|
|||||||
@@ -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
|
x86 win64 Foreign Function Interface
|
||||||
|
|
||||||
@@ -52,8 +53,14 @@ EFI64(ffi_prep_cif_machdep)(ffi_cif *cif)
|
|||||||
{
|
{
|
||||||
int flags, n;
|
int flags, n;
|
||||||
|
|
||||||
if (cif->abi != FFI_WIN64)
|
switch (cif->abi)
|
||||||
return FFI_BAD_ABI;
|
{
|
||||||
|
case FFI_WIN64:
|
||||||
|
case FFI_GNUW64:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return FFI_BAD_ABI;
|
||||||
|
}
|
||||||
|
|
||||||
flags = cif->rtype->type;
|
flags = cif->rtype->type;
|
||||||
switch (flags)
|
switch (flags)
|
||||||
@@ -61,7 +68,9 @@ EFI64(ffi_prep_cif_machdep)(ffi_cif *cif)
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
case FFI_TYPE_LONGDOUBLE:
|
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;
|
break;
|
||||||
case FFI_TYPE_COMPLEX:
|
case FFI_TYPE_COMPLEX:
|
||||||
flags = FFI_TYPE_STRUCT;
|
flags = FFI_TYPE_STRUCT;
|
||||||
@@ -106,7 +115,7 @@ ffi_call_int (ffi_cif *cif, void (*fn)(void), void *rvalue,
|
|||||||
size_t rsize;
|
size_t rsize;
|
||||||
struct win64_call_frame *frame;
|
struct win64_call_frame *frame;
|
||||||
|
|
||||||
FFI_ASSERT(cif->abi == FFI_WIN64);
|
FFI_ASSERT(cif->abi == FFI_GNUW64 || cif->abi == FFI_WIN64);
|
||||||
|
|
||||||
flags = cif->flags;
|
flags = cif->flags;
|
||||||
rsize = 0;
|
rsize = 0;
|
||||||
@@ -196,8 +205,14 @@ EFI64(ffi_prep_closure_loc)(ffi_closure* closure,
|
|||||||
};
|
};
|
||||||
char *tramp = closure->tramp;
|
char *tramp = closure->tramp;
|
||||||
|
|
||||||
if (cif->abi != FFI_WIN64)
|
switch (cif->abi)
|
||||||
return FFI_BAD_ABI;
|
{
|
||||||
|
case FFI_WIN64:
|
||||||
|
case FFI_GNUW64:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return FFI_BAD_ABI;
|
||||||
|
}
|
||||||
|
|
||||||
memcpy (tramp, trampoline, sizeof(trampoline));
|
memcpy (tramp, trampoline, sizeof(trampoline));
|
||||||
*(UINT64 *)(tramp + 16) = (uintptr_t)ffi_closure_win64;
|
*(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,
|
EFI64(ffi_prep_go_closure)(ffi_go_closure* closure, ffi_cif* cif,
|
||||||
void (*fun)(ffi_cif*, void*, void**, void*))
|
void (*fun)(ffi_cif*, void*, void**, void*))
|
||||||
{
|
{
|
||||||
if (cif->abi != FFI_WIN64)
|
switch (cif->abi)
|
||||||
return FFI_BAD_ABI;
|
{
|
||||||
|
case FFI_WIN64:
|
||||||
|
case FFI_GNUW64:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return FFI_BAD_ABI;
|
||||||
|
}
|
||||||
|
|
||||||
closure->tramp = ffi_go_closure_win64;
|
closure->tramp = ffi_go_closure_win64;
|
||||||
closure->cif = cif;
|
closure->cif = cif;
|
||||||
|
|||||||
Reference in New Issue
Block a user