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:
parent
dcec8673f2
commit
48fc746652
1 changed files with 6 additions and 3 deletions
|
|
@ -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
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue