diff options
Diffstat (limited to 'src/cmd/5g/reg.c')
-rw-r--r-- | src/cmd/5g/reg.c | 110 |
1 files changed, 81 insertions, 29 deletions
diff --git a/src/cmd/5g/reg.c b/src/cmd/5g/reg.c index 393266973..eaaaf9be3 100644 --- a/src/cmd/5g/reg.c +++ b/src/cmd/5g/reg.c @@ -1,5 +1,5 @@ // Inferno utils/5c/reg.c -// http://code.google.com/p/inferno-os/source/browse/utils/5g/reg.c +// http://code.google.com/p/inferno-os/source/browse/utils/5c/reg.c // // Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved. // Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net) @@ -34,8 +34,8 @@ #include "gg.h" #include "opt.h" -#define NREGVAR 24 -#define REGBITS ((uint32)0xffffff) +#define NREGVAR 32 +#define REGBITS ((uint32)0xffffffff) #define P2R(p) (Reg*)(p->reg) void addsplits(void); @@ -95,7 +95,7 @@ setoutvar(void) ovar.b[z] |= bit.b[z]; t = structnext(&save); } -//if(bany(ovar)) +//if(bany(&ovar)) //print("ovar = %Q\n", ovar); } @@ -160,8 +160,18 @@ static char* regname[] = { ".F5", ".F6", ".F7", + ".F8", + ".F9", + ".F10", + ".F11", + ".F12", + ".F13", + ".F14", + ".F15", }; +static Node* regnodes[NREGVAR]; + void regopt(Prog *firstp) { @@ -197,7 +207,6 @@ regopt(Prog *firstp) return; } - r1 = R; firstr = R; lastr = R; @@ -208,8 +217,11 @@ regopt(Prog *firstp) */ nvar = NREGVAR; memset(var, 0, NREGVAR*sizeof var[0]); - for(i=0; i<NREGVAR; i++) - var[i].node = newname(lookup(regname[i])); + for(i=0; i<NREGVAR; i++) { + if(regnodes[i] == N) + regnodes[i] = newname(lookup(regname[i])); + var[i].node = regnodes[i]; + } regbits = RtoB(REGSP)|RtoB(REGLINK)|RtoB(REGPC); for(z=0; z<BITS; z++) { @@ -236,6 +248,8 @@ regopt(Prog *firstp) case AGLOBL: case ANAME: case ASIGNAME: + case ALOCALS: + case ATYPE: continue; } r = rega(); @@ -263,6 +277,10 @@ regopt(Prog *firstp) } } + // Avoid making variables for direct-called functions. + if(p->as == ABL && p->to.type == D_EXTERN) + continue; + /* * left side always read */ @@ -408,10 +426,14 @@ regopt(Prog *firstp) addrs.b[z] |= bit.b[z]; } -// print("bit=%2d addr=%d et=%-6E w=%-2d s=%S + %lld\n", -// i, v->addr, v->etype, v->width, v->sym, v->offset); + if(debug['R'] && debug['v']) + print("bit=%2d addr=%d et=%-6E w=%-2d s=%N + %lld\n", + i, v->addr, v->etype, v->width, v->node, v->offset); } + if(debug['R'] && debug['v']) + dumpit("pass1", firstr); + /* * pass 2 * turn branch references to pointers @@ -420,9 +442,9 @@ regopt(Prog *firstp) for(r=firstr; r!=R; r=r->link) { p = r->prog; if(p->to.type == D_BRANCH) { - if(p->to.branch == P) + if(p->to.u.branch == P) fatal("pnil %P", p); - r1 = p->to.branch->regp; + r1 = p->to.u.branch->regp; if(r1 == R) fatal("rnil %P", p); if(r1 == r) { @@ -440,6 +462,9 @@ regopt(Prog *firstp) print(" addr = %Q\n", addrs); } + if(debug['R'] && debug['v']) + dumpit("pass2", firstr); + /* * pass 2.5 * find looping structure @@ -449,6 +474,9 @@ regopt(Prog *firstp) change = 0; loopit(firstr, nr); + if(debug['R'] && debug['v']) + dumpit("pass2.5", firstr); + /* * pass 3 * iterate propagating usage @@ -476,6 +504,9 @@ loop11: if(change) goto loop1; + if(debug['R'] && debug['v']) + dumpit("pass3", firstr); + /* * pass 4 @@ -492,6 +523,9 @@ loop2: addsplits(); + if(debug['R'] && debug['v']) + dumpit("pass4", firstr); + if(debug['R'] > 1) { print("\nprop structure:\n"); for(r = firstr; r != R; r = r->link) { @@ -543,6 +577,9 @@ loop2: r->act.b[0] &= ~REGBITS; } + if(debug['R'] && debug['v']) + dumpit("pass4.5", firstr); + /* * pass 5 * isolate regions @@ -605,6 +642,9 @@ loop2: brk: qsort(region, nregion, sizeof(region[0]), rcmp); + if(debug['R'] && debug['v']) + dumpit("pass5", firstr); + /* * pass 6 * determine used registers (paint2) @@ -633,6 +673,10 @@ brk: paint3(rgp->enter, rgp->varno, vreg, rgp->regno); rgp++; } + + if(debug['R'] && debug['v']) + dumpit("pass6", firstr); + /* * pass 7 * peep-hole on basic block @@ -641,6 +685,9 @@ brk: peep(); } + if(debug['R'] && debug['v']) + dumpit("pass7", firstr); + /* * last pass * eliminate nops @@ -662,8 +709,8 @@ brk: while(p->link != P && p->link->as == ANOP) p->link = p->link->link; if(p->to.type == D_BRANCH) - while(p->to.branch != P && p->to.branch->as == ANOP) - p->to.branch = p->to.branch->link; + while(p->to.u.branch != P && p->to.u.branch->as == ANOP) + p->to.u.branch = p->to.u.branch->link; if(p->as == AMOVW && p->to.reg == 13) { if(p->scond & C_WBIT) { vreg = -p->to.offset; // in adjust region @@ -866,6 +913,7 @@ mkvar(Reg *r, Adr *a) goto onereg; case D_REGREG: + case D_REGREG2: bit = zbits; if(a->offset != NREG) bit.b[0] |= RtoB(a->offset); @@ -926,6 +974,8 @@ mkvar(Reg *r, Adr *a) et = a->etype; o = a->offset; w = a->width; + if(w < 0) + fatal("bad width %d for %D", w, a); for(i=0; i<nvar; i++) { v = var+i; @@ -947,8 +997,6 @@ mkvar(Reg *r, Adr *a) switch(et) { case 0: case TFUNC: - case TARRAY: - case TSTRING: goto none; } @@ -964,14 +1012,13 @@ mkvar(Reg *r, Adr *a) v = var+i; v->offset = o; v->name = n; -// v->gotype = a->gotype; v->etype = et; v->width = w; v->addr = flag; // funny punning v->node = node; if(debug['R']) - print("bit=%2d et=%2d w=%d+%d %#N %D flag=%d\n", i, et, o, w, node, a, v->addr); + print("bit=%2d et=%2E w=%d+%d %#N %D flag=%d\n", i, et, o, w, node, a, v->addr); bit = blsh(i); if(n == D_EXTERN || n == D_STATIC) @@ -1033,8 +1080,12 @@ prop(Reg *r, Bits ref, Bits cal) default: // Work around for issue 1304: // flush modified globals before each instruction. - for(z=0; z<BITS; z++) + for(z=0; z<BITS; z++) { cal.b[z] |= externs.b[z]; + // issue 4066: flush modified return variables in case of panic + if(hasdefer) + cal.b[z] |= ovar.b[z]; + } break; } for(z=0; z<BITS; z++) { @@ -1486,11 +1537,12 @@ addreg(Adr *a, int rn) * 1 R1 * ... ... * 10 R10 + * 12 R12 */ int32 RtoB(int r) { - if(r >= REGTMP-2) // excluded R9 and R10 for m and g + if(r >= REGTMP-2 && r != 12) // excluded R9 and R10 for m and g, but not R12 return 0; return 1L << r; } @@ -1498,7 +1550,7 @@ RtoB(int r) int BtoR(int32 b) { - b &= 0x01fcL; // excluded R9 and R10 for m and g + b &= 0x11fcL; // excluded R9 and R10 for m and g, but not R12 if(b == 0) return 0; return bitno(b); @@ -1509,7 +1561,7 @@ BtoR(int32 b) * 18 F2 * 19 F3 * ... ... - * 23 F7 + * 31 F15 */ int32 FtoB(int f) @@ -1524,7 +1576,7 @@ int BtoF(int32 b) { - b &= 0xfc0000L; + b &= 0xfffc0000L; if(b == 0) return 0; return bitno(b) - 16; @@ -1643,7 +1695,7 @@ chasejmp(Prog *p, int *jmploop) *jmploop = 1; break; } - p = p->to.branch; + p = p->to.u.branch; } return p; } @@ -1665,8 +1717,8 @@ mark(Prog *firstp) if(p->regp != dead) break; p->regp = alive; - if(p->as != ABL && p->to.type == D_BRANCH && p->to.branch) - mark(p->to.branch); + if(p->as != ABL && p->to.type == D_BRANCH && p->to.u.branch) + mark(p->to.u.branch); if(p->as == AB || p->as == ARET || (p->as == ABL && noreturn(p))) break; } @@ -1686,8 +1738,8 @@ fixjmp(Prog *firstp) for(p=firstp; p; p=p->link) { if(debug['R'] && debug['v']) print("%P\n", p); - if(p->as != ABL && p->to.type == D_BRANCH && p->to.branch && p->to.branch->as == AB) { - p->to.branch = chasejmp(p->to.branch, &jmploop); + if(p->as != ABL && p->to.type == D_BRANCH && p->to.u.branch && p->to.u.branch->as == AB) { + p->to.u.branch = chasejmp(p->to.u.branch, &jmploop); if(debug['R'] && debug['v']) print("->%P\n", p); } @@ -1695,7 +1747,7 @@ fixjmp(Prog *firstp) } if(debug['R'] && debug['v']) print("\n"); - + // pass 2: mark all reachable code alive mark(firstp); @@ -1723,7 +1775,7 @@ fixjmp(Prog *firstp) if(!jmploop) { last = nil; for(p=firstp; p; p=p->link) { - if(p->as == AB && p->to.type == D_BRANCH && p->to.branch == p->link) { + if(p->as == AB && p->to.type == D_BRANCH && p->to.u.branch == p->link) { if(debug['R'] && debug['v']) print("del %P\n", p); continue; |