diff options
Diffstat (limited to 'src/cmd/8g/reg.c')
-rw-r--r-- | src/cmd/8g/reg.c | 111 |
1 files changed, 95 insertions, 16 deletions
diff --git a/src/cmd/8g/reg.c b/src/cmd/8g/reg.c index 1465d372c..a2f3def37 100644 --- a/src/cmd/8g/reg.c +++ b/src/cmd/8g/reg.c @@ -33,6 +33,8 @@ #define EXTERN #include "opt.h" +#define NREGVAR 8 +#define REGBITS ((uint32)0xff) #define P2R(p) (Reg*)(p->reg) static int first = 1; @@ -114,6 +116,8 @@ setaddrs(Bits bit) } } +static char* regname[] = { ".ax", ".cx", ".dx", ".bx", ".sp", ".bp", ".si", ".di" }; + void regopt(Prog *firstp) { @@ -142,7 +146,17 @@ regopt(Prog *firstp) r1 = R; firstr = R; lastr = R; - nvar = 0; + + /* + * control flow is more complicated in generated go code + * than in generated c code. define pseudo-variables for + * registers, so we have complete register usage information. + */ + nvar = NREGVAR; + memset(var, 0, NREGVAR*sizeof var[0]); + for(i=0; i<NREGVAR; i++) + var[i].sym = lookup(regname[i]); + regbits = RtoB(D_SP); for(z=0; z<BITS; z++) { externs.b[z] = 0; @@ -249,14 +263,19 @@ regopt(Prog *firstp) /* * right side write */ + case AFSTSW: + case ALEAL: case ANOP: case AMOVL: case AMOVB: case AMOVW: case AMOVBLSX: case AMOVBLZX: + case AMOVBWSX: + case AMOVBWZX: case AMOVWLSX: case AMOVWLZX: + case APOPL: for(z=0; z<BITS; z++) r->set.b[z] |= bit.b[z]; break; @@ -321,6 +340,23 @@ regopt(Prog *firstp) case AADCL: case ASBBL: + case ASETCC: + case ASETCS: + case ASETEQ: + case ASETGE: + case ASETGT: + case ASETHI: + case ASETLE: + case ASETLS: + case ASETLT: + case ASETMI: + case ASETNE: + case ASETOC: + case ASETOS: + case ASETPC: + case ASETPL: + case ASETPS: + case AXCHGB: case AXCHGW: case AXCHGL: @@ -349,20 +385,32 @@ regopt(Prog *firstp) if(p->to.type != D_NONE) break; - case AIDIVB: case AIDIVL: case AIDIVW: - case AIMULB: - case ADIVB: case ADIVL: case ADIVW: - case AMULB: case AMULL: case AMULW: + r->set.b[0] |= RtoB(D_AX) | RtoB(D_DX); + r->use1.b[0] |= RtoB(D_AX) | RtoB(D_DX); + break; + + case AIDIVB: + case AIMULB: + case ADIVB: + case AMULB: + r->set.b[0] |= RtoB(D_AX); + r->use1.b[0] |= RtoB(D_AX); + break; case ACWD: + r->set.b[0] |= RtoB(D_AX) | RtoB(D_DX); + r->use1.b[0] |= RtoB(D_AX); + break; + case ACDQ: - r->regu |= RtoB(D_AX) | RtoB(D_DX); + r->set.b[0] |= RtoB(D_DX); + r->use1.b[0] |= RtoB(D_AX); break; case AREP: @@ -370,7 +418,8 @@ regopt(Prog *firstp) case ALOOP: case ALOOPEQ: case ALOOPNE: - r->regu |= RtoB(D_CX); + r->set.b[0] |= RtoB(D_CX); + r->use1.b[0] |= RtoB(D_CX); break; case AMOVSB: @@ -379,7 +428,8 @@ regopt(Prog *firstp) case ACMPSB: case ACMPSL: case ACMPSW: - r->regu |= RtoB(D_SI) | RtoB(D_DI); + r->set.b[0] |= RtoB(D_SI) | RtoB(D_DI); + r->use1.b[0] |= RtoB(D_SI) | RtoB(D_DI); break; case ASTOSB: @@ -388,16 +438,22 @@ regopt(Prog *firstp) case ASCASB: case ASCASL: case ASCASW: - r->regu |= RtoB(D_AX) | RtoB(D_DI); + r->set.b[0] |= RtoB(D_DI); + r->use1.b[0] |= RtoB(D_AX) | RtoB(D_DI); break; case AINSB: case AINSL: case AINSW: + r->set.b[0] |= RtoB(D_DX) | RtoB(D_DI); + r->use1.b[0] |= RtoB(D_DI); + break; + case AOUTSB: case AOUTSL: case AOUTSW: - r->regu |= RtoB(D_DI) | RtoB(D_DX); + r->set.b[0] |= RtoB(D_DI); + r->use1.b[0] |= RtoB(D_DX) | RtoB(D_DI); break; } } @@ -504,6 +560,24 @@ loop2: dumpit("pass4", firstr); /* + * pass 4.5 + * move register pseudo-variables into regu. + */ + for(r = firstr; r != R; r = r->link) { + r->regu = (r->refbehind.b[0] | r->set.b[0]) & REGBITS; + + r->set.b[0] &= ~REGBITS; + r->use1.b[0] &= ~REGBITS; + r->use2.b[0] &= ~REGBITS; + r->refbehind.b[0] &= ~REGBITS; + r->refahead.b[0] &= ~REGBITS; + r->calbehind.b[0] &= ~REGBITS; + r->calahead.b[0] &= ~REGBITS; + r->regdiff.b[0] &= ~REGBITS; + r->act.b[0] &= ~REGBITS; + } + + /* * pass 5 * isolate regions * calculate costs (paint1) @@ -656,6 +730,7 @@ addmove(Reg *r, int bn, int rn, int f) a->etype = v->etype; a->type = v->name; a->gotype = v->gotype; + a->node = v->node; // need to clean this up with wptr and // some of the defaults @@ -732,7 +807,7 @@ Bits mkvar(Reg *r, Adr *a) { Var *v; - int i, t, n, et, z, w, flag; + int i, t, n, et, z, w, flag, regu; int32 o; Bits bit; Sym *s; @@ -744,14 +819,17 @@ mkvar(Reg *r, Adr *a) if(t == D_NONE) goto none; - if(r != R) { - r->regu |= doregbits(t); - r->regu |= doregbits(a->index); - } + if(r != R) + r->use1.b[0] |= doregbits(a->index); switch(t) { default: - goto none; + regu = doregbits(t); + if(regu == 0) + goto none; + bit = zbits; + bit.b[0] = regu; + return bit; case D_ADDR: a->type = a->index; @@ -821,6 +899,7 @@ mkvar(Reg *r, Adr *a) v->etype = et; v->width = w; v->addr = flag; // funny punning + v->node = a->node; if(debug['R']) print("bit=%2d et=%2d w=%d %S %D flag=%d\n", i, et, w, s, a, v->addr); |