From 7963b04a181b9cab7bf9a0d7414a206402a98a96 Mon Sep 17 00:00:00 2001 From: Ken Thompson Date: Wed, 19 Jan 2011 16:30:13 -0800 Subject: [PATCH] arm bug with stack adjust R=r CC=golang-dev https://golang.org/cl/3980043 --- src/cmd/5g/opt.h | 1 - src/cmd/5g/reg.c | 68 ++++++++++++++++++++++++++++++++---------------- 2 files changed, 46 insertions(+), 23 deletions(-) diff --git a/src/cmd/5g/opt.h b/src/cmd/5g/opt.h index a3e3abc135a..7a0070fc9dc 100644 --- a/src/cmd/5g/opt.h +++ b/src/cmd/5g/opt.h @@ -69,7 +69,6 @@ struct Reg uint16 loop; // x5 for every loop uchar refset; // diagnostic generated - uchar nomove; // funny mov instruction Reg* p1; Reg* p2; diff --git a/src/cmd/5g/reg.c b/src/cmd/5g/reg.c index a6d35f99779..d30d03b2060 100644 --- a/src/cmd/5g/reg.c +++ b/src/cmd/5g/reg.c @@ -143,7 +143,7 @@ regopt(Prog *firstp) first++; if(debug['K']) { - if(first != 4) + if(first != 1) return; // debug['R'] = 2; // debug['P'] = 2; @@ -191,21 +191,6 @@ regopt(Prog *firstp) case ANAME: case ASIGNAME: continue; - - case AMOVW: - // mark instructions that set SP - if(p->to.type == D_REG) { - switch(p->to.reg) { - case REGSP: - case REGLINK: - case REGPC: - r->nomove = 1; - break; - } - } - if(p->scond != C_SCOND_NONE) - r->nomove = 1; - break; } r = rega(); nr++; @@ -323,6 +308,7 @@ regopt(Prog *firstp) if(debug['R']) { p = firstr->prog; print("\n%L %D\n", p->lineno, &p->from); + print(" addr = %Q\n", addrs); } /* @@ -386,6 +372,7 @@ loop2: r->refahead.b[z] | r->calahead.b[z] | r->refbehind.b[z] | r->calbehind.b[z] | r->use1.b[z] | r->use2.b[z]; + bit.b[z] &= ~addrs.b[z]; } if(bany(&bit)) { @@ -511,18 +498,61 @@ brk: * last pass * eliminate nops * free aux structures + * adjust the stack pointer + * MOVW.W R1,-12(R13) <<- start + * MOVW R0,R1 + * MOVW R1,8(R13) + * MOVW $0,R1 + * MOVW R1,4(R13) + * BL ,runtime.newproc+0(SB) + * MOVW &ft+-32(SP),R7 <<- adjust + * MOVW &j+-40(SP),R6 <<- adjust + * MOVW autotmp_0003+-24(SP),R5 <<- adjust + * MOVW $12(R13),R13 <<- finish */ + vreg = 0; for(p = firstp; p != P; p = p->link) { while(p->link != P && p->link->as == ANOP) p->link = p->link->link; if(p->to.type == D_BRANCH) while(p->to.branch != P && p->to.branch->as == ANOP) p->to.branch = p->to.branch->link; + if(p->as == AMOVW && p->to.reg == 13) { + if(p->scond & C_WBIT) { + vreg = -p->to.offset; // in adjust region +// print("%P adjusting %d\n", p, vreg); + continue; + } + if(p->from.type == D_CONST && p->to.type == D_REG) { + if(p->from.offset != vreg) + print("in and out different\n"); +// print("%P finish %d\n", p, vreg); + vreg = 0; // done adjust region + continue; + } + +// print("%P %d %d from type\n", p, p->from.type, D_CONST); +// print("%P %d %d to type\n\n", p, p->to.type, D_REG); + } + + if(p->as == AMOVW && vreg != 0) { + if(p->from.sym != S) + if(p->from.name == D_AUTO || p->from.name == D_PARAM) { + p->from.offset += vreg; +// print("%P adjusting from %d %d\n", p, vreg, p->from.type); + } + if(p->to.sym != S) + if(p->to.name == D_AUTO || p->to.name == D_PARAM) { + p->to.offset += vreg; +// print("%P adjusting to %d %d\n", p, vreg, p->from.type); + } + } } if(r1 != R) { r1->link = freer; freer = firstr; } + } void @@ -1208,12 +1238,6 @@ paint3(Reg *r, int bn, int32 rb, int rn) r = r1; } - // horrible hack to prevent loading a - // variable after a call (to defer) but - // before popping the SP. - if(r->prog->as == ABL && r->nomove) - r = r->p1; - if(LOAD(r) & ~(r->set.b[z] & ~(r->use1.b[z]|r->use2.b[z])) & bb) addmove(r, bn, rn, 0);