13e12c5d1SDavid du Colombier #include "gc.h"
23e12c5d1SDavid du Colombier
33e12c5d1SDavid du Colombier Reg*
rega(void)43e12c5d1SDavid du Colombier rega(void)
53e12c5d1SDavid du Colombier {
63e12c5d1SDavid du Colombier Reg *r;
73e12c5d1SDavid du Colombier
83e12c5d1SDavid du Colombier r = freer;
93e12c5d1SDavid du Colombier if(r == R) {
107dd7cddfSDavid du Colombier r = alloc(sizeof(*r));
113e12c5d1SDavid du Colombier } else
123e12c5d1SDavid du Colombier freer = r->link;
133e12c5d1SDavid du Colombier
143e12c5d1SDavid du Colombier *r = zreg;
153e12c5d1SDavid du Colombier return r;
163e12c5d1SDavid du Colombier }
173e12c5d1SDavid du Colombier
183e12c5d1SDavid du Colombier int
rcmp(const void * a1,const void * a2)197dd7cddfSDavid du Colombier rcmp(const void *a1, const void *a2)
203e12c5d1SDavid du Colombier {
213e12c5d1SDavid du Colombier Rgn *p1, *p2;
223e12c5d1SDavid du Colombier int c1, c2;
233e12c5d1SDavid du Colombier
247dd7cddfSDavid du Colombier p1 = (Rgn*)a1;
257dd7cddfSDavid du Colombier p2 = (Rgn*)a2;
263e12c5d1SDavid du Colombier c1 = p2->cost;
273e12c5d1SDavid du Colombier c2 = p1->cost;
283e12c5d1SDavid du Colombier if(c1 -= c2)
293e12c5d1SDavid du Colombier return c1;
303e12c5d1SDavid du Colombier return p2->varno - p1->varno;
313e12c5d1SDavid du Colombier }
323e12c5d1SDavid du Colombier
333e12c5d1SDavid du Colombier void
regopt(Prog * p)343e12c5d1SDavid du Colombier regopt(Prog *p)
353e12c5d1SDavid du Colombier {
363e12c5d1SDavid du Colombier Reg *r, *r1, *r2;
37219b2ee8SDavid du Colombier Prog *p1;
383e12c5d1SDavid du Colombier int i, z;
397dd7cddfSDavid du Colombier long initpc, val, npc;
403e12c5d1SDavid du Colombier ulong vreg;
413e12c5d1SDavid du Colombier Bits bit;
423e12c5d1SDavid du Colombier struct
433e12c5d1SDavid du Colombier {
443e12c5d1SDavid du Colombier long m;
453e12c5d1SDavid du Colombier long c;
463e12c5d1SDavid du Colombier Reg* p;
473e12c5d1SDavid du Colombier } log5[6], *lp;
483e12c5d1SDavid du Colombier
493e12c5d1SDavid du Colombier firstr = R;
503e12c5d1SDavid du Colombier lastr = R;
513e12c5d1SDavid du Colombier nvar = 0;
523e12c5d1SDavid du Colombier regbits = 0;
533e12c5d1SDavid du Colombier for(z=0; z<BITS; z++) {
543e12c5d1SDavid du Colombier externs.b[z] = 0;
553e12c5d1SDavid du Colombier params.b[z] = 0;
563e12c5d1SDavid du Colombier consts.b[z] = 0;
573e12c5d1SDavid du Colombier addrs.b[z] = 0;
583e12c5d1SDavid du Colombier }
593e12c5d1SDavid du Colombier
603e12c5d1SDavid du Colombier /*
613e12c5d1SDavid du Colombier * pass 1
623e12c5d1SDavid du Colombier * build aux data structure
633e12c5d1SDavid du Colombier * allocate pcs
643e12c5d1SDavid du Colombier * find use and set of variables
653e12c5d1SDavid du Colombier */
663e12c5d1SDavid du Colombier val = 5L * 5L * 5L * 5L * 5L;
673e12c5d1SDavid du Colombier lp = log5;
683e12c5d1SDavid du Colombier for(i=0; i<5; i++) {
693e12c5d1SDavid du Colombier lp->m = val;
703e12c5d1SDavid du Colombier lp->c = 0;
713e12c5d1SDavid du Colombier lp->p = R;
723e12c5d1SDavid du Colombier val /= 5L;
733e12c5d1SDavid du Colombier lp++;
743e12c5d1SDavid du Colombier }
753e12c5d1SDavid du Colombier val = 0;
763e12c5d1SDavid du Colombier for(; p != P; p = p->link) {
773e12c5d1SDavid du Colombier switch(p->as) {
783e12c5d1SDavid du Colombier case ADATA:
793e12c5d1SDavid du Colombier case AGLOBL:
803e12c5d1SDavid du Colombier case ANAME:
81*375daca8SDavid du Colombier case ASIGNAME:
823e12c5d1SDavid du Colombier continue;
833e12c5d1SDavid du Colombier }
843e12c5d1SDavid du Colombier r = rega();
853e12c5d1SDavid du Colombier if(firstr == R) {
863e12c5d1SDavid du Colombier firstr = r;
873e12c5d1SDavid du Colombier lastr = r;
883e12c5d1SDavid du Colombier } else {
893e12c5d1SDavid du Colombier lastr->link = r;
903e12c5d1SDavid du Colombier r->p1 = lastr;
913e12c5d1SDavid du Colombier lastr->s1 = r;
923e12c5d1SDavid du Colombier lastr = r;
933e12c5d1SDavid du Colombier }
943e12c5d1SDavid du Colombier r->prog = p;
953e12c5d1SDavid du Colombier r->pc = val;
963e12c5d1SDavid du Colombier val++;
973e12c5d1SDavid du Colombier
983e12c5d1SDavid du Colombier lp = log5;
993e12c5d1SDavid du Colombier for(i=0; i<5; i++) {
1003e12c5d1SDavid du Colombier lp->c--;
1013e12c5d1SDavid du Colombier if(lp->c <= 0) {
1023e12c5d1SDavid du Colombier lp->c = lp->m;
1033e12c5d1SDavid du Colombier if(lp->p != R)
1043e12c5d1SDavid du Colombier lp->p->log5 = r;
1053e12c5d1SDavid du Colombier lp->p = r;
1063e12c5d1SDavid du Colombier (lp+1)->c = 0;
1073e12c5d1SDavid du Colombier break;
1083e12c5d1SDavid du Colombier }
1093e12c5d1SDavid du Colombier lp++;
1103e12c5d1SDavid du Colombier }
1113e12c5d1SDavid du Colombier
1123e12c5d1SDavid du Colombier r1 = r->p1;
1133e12c5d1SDavid du Colombier if(r1 != R)
1143e12c5d1SDavid du Colombier switch(r1->prog->as) {
1153e12c5d1SDavid du Colombier case ARETURN:
1163e12c5d1SDavid du Colombier case AJMP:
1173e12c5d1SDavid du Colombier case ARETT:
1183e12c5d1SDavid du Colombier r->p1 = R;
1193e12c5d1SDavid du Colombier r1->s1 = R;
1203e12c5d1SDavid du Colombier }
1213e12c5d1SDavid du Colombier
1223e12c5d1SDavid du Colombier /*
1233e12c5d1SDavid du Colombier * left side always read
1243e12c5d1SDavid du Colombier */
1253e12c5d1SDavid du Colombier bit = mkvar(&p->from, p->as==AMOVW);
1263e12c5d1SDavid du Colombier for(z=0; z<BITS; z++)
1273e12c5d1SDavid du Colombier r->use1.b[z] |= bit.b[z];
1283e12c5d1SDavid du Colombier
1293e12c5d1SDavid du Colombier /*
1303e12c5d1SDavid du Colombier * right side depends on opcode
1313e12c5d1SDavid du Colombier */
1323e12c5d1SDavid du Colombier bit = mkvar(&p->to, 0);
1333e12c5d1SDavid du Colombier if(bany(&bit))
1343e12c5d1SDavid du Colombier switch(p->as) {
1353e12c5d1SDavid du Colombier default:
1363e12c5d1SDavid du Colombier diag(Z, "reg: unknown asop: %A", p->as);
1373e12c5d1SDavid du Colombier break;
1383e12c5d1SDavid du Colombier
1393e12c5d1SDavid du Colombier /*
1403e12c5d1SDavid du Colombier * right side write
1413e12c5d1SDavid du Colombier */
1423e12c5d1SDavid du Colombier case ANOP:
1433e12c5d1SDavid du Colombier case AMOVB:
1443e12c5d1SDavid du Colombier case AMOVBU:
1453e12c5d1SDavid du Colombier case AMOVH:
1463e12c5d1SDavid du Colombier case AMOVHU:
1473e12c5d1SDavid du Colombier case AMOVW:
1483e12c5d1SDavid du Colombier case AFMOVF:
1493e12c5d1SDavid du Colombier case AFMOVD:
1503e12c5d1SDavid du Colombier for(z=0; z<BITS; z++)
1513e12c5d1SDavid du Colombier r->set.b[z] |= bit.b[z];
1523e12c5d1SDavid du Colombier break;
1533e12c5d1SDavid du Colombier
1543e12c5d1SDavid du Colombier /*
1553e12c5d1SDavid du Colombier * funny
1563e12c5d1SDavid du Colombier */
1573e12c5d1SDavid du Colombier case AJMPL:
1583e12c5d1SDavid du Colombier for(z=0; z<BITS; z++)
1593e12c5d1SDavid du Colombier addrs.b[z] |= bit.b[z];
1603e12c5d1SDavid du Colombier break;
1613e12c5d1SDavid du Colombier }
1623e12c5d1SDavid du Colombier }
1633e12c5d1SDavid du Colombier if(firstr == R)
1643e12c5d1SDavid du Colombier return;
1653e12c5d1SDavid du Colombier initpc = pc - val;
1667dd7cddfSDavid du Colombier npc = val;
1673e12c5d1SDavid du Colombier
1683e12c5d1SDavid du Colombier /*
1693e12c5d1SDavid du Colombier * pass 2
1703e12c5d1SDavid du Colombier * turn branch references to pointers
1713e12c5d1SDavid du Colombier * build back pointers
1723e12c5d1SDavid du Colombier */
1733e12c5d1SDavid du Colombier for(r = firstr; r != R; r = r->link) {
1743e12c5d1SDavid du Colombier p = r->prog;
1753e12c5d1SDavid du Colombier if(p->to.type == D_BRANCH) {
1763e12c5d1SDavid du Colombier val = p->to.offset - initpc;
1773e12c5d1SDavid du Colombier r1 = firstr;
1783e12c5d1SDavid du Colombier while(r1 != R) {
1793e12c5d1SDavid du Colombier r2 = r1->log5;
1803e12c5d1SDavid du Colombier if(r2 != R && val >= r2->pc) {
1813e12c5d1SDavid du Colombier r1 = r2;
1823e12c5d1SDavid du Colombier continue;
1833e12c5d1SDavid du Colombier }
1843e12c5d1SDavid du Colombier if(r1->pc == val)
1853e12c5d1SDavid du Colombier break;
1863e12c5d1SDavid du Colombier r1 = r1->link;
1873e12c5d1SDavid du Colombier }
1883e12c5d1SDavid du Colombier if(r1 == R) {
1893e12c5d1SDavid du Colombier nearln = p->lineno;
1903e12c5d1SDavid du Colombier diag(Z, "ref not found\n%P", p);
1913e12c5d1SDavid du Colombier continue;
1923e12c5d1SDavid du Colombier }
1933e12c5d1SDavid du Colombier if(r1 == r) {
1943e12c5d1SDavid du Colombier nearln = p->lineno;
1953e12c5d1SDavid du Colombier diag(Z, "ref to self\n%P", p);
1963e12c5d1SDavid du Colombier continue;
1973e12c5d1SDavid du Colombier }
1983e12c5d1SDavid du Colombier r->s2 = r1;
1993e12c5d1SDavid du Colombier r->p2link = r1->p2;
2003e12c5d1SDavid du Colombier r1->p2 = r;
2013e12c5d1SDavid du Colombier }
2023e12c5d1SDavid du Colombier }
2033e12c5d1SDavid du Colombier if(debug['R']) {
2043e12c5d1SDavid du Colombier p = firstr->prog;
2053e12c5d1SDavid du Colombier print("\n%L %D\n", p->lineno, &p->from);
2063e12c5d1SDavid du Colombier }
2073e12c5d1SDavid du Colombier
2083e12c5d1SDavid du Colombier /*
2093e12c5d1SDavid du Colombier * pass 2.5
2103e12c5d1SDavid du Colombier * find looping structure
2113e12c5d1SDavid du Colombier */
2123e12c5d1SDavid du Colombier for(r = firstr; r != R; r = r->link)
2133e12c5d1SDavid du Colombier r->active = 0;
2143e12c5d1SDavid du Colombier change = 0;
2157dd7cddfSDavid du Colombier loopit(firstr, npc);
2163e12c5d1SDavid du Colombier if(debug['R'] && debug['v']) {
2173e12c5d1SDavid du Colombier print("\nlooping structure:\n");
2183e12c5d1SDavid du Colombier for(r = firstr; r != R; r = r->link) {
2197dd7cddfSDavid du Colombier print("%ld:%P", r->loop, r->prog);
2203e12c5d1SDavid du Colombier for(z=0; z<BITS; z++)
2213e12c5d1SDavid du Colombier bit.b[z] = r->use1.b[z] |
2223e12c5d1SDavid du Colombier r->use2.b[z] | r->set.b[z];
2233e12c5d1SDavid du Colombier if(bany(&bit)) {
2249a747e4fSDavid du Colombier print("\t");
2253e12c5d1SDavid du Colombier if(bany(&r->use1))
2263e12c5d1SDavid du Colombier print(" u1=%B", r->use1);
2273e12c5d1SDavid du Colombier if(bany(&r->use2))
2283e12c5d1SDavid du Colombier print(" u2=%B", r->use2);
2293e12c5d1SDavid du Colombier if(bany(&r->set))
2303e12c5d1SDavid du Colombier print(" st=%B", r->set);
2313e12c5d1SDavid du Colombier }
2323e12c5d1SDavid du Colombier print("\n");
2333e12c5d1SDavid du Colombier }
2343e12c5d1SDavid du Colombier }
2353e12c5d1SDavid du Colombier
2363e12c5d1SDavid du Colombier /*
2373e12c5d1SDavid du Colombier * pass 3
2383e12c5d1SDavid du Colombier * iterate propagating usage
2393e12c5d1SDavid du Colombier * back until flow graph is complete
2403e12c5d1SDavid du Colombier */
2413e12c5d1SDavid du Colombier loop1:
2423e12c5d1SDavid du Colombier change = 0;
2433e12c5d1SDavid du Colombier for(r = firstr; r != R; r = r->link)
2443e12c5d1SDavid du Colombier r->active = 0;
2453e12c5d1SDavid du Colombier for(r = firstr; r != R; r = r->link)
2463e12c5d1SDavid du Colombier if(r->prog->as == ARETURN)
2473e12c5d1SDavid du Colombier prop(r, zbits, zbits);
2483e12c5d1SDavid du Colombier loop11:
2493e12c5d1SDavid du Colombier /* pick up unreachable code */
2503e12c5d1SDavid du Colombier i = 0;
2513e12c5d1SDavid du Colombier for(r = firstr; r != R; r = r1) {
2523e12c5d1SDavid du Colombier r1 = r->link;
2533e12c5d1SDavid du Colombier if(r1 && r1->active && !r->active) {
2543e12c5d1SDavid du Colombier prop(r, zbits, zbits);
2553e12c5d1SDavid du Colombier i = 1;
2563e12c5d1SDavid du Colombier }
2573e12c5d1SDavid du Colombier }
2583e12c5d1SDavid du Colombier if(i)
2593e12c5d1SDavid du Colombier goto loop11;
2603e12c5d1SDavid du Colombier if(change)
2613e12c5d1SDavid du Colombier goto loop1;
2623e12c5d1SDavid du Colombier
2633e12c5d1SDavid du Colombier
2643e12c5d1SDavid du Colombier /*
2653e12c5d1SDavid du Colombier * pass 4
2663e12c5d1SDavid du Colombier * iterate propagating register/variable synchrony
2673e12c5d1SDavid du Colombier * forward until graph is complete
2683e12c5d1SDavid du Colombier */
2693e12c5d1SDavid du Colombier loop2:
2703e12c5d1SDavid du Colombier change = 0;
2713e12c5d1SDavid du Colombier for(r = firstr; r != R; r = r->link)
2723e12c5d1SDavid du Colombier r->active = 0;
2733e12c5d1SDavid du Colombier synch(firstr, zbits);
2743e12c5d1SDavid du Colombier if(change)
2753e12c5d1SDavid du Colombier goto loop2;
2763e12c5d1SDavid du Colombier
2773e12c5d1SDavid du Colombier
2783e12c5d1SDavid du Colombier /*
2793e12c5d1SDavid du Colombier * pass 5
2803e12c5d1SDavid du Colombier * isolate regions
2813e12c5d1SDavid du Colombier * calculate costs (paint1)
2823e12c5d1SDavid du Colombier */
2833e12c5d1SDavid du Colombier r = firstr;
2843e12c5d1SDavid du Colombier if(r) {
2853e12c5d1SDavid du Colombier for(z=0; z<BITS; z++)
2863e12c5d1SDavid du Colombier bit.b[z] = (r->refahead.b[z] | r->calahead.b[z]) &
2873e12c5d1SDavid du Colombier ~(externs.b[z] | params.b[z] | addrs.b[z] | consts.b[z]);
2883e12c5d1SDavid du Colombier if(bany(&bit)) {
2893e12c5d1SDavid du Colombier nearln = r->prog->lineno;
2903e12c5d1SDavid du Colombier warn(Z, "used and not set: %B", bit);
2913e12c5d1SDavid du Colombier if(debug['R'] && !debug['w'])
2923e12c5d1SDavid du Colombier print("used and not set: %B\n", bit);
2933e12c5d1SDavid du Colombier }
2943e12c5d1SDavid du Colombier }
2953e12c5d1SDavid du Colombier if(debug['R'] && debug['v'])
2963e12c5d1SDavid du Colombier print("\nprop structure:\n");
2973e12c5d1SDavid du Colombier for(r = firstr; r != R; r = r->link)
2983e12c5d1SDavid du Colombier r->act = zbits;
2993e12c5d1SDavid du Colombier rgp = region;
3003e12c5d1SDavid du Colombier nregion = 0;
3013e12c5d1SDavid du Colombier for(r = firstr; r != R; r = r->link) {
3023e12c5d1SDavid du Colombier if(debug['R'] && debug['v'])
3033e12c5d1SDavid du Colombier print("%P\n set = %B; rah = %B; cal = %B\n",
3043e12c5d1SDavid du Colombier r->prog, r->set, r->refahead, r->calahead);
3053e12c5d1SDavid du Colombier for(z=0; z<BITS; z++)
3063e12c5d1SDavid du Colombier bit.b[z] = r->set.b[z] &
3073e12c5d1SDavid du Colombier ~(r->refahead.b[z] | r->calahead.b[z] | addrs.b[z]);
3083e12c5d1SDavid du Colombier if(bany(&bit)) {
3093e12c5d1SDavid du Colombier nearln = r->prog->lineno;
3103e12c5d1SDavid du Colombier warn(Z, "set and not used: %B", bit);
3113e12c5d1SDavid du Colombier if(debug['R'])
3123e12c5d1SDavid du Colombier print("set an not used: %B\n", bit);
3133e12c5d1SDavid du Colombier excise(r);
3143e12c5d1SDavid du Colombier }
3153e12c5d1SDavid du Colombier for(z=0; z<BITS; z++)
3163e12c5d1SDavid du Colombier bit.b[z] = LOAD(r) & ~(r->act.b[z] | addrs.b[z]);
3173e12c5d1SDavid du Colombier while(bany(&bit)) {
3183e12c5d1SDavid du Colombier i = bnum(bit);
3193e12c5d1SDavid du Colombier rgp->enter = r;
3203e12c5d1SDavid du Colombier rgp->varno = i;
3213e12c5d1SDavid du Colombier change = 0;
3223e12c5d1SDavid du Colombier if(debug['R'] && debug['v'])
3233e12c5d1SDavid du Colombier print("\n");
3243e12c5d1SDavid du Colombier paint1(r, i);
3253e12c5d1SDavid du Colombier bit.b[i/32] &= ~(1L<<(i%32));
3263e12c5d1SDavid du Colombier if(change <= 0) {
3273e12c5d1SDavid du Colombier if(debug['R'])
3283e12c5d1SDavid du Colombier print("%L$%d: %B\n",
3293e12c5d1SDavid du Colombier r->prog->lineno, change, blsh(i));
3303e12c5d1SDavid du Colombier continue;
3313e12c5d1SDavid du Colombier }
3323e12c5d1SDavid du Colombier rgp->cost = change;
3333e12c5d1SDavid du Colombier nregion++;
3343e12c5d1SDavid du Colombier if(nregion >= NRGN) {
3353e12c5d1SDavid du Colombier warn(Z, "too many regions");
3363e12c5d1SDavid du Colombier goto brk;
3373e12c5d1SDavid du Colombier }
3383e12c5d1SDavid du Colombier rgp++;
3393e12c5d1SDavid du Colombier }
3403e12c5d1SDavid du Colombier }
3413e12c5d1SDavid du Colombier brk:
3423e12c5d1SDavid du Colombier qsort(region, nregion, sizeof(region[0]), rcmp);
3433e12c5d1SDavid du Colombier
3443e12c5d1SDavid du Colombier /*
3453e12c5d1SDavid du Colombier * pass 6
3463e12c5d1SDavid du Colombier * determine used registers (paint2)
3473e12c5d1SDavid du Colombier * replace code (paint3)
3483e12c5d1SDavid du Colombier */
3493e12c5d1SDavid du Colombier rgp = region;
3503e12c5d1SDavid du Colombier for(i=0; i<nregion; i++) {
3513e12c5d1SDavid du Colombier bit = blsh(rgp->varno);
3523e12c5d1SDavid du Colombier vreg = paint2(rgp->enter, rgp->varno);
3533e12c5d1SDavid du Colombier vreg = allreg(vreg, rgp);
3543e12c5d1SDavid du Colombier if(debug['R']) {
3553e12c5d1SDavid du Colombier if(rgp->regno >= NREG)
3563e12c5d1SDavid du Colombier print("%L$%d F%d: %B\n",
3573e12c5d1SDavid du Colombier rgp->enter->prog->lineno,
3583e12c5d1SDavid du Colombier rgp->cost,
3593e12c5d1SDavid du Colombier rgp->regno-NREG,
3603e12c5d1SDavid du Colombier bit);
3613e12c5d1SDavid du Colombier else
3623e12c5d1SDavid du Colombier print("%L$%d R%d: %B\n",
3633e12c5d1SDavid du Colombier rgp->enter->prog->lineno,
3643e12c5d1SDavid du Colombier rgp->cost,
3653e12c5d1SDavid du Colombier rgp->regno,
3663e12c5d1SDavid du Colombier bit);
3673e12c5d1SDavid du Colombier }
3683e12c5d1SDavid du Colombier if(rgp->regno != 0)
3693e12c5d1SDavid du Colombier paint3(rgp->enter, rgp->varno, vreg, rgp->regno);
3703e12c5d1SDavid du Colombier rgp++;
3713e12c5d1SDavid du Colombier }
3723e12c5d1SDavid du Colombier /*
3733e12c5d1SDavid du Colombier * pass 7
3743e12c5d1SDavid du Colombier * peep-hole on basic block
3753e12c5d1SDavid du Colombier */
3763e12c5d1SDavid du Colombier if(!debug['R'] || debug['P'])
3773e12c5d1SDavid du Colombier peep();
3783e12c5d1SDavid du Colombier
3793e12c5d1SDavid du Colombier /*
3803e12c5d1SDavid du Colombier * pass 8
3813e12c5d1SDavid du Colombier * recalculate pc
3823e12c5d1SDavid du Colombier */
3833e12c5d1SDavid du Colombier val = initpc;
3843e12c5d1SDavid du Colombier for(r = firstr; r != R; r = r1) {
3853e12c5d1SDavid du Colombier r->pc = val;
3863e12c5d1SDavid du Colombier p = r->prog;
387219b2ee8SDavid du Colombier p1 = P;
3883e12c5d1SDavid du Colombier r1 = r->link;
389219b2ee8SDavid du Colombier if(r1 != R)
390219b2ee8SDavid du Colombier p1 = r1->prog;
391219b2ee8SDavid du Colombier for(; p != p1; p = p->link) {
3923e12c5d1SDavid du Colombier switch(p->as) {
3933e12c5d1SDavid du Colombier default:
3943e12c5d1SDavid du Colombier val++;
395219b2ee8SDavid du Colombier break;
3963e12c5d1SDavid du Colombier
397219b2ee8SDavid du Colombier case ANOP:
3983e12c5d1SDavid du Colombier case ADATA:
3993e12c5d1SDavid du Colombier case AGLOBL:
4003e12c5d1SDavid du Colombier case ANAME:
401*375daca8SDavid du Colombier case ASIGNAME:
402219b2ee8SDavid du Colombier break;
4033e12c5d1SDavid du Colombier }
4043e12c5d1SDavid du Colombier }
405219b2ee8SDavid du Colombier }
406219b2ee8SDavid du Colombier pc = val;
4073e12c5d1SDavid du Colombier
4083e12c5d1SDavid du Colombier /*
4093e12c5d1SDavid du Colombier * fix up branches
4103e12c5d1SDavid du Colombier */
4113e12c5d1SDavid du Colombier if(debug['R'])
4123e12c5d1SDavid du Colombier if(bany(&addrs))
4133e12c5d1SDavid du Colombier print("addrs: %B\n", addrs);
4143e12c5d1SDavid du Colombier
4153e12c5d1SDavid du Colombier r1 = 0; /* set */
4163e12c5d1SDavid du Colombier for(r = firstr; r != R; r = r->link) {
4173e12c5d1SDavid du Colombier p = r->prog;
4183e12c5d1SDavid du Colombier if(p->to.type == D_BRANCH)
4193e12c5d1SDavid du Colombier p->to.offset = r->s2->pc;
4203e12c5d1SDavid du Colombier r1 = r;
4213e12c5d1SDavid du Colombier }
422219b2ee8SDavid du Colombier
423219b2ee8SDavid du Colombier /*
424219b2ee8SDavid du Colombier * last pass
425219b2ee8SDavid du Colombier * eliminate nops
426219b2ee8SDavid du Colombier * free aux structures
427219b2ee8SDavid du Colombier */
428219b2ee8SDavid du Colombier for(p = firstr->prog; p != P; p = p->link){
429219b2ee8SDavid du Colombier while(p->link && p->link->as == ANOP)
430219b2ee8SDavid du Colombier p->link = p->link->link;
431219b2ee8SDavid du Colombier }
4323e12c5d1SDavid du Colombier if(r1 != R) {
4333e12c5d1SDavid du Colombier r1->link = freer;
4343e12c5d1SDavid du Colombier freer = firstr;
4353e12c5d1SDavid du Colombier }
4363e12c5d1SDavid du Colombier }
4373e12c5d1SDavid du Colombier
4383e12c5d1SDavid du Colombier /*
4393e12c5d1SDavid du Colombier * add mov b,rn
4403e12c5d1SDavid du Colombier * just after r
4413e12c5d1SDavid du Colombier */
4423e12c5d1SDavid du Colombier void
addmove(Reg * r,int bn,int rn,int f)4433e12c5d1SDavid du Colombier addmove(Reg *r, int bn, int rn, int f)
4443e12c5d1SDavid du Colombier {
4453e12c5d1SDavid du Colombier Prog *p, *p1;
4463e12c5d1SDavid du Colombier Adr *a;
4473e12c5d1SDavid du Colombier Var *v;
4483e12c5d1SDavid du Colombier
4497dd7cddfSDavid du Colombier p1 = alloc(sizeof(*p1));
4503e12c5d1SDavid du Colombier *p1 = zprog;
4513e12c5d1SDavid du Colombier p = r->prog;
4523e12c5d1SDavid du Colombier
4533e12c5d1SDavid du Colombier p1->link = p->link;
4543e12c5d1SDavid du Colombier p->link = p1;
4553e12c5d1SDavid du Colombier p1->lineno = p->lineno;
4563e12c5d1SDavid du Colombier
4573e12c5d1SDavid du Colombier v = var + bn;
4583e12c5d1SDavid du Colombier
4593e12c5d1SDavid du Colombier a = &p1->to;
4603e12c5d1SDavid du Colombier a->sym = v->sym;
4613e12c5d1SDavid du Colombier a->name = v->name;
4623e12c5d1SDavid du Colombier a->offset = v->offset;
4633e12c5d1SDavid du Colombier a->etype = v->etype;
4643e12c5d1SDavid du Colombier a->type = D_OREG;
4653e12c5d1SDavid du Colombier if(a->etype == TARRAY || a->sym == S)
4663e12c5d1SDavid du Colombier a->type = D_CONST;
4673e12c5d1SDavid du Colombier
4683e12c5d1SDavid du Colombier p1->as = AMOVW;
4693e12c5d1SDavid du Colombier if(v->etype == TCHAR || v->etype == TUCHAR)
4703e12c5d1SDavid du Colombier p1->as = AMOVB;
4713e12c5d1SDavid du Colombier if(v->etype == TSHORT || v->etype == TUSHORT)
4723e12c5d1SDavid du Colombier p1->as = AMOVH;
4733e12c5d1SDavid du Colombier if(v->etype == TFLOAT)
4743e12c5d1SDavid du Colombier p1->as = AFMOVF;
4753e12c5d1SDavid du Colombier if(v->etype == TDOUBLE)
4763e12c5d1SDavid du Colombier p1->as = AFMOVD;
4773e12c5d1SDavid du Colombier
4783e12c5d1SDavid du Colombier p1->from.type = D_REG;
4793e12c5d1SDavid du Colombier p1->from.reg = rn;
4803e12c5d1SDavid du Colombier if(rn >= NREG) {
4813e12c5d1SDavid du Colombier p1->from.type = D_FREG;
4823e12c5d1SDavid du Colombier p1->from.reg = rn-NREG;
4833e12c5d1SDavid du Colombier }
4843e12c5d1SDavid du Colombier if(!f) {
4853e12c5d1SDavid du Colombier p1->from = *a;
4863e12c5d1SDavid du Colombier *a = zprog.from;
4873e12c5d1SDavid du Colombier a->type = D_REG;
4883e12c5d1SDavid du Colombier a->reg = rn;
4893e12c5d1SDavid du Colombier if(rn >= NREG) {
4903e12c5d1SDavid du Colombier a->type = D_FREG;
4913e12c5d1SDavid du Colombier a->reg = rn-NREG;
4923e12c5d1SDavid du Colombier }
4933e12c5d1SDavid du Colombier if(v->etype == TUCHAR)
4943e12c5d1SDavid du Colombier p1->as = AMOVBU;
4953e12c5d1SDavid du Colombier if(v->etype == TUSHORT)
4963e12c5d1SDavid du Colombier p1->as = AMOVHU;
4973e12c5d1SDavid du Colombier }
4983e12c5d1SDavid du Colombier if(debug['R'])
4999a747e4fSDavid du Colombier print("%P\t.a%P\n", p, p1);
5003e12c5d1SDavid du Colombier }
5013e12c5d1SDavid du Colombier
5023e12c5d1SDavid du Colombier Bits
mkvar(Adr * a,int docon)5033e12c5d1SDavid du Colombier mkvar(Adr *a, int docon)
5043e12c5d1SDavid du Colombier {
5053e12c5d1SDavid du Colombier Var *v;
5063e12c5d1SDavid du Colombier int i, t, n, et, z;
5073e12c5d1SDavid du Colombier long o;
5083e12c5d1SDavid du Colombier Bits bit;
5093e12c5d1SDavid du Colombier Sym *s;
5103e12c5d1SDavid du Colombier
5113e12c5d1SDavid du Colombier t = a->type;
5123e12c5d1SDavid du Colombier if(t == D_REG && a->reg != NREG)
5133e12c5d1SDavid du Colombier regbits |= RtoB(a->reg);
5143e12c5d1SDavid du Colombier if(t == D_FREG && a->reg != NREG)
5153e12c5d1SDavid du Colombier regbits |= FtoB(a->reg);
5163e12c5d1SDavid du Colombier s = a->sym;
5173e12c5d1SDavid du Colombier o = a->offset;
5183e12c5d1SDavid du Colombier et = a->etype;
5193e12c5d1SDavid du Colombier if(s == S) {
5203e12c5d1SDavid du Colombier if(t != D_CONST || !docon || a->reg != NREG)
5213e12c5d1SDavid du Colombier goto none;
5223e12c5d1SDavid du Colombier et = TLONG;
5233e12c5d1SDavid du Colombier }
5243e12c5d1SDavid du Colombier if(t == D_CONST) {
5253e12c5d1SDavid du Colombier if(s == S && sval(o))
5263e12c5d1SDavid du Colombier goto none;
5273e12c5d1SDavid du Colombier }
5283e12c5d1SDavid du Colombier n = a->name;
5293e12c5d1SDavid du Colombier v = var;
5303e12c5d1SDavid du Colombier for(i=0; i<nvar; i++) {
5313e12c5d1SDavid du Colombier if(s == v->sym)
5323e12c5d1SDavid du Colombier if(n == v->name)
5333e12c5d1SDavid du Colombier if(o == v->offset)
5343e12c5d1SDavid du Colombier goto out;
5353e12c5d1SDavid du Colombier v++;
5363e12c5d1SDavid du Colombier }
5373e12c5d1SDavid du Colombier if(s)
5383e12c5d1SDavid du Colombier if(s->name[0] == '.')
5393e12c5d1SDavid du Colombier goto none;
5403e12c5d1SDavid du Colombier if(nvar >= NVAR) {
5417dd7cddfSDavid du Colombier if(debug['w'] > 1 && s)
5423e12c5d1SDavid du Colombier warn(Z, "variable not optimized: %s", s->name);
5433e12c5d1SDavid du Colombier goto none;
5443e12c5d1SDavid du Colombier }
5453e12c5d1SDavid du Colombier i = nvar;
5463e12c5d1SDavid du Colombier nvar++;
5473e12c5d1SDavid du Colombier v = &var[i];
5483e12c5d1SDavid du Colombier v->sym = s;
5493e12c5d1SDavid du Colombier v->offset = o;
5503e12c5d1SDavid du Colombier v->etype = et;
5513e12c5d1SDavid du Colombier v->name = n;
5523e12c5d1SDavid du Colombier if(debug['R'])
5533e12c5d1SDavid du Colombier print("bit=%2d et=%2d %D\n", i, et, a);
5543e12c5d1SDavid du Colombier out:
5553e12c5d1SDavid du Colombier bit = blsh(i);
5563e12c5d1SDavid du Colombier if(n == D_EXTERN || n == D_STATIC)
5573e12c5d1SDavid du Colombier for(z=0; z<BITS; z++)
5583e12c5d1SDavid du Colombier externs.b[z] |= bit.b[z];
5593e12c5d1SDavid du Colombier if(n == D_PARAM)
5603e12c5d1SDavid du Colombier for(z=0; z<BITS; z++)
5613e12c5d1SDavid du Colombier params.b[z] |= bit.b[z];
562219b2ee8SDavid du Colombier if(v->etype != et || !typechlpfd[et]) /* funny punning */
5633e12c5d1SDavid du Colombier for(z=0; z<BITS; z++)
5643e12c5d1SDavid du Colombier addrs.b[z] |= bit.b[z];
5653e12c5d1SDavid du Colombier if(t == D_CONST) {
5663e12c5d1SDavid du Colombier if(s == S) {
5673e12c5d1SDavid du Colombier for(z=0; z<BITS; z++)
5683e12c5d1SDavid du Colombier consts.b[z] |= bit.b[z];
5693e12c5d1SDavid du Colombier return bit;
5703e12c5d1SDavid du Colombier }
5713e12c5d1SDavid du Colombier if(et != TARRAY)
5723e12c5d1SDavid du Colombier for(z=0; z<BITS; z++)
5733e12c5d1SDavid du Colombier addrs.b[z] |= bit.b[z];
5743e12c5d1SDavid du Colombier for(z=0; z<BITS; z++)
5753e12c5d1SDavid du Colombier params.b[z] |= bit.b[z];
5763e12c5d1SDavid du Colombier return bit;
5773e12c5d1SDavid du Colombier }
5783e12c5d1SDavid du Colombier if(t == D_OREG)
5793e12c5d1SDavid du Colombier return bit;
5803e12c5d1SDavid du Colombier
5813e12c5d1SDavid du Colombier none:
5823e12c5d1SDavid du Colombier return zbits;
5833e12c5d1SDavid du Colombier }
5843e12c5d1SDavid du Colombier
5853e12c5d1SDavid du Colombier void
prop(Reg * r,Bits ref,Bits cal)5863e12c5d1SDavid du Colombier prop(Reg *r, Bits ref, Bits cal)
5873e12c5d1SDavid du Colombier {
5883e12c5d1SDavid du Colombier Reg *r1, *r2;
5893e12c5d1SDavid du Colombier int z;
5903e12c5d1SDavid du Colombier
5913e12c5d1SDavid du Colombier for(r1 = r; r1 != R; r1 = r1->p1) {
5923e12c5d1SDavid du Colombier for(z=0; z<BITS; z++) {
5933e12c5d1SDavid du Colombier ref.b[z] |= r1->refahead.b[z];
5943e12c5d1SDavid du Colombier if(ref.b[z] != r1->refahead.b[z]) {
5953e12c5d1SDavid du Colombier r1->refahead.b[z] = ref.b[z];
5963e12c5d1SDavid du Colombier change++;
5973e12c5d1SDavid du Colombier }
5983e12c5d1SDavid du Colombier cal.b[z] |= r1->calahead.b[z];
5993e12c5d1SDavid du Colombier if(cal.b[z] != r1->calahead.b[z]) {
6003e12c5d1SDavid du Colombier r1->calahead.b[z] = cal.b[z];
6013e12c5d1SDavid du Colombier change++;
6023e12c5d1SDavid du Colombier }
6033e12c5d1SDavid du Colombier }
6043e12c5d1SDavid du Colombier switch(r1->prog->as) {
6053e12c5d1SDavid du Colombier case AJMPL:
6063e12c5d1SDavid du Colombier for(z=0; z<BITS; z++) {
6073e12c5d1SDavid du Colombier cal.b[z] |= ref.b[z] | externs.b[z];
6083e12c5d1SDavid du Colombier ref.b[z] = 0;
6093e12c5d1SDavid du Colombier }
6103e12c5d1SDavid du Colombier break;
6113e12c5d1SDavid du Colombier
6123e12c5d1SDavid du Colombier case ATEXT:
6133e12c5d1SDavid du Colombier for(z=0; z<BITS; z++) {
6143e12c5d1SDavid du Colombier cal.b[z] = 0;
6153e12c5d1SDavid du Colombier ref.b[z] = 0;
6163e12c5d1SDavid du Colombier }
6173e12c5d1SDavid du Colombier break;
6183e12c5d1SDavid du Colombier
6193e12c5d1SDavid du Colombier case ARETURN:
6203e12c5d1SDavid du Colombier for(z=0; z<BITS; z++) {
6213e12c5d1SDavid du Colombier cal.b[z] = externs.b[z];
6223e12c5d1SDavid du Colombier ref.b[z] = 0;
6233e12c5d1SDavid du Colombier }
6243e12c5d1SDavid du Colombier }
6253e12c5d1SDavid du Colombier for(z=0; z<BITS; z++) {
6263e12c5d1SDavid du Colombier ref.b[z] = (ref.b[z] & ~r1->set.b[z]) |
6273e12c5d1SDavid du Colombier r1->use1.b[z] | r1->use2.b[z];
6283e12c5d1SDavid du Colombier cal.b[z] &= ~(r1->set.b[z] | r1->use1.b[z] | r1->use2.b[z]);
6293e12c5d1SDavid du Colombier r1->refbehind.b[z] = ref.b[z];
6303e12c5d1SDavid du Colombier r1->calbehind.b[z] = cal.b[z];
6313e12c5d1SDavid du Colombier }
6323e12c5d1SDavid du Colombier if(r1->active)
6333e12c5d1SDavid du Colombier break;
6343e12c5d1SDavid du Colombier r1->active = 1;
6353e12c5d1SDavid du Colombier }
6363e12c5d1SDavid du Colombier for(; r != r1; r = r->p1)
6373e12c5d1SDavid du Colombier for(r2 = r->p2; r2 != R; r2 = r2->p2link)
6383e12c5d1SDavid du Colombier prop(r2, r->refbehind, r->calbehind);
6393e12c5d1SDavid du Colombier }
6403e12c5d1SDavid du Colombier
6417dd7cddfSDavid du Colombier
6427dd7cddfSDavid du Colombier /*
6437dd7cddfSDavid du Colombier * find looping structure
6447dd7cddfSDavid du Colombier *
6457dd7cddfSDavid du Colombier * 1) find reverse postordering
6467dd7cddfSDavid du Colombier * 2) find approximate dominators,
6477dd7cddfSDavid du Colombier * the actual dominators if the flow graph is reducible
6487dd7cddfSDavid du Colombier * otherwise, dominators plus some other non-dominators.
6497dd7cddfSDavid du Colombier * See Matthew S. Hecht and Jeffrey D. Ullman,
6507dd7cddfSDavid du Colombier * "Analysis of a Simple Algorithm for Global Data Flow Problems",
6517dd7cddfSDavid du Colombier * Conf. Record of ACM Symp. on Principles of Prog. Langs, Boston, Massachusetts,
6527dd7cddfSDavid du Colombier * Oct. 1-3, 1973, pp. 207-217.
6537dd7cddfSDavid du Colombier * 3) find all nodes with a predecessor dominated by the current node.
6547dd7cddfSDavid du Colombier * such a node is a loop head.
6557dd7cddfSDavid du Colombier * recursively, all preds with a greater rpo number are in the loop
6567dd7cddfSDavid du Colombier */
6577dd7cddfSDavid du Colombier long
postorder(Reg * r,Reg ** rpo2r,long n)6587dd7cddfSDavid du Colombier postorder(Reg *r, Reg **rpo2r, long n)
6593e12c5d1SDavid du Colombier {
6603e12c5d1SDavid du Colombier Reg *r1;
6613e12c5d1SDavid du Colombier
6627dd7cddfSDavid du Colombier r->rpo = 1;
6637dd7cddfSDavid du Colombier r1 = r->s1;
6647dd7cddfSDavid du Colombier if(r1 && !r1->rpo)
6657dd7cddfSDavid du Colombier n = postorder(r1, rpo2r, n);
6667dd7cddfSDavid du Colombier r1 = r->s2;
6677dd7cddfSDavid du Colombier if(r1 && !r1->rpo)
6687dd7cddfSDavid du Colombier n = postorder(r1, rpo2r, n);
6697dd7cddfSDavid du Colombier rpo2r[n] = r;
6707dd7cddfSDavid du Colombier n++;
6717dd7cddfSDavid du Colombier return n;
6723e12c5d1SDavid du Colombier }
6737dd7cddfSDavid du Colombier
6747dd7cddfSDavid du Colombier long
rpolca(long * idom,long rpo1,long rpo2)6757dd7cddfSDavid du Colombier rpolca(long *idom, long rpo1, long rpo2)
6767dd7cddfSDavid du Colombier {
6777dd7cddfSDavid du Colombier long t;
6787dd7cddfSDavid du Colombier
6797dd7cddfSDavid du Colombier if(rpo1 == -1)
6807dd7cddfSDavid du Colombier return rpo2;
6817dd7cddfSDavid du Colombier while(rpo1 != rpo2){
6827dd7cddfSDavid du Colombier if(rpo1 > rpo2){
6837dd7cddfSDavid du Colombier t = rpo2;
6847dd7cddfSDavid du Colombier rpo2 = rpo1;
6857dd7cddfSDavid du Colombier rpo1 = t;
6863e12c5d1SDavid du Colombier }
6877dd7cddfSDavid du Colombier while(rpo1 < rpo2){
6887dd7cddfSDavid du Colombier t = idom[rpo2];
6897dd7cddfSDavid du Colombier if(t >= rpo2)
690*375daca8SDavid du Colombier fatal(Z, "bad idom");
6917dd7cddfSDavid du Colombier rpo2 = t;
6927dd7cddfSDavid du Colombier }
6937dd7cddfSDavid du Colombier }
6947dd7cddfSDavid du Colombier return rpo1;
6957dd7cddfSDavid du Colombier }
6967dd7cddfSDavid du Colombier
6977dd7cddfSDavid du Colombier int
doms(long * idom,long r,long s)6987dd7cddfSDavid du Colombier doms(long *idom, long r, long s)
6997dd7cddfSDavid du Colombier {
7007dd7cddfSDavid du Colombier while(s > r)
7017dd7cddfSDavid du Colombier s = idom[s];
7027dd7cddfSDavid du Colombier return s == r;
7037dd7cddfSDavid du Colombier }
7047dd7cddfSDavid du Colombier
7057dd7cddfSDavid du Colombier int
loophead(long * idom,Reg * r)7067dd7cddfSDavid du Colombier loophead(long *idom, Reg *r)
7077dd7cddfSDavid du Colombier {
7087dd7cddfSDavid du Colombier long src;
7097dd7cddfSDavid du Colombier
7107dd7cddfSDavid du Colombier src = r->rpo;
7117dd7cddfSDavid du Colombier if(r->p1 != R && doms(idom, src, r->p1->rpo))
7127dd7cddfSDavid du Colombier return 1;
7137dd7cddfSDavid du Colombier for(r = r->p2; r != R; r = r->p2link)
7147dd7cddfSDavid du Colombier if(doms(idom, src, r->rpo))
7157dd7cddfSDavid du Colombier return 1;
7167dd7cddfSDavid du Colombier return 0;
7177dd7cddfSDavid du Colombier }
7187dd7cddfSDavid du Colombier
7197dd7cddfSDavid du Colombier void
loopmark(Reg ** rpo2r,long head,Reg * r)7207dd7cddfSDavid du Colombier loopmark(Reg **rpo2r, long head, Reg *r)
7217dd7cddfSDavid du Colombier {
7227dd7cddfSDavid du Colombier if(r->rpo < head || r->active == head)
7237dd7cddfSDavid du Colombier return;
7247dd7cddfSDavid du Colombier r->active = head;
7257dd7cddfSDavid du Colombier r->loop += LOOP;
7267dd7cddfSDavid du Colombier if(r->p1 != R)
7277dd7cddfSDavid du Colombier loopmark(rpo2r, head, r->p1);
7287dd7cddfSDavid du Colombier for(r = r->p2; r != R; r = r->p2link)
7297dd7cddfSDavid du Colombier loopmark(rpo2r, head, r);
7307dd7cddfSDavid du Colombier }
7317dd7cddfSDavid du Colombier
7327dd7cddfSDavid du Colombier void
loopit(Reg * r,long nr)7337dd7cddfSDavid du Colombier loopit(Reg *r, long nr)
7347dd7cddfSDavid du Colombier {
73559cc4ca5SDavid du Colombier Reg *r1;
73659cc4ca5SDavid du Colombier long i, d, me;
7377dd7cddfSDavid du Colombier
73859cc4ca5SDavid du Colombier if(nr > maxnr) {
73959cc4ca5SDavid du Colombier rpo2r = alloc(nr * sizeof(Reg*));
74059cc4ca5SDavid du Colombier idom = alloc(nr * sizeof(long));
74159cc4ca5SDavid du Colombier maxnr = nr;
74259cc4ca5SDavid du Colombier }
74359cc4ca5SDavid du Colombier
7447dd7cddfSDavid du Colombier d = postorder(r, rpo2r, 0);
7457dd7cddfSDavid du Colombier if(d > nr)
746*375daca8SDavid du Colombier fatal(Z, "too many reg nodes");
7477dd7cddfSDavid du Colombier nr = d;
7487dd7cddfSDavid du Colombier for(i = 0; i < nr / 2; i++){
7497dd7cddfSDavid du Colombier r1 = rpo2r[i];
7507dd7cddfSDavid du Colombier rpo2r[i] = rpo2r[nr - 1 - i];
7517dd7cddfSDavid du Colombier rpo2r[nr - 1 - i] = r1;
7527dd7cddfSDavid du Colombier }
7537dd7cddfSDavid du Colombier for(i = 0; i < nr; i++)
7547dd7cddfSDavid du Colombier rpo2r[i]->rpo = i;
7557dd7cddfSDavid du Colombier
7567dd7cddfSDavid du Colombier idom[0] = 0;
7577dd7cddfSDavid du Colombier for(i = 0; i < nr; i++){
7587dd7cddfSDavid du Colombier r1 = rpo2r[i];
7597dd7cddfSDavid du Colombier me = r1->rpo;
7607dd7cddfSDavid du Colombier d = -1;
7617dd7cddfSDavid du Colombier if(r1->p1 != R && r1->p1->rpo < me)
7627dd7cddfSDavid du Colombier d = r1->p1->rpo;
7637dd7cddfSDavid du Colombier for(r1 = r1->p2; r1 != nil; r1 = r1->p2link)
7647dd7cddfSDavid du Colombier if(r1->rpo < me)
7657dd7cddfSDavid du Colombier d = rpolca(idom, d, r1->rpo);
7667dd7cddfSDavid du Colombier idom[i] = d;
7677dd7cddfSDavid du Colombier }
7687dd7cddfSDavid du Colombier
7697dd7cddfSDavid du Colombier for(i = 0; i < nr; i++){
7707dd7cddfSDavid du Colombier r1 = rpo2r[i];
7717dd7cddfSDavid du Colombier r1->loop++;
7727dd7cddfSDavid du Colombier if(r1->p2 != R && loophead(idom, r1))
7737dd7cddfSDavid du Colombier loopmark(rpo2r, i, r1);
7747dd7cddfSDavid du Colombier }
7753e12c5d1SDavid du Colombier }
7763e12c5d1SDavid du Colombier
7773e12c5d1SDavid du Colombier void
synch(Reg * r,Bits dif)7783e12c5d1SDavid du Colombier synch(Reg *r, Bits dif)
7793e12c5d1SDavid du Colombier {
7803e12c5d1SDavid du Colombier Reg *r1;
7813e12c5d1SDavid du Colombier int z;
7823e12c5d1SDavid du Colombier
7833e12c5d1SDavid du Colombier for(r1 = r; r1 != R; r1 = r1->s1) {
7843e12c5d1SDavid du Colombier for(z=0; z<BITS; z++) {
7853e12c5d1SDavid du Colombier dif.b[z] = (dif.b[z] &
7863e12c5d1SDavid du Colombier ~(~r1->refbehind.b[z] & r1->refahead.b[z])) |
7873e12c5d1SDavid du Colombier r1->set.b[z] | r1->regdiff.b[z];
7883e12c5d1SDavid du Colombier if(dif.b[z] != r1->regdiff.b[z]) {
7893e12c5d1SDavid du Colombier r1->regdiff.b[z] = dif.b[z];
7903e12c5d1SDavid du Colombier change++;
7913e12c5d1SDavid du Colombier }
7923e12c5d1SDavid du Colombier }
7933e12c5d1SDavid du Colombier if(r1->active)
7943e12c5d1SDavid du Colombier break;
7953e12c5d1SDavid du Colombier r1->active = 1;
7963e12c5d1SDavid du Colombier for(z=0; z<BITS; z++)
7973e12c5d1SDavid du Colombier dif.b[z] &= ~(~r1->calbehind.b[z] & r1->calahead.b[z]);
7983e12c5d1SDavid du Colombier if(r1->s2 != R)
7993e12c5d1SDavid du Colombier synch(r1->s2, dif);
8003e12c5d1SDavid du Colombier }
8013e12c5d1SDavid du Colombier }
8023e12c5d1SDavid du Colombier
8033e12c5d1SDavid du Colombier ulong
allreg(ulong b,Rgn * r)8043e12c5d1SDavid du Colombier allreg(ulong b, Rgn *r)
8053e12c5d1SDavid du Colombier {
8063e12c5d1SDavid du Colombier Var *v;
8073e12c5d1SDavid du Colombier int i;
8083e12c5d1SDavid du Colombier
8093e12c5d1SDavid du Colombier v = var + r->varno;
8103e12c5d1SDavid du Colombier r->regno = 0;
8113e12c5d1SDavid du Colombier switch(v->etype) {
8123e12c5d1SDavid du Colombier
8133e12c5d1SDavid du Colombier default:
8143e12c5d1SDavid du Colombier diag(Z, "unknown etype %d/%d", bitno(b), v->etype);
8153e12c5d1SDavid du Colombier break;
8163e12c5d1SDavid du Colombier
8173e12c5d1SDavid du Colombier case TCHAR:
8183e12c5d1SDavid du Colombier case TUCHAR:
8193e12c5d1SDavid du Colombier case TSHORT:
8203e12c5d1SDavid du Colombier case TUSHORT:
8217dd7cddfSDavid du Colombier case TINT:
8227dd7cddfSDavid du Colombier case TUINT:
8233e12c5d1SDavid du Colombier case TLONG:
8243e12c5d1SDavid du Colombier case TULONG:
8253e12c5d1SDavid du Colombier case TIND:
8263e12c5d1SDavid du Colombier case TARRAY:
8273e12c5d1SDavid du Colombier i = BtoR(~b);
8283e12c5d1SDavid du Colombier if(i && r->cost > 0) {
8293e12c5d1SDavid du Colombier r->regno = i;
8303e12c5d1SDavid du Colombier return RtoB(i);
8313e12c5d1SDavid du Colombier }
8323e12c5d1SDavid du Colombier break;
8333e12c5d1SDavid du Colombier
8343e12c5d1SDavid du Colombier case TDOUBLE:
8353e12c5d1SDavid du Colombier case TFLOAT:
8363e12c5d1SDavid du Colombier i = BtoF(~b);
8373e12c5d1SDavid du Colombier if(i && r->cost > 0) {
8383e12c5d1SDavid du Colombier r->regno = i+NREG;
8393e12c5d1SDavid du Colombier return FtoB(i);
8403e12c5d1SDavid du Colombier }
8413e12c5d1SDavid du Colombier break;
8423e12c5d1SDavid du Colombier }
8433e12c5d1SDavid du Colombier return 0;
8443e12c5d1SDavid du Colombier }
8453e12c5d1SDavid du Colombier
8463e12c5d1SDavid du Colombier void
paint1(Reg * r,int bn)8473e12c5d1SDavid du Colombier paint1(Reg *r, int bn)
8483e12c5d1SDavid du Colombier {
8493e12c5d1SDavid du Colombier Reg *r1;
8503e12c5d1SDavid du Colombier Prog *p;
8513e12c5d1SDavid du Colombier int z;
8523e12c5d1SDavid du Colombier ulong bb;
8533e12c5d1SDavid du Colombier
8543e12c5d1SDavid du Colombier z = bn/32;
8553e12c5d1SDavid du Colombier bb = 1L<<(bn%32);
8563e12c5d1SDavid du Colombier if(r->act.b[z] & bb)
8573e12c5d1SDavid du Colombier return;
8583e12c5d1SDavid du Colombier for(;;) {
8593e12c5d1SDavid du Colombier if(!(r->refbehind.b[z] & bb))
8603e12c5d1SDavid du Colombier break;
8613e12c5d1SDavid du Colombier r1 = r->p1;
8623e12c5d1SDavid du Colombier if(r1 == R)
8633e12c5d1SDavid du Colombier break;
8643e12c5d1SDavid du Colombier if(!(r1->refahead.b[z] & bb))
8653e12c5d1SDavid du Colombier break;
8663e12c5d1SDavid du Colombier if(r1->act.b[z] & bb)
8673e12c5d1SDavid du Colombier break;
8683e12c5d1SDavid du Colombier r = r1;
8693e12c5d1SDavid du Colombier }
8703e12c5d1SDavid du Colombier
8713e12c5d1SDavid du Colombier if(LOAD(r) & ~(r->set.b[z]&~(r->use1.b[z]|r->use2.b[z])) & bb) {
8723e12c5d1SDavid du Colombier change -= CLOAD * r->loop;
8733e12c5d1SDavid du Colombier if(debug['R'] && debug['v'])
8749a747e4fSDavid du Colombier print("%ld%P\tld %B $%d\n", r->loop,
8759a747e4fSDavid du Colombier r->prog, blsh(bn), change);
8763e12c5d1SDavid du Colombier }
8773e12c5d1SDavid du Colombier for(;;) {
8783e12c5d1SDavid du Colombier r->act.b[z] |= bb;
8793e12c5d1SDavid du Colombier p = r->prog;
8803e12c5d1SDavid du Colombier
8813e12c5d1SDavid du Colombier if(r->use1.b[z] & bb) {
8823e12c5d1SDavid du Colombier change += CREF * r->loop;
8833e12c5d1SDavid du Colombier if(p->to.type == D_FREG && p->as == AMOVW)
8843e12c5d1SDavid du Colombier change = -CINF; /* cant go Rreg to Freg */
8853e12c5d1SDavid du Colombier if(debug['R'] && debug['v'])
8869a747e4fSDavid du Colombier print("%ld%P\tu1 %B $%d\n", r->loop,
8879a747e4fSDavid du Colombier p, blsh(bn), change);
8883e12c5d1SDavid du Colombier }
8893e12c5d1SDavid du Colombier
8903e12c5d1SDavid du Colombier if((r->use2.b[z]|r->set.b[z]) & bb) {
8913e12c5d1SDavid du Colombier change += CREF * r->loop;
8923e12c5d1SDavid du Colombier if(p->from.type == D_FREG && p->as == AMOVW)
8933e12c5d1SDavid du Colombier change = -CINF; /* cant go Rreg to Freg */
8943e12c5d1SDavid du Colombier if(debug['R'] && debug['v'])
8959a747e4fSDavid du Colombier print("%ld%P\tu2 %B $%d\n", r->loop,
8969a747e4fSDavid du Colombier p, blsh(bn), change);
8973e12c5d1SDavid du Colombier }
8983e12c5d1SDavid du Colombier
8993e12c5d1SDavid du Colombier if(STORE(r) & r->regdiff.b[z] & bb) {
9003e12c5d1SDavid du Colombier change -= CLOAD * r->loop;
9013e12c5d1SDavid du Colombier if(debug['R'] && debug['v'])
9029a747e4fSDavid du Colombier print("%ld%P\tst %B $%d\n", r->loop,
9039a747e4fSDavid du Colombier p, blsh(bn), change);
9043e12c5d1SDavid du Colombier }
9053e12c5d1SDavid du Colombier
9063e12c5d1SDavid du Colombier if(r->refbehind.b[z] & bb)
9073e12c5d1SDavid du Colombier for(r1 = r->p2; r1 != R; r1 = r1->p2link)
9083e12c5d1SDavid du Colombier if(r1->refahead.b[z] & bb)
9093e12c5d1SDavid du Colombier paint1(r1, bn);
9103e12c5d1SDavid du Colombier
9113e12c5d1SDavid du Colombier if(!(r->refahead.b[z] & bb))
9123e12c5d1SDavid du Colombier break;
9133e12c5d1SDavid du Colombier r1 = r->s2;
9143e12c5d1SDavid du Colombier if(r1 != R)
9153e12c5d1SDavid du Colombier if(r1->refbehind.b[z] & bb)
9163e12c5d1SDavid du Colombier paint1(r1, bn);
9173e12c5d1SDavid du Colombier r = r->s1;
9183e12c5d1SDavid du Colombier if(r == R)
9193e12c5d1SDavid du Colombier break;
9203e12c5d1SDavid du Colombier if(r->act.b[z] & bb)
9213e12c5d1SDavid du Colombier break;
9223e12c5d1SDavid du Colombier if(!(r->refbehind.b[z] & bb))
9233e12c5d1SDavid du Colombier break;
9243e12c5d1SDavid du Colombier }
9253e12c5d1SDavid du Colombier }
9263e12c5d1SDavid du Colombier
9273e12c5d1SDavid du Colombier ulong
paint2(Reg * r,int bn)9283e12c5d1SDavid du Colombier paint2(Reg *r, int bn)
9293e12c5d1SDavid du Colombier {
9303e12c5d1SDavid du Colombier Reg *r1;
9313e12c5d1SDavid du Colombier int z;
9323e12c5d1SDavid du Colombier ulong bb, vreg;
9333e12c5d1SDavid du Colombier
9343e12c5d1SDavid du Colombier z = bn/32;
9353e12c5d1SDavid du Colombier bb = 1L << (bn%32);
9363e12c5d1SDavid du Colombier vreg = regbits;
9373e12c5d1SDavid du Colombier if(!(r->act.b[z] & bb))
9383e12c5d1SDavid du Colombier return vreg;
9393e12c5d1SDavid du Colombier for(;;) {
9403e12c5d1SDavid du Colombier if(!(r->refbehind.b[z] & bb))
9413e12c5d1SDavid du Colombier break;
9423e12c5d1SDavid du Colombier r1 = r->p1;
9433e12c5d1SDavid du Colombier if(r1 == R)
9443e12c5d1SDavid du Colombier break;
9453e12c5d1SDavid du Colombier if(!(r1->refahead.b[z] & bb))
9463e12c5d1SDavid du Colombier break;
9473e12c5d1SDavid du Colombier if(!(r1->act.b[z] & bb))
9483e12c5d1SDavid du Colombier break;
9493e12c5d1SDavid du Colombier r = r1;
9503e12c5d1SDavid du Colombier }
9513e12c5d1SDavid du Colombier for(;;) {
9523e12c5d1SDavid du Colombier r->act.b[z] &= ~bb;
9533e12c5d1SDavid du Colombier
9543e12c5d1SDavid du Colombier vreg |= r->regu;
9553e12c5d1SDavid du Colombier
9563e12c5d1SDavid du Colombier if(r->refbehind.b[z] & bb)
9573e12c5d1SDavid du Colombier for(r1 = r->p2; r1 != R; r1 = r1->p2link)
9583e12c5d1SDavid du Colombier if(r1->refahead.b[z] & bb)
9593e12c5d1SDavid du Colombier vreg |= paint2(r1, bn);
9603e12c5d1SDavid du Colombier
9613e12c5d1SDavid du Colombier if(!(r->refahead.b[z] & bb))
9623e12c5d1SDavid du Colombier break;
9633e12c5d1SDavid du Colombier r1 = r->s2;
9643e12c5d1SDavid du Colombier if(r1 != R)
9653e12c5d1SDavid du Colombier if(r1->refbehind.b[z] & bb)
9663e12c5d1SDavid du Colombier vreg |= paint2(r1, bn);
9673e12c5d1SDavid du Colombier r = r->s1;
9683e12c5d1SDavid du Colombier if(r == R)
9693e12c5d1SDavid du Colombier break;
9703e12c5d1SDavid du Colombier if(!(r->act.b[z] & bb))
9713e12c5d1SDavid du Colombier break;
9723e12c5d1SDavid du Colombier if(!(r->refbehind.b[z] & bb))
9733e12c5d1SDavid du Colombier break;
9743e12c5d1SDavid du Colombier }
9753e12c5d1SDavid du Colombier return vreg;
9763e12c5d1SDavid du Colombier }
9773e12c5d1SDavid du Colombier
9783e12c5d1SDavid du Colombier void
paint3(Reg * r,int bn,long rb,int rn)9793e12c5d1SDavid du Colombier paint3(Reg *r, int bn, long rb, int rn)
9803e12c5d1SDavid du Colombier {
9813e12c5d1SDavid du Colombier Reg *r1;
9823e12c5d1SDavid du Colombier Prog *p;
9833e12c5d1SDavid du Colombier int z;
9843e12c5d1SDavid du Colombier ulong bb;
9853e12c5d1SDavid du Colombier
9863e12c5d1SDavid du Colombier z = bn/32;
9873e12c5d1SDavid du Colombier bb = 1L << (bn%32);
9883e12c5d1SDavid du Colombier if(r->act.b[z] & bb)
9893e12c5d1SDavid du Colombier return;
9903e12c5d1SDavid du Colombier for(;;) {
9913e12c5d1SDavid du Colombier if(!(r->refbehind.b[z] & bb))
9923e12c5d1SDavid du Colombier break;
9933e12c5d1SDavid du Colombier r1 = r->p1;
9943e12c5d1SDavid du Colombier if(r1 == R)
9953e12c5d1SDavid du Colombier break;
9963e12c5d1SDavid du Colombier if(!(r1->refahead.b[z] & bb))
9973e12c5d1SDavid du Colombier break;
9983e12c5d1SDavid du Colombier if(r1->act.b[z] & bb)
9993e12c5d1SDavid du Colombier break;
10003e12c5d1SDavid du Colombier r = r1;
10013e12c5d1SDavid du Colombier }
10023e12c5d1SDavid du Colombier
10033e12c5d1SDavid du Colombier if(LOAD(r) & ~(r->set.b[z] & ~(r->use1.b[z]|r->use2.b[z])) & bb)
10043e12c5d1SDavid du Colombier addmove(r, bn, rn, 0);
10053e12c5d1SDavid du Colombier for(;;) {
10063e12c5d1SDavid du Colombier r->act.b[z] |= bb;
10073e12c5d1SDavid du Colombier p = r->prog;
10083e12c5d1SDavid du Colombier
10093e12c5d1SDavid du Colombier if(r->use1.b[z] & bb) {
10103e12c5d1SDavid du Colombier if(debug['R'])
10113e12c5d1SDavid du Colombier print("%P", p);
10123e12c5d1SDavid du Colombier addreg(&p->from, rn);
10133e12c5d1SDavid du Colombier if(debug['R'])
10149a747e4fSDavid du Colombier print("\t.c%P\n", p);
10153e12c5d1SDavid du Colombier }
10163e12c5d1SDavid du Colombier if((r->use2.b[z]|r->set.b[z]) & bb) {
10173e12c5d1SDavid du Colombier if(debug['R'])
10183e12c5d1SDavid du Colombier print("%P", p);
10193e12c5d1SDavid du Colombier addreg(&p->to, rn);
10203e12c5d1SDavid du Colombier if(debug['R'])
10219a747e4fSDavid du Colombier print("\t.c%P\n", p);
10223e12c5d1SDavid du Colombier }
10233e12c5d1SDavid du Colombier
10243e12c5d1SDavid du Colombier if(STORE(r) & r->regdiff.b[z] & bb)
10253e12c5d1SDavid du Colombier addmove(r, bn, rn, 1);
10263e12c5d1SDavid du Colombier r->regu |= rb;
10273e12c5d1SDavid du Colombier
10283e12c5d1SDavid du Colombier if(r->refbehind.b[z] & bb)
10293e12c5d1SDavid du Colombier for(r1 = r->p2; r1 != R; r1 = r1->p2link)
10303e12c5d1SDavid du Colombier if(r1->refahead.b[z] & bb)
10313e12c5d1SDavid du Colombier paint3(r1, bn, rb, rn);
10323e12c5d1SDavid du Colombier
10333e12c5d1SDavid du Colombier if(!(r->refahead.b[z] & bb))
10343e12c5d1SDavid du Colombier break;
10353e12c5d1SDavid du Colombier r1 = r->s2;
10363e12c5d1SDavid du Colombier if(r1 != R)
10373e12c5d1SDavid du Colombier if(r1->refbehind.b[z] & bb)
10383e12c5d1SDavid du Colombier paint3(r1, bn, rb, rn);
10393e12c5d1SDavid du Colombier r = r->s1;
10403e12c5d1SDavid du Colombier if(r == R)
10413e12c5d1SDavid du Colombier break;
10423e12c5d1SDavid du Colombier if(r->act.b[z] & bb)
10433e12c5d1SDavid du Colombier break;
10443e12c5d1SDavid du Colombier if(!(r->refbehind.b[z] & bb))
10453e12c5d1SDavid du Colombier break;
10463e12c5d1SDavid du Colombier }
10473e12c5d1SDavid du Colombier }
10483e12c5d1SDavid du Colombier
10493e12c5d1SDavid du Colombier void
addreg(Adr * a,int rn)10503e12c5d1SDavid du Colombier addreg(Adr *a, int rn)
10513e12c5d1SDavid du Colombier {
10523e12c5d1SDavid du Colombier
10533e12c5d1SDavid du Colombier a->sym = 0;
10543e12c5d1SDavid du Colombier a->name = D_NONE;
10553e12c5d1SDavid du Colombier a->type = D_REG;
10563e12c5d1SDavid du Colombier a->reg = rn;
10573e12c5d1SDavid du Colombier if(rn >= NREG) {
10583e12c5d1SDavid du Colombier a->type = D_FREG;
10593e12c5d1SDavid du Colombier a->reg = rn-NREG;
10603e12c5d1SDavid du Colombier }
10613e12c5d1SDavid du Colombier }
10623e12c5d1SDavid du Colombier
10633e12c5d1SDavid du Colombier /*
10643e12c5d1SDavid du Colombier * bit reg
10653e12c5d1SDavid du Colombier * 0 R9
10663e12c5d1SDavid du Colombier * 1 R10
10673e12c5d1SDavid du Colombier * ... ...
10683e12c5d1SDavid du Colombier * 4 R13
10693e12c5d1SDavid du Colombier * 5 R16
10703e12c5d1SDavid du Colombier * ... ...
10713e12c5d1SDavid du Colombier * 20 R31
10723e12c5d1SDavid du Colombier */
10733e12c5d1SDavid du Colombier long
RtoB(int r)10743e12c5d1SDavid du Colombier RtoB(int r)
10753e12c5d1SDavid du Colombier {
10763e12c5d1SDavid du Colombier
10773e12c5d1SDavid du Colombier if(r >= 9 && r <= 13)
10783e12c5d1SDavid du Colombier return 1L << (r-9);
10793e12c5d1SDavid du Colombier if(r >= 16 && r <= 31)
10803e12c5d1SDavid du Colombier return 1L << (r-11);
10813e12c5d1SDavid du Colombier return 0;
10823e12c5d1SDavid du Colombier }
10833e12c5d1SDavid du Colombier
10843e12c5d1SDavid du Colombier int
BtoR(long b)10853e12c5d1SDavid du Colombier BtoR(long b)
10863e12c5d1SDavid du Colombier {
10873e12c5d1SDavid du Colombier int r;
10883e12c5d1SDavid du Colombier
10893e12c5d1SDavid du Colombier b &= 0x001fffffL;
10903e12c5d1SDavid du Colombier if(b == 0)
10913e12c5d1SDavid du Colombier return 0;
10923e12c5d1SDavid du Colombier r = bitno(b) + 9;
10933e12c5d1SDavid du Colombier if(r >= 14)
10943e12c5d1SDavid du Colombier r += 2;
10953e12c5d1SDavid du Colombier return r;
10963e12c5d1SDavid du Colombier }
10973e12c5d1SDavid du Colombier
10983e12c5d1SDavid du Colombier /*
10993e12c5d1SDavid du Colombier * bit reg
11003e12c5d1SDavid du Colombier * 22 F4
11013e12c5d1SDavid du Colombier * 23 F6
11023e12c5d1SDavid du Colombier * ... ...
11033e12c5d1SDavid du Colombier * 31 F22
11043e12c5d1SDavid du Colombier */
11053e12c5d1SDavid du Colombier long
FtoB(int f)11063e12c5d1SDavid du Colombier FtoB(int f)
11073e12c5d1SDavid du Colombier {
11083e12c5d1SDavid du Colombier
11093e12c5d1SDavid du Colombier if(f < 4 || f > 22 || (f&1))
11103e12c5d1SDavid du Colombier return 0;
11113e12c5d1SDavid du Colombier return 1L << (f/2 + 20);
11123e12c5d1SDavid du Colombier }
11133e12c5d1SDavid du Colombier
BtoF(long b)11143e12c5d1SDavid du Colombier BtoF(long b)
11153e12c5d1SDavid du Colombier {
11163e12c5d1SDavid du Colombier
11173e12c5d1SDavid du Colombier b &= 0xffc00000L;
11183e12c5d1SDavid du Colombier if(b == 0)
11193e12c5d1SDavid du Colombier return 0;
11203e12c5d1SDavid du Colombier return bitno(b)*2 - 40;
11213e12c5d1SDavid du Colombier }
1122