]> Cypherpunks repositories - gostls13.git/commitdiff
arm reg bug with SP adjust
authorKen Thompson <ken@golang.org>
Tue, 18 Jan 2011 04:39:26 +0000 (20:39 -0800)
committerKen Thompson <ken@golang.org>
Tue, 18 Jan 2011 04:39:26 +0000 (20:39 -0800)
after call to deferproc

R=r
CC=golang-dev
https://golang.org/cl/4059041

src/cmd/5g/opt.h
src/cmd/5g/peep.c
src/cmd/5g/reg.c

index 9a4e17571c0ab50738b49b8d45fbdc4dd99effe3..a3e3abc135ac246a9d6c59e2ca7dc9955698873a 100644 (file)
@@ -69,6 +69,7 @@ struct        Reg
 
        uint16  loop;           // x5 for every loop
        uchar   refset;         // diagnostic generated
+       uchar   nomove;         // funny mov instruction
 
        Reg*    p1;
        Reg*    p2;
@@ -128,7 +129,7 @@ Reg*        rega(void);
 int    rcmp(const void*, const void*);
 void   regopt(Prog*);
 void   addmove(Reg*, int, int, int);
-Bits   mkvar(Reg *r, Adr *a, int);
+Bits   mkvar(Reg *r, Adr *a);
 void   prop(Reg*, Bits, Bits);
 void   loopit(Reg*, int32);
 void   synch(Reg*, Bits);
index da46f8dda578ee3444cbdbb1854732a2cd409542..b442ee8d168a55953065705ef758b9463e3c25c0 100644 (file)
@@ -983,7 +983,7 @@ copyu(Prog *p, Adr *v, Adr *s)
                                        return 2;
                        } else {
                                if(p->to.reg == v->reg)
-                               return 2;
+                                       return 2;
                        }
                }
                if(s != A) {
index 1d814d2c66626facc209859440aeace854ea8541..a6d35f99779cbe7c95bf456fbd5710564e4fede4 100644 (file)
@@ -83,7 +83,7 @@ setoutvar(void)
                n = nodarg(t, 1);
                a = zprog.from;
                naddr(n, &a, 0);
-               bit = mkvar(R, &a, 0);
+               bit = mkvar(R, &a);
                for(z=0; z<BITS; z++)
                        ovar.b[z] |= bit.b[z];
                t = structnext(&save);
@@ -143,7 +143,7 @@ regopt(Prog *firstp)
        first++;
 
        if(debug['K']) {
-               if(first != 1)
+               if(first != 4)
                        return;
 //             debug['R'] = 2;
 //             debug['P'] = 2;
@@ -165,7 +165,7 @@ regopt(Prog *firstp)
        firstr = R;
        lastr = R;
        nvar = 0;
-       regbits = 0;
+       regbits = RtoB(REGSP)|RtoB(REGLINK)|RtoB(REGPC);
        for(z=0; z<BITS; z++) {
                externs.b[z] = 0;
                params.b[z] = 0;
@@ -191,6 +191,21 @@ 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++;
@@ -220,14 +235,14 @@ regopt(Prog *firstp)
                /*
                 * left side always read
                 */
-               bit = mkvar(r, &p->from, p->as==AMOVW);
+               bit = mkvar(r, &p->from);
                for(z=0; z<BITS; z++)
                        r->use1.b[z] |= bit.b[z];
 
                /*
                 * right side depends on opcode
                 */
-               bit = mkvar(r, &p->to, 0);
+               bit = mkvar(r, &p->to);
                if(bany(&bit))
                switch(p->as) {
                default:
@@ -567,6 +582,9 @@ addmove(Reg *r, int bn, int rn, int f)
        if(a->etype == TARRAY || a->sym == S)
                a->type = D_CONST;
 
+       if(v->addr)
+               fatal("addmove: shouldnt be doing this %A\n", a);
+
        switch(v->etype) {
        default:
                print("What is this %E\n", v->etype);
@@ -636,7 +654,7 @@ overlap(int32 o1, int w1, int32 o2, int w2)
 }
 
 Bits
-mkvar(Reg *r, Adr *a, int docon)
+mkvar(Reg *r, Adr *a)
 {
        Var *v;
        int i, t, n, et, z, w, flag;
@@ -1190,8 +1208,15 @@ 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);
+
        for(;;) {
                r->act.b[z] |= bb;
                p = r->prog;
@@ -1240,6 +1265,9 @@ void
 addreg(Adr *a, int rn)
 {
 
+       if(a->type == D_CONST)
+               fatal("addreg: cant do this %D %d\n", a, rn);
+
        a->sym = 0;
        a->name = D_NONE;
        a->type = D_REG;