13e12c5d1SDavid du Colombier #include "gc.h" 23e12c5d1SDavid du Colombier 33e12c5d1SDavid du Colombier void 43e12c5d1SDavid du Colombier codgen(Node *n, Node *nn) 53e12c5d1SDavid du Colombier { 63e12c5d1SDavid du Colombier Prog *sp; 73e12c5d1SDavid du Colombier Node *n1, nod, nod1; 83e12c5d1SDavid du Colombier 93e12c5d1SDavid du Colombier cursafe = 0; 103e12c5d1SDavid du Colombier curarg = 0; 113e12c5d1SDavid du Colombier maxargsafe = 0; 123e12c5d1SDavid du Colombier 133e12c5d1SDavid du Colombier /* 143e12c5d1SDavid du Colombier * isolate name 153e12c5d1SDavid du Colombier */ 163e12c5d1SDavid du Colombier for(n1 = nn;; n1 = n1->left) { 173e12c5d1SDavid du Colombier if(n1 == Z) { 183e12c5d1SDavid du Colombier diag(nn, "cant find function name"); 193e12c5d1SDavid du Colombier return; 203e12c5d1SDavid du Colombier } 213e12c5d1SDavid du Colombier if(n1->op == ONAME) 223e12c5d1SDavid du Colombier break; 233e12c5d1SDavid du Colombier } 243e12c5d1SDavid du Colombier nearln = nn->lineno; 253e12c5d1SDavid du Colombier gpseudo(ATEXT, n1->sym, nodconst(stkoff)); 263e12c5d1SDavid du Colombier sp = p; 273e12c5d1SDavid du Colombier 283e12c5d1SDavid du Colombier /* 293e12c5d1SDavid du Colombier * isolate first argument 303e12c5d1SDavid du Colombier */ 313e12c5d1SDavid du Colombier if(REGARG) { 32*219b2ee8SDavid du Colombier if(typesu[thisfn->link->etype] || typev[thisfn->link->etype]) { 333e12c5d1SDavid du Colombier nod1 = *nodret->left; 343e12c5d1SDavid du Colombier nodreg(&nod, &nod1, REGARG); 353e12c5d1SDavid du Colombier gopcode(OAS, &nod, Z, &nod1); 363e12c5d1SDavid du Colombier } else 373e12c5d1SDavid du Colombier if(firstarg && typechlp[firstargtype->etype]) { 383e12c5d1SDavid du Colombier nod1 = *nodret->left; 393e12c5d1SDavid du Colombier nod1.sym = firstarg; 403e12c5d1SDavid du Colombier nod1.type = firstargtype; 413e12c5d1SDavid du Colombier if(firstargtype->width < tint->width) 42*219b2ee8SDavid du Colombier nod1.xoffset += endian(firstargtype->width); 433e12c5d1SDavid du Colombier nod1.etype = firstargtype->etype; 443e12c5d1SDavid du Colombier nodreg(&nod, &nod1, REGARG); 453e12c5d1SDavid du Colombier gopcode(OAS, &nod, Z, &nod1); 463e12c5d1SDavid du Colombier } 473e12c5d1SDavid du Colombier } 483e12c5d1SDavid du Colombier 493e12c5d1SDavid du Colombier retok = 0; 503e12c5d1SDavid du Colombier gen(n); 513e12c5d1SDavid du Colombier if(!retok) 523e12c5d1SDavid du Colombier if(thisfn->link->etype != TVOID) 533e12c5d1SDavid du Colombier warn(Z, "no return at end of function: %s", n1->sym->name); 543e12c5d1SDavid du Colombier noretval(3); 553e12c5d1SDavid du Colombier gbranch(ORETURN); 563e12c5d1SDavid du Colombier 573e12c5d1SDavid du Colombier if(!debug['N'] || debug['R'] || debug['P']) 583e12c5d1SDavid du Colombier regopt(sp); 593e12c5d1SDavid du Colombier 603e12c5d1SDavid du Colombier sp->to.offset += maxargsafe; 613e12c5d1SDavid du Colombier } 623e12c5d1SDavid du Colombier 633e12c5d1SDavid du Colombier void 643e12c5d1SDavid du Colombier gen(Node *n) 653e12c5d1SDavid du Colombier { 663e12c5d1SDavid du Colombier Node *l, nod; 673e12c5d1SDavid du Colombier Prog *sp, *spc, *spb; 683e12c5d1SDavid du Colombier Case *cn; 693e12c5d1SDavid du Colombier long sbc, scc; 703e12c5d1SDavid du Colombier int o; 713e12c5d1SDavid du Colombier 723e12c5d1SDavid du Colombier loop: 733e12c5d1SDavid du Colombier if(n == Z) 743e12c5d1SDavid du Colombier return; 753e12c5d1SDavid du Colombier nearln = n->lineno; 763e12c5d1SDavid du Colombier o = n->op; 773e12c5d1SDavid du Colombier if(debug['G']) 783e12c5d1SDavid du Colombier if(o != OLIST) 793e12c5d1SDavid du Colombier print("%L %O\n", nearln, o); 803e12c5d1SDavid du Colombier 813e12c5d1SDavid du Colombier retok = 0; 823e12c5d1SDavid du Colombier switch(o) { 833e12c5d1SDavid du Colombier 843e12c5d1SDavid du Colombier default: 853e12c5d1SDavid du Colombier complex(n); 863e12c5d1SDavid du Colombier cgen(n, Z); 873e12c5d1SDavid du Colombier break; 883e12c5d1SDavid du Colombier 893e12c5d1SDavid du Colombier case OLIST: 903e12c5d1SDavid du Colombier gen(n->left); 913e12c5d1SDavid du Colombier 923e12c5d1SDavid du Colombier rloop: 933e12c5d1SDavid du Colombier n = n->right; 943e12c5d1SDavid du Colombier goto loop; 953e12c5d1SDavid du Colombier 963e12c5d1SDavid du Colombier case ORETURN: 973e12c5d1SDavid du Colombier retok = 1; 983e12c5d1SDavid du Colombier complex(n); 993e12c5d1SDavid du Colombier if(n->type == T) 1003e12c5d1SDavid du Colombier break; 1013e12c5d1SDavid du Colombier l = n->left; 1023e12c5d1SDavid du Colombier if(l == Z) { 1033e12c5d1SDavid du Colombier noretval(3); 1043e12c5d1SDavid du Colombier gbranch(ORETURN); 1053e12c5d1SDavid du Colombier break; 1063e12c5d1SDavid du Colombier } 107*219b2ee8SDavid du Colombier if(typesu[n->type->etype] || typev[n->type->etype]) { 1083e12c5d1SDavid du Colombier sugen(l, nodret, n->type->width); 1093e12c5d1SDavid du Colombier noretval(3); 1103e12c5d1SDavid du Colombier gbranch(ORETURN); 1113e12c5d1SDavid du Colombier break; 1123e12c5d1SDavid du Colombier } 1133e12c5d1SDavid du Colombier regret(&nod, n); 1143e12c5d1SDavid du Colombier cgen(l, &nod); 1153e12c5d1SDavid du Colombier regfree(&nod); 116*219b2ee8SDavid du Colombier if(typefd[n->type->etype]) 1173e12c5d1SDavid du Colombier noretval(1); 1183e12c5d1SDavid du Colombier else 1193e12c5d1SDavid du Colombier noretval(2); 1203e12c5d1SDavid du Colombier gbranch(ORETURN); 1213e12c5d1SDavid du Colombier break; 1223e12c5d1SDavid du Colombier 1233e12c5d1SDavid du Colombier case OLABEL: 1243e12c5d1SDavid du Colombier l = n->left; 1253e12c5d1SDavid du Colombier if(l) { 126*219b2ee8SDavid du Colombier l->pc = pc; 1273e12c5d1SDavid du Colombier if(l->label) 1283e12c5d1SDavid du Colombier patch(l->label, pc); 1293e12c5d1SDavid du Colombier } 1303e12c5d1SDavid du Colombier gbranch(OGOTO); /* prevent self reference in reg */ 1313e12c5d1SDavid du Colombier patch(p, pc); 1323e12c5d1SDavid du Colombier goto rloop; 1333e12c5d1SDavid du Colombier 1343e12c5d1SDavid du Colombier case OGOTO: 1353e12c5d1SDavid du Colombier retok = 1; 1363e12c5d1SDavid du Colombier n = n->left; 1373e12c5d1SDavid du Colombier if(n == Z) 1383e12c5d1SDavid du Colombier return; 1393e12c5d1SDavid du Colombier if(n->complex == 0) { 1403e12c5d1SDavid du Colombier diag(Z, "label undefined: %s", n->sym->name); 1413e12c5d1SDavid du Colombier return; 1423e12c5d1SDavid du Colombier } 1433e12c5d1SDavid du Colombier gbranch(OGOTO); 144*219b2ee8SDavid du Colombier if(n->pc) { 145*219b2ee8SDavid du Colombier patch(p, n->pc); 1463e12c5d1SDavid du Colombier return; 1473e12c5d1SDavid du Colombier } 1483e12c5d1SDavid du Colombier if(n->label) 1493e12c5d1SDavid du Colombier patch(n->label, pc-1); 1503e12c5d1SDavid du Colombier n->label = p; 1513e12c5d1SDavid du Colombier return; 1523e12c5d1SDavid du Colombier 1533e12c5d1SDavid du Colombier case OCASE: 1543e12c5d1SDavid du Colombier l = n->left; 1553e12c5d1SDavid du Colombier if(cases == C) 1563e12c5d1SDavid du Colombier diag(n, "case/default outside a switch"); 1573e12c5d1SDavid du Colombier if(l == Z) { 1583e12c5d1SDavid du Colombier cas(); 1593e12c5d1SDavid du Colombier cases->val = 0; 1603e12c5d1SDavid du Colombier cases->def = 1; 1613e12c5d1SDavid du Colombier cases->label = pc; 1623e12c5d1SDavid du Colombier goto rloop; 1633e12c5d1SDavid du Colombier } 1643e12c5d1SDavid du Colombier complex(l); 1653e12c5d1SDavid du Colombier if(l->type == T) 1663e12c5d1SDavid du Colombier goto rloop; 1673e12c5d1SDavid du Colombier if(l->op == OCONST) 1683e12c5d1SDavid du Colombier if(typechl[l->type->etype]) { 1693e12c5d1SDavid du Colombier cas(); 170*219b2ee8SDavid du Colombier cases->val = l->vconst; 1713e12c5d1SDavid du Colombier cases->def = 0; 1723e12c5d1SDavid du Colombier cases->label = pc; 1733e12c5d1SDavid du Colombier goto rloop; 1743e12c5d1SDavid du Colombier } 1753e12c5d1SDavid du Colombier diag(n, "case expression must be integer constant"); 1763e12c5d1SDavid du Colombier goto rloop; 1773e12c5d1SDavid du Colombier 1783e12c5d1SDavid du Colombier case OSWITCH: 1793e12c5d1SDavid du Colombier l = n->left; 1803e12c5d1SDavid du Colombier complex(l); 1813e12c5d1SDavid du Colombier if(l->type == T) 1823e12c5d1SDavid du Colombier break; 1833e12c5d1SDavid du Colombier if(!typechl[l->type->etype]) { 1843e12c5d1SDavid du Colombier diag(n, "switch expression must be integer"); 1853e12c5d1SDavid du Colombier break; 1863e12c5d1SDavid du Colombier } 1873e12c5d1SDavid du Colombier 1883e12c5d1SDavid du Colombier gbranch(OGOTO); /* entry */ 1893e12c5d1SDavid du Colombier sp = p; 1903e12c5d1SDavid du Colombier 1913e12c5d1SDavid du Colombier cn = cases; 1923e12c5d1SDavid du Colombier cases = C; 1933e12c5d1SDavid du Colombier cas(); 1943e12c5d1SDavid du Colombier 1953e12c5d1SDavid du Colombier sbc = breakpc; 1963e12c5d1SDavid du Colombier breakpc = pc; 1973e12c5d1SDavid du Colombier gbranch(OGOTO); 1983e12c5d1SDavid du Colombier spb = p; 1993e12c5d1SDavid du Colombier 2003e12c5d1SDavid du Colombier gen(n->right); 2013e12c5d1SDavid du Colombier gbranch(OGOTO); 2023e12c5d1SDavid du Colombier patch(p, breakpc); 2033e12c5d1SDavid du Colombier 2043e12c5d1SDavid du Colombier patch(sp, pc); 2053e12c5d1SDavid du Colombier regalloc(&nod, l, Z); 2063e12c5d1SDavid du Colombier nod.type = types[TLONG]; 2073e12c5d1SDavid du Colombier cgen(l, &nod); 2083e12c5d1SDavid du Colombier doswit(&nod); 2093e12c5d1SDavid du Colombier regfree(&nod); 2103e12c5d1SDavid du Colombier patch(spb, pc); 2113e12c5d1SDavid du Colombier 2123e12c5d1SDavid du Colombier cases = cn; 2133e12c5d1SDavid du Colombier breakpc = sbc; 2143e12c5d1SDavid du Colombier break; 2153e12c5d1SDavid du Colombier 2163e12c5d1SDavid du Colombier case OWHILE: 2173e12c5d1SDavid du Colombier case ODWHILE: 2183e12c5d1SDavid du Colombier l = n->left; 2193e12c5d1SDavid du Colombier gbranch(OGOTO); /* entry */ 2203e12c5d1SDavid du Colombier sp = p; 2213e12c5d1SDavid du Colombier 2223e12c5d1SDavid du Colombier scc = continpc; 2233e12c5d1SDavid du Colombier continpc = pc; 2243e12c5d1SDavid du Colombier gbranch(OGOTO); 2253e12c5d1SDavid du Colombier spc = p; 2263e12c5d1SDavid du Colombier 2273e12c5d1SDavid du Colombier sbc = breakpc; 2283e12c5d1SDavid du Colombier breakpc = pc; 2293e12c5d1SDavid du Colombier gbranch(OGOTO); 2303e12c5d1SDavid du Colombier spb = p; 2313e12c5d1SDavid du Colombier 2323e12c5d1SDavid du Colombier patch(spc, pc); 2333e12c5d1SDavid du Colombier if(n->op == OWHILE) 2343e12c5d1SDavid du Colombier patch(sp, pc); 2353e12c5d1SDavid du Colombier bcomplex(l); /* test */ 2363e12c5d1SDavid du Colombier patch(p, breakpc); 2373e12c5d1SDavid du Colombier 2383e12c5d1SDavid du Colombier if(n->op == ODWHILE) 2393e12c5d1SDavid du Colombier patch(sp, pc); 2403e12c5d1SDavid du Colombier gen(n->right); /* body */ 2413e12c5d1SDavid du Colombier gbranch(OGOTO); 2423e12c5d1SDavid du Colombier patch(p, continpc); 2433e12c5d1SDavid du Colombier 2443e12c5d1SDavid du Colombier patch(spb, pc); 2453e12c5d1SDavid du Colombier continpc = scc; 2463e12c5d1SDavid du Colombier breakpc = sbc; 2473e12c5d1SDavid du Colombier break; 2483e12c5d1SDavid du Colombier 2493e12c5d1SDavid du Colombier case OFOR: 2503e12c5d1SDavid du Colombier l = n->left; 2513e12c5d1SDavid du Colombier gen(l->right->left); /* init */ 2523e12c5d1SDavid du Colombier gbranch(OGOTO); /* entry */ 2533e12c5d1SDavid du Colombier sp = p; 2543e12c5d1SDavid du Colombier 2553e12c5d1SDavid du Colombier scc = continpc; 2563e12c5d1SDavid du Colombier continpc = pc; 2573e12c5d1SDavid du Colombier gbranch(OGOTO); 2583e12c5d1SDavid du Colombier spc = p; 2593e12c5d1SDavid du Colombier 2603e12c5d1SDavid du Colombier sbc = breakpc; 2613e12c5d1SDavid du Colombier breakpc = pc; 2623e12c5d1SDavid du Colombier gbranch(OGOTO); 2633e12c5d1SDavid du Colombier spb = p; 2643e12c5d1SDavid du Colombier 2653e12c5d1SDavid du Colombier patch(spc, pc); 2663e12c5d1SDavid du Colombier gen(l->right->right); /* inc */ 2673e12c5d1SDavid du Colombier patch(sp, pc); 2683e12c5d1SDavid du Colombier if(l->left != Z) { /* test */ 2693e12c5d1SDavid du Colombier bcomplex(l->left); 2703e12c5d1SDavid du Colombier patch(p, breakpc); 2713e12c5d1SDavid du Colombier } 2723e12c5d1SDavid du Colombier gen(n->right); /* body */ 2733e12c5d1SDavid du Colombier gbranch(OGOTO); 2743e12c5d1SDavid du Colombier patch(p, continpc); 2753e12c5d1SDavid du Colombier 2763e12c5d1SDavid du Colombier patch(spb, pc); 2773e12c5d1SDavid du Colombier continpc = scc; 2783e12c5d1SDavid du Colombier breakpc = sbc; 2793e12c5d1SDavid du Colombier break; 2803e12c5d1SDavid du Colombier 2813e12c5d1SDavid du Colombier case OCONTINUE: 2823e12c5d1SDavid du Colombier if(continpc < 0) { 2833e12c5d1SDavid du Colombier diag(n, "continue not in a loop"); 2843e12c5d1SDavid du Colombier break; 2853e12c5d1SDavid du Colombier } 2863e12c5d1SDavid du Colombier gbranch(OGOTO); 2873e12c5d1SDavid du Colombier patch(p, continpc); 2883e12c5d1SDavid du Colombier break; 2893e12c5d1SDavid du Colombier 2903e12c5d1SDavid du Colombier case OBREAK: 2913e12c5d1SDavid du Colombier if(breakpc < 0) { 2923e12c5d1SDavid du Colombier diag(n, "break not in a loop"); 2933e12c5d1SDavid du Colombier break; 2943e12c5d1SDavid du Colombier } 2953e12c5d1SDavid du Colombier gbranch(OGOTO); 2963e12c5d1SDavid du Colombier patch(p, breakpc); 2973e12c5d1SDavid du Colombier break; 2983e12c5d1SDavid du Colombier 2993e12c5d1SDavid du Colombier case OIF: 3003e12c5d1SDavid du Colombier l = n->left; 3013e12c5d1SDavid du Colombier bcomplex(l); 3023e12c5d1SDavid du Colombier sp = p; 3033e12c5d1SDavid du Colombier if(n->right->left != Z) 3043e12c5d1SDavid du Colombier gen(n->right->left); 3053e12c5d1SDavid du Colombier if(n->right->right != Z) { 3063e12c5d1SDavid du Colombier gbranch(OGOTO); 3073e12c5d1SDavid du Colombier patch(sp, pc); 3083e12c5d1SDavid du Colombier sp = p; 3093e12c5d1SDavid du Colombier gen(n->right->right); 3103e12c5d1SDavid du Colombier } 3113e12c5d1SDavid du Colombier patch(sp, pc); 3123e12c5d1SDavid du Colombier break; 3133e12c5d1SDavid du Colombier 3143e12c5d1SDavid du Colombier case OSET: 3153e12c5d1SDavid du Colombier case OUSED: 3163e12c5d1SDavid du Colombier n = n->left; 3173e12c5d1SDavid du Colombier for(;;) { 3183e12c5d1SDavid du Colombier if(n->op == OLIST) { 3193e12c5d1SDavid du Colombier l = n->right; 3203e12c5d1SDavid du Colombier n = n->left; 3213e12c5d1SDavid du Colombier complex(l); 3223e12c5d1SDavid du Colombier if(l->op == ONAME) { 3233e12c5d1SDavid du Colombier if(o == OSET) 3243e12c5d1SDavid du Colombier gins(ANOP, Z, l); 3253e12c5d1SDavid du Colombier else 3263e12c5d1SDavid du Colombier gins(ANOP, l, Z); 3273e12c5d1SDavid du Colombier } 3283e12c5d1SDavid du Colombier } else { 3293e12c5d1SDavid du Colombier complex(n); 3303e12c5d1SDavid du Colombier if(n->op == ONAME) { 3313e12c5d1SDavid du Colombier if(o == OSET) 3323e12c5d1SDavid du Colombier gins(ANOP, Z, n); 3333e12c5d1SDavid du Colombier else 3343e12c5d1SDavid du Colombier gins(ANOP, n, Z); 3353e12c5d1SDavid du Colombier } 3363e12c5d1SDavid du Colombier break; 3373e12c5d1SDavid du Colombier } 3383e12c5d1SDavid du Colombier } 3393e12c5d1SDavid du Colombier break; 3403e12c5d1SDavid du Colombier } 3413e12c5d1SDavid du Colombier } 3423e12c5d1SDavid du Colombier 3433e12c5d1SDavid du Colombier void 3443e12c5d1SDavid du Colombier noretval(int n) 3453e12c5d1SDavid du Colombier { 3463e12c5d1SDavid du Colombier 3473e12c5d1SDavid du Colombier if(n & 1) { 3483e12c5d1SDavid du Colombier gins(ANOP, Z, Z); 3493e12c5d1SDavid du Colombier p->to.type = D_REG; 3503e12c5d1SDavid du Colombier p->to.reg = REGRET; 3513e12c5d1SDavid du Colombier } 3523e12c5d1SDavid du Colombier if(n & 2) { 3533e12c5d1SDavid du Colombier gins(ANOP, Z, Z); 3543e12c5d1SDavid du Colombier p->to.type = D_FREG; 3553e12c5d1SDavid du Colombier p->to.reg = FREGRET; 3563e12c5d1SDavid du Colombier } 3573e12c5d1SDavid du Colombier } 3583e12c5d1SDavid du Colombier 3593e12c5d1SDavid du Colombier /* 3603e12c5d1SDavid du Colombier * calculate addressability as follows 3613e12c5d1SDavid du Colombier * CONST ==> 20 $value 3623e12c5d1SDavid du Colombier * NAME ==> 10 name 3633e12c5d1SDavid du Colombier * REGISTER ==> 11 register 3643e12c5d1SDavid du Colombier * INDREG ==> 12 *[(reg)+offset] 3653e12c5d1SDavid du Colombier * &10 ==> 2 $name 3663e12c5d1SDavid du Colombier * ADD(2, 20) ==> 2 $name+offset 3673e12c5d1SDavid du Colombier * ADD(3, 20) ==> 3 $(reg)+offset 3683e12c5d1SDavid du Colombier * &12 ==> 3 $(reg)+offset 3693e12c5d1SDavid du Colombier * *11 ==> 11 ?? 3703e12c5d1SDavid du Colombier * *2 ==> 10 name 3713e12c5d1SDavid du Colombier * *3 ==> 12 *(reg)+offset 3723e12c5d1SDavid du Colombier * calculate complexity (number of registers) 3733e12c5d1SDavid du Colombier */ 3743e12c5d1SDavid du Colombier void 3753e12c5d1SDavid du Colombier xcom(Node *n) 3763e12c5d1SDavid du Colombier { 3773e12c5d1SDavid du Colombier Node *l, *r; 3783e12c5d1SDavid du Colombier int t; 3793e12c5d1SDavid du Colombier 3803e12c5d1SDavid du Colombier if(n == Z) 3813e12c5d1SDavid du Colombier return; 3823e12c5d1SDavid du Colombier l = n->left; 3833e12c5d1SDavid du Colombier r = n->right; 3843e12c5d1SDavid du Colombier n->addable = 0; 3853e12c5d1SDavid du Colombier n->complex = 0; 3863e12c5d1SDavid du Colombier switch(n->op) { 3873e12c5d1SDavid du Colombier case OCONST: 3883e12c5d1SDavid du Colombier n->addable = 20; 3893e12c5d1SDavid du Colombier return; 3903e12c5d1SDavid du Colombier 3913e12c5d1SDavid du Colombier case OREGISTER: 3923e12c5d1SDavid du Colombier n->addable = 11; 3933e12c5d1SDavid du Colombier return; 3943e12c5d1SDavid du Colombier 3953e12c5d1SDavid du Colombier case OINDREG: 3963e12c5d1SDavid du Colombier n->addable = 12; 3973e12c5d1SDavid du Colombier return; 3983e12c5d1SDavid du Colombier 3993e12c5d1SDavid du Colombier case ONAME: 4003e12c5d1SDavid du Colombier n->addable = 10; 4013e12c5d1SDavid du Colombier return; 4023e12c5d1SDavid du Colombier 4033e12c5d1SDavid du Colombier case OADDR: 4043e12c5d1SDavid du Colombier xcom(l); 4053e12c5d1SDavid du Colombier if(l->addable == 10) 4063e12c5d1SDavid du Colombier n->addable = 2; 4073e12c5d1SDavid du Colombier if(l->addable == 12) 4083e12c5d1SDavid du Colombier n->addable = 3; 4093e12c5d1SDavid du Colombier break; 4103e12c5d1SDavid du Colombier 4113e12c5d1SDavid du Colombier case OIND: 4123e12c5d1SDavid du Colombier xcom(l); 4133e12c5d1SDavid du Colombier if(l->addable == 11) 4143e12c5d1SDavid du Colombier n->addable = 12; 4153e12c5d1SDavid du Colombier if(l->addable == 3) 4163e12c5d1SDavid du Colombier n->addable = 12; 4173e12c5d1SDavid du Colombier if(l->addable == 2) 4183e12c5d1SDavid du Colombier n->addable = 10; 4193e12c5d1SDavid du Colombier break; 4203e12c5d1SDavid du Colombier 4213e12c5d1SDavid du Colombier case OADD: 4223e12c5d1SDavid du Colombier xcom(l); 4233e12c5d1SDavid du Colombier xcom(r); 4243e12c5d1SDavid du Colombier if(l->addable == 20) { 4253e12c5d1SDavid du Colombier if(r->addable == 2) 4263e12c5d1SDavid du Colombier n->addable = 2; 4273e12c5d1SDavid du Colombier if(r->addable == 3) 4283e12c5d1SDavid du Colombier n->addable = 3; 4293e12c5d1SDavid du Colombier } 4303e12c5d1SDavid du Colombier if(r->addable == 20) { 4313e12c5d1SDavid du Colombier if(l->addable == 2) 4323e12c5d1SDavid du Colombier n->addable = 2; 4333e12c5d1SDavid du Colombier if(l->addable == 3) 4343e12c5d1SDavid du Colombier n->addable = 3; 4353e12c5d1SDavid du Colombier } 4363e12c5d1SDavid du Colombier break; 4373e12c5d1SDavid du Colombier 4383e12c5d1SDavid du Colombier case OASLMUL: 4393e12c5d1SDavid du Colombier case OASMUL: 4403e12c5d1SDavid du Colombier xcom(l); 4413e12c5d1SDavid du Colombier xcom(r); 4423e12c5d1SDavid du Colombier t = vlog(r); 4433e12c5d1SDavid du Colombier if(t >= 0) { 4443e12c5d1SDavid du Colombier n->op = OASASHL; 445*219b2ee8SDavid du Colombier r->vconst = t; 446*219b2ee8SDavid du Colombier r->type = tint; 4473e12c5d1SDavid du Colombier } 4483e12c5d1SDavid du Colombier break; 4493e12c5d1SDavid du Colombier 4503e12c5d1SDavid du Colombier case OMUL: 4513e12c5d1SDavid du Colombier case OLMUL: 4523e12c5d1SDavid du Colombier xcom(l); 4533e12c5d1SDavid du Colombier xcom(r); 4543e12c5d1SDavid du Colombier t = vlog(r); 4553e12c5d1SDavid du Colombier if(t >= 0) { 4563e12c5d1SDavid du Colombier n->op = OASHL; 457*219b2ee8SDavid du Colombier r->vconst = t; 458*219b2ee8SDavid du Colombier r->type = tint; 4593e12c5d1SDavid du Colombier } 4603e12c5d1SDavid du Colombier t = vlog(l); 4613e12c5d1SDavid du Colombier if(t >= 0) { 4623e12c5d1SDavid du Colombier n->op = OASHL; 4633e12c5d1SDavid du Colombier n->left = r; 4643e12c5d1SDavid du Colombier n->right = l; 4653e12c5d1SDavid du Colombier r = l; 4663e12c5d1SDavid du Colombier l = n->left; 467*219b2ee8SDavid du Colombier r->vconst = t; 468*219b2ee8SDavid du Colombier r->type = tint; 4693e12c5d1SDavid du Colombier } 4703e12c5d1SDavid du Colombier break; 4713e12c5d1SDavid du Colombier 4723e12c5d1SDavid du Colombier case OASLDIV: 4733e12c5d1SDavid du Colombier xcom(l); 4743e12c5d1SDavid du Colombier xcom(r); 4753e12c5d1SDavid du Colombier t = vlog(r); 4763e12c5d1SDavid du Colombier if(t >= 0) { 4773e12c5d1SDavid du Colombier n->op = OASLSHR; 478*219b2ee8SDavid du Colombier r->vconst = t; 479*219b2ee8SDavid du Colombier r->type = tint; 4803e12c5d1SDavid du Colombier } 4813e12c5d1SDavid du Colombier break; 4823e12c5d1SDavid du Colombier 4833e12c5d1SDavid du Colombier case OLDIV: 4843e12c5d1SDavid du Colombier xcom(l); 4853e12c5d1SDavid du Colombier xcom(r); 4863e12c5d1SDavid du Colombier t = vlog(r); 4873e12c5d1SDavid du Colombier if(t >= 0) { 4883e12c5d1SDavid du Colombier n->op = OLSHR; 489*219b2ee8SDavid du Colombier r->vconst = t; 490*219b2ee8SDavid du Colombier r->type = tint; 4913e12c5d1SDavid du Colombier } 4923e12c5d1SDavid du Colombier break; 4933e12c5d1SDavid du Colombier 4943e12c5d1SDavid du Colombier case OASLMOD: 4953e12c5d1SDavid du Colombier xcom(l); 4963e12c5d1SDavid du Colombier xcom(r); 4973e12c5d1SDavid du Colombier t = vlog(r); 4983e12c5d1SDavid du Colombier if(t >= 0) { 4993e12c5d1SDavid du Colombier n->op = OASAND; 500*219b2ee8SDavid du Colombier r->vconst--; 5013e12c5d1SDavid du Colombier } 5023e12c5d1SDavid du Colombier break; 5033e12c5d1SDavid du Colombier 5043e12c5d1SDavid du Colombier case OLMOD: 5053e12c5d1SDavid du Colombier xcom(l); 5063e12c5d1SDavid du Colombier xcom(r); 5073e12c5d1SDavid du Colombier t = vlog(r); 5083e12c5d1SDavid du Colombier if(t >= 0) { 5093e12c5d1SDavid du Colombier n->op = OAND; 510*219b2ee8SDavid du Colombier r->vconst--; 5113e12c5d1SDavid du Colombier } 5123e12c5d1SDavid du Colombier break; 5133e12c5d1SDavid du Colombier 5143e12c5d1SDavid du Colombier default: 5153e12c5d1SDavid du Colombier if(l != Z) 5163e12c5d1SDavid du Colombier xcom(l); 5173e12c5d1SDavid du Colombier if(r != Z) 5183e12c5d1SDavid du Colombier xcom(r); 5193e12c5d1SDavid du Colombier break; 5203e12c5d1SDavid du Colombier } 5213e12c5d1SDavid du Colombier if(n->addable >= 10) 5223e12c5d1SDavid du Colombier return; 523*219b2ee8SDavid du Colombier 5243e12c5d1SDavid du Colombier if(l != Z) 5253e12c5d1SDavid du Colombier n->complex = l->complex; 5263e12c5d1SDavid du Colombier if(r != Z) { 5273e12c5d1SDavid du Colombier if(r->complex == n->complex) 528*219b2ee8SDavid du Colombier n->complex = r->complex+1; 529*219b2ee8SDavid du Colombier else 5303e12c5d1SDavid du Colombier if(r->complex > n->complex) 5313e12c5d1SDavid du Colombier n->complex = r->complex; 5323e12c5d1SDavid du Colombier } 5333e12c5d1SDavid du Colombier if(n->complex == 0) 5343e12c5d1SDavid du Colombier n->complex++; 5353e12c5d1SDavid du Colombier 536*219b2ee8SDavid du Colombier if(com64(n)) 537*219b2ee8SDavid du Colombier return; 538*219b2ee8SDavid du Colombier 539*219b2ee8SDavid du Colombier switch(n->op) { 5403e12c5d1SDavid du Colombier case OFUNC: 5413e12c5d1SDavid du Colombier n->complex = FNX; 5423e12c5d1SDavid du Colombier break; 5433e12c5d1SDavid du Colombier 5443e12c5d1SDavid du Colombier case OADD: 5453e12c5d1SDavid du Colombier case OXOR: 5463e12c5d1SDavid du Colombier case OAND: 5473e12c5d1SDavid du Colombier case OOR: 5483e12c5d1SDavid du Colombier case OEQ: 5493e12c5d1SDavid du Colombier case ONE: 5503e12c5d1SDavid du Colombier /* 5513e12c5d1SDavid du Colombier * immediate operators, make const on right 5523e12c5d1SDavid du Colombier */ 5533e12c5d1SDavid du Colombier if(l->op == OCONST) { 5543e12c5d1SDavid du Colombier n->left = r; 5553e12c5d1SDavid du Colombier n->right = l; 5563e12c5d1SDavid du Colombier } 5573e12c5d1SDavid du Colombier break; 5583e12c5d1SDavid du Colombier } 5593e12c5d1SDavid du Colombier } 5603e12c5d1SDavid du Colombier 5613e12c5d1SDavid du Colombier void 5623e12c5d1SDavid du Colombier bcomplex(Node *n) 5633e12c5d1SDavid du Colombier { 5643e12c5d1SDavid du Colombier 5653e12c5d1SDavid du Colombier complex(n); 5663e12c5d1SDavid du Colombier if(n->type != T) 5673e12c5d1SDavid du Colombier if(tcompat(n, T, n->type, tnot)) 5683e12c5d1SDavid du Colombier n->type = T; 5693e12c5d1SDavid du Colombier if(n->type != T) { 570*219b2ee8SDavid du Colombier bool64(n); 5713e12c5d1SDavid du Colombier boolgen(n, 1, Z); 5723e12c5d1SDavid du Colombier } else 5733e12c5d1SDavid du Colombier gbranch(OGOTO); 5743e12c5d1SDavid du Colombier } 575