diff options
| author | grischka <grischka> | 2016-10-03 12:27:50 +0200 |
|---|---|---|
| committer | grischka <grischka> | 2016-10-03 12:33:41 +0200 |
| commit | 5805b07218aef3c1049b5db9d89841d383ee917d (patch) | |
| tree | 846727d417b859d959bbee0cfa697c87d34fbdb9 | |
| parent | 78f1c10e0f10770880d50d917910adfdedd646a2 (diff) | |
| download | tinycc-5805b07218aef3c1049b5db9d89841d383ee917d.tar.gz tinycc-5805b07218aef3c1049b5db9d89841d383ee917d.tar.bz2 | |
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.
| -rw-r--r-- | arm-gen.c | 11 | ||||
| -rw-r--r-- | tccgen.c | 5 |
2 files changed, 16 insertions, 0 deletions
@@ -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); @@ -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); |
