13e12c5d1SDavid du Colombier #include "gc.h" 23e12c5d1SDavid du Colombier 3da51d93aSDavid du Colombier static int 4da51d93aSDavid du Colombier needc(Prog *p) 5da51d93aSDavid du Colombier { 6da51d93aSDavid du Colombier while(p != P) { 7da51d93aSDavid du Colombier switch(p->as) { 8da51d93aSDavid du Colombier case AADCL: 9da51d93aSDavid du Colombier case ASBBL: 10375daca8SDavid du Colombier case ARCRL: 11da51d93aSDavid du Colombier return 1; 12da51d93aSDavid du Colombier case AADDL: 13da51d93aSDavid du Colombier case ASUBL: 14da51d93aSDavid du Colombier case AJMP: 15da51d93aSDavid du Colombier case ARET: 16da51d93aSDavid du Colombier case ACALL: 17da51d93aSDavid du Colombier return 0; 18da51d93aSDavid du Colombier default: 19da51d93aSDavid du Colombier if(p->to.type == D_BRANCH) 20da51d93aSDavid du Colombier return 0; 21da51d93aSDavid du Colombier } 22da51d93aSDavid du Colombier p = p->link; 23da51d93aSDavid du Colombier } 24da51d93aSDavid du Colombier return 0; 25da51d93aSDavid du Colombier } 26da51d93aSDavid du Colombier 273e12c5d1SDavid du Colombier void 283e12c5d1SDavid du Colombier peep(void) 293e12c5d1SDavid du Colombier { 303e12c5d1SDavid du Colombier Reg *r, *r1, *r2; 3180ee5cbfSDavid du Colombier Prog *p, *p1; 323e12c5d1SDavid du Colombier int t; 3380ee5cbfSDavid du Colombier 343e12c5d1SDavid du Colombier /* 353e12c5d1SDavid du Colombier * complete R structure 363e12c5d1SDavid du Colombier */ 373e12c5d1SDavid du Colombier t = 0; 383e12c5d1SDavid du Colombier for(r=firstr; r!=R; r=r1) { 393e12c5d1SDavid du Colombier r1 = r->link; 403e12c5d1SDavid du Colombier if(r1 == R) 413e12c5d1SDavid du Colombier break; 423e12c5d1SDavid du Colombier p = r->prog->link; 433e12c5d1SDavid du Colombier while(p != r1->prog) 443e12c5d1SDavid du Colombier switch(p->as) { 453e12c5d1SDavid du Colombier default: 463e12c5d1SDavid du Colombier r2 = rega(); 473e12c5d1SDavid du Colombier r->link = r2; 483e12c5d1SDavid du Colombier r2->link = r1; 493e12c5d1SDavid du Colombier 503e12c5d1SDavid du Colombier r2->prog = p; 513e12c5d1SDavid du Colombier r2->p1 = r; 523e12c5d1SDavid du Colombier r->s1 = r2; 533e12c5d1SDavid du Colombier r2->s1 = r1; 543e12c5d1SDavid du Colombier r1->p1 = r2; 553e12c5d1SDavid du Colombier 563e12c5d1SDavid du Colombier r = r2; 573e12c5d1SDavid du Colombier t++; 583e12c5d1SDavid du Colombier 593e12c5d1SDavid du Colombier case ADATA: 603e12c5d1SDavid du Colombier case AGLOBL: 613e12c5d1SDavid du Colombier case ANAME: 62375daca8SDavid du Colombier case ASIGNAME: 633e12c5d1SDavid du Colombier p = p->link; 643e12c5d1SDavid du Colombier } 653e12c5d1SDavid du Colombier } 663e12c5d1SDavid du Colombier 67375daca8SDavid du Colombier pc = 0; /* speculating it won't kill */ 68da51d93aSDavid du Colombier 693e12c5d1SDavid du Colombier loop1: 70da51d93aSDavid du Colombier if(debug['b']) 71da51d93aSDavid du Colombier comtarg(); 72da51d93aSDavid du Colombier 733e12c5d1SDavid du Colombier t = 0; 743e12c5d1SDavid du Colombier for(r=firstr; r!=R; r=r->link) { 753e12c5d1SDavid du Colombier p = r->prog; 7680ee5cbfSDavid du Colombier switch(p->as) { 7780ee5cbfSDavid du Colombier case AMOVL: 783e12c5d1SDavid du Colombier if(regtyp(&p->to)) 793e12c5d1SDavid du Colombier if(regtyp(&p->from)) { 803e12c5d1SDavid du Colombier if(copyprop(r)) { 813e12c5d1SDavid du Colombier excise(r); 823e12c5d1SDavid du Colombier t++; 833e12c5d1SDavid du Colombier } 843e12c5d1SDavid du Colombier if(subprop(r) && copyprop(r)) { 853e12c5d1SDavid du Colombier excise(r); 863e12c5d1SDavid du Colombier t++; 873e12c5d1SDavid du Colombier } 883e12c5d1SDavid du Colombier } 8980ee5cbfSDavid du Colombier break; 9080ee5cbfSDavid du Colombier 9180ee5cbfSDavid du Colombier case AMOVBLSX: 9280ee5cbfSDavid du Colombier case AMOVBLZX: 9380ee5cbfSDavid du Colombier case AMOVWLSX: 9480ee5cbfSDavid du Colombier case AMOVWLZX: 9580ee5cbfSDavid du Colombier if(regtyp(&p->to)) { 9680ee5cbfSDavid du Colombier r1 = uniqs(r); 9780ee5cbfSDavid du Colombier if(r1 != R) { 9880ee5cbfSDavid du Colombier p1 = r1->prog; 9980ee5cbfSDavid du Colombier if(p->as == p1->as && p->to.type == p1->from.type) 10080ee5cbfSDavid du Colombier p1->as = AMOVL; 10180ee5cbfSDavid du Colombier } 10280ee5cbfSDavid du Colombier } 10380ee5cbfSDavid du Colombier break; 104651dbb72SDavid du Colombier case AADDL: 105651dbb72SDavid du Colombier case AADDW: 106da51d93aSDavid du Colombier if(p->from.type != D_CONST || needc(p->link)) 107651dbb72SDavid du Colombier break; 108651dbb72SDavid du Colombier if(p->from.offset == -1){ 109651dbb72SDavid du Colombier if(p->as == AADDL) 110651dbb72SDavid du Colombier p->as = ADECL; 111651dbb72SDavid du Colombier else 112651dbb72SDavid du Colombier p->as = ADECW; 113651dbb72SDavid du Colombier p->from = zprog.from; 114651dbb72SDavid du Colombier } 115651dbb72SDavid du Colombier else if(p->from.offset == 1){ 116651dbb72SDavid du Colombier if(p->as == AADDL) 117651dbb72SDavid du Colombier p->as = AINCL; 118651dbb72SDavid du Colombier else 119651dbb72SDavid du Colombier p->as = AINCW; 120651dbb72SDavid du Colombier p->from = zprog.from; 121651dbb72SDavid du Colombier } 122651dbb72SDavid du Colombier break; 123651dbb72SDavid du Colombier case ASUBL: 124651dbb72SDavid du Colombier case ASUBW: 125da51d93aSDavid du Colombier if(p->from.type != D_CONST || needc(p->link)) 126651dbb72SDavid du Colombier break; 127651dbb72SDavid du Colombier if(p->from.offset == -1) { 128651dbb72SDavid du Colombier if(p->as == ASUBL) 129651dbb72SDavid du Colombier p->as = AINCL; 130651dbb72SDavid du Colombier else 131651dbb72SDavid du Colombier p->as = AINCW; 132651dbb72SDavid du Colombier p->from = zprog.from; 133651dbb72SDavid du Colombier } 134651dbb72SDavid du Colombier else if(p->from.offset == 1){ 135651dbb72SDavid du Colombier if(p->as == ASUBL) 136651dbb72SDavid du Colombier p->as = ADECL; 137651dbb72SDavid du Colombier else 138651dbb72SDavid du Colombier p->as = ADECW; 139651dbb72SDavid du Colombier p->from = zprog.from; 140651dbb72SDavid du Colombier } 141651dbb72SDavid du Colombier break; 14280ee5cbfSDavid du Colombier } 1433e12c5d1SDavid du Colombier } 1443e12c5d1SDavid du Colombier if(t) 1453e12c5d1SDavid du Colombier goto loop1; 1463e12c5d1SDavid du Colombier } 1473e12c5d1SDavid du Colombier 1483e12c5d1SDavid du Colombier void 1493e12c5d1SDavid du Colombier excise(Reg *r) 1503e12c5d1SDavid du Colombier { 1513e12c5d1SDavid du Colombier Prog *p; 1523e12c5d1SDavid du Colombier 1533e12c5d1SDavid du Colombier p = r->prog; 1543e12c5d1SDavid du Colombier p->as = ANOP; 1553e12c5d1SDavid du Colombier p->from = zprog.from; 1563e12c5d1SDavid du Colombier p->to = zprog.to; 1573e12c5d1SDavid du Colombier } 1583e12c5d1SDavid du Colombier 1593e12c5d1SDavid du Colombier Reg* 1603e12c5d1SDavid du Colombier uniqp(Reg *r) 1613e12c5d1SDavid du Colombier { 1623e12c5d1SDavid du Colombier Reg *r1; 1633e12c5d1SDavid du Colombier 1643e12c5d1SDavid du Colombier r1 = r->p1; 1653e12c5d1SDavid du Colombier if(r1 == R) { 1663e12c5d1SDavid du Colombier r1 = r->p2; 1673e12c5d1SDavid du Colombier if(r1 == R || r1->p2link != R) 1683e12c5d1SDavid du Colombier return R; 1693e12c5d1SDavid du Colombier } else 1703e12c5d1SDavid du Colombier if(r->p2 != R) 1713e12c5d1SDavid du Colombier return R; 1723e12c5d1SDavid du Colombier return r1; 1733e12c5d1SDavid du Colombier } 1743e12c5d1SDavid du Colombier 1753e12c5d1SDavid du Colombier Reg* 1763e12c5d1SDavid du Colombier uniqs(Reg *r) 1773e12c5d1SDavid du Colombier { 1783e12c5d1SDavid du Colombier Reg *r1; 1793e12c5d1SDavid du Colombier 1803e12c5d1SDavid du Colombier r1 = r->s1; 1813e12c5d1SDavid du Colombier if(r1 == R) { 1823e12c5d1SDavid du Colombier r1 = r->s2; 1833e12c5d1SDavid du Colombier if(r1 == R) 1843e12c5d1SDavid du Colombier return R; 1853e12c5d1SDavid du Colombier } else 1863e12c5d1SDavid du Colombier if(r->s2 != R) 1873e12c5d1SDavid du Colombier return R; 1883e12c5d1SDavid du Colombier return r1; 1893e12c5d1SDavid du Colombier } 1903e12c5d1SDavid du Colombier 1913e12c5d1SDavid du Colombier int 1923e12c5d1SDavid du Colombier regtyp(Adr *a) 1933e12c5d1SDavid du Colombier { 1943e12c5d1SDavid du Colombier int t; 1953e12c5d1SDavid du Colombier 1963e12c5d1SDavid du Colombier t = a->type; 1973e12c5d1SDavid du Colombier if(t >= D_AX && t <= D_DI) 1983e12c5d1SDavid du Colombier return 1; 1993e12c5d1SDavid du Colombier return 0; 2003e12c5d1SDavid du Colombier } 2013e12c5d1SDavid du Colombier 2023e12c5d1SDavid du Colombier /* 2033e12c5d1SDavid du Colombier * the idea is to substitute 2043e12c5d1SDavid du Colombier * one register for another 2053e12c5d1SDavid du Colombier * from one MOV to another 2063e12c5d1SDavid du Colombier * MOV a, R0 2073e12c5d1SDavid du Colombier * ADD b, R0 / no use of R1 2083e12c5d1SDavid du Colombier * MOV R0, R1 2093e12c5d1SDavid du Colombier * would be converted to 2103e12c5d1SDavid du Colombier * MOV a, R1 2113e12c5d1SDavid du Colombier * ADD b, R1 2123e12c5d1SDavid du Colombier * MOV R1, R0 2133e12c5d1SDavid du Colombier * hopefully, then the former or latter MOV 2143e12c5d1SDavid du Colombier * will be eliminated by copy propagation. 2153e12c5d1SDavid du Colombier */ 2163e12c5d1SDavid du Colombier int 2173e12c5d1SDavid du Colombier subprop(Reg *r0) 2183e12c5d1SDavid du Colombier { 2193e12c5d1SDavid du Colombier Prog *p; 2203e12c5d1SDavid du Colombier Adr *v1, *v2; 2213e12c5d1SDavid du Colombier Reg *r; 2223e12c5d1SDavid du Colombier int t; 2233e12c5d1SDavid du Colombier 2243e12c5d1SDavid du Colombier p = r0->prog; 2253e12c5d1SDavid du Colombier v1 = &p->from; 2263e12c5d1SDavid du Colombier if(!regtyp(v1)) 2273e12c5d1SDavid du Colombier return 0; 2283e12c5d1SDavid du Colombier v2 = &p->to; 2293e12c5d1SDavid du Colombier if(!regtyp(v2)) 2303e12c5d1SDavid du Colombier return 0; 2313e12c5d1SDavid du Colombier for(r=uniqp(r0); r!=R; r=uniqp(r)) { 2323e12c5d1SDavid du Colombier if(uniqs(r) == R) 2333e12c5d1SDavid du Colombier break; 2343e12c5d1SDavid du Colombier p = r->prog; 2353e12c5d1SDavid du Colombier switch(p->as) { 2363e12c5d1SDavid du Colombier case ACALL: 2373e12c5d1SDavid du Colombier return 0; 2383e12c5d1SDavid du Colombier 2399a747e4fSDavid du Colombier case AIMULL: 2409a747e4fSDavid du Colombier case AIMULW: 2419a747e4fSDavid du Colombier if(p->to.type != D_NONE) 2429a747e4fSDavid du Colombier break; 2439a747e4fSDavid du Colombier 2443e12c5d1SDavid du Colombier case ADIVB: 2453e12c5d1SDavid du Colombier case ADIVL: 2463e12c5d1SDavid du Colombier case ADIVW: 2473e12c5d1SDavid du Colombier case AIDIVB: 2483e12c5d1SDavid du Colombier case AIDIVL: 2493e12c5d1SDavid du Colombier case AIDIVW: 2503e12c5d1SDavid du Colombier case AIMULB: 2513e12c5d1SDavid du Colombier case AMULB: 2523e12c5d1SDavid du Colombier case AMULL: 2533e12c5d1SDavid du Colombier case AMULW: 2543e12c5d1SDavid du Colombier 2557dd7cddfSDavid du Colombier case AROLB: 2567dd7cddfSDavid du Colombier case AROLL: 2577dd7cddfSDavid du Colombier case AROLW: 2587dd7cddfSDavid du Colombier case ARORB: 2597dd7cddfSDavid du Colombier case ARORL: 2607dd7cddfSDavid du Colombier case ARORW: 2617dd7cddfSDavid du Colombier case ASALB: 2627dd7cddfSDavid du Colombier case ASALL: 2637dd7cddfSDavid du Colombier case ASALW: 2647dd7cddfSDavid du Colombier case ASARB: 2657dd7cddfSDavid du Colombier case ASARL: 2667dd7cddfSDavid du Colombier case ASARW: 267219b2ee8SDavid du Colombier case ASHLB: 268219b2ee8SDavid du Colombier case ASHLL: 269219b2ee8SDavid du Colombier case ASHLW: 270219b2ee8SDavid du Colombier case ASHRB: 271219b2ee8SDavid du Colombier case ASHRL: 272219b2ee8SDavid du Colombier case ASHRW: 273219b2ee8SDavid du Colombier 2743e12c5d1SDavid du Colombier case AREP: 2753e12c5d1SDavid du Colombier case AREPN: 2763e12c5d1SDavid du Colombier 2773e12c5d1SDavid du Colombier case ACWD: 2783e12c5d1SDavid du Colombier case ACDQ: 2793e12c5d1SDavid du Colombier 2803e12c5d1SDavid du Colombier case AMOVSL: 2813e12c5d1SDavid du Colombier case AFSTSW: 2823e12c5d1SDavid du Colombier return 0; 2833e12c5d1SDavid du Colombier 2843e12c5d1SDavid du Colombier case AMOVL: 2853e12c5d1SDavid du Colombier if(p->to.type == v1->type) 2863e12c5d1SDavid du Colombier goto gotit; 2873e12c5d1SDavid du Colombier break; 2883e12c5d1SDavid du Colombier } 2893e12c5d1SDavid du Colombier if(copyau(&p->from, v2) || 2903e12c5d1SDavid du Colombier copyau(&p->to, v2)) 2913e12c5d1SDavid du Colombier break; 2923e12c5d1SDavid du Colombier if(copysub(&p->from, v1, v2, 0) || 2933e12c5d1SDavid du Colombier copysub(&p->to, v1, v2, 0)) 2943e12c5d1SDavid du Colombier break; 2953e12c5d1SDavid du Colombier } 2963e12c5d1SDavid du Colombier return 0; 2973e12c5d1SDavid du Colombier 2983e12c5d1SDavid du Colombier gotit: 2993e12c5d1SDavid du Colombier copysub(&p->to, v1, v2, 1); 3003e12c5d1SDavid du Colombier if(debug['P']) { 3013e12c5d1SDavid du Colombier print("gotit: %D->%D\n%P", v1, v2, r->prog); 3023e12c5d1SDavid du Colombier if(p->from.type == v2->type) 3033e12c5d1SDavid du Colombier print(" excise"); 3043e12c5d1SDavid du Colombier print("\n"); 3053e12c5d1SDavid du Colombier } 3063e12c5d1SDavid du Colombier for(r=uniqs(r); r!=r0; r=uniqs(r)) { 3073e12c5d1SDavid du Colombier p = r->prog; 3083e12c5d1SDavid du Colombier copysub(&p->from, v1, v2, 1); 3093e12c5d1SDavid du Colombier copysub(&p->to, v1, v2, 1); 3103e12c5d1SDavid du Colombier if(debug['P']) 3113e12c5d1SDavid du Colombier print("%P\n", r->prog); 3123e12c5d1SDavid du Colombier } 3133e12c5d1SDavid du Colombier t = v1->type; 3143e12c5d1SDavid du Colombier v1->type = v2->type; 3153e12c5d1SDavid du Colombier v2->type = t; 3163e12c5d1SDavid du Colombier if(debug['P']) 3173e12c5d1SDavid du Colombier print("%P last\n", r->prog); 3183e12c5d1SDavid du Colombier return 1; 3193e12c5d1SDavid du Colombier } 3203e12c5d1SDavid du Colombier 3213e12c5d1SDavid du Colombier /* 3223e12c5d1SDavid du Colombier * The idea is to remove redundant copies. 3233e12c5d1SDavid du Colombier * v1->v2 F=0 3243e12c5d1SDavid du Colombier * (use v2 s/v2/v1/)* 3253e12c5d1SDavid du Colombier * set v1 F=1 3263e12c5d1SDavid du Colombier * use v2 return fail 3273e12c5d1SDavid du Colombier * ----------------- 3283e12c5d1SDavid du Colombier * v1->v2 F=0 3293e12c5d1SDavid du Colombier * (use v2 s/v2/v1/)* 3303e12c5d1SDavid du Colombier * set v1 F=1 3313e12c5d1SDavid du Colombier * set v2 return success 3323e12c5d1SDavid du Colombier */ 3333e12c5d1SDavid du Colombier int 3343e12c5d1SDavid du Colombier copyprop(Reg *r0) 3353e12c5d1SDavid du Colombier { 3363e12c5d1SDavid du Colombier Prog *p; 3373e12c5d1SDavid du Colombier Adr *v1, *v2; 3383e12c5d1SDavid du Colombier Reg *r; 3393e12c5d1SDavid du Colombier 3403e12c5d1SDavid du Colombier p = r0->prog; 3413e12c5d1SDavid du Colombier v1 = &p->from; 3423e12c5d1SDavid du Colombier v2 = &p->to; 3433e12c5d1SDavid du Colombier if(copyas(v1, v2)) 3443e12c5d1SDavid du Colombier return 1; 3453e12c5d1SDavid du Colombier for(r=firstr; r!=R; r=r->link) 3463e12c5d1SDavid du Colombier r->active = 0; 3473e12c5d1SDavid du Colombier return copy1(v1, v2, r0->s1, 0); 3483e12c5d1SDavid du Colombier } 3493e12c5d1SDavid du Colombier 3503e12c5d1SDavid du Colombier int 3513e12c5d1SDavid du Colombier copy1(Adr *v1, Adr *v2, Reg *r, int f) 3523e12c5d1SDavid du Colombier { 3533e12c5d1SDavid du Colombier int t; 3543e12c5d1SDavid du Colombier Prog *p; 3553e12c5d1SDavid du Colombier 3563e12c5d1SDavid du Colombier if(r->active) { 3573e12c5d1SDavid du Colombier if(debug['P']) 3583e12c5d1SDavid du Colombier print("act set; return 1\n"); 3593e12c5d1SDavid du Colombier return 1; 3603e12c5d1SDavid du Colombier } 3613e12c5d1SDavid du Colombier r->active = 1; 3623e12c5d1SDavid du Colombier if(debug['P']) 3633e12c5d1SDavid du Colombier print("copy %D->%D f=%d\n", v1, v2, f); 3643e12c5d1SDavid du Colombier for(; r != R; r = r->s1) { 3653e12c5d1SDavid du Colombier p = r->prog; 3663e12c5d1SDavid du Colombier if(debug['P']) 3673e12c5d1SDavid du Colombier print("%P", p); 3683e12c5d1SDavid du Colombier if(!f && uniqp(r) == R) { 3693e12c5d1SDavid du Colombier f = 1; 3703e12c5d1SDavid du Colombier if(debug['P']) 3713e12c5d1SDavid du Colombier print("; merge; f=%d", f); 3723e12c5d1SDavid du Colombier } 3733e12c5d1SDavid du Colombier t = copyu(p, v2, A); 3743e12c5d1SDavid du Colombier switch(t) { 3753e12c5d1SDavid du Colombier case 2: /* rar, cant split */ 3763e12c5d1SDavid du Colombier if(debug['P']) 3773e12c5d1SDavid du Colombier print("; %D rar; return 0\n", v2); 3783e12c5d1SDavid du Colombier return 0; 3793e12c5d1SDavid du Colombier 3803e12c5d1SDavid du Colombier case 3: /* set */ 3813e12c5d1SDavid du Colombier if(debug['P']) 3823e12c5d1SDavid du Colombier print("; %D set; return 1\n", v2); 3833e12c5d1SDavid du Colombier return 1; 3843e12c5d1SDavid du Colombier 3853e12c5d1SDavid du Colombier case 1: /* used, substitute */ 3863e12c5d1SDavid du Colombier case 4: /* use and set */ 3873e12c5d1SDavid du Colombier if(f) { 3883e12c5d1SDavid du Colombier if(!debug['P']) 3893e12c5d1SDavid du Colombier return 0; 3903e12c5d1SDavid du Colombier if(t == 4) 3913e12c5d1SDavid du Colombier print("; %D used+set and f=%d; return 0\n", v2, f); 3923e12c5d1SDavid du Colombier else 3933e12c5d1SDavid du Colombier print("; %D used and f=%d; return 0\n", v2, f); 3943e12c5d1SDavid du Colombier return 0; 3953e12c5d1SDavid du Colombier } 3963e12c5d1SDavid du Colombier if(copyu(p, v2, v1)) { 3973e12c5d1SDavid du Colombier if(debug['P']) 3983e12c5d1SDavid du Colombier print("; sub fail; return 0\n"); 3993e12c5d1SDavid du Colombier return 0; 4003e12c5d1SDavid du Colombier } 4013e12c5d1SDavid du Colombier if(debug['P']) 4023e12c5d1SDavid du Colombier print("; sub %D/%D", v2, v1); 4033e12c5d1SDavid du Colombier if(t == 4) { 4043e12c5d1SDavid du Colombier if(debug['P']) 4053e12c5d1SDavid du Colombier print("; %D used+set; return 1\n", v2); 4063e12c5d1SDavid du Colombier return 1; 4073e12c5d1SDavid du Colombier } 4083e12c5d1SDavid du Colombier break; 4093e12c5d1SDavid du Colombier } 4103e12c5d1SDavid du Colombier if(!f) { 4113e12c5d1SDavid du Colombier t = copyu(p, v1, A); 4123e12c5d1SDavid du Colombier if(!f && (t == 2 || t == 3 || t == 4)) { 4133e12c5d1SDavid du Colombier f = 1; 4143e12c5d1SDavid du Colombier if(debug['P']) 4153e12c5d1SDavid du Colombier print("; %D set and !f; f=%d", v1, f); 4163e12c5d1SDavid du Colombier } 4173e12c5d1SDavid du Colombier } 4183e12c5d1SDavid du Colombier if(debug['P']) 4193e12c5d1SDavid du Colombier print("\n"); 4203e12c5d1SDavid du Colombier if(r->s2) 4213e12c5d1SDavid du Colombier if(!copy1(v1, v2, r->s2, f)) 4223e12c5d1SDavid du Colombier return 0; 4233e12c5d1SDavid du Colombier } 4243e12c5d1SDavid du Colombier return 1; 4253e12c5d1SDavid du Colombier } 4263e12c5d1SDavid du Colombier 4273e12c5d1SDavid du Colombier /* 4283e12c5d1SDavid du Colombier * return 4293e12c5d1SDavid du Colombier * 1 if v only used (and substitute), 4303e12c5d1SDavid du Colombier * 2 if read-alter-rewrite 4313e12c5d1SDavid du Colombier * 3 if set 4323e12c5d1SDavid du Colombier * 4 if set and used 4333e12c5d1SDavid du Colombier * 0 otherwise (not touched) 4343e12c5d1SDavid du Colombier */ 435219b2ee8SDavid du Colombier int 4363e12c5d1SDavid du Colombier copyu(Prog *p, Adr *v, Adr *s) 4373e12c5d1SDavid du Colombier { 4383e12c5d1SDavid du Colombier 4393e12c5d1SDavid du Colombier switch(p->as) { 4403e12c5d1SDavid du Colombier 4413e12c5d1SDavid du Colombier default: 4423e12c5d1SDavid du Colombier if(debug['P']) 4433e12c5d1SDavid du Colombier print("unknown op %A\n", p->as); 4443e12c5d1SDavid du Colombier return 2; 4453e12c5d1SDavid du Colombier 446da51d93aSDavid du Colombier case ANEGB: 447da51d93aSDavid du Colombier case ANEGW: 448da51d93aSDavid du Colombier case ANEGL: 449da51d93aSDavid du Colombier case ANOTB: 450da51d93aSDavid du Colombier case ANOTW: 451da51d93aSDavid du Colombier case ANOTL: 452da51d93aSDavid du Colombier if(copyas(&p->to, v)) 453da51d93aSDavid du Colombier return 2; 454da51d93aSDavid du Colombier break; 455da51d93aSDavid du Colombier 4563e12c5d1SDavid du Colombier case ALEAL: /* lhs addr, rhs store */ 4573e12c5d1SDavid du Colombier if(copyas(&p->from, v)) 4583e12c5d1SDavid du Colombier return 2; 4593e12c5d1SDavid du Colombier 4603e12c5d1SDavid du Colombier 4613e12c5d1SDavid du Colombier case ANOP: /* rhs store */ 4623e12c5d1SDavid du Colombier case AMOVL: 4633e12c5d1SDavid du Colombier case AMOVBLSX: 4643e12c5d1SDavid du Colombier case AMOVBLZX: 4653e12c5d1SDavid du Colombier case AMOVWLSX: 4663e12c5d1SDavid du Colombier case AMOVWLZX: 4673e12c5d1SDavid du Colombier if(copyas(&p->to, v)) { 4683e12c5d1SDavid du Colombier if(s != A) 4693e12c5d1SDavid du Colombier return copysub(&p->from, v, s, 1); 4703e12c5d1SDavid du Colombier if(copyau(&p->from, v)) 4713e12c5d1SDavid du Colombier return 4; 4723e12c5d1SDavid du Colombier return 3; 4733e12c5d1SDavid du Colombier } 4743e12c5d1SDavid du Colombier goto caseread; 4753e12c5d1SDavid du Colombier 4763e12c5d1SDavid du Colombier case AROLB: 4773e12c5d1SDavid du Colombier case AROLL: 4783e12c5d1SDavid du Colombier case AROLW: 4793e12c5d1SDavid du Colombier case ARORB: 4803e12c5d1SDavid du Colombier case ARORL: 4813e12c5d1SDavid du Colombier case ARORW: 4823e12c5d1SDavid du Colombier case ASALB: 4833e12c5d1SDavid du Colombier case ASALL: 4843e12c5d1SDavid du Colombier case ASALW: 4853e12c5d1SDavid du Colombier case ASARB: 4863e12c5d1SDavid du Colombier case ASARL: 4873e12c5d1SDavid du Colombier case ASARW: 4883e12c5d1SDavid du Colombier case ASHLB: 4893e12c5d1SDavid du Colombier case ASHLL: 4903e12c5d1SDavid du Colombier case ASHLW: 4913e12c5d1SDavid du Colombier case ASHRB: 4923e12c5d1SDavid du Colombier case ASHRL: 4933e12c5d1SDavid du Colombier case ASHRW: 4943e12c5d1SDavid du Colombier if(copyas(&p->to, v)) 4953e12c5d1SDavid du Colombier return 2; 4963e12c5d1SDavid du Colombier if(copyas(&p->from, v)) 4973e12c5d1SDavid du Colombier if(p->from.type == D_CX) 4983e12c5d1SDavid du Colombier return 2; 4993e12c5d1SDavid du Colombier goto caseread; 5003e12c5d1SDavid du Colombier 5013e12c5d1SDavid du Colombier case AADDB: /* rhs rar */ 5023e12c5d1SDavid du Colombier case AADDL: 5033e12c5d1SDavid du Colombier case AADDW: 5043e12c5d1SDavid du Colombier case AANDB: 5053e12c5d1SDavid du Colombier case AANDL: 5063e12c5d1SDavid du Colombier case AANDW: 507651dbb72SDavid du Colombier case ADECL: 508651dbb72SDavid du Colombier case ADECW: 509651dbb72SDavid du Colombier case AINCL: 510651dbb72SDavid du Colombier case AINCW: 5113e12c5d1SDavid du Colombier case ASUBB: 5123e12c5d1SDavid du Colombier case ASUBL: 5133e12c5d1SDavid du Colombier case ASUBW: 5143e12c5d1SDavid du Colombier case AORB: 5153e12c5d1SDavid du Colombier case AORL: 5163e12c5d1SDavid du Colombier case AORW: 5173e12c5d1SDavid du Colombier case AXORB: 5183e12c5d1SDavid du Colombier case AXORL: 5193e12c5d1SDavid du Colombier case AXORW: 5203e12c5d1SDavid du Colombier case AMOVB: 5213e12c5d1SDavid du Colombier case AMOVW: 5223e12c5d1SDavid du Colombier 5233e12c5d1SDavid du Colombier case AFMOVB: 5243e12c5d1SDavid du Colombier case AFMOVBP: 5253e12c5d1SDavid du Colombier case AFMOVD: 5263e12c5d1SDavid du Colombier case AFMOVDP: 5273e12c5d1SDavid du Colombier case AFMOVF: 5283e12c5d1SDavid du Colombier case AFMOVFP: 5293e12c5d1SDavid du Colombier case AFMOVL: 5303e12c5d1SDavid du Colombier case AFMOVLP: 5313e12c5d1SDavid du Colombier case AFMOVV: 5323e12c5d1SDavid du Colombier case AFMOVVP: 5333e12c5d1SDavid du Colombier case AFMOVW: 5343e12c5d1SDavid du Colombier case AFMOVWP: 5353e12c5d1SDavid du Colombier case AFMOVX: 5363e12c5d1SDavid du Colombier case AFMOVXP: 5373e12c5d1SDavid du Colombier case AFADDDP: 5383e12c5d1SDavid du Colombier case AFADDW: 5393e12c5d1SDavid du Colombier case AFADDL: 5403e12c5d1SDavid du Colombier case AFADDF: 5413e12c5d1SDavid du Colombier case AFADDD: 5423e12c5d1SDavid du Colombier case AFMULDP: 5433e12c5d1SDavid du Colombier case AFMULW: 5443e12c5d1SDavid du Colombier case AFMULL: 5453e12c5d1SDavid du Colombier case AFMULF: 5463e12c5d1SDavid du Colombier case AFMULD: 5473e12c5d1SDavid du Colombier case AFSUBDP: 5483e12c5d1SDavid du Colombier case AFSUBW: 5493e12c5d1SDavid du Colombier case AFSUBL: 5503e12c5d1SDavid du Colombier case AFSUBF: 5513e12c5d1SDavid du Colombier case AFSUBD: 5523e12c5d1SDavid du Colombier case AFSUBRDP: 5533e12c5d1SDavid du Colombier case AFSUBRW: 5543e12c5d1SDavid du Colombier case AFSUBRL: 5553e12c5d1SDavid du Colombier case AFSUBRF: 5563e12c5d1SDavid du Colombier case AFSUBRD: 5573e12c5d1SDavid du Colombier case AFDIVDP: 5583e12c5d1SDavid du Colombier case AFDIVW: 5593e12c5d1SDavid du Colombier case AFDIVL: 5603e12c5d1SDavid du Colombier case AFDIVF: 5613e12c5d1SDavid du Colombier case AFDIVD: 5623e12c5d1SDavid du Colombier case AFDIVRDP: 5633e12c5d1SDavid du Colombier case AFDIVRW: 5643e12c5d1SDavid du Colombier case AFDIVRL: 5653e12c5d1SDavid du Colombier case AFDIVRF: 5663e12c5d1SDavid du Colombier case AFDIVRD: 5673e12c5d1SDavid du Colombier if(copyas(&p->to, v)) 5683e12c5d1SDavid du Colombier return 2; 5693e12c5d1SDavid du Colombier goto caseread; 5703e12c5d1SDavid du Colombier 5713e12c5d1SDavid du Colombier case ACMPL: /* read only */ 5723e12c5d1SDavid du Colombier case ACMPW: 5733e12c5d1SDavid du Colombier case ACMPB: 5743e12c5d1SDavid du Colombier 5753e12c5d1SDavid du Colombier case AFCOMB: 5763e12c5d1SDavid du Colombier case AFCOMBP: 5773e12c5d1SDavid du Colombier case AFCOMD: 5783e12c5d1SDavid du Colombier case AFCOMDP: 5793e12c5d1SDavid du Colombier case AFCOMDPP: 5803e12c5d1SDavid du Colombier case AFCOMF: 5813e12c5d1SDavid du Colombier case AFCOMFP: 5823e12c5d1SDavid du Colombier case AFCOML: 5833e12c5d1SDavid du Colombier case AFCOMLP: 5843e12c5d1SDavid du Colombier case AFCOMW: 5853e12c5d1SDavid du Colombier case AFCOMWP: 5863e12c5d1SDavid du Colombier case AFUCOM: 5873e12c5d1SDavid du Colombier case AFUCOMP: 5883e12c5d1SDavid du Colombier case AFUCOMPP: 5893e12c5d1SDavid du Colombier caseread: 5903e12c5d1SDavid du Colombier if(s != A) { 5913e12c5d1SDavid du Colombier if(copysub(&p->from, v, s, 1)) 5923e12c5d1SDavid du Colombier return 1; 5933e12c5d1SDavid du Colombier return copysub(&p->to, v, s, 1); 5943e12c5d1SDavid du Colombier } 5953e12c5d1SDavid du Colombier if(copyau(&p->from, v)) 5963e12c5d1SDavid du Colombier return 1; 5973e12c5d1SDavid du Colombier if(copyau(&p->to, v)) 5983e12c5d1SDavid du Colombier return 1; 5993e12c5d1SDavid du Colombier break; 6003e12c5d1SDavid du Colombier 6013e12c5d1SDavid du Colombier case AJGE: /* no reference */ 6023e12c5d1SDavid du Colombier case AJNE: 6033e12c5d1SDavid du Colombier case AJLE: 6043e12c5d1SDavid du Colombier case AJEQ: 6053e12c5d1SDavid du Colombier case AJHI: 6063e12c5d1SDavid du Colombier case AJLS: 6073e12c5d1SDavid du Colombier case AJMI: 6083e12c5d1SDavid du Colombier case AJPL: 6093e12c5d1SDavid du Colombier case AJGT: 6103e12c5d1SDavid du Colombier case AJLT: 6113e12c5d1SDavid du Colombier case AJCC: 6123e12c5d1SDavid du Colombier case AJCS: 6133e12c5d1SDavid du Colombier 6143e12c5d1SDavid du Colombier case AADJSP: 6153e12c5d1SDavid du Colombier case AFLDZ: 6163e12c5d1SDavid du Colombier case AWAIT: 6173e12c5d1SDavid du Colombier break; 6183e12c5d1SDavid du Colombier 6199a747e4fSDavid du Colombier case AIMULL: 6209a747e4fSDavid du Colombier case AIMULW: 6219a747e4fSDavid du Colombier if(p->to.type != D_NONE) { 6229a747e4fSDavid du Colombier if(copyas(&p->to, v)) 6239a747e4fSDavid du Colombier return 2; 6249a747e4fSDavid du Colombier goto caseread; 6259a747e4fSDavid du Colombier } 6269a747e4fSDavid du Colombier 6273e12c5d1SDavid du Colombier case ADIVB: 6283e12c5d1SDavid du Colombier case ADIVL: 6293e12c5d1SDavid du Colombier case ADIVW: 6303e12c5d1SDavid du Colombier case AIDIVB: 6313e12c5d1SDavid du Colombier case AIDIVL: 6323e12c5d1SDavid du Colombier case AIDIVW: 6333e12c5d1SDavid du Colombier case AIMULB: 6343e12c5d1SDavid du Colombier case AMULB: 6353e12c5d1SDavid du Colombier case AMULL: 6363e12c5d1SDavid du Colombier case AMULW: 6373e12c5d1SDavid du Colombier 6383e12c5d1SDavid du Colombier case ACWD: 6393e12c5d1SDavid du Colombier case ACDQ: 640219b2ee8SDavid du Colombier if(v->type == D_AX || v->type == D_DX) 641219b2ee8SDavid du Colombier return 2; 642219b2ee8SDavid du Colombier goto caseread; 6433e12c5d1SDavid du Colombier 6443e12c5d1SDavid du Colombier case AMOVSL: 645219b2ee8SDavid du Colombier case AREP: 646219b2ee8SDavid du Colombier case AREPN: 647219b2ee8SDavid du Colombier if(v->type == D_CX || v->type == D_DI || v->type == D_SI) 6483e12c5d1SDavid du Colombier return 2; 649219b2ee8SDavid du Colombier goto caseread; 650219b2ee8SDavid du Colombier 651219b2ee8SDavid du Colombier case AFSTSW: 652219b2ee8SDavid du Colombier if(v->type == D_AX) 6533e12c5d1SDavid du Colombier return 2; 6543e12c5d1SDavid du Colombier goto caseread; 6553e12c5d1SDavid du Colombier 6563e12c5d1SDavid du Colombier case AJMP: /* funny */ 6573e12c5d1SDavid du Colombier if(s != A) { 6583e12c5d1SDavid du Colombier if(copysub(&p->to, v, s, 1)) 6593e12c5d1SDavid du Colombier return 1; 6603e12c5d1SDavid du Colombier return 0; 6613e12c5d1SDavid du Colombier } 6623e12c5d1SDavid du Colombier if(copyau(&p->to, v)) 6633e12c5d1SDavid du Colombier return 1; 6643e12c5d1SDavid du Colombier return 0; 6653e12c5d1SDavid du Colombier 6663e12c5d1SDavid du Colombier case ARET: /* funny */ 6673e12c5d1SDavid du Colombier if(v->type == REGRET) 6683e12c5d1SDavid du Colombier return 2; 669219b2ee8SDavid du Colombier if(s != A) 670219b2ee8SDavid du Colombier return 1; 671219b2ee8SDavid du Colombier return 3; 6723e12c5d1SDavid du Colombier 6733e12c5d1SDavid du Colombier case ACALL: /* funny */ 674*4ac975e2SDavid du Colombier if(REGARG>=0 && v->type == REGARG) 6753e12c5d1SDavid du Colombier return 2; 6763e12c5d1SDavid du Colombier 6773e12c5d1SDavid du Colombier if(s != A) { 6783e12c5d1SDavid du Colombier if(copysub(&p->to, v, s, 1)) 6793e12c5d1SDavid du Colombier return 1; 6803e12c5d1SDavid du Colombier return 0; 6813e12c5d1SDavid du Colombier } 6823e12c5d1SDavid du Colombier if(copyau(&p->to, v)) 6833e12c5d1SDavid du Colombier return 4; 6843e12c5d1SDavid du Colombier return 3; 6853e12c5d1SDavid du Colombier } 6863e12c5d1SDavid du Colombier return 0; 6873e12c5d1SDavid du Colombier } 6883e12c5d1SDavid du Colombier 6893e12c5d1SDavid du Colombier /* 6903e12c5d1SDavid du Colombier * direct reference, 6913e12c5d1SDavid du Colombier * could be set/use depending on 6923e12c5d1SDavid du Colombier * semantics 6933e12c5d1SDavid du Colombier */ 6943e12c5d1SDavid du Colombier int 6953e12c5d1SDavid du Colombier copyas(Adr *a, Adr *v) 6963e12c5d1SDavid du Colombier { 6973e12c5d1SDavid du Colombier if(a->type != v->type) 6983e12c5d1SDavid du Colombier return 0; 6993e12c5d1SDavid du Colombier if(regtyp(v)) 7003e12c5d1SDavid du Colombier return 1; 7013e12c5d1SDavid du Colombier if(v->type == D_AUTO || v->type == D_PARAM) 7023e12c5d1SDavid du Colombier if(v->offset == a->offset) 7033e12c5d1SDavid du Colombier return 1; 7043e12c5d1SDavid du Colombier return 0; 7053e12c5d1SDavid du Colombier } 7063e12c5d1SDavid du Colombier 7073e12c5d1SDavid du Colombier /* 7083e12c5d1SDavid du Colombier * either direct or indirect 7093e12c5d1SDavid du Colombier */ 7103e12c5d1SDavid du Colombier int 7113e12c5d1SDavid du Colombier copyau(Adr *a, Adr *v) 7123e12c5d1SDavid du Colombier { 7133e12c5d1SDavid du Colombier 7143e12c5d1SDavid du Colombier if(copyas(a, v)) 7153e12c5d1SDavid du Colombier return 1; 7163e12c5d1SDavid du Colombier if(regtyp(v)) { 7173e12c5d1SDavid du Colombier if(a->type-D_INDIR == v->type) 7183e12c5d1SDavid du Colombier return 1; 7193e12c5d1SDavid du Colombier if(a->index == v->type) 7203e12c5d1SDavid du Colombier return 1; 7213e12c5d1SDavid du Colombier } 7223e12c5d1SDavid du Colombier return 0; 7233e12c5d1SDavid du Colombier } 7243e12c5d1SDavid du Colombier 7253e12c5d1SDavid du Colombier /* 7263e12c5d1SDavid du Colombier * substitute s for v in a 7273e12c5d1SDavid du Colombier * return failure to substitute 7283e12c5d1SDavid du Colombier */ 7293e12c5d1SDavid du Colombier int 7303e12c5d1SDavid du Colombier copysub(Adr *a, Adr *v, Adr *s, int f) 7313e12c5d1SDavid du Colombier { 7323e12c5d1SDavid du Colombier int t; 733219b2ee8SDavid du Colombier 7343e12c5d1SDavid du Colombier if(copyas(a, v)) { 7353e12c5d1SDavid du Colombier t = s->type; 7363e12c5d1SDavid du Colombier if(t >= D_AX && t <= D_DI) { 7373e12c5d1SDavid du Colombier if(f) 7383e12c5d1SDavid du Colombier a->type = t; 7393e12c5d1SDavid du Colombier } 7403e12c5d1SDavid du Colombier return 0; 7413e12c5d1SDavid du Colombier } 7423e12c5d1SDavid du Colombier if(regtyp(v)) { 7433e12c5d1SDavid du Colombier t = v->type; 7443e12c5d1SDavid du Colombier if(a->type == t+D_INDIR) { 74580ee5cbfSDavid du Colombier if(s->type == D_BP && a->index != D_NONE) 746375daca8SDavid du Colombier return 1; /* can't use BP-base with index */ 7473e12c5d1SDavid du Colombier if(f) 7483e12c5d1SDavid du Colombier a->type = s->type+D_INDIR; 749375daca8SDavid du Colombier // return 0; 7503e12c5d1SDavid du Colombier } 7513e12c5d1SDavid du Colombier if(a->index == t) { 7523e12c5d1SDavid du Colombier if(f) 7533e12c5d1SDavid du Colombier a->index = s->type; 7543e12c5d1SDavid du Colombier return 0; 7553e12c5d1SDavid du Colombier } 7563e12c5d1SDavid du Colombier return 0; 7573e12c5d1SDavid du Colombier } 7583e12c5d1SDavid du Colombier return 0; 7593e12c5d1SDavid du Colombier } 760