13e12c5d1SDavid du Colombier #include "gc.h" 23e12c5d1SDavid du Colombier 33e12c5d1SDavid du Colombier void 43e12c5d1SDavid du Colombier peep(void) 53e12c5d1SDavid du Colombier { 63e12c5d1SDavid du Colombier Reg *r, *r1, *r2; 73e12c5d1SDavid du Colombier Prog *p, *p1; 83e12c5d1SDavid du Colombier int t; 93e12c5d1SDavid du Colombier /* 103e12c5d1SDavid du Colombier * complete R structure 113e12c5d1SDavid du Colombier */ 123e12c5d1SDavid du Colombier t = 0; 133e12c5d1SDavid du Colombier for(r=firstr; r!=R; r=r1) { 143e12c5d1SDavid du Colombier r1 = r->link; 153e12c5d1SDavid du Colombier if(r1 == R) 163e12c5d1SDavid du Colombier break; 173e12c5d1SDavid du Colombier p = r->prog->link; 183e12c5d1SDavid du Colombier while(p != r1->prog) 193e12c5d1SDavid du Colombier switch(p->as) { 203e12c5d1SDavid du Colombier default: 213e12c5d1SDavid du Colombier r2 = rega(); 223e12c5d1SDavid du Colombier r->link = r2; 233e12c5d1SDavid du Colombier r2->link = r1; 243e12c5d1SDavid du Colombier 253e12c5d1SDavid du Colombier r2->prog = p; 263e12c5d1SDavid du Colombier r2->p1 = r; 273e12c5d1SDavid du Colombier r->s1 = r2; 283e12c5d1SDavid du Colombier r2->s1 = r1; 293e12c5d1SDavid du Colombier r1->p1 = r2; 303e12c5d1SDavid du Colombier 313e12c5d1SDavid du Colombier r = r2; 323e12c5d1SDavid du Colombier t++; 333e12c5d1SDavid du Colombier 343e12c5d1SDavid du Colombier case ADATA: 353e12c5d1SDavid du Colombier case AGLOBL: 363e12c5d1SDavid du Colombier case ANAME: 373e12c5d1SDavid du Colombier p = p->link; 383e12c5d1SDavid du Colombier } 393e12c5d1SDavid du Colombier } 403e12c5d1SDavid du Colombier 413e12c5d1SDavid du Colombier loop1: 423e12c5d1SDavid du Colombier t = 0; 433e12c5d1SDavid du Colombier for(r=firstr; r!=R; r=r->link) { 443e12c5d1SDavid du Colombier p = r->prog; 453e12c5d1SDavid du Colombier if(p->as == AMOVW || p->as == AMOVF || p->as == AMOVD) 463e12c5d1SDavid du Colombier if(regtyp(&p->to)) { 473e12c5d1SDavid du Colombier if(regtyp(&p->from)) 483e12c5d1SDavid du Colombier if(p->from.type == p->to.type) { 493e12c5d1SDavid du Colombier if(copyprop(r)) { 503e12c5d1SDavid du Colombier excise(r); 513e12c5d1SDavid du Colombier t++; 523e12c5d1SDavid du Colombier } else 533e12c5d1SDavid du Colombier if(subprop(r) && copyprop(r)) { 543e12c5d1SDavid du Colombier excise(r); 553e12c5d1SDavid du Colombier t++; 563e12c5d1SDavid du Colombier } 573e12c5d1SDavid du Colombier } 583e12c5d1SDavid du Colombier if(regzer(&p->from)) 593e12c5d1SDavid du Colombier if(p->to.type == D_REG) { 603e12c5d1SDavid du Colombier p->from.type = D_REG; 613e12c5d1SDavid du Colombier p->from.reg = 0; 623e12c5d1SDavid du Colombier if(copyprop(r)) { 633e12c5d1SDavid du Colombier excise(r); 643e12c5d1SDavid du Colombier t++; 653e12c5d1SDavid du Colombier } else 663e12c5d1SDavid du Colombier if(subprop(r) && copyprop(r)) { 673e12c5d1SDavid du Colombier excise(r); 683e12c5d1SDavid du Colombier t++; 693e12c5d1SDavid du Colombier } 703e12c5d1SDavid du Colombier } 713e12c5d1SDavid du Colombier } 723e12c5d1SDavid du Colombier } 733e12c5d1SDavid du Colombier if(t) 743e12c5d1SDavid du Colombier goto loop1; 753e12c5d1SDavid du Colombier /* 763e12c5d1SDavid du Colombier * look for MOVB x,R; MOVB R,R 773e12c5d1SDavid du Colombier */ 783e12c5d1SDavid du Colombier for(r=firstr; r!=R; r=r->link) { 793e12c5d1SDavid du Colombier p = r->prog; 803e12c5d1SDavid du Colombier switch(p->as) { 813e12c5d1SDavid du Colombier default: 823e12c5d1SDavid du Colombier continue; 833e12c5d1SDavid du Colombier case AMOVH: 843e12c5d1SDavid du Colombier case AMOVHU: 853e12c5d1SDavid du Colombier case AMOVB: 863e12c5d1SDavid du Colombier case AMOVBU: 873e12c5d1SDavid du Colombier if(p->to.type != D_REG) 883e12c5d1SDavid du Colombier continue; 893e12c5d1SDavid du Colombier break; 903e12c5d1SDavid du Colombier } 913e12c5d1SDavid du Colombier r1 = r->link; 923e12c5d1SDavid du Colombier if(r1 == R) 933e12c5d1SDavid du Colombier continue; 943e12c5d1SDavid du Colombier p1 = r1->prog; 953e12c5d1SDavid du Colombier if(p1->as != p->as) 963e12c5d1SDavid du Colombier continue; 973e12c5d1SDavid du Colombier if(p1->from.type != D_REG || p1->from.reg != p->to.reg) 983e12c5d1SDavid du Colombier continue; 993e12c5d1SDavid du Colombier if(p1->to.type != D_REG || p1->to.reg != p->to.reg) 1003e12c5d1SDavid du Colombier continue; 1013e12c5d1SDavid du Colombier excise(r1); 1023e12c5d1SDavid du Colombier } 1033e12c5d1SDavid du Colombier } 1043e12c5d1SDavid du Colombier 1053e12c5d1SDavid du Colombier void 1063e12c5d1SDavid du Colombier excise(Reg *r) 1073e12c5d1SDavid du Colombier { 1083e12c5d1SDavid du Colombier Prog *p; 1093e12c5d1SDavid du Colombier 1103e12c5d1SDavid du Colombier p = r->prog; 1113e12c5d1SDavid du Colombier p->as = ANOP; 1123e12c5d1SDavid du Colombier p->from = zprog.from; 1133e12c5d1SDavid du Colombier p->to = zprog.to; 1143e12c5d1SDavid du Colombier p->reg = zprog.reg; /**/ 1153e12c5d1SDavid du Colombier } 1163e12c5d1SDavid du Colombier 1173e12c5d1SDavid du Colombier Reg* 1183e12c5d1SDavid du Colombier uniqp(Reg *r) 1193e12c5d1SDavid du Colombier { 1203e12c5d1SDavid du Colombier Reg *r1; 1213e12c5d1SDavid du Colombier 1223e12c5d1SDavid du Colombier r1 = r->p1; 1233e12c5d1SDavid du Colombier if(r1 == R) { 1243e12c5d1SDavid du Colombier r1 = r->p2; 1253e12c5d1SDavid du Colombier if(r1 == R || r1->p2link != R) 1263e12c5d1SDavid du Colombier return R; 1273e12c5d1SDavid du Colombier } else 1283e12c5d1SDavid du Colombier if(r->p2 != R) 1293e12c5d1SDavid du Colombier return R; 1303e12c5d1SDavid du Colombier return r1; 1313e12c5d1SDavid du Colombier } 1323e12c5d1SDavid du Colombier 1333e12c5d1SDavid du Colombier Reg* 1343e12c5d1SDavid du Colombier uniqs(Reg *r) 1353e12c5d1SDavid du Colombier { 1363e12c5d1SDavid du Colombier Reg *r1; 1373e12c5d1SDavid du Colombier 1383e12c5d1SDavid du Colombier r1 = r->s1; 1393e12c5d1SDavid du Colombier if(r1 == R) { 1403e12c5d1SDavid du Colombier r1 = r->s2; 1413e12c5d1SDavid du Colombier if(r1 == R) 1423e12c5d1SDavid du Colombier return R; 1433e12c5d1SDavid du Colombier } else 1443e12c5d1SDavid du Colombier if(r->s2 != R) 1453e12c5d1SDavid du Colombier return R; 1463e12c5d1SDavid du Colombier return r1; 1473e12c5d1SDavid du Colombier } 1483e12c5d1SDavid du Colombier 1493e12c5d1SDavid du Colombier int 1503e12c5d1SDavid du Colombier regzer(Adr *a) 1513e12c5d1SDavid du Colombier { 1523e12c5d1SDavid du Colombier 1533e12c5d1SDavid du Colombier if(a->type == D_CONST) 1543e12c5d1SDavid du Colombier if(a->sym == S) 1553e12c5d1SDavid du Colombier if(a->offset == 0) 1563e12c5d1SDavid du Colombier return 1; 1573e12c5d1SDavid du Colombier if(a->type == D_REG) 1583e12c5d1SDavid du Colombier if(a->reg == 0) 1593e12c5d1SDavid du Colombier return 1; 1603e12c5d1SDavid du Colombier return 0; 1613e12c5d1SDavid du Colombier } 1623e12c5d1SDavid du Colombier 1633e12c5d1SDavid du Colombier int 1643e12c5d1SDavid du Colombier regtyp(Adr *a) 1653e12c5d1SDavid du Colombier { 1663e12c5d1SDavid du Colombier 1673e12c5d1SDavid du Colombier if(a->type == D_REG) { 1683e12c5d1SDavid du Colombier if(a->reg != 0) 1693e12c5d1SDavid du Colombier return 1; 1703e12c5d1SDavid du Colombier return 0; 1713e12c5d1SDavid du Colombier } 1723e12c5d1SDavid du Colombier if(a->type == D_FREG) 1733e12c5d1SDavid du Colombier return 1; 1743e12c5d1SDavid du Colombier return 0; 1753e12c5d1SDavid du Colombier } 1763e12c5d1SDavid du Colombier 1773e12c5d1SDavid du Colombier /* 1783e12c5d1SDavid du Colombier * the idea is to substitute 1793e12c5d1SDavid du Colombier * one register for another 1803e12c5d1SDavid du Colombier * from one MOV to another 1813e12c5d1SDavid du Colombier * MOV a, R0 1823e12c5d1SDavid du Colombier * ADD b, R0 / no use of R1 1833e12c5d1SDavid du Colombier * MOV R0, R1 1843e12c5d1SDavid du Colombier * would be converted to 1853e12c5d1SDavid du Colombier * MOV a, R1 1863e12c5d1SDavid du Colombier * ADD b, R1 1873e12c5d1SDavid du Colombier * MOV R1, R0 1883e12c5d1SDavid du Colombier * hopefully, then the former or latter MOV 1893e12c5d1SDavid du Colombier * will be eliminated by copy propagation. 1903e12c5d1SDavid du Colombier */ 1913e12c5d1SDavid du Colombier int 1923e12c5d1SDavid du Colombier subprop(Reg *r0) 1933e12c5d1SDavid du Colombier { 1943e12c5d1SDavid du Colombier Prog *p; 1953e12c5d1SDavid du Colombier Adr *v1, *v2; 1963e12c5d1SDavid du Colombier Reg *r; 1973e12c5d1SDavid du Colombier int t; 1983e12c5d1SDavid du Colombier 1993e12c5d1SDavid du Colombier p = r0->prog; 2003e12c5d1SDavid du Colombier v1 = &p->from; 2013e12c5d1SDavid du Colombier if(!regtyp(v1)) 2023e12c5d1SDavid du Colombier return 0; 2033e12c5d1SDavid du Colombier v2 = &p->to; 2043e12c5d1SDavid du Colombier if(!regtyp(v2)) 2053e12c5d1SDavid du Colombier return 0; 2063e12c5d1SDavid du Colombier for(r=uniqp(r0); r!=R; r=uniqp(r)) { 2073e12c5d1SDavid du Colombier if(uniqs(r) == R) 2083e12c5d1SDavid du Colombier break; 2093e12c5d1SDavid du Colombier p = r->prog; 2103e12c5d1SDavid du Colombier switch(p->as) { 2113e12c5d1SDavid du Colombier case AJAL: 2123e12c5d1SDavid du Colombier return 0; 2133e12c5d1SDavid du Colombier 2143e12c5d1SDavid du Colombier case ASGT: 2153e12c5d1SDavid du Colombier case ASGTU: 2163e12c5d1SDavid du Colombier 2173e12c5d1SDavid du Colombier case AADD: 2183e12c5d1SDavid du Colombier case AADDU: 2193e12c5d1SDavid du Colombier case ASUB: 2203e12c5d1SDavid du Colombier case ASUBU: 2213e12c5d1SDavid du Colombier case ASLL: 2223e12c5d1SDavid du Colombier case ASRL: 2233e12c5d1SDavid du Colombier case ASRA: 2243e12c5d1SDavid du Colombier case AOR: 2253e12c5d1SDavid du Colombier case AAND: 2263e12c5d1SDavid du Colombier case AXOR: 2273e12c5d1SDavid du Colombier case AMUL: 2283e12c5d1SDavid du Colombier case AMULU: 2293e12c5d1SDavid du Colombier case ADIV: 2303e12c5d1SDavid du Colombier case ADIVU: 2313e12c5d1SDavid du Colombier 2323e12c5d1SDavid du Colombier case AADDD: 2333e12c5d1SDavid du Colombier case AADDF: 2343e12c5d1SDavid du Colombier case ASUBD: 2353e12c5d1SDavid du Colombier case ASUBF: 2363e12c5d1SDavid du Colombier case AMULD: 2373e12c5d1SDavid du Colombier case AMULF: 2383e12c5d1SDavid du Colombier case ADIVD: 2393e12c5d1SDavid du Colombier case ADIVF: 2403e12c5d1SDavid du Colombier if(p->to.type == v1->type) 2413e12c5d1SDavid du Colombier if(p->to.reg == v1->reg) { 2423e12c5d1SDavid du Colombier if(p->reg == NREG) 2433e12c5d1SDavid du Colombier p->reg = p->to.reg; 2443e12c5d1SDavid du Colombier goto gotit; 2453e12c5d1SDavid du Colombier } 2463e12c5d1SDavid du Colombier break; 2473e12c5d1SDavid du Colombier 2483e12c5d1SDavid du Colombier case AMOVF: 2493e12c5d1SDavid du Colombier case AMOVD: 2503e12c5d1SDavid du Colombier case AMOVW: 2513e12c5d1SDavid du Colombier if(p->to.type == v1->type) 2523e12c5d1SDavid du Colombier if(p->to.reg == v1->reg) 2533e12c5d1SDavid du Colombier goto gotit; 2543e12c5d1SDavid du Colombier break; 2553e12c5d1SDavid du Colombier } 2563e12c5d1SDavid du Colombier if(copyau(&p->from, v2) || 2573e12c5d1SDavid du Colombier copyau1(p, v2) || 2583e12c5d1SDavid du Colombier copyau(&p->to, v2)) 2593e12c5d1SDavid du Colombier break; 2603e12c5d1SDavid du Colombier if(copysub(&p->from, v1, v2, 0) || 2613e12c5d1SDavid du Colombier copysub1(p, v1, v2, 0) || 2623e12c5d1SDavid du Colombier copysub(&p->to, v1, v2, 0)) 2633e12c5d1SDavid du Colombier break; 2643e12c5d1SDavid du Colombier } 2653e12c5d1SDavid du Colombier return 0; 2663e12c5d1SDavid du Colombier 2673e12c5d1SDavid du Colombier gotit: 2683e12c5d1SDavid du Colombier copysub(&p->to, v1, v2, 1); 2693e12c5d1SDavid du Colombier if(debug['P']) { 2703e12c5d1SDavid du Colombier print("gotit: %D->%D\n%P", v1, v2, r->prog); 2713e12c5d1SDavid du Colombier if(p->from.type == v2->type) 2723e12c5d1SDavid du Colombier print(" excise"); 2733e12c5d1SDavid du Colombier print("\n"); 2743e12c5d1SDavid du Colombier } 2753e12c5d1SDavid du Colombier for(r=uniqs(r); r!=r0; r=uniqs(r)) { 2763e12c5d1SDavid du Colombier p = r->prog; 2773e12c5d1SDavid du Colombier copysub(&p->from, v1, v2, 1); 2783e12c5d1SDavid du Colombier copysub1(p, v1, v2, 1); 2793e12c5d1SDavid du Colombier copysub(&p->to, v1, v2, 1); 2803e12c5d1SDavid du Colombier if(debug['P']) 2813e12c5d1SDavid du Colombier print("%P\n", r->prog); 2823e12c5d1SDavid du Colombier } 2833e12c5d1SDavid du Colombier t = v1->reg; 2843e12c5d1SDavid du Colombier v1->reg = v2->reg; 2853e12c5d1SDavid du Colombier v2->reg = t; 2863e12c5d1SDavid du Colombier if(debug['P']) 2873e12c5d1SDavid du Colombier print("%P last\n", r->prog); 2883e12c5d1SDavid du Colombier return 1; 2893e12c5d1SDavid du Colombier } 2903e12c5d1SDavid du Colombier 2913e12c5d1SDavid du Colombier /* 2923e12c5d1SDavid du Colombier * The idea is to remove redundant copies. 2933e12c5d1SDavid du Colombier * v1->v2 F=0 2943e12c5d1SDavid du Colombier * (use v2 s/v2/v1/)* 2953e12c5d1SDavid du Colombier * set v1 F=1 2963e12c5d1SDavid du Colombier * use v2 return fail 2973e12c5d1SDavid du Colombier * ----------------- 2983e12c5d1SDavid du Colombier * v1->v2 F=0 2993e12c5d1SDavid du Colombier * (use v2 s/v2/v1/)* 3003e12c5d1SDavid du Colombier * set v1 F=1 3013e12c5d1SDavid du Colombier * set v2 return success 3023e12c5d1SDavid du Colombier */ 3033e12c5d1SDavid du Colombier int 3043e12c5d1SDavid du Colombier copyprop(Reg *r0) 3053e12c5d1SDavid du Colombier { 3063e12c5d1SDavid du Colombier Prog *p; 3073e12c5d1SDavid du Colombier Adr *v1, *v2; 3083e12c5d1SDavid du Colombier Reg *r; 3093e12c5d1SDavid du Colombier 3103e12c5d1SDavid du Colombier p = r0->prog; 3113e12c5d1SDavid du Colombier v1 = &p->from; 3123e12c5d1SDavid du Colombier v2 = &p->to; 3133e12c5d1SDavid du Colombier if(copyas(v1, v2)) 3143e12c5d1SDavid du Colombier return 1; 3153e12c5d1SDavid du Colombier for(r=firstr; r!=R; r=r->link) 3163e12c5d1SDavid du Colombier r->active = 0; 3173e12c5d1SDavid du Colombier return copy1(v1, v2, r0->s1, 0); 3183e12c5d1SDavid du Colombier } 3193e12c5d1SDavid du Colombier 3203e12c5d1SDavid du Colombier int 3213e12c5d1SDavid du Colombier copy1(Adr *v1, Adr *v2, Reg *r, int f) 3223e12c5d1SDavid du Colombier { 3233e12c5d1SDavid du Colombier int t; 3243e12c5d1SDavid du Colombier Prog *p; 3253e12c5d1SDavid du Colombier 3263e12c5d1SDavid du Colombier if(r->active) { 3273e12c5d1SDavid du Colombier if(debug['P']) 3283e12c5d1SDavid du Colombier print("act set; return 1\n"); 3293e12c5d1SDavid du Colombier return 1; 3303e12c5d1SDavid du Colombier } 3313e12c5d1SDavid du Colombier r->active = 1; 3323e12c5d1SDavid du Colombier if(debug['P']) 3333e12c5d1SDavid du Colombier print("copy %D->%D f=%d\n", v1, v2, f); 3343e12c5d1SDavid du Colombier for(; r != R; r = r->s1) { 3353e12c5d1SDavid du Colombier p = r->prog; 3363e12c5d1SDavid du Colombier if(debug['P']) 3373e12c5d1SDavid du Colombier print("%P", p); 3383e12c5d1SDavid du Colombier if(!f && uniqp(r) == R) { 3393e12c5d1SDavid du Colombier f = 1; 3403e12c5d1SDavid du Colombier if(debug['P']) 3413e12c5d1SDavid du Colombier print("; merge; f=%d", f); 3423e12c5d1SDavid du Colombier } 3433e12c5d1SDavid du Colombier t = copyu(p, v2, A); 3443e12c5d1SDavid du Colombier switch(t) { 3453e12c5d1SDavid du Colombier case 2: /* rar, cant split */ 3463e12c5d1SDavid du Colombier if(debug['P']) 3473e12c5d1SDavid du Colombier print("; %Drar; return 0\n", v2); 3483e12c5d1SDavid du Colombier return 0; 3493e12c5d1SDavid du Colombier 3503e12c5d1SDavid du Colombier case 3: /* set */ 3513e12c5d1SDavid du Colombier if(debug['P']) 3523e12c5d1SDavid du Colombier print("; %Dset; return 1\n", v2); 3533e12c5d1SDavid du Colombier return 1; 3543e12c5d1SDavid du Colombier 3553e12c5d1SDavid du Colombier case 1: /* used, substitute */ 3563e12c5d1SDavid du Colombier case 4: /* use and set */ 3573e12c5d1SDavid du Colombier if(f) { 3583e12c5d1SDavid du Colombier if(!debug['P']) 3593e12c5d1SDavid du Colombier return 0; 3603e12c5d1SDavid du Colombier if(t == 4) 3613e12c5d1SDavid du Colombier print("; %Dused+set and f=%d; return 0\n", v2, f); 3623e12c5d1SDavid du Colombier else 3633e12c5d1SDavid du Colombier print("; %Dused and f=%d; return 0\n", v2, f); 3643e12c5d1SDavid du Colombier return 0; 3653e12c5d1SDavid du Colombier } 3663e12c5d1SDavid du Colombier if(copyu(p, v2, v1)) { 3673e12c5d1SDavid du Colombier if(debug['P']) 3683e12c5d1SDavid du Colombier print("; sub fail; return 0\n"); 3693e12c5d1SDavid du Colombier return 0; 3703e12c5d1SDavid du Colombier } 3713e12c5d1SDavid du Colombier if(debug['P']) 3723e12c5d1SDavid du Colombier print("; sub%D/%D", v2, v1); 3733e12c5d1SDavid du Colombier if(t == 4) { 3743e12c5d1SDavid du Colombier if(debug['P']) 3753e12c5d1SDavid du Colombier print("; %Dused+set; return 1\n", v2); 3763e12c5d1SDavid du Colombier return 1; 3773e12c5d1SDavid du Colombier } 3783e12c5d1SDavid du Colombier break; 3793e12c5d1SDavid du Colombier } 3803e12c5d1SDavid du Colombier if(!f) { 3813e12c5d1SDavid du Colombier t = copyu(p, v1, A); 3823e12c5d1SDavid du Colombier if(!f && (t == 2 || t == 3 || t == 4)) { 3833e12c5d1SDavid du Colombier f = 1; 3843e12c5d1SDavid du Colombier if(debug['P']) 3853e12c5d1SDavid du Colombier print("; %Dset and !f; f=%d", v1, f); 3863e12c5d1SDavid du Colombier } 3873e12c5d1SDavid du Colombier } 3883e12c5d1SDavid du Colombier if(debug['P']) 3893e12c5d1SDavid du Colombier print("\n"); 3903e12c5d1SDavid du Colombier if(r->s2) 3913e12c5d1SDavid du Colombier if(!copy1(v1, v2, r->s2, f)) 3923e12c5d1SDavid du Colombier return 0; 3933e12c5d1SDavid du Colombier } 3943e12c5d1SDavid du Colombier return 1; 3953e12c5d1SDavid du Colombier } 3963e12c5d1SDavid du Colombier 3973e12c5d1SDavid du Colombier /* 3983e12c5d1SDavid du Colombier * return 3993e12c5d1SDavid du Colombier * 1 if v only used (and substitute), 4003e12c5d1SDavid du Colombier * 2 if read-alter-rewrite 4013e12c5d1SDavid du Colombier * 3 if set 4023e12c5d1SDavid du Colombier * 4 if set and used 4033e12c5d1SDavid du Colombier * 0 otherwise (not touched) 4043e12c5d1SDavid du Colombier */ 4053e12c5d1SDavid du Colombier copyu(Prog *p, Adr *v, Adr *s) 4063e12c5d1SDavid du Colombier { 4073e12c5d1SDavid du Colombier 4083e12c5d1SDavid du Colombier switch(p->as) { 4093e12c5d1SDavid du Colombier 4103e12c5d1SDavid du Colombier default: 4113e12c5d1SDavid du Colombier if(debug['P']) 4123e12c5d1SDavid du Colombier print(" (???)"); 4133e12c5d1SDavid du Colombier return 2; 4143e12c5d1SDavid du Colombier 4153e12c5d1SDavid du Colombier 4163e12c5d1SDavid du Colombier case ANOP: /* read, write */ 4173e12c5d1SDavid du Colombier case AMOVW: 4183e12c5d1SDavid du Colombier case AMOVF: 4193e12c5d1SDavid du Colombier case AMOVD: 4203e12c5d1SDavid du Colombier case AMOVH: 4213e12c5d1SDavid du Colombier case AMOVHU: 4223e12c5d1SDavid du Colombier case AMOVB: 4233e12c5d1SDavid du Colombier case AMOVBU: 4243e12c5d1SDavid du Colombier case AMOVDW: 4253e12c5d1SDavid du Colombier case AMOVWD: 4263e12c5d1SDavid du Colombier case AMOVFD: 4273e12c5d1SDavid du Colombier case AMOVDF: 4283e12c5d1SDavid du Colombier if(s != A) { 4293e12c5d1SDavid du Colombier if(copysub(&p->from, v, s, 1)) 4303e12c5d1SDavid du Colombier return 1; 4313e12c5d1SDavid du Colombier if(!copyas(&p->to, v)) 4323e12c5d1SDavid du Colombier if(copysub(&p->to, v, s, 1)) 4333e12c5d1SDavid du Colombier return 1; 4343e12c5d1SDavid du Colombier return 0; 4353e12c5d1SDavid du Colombier } 4363e12c5d1SDavid du Colombier if(copyas(&p->to, v)) { 4373e12c5d1SDavid du Colombier if(copyau(&p->from, v)) 4383e12c5d1SDavid du Colombier return 4; 4393e12c5d1SDavid du Colombier return 3; 4403e12c5d1SDavid du Colombier } 4413e12c5d1SDavid du Colombier if(copyau(&p->from, v)) 4423e12c5d1SDavid du Colombier return 1; 4433e12c5d1SDavid du Colombier if(copyau(&p->to, v)) 4443e12c5d1SDavid du Colombier return 1; 4453e12c5d1SDavid du Colombier return 0; 4463e12c5d1SDavid du Colombier 4473e12c5d1SDavid du Colombier case ASGT: /* read, read, write */ 4483e12c5d1SDavid du Colombier case ASGTU: 4493e12c5d1SDavid du Colombier 4503e12c5d1SDavid du Colombier case AADD: 4513e12c5d1SDavid du Colombier case AADDU: 4523e12c5d1SDavid du Colombier case ASUB: 4533e12c5d1SDavid du Colombier case ASUBU: 4543e12c5d1SDavid du Colombier case ASLL: 4553e12c5d1SDavid du Colombier case ASRL: 4563e12c5d1SDavid du Colombier case ASRA: 4573e12c5d1SDavid du Colombier case AOR: 4583e12c5d1SDavid du Colombier case ANOR: 4593e12c5d1SDavid du Colombier case AAND: 4603e12c5d1SDavid du Colombier case AXOR: 4613e12c5d1SDavid du Colombier case AMUL: 4623e12c5d1SDavid du Colombier case AMULU: 4633e12c5d1SDavid du Colombier case ADIV: 4643e12c5d1SDavid du Colombier case ADIVU: 4653e12c5d1SDavid du Colombier 4663e12c5d1SDavid du Colombier case AADDF: 4673e12c5d1SDavid du Colombier case AADDD: 4683e12c5d1SDavid du Colombier case ASUBF: 4693e12c5d1SDavid du Colombier case ASUBD: 4703e12c5d1SDavid du Colombier case AMULF: 4713e12c5d1SDavid du Colombier case AMULD: 4723e12c5d1SDavid du Colombier case ADIVF: 4733e12c5d1SDavid du Colombier case ADIVD: 4743e12c5d1SDavid du Colombier if(s != A) { 4753e12c5d1SDavid du Colombier if(copysub(&p->from, v, s, 1)) 4763e12c5d1SDavid du Colombier return 1; 4773e12c5d1SDavid du Colombier if(copysub1(p, v, s, 1)) 4783e12c5d1SDavid du Colombier return 1; 4793e12c5d1SDavid du Colombier if(!copyas(&p->to, v)) 4803e12c5d1SDavid du Colombier if(copysub(&p->to, v, s, 1)) 4813e12c5d1SDavid du Colombier return 1; 4823e12c5d1SDavid du Colombier return 0; 4833e12c5d1SDavid du Colombier } 4843e12c5d1SDavid du Colombier if(copyas(&p->to, v)) { 4853e12c5d1SDavid du Colombier if(p->reg == NREG) 4863e12c5d1SDavid du Colombier p->reg = p->to.reg; 4873e12c5d1SDavid du Colombier if(copyau(&p->from, v)) 4883e12c5d1SDavid du Colombier return 4; 4893e12c5d1SDavid du Colombier if(copyau1(p, v)) 4903e12c5d1SDavid du Colombier return 4; 4913e12c5d1SDavid du Colombier return 3; 4923e12c5d1SDavid du Colombier } 4933e12c5d1SDavid du Colombier if(copyau(&p->from, v)) 4943e12c5d1SDavid du Colombier return 1; 4953e12c5d1SDavid du Colombier if(copyau1(p, v)) 4963e12c5d1SDavid du Colombier return 1; 4973e12c5d1SDavid du Colombier if(copyau(&p->to, v)) 4983e12c5d1SDavid du Colombier return 1; 4993e12c5d1SDavid du Colombier return 0; 5003e12c5d1SDavid du Colombier 5013e12c5d1SDavid du Colombier case ABEQ: /* read, read */ 5023e12c5d1SDavid du Colombier case ABNE: 5033e12c5d1SDavid du Colombier case ABGTZ: 5043e12c5d1SDavid du Colombier case ABGEZ: 5053e12c5d1SDavid du Colombier case ABLTZ: 5063e12c5d1SDavid du Colombier case ABLEZ: 5073e12c5d1SDavid du Colombier 5083e12c5d1SDavid du Colombier case ACMPEQD: 5093e12c5d1SDavid du Colombier case ACMPEQF: 5103e12c5d1SDavid du Colombier case ACMPGED: 5113e12c5d1SDavid du Colombier case ACMPGEF: 5123e12c5d1SDavid du Colombier case ACMPGTD: 5133e12c5d1SDavid du Colombier case ACMPGTF: 5143e12c5d1SDavid du Colombier case ABFPF: 5153e12c5d1SDavid du Colombier case ABFPT: 5163e12c5d1SDavid du Colombier if(s != A) { 5173e12c5d1SDavid du Colombier if(copysub(&p->from, v, s, 1)) 5183e12c5d1SDavid du Colombier return 1; 5193e12c5d1SDavid du Colombier return copysub1(p, v, s, 1); 5203e12c5d1SDavid du Colombier } 5213e12c5d1SDavid du Colombier if(copyau(&p->from, v)) 5223e12c5d1SDavid du Colombier return 1; 5233e12c5d1SDavid du Colombier if(copyau1(p, v)) 5243e12c5d1SDavid du Colombier return 1; 5253e12c5d1SDavid du Colombier return 0; 5263e12c5d1SDavid du Colombier 5273e12c5d1SDavid du Colombier case AJMP: /* funny */ 5283e12c5d1SDavid du Colombier if(s != A) { 5293e12c5d1SDavid du Colombier if(copysub(&p->to, v, s, 1)) 5303e12c5d1SDavid du Colombier return 1; 5313e12c5d1SDavid du Colombier return 0; 5323e12c5d1SDavid du Colombier } 5333e12c5d1SDavid du Colombier if(copyau(&p->to, v)) 5343e12c5d1SDavid du Colombier return 1; 5353e12c5d1SDavid du Colombier return 0; 5363e12c5d1SDavid du Colombier 5373e12c5d1SDavid du Colombier case ARET: /* funny */ 5383e12c5d1SDavid du Colombier if(v->type == D_REG) 5393e12c5d1SDavid du Colombier if(v->reg == REGRET) 5403e12c5d1SDavid du Colombier return 2; 5413e12c5d1SDavid du Colombier if(v->type == D_FREG) 5423e12c5d1SDavid du Colombier if(v->reg == FREGRET) 5433e12c5d1SDavid du Colombier return 2; 5443e12c5d1SDavid du Colombier 5453e12c5d1SDavid du Colombier case AJAL: /* funny */ 5463e12c5d1SDavid du Colombier if(v->type == D_REG) { 5473e12c5d1SDavid du Colombier if(v->reg <= REGEXT && v->reg > exregoffset) 5483e12c5d1SDavid du Colombier return 2; 549*219b2ee8SDavid du Colombier if(REGARG && v->reg == REGARG) 5503e12c5d1SDavid du Colombier return 2; 5513e12c5d1SDavid du Colombier } 5523e12c5d1SDavid du Colombier if(v->type == D_FREG) 5533e12c5d1SDavid du Colombier if(v->reg <= FREGEXT && v->reg > exfregoffset) 5543e12c5d1SDavid du Colombier return 2; 5553e12c5d1SDavid du Colombier 5563e12c5d1SDavid du Colombier if(s != A) { 5573e12c5d1SDavid du Colombier if(copysub(&p->to, v, s, 1)) 5583e12c5d1SDavid du Colombier return 1; 5593e12c5d1SDavid du Colombier return 0; 5603e12c5d1SDavid du Colombier } 5613e12c5d1SDavid du Colombier if(copyau(&p->to, v)) 5623e12c5d1SDavid du Colombier return 4; 5633e12c5d1SDavid du Colombier return 3; 5643e12c5d1SDavid du Colombier 5653e12c5d1SDavid du Colombier case ATEXT: /* funny */ 5663e12c5d1SDavid du Colombier if(v->type == D_REG) 5673e12c5d1SDavid du Colombier if(v->reg == REGARG) 5683e12c5d1SDavid du Colombier return 3; 5693e12c5d1SDavid du Colombier return 0; 5703e12c5d1SDavid du Colombier } 5713e12c5d1SDavid du Colombier return 0; 5723e12c5d1SDavid du Colombier } 5733e12c5d1SDavid du Colombier 5743e12c5d1SDavid du Colombier int 5753e12c5d1SDavid du Colombier a2type(Prog *p) 5763e12c5d1SDavid du Colombier { 5773e12c5d1SDavid du Colombier 5783e12c5d1SDavid du Colombier switch(p->as) { 5793e12c5d1SDavid du Colombier case ABEQ: 5803e12c5d1SDavid du Colombier case ABNE: 5813e12c5d1SDavid du Colombier case ABGTZ: 5823e12c5d1SDavid du Colombier case ABGEZ: 5833e12c5d1SDavid du Colombier case ABLTZ: 5843e12c5d1SDavid du Colombier case ABLEZ: 5853e12c5d1SDavid du Colombier 5863e12c5d1SDavid du Colombier case ASGT: 5873e12c5d1SDavid du Colombier case ASGTU: 5883e12c5d1SDavid du Colombier 5893e12c5d1SDavid du Colombier case AADD: 5903e12c5d1SDavid du Colombier case AADDU: 5913e12c5d1SDavid du Colombier case ASUB: 5923e12c5d1SDavid du Colombier case ASUBU: 5933e12c5d1SDavid du Colombier case ASLL: 5943e12c5d1SDavid du Colombier case ASRL: 5953e12c5d1SDavid du Colombier case ASRA: 5963e12c5d1SDavid du Colombier case AOR: 5973e12c5d1SDavid du Colombier case AAND: 5983e12c5d1SDavid du Colombier case AXOR: 5993e12c5d1SDavid du Colombier case AMUL: 6003e12c5d1SDavid du Colombier case AMULU: 6013e12c5d1SDavid du Colombier case ADIV: 6023e12c5d1SDavid du Colombier case ADIVU: 6033e12c5d1SDavid du Colombier return D_REG; 6043e12c5d1SDavid du Colombier 6053e12c5d1SDavid du Colombier case ACMPEQD: 6063e12c5d1SDavid du Colombier case ACMPEQF: 6073e12c5d1SDavid du Colombier case ACMPGED: 6083e12c5d1SDavid du Colombier case ACMPGEF: 6093e12c5d1SDavid du Colombier case ACMPGTD: 6103e12c5d1SDavid du Colombier case ACMPGTF: 6113e12c5d1SDavid du Colombier 6123e12c5d1SDavid du Colombier case AADDF: 6133e12c5d1SDavid du Colombier case AADDD: 6143e12c5d1SDavid du Colombier case ASUBF: 6153e12c5d1SDavid du Colombier case ASUBD: 6163e12c5d1SDavid du Colombier case AMULF: 6173e12c5d1SDavid du Colombier case AMULD: 6183e12c5d1SDavid du Colombier case ADIVF: 6193e12c5d1SDavid du Colombier case ADIVD: 6203e12c5d1SDavid du Colombier return D_FREG; 6213e12c5d1SDavid du Colombier } 6223e12c5d1SDavid du Colombier return D_NONE; 6233e12c5d1SDavid du Colombier } 6243e12c5d1SDavid du Colombier 6253e12c5d1SDavid du Colombier /* 6263e12c5d1SDavid du Colombier * direct reference, 6273e12c5d1SDavid du Colombier * could be set/use depending on 6283e12c5d1SDavid du Colombier * semantics 6293e12c5d1SDavid du Colombier */ 6303e12c5d1SDavid du Colombier int 6313e12c5d1SDavid du Colombier copyas(Adr *a, Adr *v) 6323e12c5d1SDavid du Colombier { 6333e12c5d1SDavid du Colombier 6343e12c5d1SDavid du Colombier if(regtyp(v)) 6353e12c5d1SDavid du Colombier if(a->type == v->type) 6363e12c5d1SDavid du Colombier if(a->reg == v->reg) 6373e12c5d1SDavid du Colombier return 1; 6383e12c5d1SDavid du Colombier return 0; 6393e12c5d1SDavid du Colombier } 6403e12c5d1SDavid du Colombier 6413e12c5d1SDavid du Colombier /* 6423e12c5d1SDavid du Colombier * either direct or indirect 6433e12c5d1SDavid du Colombier */ 6443e12c5d1SDavid du Colombier int 6453e12c5d1SDavid du Colombier copyau(Adr *a, Adr *v) 6463e12c5d1SDavid du Colombier { 6473e12c5d1SDavid du Colombier 6483e12c5d1SDavid du Colombier if(copyas(a, v)) 6493e12c5d1SDavid du Colombier return 1; 6503e12c5d1SDavid du Colombier if(v->type == D_REG) 6513e12c5d1SDavid du Colombier if(a->type == D_OREG) 6523e12c5d1SDavid du Colombier if(v->reg == a->reg) 6533e12c5d1SDavid du Colombier return 1; 6543e12c5d1SDavid du Colombier return 0; 6553e12c5d1SDavid du Colombier } 6563e12c5d1SDavid du Colombier 6573e12c5d1SDavid du Colombier int 6583e12c5d1SDavid du Colombier copyau1(Prog *p, Adr *v) 6593e12c5d1SDavid du Colombier { 6603e12c5d1SDavid du Colombier 6613e12c5d1SDavid du Colombier if(regtyp(v)) 6623e12c5d1SDavid du Colombier if(p->from.type == v->type || p->to.type == v->type) 6633e12c5d1SDavid du Colombier if(p->reg == v->reg) { 6643e12c5d1SDavid du Colombier if(a2type(p) != v->type) 6653e12c5d1SDavid du Colombier print("botch a2type %P\n", p); 6663e12c5d1SDavid du Colombier return 1; 6673e12c5d1SDavid du Colombier } 6683e12c5d1SDavid du Colombier return 0; 6693e12c5d1SDavid du Colombier } 6703e12c5d1SDavid du Colombier 6713e12c5d1SDavid du Colombier /* 6723e12c5d1SDavid du Colombier * substitute s for v in a 6733e12c5d1SDavid du Colombier * return failure to substitute 6743e12c5d1SDavid du Colombier */ 6753e12c5d1SDavid du Colombier int 6763e12c5d1SDavid du Colombier copysub(Adr *a, Adr *v, Adr *s, int f) 6773e12c5d1SDavid du Colombier { 6783e12c5d1SDavid du Colombier 6793e12c5d1SDavid du Colombier if(f) 6803e12c5d1SDavid du Colombier if(copyau(a, v)) 6813e12c5d1SDavid du Colombier a->reg = s->reg; 6823e12c5d1SDavid du Colombier return 0; 6833e12c5d1SDavid du Colombier } 6843e12c5d1SDavid du Colombier 6853e12c5d1SDavid du Colombier int 6863e12c5d1SDavid du Colombier copysub1(Prog *p1, Adr *v, Adr *s, int f) 6873e12c5d1SDavid du Colombier { 6883e12c5d1SDavid du Colombier 6893e12c5d1SDavid du Colombier if(f) 6903e12c5d1SDavid du Colombier if(copyau1(p1, v)) 6913e12c5d1SDavid du Colombier p1->reg = s->reg; 6923e12c5d1SDavid du Colombier return 0; 6933e12c5d1SDavid du Colombier } 694