Alternative fix for "Incorrect function call code on ARMv6"

"make test" crashes without that "save_regs()".

This partially reverts
commit 49d3118621.

Found another solution:  In a 2nd pass Just look if
any of the argument registers has been saved again,
and restore if so.
This commit is contained in:
grischka
2016-10-03 12:27:50 +02:00
parent 78f1c10e0f
commit 5805b07218
2 changed files with 16 additions and 0 deletions

View File

@ -1047,6 +1047,7 @@ static int copy_params(int nb_args, struct plan *plan, int todo)
{ {
int size, align, r, i, nb_extra_sval = 0; int size, align, r, i, nb_extra_sval = 0;
struct param_plan *pplan; struct param_plan *pplan;
int pass = 0;
/* Several constraints require parameters to be copied in a specific order: /* Several constraints require parameters to be copied in a specific order:
- structures are copied to the stack before being loaded in a reg; - structures are copied to the stack before being loaded in a reg;
@ -1063,8 +1064,14 @@ static int copy_params(int nb_args, struct plan *plan, int todo)
- parameters assigned to VFP regs be copied before structures assigned to - parameters assigned to VFP regs be copied before structures assigned to
VFP regs as the copy might use an even numbered VFP reg that already VFP regs as the copy might use an even numbered VFP reg that already
holds part of a structure. */ holds part of a structure. */
again:
for(i = 0; i < NB_CLASSES; i++) { for(i = 0; i < NB_CLASSES; i++) {
for(pplan = plan->clsplans[i]; pplan; pplan = pplan->prev) { for(pplan = plan->clsplans[i]; pplan; pplan = pplan->prev) {
if (pass
&& (i != CORE_CLASS || pplan->sval->r < VT_CONST))
continue;
vpushv(pplan->sval); vpushv(pplan->sval);
pplan->sval->r = pplan->sval->r2 = VT_CONST; /* disable entry */ pplan->sval->r = pplan->sval->r2 = VT_CONST; /* disable entry */
switch(i) { switch(i) {
@ -1170,6 +1177,10 @@ static int copy_params(int nb_args, struct plan *plan, int todo)
} }
} }
/* second pass to restore registers that were saved on stack by accident */
if (++pass < 2)
goto again;
/* Manually free remaining registers since next parameters are loaded /* Manually free remaining registers since next parameters are loaded
* manually, without the help of gv(int). */ * manually, without the help of gv(int). */
save_regs(nb_args); save_regs(nb_args);

View File

@ -861,6 +861,11 @@ ST_FUNC int gv(int rc)
#endif #endif
if (r >= VT_CONST || /* XXX: test to VT_CONST incorrect ? */ if (r >= VT_CONST || /* XXX: test to VT_CONST incorrect ? */
(vtop->r & VT_LVAL)) { (vtop->r & VT_LVAL)) {
/* We do not want to modifier the long long
pointer here, so the safest (and less
efficient) is to save all the other registers
in the stack. XXX: totally inefficient. */
save_regs(1);
/* load from memory */ /* load from memory */
vtop->type.t = load_type; vtop->type.t = load_type;
load(r, vtop); load(r, vtop);