arm: Add argument space for the hidden struct return pointer This should have been failing all along, but it's only exposed by the complex_int test case.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
diff --git a/src/arm/ffi.c b/src/arm/ffi.c
index 9a11e8f..eabab47 100644
--- a/src/arm/ffi.c
+++ b/src/arm/ffi.c
@@ -202,17 +202,7 @@ ffi_status
ffi_prep_cif_machdep (ffi_cif *cif)
{
int flags = 0, cabi = cif->abi;
- size_t bytes;
-
- /* Round the stack up to a multiple of 8 bytes. This isn't needed
- everywhere, but it is on some platforms, and it doesn't harm anything
- when it isn't needed. */
- bytes = ALIGN (cif->bytes, 8);
-
- /* Minimum stack space is the 4 register arguments that we pop. */
- if (bytes < 4*4)
- bytes = 4*4;
- cif->bytes = bytes;
+ size_t bytes = cif->bytes;
/* Map out the register placements of VFP register args. The VFP
hard-float calling conventions are slightly more sophisticated
@@ -270,12 +260,29 @@ ffi_prep_cif_machdep (ffi_cif *cif)
A Composite Type larger than 4 bytes, or whose size cannot
be determined statically ... is stored in memory at an
address passed [in r0]. */
- flags = (cif->rtype->size <= 4 ? ARM_TYPE_INT : ARM_TYPE_STRUCT);
+ if (cif->rtype->size <= 4)
+ flags = ARM_TYPE_INT;
+ else
+ {
+ flags = ARM_TYPE_STRUCT;
+ bytes += 4;
+ }
break;
default:
abort();
}
+
+ /* Round the stack up to a multiple of 8 bytes. This isn't needed
+ everywhere, but it is on some platforms, and it doesn't harm anything
+ when it isn't needed. */
+ bytes = ALIGN (bytes, 8);
+
+ /* Minimum stack space is the 4 register arguments that we pop. */
+ if (bytes < 4*4)
+ bytes = 4*4;
+
+ cif->bytes = bytes;
cif->flags = flags;
return FFI_OK;