13e12c5d1SDavid du Colombier #include "gc.h" 23e12c5d1SDavid du Colombier 33e12c5d1SDavid du Colombier #define COL1 32 43e12c5d1SDavid du Colombier 5*219b2ee8SDavid du Colombier void addsplits(void); 6*219b2ee8SDavid du Colombier 73e12c5d1SDavid du Colombier Reg* 83e12c5d1SDavid du Colombier rega(void) 93e12c5d1SDavid du Colombier { 103e12c5d1SDavid du Colombier Reg *r; 113e12c5d1SDavid du Colombier 123e12c5d1SDavid du Colombier r = freer; 133e12c5d1SDavid du Colombier if(r == R) { 143e12c5d1SDavid du Colombier ALLOC(r, Reg); 153e12c5d1SDavid du Colombier } else 163e12c5d1SDavid du Colombier freer = r->link; 173e12c5d1SDavid du Colombier 183e12c5d1SDavid du Colombier *r = zreg; 193e12c5d1SDavid du Colombier return r; 203e12c5d1SDavid du Colombier } 213e12c5d1SDavid du Colombier 223e12c5d1SDavid du Colombier int 233e12c5d1SDavid du Colombier rcmp(void *a1, void *a2) 243e12c5d1SDavid du Colombier { 253e12c5d1SDavid du Colombier Rgn *p1, *p2; 263e12c5d1SDavid du Colombier int c1, c2; 273e12c5d1SDavid du Colombier 283e12c5d1SDavid du Colombier p1 = a1; 293e12c5d1SDavid du Colombier p2 = a2; 303e12c5d1SDavid du Colombier c1 = p2->cost; 313e12c5d1SDavid du Colombier c2 = p1->cost; 323e12c5d1SDavid du Colombier if(c1 -= c2) 333e12c5d1SDavid du Colombier return c1; 343e12c5d1SDavid du Colombier return p2->varno - p1->varno; 353e12c5d1SDavid du Colombier } 363e12c5d1SDavid du Colombier 373e12c5d1SDavid du Colombier void 383e12c5d1SDavid du Colombier regopt(Prog *p) 393e12c5d1SDavid du Colombier { 403e12c5d1SDavid du Colombier Reg *r, *r1, *r2; 41*219b2ee8SDavid du Colombier Prog *p1; 423e12c5d1SDavid du Colombier int i, z; 433e12c5d1SDavid du Colombier long initpc, val; 443e12c5d1SDavid du Colombier ulong vreg; 453e12c5d1SDavid du Colombier Bits bit; 463e12c5d1SDavid du Colombier struct 473e12c5d1SDavid du Colombier { 483e12c5d1SDavid du Colombier long m; 493e12c5d1SDavid du Colombier long c; 503e12c5d1SDavid du Colombier Reg* p; 513e12c5d1SDavid du Colombier } log5[6], *lp; 523e12c5d1SDavid du Colombier 533e12c5d1SDavid du Colombier firstr = R; 543e12c5d1SDavid du Colombier lastr = R; 553e12c5d1SDavid du Colombier nvar = 0; 563e12c5d1SDavid du Colombier regbits = 0; 573e12c5d1SDavid du Colombier for(z=0; z<BITS; z++) { 583e12c5d1SDavid du Colombier externs.b[z] = 0; 593e12c5d1SDavid du Colombier params.b[z] = 0; 603e12c5d1SDavid du Colombier consts.b[z] = 0; 613e12c5d1SDavid du Colombier addrs.b[z] = 0; 623e12c5d1SDavid du Colombier } 633e12c5d1SDavid du Colombier 643e12c5d1SDavid du Colombier /* 653e12c5d1SDavid du Colombier * pass 1 663e12c5d1SDavid du Colombier * build aux data structure 673e12c5d1SDavid du Colombier * allocate pcs 683e12c5d1SDavid du Colombier * find use and set of variables 693e12c5d1SDavid du Colombier */ 703e12c5d1SDavid du Colombier val = 5L * 5L * 5L * 5L * 5L; 713e12c5d1SDavid du Colombier lp = log5; 723e12c5d1SDavid du Colombier for(i=0; i<5; i++) { 733e12c5d1SDavid du Colombier lp->m = val; 743e12c5d1SDavid du Colombier lp->c = 0; 753e12c5d1SDavid du Colombier lp->p = R; 763e12c5d1SDavid du Colombier val /= 5L; 773e12c5d1SDavid du Colombier lp++; 783e12c5d1SDavid du Colombier } 793e12c5d1SDavid du Colombier val = 0; 803e12c5d1SDavid du Colombier for(; p != P; p = p->link) { 813e12c5d1SDavid du Colombier switch(p->as) { 823e12c5d1SDavid du Colombier case ADATA: 833e12c5d1SDavid du Colombier case AGLOBL: 843e12c5d1SDavid du Colombier case ANAME: 853e12c5d1SDavid du Colombier continue; 863e12c5d1SDavid du Colombier } 873e12c5d1SDavid du Colombier r = rega(); 883e12c5d1SDavid du Colombier if(firstr == R) { 893e12c5d1SDavid du Colombier firstr = r; 903e12c5d1SDavid du Colombier lastr = r; 913e12c5d1SDavid du Colombier } else { 923e12c5d1SDavid du Colombier lastr->link = r; 933e12c5d1SDavid du Colombier r->p1 = lastr; 943e12c5d1SDavid du Colombier lastr->s1 = r; 953e12c5d1SDavid du Colombier lastr = r; 963e12c5d1SDavid du Colombier } 973e12c5d1SDavid du Colombier r->prog = p; 983e12c5d1SDavid du Colombier r->pc = val; 993e12c5d1SDavid du Colombier val++; 1003e12c5d1SDavid du Colombier 1013e12c5d1SDavid du Colombier lp = log5; 1023e12c5d1SDavid du Colombier for(i=0; i<5; i++) { 1033e12c5d1SDavid du Colombier lp->c--; 1043e12c5d1SDavid du Colombier if(lp->c <= 0) { 1053e12c5d1SDavid du Colombier lp->c = lp->m; 1063e12c5d1SDavid du Colombier if(lp->p != R) 1073e12c5d1SDavid du Colombier lp->p->log5 = r; 1083e12c5d1SDavid du Colombier lp->p = r; 1093e12c5d1SDavid du Colombier (lp+1)->c = 0; 1103e12c5d1SDavid du Colombier break; 1113e12c5d1SDavid du Colombier } 1123e12c5d1SDavid du Colombier lp++; 1133e12c5d1SDavid du Colombier } 1143e12c5d1SDavid du Colombier 1153e12c5d1SDavid du Colombier r1 = r->p1; 1163e12c5d1SDavid du Colombier if(r1 != R) 1173e12c5d1SDavid du Colombier switch(r1->prog->as) { 1183e12c5d1SDavid du Colombier case ARET: 1193e12c5d1SDavid du Colombier case AJMP: 1203e12c5d1SDavid du Colombier case ARFE: 1213e12c5d1SDavid du Colombier r->p1 = R; 1223e12c5d1SDavid du Colombier r1->s1 = R; 1233e12c5d1SDavid du Colombier } 1243e12c5d1SDavid du Colombier 1253e12c5d1SDavid du Colombier /* 1263e12c5d1SDavid du Colombier * left side always read 1273e12c5d1SDavid du Colombier */ 1283e12c5d1SDavid du Colombier bit = mkvar(&p->from, p->as==AMOVW); 1293e12c5d1SDavid du Colombier for(z=0; z<BITS; z++) 1303e12c5d1SDavid du Colombier r->use1.b[z] |= bit.b[z]; 1313e12c5d1SDavid du Colombier 1323e12c5d1SDavid du Colombier /* 1333e12c5d1SDavid du Colombier * right side depends on opcode 1343e12c5d1SDavid du Colombier */ 1353e12c5d1SDavid du Colombier bit = mkvar(&p->to, 0); 1363e12c5d1SDavid du Colombier if(bany(&bit)) 1373e12c5d1SDavid du Colombier switch(p->as) { 1383e12c5d1SDavid du Colombier default: 1393e12c5d1SDavid du Colombier diag(Z, "reg: unknown asop: %A", p->as); 1403e12c5d1SDavid du Colombier break; 1413e12c5d1SDavid du Colombier 1423e12c5d1SDavid du Colombier /* 1433e12c5d1SDavid du Colombier * right side write 1443e12c5d1SDavid du Colombier */ 1453e12c5d1SDavid du Colombier case ANOP: 1463e12c5d1SDavid du Colombier case AMOVB: 1473e12c5d1SDavid du Colombier case AMOVBU: 1483e12c5d1SDavid du Colombier case AMOVH: 1493e12c5d1SDavid du Colombier case AMOVHU: 1503e12c5d1SDavid du Colombier case AMOVW: 1513e12c5d1SDavid du Colombier case AMOVF: 1523e12c5d1SDavid du Colombier case AMOVD: 1533e12c5d1SDavid du Colombier for(z=0; z<BITS; z++) 1543e12c5d1SDavid du Colombier r->set.b[z] |= bit.b[z]; 1553e12c5d1SDavid du Colombier break; 1563e12c5d1SDavid du Colombier 1573e12c5d1SDavid du Colombier /* 1583e12c5d1SDavid du Colombier * funny 1593e12c5d1SDavid du Colombier */ 1603e12c5d1SDavid du Colombier case AJAL: 1613e12c5d1SDavid du Colombier for(z=0; z<BITS; z++) 1623e12c5d1SDavid du Colombier addrs.b[z] |= bit.b[z]; 1633e12c5d1SDavid du Colombier break; 1643e12c5d1SDavid du Colombier } 1653e12c5d1SDavid du Colombier } 1663e12c5d1SDavid du Colombier if(firstr == R) 1673e12c5d1SDavid du Colombier return; 1683e12c5d1SDavid du Colombier initpc = pc - val; 1693e12c5d1SDavid du Colombier 1703e12c5d1SDavid du Colombier /* 1713e12c5d1SDavid du Colombier * pass 2 1723e12c5d1SDavid du Colombier * turn branch references to pointers 1733e12c5d1SDavid du Colombier * build back pointers 1743e12c5d1SDavid du Colombier */ 1753e12c5d1SDavid du Colombier for(r = firstr; r != R; r = r->link) { 1763e12c5d1SDavid du Colombier p = r->prog; 1773e12c5d1SDavid du Colombier if(p->to.type == D_BRANCH) { 1783e12c5d1SDavid du Colombier val = p->to.offset - initpc; 1793e12c5d1SDavid du Colombier r1 = firstr; 1803e12c5d1SDavid du Colombier while(r1 != R) { 1813e12c5d1SDavid du Colombier r2 = r1->log5; 1823e12c5d1SDavid du Colombier if(r2 != R && val >= r2->pc) { 1833e12c5d1SDavid du Colombier r1 = r2; 1843e12c5d1SDavid du Colombier continue; 1853e12c5d1SDavid du Colombier } 1863e12c5d1SDavid du Colombier if(r1->pc == val) 1873e12c5d1SDavid du Colombier break; 1883e12c5d1SDavid du Colombier r1 = r1->link; 1893e12c5d1SDavid du Colombier } 1903e12c5d1SDavid du Colombier if(r1 == R) { 1913e12c5d1SDavid du Colombier nearln = p->lineno; 1923e12c5d1SDavid du Colombier diag(Z, "ref not found\n%P", p); 1933e12c5d1SDavid du Colombier continue; 1943e12c5d1SDavid du Colombier } 1953e12c5d1SDavid du Colombier if(r1 == r) { 1963e12c5d1SDavid du Colombier nearln = p->lineno; 1973e12c5d1SDavid du Colombier diag(Z, "ref to self\n%P", p); 1983e12c5d1SDavid du Colombier continue; 1993e12c5d1SDavid du Colombier } 2003e12c5d1SDavid du Colombier r->s2 = r1; 2013e12c5d1SDavid du Colombier r->p2link = r1->p2; 2023e12c5d1SDavid du Colombier r1->p2 = r; 2033e12c5d1SDavid du Colombier } 2043e12c5d1SDavid du Colombier } 2053e12c5d1SDavid du Colombier if(debug['R']) { 2063e12c5d1SDavid du Colombier p = firstr->prog; 2073e12c5d1SDavid du Colombier print("\n%L %D\n", p->lineno, &p->from); 2083e12c5d1SDavid du Colombier } 2093e12c5d1SDavid du Colombier 2103e12c5d1SDavid du Colombier /* 2113e12c5d1SDavid du Colombier * pass 2.5 2123e12c5d1SDavid du Colombier * find looping structure 2133e12c5d1SDavid du Colombier */ 2143e12c5d1SDavid du Colombier for(r = firstr; r != R; r = r->link) 2153e12c5d1SDavid du Colombier r->active = 0; 2163e12c5d1SDavid du Colombier change = 0; 2173e12c5d1SDavid du Colombier loopit(firstr); 2183e12c5d1SDavid du Colombier 2193e12c5d1SDavid du Colombier /* 2203e12c5d1SDavid du Colombier * pass 3 2213e12c5d1SDavid du Colombier * iterate propagating usage 2223e12c5d1SDavid du Colombier * back until flow graph is complete 2233e12c5d1SDavid du Colombier */ 2243e12c5d1SDavid du Colombier loop1: 2253e12c5d1SDavid du Colombier change = 0; 2263e12c5d1SDavid du Colombier for(r = firstr; r != R; r = r->link) 2273e12c5d1SDavid du Colombier r->active = 0; 2283e12c5d1SDavid du Colombier for(r = firstr; r != R; r = r->link) 2293e12c5d1SDavid du Colombier if(r->prog->as == ARET) 2303e12c5d1SDavid du Colombier prop(r, zbits, zbits); 2313e12c5d1SDavid du Colombier loop11: 2323e12c5d1SDavid du Colombier /* pick up unreachable code */ 2333e12c5d1SDavid du Colombier i = 0; 2343e12c5d1SDavid du Colombier for(r = firstr; r != R; r = r1) { 2353e12c5d1SDavid du Colombier r1 = r->link; 2363e12c5d1SDavid du Colombier if(r1 && r1->active && !r->active) { 2373e12c5d1SDavid du Colombier prop(r, zbits, zbits); 2383e12c5d1SDavid du Colombier i = 1; 2393e12c5d1SDavid du Colombier } 2403e12c5d1SDavid du Colombier } 2413e12c5d1SDavid du Colombier if(i) 2423e12c5d1SDavid du Colombier goto loop11; 2433e12c5d1SDavid du Colombier if(change) 2443e12c5d1SDavid du Colombier goto loop1; 2453e12c5d1SDavid du Colombier 2463e12c5d1SDavid du Colombier 2473e12c5d1SDavid du Colombier /* 2483e12c5d1SDavid du Colombier * pass 4 2493e12c5d1SDavid du Colombier * iterate propagating register/variable synchrony 2503e12c5d1SDavid du Colombier * forward until graph is complete 2513e12c5d1SDavid du Colombier */ 2523e12c5d1SDavid du Colombier loop2: 2533e12c5d1SDavid du Colombier change = 0; 2543e12c5d1SDavid du Colombier for(r = firstr; r != R; r = r->link) 2553e12c5d1SDavid du Colombier r->active = 0; 2563e12c5d1SDavid du Colombier synch(firstr, zbits); 2573e12c5d1SDavid du Colombier if(change) 2583e12c5d1SDavid du Colombier goto loop2; 2593e12c5d1SDavid du Colombier 260*219b2ee8SDavid du Colombier addsplits(); 261*219b2ee8SDavid du Colombier 262*219b2ee8SDavid du Colombier if(debug['R'] && debug['v']) { 263*219b2ee8SDavid du Colombier print("\nprop structure:\n"); 264*219b2ee8SDavid du Colombier for(r = firstr; r != R; r = r->link) { 265*219b2ee8SDavid du Colombier print("%d:%P", r->loop, r->prog); 266*219b2ee8SDavid du Colombier for(z=0; z<BITS; z++) 267*219b2ee8SDavid du Colombier bit.b[z] = r->set.b[z] | 268*219b2ee8SDavid du Colombier r->refahead.b[z] | r->calahead.b[z] | 269*219b2ee8SDavid du Colombier r->refbehind.b[z] | r->calbehind.b[z] | 270*219b2ee8SDavid du Colombier r->use1.b[z] | r->use2.b[z]; 271*219b2ee8SDavid du Colombier if(bany(&bit)) { 272*219b2ee8SDavid du Colombier print("%|", COL1); 273*219b2ee8SDavid du Colombier if(bany(&r->use1)) 274*219b2ee8SDavid du Colombier print(" u1=%B", r->use1); 275*219b2ee8SDavid du Colombier if(bany(&r->use2)) 276*219b2ee8SDavid du Colombier print(" u2=%B", r->use2); 277*219b2ee8SDavid du Colombier if(bany(&r->set)) 278*219b2ee8SDavid du Colombier print(" st=%B", r->set); 279*219b2ee8SDavid du Colombier if(bany(&r->refahead)) 280*219b2ee8SDavid du Colombier print(" ra=%B", r->refahead); 281*219b2ee8SDavid du Colombier if(bany(&r->calahead)) 282*219b2ee8SDavid du Colombier print(" ca=%B", r->calahead); 283*219b2ee8SDavid du Colombier if(bany(&r->refbehind)) 284*219b2ee8SDavid du Colombier print(" rb=%B", r->refbehind); 285*219b2ee8SDavid du Colombier if(bany(&r->calbehind)) 286*219b2ee8SDavid du Colombier print(" cb=%B", r->calbehind); 287*219b2ee8SDavid du Colombier } 288*219b2ee8SDavid du Colombier print("\n"); 289*219b2ee8SDavid du Colombier } 290*219b2ee8SDavid du Colombier } 2913e12c5d1SDavid du Colombier 2923e12c5d1SDavid du Colombier /* 2933e12c5d1SDavid du Colombier * pass 5 2943e12c5d1SDavid du Colombier * isolate regions 2953e12c5d1SDavid du Colombier * calculate costs (paint1) 2963e12c5d1SDavid du Colombier */ 2973e12c5d1SDavid du Colombier r = firstr; 2983e12c5d1SDavid du Colombier if(r) { 2993e12c5d1SDavid du Colombier for(z=0; z<BITS; z++) 3003e12c5d1SDavid du Colombier bit.b[z] = (r->refahead.b[z] | r->calahead.b[z]) & 3013e12c5d1SDavid du Colombier ~(externs.b[z] | params.b[z] | addrs.b[z] | consts.b[z]); 3023e12c5d1SDavid du Colombier if(bany(&bit)) { 3033e12c5d1SDavid du Colombier nearln = r->prog->lineno; 3043e12c5d1SDavid du Colombier warn(Z, "used and not set: %B", bit); 3053e12c5d1SDavid du Colombier if(debug['R'] && !debug['w']) 3063e12c5d1SDavid du Colombier print("used and not set: %B\n", bit); 3073e12c5d1SDavid du Colombier } 3083e12c5d1SDavid du Colombier } 309*219b2ee8SDavid du Colombier 3103e12c5d1SDavid du Colombier for(r = firstr; r != R; r = r->link) 3113e12c5d1SDavid du Colombier r->act = zbits; 3123e12c5d1SDavid du Colombier rgp = region; 3133e12c5d1SDavid du Colombier nregion = 0; 3143e12c5d1SDavid du Colombier for(r = firstr; r != R; r = r->link) { 3153e12c5d1SDavid du Colombier for(z=0; z<BITS; z++) 3163e12c5d1SDavid du Colombier bit.b[z] = r->set.b[z] & 3173e12c5d1SDavid du Colombier ~(r->refahead.b[z] | r->calahead.b[z] | addrs.b[z]); 3183e12c5d1SDavid du Colombier if(bany(&bit)) { 3193e12c5d1SDavid du Colombier nearln = r->prog->lineno; 3203e12c5d1SDavid du Colombier warn(Z, "set and not used: %B", bit); 3213e12c5d1SDavid du Colombier if(debug['R']) 322*219b2ee8SDavid du Colombier print("set and not used: %B\n", bit); 3233e12c5d1SDavid du Colombier excise(r); 3243e12c5d1SDavid du Colombier } 3253e12c5d1SDavid du Colombier for(z=0; z<BITS; z++) 3263e12c5d1SDavid du Colombier bit.b[z] = LOAD(r) & ~(r->act.b[z] | addrs.b[z]); 3273e12c5d1SDavid du Colombier while(bany(&bit)) { 3283e12c5d1SDavid du Colombier i = bnum(bit); 3293e12c5d1SDavid du Colombier rgp->enter = r; 3303e12c5d1SDavid du Colombier rgp->varno = i; 3313e12c5d1SDavid du Colombier change = 0; 3323e12c5d1SDavid du Colombier if(debug['R'] && debug['v']) 3333e12c5d1SDavid du Colombier print("\n"); 3343e12c5d1SDavid du Colombier paint1(r, i); 3353e12c5d1SDavid du Colombier bit.b[i/32] &= ~(1L<<(i%32)); 3363e12c5d1SDavid du Colombier if(change <= 0) { 3373e12c5d1SDavid du Colombier if(debug['R']) 3383e12c5d1SDavid du Colombier print("%L $%d: %B\n", 3393e12c5d1SDavid du Colombier r->prog->lineno, change, blsh(i)); 3403e12c5d1SDavid du Colombier continue; 3413e12c5d1SDavid du Colombier } 3423e12c5d1SDavid du Colombier rgp->cost = change; 3433e12c5d1SDavid du Colombier nregion++; 3443e12c5d1SDavid du Colombier if(nregion >= NRGN) { 3453e12c5d1SDavid du Colombier warn(Z, "too many regions"); 3463e12c5d1SDavid du Colombier goto brk; 3473e12c5d1SDavid du Colombier } 3483e12c5d1SDavid du Colombier rgp++; 3493e12c5d1SDavid du Colombier } 3503e12c5d1SDavid du Colombier } 3513e12c5d1SDavid du Colombier brk: 3523e12c5d1SDavid du Colombier qsort(region, nregion, sizeof(region[0]), rcmp); 3533e12c5d1SDavid du Colombier 3543e12c5d1SDavid du Colombier /* 3553e12c5d1SDavid du Colombier * pass 6 3563e12c5d1SDavid du Colombier * determine used registers (paint2) 3573e12c5d1SDavid du Colombier * replace code (paint3) 3583e12c5d1SDavid du Colombier */ 3593e12c5d1SDavid du Colombier rgp = region; 3603e12c5d1SDavid du Colombier for(i=0; i<nregion; i++) { 3613e12c5d1SDavid du Colombier bit = blsh(rgp->varno); 3623e12c5d1SDavid du Colombier vreg = paint2(rgp->enter, rgp->varno); 3633e12c5d1SDavid du Colombier vreg = allreg(vreg, rgp); 3643e12c5d1SDavid du Colombier if(debug['R']) { 3653e12c5d1SDavid du Colombier if(rgp->regno >= NREG) 3663e12c5d1SDavid du Colombier print("%L $%d F%d: %B\n", 3673e12c5d1SDavid du Colombier rgp->enter->prog->lineno, 3683e12c5d1SDavid du Colombier rgp->cost, 3693e12c5d1SDavid du Colombier rgp->regno-NREG, 3703e12c5d1SDavid du Colombier bit); 3713e12c5d1SDavid du Colombier else 3723e12c5d1SDavid du Colombier print("%L $%d R%d: %B\n", 3733e12c5d1SDavid du Colombier rgp->enter->prog->lineno, 3743e12c5d1SDavid du Colombier rgp->cost, 3753e12c5d1SDavid du Colombier rgp->regno, 3763e12c5d1SDavid du Colombier bit); 3773e12c5d1SDavid du Colombier } 3783e12c5d1SDavid du Colombier if(rgp->regno != 0) 3793e12c5d1SDavid du Colombier paint3(rgp->enter, rgp->varno, vreg, rgp->regno); 3803e12c5d1SDavid du Colombier rgp++; 3813e12c5d1SDavid du Colombier } 3823e12c5d1SDavid du Colombier /* 3833e12c5d1SDavid du Colombier * pass 7 3843e12c5d1SDavid du Colombier * peep-hole on basic block 3853e12c5d1SDavid du Colombier */ 3863e12c5d1SDavid du Colombier if(!debug['R'] || debug['P']) 3873e12c5d1SDavid du Colombier peep(); 3883e12c5d1SDavid du Colombier 3893e12c5d1SDavid du Colombier /* 3903e12c5d1SDavid du Colombier * pass 8 3913e12c5d1SDavid du Colombier * recalculate pc 3923e12c5d1SDavid du Colombier */ 3933e12c5d1SDavid du Colombier val = initpc; 3943e12c5d1SDavid du Colombier for(r = firstr; r != R; r = r1) { 3953e12c5d1SDavid du Colombier r->pc = val; 3963e12c5d1SDavid du Colombier p = r->prog; 397*219b2ee8SDavid du Colombier p1 = P; 3983e12c5d1SDavid du Colombier r1 = r->link; 399*219b2ee8SDavid du Colombier if(r1 != R) 400*219b2ee8SDavid du Colombier p1 = r1->prog; 401*219b2ee8SDavid du Colombier for(; p != p1; p = p->link) { 4023e12c5d1SDavid du Colombier switch(p->as) { 4033e12c5d1SDavid du Colombier default: 4043e12c5d1SDavid du Colombier val++; 405*219b2ee8SDavid du Colombier break; 4063e12c5d1SDavid du Colombier 407*219b2ee8SDavid du Colombier case ANOP: 4083e12c5d1SDavid du Colombier case ADATA: 4093e12c5d1SDavid du Colombier case AGLOBL: 4103e12c5d1SDavid du Colombier case ANAME: 411*219b2ee8SDavid du Colombier break; 4123e12c5d1SDavid du Colombier } 4133e12c5d1SDavid du Colombier } 414*219b2ee8SDavid du Colombier } 415*219b2ee8SDavid du Colombier pc = val; 4163e12c5d1SDavid du Colombier 4173e12c5d1SDavid du Colombier /* 4183e12c5d1SDavid du Colombier * fix up branches 4193e12c5d1SDavid du Colombier */ 4203e12c5d1SDavid du Colombier if(debug['R']) 4213e12c5d1SDavid du Colombier if(bany(&addrs)) 4223e12c5d1SDavid du Colombier print("addrs: %B\n", addrs); 4233e12c5d1SDavid du Colombier 4243e12c5d1SDavid du Colombier r1 = 0; /* set */ 4253e12c5d1SDavid du Colombier for(r = firstr; r != R; r = r->link) { 4263e12c5d1SDavid du Colombier p = r->prog; 4273e12c5d1SDavid du Colombier if(p->to.type == D_BRANCH) 4283e12c5d1SDavid du Colombier p->to.offset = r->s2->pc; 4293e12c5d1SDavid du Colombier r1 = r; 4303e12c5d1SDavid du Colombier } 431*219b2ee8SDavid du Colombier 432*219b2ee8SDavid du Colombier /* 433*219b2ee8SDavid du Colombier * last pass 434*219b2ee8SDavid du Colombier * eliminate nops 435*219b2ee8SDavid du Colombier * free aux structures 436*219b2ee8SDavid du Colombier */ 437*219b2ee8SDavid du Colombier for(p = firstr->prog; p != P; p = p->link){ 438*219b2ee8SDavid du Colombier while(p->link && p->link->as == ANOP) 439*219b2ee8SDavid du Colombier p->link = p->link->link; 440*219b2ee8SDavid du Colombier } 4413e12c5d1SDavid du Colombier if(r1 != R) { 4423e12c5d1SDavid du Colombier r1->link = freer; 4433e12c5d1SDavid du Colombier freer = firstr; 4443e12c5d1SDavid du Colombier } 4453e12c5d1SDavid du Colombier } 4463e12c5d1SDavid du Colombier 447*219b2ee8SDavid du Colombier void 448*219b2ee8SDavid du Colombier addsplits(void) 449*219b2ee8SDavid du Colombier { 450*219b2ee8SDavid du Colombier Reg *r, *r1; 451*219b2ee8SDavid du Colombier int z, i; 452*219b2ee8SDavid du Colombier Bits bit; 453*219b2ee8SDavid du Colombier 454*219b2ee8SDavid du Colombier for(r = firstr; r != R; r = r->link) { 455*219b2ee8SDavid du Colombier if(r->loop > 1) 456*219b2ee8SDavid du Colombier continue; 457*219b2ee8SDavid du Colombier if(r->prog->as == AJAL) 458*219b2ee8SDavid du Colombier continue; 459*219b2ee8SDavid du Colombier for(r1 = r->p2; r1 != R; r1 = r1->p2link) { 460*219b2ee8SDavid du Colombier if(r1->loop <= 1) 461*219b2ee8SDavid du Colombier continue; 462*219b2ee8SDavid du Colombier for(z=0; z<BITS; z++) 463*219b2ee8SDavid du Colombier bit.b[z] = r1->calbehind.b[z] & 464*219b2ee8SDavid du Colombier (r->refahead.b[z] | r->use1.b[z] | r->use2.b[z]) & 465*219b2ee8SDavid du Colombier ~(r->calahead.b[z] & addrs.b[z]); 466*219b2ee8SDavid du Colombier while(bany(&bit)) { 467*219b2ee8SDavid du Colombier i = bnum(bit); 468*219b2ee8SDavid du Colombier bit.b[i/32] &= ~(1L << (i%32)); 469*219b2ee8SDavid du Colombier } 470*219b2ee8SDavid du Colombier } 471*219b2ee8SDavid du Colombier } 472*219b2ee8SDavid du Colombier } 473*219b2ee8SDavid du Colombier 4743e12c5d1SDavid du Colombier /* 4753e12c5d1SDavid du Colombier * add mov b,rn 4763e12c5d1SDavid du Colombier * just after r 4773e12c5d1SDavid du Colombier */ 4783e12c5d1SDavid du Colombier void 4793e12c5d1SDavid du Colombier addmove(Reg *r, int bn, int rn, int f) 4803e12c5d1SDavid du Colombier { 4813e12c5d1SDavid du Colombier Prog *p, *p1; 4823e12c5d1SDavid du Colombier Adr *a; 4833e12c5d1SDavid du Colombier Var *v; 4843e12c5d1SDavid du Colombier 4853e12c5d1SDavid du Colombier ALLOC(p1,Prog); 4863e12c5d1SDavid du Colombier *p1 = zprog; 4873e12c5d1SDavid du Colombier p = r->prog; 4883e12c5d1SDavid du Colombier 4893e12c5d1SDavid du Colombier p1->link = p->link; 4903e12c5d1SDavid du Colombier p->link = p1; 4913e12c5d1SDavid du Colombier p1->lineno = p->lineno; 4923e12c5d1SDavid du Colombier 4933e12c5d1SDavid du Colombier v = var + bn; 4943e12c5d1SDavid du Colombier 4953e12c5d1SDavid du Colombier a = &p1->to; 4963e12c5d1SDavid du Colombier a->sym = v->sym; 4973e12c5d1SDavid du Colombier a->name = v->name; 4983e12c5d1SDavid du Colombier a->offset = v->offset; 4993e12c5d1SDavid du Colombier a->etype = v->etype; 5003e12c5d1SDavid du Colombier a->type = D_OREG; 5013e12c5d1SDavid du Colombier if(a->etype == TARRAY || a->sym == S) 5023e12c5d1SDavid du Colombier a->type = D_CONST; 5033e12c5d1SDavid du Colombier 5043e12c5d1SDavid du Colombier p1->as = AMOVW; 5053e12c5d1SDavid du Colombier if(v->etype == TCHAR || v->etype == TUCHAR) 5063e12c5d1SDavid du Colombier p1->as = AMOVB; 5073e12c5d1SDavid du Colombier if(v->etype == TSHORT || v->etype == TUSHORT) 5083e12c5d1SDavid du Colombier p1->as = AMOVH; 5093e12c5d1SDavid du Colombier if(v->etype == TFLOAT) 5103e12c5d1SDavid du Colombier p1->as = AMOVF; 5113e12c5d1SDavid du Colombier if(v->etype == TDOUBLE) 5123e12c5d1SDavid du Colombier p1->as = AMOVD; 5133e12c5d1SDavid du Colombier 5143e12c5d1SDavid du Colombier p1->from.type = D_REG; 5153e12c5d1SDavid du Colombier p1->from.reg = rn; 5163e12c5d1SDavid du Colombier if(rn >= NREG) { 5173e12c5d1SDavid du Colombier p1->from.type = D_FREG; 5183e12c5d1SDavid du Colombier p1->from.reg = rn-NREG; 5193e12c5d1SDavid du Colombier } 5203e12c5d1SDavid du Colombier if(!f) { 5213e12c5d1SDavid du Colombier p1->from = *a; 5223e12c5d1SDavid du Colombier *a = zprog.from; 5233e12c5d1SDavid du Colombier a->type = D_REG; 5243e12c5d1SDavid du Colombier a->reg = rn; 5253e12c5d1SDavid du Colombier if(rn >= NREG) { 5263e12c5d1SDavid du Colombier a->type = D_FREG; 5273e12c5d1SDavid du Colombier a->reg = rn-NREG; 5283e12c5d1SDavid du Colombier } 5293e12c5d1SDavid du Colombier if(v->etype == TUCHAR) 5303e12c5d1SDavid du Colombier p1->as = AMOVBU; 5313e12c5d1SDavid du Colombier if(v->etype == TUSHORT) 5323e12c5d1SDavid du Colombier p1->as = AMOVHU; 5333e12c5d1SDavid du Colombier } 5343e12c5d1SDavid du Colombier if(debug['R']) 5353e12c5d1SDavid du Colombier print("%P%|.a%P\n", p, COL1, p1); 5363e12c5d1SDavid du Colombier } 5373e12c5d1SDavid du Colombier 5383e12c5d1SDavid du Colombier Bits 5393e12c5d1SDavid du Colombier mkvar(Adr *a, int docon) 5403e12c5d1SDavid du Colombier { 5413e12c5d1SDavid du Colombier Var *v; 5423e12c5d1SDavid du Colombier int i, t, n, et, z; 5433e12c5d1SDavid du Colombier long o; 5443e12c5d1SDavid du Colombier Bits bit; 5453e12c5d1SDavid du Colombier Sym *s; 5463e12c5d1SDavid du Colombier 5473e12c5d1SDavid du Colombier t = a->type; 5483e12c5d1SDavid du Colombier if(t == D_REG && a->reg != NREG) 5493e12c5d1SDavid du Colombier regbits |= RtoB(a->reg); 5503e12c5d1SDavid du Colombier if(t == D_FREG && a->reg != NREG) 5513e12c5d1SDavid du Colombier regbits |= FtoB(a->reg); 5523e12c5d1SDavid du Colombier s = a->sym; 5533e12c5d1SDavid du Colombier o = a->offset; 5543e12c5d1SDavid du Colombier et = a->etype; 5553e12c5d1SDavid du Colombier if(s == S) { 5563e12c5d1SDavid du Colombier if(t != D_CONST || !docon || a->reg != NREG) 5573e12c5d1SDavid du Colombier goto none; 5583e12c5d1SDavid du Colombier et = TLONG; 5593e12c5d1SDavid du Colombier } 5603e12c5d1SDavid du Colombier if(t == D_CONST) { 5613e12c5d1SDavid du Colombier if(s == S && sval(o)) 5623e12c5d1SDavid du Colombier goto none; 5633e12c5d1SDavid du Colombier } 5643e12c5d1SDavid du Colombier 5653e12c5d1SDavid du Colombier n = a->name; 5663e12c5d1SDavid du Colombier v = var; 5673e12c5d1SDavid du Colombier for(i=0; i<nvar; i++) { 5683e12c5d1SDavid du Colombier if(s == v->sym) 5693e12c5d1SDavid du Colombier if(n == v->name) 5703e12c5d1SDavid du Colombier if(o == v->offset) 5713e12c5d1SDavid du Colombier goto out; 5723e12c5d1SDavid du Colombier v++; 5733e12c5d1SDavid du Colombier } 5743e12c5d1SDavid du Colombier if(s) 5753e12c5d1SDavid du Colombier if(s->name[0] == '.') 5763e12c5d1SDavid du Colombier goto none; 5773e12c5d1SDavid du Colombier if(nvar >= NVAR) { 5783e12c5d1SDavid du Colombier if(s) 5793e12c5d1SDavid du Colombier warn(Z, "variable not optimized: %s", s->name); 5803e12c5d1SDavid du Colombier goto none; 5813e12c5d1SDavid du Colombier } 5823e12c5d1SDavid du Colombier i = nvar; 5833e12c5d1SDavid du Colombier nvar++; 5843e12c5d1SDavid du Colombier v = &var[i]; 5853e12c5d1SDavid du Colombier v->sym = s; 5863e12c5d1SDavid du Colombier v->offset = o; 5873e12c5d1SDavid du Colombier v->etype = et; 5883e12c5d1SDavid du Colombier v->name = n; 5893e12c5d1SDavid du Colombier if(debug['R']) 5903e12c5d1SDavid du Colombier print("bit=%2d et=%2d %D\n", i, et, a); 5913e12c5d1SDavid du Colombier out: 5923e12c5d1SDavid du Colombier bit = blsh(i); 5933e12c5d1SDavid du Colombier if(n == D_EXTERN || n == D_STATIC) 5943e12c5d1SDavid du Colombier for(z=0; z<BITS; z++) 5953e12c5d1SDavid du Colombier externs.b[z] |= bit.b[z]; 5963e12c5d1SDavid du Colombier if(n == D_PARAM) 5973e12c5d1SDavid du Colombier for(z=0; z<BITS; z++) 5983e12c5d1SDavid du Colombier params.b[z] |= bit.b[z]; 599*219b2ee8SDavid du Colombier if(v->etype != et || !typechlpfd[et]) /* funny punning */ 6003e12c5d1SDavid du Colombier for(z=0; z<BITS; z++) 6013e12c5d1SDavid du Colombier addrs.b[z] |= bit.b[z]; 6023e12c5d1SDavid du Colombier if(t == D_CONST) { 6033e12c5d1SDavid du Colombier if(s == S) { 6043e12c5d1SDavid du Colombier for(z=0; z<BITS; z++) 6053e12c5d1SDavid du Colombier consts.b[z] |= bit.b[z]; 6063e12c5d1SDavid du Colombier return bit; 6073e12c5d1SDavid du Colombier } 6083e12c5d1SDavid du Colombier if(et != TARRAY) 6093e12c5d1SDavid du Colombier for(z=0; z<BITS; z++) 6103e12c5d1SDavid du Colombier addrs.b[z] |= bit.b[z]; 6113e12c5d1SDavid du Colombier for(z=0; z<BITS; z++) 6123e12c5d1SDavid du Colombier params.b[z] |= bit.b[z]; 6133e12c5d1SDavid du Colombier return bit; 6143e12c5d1SDavid du Colombier } 6153e12c5d1SDavid du Colombier if(t == D_OREG) 6163e12c5d1SDavid du Colombier return bit; 6173e12c5d1SDavid du Colombier 6183e12c5d1SDavid du Colombier none: 6193e12c5d1SDavid du Colombier return zbits; 6203e12c5d1SDavid du Colombier } 6213e12c5d1SDavid du Colombier 6223e12c5d1SDavid du Colombier void 6233e12c5d1SDavid du Colombier prop(Reg *r, Bits ref, Bits cal) 6243e12c5d1SDavid du Colombier { 6253e12c5d1SDavid du Colombier Reg *r1, *r2; 6263e12c5d1SDavid du Colombier int z; 6273e12c5d1SDavid du Colombier 6283e12c5d1SDavid du Colombier for(r1 = r; r1 != R; r1 = r1->p1) { 6293e12c5d1SDavid du Colombier for(z=0; z<BITS; z++) { 6303e12c5d1SDavid du Colombier ref.b[z] |= r1->refahead.b[z]; 6313e12c5d1SDavid du Colombier if(ref.b[z] != r1->refahead.b[z]) { 6323e12c5d1SDavid du Colombier r1->refahead.b[z] = ref.b[z]; 6333e12c5d1SDavid du Colombier change++; 6343e12c5d1SDavid du Colombier } 6353e12c5d1SDavid du Colombier cal.b[z] |= r1->calahead.b[z]; 6363e12c5d1SDavid du Colombier if(cal.b[z] != r1->calahead.b[z]) { 6373e12c5d1SDavid du Colombier r1->calahead.b[z] = cal.b[z]; 6383e12c5d1SDavid du Colombier change++; 6393e12c5d1SDavid du Colombier } 6403e12c5d1SDavid du Colombier } 6413e12c5d1SDavid du Colombier switch(r1->prog->as) { 6423e12c5d1SDavid du Colombier case AJAL: 6433e12c5d1SDavid du Colombier for(z=0; z<BITS; z++) { 6443e12c5d1SDavid du Colombier cal.b[z] |= ref.b[z] | externs.b[z]; 6453e12c5d1SDavid du Colombier ref.b[z] = 0; 6463e12c5d1SDavid du Colombier } 6473e12c5d1SDavid du Colombier break; 6483e12c5d1SDavid du Colombier 6493e12c5d1SDavid du Colombier case ATEXT: 6503e12c5d1SDavid du Colombier for(z=0; z<BITS; z++) { 6513e12c5d1SDavid du Colombier cal.b[z] = 0; 6523e12c5d1SDavid du Colombier ref.b[z] = 0; 6533e12c5d1SDavid du Colombier } 6543e12c5d1SDavid du Colombier break; 6553e12c5d1SDavid du Colombier 6563e12c5d1SDavid du Colombier case ARET: 6573e12c5d1SDavid du Colombier for(z=0; z<BITS; z++) { 6583e12c5d1SDavid du Colombier cal.b[z] = externs.b[z]; 6593e12c5d1SDavid du Colombier ref.b[z] = 0; 6603e12c5d1SDavid du Colombier } 6613e12c5d1SDavid du Colombier } 6623e12c5d1SDavid du Colombier for(z=0; z<BITS; z++) { 6633e12c5d1SDavid du Colombier ref.b[z] = (ref.b[z] & ~r1->set.b[z]) | 6643e12c5d1SDavid du Colombier r1->use1.b[z] | r1->use2.b[z]; 6653e12c5d1SDavid du Colombier cal.b[z] &= ~(r1->set.b[z] | r1->use1.b[z] | r1->use2.b[z]); 6663e12c5d1SDavid du Colombier r1->refbehind.b[z] = ref.b[z]; 6673e12c5d1SDavid du Colombier r1->calbehind.b[z] = cal.b[z]; 6683e12c5d1SDavid du Colombier } 6693e12c5d1SDavid du Colombier if(r1->active) 6703e12c5d1SDavid du Colombier break; 6713e12c5d1SDavid du Colombier r1->active = 1; 6723e12c5d1SDavid du Colombier } 6733e12c5d1SDavid du Colombier for(; r != r1; r = r->p1) 6743e12c5d1SDavid du Colombier for(r2 = r->p2; r2 != R; r2 = r2->p2link) 6753e12c5d1SDavid du Colombier prop(r2, r->refbehind, r->calbehind); 6763e12c5d1SDavid du Colombier } 6773e12c5d1SDavid du Colombier 6783e12c5d1SDavid du Colombier int 6793e12c5d1SDavid du Colombier loopit(Reg *r) 6803e12c5d1SDavid du Colombier { 6813e12c5d1SDavid du Colombier Reg *r1; 6823e12c5d1SDavid du Colombier int l, m; 6833e12c5d1SDavid du Colombier 6843e12c5d1SDavid du Colombier l = 0; 6853e12c5d1SDavid du Colombier r->active = 1; 6863e12c5d1SDavid du Colombier r->loop = 0; 6873e12c5d1SDavid du Colombier if(r1 = r->s1) 6883e12c5d1SDavid du Colombier switch(r1->active) { 6893e12c5d1SDavid du Colombier case 0: 6903e12c5d1SDavid du Colombier l += loopit(r1); 6913e12c5d1SDavid du Colombier break; 6923e12c5d1SDavid du Colombier case 1: 6933e12c5d1SDavid du Colombier l += LOOP; 6943e12c5d1SDavid du Colombier r1->loop += LOOP; 6953e12c5d1SDavid du Colombier } 6963e12c5d1SDavid du Colombier if(r1 = r->s2) 6973e12c5d1SDavid du Colombier switch(r1->active) { 6983e12c5d1SDavid du Colombier case 0: 6993e12c5d1SDavid du Colombier l += loopit(r1); 7003e12c5d1SDavid du Colombier break; 7013e12c5d1SDavid du Colombier case 1: 7023e12c5d1SDavid du Colombier l += LOOP; 7033e12c5d1SDavid du Colombier r1->loop += LOOP; 7043e12c5d1SDavid du Colombier } 7053e12c5d1SDavid du Colombier r->active = 2; 7063e12c5d1SDavid du Colombier m = r->loop; 7073e12c5d1SDavid du Colombier r->loop = l + 1; 7083e12c5d1SDavid du Colombier return l - m; 7093e12c5d1SDavid du Colombier } 7103e12c5d1SDavid du Colombier 7113e12c5d1SDavid du Colombier void 7123e12c5d1SDavid du Colombier synch(Reg *r, Bits dif) 7133e12c5d1SDavid du Colombier { 7143e12c5d1SDavid du Colombier Reg *r1; 7153e12c5d1SDavid du Colombier int z; 7163e12c5d1SDavid du Colombier 7173e12c5d1SDavid du Colombier for(r1 = r; r1 != R; r1 = r1->s1) { 7183e12c5d1SDavid du Colombier for(z=0; z<BITS; z++) { 7193e12c5d1SDavid du Colombier dif.b[z] = (dif.b[z] & 7203e12c5d1SDavid du Colombier ~(~r1->refbehind.b[z] & r1->refahead.b[z])) | 7213e12c5d1SDavid du Colombier r1->set.b[z] | r1->regdiff.b[z]; 7223e12c5d1SDavid du Colombier if(dif.b[z] != r1->regdiff.b[z]) { 7233e12c5d1SDavid du Colombier r1->regdiff.b[z] = dif.b[z]; 7243e12c5d1SDavid du Colombier change++; 7253e12c5d1SDavid du Colombier } 7263e12c5d1SDavid du Colombier } 7273e12c5d1SDavid du Colombier if(r1->active) 7283e12c5d1SDavid du Colombier break; 7293e12c5d1SDavid du Colombier r1->active = 1; 7303e12c5d1SDavid du Colombier for(z=0; z<BITS; z++) 7313e12c5d1SDavid du Colombier dif.b[z] &= ~(~r1->calbehind.b[z] & r1->calahead.b[z]); 7323e12c5d1SDavid du Colombier if(r1->s2 != R) 7333e12c5d1SDavid du Colombier synch(r1->s2, dif); 7343e12c5d1SDavid du Colombier } 7353e12c5d1SDavid du Colombier } 7363e12c5d1SDavid du Colombier 7373e12c5d1SDavid du Colombier ulong 7383e12c5d1SDavid du Colombier allreg(ulong b, Rgn *r) 7393e12c5d1SDavid du Colombier { 7403e12c5d1SDavid du Colombier Var *v; 7413e12c5d1SDavid du Colombier int i; 7423e12c5d1SDavid du Colombier 7433e12c5d1SDavid du Colombier v = var + r->varno; 7443e12c5d1SDavid du Colombier r->regno = 0; 7453e12c5d1SDavid du Colombier switch(v->etype) { 7463e12c5d1SDavid du Colombier 7473e12c5d1SDavid du Colombier default: 7483e12c5d1SDavid du Colombier diag(Z, "unknown etype %d/%d", bitno(b), v->etype); 7493e12c5d1SDavid du Colombier break; 7503e12c5d1SDavid du Colombier 7513e12c5d1SDavid du Colombier case TCHAR: 7523e12c5d1SDavid du Colombier case TUCHAR: 7533e12c5d1SDavid du Colombier case TSHORT: 7543e12c5d1SDavid du Colombier case TUSHORT: 7553e12c5d1SDavid du Colombier case TLONG: 7563e12c5d1SDavid du Colombier case TULONG: 7573e12c5d1SDavid du Colombier case TIND: 7583e12c5d1SDavid du Colombier case TARRAY: 7593e12c5d1SDavid du Colombier i = BtoR(~b); 760*219b2ee8SDavid du Colombier if(i && r->cost >= 0) { 7613e12c5d1SDavid du Colombier r->regno = i; 7623e12c5d1SDavid du Colombier return RtoB(i); 7633e12c5d1SDavid du Colombier } 7643e12c5d1SDavid du Colombier break; 7653e12c5d1SDavid du Colombier 7663e12c5d1SDavid du Colombier case TVLONG: 7673e12c5d1SDavid du Colombier case TDOUBLE: 7683e12c5d1SDavid du Colombier case TFLOAT: 7693e12c5d1SDavid du Colombier i = BtoF(~b); 770*219b2ee8SDavid du Colombier if(i && r->cost >= 0) { 7713e12c5d1SDavid du Colombier r->regno = i+NREG; 7723e12c5d1SDavid du Colombier return FtoB(i); 7733e12c5d1SDavid du Colombier } 7743e12c5d1SDavid du Colombier break; 7753e12c5d1SDavid du Colombier } 7763e12c5d1SDavid du Colombier return 0; 7773e12c5d1SDavid du Colombier } 7783e12c5d1SDavid du Colombier 7793e12c5d1SDavid du Colombier void 7803e12c5d1SDavid du Colombier paint1(Reg *r, int bn) 7813e12c5d1SDavid du Colombier { 7823e12c5d1SDavid du Colombier Reg *r1; 7833e12c5d1SDavid du Colombier Prog *p; 7843e12c5d1SDavid du Colombier int z; 7853e12c5d1SDavid du Colombier ulong bb; 7863e12c5d1SDavid du Colombier 7873e12c5d1SDavid du Colombier z = bn/32; 7883e12c5d1SDavid du Colombier bb = 1L<<(bn%32); 7893e12c5d1SDavid du Colombier if(r->act.b[z] & bb) 7903e12c5d1SDavid du Colombier return; 7913e12c5d1SDavid du Colombier for(;;) { 7923e12c5d1SDavid du Colombier if(!(r->refbehind.b[z] & bb)) 7933e12c5d1SDavid du Colombier break; 7943e12c5d1SDavid du Colombier r1 = r->p1; 7953e12c5d1SDavid du Colombier if(r1 == R) 7963e12c5d1SDavid du Colombier break; 7973e12c5d1SDavid du Colombier if(!(r1->refahead.b[z] & bb)) 7983e12c5d1SDavid du Colombier break; 7993e12c5d1SDavid du Colombier if(r1->act.b[z] & bb) 8003e12c5d1SDavid du Colombier break; 8013e12c5d1SDavid du Colombier r = r1; 8023e12c5d1SDavid du Colombier } 8033e12c5d1SDavid du Colombier 8043e12c5d1SDavid du Colombier if(LOAD(r) & ~(r->set.b[z] & ~(r->use1.b[z]|r->use2.b[z])) & bb) { 8053e12c5d1SDavid du Colombier change -= CLOAD * r->loop; 8063e12c5d1SDavid du Colombier if(debug['R'] && debug['v']) 8073e12c5d1SDavid du Colombier print("%d%P%|ld %B $%d\n", r->loop, 8083e12c5d1SDavid du Colombier r->prog, COL1, blsh(bn), change); 8093e12c5d1SDavid du Colombier } 8103e12c5d1SDavid du Colombier for(;;) { 8113e12c5d1SDavid du Colombier r->act.b[z] |= bb; 8123e12c5d1SDavid du Colombier p = r->prog; 8133e12c5d1SDavid du Colombier 8143e12c5d1SDavid du Colombier if(r->use1.b[z] & bb) { 8153e12c5d1SDavid du Colombier change += CREF * r->loop; 8163e12c5d1SDavid du Colombier if(debug['R'] && debug['v']) 8173e12c5d1SDavid du Colombier print("%d%P%|u1 %B $%d\n", r->loop, 8183e12c5d1SDavid du Colombier p, COL1, blsh(bn), change); 8193e12c5d1SDavid du Colombier } 8203e12c5d1SDavid du Colombier 8213e12c5d1SDavid du Colombier if((r->use2.b[z]|r->set.b[z]) & bb) { 8223e12c5d1SDavid du Colombier change += CREF * r->loop; 8233e12c5d1SDavid du Colombier if(debug['R'] && debug['v']) 8243e12c5d1SDavid du Colombier print("%d%P%|u2 %B $%d\n", r->loop, 8253e12c5d1SDavid du Colombier p, COL1, blsh(bn), change); 8263e12c5d1SDavid du Colombier } 8273e12c5d1SDavid du Colombier 8283e12c5d1SDavid du Colombier if(STORE(r) & r->regdiff.b[z] & bb) { 8293e12c5d1SDavid du Colombier change -= CLOAD * r->loop; 8303e12c5d1SDavid du Colombier if(debug['R'] && debug['v']) 8313e12c5d1SDavid du Colombier print("%d%P%|st %B $%d\n", r->loop, 8323e12c5d1SDavid du Colombier p, COL1, blsh(bn), change); 8333e12c5d1SDavid du Colombier } 8343e12c5d1SDavid du Colombier 8353e12c5d1SDavid du Colombier if(r->refbehind.b[z] & bb) 8363e12c5d1SDavid du Colombier for(r1 = r->p2; r1 != R; r1 = r1->p2link) 8373e12c5d1SDavid du Colombier if(r1->refahead.b[z] & bb) 8383e12c5d1SDavid du Colombier paint1(r1, bn); 8393e12c5d1SDavid du Colombier 8403e12c5d1SDavid du Colombier if(!(r->refahead.b[z] & bb)) 8413e12c5d1SDavid du Colombier break; 8423e12c5d1SDavid du Colombier r1 = r->s2; 8433e12c5d1SDavid du Colombier if(r1 != R) 8443e12c5d1SDavid du Colombier if(r1->refbehind.b[z] & bb) 8453e12c5d1SDavid du Colombier paint1(r1, bn); 8463e12c5d1SDavid du Colombier r = r->s1; 8473e12c5d1SDavid du Colombier if(r == R) 8483e12c5d1SDavid du Colombier break; 8493e12c5d1SDavid du Colombier if(r->act.b[z] & bb) 8503e12c5d1SDavid du Colombier break; 8513e12c5d1SDavid du Colombier if(!(r->refbehind.b[z] & bb)) 8523e12c5d1SDavid du Colombier break; 8533e12c5d1SDavid du Colombier } 8543e12c5d1SDavid du Colombier } 8553e12c5d1SDavid du Colombier 8563e12c5d1SDavid du Colombier ulong 8573e12c5d1SDavid du Colombier paint2(Reg *r, int bn) 8583e12c5d1SDavid du Colombier { 8593e12c5d1SDavid du Colombier Reg *r1; 8603e12c5d1SDavid du Colombier int z; 8613e12c5d1SDavid du Colombier ulong bb, vreg; 8623e12c5d1SDavid du Colombier 8633e12c5d1SDavid du Colombier z = bn/32; 8643e12c5d1SDavid du Colombier bb = 1L << (bn%32); 8653e12c5d1SDavid du Colombier vreg = regbits; 8663e12c5d1SDavid du Colombier if(!(r->act.b[z] & bb)) 8673e12c5d1SDavid du Colombier return vreg; 8683e12c5d1SDavid du Colombier for(;;) { 8693e12c5d1SDavid du Colombier if(!(r->refbehind.b[z] & bb)) 8703e12c5d1SDavid du Colombier break; 8713e12c5d1SDavid du Colombier r1 = r->p1; 8723e12c5d1SDavid du Colombier if(r1 == R) 8733e12c5d1SDavid du Colombier break; 8743e12c5d1SDavid du Colombier if(!(r1->refahead.b[z] & bb)) 8753e12c5d1SDavid du Colombier break; 8763e12c5d1SDavid du Colombier if(!(r1->act.b[z] & bb)) 8773e12c5d1SDavid du Colombier break; 8783e12c5d1SDavid du Colombier r = r1; 8793e12c5d1SDavid du Colombier } 8803e12c5d1SDavid du Colombier for(;;) { 8813e12c5d1SDavid du Colombier r->act.b[z] &= ~bb; 8823e12c5d1SDavid du Colombier 8833e12c5d1SDavid du Colombier vreg |= r->regu; 8843e12c5d1SDavid du Colombier 8853e12c5d1SDavid du Colombier if(r->refbehind.b[z] & bb) 8863e12c5d1SDavid du Colombier for(r1 = r->p2; r1 != R; r1 = r1->p2link) 8873e12c5d1SDavid du Colombier if(r1->refahead.b[z] & bb) 8883e12c5d1SDavid du Colombier vreg |= paint2(r1, bn); 8893e12c5d1SDavid du Colombier 8903e12c5d1SDavid du Colombier if(!(r->refahead.b[z] & bb)) 8913e12c5d1SDavid du Colombier break; 8923e12c5d1SDavid du Colombier r1 = r->s2; 8933e12c5d1SDavid du Colombier if(r1 != R) 8943e12c5d1SDavid du Colombier if(r1->refbehind.b[z] & bb) 8953e12c5d1SDavid du Colombier vreg |= paint2(r1, bn); 8963e12c5d1SDavid du Colombier r = r->s1; 8973e12c5d1SDavid du Colombier if(r == R) 8983e12c5d1SDavid du Colombier break; 8993e12c5d1SDavid du Colombier if(!(r->act.b[z] & bb)) 9003e12c5d1SDavid du Colombier break; 9013e12c5d1SDavid du Colombier if(!(r->refbehind.b[z] & bb)) 9023e12c5d1SDavid du Colombier break; 9033e12c5d1SDavid du Colombier } 9043e12c5d1SDavid du Colombier return vreg; 9053e12c5d1SDavid du Colombier } 9063e12c5d1SDavid du Colombier 9073e12c5d1SDavid du Colombier void 9083e12c5d1SDavid du Colombier paint3(Reg *r, int bn, long rb, int rn) 9093e12c5d1SDavid du Colombier { 9103e12c5d1SDavid du Colombier Reg *r1; 9113e12c5d1SDavid du Colombier Prog *p; 9123e12c5d1SDavid du Colombier int z; 9133e12c5d1SDavid du Colombier ulong bb; 9143e12c5d1SDavid du Colombier 9153e12c5d1SDavid du Colombier z = bn/32; 9163e12c5d1SDavid du Colombier bb = 1L << (bn%32); 9173e12c5d1SDavid du Colombier if(r->act.b[z] & bb) 9183e12c5d1SDavid du Colombier return; 9193e12c5d1SDavid du Colombier for(;;) { 9203e12c5d1SDavid du Colombier if(!(r->refbehind.b[z] & bb)) 9213e12c5d1SDavid du Colombier break; 9223e12c5d1SDavid du Colombier r1 = r->p1; 9233e12c5d1SDavid du Colombier if(r1 == R) 9243e12c5d1SDavid du Colombier break; 9253e12c5d1SDavid du Colombier if(!(r1->refahead.b[z] & bb)) 9263e12c5d1SDavid du Colombier break; 9273e12c5d1SDavid du Colombier if(r1->act.b[z] & bb) 9283e12c5d1SDavid du Colombier break; 9293e12c5d1SDavid du Colombier r = r1; 9303e12c5d1SDavid du Colombier } 9313e12c5d1SDavid du Colombier 9323e12c5d1SDavid du Colombier if(LOAD(r) & ~(r->set.b[z] & ~(r->use1.b[z]|r->use2.b[z])) & bb) 9333e12c5d1SDavid du Colombier addmove(r, bn, rn, 0); 9343e12c5d1SDavid du Colombier for(;;) { 9353e12c5d1SDavid du Colombier r->act.b[z] |= bb; 9363e12c5d1SDavid du Colombier p = r->prog; 9373e12c5d1SDavid du Colombier 9383e12c5d1SDavid du Colombier if(r->use1.b[z] & bb) { 9393e12c5d1SDavid du Colombier if(debug['R']) 9403e12c5d1SDavid du Colombier print("%P", p); 9413e12c5d1SDavid du Colombier addreg(&p->from, rn); 9423e12c5d1SDavid du Colombier if(debug['R']) 9433e12c5d1SDavid du Colombier print("%|.c%P\n", COL1, p); 9443e12c5d1SDavid du Colombier } 9453e12c5d1SDavid du Colombier if((r->use2.b[z]|r->set.b[z]) & bb) { 9463e12c5d1SDavid du Colombier if(debug['R']) 9473e12c5d1SDavid du Colombier print("%P", p); 9483e12c5d1SDavid du Colombier addreg(&p->to, rn); 9493e12c5d1SDavid du Colombier if(debug['R']) 9503e12c5d1SDavid du Colombier print("%|.c%P\n", COL1, p); 9513e12c5d1SDavid du Colombier } 9523e12c5d1SDavid du Colombier 9533e12c5d1SDavid du Colombier if(STORE(r) & r->regdiff.b[z] & bb) 9543e12c5d1SDavid du Colombier addmove(r, bn, rn, 1); 9553e12c5d1SDavid du Colombier r->regu |= rb; 9563e12c5d1SDavid du Colombier 9573e12c5d1SDavid du Colombier if(r->refbehind.b[z] & bb) 9583e12c5d1SDavid du Colombier for(r1 = r->p2; r1 != R; r1 = r1->p2link) 9593e12c5d1SDavid du Colombier if(r1->refahead.b[z] & bb) 9603e12c5d1SDavid du Colombier paint3(r1, bn, rb, rn); 9613e12c5d1SDavid du Colombier 9623e12c5d1SDavid du Colombier if(!(r->refahead.b[z] & bb)) 9633e12c5d1SDavid du Colombier break; 9643e12c5d1SDavid du Colombier r1 = r->s2; 9653e12c5d1SDavid du Colombier if(r1 != R) 9663e12c5d1SDavid du Colombier if(r1->refbehind.b[z] & bb) 9673e12c5d1SDavid du Colombier paint3(r1, bn, rb, rn); 9683e12c5d1SDavid du Colombier r = r->s1; 9693e12c5d1SDavid du Colombier if(r == R) 9703e12c5d1SDavid du Colombier break; 9713e12c5d1SDavid du Colombier if(r->act.b[z] & bb) 9723e12c5d1SDavid du Colombier break; 9733e12c5d1SDavid du Colombier if(!(r->refbehind.b[z] & bb)) 9743e12c5d1SDavid du Colombier break; 9753e12c5d1SDavid du Colombier } 9763e12c5d1SDavid du Colombier } 9773e12c5d1SDavid du Colombier 9783e12c5d1SDavid du Colombier void 9793e12c5d1SDavid du Colombier addreg(Adr *a, int rn) 9803e12c5d1SDavid du Colombier { 9813e12c5d1SDavid du Colombier 9823e12c5d1SDavid du Colombier a->sym = 0; 9833e12c5d1SDavid du Colombier a->name = D_NONE; 9843e12c5d1SDavid du Colombier a->type = D_REG; 9853e12c5d1SDavid du Colombier a->reg = rn; 9863e12c5d1SDavid du Colombier if(rn >= NREG) { 9873e12c5d1SDavid du Colombier a->type = D_FREG; 9883e12c5d1SDavid du Colombier a->reg = rn-NREG; 9893e12c5d1SDavid du Colombier } 9903e12c5d1SDavid du Colombier } 9913e12c5d1SDavid du Colombier 9923e12c5d1SDavid du Colombier /* 9933e12c5d1SDavid du Colombier * bit reg 9943e12c5d1SDavid du Colombier * 0 R3 9953e12c5d1SDavid du Colombier * 1 R4 9963e12c5d1SDavid du Colombier * ... ... 9973e12c5d1SDavid du Colombier * 19 R22 9983e12c5d1SDavid du Colombier * 20 R23 9993e12c5d1SDavid du Colombier */ 10003e12c5d1SDavid du Colombier long 10013e12c5d1SDavid du Colombier RtoB(int r) 10023e12c5d1SDavid du Colombier { 10033e12c5d1SDavid du Colombier 10043e12c5d1SDavid du Colombier if(r < 3 || r > 23) 10053e12c5d1SDavid du Colombier return 0; 10063e12c5d1SDavid du Colombier return 1L << (r-3); 10073e12c5d1SDavid du Colombier } 10083e12c5d1SDavid du Colombier 10093e12c5d1SDavid du Colombier BtoR(long b) 10103e12c5d1SDavid du Colombier { 10113e12c5d1SDavid du Colombier 10123e12c5d1SDavid du Colombier b &= 0x001fffffL; 10133e12c5d1SDavid du Colombier if(b == 0) 10143e12c5d1SDavid du Colombier return 0; 10153e12c5d1SDavid du Colombier return bitno(b) + 3; 10163e12c5d1SDavid du Colombier } 10173e12c5d1SDavid du Colombier 10183e12c5d1SDavid du Colombier /* 10193e12c5d1SDavid du Colombier * bit reg 10203e12c5d1SDavid du Colombier * 22 F4 10213e12c5d1SDavid du Colombier * 23 F6 10223e12c5d1SDavid du Colombier * ... ... 10233e12c5d1SDavid du Colombier * 31 F22 10243e12c5d1SDavid du Colombier */ 10253e12c5d1SDavid du Colombier long 10263e12c5d1SDavid du Colombier FtoB(int f) 10273e12c5d1SDavid du Colombier { 10283e12c5d1SDavid du Colombier 10293e12c5d1SDavid du Colombier if(f < 4 || f > 22 || (f&1)) 10303e12c5d1SDavid du Colombier return 0; 10313e12c5d1SDavid du Colombier return 1L << (f/2 + 20); 10323e12c5d1SDavid du Colombier } 10333e12c5d1SDavid du Colombier 1034*219b2ee8SDavid du Colombier int 10353e12c5d1SDavid du Colombier BtoF(long b) 10363e12c5d1SDavid du Colombier { 10373e12c5d1SDavid du Colombier 10383e12c5d1SDavid du Colombier b &= 0xffc00000L; 10393e12c5d1SDavid du Colombier if(b == 0) 10403e12c5d1SDavid du Colombier return 0; 10413e12c5d1SDavid du Colombier return bitno(b)*2 - 40; 10423e12c5d1SDavid du Colombier } 1043