Work around LLVM ABI problem on x86-64

This commit is contained in:
Anthony Green
2013-02-06 17:37:15 -05:00
parent 370112938e
commit 6a79012942
2 changed files with 24 additions and 2 deletions

View File

@@ -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> 2013-01-21 Nathan Rossi <nathan.rossi@xilinx.com>
* README: Add MicroBlaze details. * README: Add MicroBlaze details.

View File

@@ -484,8 +484,25 @@ ffi_call (ffi_cif *cif, void (*fn)(void), void *rvalue, void **avalue)
{ {
case X86_64_INTEGER_CLASS: case X86_64_INTEGER_CLASS:
case X86_64_INTEGERSI_CLASS: case X86_64_INTEGERSI_CLASS:
/* 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 *)&reg_args->gpr[gprcount] = (SINT64) *((SINT8 *) a);
break;
case FFI_TYPE_SINT16:
*(SINT64 *)&reg_args->gpr[gprcount] = (SINT64) *((SINT16 *) a);
break;
case FFI_TYPE_SINT32:
*(SINT64 *)&reg_args->gpr[gprcount] = (SINT64) *((SINT32 *) a);
break;
default:
reg_args->gpr[gprcount] = 0; reg_args->gpr[gprcount] = 0;
memcpy (&reg_args->gpr[gprcount], a, size < 8 ? size : 8); memcpy (&reg_args->gpr[gprcount], a, size < 8 ? size : 8);
}
gprcount++; gprcount++;
break; break;
case X86_64_SSE_CLASS: case X86_64_SSE_CLASS: