summaryrefslogtreecommitdiff
path: root/src/cmd/8g/reg.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/8g/reg.c')
-rw-r--r--src/cmd/8g/reg.c111
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);