From b691585785086024549cfb9ac65f3397263965aa Mon Sep 17 00:00:00 2001 From: grischka Date: Tue, 4 Oct 2016 17:36:51 +0200 Subject: tccgen: arm/i386: save_reg_upstack tccgen.c:gv() when loading long long from lvalue, before was saving all registers which caused problems in the arm function call register parameter preparation, as with void foo(long long y, int x); int main(void) { unsigned int *xx[1], x; unsigned long long *yy[1], y; foo(**yy, **xx); return 0; } Now only the modified register is saved if necessary, as in this case where it is used to store the result of the post-inc: long long *p, v, **pp; v = 1; p = &v; p[0]++; printf("another long long spill test : %lld\n", *p); i386-gen.c : - found a similar problem with TOK_UMULL caused by the vstack juggle in tccgen:gen_opl() (bug seen only when using EBX as 4th register) --- tccgen.c | 44 ++++++++++++++++++++++++++------------------ 1 file changed, 26 insertions(+), 18 deletions(-) (limited to 'tccgen.c') diff --git a/tccgen.c b/tccgen.c index 56be31b..8144dc0 100644 --- a/tccgen.c +++ b/tccgen.c @@ -533,17 +533,35 @@ static void vdup(void) vpushv(vtop); } +/* save registers up to (vtop - n) stack entry */ +ST_FUNC void save_regs(int n) +{ + SValue *p, *p1; + for(p = vstack, p1 = vtop - n; p <= p1; p++) + save_reg(p->r); +} + /* save r to the memory stack, and mark it as being free */ ST_FUNC void save_reg(int r) +{ + save_reg_upstack(r, 0); +} + +/* save r to the memory stack, and mark it as being free, + if seen up to (vtop - n) stack entry */ +ST_FUNC void save_reg_upstack(int r, int n) { int l, saved, size, align; - SValue *p, sv; + SValue *p, *p1, sv; CType *type; + if ((r &= VT_VALMASK) >= VT_CONST) + return; + /* modify all stack values */ saved = 0; l = 0; - for(p=vstack;p<=vtop;p++) { + for(p = vstack, p1 = vtop - n; p <= p1; p++) { if ((p->r & VT_VALMASK) == r || ((p->type.t & VT_BTYPE) == VT_LLONG && (p->r2 & VT_VALMASK) == r)) { /* must save value on stack if not already done */ @@ -659,20 +677,6 @@ ST_FUNC int get_reg(int rc) return -1; } -/* save registers up to (vtop - n) stack entry */ -ST_FUNC void save_regs(int n) -{ - int r; - SValue *p, *p1; - p1 = vtop - n; - for(p = vstack;p <= p1; p++) { - r = p->r & VT_VALMASK; - if (r < VT_CONST) { - save_reg(r); - } - } -} - /* move register 's' (of type 't') to 'r', and flush previous value of r to memory if needed */ static void move_reg(int r, int s, int t) @@ -859,13 +863,17 @@ ST_FUNC int gv(int rc) vpushi(ll >> 32); /* second word */ } else #endif - if (r >= VT_CONST || /* XXX: test to VT_CONST incorrect ? */ - (vtop->r & VT_LVAL)) { + if (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. */ + #if 0 save_regs(1); + #else + /* lvalue_save: save only if used further down the stack */ + save_reg_upstack(vtop->r, 1); + #endif /* load from memory */ vtop->type.t = load_type; load(r, vtop); -- cgit v1.3.1