diff options
Diffstat (limited to 'src/cmd/5g')
-rw-r--r-- | src/cmd/5g/cgen64.c | 50 | ||||
-rw-r--r-- | src/cmd/5g/list.c | 6 | ||||
-rw-r--r-- | src/cmd/5g/peep.c | 216 | ||||
-rw-r--r-- | src/cmd/5g/reg.c | 72 |
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"); +// } + } +} |