From 5805b07218aef3c1049b5db9d89841d383ee917d Mon Sep 17 00:00:00 2001 From: grischka <grischka> Date: Mon, 3 Oct 2016 12:27:50 +0200 Subject: [PATCH] Alternative fix for "Incorrect function call code on ARMv6" "make test" crashes without that "save_regs()". This partially reverts commit 49d3118621a68f6583228f123efd16f0f803d908. Found another solution: In a 2nd pass Just look if any of the argument registers has been saved again, and restore if so. --- arm-gen.c | 11 +++++++++++ tccgen.c | 5 +++++ 2 files changed, 16 insertions(+) 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);