diff options
author | Anthony Green <green@moxielogic.com> | 2013-02-06 17:37:15 -0500 |
---|---|---|
committer | Anthony Green <green@moxielogic.com> | 2013-02-06 17:37:15 -0500 |
commit | 6a790129427121f7db2d876e7218a3104e6d2741 (patch) | |
tree | 8238ff3b070fe20edef80d3d108b7e0b6884cead | |
parent | 370112938e705128fd5dd4017fc1a1210bd0271a (diff) | |
download | libffi-6a790129427121f7db2d876e7218a3104e6d2741.tar.gz |
Work around LLVM ABI problem on x86-64
-rw-r--r-- | ChangeLog | 5 | ||||
-rw-r--r-- | src/x86/ffi64.c | 21 |
2 files changed, 24 insertions, 2 deletions
@@ -1,3 +1,8 @@ +2013-02-02 Mark H Weaver <mhw@netris.org> + + * src/x86/ffi64.c (ffi_call): Sign-extend integer arguments passed + via general purpose registers. + 2013-01-21 Nathan Rossi <nathan.rossi@xilinx.com> * README: Add MicroBlaze details. diff --git a/src/x86/ffi64.c b/src/x86/ffi64.c index b8a823d..2014af2 100644 --- a/src/x86/ffi64.c +++ b/src/x86/ffi64.c @@ -484,8 +484,25 @@ ffi_call (ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue) { case X86_64_INTEGER_CLASS: case X86_64_INTEGERSI_CLASS: - reg_args->gpr[gprcount] = 0; - memcpy (®_args->gpr[gprcount], a, size < 8 ? size : 8); + /* Sign-extend integer arguments passed in general + purpose registers, to cope with the fact that + LLVM incorrectly assumes that this will be done + (the x86-64 PS ABI does not specify this). */ + switch (arg_types[i]->type) + { + case FFI_TYPE_SINT8: + *(SINT64 *)®_args->gpr[gprcount] = (SINT64) *((SINT8 *) a); + break; + case FFI_TYPE_SINT16: + *(SINT64 *)®_args->gpr[gprcount] = (SINT64) *((SINT16 *) a); + break; + case FFI_TYPE_SINT32: + *(SINT64 *)®_args->gpr[gprcount] = (SINT64) *((SINT32 *) a); + break; + default: + reg_args->gpr[gprcount] = 0; + memcpy (®_args->gpr[gprcount], a, size < 8 ? size : 8); + } gprcount++; break; case X86_64_SSE_CLASS: |