aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Preud'homme <robotux@celest.fr>2013-11-25 10:51:39 +0800
committerThomas Preud'homme <robotux@celest.fr>2013-11-25 10:58:00 +0800
commit48fc7466527d8b3409f313421e8aed559563bfdb (patch)
tree01fec978c2a548a2053577826228b4736977a68a
parentdcec8673f21da86ae3dcf1ca3e9498127715b795 (diff)
downloadtinycc-48fc7466527d8b3409f313421e8aed559563bfdb.tar.gz
tinycc-48fc7466527d8b3409f313421e8aed559563bfdb.tar.bz2
Fix structure passing in ARM calling convention
Fix the address on stack where a structure is copied when it is a parameter of a function call. This address must be computed from the stack pointer and a possible padding offset.
-rw-r--r--arm-gen.c9
1 files changed, 6 insertions, 3 deletions
diff --git a/arm-gen.c b/arm-gen.c
index 6d0acd8..8b07708 100644
--- a/arm-gen.c
+++ b/arm-gen.c
@@ -1020,19 +1020,22 @@ static int copy_params(int nb_args, struct plan *plan, int todo)
case CORE_STRUCT_CLASS:
case VFP_STRUCT_CLASS:
if ((pplan->sval->type.t & VT_BTYPE) == VT_STRUCT) {
+ int padding = 0;
size = type_size(&pplan->sval->type, &align);
/* align to stack align size */
size = (size + 3) & ~3;
if (i == STACK_CLASS && pplan->prev)
- size += pplan->start - pplan->prev->end; /* Add padding if any */
+ padding = pplan->start - pplan->prev->end;
+ size += padding; /* Add padding if any */
/* allocate the necessary size on stack */
gadd_sp(-size);
/* generate structure store */
r = get_reg(RC_INT);
- o(0xE1A0000D|(intr(r)<<12)); /* mov r, sp */
+ o(0xE28D0000|(intr(r)<<12)|padding); /* add r, sp, padding */
vset(&vtop->type, r | VT_LVAL, 0);
vswap();
- vstore(); /* memcpy to current sp */
+ vstore(); /* memcpy to current sp + potential padding */
+
/* Homogeneous float aggregate are loaded to VFP registers
immediately since there is no way of loading data in multiple
non consecutive VFP registers as what is done for other