diff --git a/arm-gen.c b/arm-gen.c index 218ace1f..cca9da5d 100644 --- a/arm-gen.c +++ b/arm-gen.c @@ -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; struct param_plan *pplan; + int pass = 0; /* Several constraints require parameters to be copied in a specific order: - 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 VFP regs as the copy might use an even numbered VFP reg that already holds part of a structure. */ +again: for(i = 0; i < NB_CLASSES; i++) { for(pplan = plan->clsplans[i]; pplan; pplan = pplan->prev) { + + if (pass + && (i != CORE_CLASS || pplan->sval->r < VT_CONST)) + continue; + vpushv(pplan->sval); pplan->sval->r = pplan->sval->r2 = VT_CONST; /* disable entry */ 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, without the help of gv(int). */ save_regs(nb_args); diff --git a/tccgen.c b/tccgen.c index d55ee391..56be31bf 100644 --- a/tccgen.c +++ b/tccgen.c @@ -861,6 +861,11 @@ ST_FUNC int gv(int rc) #endif if (r >= VT_CONST || /* XXX: test to VT_CONST incorrect ? */ (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 */ vtop->type.t = load_type; load(r, vtop);