diff options
Diffstat (limited to 'utils/2c/reg.c')
| -rw-r--r-- | utils/2c/reg.c | 1275 |
1 files changed, 0 insertions, 1275 deletions
diff --git a/utils/2c/reg.c b/utils/2c/reg.c deleted file mode 100644 index d314096d..00000000 --- a/utils/2c/reg.c +++ /dev/null @@ -1,1275 +0,0 @@ -#include "gc.h" - -Reg* -rega(void) -{ - Reg *r; - - r = freer; - if(r == R) { - r = alloc(sizeof(*r)); - } else - freer = r->link; - - *r = zreg; - return r; -} - -int -rcmp(const void *a1, const void *a2) -{ - Rgn *p1, *p2; - int c1, c2; - - p1 = (Rgn*)a1; - p2 = (Rgn*)a2; - c1 = p2->costr; - if(p2->costa > c1) - c1 = p2->costa; - c2 = p1->costr; - if(p1->costa > c2) - c2 = p1->costa; - if(c1 -= c2) - return c1; - return p2->varno - p1->varno; -} - -void -regopt(Prog *p) -{ - Reg *r, *r1, *r2; - Prog *p1; - int i, z; - long val, initpc, npc; - ulong vreg; - Bits bit; - Var *v; - struct { - long m; - long c; - Reg* p; - } log5[6], *lp; - - firstr = R; - lastr = R; - nvar = 0; - for(z=0; z<BITS; z++) { - externs.b[z] = 0; - params.b[z] = 0; - addrs.b[z] = 0; - } - regbits = RtoB(0) | /* return reg */ - AtoB(6) | AtoB(7) | /* sp and sb */ - FtoB(0) | FtoB(1); /* floating return reg */ - for(i=0; i<NREG; i++) { - if(regused[i]) - regbits |= RtoB(i); - if(fregused[i]) - regbits |= FtoB(i); - if(aregused[i]) - regbits |= AtoB(i); - } - - /* - * pass 1 - * build aux data structure - * allocate pcs - * find use and set of variables - */ - val = 5L * 5L * 5L * 5L * 5L; - lp = log5; - for(i=0; i<5; i++) { - lp->m = val; - lp->c = 0; - lp->p = R; - val /= 5L; - lp++; - } - val = 0; - for(; p != P; p = p->link) { - switch(p->as) { - case ADATA: - case AGLOBL: - case ANAME: - case ASIGNAME: - continue; - } - r = rega(); - if(firstr == R) { - firstr = r; - lastr = r; - } else { - lastr->link = r; - r->p1 = lastr; - lastr->s1 = r; - lastr = r; - } - r->prog = p; - r->pc = val; - val++; - - lp = log5; - for(i=0; i<5; i++) { - lp->c--; - if(lp->c <= 0) { - lp->c = lp->m; - if(lp->p != R) - lp->p->log5 = r; - lp->p = r; - (lp+1)->c = 0; - break; - } - lp++; - } - - r1 = r->p1; - if(r1 != R) - switch(r1->prog->as) { - case ABRA: - case ARTS: - case ARTE: - r->p1 = R; - r1->s1 = R; - } - - bit = mkvar(&p->from, AGOK); - if(bany(&bit)) - switch(p->as) { - case ALEA: - if(!(mvbits & B_INDIR)) - for(z=0; z<BITS; z++) - addrs.b[z] |= bit.b[z]; - - default: - if(mvbits & B_ADDR) - for(z=0; z<BITS; z++) - addrs.b[z] |= bit.b[z]; - for(z=0; z<BITS; z++) - r->use1.b[z] |= bit.b[z]; - } - - bit = mkvar(&p->to, p->as); - if(bany(&bit)) - switch(p->as) { - case ABSR: /* funny */ - for(z=0; z<BITS; z++) - addrs.b[z] |= bit.b[z]; - goto def; - - case APEA: - if(!(mvbits & B_INDIR)) - for(z=0; z<BITS; z++) - addrs.b[z] |= bit.b[z]; - - def: - case ACMPB: case ACMPW: case ACMPL: - case AFCMPF: case AFCMPD: - case ATSTB: case ATSTW: case ATSTL: - case AFTSTF: case AFTSTD: - case ABFEXTU: case ABFEXTS: - if(mvbits & B_ADDR) - for(z=0; z<BITS; z++) - addrs.b[z] |= bit.b[z]; - for(z=0; z<BITS; z++) - r->use2.b[z] |= bit.b[z]; - break; - - default: - diag(Z, "reg: unknown asop: %A", p->as); - - case AADDB: case AADDW: case AADDL: - case ASUBB: case ASUBW: case ASUBL: - case AANDB: case AANDW: case AANDL: - case AORB: case AORW: case AORL: - case AEORB: case AEORW: case AEORL: - case ABFINS: - for(z=0; z<BITS; z++) - r->use2.b[z] |= bit.b[z]; - - case ANOP: - case AMOVB: case AMOVW: case AMOVL: - case AFMOVEB: case AFMOVEW: case AFMOVEL: - case ACLRB: case ACLRW: case ACLRL: - case AFMOVEF: case AFMOVED: - if(mvbits & B_INDIR) - for(z=0; z<BITS; z++) - r->use2.b[z] |= bit.b[z]; - else - for(z=0; z<BITS; z++) - r->set.b[z] |= bit.b[z]; - break; - - } - } - if(firstr == R) - return; - initpc = pc - val; - npc = val; - - /* - * pass 2 - * turn branch references to pointers - * build back pointers - */ - for(r = firstr; r != R; r = r->link) { - p = r->prog; - if(p->to.type == D_BRANCH) { - val = p->to.offset - initpc; - r1 = firstr; - while(r1 != R) { - r2 = r1->log5; - if(r2 != R && val >= r2->pc) { - r1 = r2; - continue; - } - if(r1->pc == val) - break; - r1 = r1->link; - } - if(r1 == R) { - diag(Z, "ref not found\n%L:%P", p->lineno, p); - continue; - } - if(r1 == r) { - diag(Z, "ref to self"); - continue; - } - r->s2 = r1; - r->p2link = r1->p2; - r1->p2 = r; - } - } - if(debug['R']) - print("\n%L %D\n", firstr->prog->lineno, &firstr->prog->from); - - /* - * pass 2.5 - * find looping structure - */ - for(r = firstr; r != R; r = r->link) - r->active = 0; - changer = 0; - loopit(firstr, npc); - if(debug['R'] && debug['v']) { - print("\nlooping structure:\n"); - for(r = firstr; r != R; r = r->link) { - print("%ld:%P", r->loop, r->prog); - for(z=0; z<BITS; z++) - bit.b[z] = r->use1.b[z] | - r->use2.b[z] | r->set.b[z]; - if(bany(&bit)) { - print("\t"); - if(bany(&r->use1)) - print(" u1=%B", r->use1); - if(bany(&r->use2)) - print(" u2=%B", r->use2); - if(bany(&r->set)) - print(" st=%B", r->set); - } - print("\n"); - } - } - - /* - * pass 3 - * iterate propagating usage - * back until flow graph is complete - */ -loop1: - changer = 0; - for(r = firstr; r != R; r = r->link) - r->active = 0; - for(r = firstr; r != R; r = r->link) - if(r->prog->as == ARTS) - prop(r, zbits, zbits); -loop11: - /* pick up unreachable code */ - i = 0; - for(r = firstr; r != R; r = r1) { - r1 = r->link; - if(r1 && r1->active && !r->active) { - prop(r, zbits, zbits); - i = 1; - } - } - if(i) - goto loop11; - if(changer) - goto loop1; - - /* - * pass 4 - * iterate propagating register/variable synchrony - * forward until graph is complete - */ -loop2: - changer = 0; - for(r = firstr; r != R; r = r->link) - r->active = 0; - synch(firstr, zbits); - if(changer) - goto loop2; - - - /* - * pass 5 - * isolate regions - * calculate costs (paint1) - */ - r = firstr; - if(r) { - for(z=0; z<BITS; z++) - bit.b[z] = (r->refahead.b[z] | r->calahead.b[z]) & - ~(externs.b[z] | params.b[z] | addrs.b[z]); - if(bany(&bit)) { - nearln = r->prog->lineno; - warn(Z, "used and not set: %B", bit); - if(debug['R'] && !debug['w']) - print("used and not set: %B\n", bit); - - /* - * 68040 'feature': - * load of a denormalized fp will trap - */ - while(bany(&bit)) { - i = bnum(bit); - bit.b[i/32] &= ~(1L << (i%32)); - v = var + i; - if(v->type == D_AUTO) { - r->set.b[i/32] |= (1L << (i%32)); - if(typefd[v->etype]) - addmove(r, i, NREG+NREG, 1); - } - } - } - } - if(debug['R'] && debug['v']) - print("\nprop structure:\n"); - for(r = firstr; r != R; r = r->link) { - if(debug['R'] && debug['v']) - print("%P\n set = %B; rah = %B; cal = %B\n", - r->prog, r->set, r->refahead, r->calahead); - r->act = zbits; - } - rgp = region; - nregion = 0; - for(r = firstr; r != R; r = r->link) { - for(z=0; z<BITS; z++) - bit.b[z] = r->set.b[z] & - ~(r->refahead.b[z] | r->calahead.b[z] | addrs.b[z]); - if(bany(&bit)) { - nearln = r->prog->lineno; - warn(Z, "set and not used: %B", bit); - if(debug['R']) - print("set an not used: %B\n", bit); - excise(r); - } - for(z=0; z<BITS; z++) - bit.b[z] = LOAD(r) & ~(r->act.b[z] | addrs.b[z]); - while(bany(&bit)) { - i = bnum(bit); - rgp->enter = r; - rgp->varno = i; - changer = 0; - changea = 0; - if(debug['R'] && debug['v']) - print("\n"); - paint1(r, i); - bit.b[i/32] &= ~(1L<<(i%32)); - if(changer <= 0 && changea <= 0) { - if(debug['R']) - print("%L$%d.%d: %B\n", - r->prog->lineno, - changer, changea, blsh(i)); - continue; - } - rgp->costr = changer; - rgp->costa = changea; - nregion++; - if(nregion >= NRGN) { - warn(Z, "too many regions"); - goto brk; - } - rgp++; - } - } -brk: - qsort(region, nregion, sizeof(region[0]), rcmp); - - /* - * pass 6 - * determine used registers (paint2) - * replace code (paint3) - */ - rgp = region; - for(i=0; i<nregion; i++) { - bit = blsh(rgp->varno); - vreg = paint2(rgp->enter, rgp->varno); - vreg = allreg(vreg, rgp); - if(debug['R']) - print("%L$%d.%d %R: %B\n", - rgp->enter->prog->lineno, - rgp->costr, rgp->costa, - rgp->regno, - bit); - if(rgp->regno != D_NONE) - paint3(rgp->enter, rgp->varno, vreg, rgp->regno); - rgp++; - } - /* - * pass 7 - * peep-hole on basic block - */ - if(!debug['R'] || debug['P']) - peep(); - - /* - * pass 8 - * recalculate pc - */ - val = initpc; - for(r = firstr; r != R; r = r1) { - r->pc = val; - p = r->prog; - p1 = P; - r1 = r->link; - if(r1 != R) - p1 = r1->prog; - for(; p != p1; p = p->link) { - switch(p->as) { - default: - val++; - break; - - case ANOP: - case ADATA: - case AGLOBL: - case ANAME: - case ASIGNAME: - break; - } - } - } - pc = val; - - /* - * fix up branches - */ - if(debug['R']) - if(bany(&addrs)) - print("addrs: %B\n", addrs); - - r1 = 0; /* set */ - for(r = firstr; r != R; r = r->link) { - p = r->prog; - if(p->to.type == D_BRANCH) - p->to.offset = r->s2->pc; - r1 = r; - } - - /* - * last pass - * eliminate nops - * free aux structures - */ - for(p = firstr->prog; p != P; p = p->link){ - while(p->link && p->link->as == ANOP) - p->link = p->link->link; - } - if(r1 != R) { - r1->link = freer; - freer = firstr; - } -} - -/* - * add mov b,rn - * just after r - */ -void -addmove(Reg *r, int bn, int rn, int f) -{ - Prog *p, *p1; - Var *v; - int badccr; - - badccr = 0; - p = r->prog; - p1 = p->link; - if(p1) - switch(p1->as) { - case AMOVW: - if(p1->from.type == D_CCR) - p = p1; - break; - - case ABEQ: - case ABNE: - case ABLE: - case ABLS: - case ABLT: - case ABMI: - case ABGE: - case ABPL: - case ABGT: - case ABHI: - case ABCC: - case ABCS: - p1 = prg(); - p1->link = p->link; - p->link = p1; - p1->lineno = p->lineno; - - p1->from.type = D_CCR; - p1->to.type = D_TOS; - p1->as = AMOVW; - p = p1; - badccr = 1; - } - p1 = prg(); - p1->link = p->link; - p->link = p1; - p1->lineno = p->lineno; - - v = var + bn; - p1->from.sym = v->sym; - p1->from.type = v->type; - p1->from.offset = v->offset; - p1->from.etype = v->etype; - p1->to.type = rn; - if(f) { - p1->to = p1->from; - p1->from = zprog.from; - p1->from.type = rn; - } - p1->as = opxt[OAS][v->etype]; - if(badccr) { - p = p1; - p1 = prg(); - p1->link = p->link; - p->link = p1; - p1->lineno = p->lineno; - - p1->from.type = D_TOS; - p1->to.type = D_CCR; - p1->as = AMOVW; - } - if(debug['R']) - print("%P\t.a%P\n", p, p1); -} - -Bits -mkvar(Adr *a, int as) -{ - Var *v; - int i, t, z; - long o; - Bits bit; - Sym *s; - - mvbits = 0; - t = a->type & D_MASK; - switch(t) { - - default: - if(t >= D_R0 && t < D_R0+NREG) { - regbits |= RtoB(t-D_R0); - if(as == ADIVUL || as == ADIVSL) - regbits |= RtoB(t-D_R0+1); - } - if(t >= D_A0 && t < D_A0+NREG) - regbits |= AtoB(t-D_A0); - if(t >= D_F0 && t < D_F0+NREG) - regbits |= FtoB(t-D_F0); - goto none; - - case D_EXTERN: - case D_STATIC: - case D_AUTO: - case D_PARAM: - break; - } - s = a->sym; - if(s == S) - goto none; - - if((a->type & I_MASK) == I_ADDR) - mvbits |= B_ADDR; - - switch(a->index & I_MASK) { - case I_INDEX1: - mvbits |= B_ADDR; - break; - - case I_INDEX2: - case I_INDEX3: - mvbits |= B_INDIR; - break; - } - - o = a->offset; - v = var; - for(i=0; i<nvar; i++) { - if(s == v->sym) - if(t == v->type) - if(o == v->offset) - goto out; - v++; - } - if(s) - if(s->name[0] == '.') - goto none; - if(nvar >= NVAR) { - if(debug['w'] > 1 && s) - warn(Z, "variable not optimized: %s", s->name); - goto none; - } - i = nvar; - nvar++; - v = &var[i]; - v->sym = s; - v->offset = o; - v->etype = a->etype; - v->type = t; - if(debug['R']) - print("bit=%2d et=%2d %s (%p,%d,%ld)\n", - i, a->etype, s->name, - v->sym, v->type, v->offset); - -out: - bit = blsh(i); - if(t == D_EXTERN || t == D_STATIC) - for(z=0; z<BITS; z++) - externs.b[z] |= bit.b[z]; - if(t == D_PARAM) - for(z=0; z<BITS; z++) - params.b[z] |= bit.b[z]; - if(a->etype != v->etype || !typechlpfd[a->etype]) - for(z=0; z<BITS; z++) - addrs.b[z] |= bit.b[z]; /* funny punning */ - return bit; - -none: - return zbits; -} - -void -prop(Reg *r, Bits ref, Bits cal) -{ - Reg *r1, *r2; - int z; - - for(r1 = r; r1 != R; r1 = r1->p1) { - for(z=0; z<BITS; z++) { - ref.b[z] |= r1->refahead.b[z]; - if(ref.b[z] != r1->refahead.b[z]) { - r1->refahead.b[z] = ref.b[z]; - changer++; - } - cal.b[z] |= r1->calahead.b[z]; - if(cal.b[z] != r1->calahead.b[z]) { - r1->calahead.b[z] = cal.b[z]; - changer++; - } - } - switch(r1->prog->as) { - case ABSR: - for(z=0; z<BITS; z++) { - cal.b[z] |= ref.b[z] | externs.b[z]; - ref.b[z] = 0; - } - break; - - case ATEXT: - for(z=0; z<BITS; z++) { - cal.b[z] = 0; - ref.b[z] = 0; - } - break; - - case ARTS: - for(z=0; z<BITS; z++) { - cal.b[z] = externs.b[z]; - ref.b[z] = 0; - } - } - for(z=0; z<BITS; z++) { - ref.b[z] = (ref.b[z] & ~r1->set.b[z]) | - r1->use1.b[z] | r1->use2.b[z]; - cal.b[z] &= ~(r1->set.b[z] | r1->use1.b[z] | r1->use2.b[z]); - r1->refbehind.b[z] = ref.b[z]; - r1->calbehind.b[z] = cal.b[z]; - } - if(r1->active) - break; - r1->active = 1; - } - for(; r != r1; r = r->p1) - for(r2 = r->p2; r2 != R; r2 = r2->p2link) - prop(r2, r->refbehind, r->calbehind); -} - -/* - * find looping structure - * - * 1) find reverse postordering - * 2) find approximate dominators, - * the actual dominators if the flow graph is reducible - * otherwise, dominators plus some other non-dominators. - * See Matthew S. Hecht and Jeffrey D. Ullman, - * "Analysis of a Simple Algorithm for Global Data Flow Problems", - * Conf. Record of ACM Symp. on Principles of Prog. Langs, Boston, Massachusetts, - * Oct. 1-3, 1973, pp. 207-217. - * 3) find all nodes with a predecessor dominated by the current node. - * such a node is a loop head. - * recursively, all preds with a greater rpo number are in the loop - */ -long -postorder(Reg *r, Reg **rpo2r, long n) -{ - Reg *r1; - - r->rpo = 1; - r1 = r->s1; - if(r1 && !r1->rpo) - n = postorder(r1, rpo2r, n); - r1 = r->s2; - if(r1 && !r1->rpo) - n = postorder(r1, rpo2r, n); - rpo2r[n] = r; - n++; - return n; -} - -long -rpolca(long *idom, long rpo1, long rpo2) -{ - long t; - - if(rpo1 == -1) - return rpo2; - while(rpo1 != rpo2){ - if(rpo1 > rpo2){ - t = rpo2; - rpo2 = rpo1; - rpo1 = t; - } - while(rpo1 < rpo2){ - t = idom[rpo2]; - if(t >= rpo2) - fatal(Z, "bad idom"); - rpo2 = t; - } - } - return rpo1; -} - -int -doms(long *idom, long r, long s) -{ - while(s > r) - s = idom[s]; - return s == r; -} - -int -loophead(long *idom, Reg *r) -{ - long src; - - src = r->rpo; - if(r->p1 != R && doms(idom, src, r->p1->rpo)) - return 1; - for(r = r->p2; r != R; r = r->p2link) - if(doms(idom, src, r->rpo)) - return 1; - return 0; -} - -void -loopmark(Reg **rpo2r, long head, Reg *r) -{ - if(r->rpo < head || r->active == head) - return; - r->active = head; - r->loop += LOOP; - if(r->p1 != R) - loopmark(rpo2r, head, r->p1); - for(r = r->p2; r != R; r = r->p2link) - loopmark(rpo2r, head, r); -} - -void -loopit(Reg *r, long nr) -{ - Reg *r1; - long i, d, me; - - if(nr > maxnr) { - rpo2r = alloc(nr * sizeof(Reg*)); - idom = alloc(nr * sizeof(long)); - maxnr = nr; - } - - d = postorder(r, rpo2r, 0); - if(d > nr) - fatal(Z, "too many reg nodes"); - nr = d; - for(i = 0; i < nr / 2; i++){ - r1 = rpo2r[i]; - rpo2r[i] = rpo2r[nr - 1 - i]; - rpo2r[nr - 1 - i] = r1; - } - for(i = 0; i < nr; i++) - rpo2r[i]->rpo = i; - - idom[0] = 0; - for(i = 0; i < nr; i++){ - r1 = rpo2r[i]; - me = r1->rpo; - d = -1; - if(r1->p1 != R && r1->p1->rpo < me) - d = r1->p1->rpo; - for(r1 = r1->p2; r1 != nil; r1 = r1->p2link) - if(r1->rpo < me) - d = rpolca(idom, d, r1->rpo); - idom[i] = d; - } - - for(i = 0; i < nr; i++){ - r1 = rpo2r[i]; - r1->loop++; - if(r1->p2 != R && loophead(idom, r1)) - loopmark(rpo2r, i, r1); - } -} - -void -synch(Reg *r, Bits dif) -{ - Reg *r1; - int z; - - for(r1 = r; r1 != R; r1 = r1->s1) { - for(z=0; z<BITS; z++) { - dif.b[z] = (dif.b[z] & - ~(~r1->refbehind.b[z] & r1->refahead.b[z])) | - r1->set.b[z] | r1->regdiff.b[z]; - if(dif.b[z] != r1->regdiff.b[z]) { - r1->regdiff.b[z] = dif.b[z]; - changer++; - } - } - if(r1->active) - break; - r1->active = 1; - for(z=0; z<BITS; z++) - dif.b[z] &= ~(~r1->calbehind.b[z] & r1->calahead.b[z]); - if(r1->s2 != R) - synch(r1->s2, dif); - } -} - -ulong -allreg(ulong b, Rgn *r) -{ - Var *v; - int i, j; - - v = var + r->varno; - r->regno = D_NONE; - switch(v->etype) { - - default: - diag(Z, "unknown etype"); - break; - - case TCHAR: - case TUCHAR: - case TSHORT: - case TUSHORT: - case TINT: - case TUINT: - case TLONG: - case TULONG: - case TIND: - i = BtoR(~b); - j = BtoA(~b); - if(r->costa == r->costr) - if(i > j) - i = NREG; - if(j < NREG && r->costa > 0) - if(r->costa > r->costr || i >= NREG) { - r->regno = D_A0 + j; - return AtoB(j); - } - if(i < NREG && r->costr > 0) { - r->regno = D_R0 + i; - return RtoB(i); - } - break; - - case TDOUBLE: - case TFLOAT: - i = BtoF(~b); - if(i < NREG) { - r->regno = D_F0 + i; - return FtoB(i); - } - break; - } - return 0; -} - -void -paint1(Reg *r, int bn) -{ - Reg *r1; - Prog *p; - int z; - ulong bb; - int x; - - z = bn/32; - bb = 1L<<(bn%32); - if(r->act.b[z] & bb) - return; - for(;;) { - if(!(r->refbehind.b[z] & bb)) - break; - r1 = r->p1; - if(r1 == R) - break; - if(!(r1->refahead.b[z] & bb)) - break; - if(r1->act.b[z] & bb) - break; - r = r1; - } - if(LOAD(r) & ~(r->set.b[z]&~(r->use1.b[z]|r->use2.b[z])) & bb) { - changer -= CLOAD * r->loop; - changea -= CLOAD * r->loop; - if(debug['R'] && debug['v']) - print("%ld%P\tld %B $%d.%d\n", r->loop, - r->prog, blsh(bn), changer, changea); - } - for(;;) { - r->act.b[z] |= bb; - p = r->prog; - - if(r->use1.b[z] & bb) { - changer += CREF * r->loop; - changea += CREF * r->loop; - x = p->from.index; - if(x == D_NONE) { - switch(p->as) { - default: - changea = -CINF; - case AADDL: - case ASUBL: - case AMOVL: - case ACMPL: - break; - } - } else { - changer += (CXREF-CREF) * r->loop; - if(x != (I_INDEX3|D_NONE)) - changer = -CINF; - if((x&I_MASK) == I_INDEX1) - changea = -CINF; - } - if(p->as == AMOVL) { - x = p->to.type; - if(x >= D_R0 && x < D_R0+NREG) - changer += r->loop; - if(x >= D_A0 && x < D_A0+NREG) - changea += r->loop; - } - if(debug['R'] && debug['v']) - print("%ld%P\tu1 %B $%d.%d\n", r->loop, - p, blsh(bn), changer, changea); - } - if((r->use2.b[z]|r->set.b[z]) & bb) { - changer += CREF * r->loop; - changea += CREF * r->loop; - x = p->to.index; - if(x == D_NONE) - switch(p->as) { - default: - changea = -CINF; - break; - case AMOVL: - case AADDL: - case ACMPL: - case ASUBL: - case ACLRL: /* can be faked */ - case ATSTL: /* can be faked */ - break; - } - else { - changer += (CXREF-CREF) * r->loop; - if(x != (I_INDEX3|D_NONE)) - changer = -CINF; - if((x&I_MASK) == I_INDEX1) - changea = -CINF; - } - if(p->as == AMOVL) { - x = p->from.type; - if(x >= D_R0 && x < D_R0+NREG) - changer += r->loop; - if(x >= D_A0 && x < D_A0+NREG) - changea += r->loop; - } - if(debug['R'] && debug['v']) - print("%ld%P\tu2 %B $%d.%d\n", r->loop, - p, blsh(bn), changer, changea); - } - if(STORE(r) & r->regdiff.b[z] & bb) { - changer -= CLOAD * r->loop; - changea -= CLOAD * r->loop; - if(debug['R'] && debug['v']) - print("%ld%P\tst %B $%d.%d\n", r->loop, - p, blsh(bn), changer, changea); - } - - if(r->refbehind.b[z] & bb) - for(r1 = r->p2; r1 != R; r1 = r1->p2link) - if(r1->refahead.b[z] & bb) - paint1(r1, bn); - - if(!(r->refahead.b[z] & bb)) - break; - r1 = r->s2; - if(r1 != R) - if(r1->refbehind.b[z] & bb) - paint1(r1, bn); - r = r->s1; - if(r == R) - break; - if(r->act.b[z] & bb) - break; - if(!(r->refbehind.b[z] & bb)) - break; - } -} - -ulong -paint2(Reg *r, int bn) -{ - Reg *r1; - int z; - ulong bb, vreg; - - z = bn/32; - bb = 1L << (bn%32); - vreg = regbits; - if(!(r->act.b[z] & bb)) - return vreg; - for(;;) { - if(!(r->refbehind.b[z] & bb)) - break; - r1 = r->p1; - if(r1 == R) - break; - if(!(r1->refahead.b[z] & bb)) - break; - if(!(r1->act.b[z] & bb)) - break; - r = r1; - } - for(;;) { - r->act.b[z] &= ~bb; - - vreg |= r->regu; - - if(r->refbehind.b[z] & bb) - for(r1 = r->p2; r1 != R; r1 = r1->p2link) - if(r1->refahead.b[z] & bb) - vreg |= paint2(r1, bn); - - if(!(r->refahead.b[z] & bb)) - break; - r1 = r->s2; - if(r1 != R) - if(r1->refbehind.b[z] & bb) - vreg |= paint2(r1, bn); - r = r->s1; - if(r == R) - break; - if(!(r->act.b[z] & bb)) - break; - if(!(r->refbehind.b[z] & bb)) - break; - } - return vreg; -} - -void -paint3(Reg *r, int bn, ulong rb, int rn) -{ - Reg *r1; - Prog *p; - int z; - ulong bb; - - z = bn/32; - bb = 1L << (bn%32); - if(r->act.b[z] & bb) - return; - for(;;) { - if(!(r->refbehind.b[z] & bb)) - break; - r1 = r->p1; - if(r1 == R) - break; - if(!(r1->refahead.b[z] & bb)) - break; - if(r1->act.b[z] & bb) - break; - r = r1; - } - 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; - - if(r->use1.b[z] & bb) { - if(debug['R']) - print("%P", p); - addreg(&p->from, rn); - if(debug['R']) - print("\t.c%P\n", p); - } - if((r->use2.b[z]|r->set.b[z]) & bb) { - if(debug['R']) - print("%P", p); - addreg(&p->to, rn); - if(debug['R']) - print("\t.c%P\n", p); - } - if(STORE(r) & r->regdiff.b[z] & bb) - addmove(r, bn, rn, 1); - r->regu |= rb; - - if(r->refbehind.b[z] & bb) - for(r1 = r->p2; r1 != R; r1 = r1->p2link) - if(r1->refahead.b[z] & bb) - paint3(r1, bn, rb, rn); - - if(!(r->refahead.b[z] & bb)) - break; - r1 = r->s2; - if(r1 != R) - if(r1->refbehind.b[z] & bb) - paint3(r1, bn, rb, rn); - r = r->s1; - if(r == R) - break; - if(r->act.b[z] & bb) - break; - if(!(r->refbehind.b[z] & bb)) - break; - } -} - -void -addreg(Adr *a, int rn) -{ - int x; - - a->sym = 0; - x = a->index; - if(rn >= D_R0 && rn < D_R0+NREG) - goto addr; - if(x == (I_INDEX3|D_NONE)) { - a->type = rn | I_INDIR; - a->index = D_NONE; - a->offset = a->displace; - a->displace = 0; - return; - } - if(x != D_NONE) { - a->type = rn | I_INDIR; - a->index += I_INDEX1 - I_INDEX2; - a->offset = a->displace; - a->displace = 0; - return; - } - a->type = rn | (a->type & I_INDIR); - return; - -addr: - if(x == (I_INDEX3|D_NONE)) { - a->type = D_NONE|I_INDIR; - a->index += I_INDEX1 + rn - D_NONE - I_INDEX3; - a->scale = 4; /* .L*1 */ - a->offset = a->displace; - a->displace = 0; - return; - } - a->type = rn | (a->type & I_INDIR); -} - -/* - * bit reg - * 0-7 R0-R7 - * 8-15 A0-A7 - * 16-23 F0-F7 - */ -ulong -RtoB(int r) -{ - - if(r < 0 || r >= NREG) - return 0; - return 1L << (r + 0); -} - -int -BtoR(ulong b) -{ - - b &= 0x0000ffL; - if(b == 0) - return NREG; - return bitno(b) - 0; -} - -ulong -AtoB(int a) -{ - - if(a < 0 || a >= NREG) - return 0; - return 1L << (a + NREG); -} - -int -BtoA(ulong b) -{ - - b &= 0x00ff00L; - if(b == 0) - return NREG; - return bitno(b) - NREG; -} - -ulong -FtoB(int f) -{ - - if(f < 0 || f >= NREG) - return 0; - return 1L << (f + NREG+NREG); -} - -int -BtoF(ulong b) -{ - - b &= 0xff0000L; - if(b == 0) - return NREG; - return bitno(b) - NREG-NREG; -} |
