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.
This commit is contained in:
Thomas Preud'homme 2013-11-25 10:51:39 +08:00
parent dcec8673f2
commit 48fc746652

View file

@ -1020,19 +1020,22 @@ static int copy_params(int nb_args, struct plan *plan, int todo)
case CORE_STRUCT_CLASS: case CORE_STRUCT_CLASS:
case VFP_STRUCT_CLASS: case VFP_STRUCT_CLASS:
if ((pplan->sval->type.t & VT_BTYPE) == VT_STRUCT) { if ((pplan->sval->type.t & VT_BTYPE) == VT_STRUCT) {
int padding = 0;
size = type_size(&pplan->sval->type, &align); size = type_size(&pplan->sval->type, &align);
/* align to stack align size */ /* align to stack align size */
size = (size + 3) & ~3; size = (size + 3) & ~3;
if (i == STACK_CLASS && pplan->prev) 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 */ /* allocate the necessary size on stack */
gadd_sp(-size); gadd_sp(-size);
/* generate structure store */ /* generate structure store */
r = get_reg(RC_INT); 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); vset(&vtop->type, r | VT_LVAL, 0);
vswap(); vswap();
vstore(); /* memcpy to current sp */ vstore(); /* memcpy to current sp + potential padding */
/* Homogeneous float aggregate are loaded to VFP registers /* Homogeneous float aggregate are loaded to VFP registers
immediately since there is no way of loading data in multiple immediately since there is no way of loading data in multiple
non consecutive VFP registers as what is done for other non consecutive VFP registers as what is done for other