summaryrefslogtreecommitdiff
path: root/src/cmd/5g
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/5g')
-rw-r--r--src/cmd/5g/cgen64.c50
-rw-r--r--src/cmd/5g/list.c6
-rw-r--r--src/cmd/5g/peep.c216
-rw-r--r--src/cmd/5g/reg.c72
4 files changed, 199 insertions, 145 deletions
diff --git a/src/cmd/5g/cgen64.c b/src/cmd/5g/cgen64.c
index 78f2f4aeb..4da8db2ae 100644
--- a/src/cmd/5g/cgen64.c
+++ b/src/cmd/5g/cgen64.c
@@ -64,17 +64,21 @@ cgen64(Node *n, Node *res)
return;
case OCOM:
+ regalloc(&t1, lo1.type, N);
+ gmove(ncon(-1), &t1);
+
split64(res, &lo2, &hi2);
regalloc(&n1, lo1.type, N);
gins(AMOVW, &lo1, &n1);
- gins(AMVN, &n1, &n1);
+ gins(AEOR, &t1, &n1);
gins(AMOVW, &n1, &lo2);
gins(AMOVW, &hi1, &n1);
- gins(AMVN, &n1, &n1);
+ gins(AEOR, &t1, &n1);
gins(AMOVW, &n1, &hi2);
+ regfree(&t1);
regfree(&n1);
splitclean();
splitclean();
@@ -204,14 +208,17 @@ cgen64(Node *n, Node *res)
// here and below (verify it optimizes to EOR)
gins(AEOR, &al, &al);
gins(AEOR, &ah, &ah);
- } else if(v > 32) {
+ } else
+ if(v > 32) {
gins(AEOR, &al, &al);
// MOVW bl<<(v-32), ah
gshift(AMOVW, &bl, SHIFT_LL, (v-32), &ah);
- } else if(v == 32) {
+ } else
+ if(v == 32) {
gins(AEOR, &al, &al);
gins(AMOVW, &bl, &ah);
- } else if(v > 0) {
+ } else
+ if(v > 0) {
// MOVW bl<<v, al
gshift(AMOVW, &bl, SHIFT_LL, v, &al);
@@ -341,7 +348,8 @@ olsh_break:
gins(AEOR, &al, &al);
gins(AEOR, &ah, &ah);
}
- } else if(v > 32) {
+ } else
+ if(v > 32) {
if(bh.type->etype == TINT32) {
// MOVW bh->(v-32), al
gshift(AMOVW, &bh, SHIFT_AR, v-32, &al);
@@ -353,7 +361,8 @@ olsh_break:
gshift(AMOVW, &bh, SHIFT_LR, v-32, &al);
gins(AEOR, &ah, &ah);
}
- } else if(v == 32) {
+ } else
+ if(v == 32) {
gins(AMOVW, &bh, &al);
if(bh.type->etype == TINT32) {
// MOVW bh->31, ah
@@ -361,7 +370,8 @@ olsh_break:
} else {
gins(AEOR, &ah, &ah);
}
- } else if( v > 0) {
+ } else
+ if( v > 0) {
// MOVW bl>>v, al
gshift(AMOVW, &bl, SHIFT_LR, v, &al);
@@ -384,11 +394,16 @@ olsh_break:
regalloc(&s, types[TUINT32], N);
regalloc(&creg, types[TUINT32], N);
- if (is64(r->type)) {
+ if(is64(r->type)) {
// shift is >= 1<<32
split64(r, &cl, &ch);
gmove(&ch, &s);
- p1 = gins(ATST, &s, N);
+ gins(ATST, &s, N);
+ if(bh.type->etype == TINT32)
+ p1 = gshift(AMOVW, &bh, SHIFT_AR, 31, &ah);
+ else
+ p1 = gins(AEOR, &ah, &ah);
+ p1->scond = C_SCOND_NE;
p6 = gbranch(ABNE, T);
gmove(&cl, &s);
splitclean();
@@ -441,7 +456,6 @@ olsh_break:
p1 = gshift(AMOVW, &bh, SHIFT_AR, 31, &ah);
else
p1 = gins(AEOR, &ah, &ah);
- p1->scond = C_SCOND_EQ;
p4 = gbranch(ABEQ, T);
// check if shift is < 64
@@ -461,33 +475,23 @@ olsh_break:
// MOVW bh->(s-32), al
p1 = gregshift(AMOVW, &bh, SHIFT_AR, &s, &al);
p1->scond = C_SCOND_LO;
-
- // MOVW bh->31, ah
- p1 = gshift(AMOVW, &bh, SHIFT_AR, 31, &ah);
- p1->scond = C_SCOND_LO;
} else {
// MOVW bh>>(v-32), al
p1 = gregshift(AMOVW, &bh, SHIFT_LR, &s, &al);
p1->scond = C_SCOND_LO;
-
- p1 = gins(AEOR, &ah, &ah);
- p1->scond = C_SCOND_LO;
}
// BLO end
p5 = gbranch(ABLO, T);
// s >= 64
- if (p6 != P) patch(p6, pc);
+ if(p6 != P)
+ patch(p6, pc);
if(bh.type->etype == TINT32) {
// MOVW bh->31, al
gshift(AMOVW, &bh, SHIFT_AR, 31, &al);
-
- // MOVW bh->31, ah
- gshift(AMOVW, &bh, SHIFT_AR, 31, &ah);
} else {
gins(AEOR, &al, &al);
- gins(AEOR, &ah, &ah);
}
patch(p2, pc);
diff --git a/src/cmd/5g/list.c b/src/cmd/5g/list.c
index ce74d6478..0c6dbbf71 100644
--- a/src/cmd/5g/list.c
+++ b/src/cmd/5g/list.c
@@ -87,6 +87,10 @@ Dconv(Fmt *fp)
int32 v;
a = va_arg(fp->args, Addr*);
+ if(a == A) {
+ sprint(str, "<nil>");
+ goto conv;
+ }
i = a->type;
switch(i) {
@@ -183,7 +187,7 @@ Dconv(Fmt *fp)
// a->type = D_ADDR;
// goto conv;
}
-//conv:
+conv:
return fmtstrcpy(fp, str);
}
diff --git a/src/cmd/5g/peep.c b/src/cmd/5g/peep.c
index f619a6206..ca12d70f2 100644
--- a/src/cmd/5g/peep.c
+++ b/src/cmd/5g/peep.c
@@ -48,7 +48,6 @@ peep(void)
/*
* complete R structure
*/
- t = 0;
for(r=firstr; r!=R; r=r1) {
r1 = r->link;
if(r1 == R)
@@ -68,7 +67,6 @@ peep(void)
r1->p1 = r2;
r = r2;
- t++;
case ADATA:
case AGLOBL:
@@ -77,8 +75,10 @@ peep(void)
p = p->link;
}
}
+//dumpit("begin", firstr);
loop1:
+
t = 0;
for(r=firstr; r!=R; r=r->link) {
p = r->prog;
@@ -99,71 +99,75 @@ loop1:
case AMOVW:
case AMOVF:
case AMOVD:
- if(!regtyp(&p->to))
- break;
-// if(isdconst(&p->from)) {
-// constprop(&p->from, &p->to, r->s1);
-// break;
-// }
- if(!regtyp(&p->from))
- break;
- if(p->from.type != p->to.type)
- break;
- if(copyprop(r)) {
- excise(r);
- t++;
- break;
+ if(regtyp(&p->from))
+ if(p->from.type == p->to.type)
+ if(p->scond == C_SCOND_NONE) {
+ if(copyprop(r)) {
+ excise(r);
+ t++;
+ break;
+ }
+ if(subprop(r) && copyprop(r)) {
+ excise(r);
+ t++;
+ break;
+ }
}
- if(subprop(r) && copyprop(r)) {
- excise(r);
- t++;
- break;
+ break;
+
+ if(p->scond == C_SCOND_NONE)
+ if(regtyp(&p->to))
+ if(isdconst(&p->from)) {
+ constprop(&p->from, &p->to, r->s1);
}
+ break;
}
}
if(t)
goto loop1;
- /*
- * look for MOVB x,R; MOVB R,R
- */
+
+return;
+
for(r=firstr; r!=R; r=r->link) {
p = r->prog;
switch(p->as) {
- default:
- continue;
- case AEOR:
- /*
- * EOR -1,x,y => MVN x,y
- */
- if(isdconst(&p->from) && p->from.offset == -1) {
- p->as = AMVN;
- p->from.type = D_REG;
- if(p->reg != NREG)
- p->from.reg = p->reg;
- else
- p->from.reg = p->to.reg;
- p->reg = NREG;
- }
- continue;
+// case AEOR:
+// /*
+// * EOR -1,x,y => MVN x,y
+// */
+// if(isdconst(&p->from) && p->from.offset == -1) {
+// p->as = AMVN;
+// p->from.type = D_REG;
+// if(p->reg != NREG)
+// p->from.reg = p->reg;
+// else
+// p->from.reg = p->to.reg;
+// p->reg = NREG;
+// }
+// break;
+
case AMOVH:
case AMOVHU:
case AMOVB:
case AMOVBU:
+ /*
+ * look for MOVB x,R; MOVB R,R
+ */
if(p->to.type != D_REG)
- continue;
+ break;
+ if(r1 == R)
+ break;
+ p1 = r1->prog;
+ if(p1->as != p->as)
+ break;
+ if(p1->from.type != D_REG || p1->from.reg != p->to.reg)
+ break;
+ if(p1->to.type != D_REG || p1->to.reg != p->to.reg)
+ break;
+ excise(r1);
break;
}
r1 = r->link;
- if(r1 == R)
- continue;
- p1 = r1->prog;
- if(p1->as != p->as)
- continue;
- if(p1->from.type != D_REG || p1->from.reg != p->to.reg)
- continue;
- if(p1->to.type != D_REG || p1->to.reg != p->to.reg)
- continue;
- excise(r1);
}
// for(r=firstr; r!=R; r=r->link) {
@@ -335,6 +339,8 @@ subprop(Reg *r0)
case AMULLU:
case AMULA:
+ case AMVN:
+ return 0;
case ACMN:
case AADD:
@@ -347,7 +353,6 @@ subprop(Reg *r0)
case AORR:
case AAND:
case AEOR:
- case AMVN:
case AMUL:
case AMULU:
case ADIV:
@@ -364,7 +369,8 @@ subprop(Reg *r0)
case ADIVD:
case ADIVF:
if(p->to.type == v1->type)
- if(p->to.reg == v1->reg) {
+ if(p->to.reg == v1->reg)
+ if(p->scond == C_SCOND_NONE) {
if(p->reg == NREG)
p->reg = p->to.reg;
goto gotit;
@@ -376,6 +382,7 @@ subprop(Reg *r0)
case AMOVW:
if(p->to.type == v1->type)
if(p->to.reg == v1->reg)
+ if(p->scond == C_SCOND_NONE)
goto gotit;
break;
@@ -662,7 +669,7 @@ shiftprop(Reg *r)
FAIL("can't swap");
if(p1->reg == NREG && p1->to.reg == n)
FAIL("shift result used twice");
- case AMVN:
+// case AMVN:
if(p1->from.type == D_SHIFT)
FAIL("shift result used in shift");
if(p1->from.type != D_REG || p1->from.reg != n)
@@ -971,7 +978,7 @@ copyu(Prog *p, Adr *v, Adr *s)
}
return 0;
- case ANOP: /* read, write */
+ case ANOP: /* read,, write */
case AMOVW:
case AMOVF:
case AMOVD:
@@ -979,6 +986,8 @@ copyu(Prog *p, Adr *v, Adr *s)
case AMOVHU:
case AMOVB:
case AMOVBU:
+ case AMOVFW:
+ case AMOVWF:
case AMOVDW:
case AMOVWD:
case AMOVFD:
@@ -1014,6 +1023,7 @@ copyu(Prog *p, Adr *v, Adr *s)
case AMULLU: /* read, read, write, write */
case AMULA:
+ case AMVN:
return 2;
case AADD: /* read, read, write */
@@ -1027,7 +1037,6 @@ copyu(Prog *p, Adr *v, Adr *s)
case AORR:
case AAND:
case AEOR:
- case AMVN:
case AMUL:
case AMULU:
case ADIV:
@@ -1043,12 +1052,12 @@ copyu(Prog *p, Adr *v, Adr *s)
case ADIVF:
case ADIVD:
- case ACMPF:
+ case ACMPF: /* read, read, */
case ACMPD:
- case ATST:
case ACMP:
case ACMN:
case ACASE:
+ case ATST: /* read,, */
if(s != A) {
if(copysub(&p->from, v, s, 1))
return 1;
@@ -1150,53 +1159,6 @@ copyu(Prog *p, Adr *v, Adr *s)
return 0;
}
-int
-a2type(Prog *p)
-{
-
- switch(p->as) {
-
- case ATST:
- case ACMP:
- case ACMN:
-
- case AMULLU:
- case AMULA:
-
- case AADD:
- case ASUB:
- case ARSB:
- case ASLL:
- case ASRL:
- case ASRA:
- case AORR:
- case AAND:
- case AEOR:
- case AMVN:
- case AMUL:
- case AMULU:
- case ADIV:
- case ADIVU:
- case AMOD:
- case AMODU:
- return D_REG;
-
- case ACMPF:
- case ACMPD:
-
- case AADDF:
- case AADDD:
- case ASUBF:
- case ASUBD:
- case AMULF:
- case AMULD:
- case ADIVF:
- case ADIVD:
- return D_FREG;
- }
- return D_NONE;
-}
-
/*
* direct reference,
* could be set/use depending on
@@ -1233,15 +1195,15 @@ copyau(Adr *a, Adr *v)
return 1;
if(v->type == D_REG) {
if(a->type == D_CONST && a->reg != NREG) {
- if(v->reg == a->reg)
+ if(a->reg == v->reg)
return 1;
} else
if(a->type == D_OREG) {
- if(v->reg == a->reg)
+ if(a->reg == v->reg)
return 1;
} else
if(a->type == D_REGREG) {
- if(v->reg == a->reg)
+ if(a->reg == v->reg)
return 1;
if(a->offset == v->reg)
return 1;
@@ -1256,17 +1218,33 @@ copyau(Adr *a, Adr *v)
return 0;
}
+/*
+ * compare v to the center
+ * register in p (p->reg)
+ * the trick is that this
+ * register might be D_REG
+ * D_FREG. there are basically
+ * two cases,
+ * ADD r,r,r
+ * CMP r,r,
+ */
int
copyau1(Prog *p, Adr *v)
{
- if(regtyp(v)) {
- if(a2type(p) == v->type)
- if(p->reg == v->reg) {
- if(a2type(p) != v->type)
- print("botch a2type %P\n", p);
- return 1;
+ if(regtyp(v))
+ if(p->reg == v->reg) {
+ if(p->to.type != D_NONE) {
+ if(v->type == p->to.type)
+ return 1;
+ return 0;
+ }
+ if(p->from.type != D_NONE) {
+ if(v->type == p->from.type)
+ return 1;
+ return 0;
}
+ print("copyau1: cant tell %P\n", p);
}
return 0;
}
@@ -1479,24 +1457,24 @@ applypred(Reg *rstart, Joininfo *j, int cond, int branch)
pred = predinfo[rstart->prog->as - ABEQ].notscond;
for(r = j->start;; r = successor(r)) {
- if (r->prog->as == AB) {
- if (r != j->last || branch == Delbranch)
+ if(r->prog->as == AB) {
+ if(r != j->last || branch == Delbranch)
excise(r);
else {
- if (cond == Truecond)
+ if(cond == Truecond)
r->prog->as = predinfo[rstart->prog->as - ABEQ].opcode;
else
r->prog->as = predinfo[rstart->prog->as - ABEQ].notopcode;
}
}
else
- if (predicable(r->prog))
+ if(predicable(r->prog))
r->prog->scond = (r->prog->scond&~C_SCOND)|pred;
- if (r->s1 != r->link) {
+ if(r->s1 != r->link) {
r->s1 = r->link;
r->link->p1 = r;
}
- if (r == j->last)
+ if(r == j->last)
break;
}
}
diff --git a/src/cmd/5g/reg.c b/src/cmd/5g/reg.c
index eaf02b237..f31f70535 100644
--- a/src/cmd/5g/reg.c
+++ b/src/cmd/5g/reg.c
@@ -140,8 +140,8 @@ regopt(Prog *firstp)
if(first == 0) {
fmtinstall('Q', Qconv);
}
- first++;
+ first++;
if(debug['K']) {
if(first != 13)
return;
@@ -491,7 +491,7 @@ brk:
* peep-hole on basic block
*/
if(!debug['R'] || debug['P']) {
-// peep();
+ peep();
}
/*
@@ -1375,3 +1375,71 @@ noreturn(Prog *p)
return 1;
return 0;
}
+
+void
+dumpone(Reg *r)
+{
+ int z;
+ Bits bit;
+
+ print("%d:%P", r->loop, r->prog);
+ for(z=0; z<BITS; z++)
+ bit.b[z] =
+ r->set.b[z] |
+ r->use1.b[z] |
+ r->use2.b[z] |
+ r->refbehind.b[z] |
+ r->refahead.b[z] |
+ r->calbehind.b[z] |
+ r->calahead.b[z] |
+ r->regdiff.b[z] |
+ r->act.b[z] |
+ 0;
+// if(bany(&bit)) {
+// print("\t");
+// if(bany(&r->set))
+// print(" s:%Q", r->set);
+// if(bany(&r->use1))
+// print(" u1:%Q", r->use1);
+// if(bany(&r->use2))
+// print(" u2:%Q", r->use2);
+// if(bany(&r->refbehind))
+// print(" rb:%Q ", r->refbehind);
+// if(bany(&r->refahead))
+// print(" ra:%Q ", r->refahead);
+// if(bany(&r->calbehind))
+// print("cb:%Q ", r->calbehind);
+// if(bany(&r->calahead))
+// print(" ca:%Q ", r->calahead);
+// if(bany(&r->regdiff))
+// print(" d:%Q ", r->regdiff);
+// if(bany(&r->act))
+// print(" a:%Q ", r->act);
+// }
+ print("\n");
+}
+
+void
+dumpit(char *str, Reg *r0)
+{
+ Reg *r, *r1;
+
+ print("\n%s\n", str);
+ for(r = r0; r != R; r = r->link) {
+ dumpone(r);
+ r1 = r->p2;
+ if(r1 != R) {
+ print(" pred:");
+ for(; r1 != R; r1 = r1->p2link)
+ print(" %.4ud", r1->prog->loc);
+ print("\n");
+ }
+// r1 = r->s1;
+// if(r1 != R) {
+// print(" succ:");
+// for(; r1 != R; r1 = r1->s1)
+// print(" %.4ud", r1->prog->loc);
+// print("\n");
+// }
+ }
+}