1*3e12c5d1SDavid du Colombier #include "gc.h" 2*3e12c5d1SDavid du Colombier 3*3e12c5d1SDavid du Colombier void 4*3e12c5d1SDavid du Colombier codgen(Node *n, Node *nn) 5*3e12c5d1SDavid du Colombier { 6*3e12c5d1SDavid du Colombier Prog *sp; 7*3e12c5d1SDavid du Colombier Node *n1, nod, nod1; 8*3e12c5d1SDavid du Colombier 9*3e12c5d1SDavid du Colombier cursafe = 0; 10*3e12c5d1SDavid du Colombier curarg = 0; 11*3e12c5d1SDavid du Colombier maxargsafe = 0; 12*3e12c5d1SDavid du Colombier 13*3e12c5d1SDavid du Colombier /* 14*3e12c5d1SDavid du Colombier * isolate name 15*3e12c5d1SDavid du Colombier */ 16*3e12c5d1SDavid du Colombier for(n1 = nn;; n1 = n1->left) { 17*3e12c5d1SDavid du Colombier if(n1 == Z) { 18*3e12c5d1SDavid du Colombier diag(nn, "cant find function name"); 19*3e12c5d1SDavid du Colombier return; 20*3e12c5d1SDavid du Colombier } 21*3e12c5d1SDavid du Colombier if(n1->op == ONAME) 22*3e12c5d1SDavid du Colombier break; 23*3e12c5d1SDavid du Colombier } 24*3e12c5d1SDavid du Colombier nearln = nn->lineno; 25*3e12c5d1SDavid du Colombier gpseudo(ATEXT, n1->sym, nodconst(stkoff)); 26*3e12c5d1SDavid du Colombier sp = p; 27*3e12c5d1SDavid du Colombier 28*3e12c5d1SDavid du Colombier /* 29*3e12c5d1SDavid du Colombier * isolate first argument 30*3e12c5d1SDavid du Colombier */ 31*3e12c5d1SDavid du Colombier if(REGARG) { 32*3e12c5d1SDavid du Colombier if(typesu[thisfn->link->etype]) { 33*3e12c5d1SDavid du Colombier nod1 = *nodret->left; 34*3e12c5d1SDavid du Colombier nodreg(&nod, &nod1, REGARG); 35*3e12c5d1SDavid du Colombier gopcode(OAS, &nod, Z, &nod1); 36*3e12c5d1SDavid du Colombier } else 37*3e12c5d1SDavid du Colombier if(firstarg && typechlp[firstargtype->etype]) { 38*3e12c5d1SDavid du Colombier nod1 = *nodret->left; 39*3e12c5d1SDavid du Colombier nod1.sym = firstarg; 40*3e12c5d1SDavid du Colombier nod1.type = firstargtype; 41*3e12c5d1SDavid du Colombier if(firstargtype->width < tint->width) 42*3e12c5d1SDavid du Colombier nod1.offset += endian(firstargtype->width); 43*3e12c5d1SDavid du Colombier nod1.etype = firstargtype->etype; 44*3e12c5d1SDavid du Colombier nodreg(&nod, &nod1, REGARG); 45*3e12c5d1SDavid du Colombier gopcode(OAS, &nod, Z, &nod1); 46*3e12c5d1SDavid du Colombier } 47*3e12c5d1SDavid du Colombier } 48*3e12c5d1SDavid du Colombier 49*3e12c5d1SDavid du Colombier retok = 0; 50*3e12c5d1SDavid du Colombier gen(n); 51*3e12c5d1SDavid du Colombier if(!retok) 52*3e12c5d1SDavid du Colombier if(thisfn->link->etype != TVOID) 53*3e12c5d1SDavid du Colombier warn(Z, "no return at end of function: %s", n1->sym->name); 54*3e12c5d1SDavid du Colombier noretval(3); 55*3e12c5d1SDavid du Colombier gbranch(ORETURN); 56*3e12c5d1SDavid du Colombier 57*3e12c5d1SDavid du Colombier if(!debug['N'] || debug['R'] || debug['P']) 58*3e12c5d1SDavid du Colombier regopt(sp); 59*3e12c5d1SDavid du Colombier 60*3e12c5d1SDavid du Colombier sp->to.offset += maxargsafe; 61*3e12c5d1SDavid du Colombier } 62*3e12c5d1SDavid du Colombier 63*3e12c5d1SDavid du Colombier void 64*3e12c5d1SDavid du Colombier gen(Node *n) 65*3e12c5d1SDavid du Colombier { 66*3e12c5d1SDavid du Colombier Node *l, nod; 67*3e12c5d1SDavid du Colombier Prog *sp, *spc, *spb; 68*3e12c5d1SDavid du Colombier Case *cn; 69*3e12c5d1SDavid du Colombier long sbc, scc; 70*3e12c5d1SDavid du Colombier int o; 71*3e12c5d1SDavid du Colombier 72*3e12c5d1SDavid du Colombier loop: 73*3e12c5d1SDavid du Colombier if(n == Z) 74*3e12c5d1SDavid du Colombier return; 75*3e12c5d1SDavid du Colombier nearln = n->lineno; 76*3e12c5d1SDavid du Colombier o = n->op; 77*3e12c5d1SDavid du Colombier if(debug['G']) 78*3e12c5d1SDavid du Colombier if(o != OLIST) 79*3e12c5d1SDavid du Colombier print("%L %O\n", nearln, o); 80*3e12c5d1SDavid du Colombier 81*3e12c5d1SDavid du Colombier retok = 0; 82*3e12c5d1SDavid du Colombier switch(o) { 83*3e12c5d1SDavid du Colombier 84*3e12c5d1SDavid du Colombier default: 85*3e12c5d1SDavid du Colombier complex(n); 86*3e12c5d1SDavid du Colombier cgen(n, Z); 87*3e12c5d1SDavid du Colombier break; 88*3e12c5d1SDavid du Colombier 89*3e12c5d1SDavid du Colombier case OLIST: 90*3e12c5d1SDavid du Colombier gen(n->left); 91*3e12c5d1SDavid du Colombier 92*3e12c5d1SDavid du Colombier rloop: 93*3e12c5d1SDavid du Colombier n = n->right; 94*3e12c5d1SDavid du Colombier goto loop; 95*3e12c5d1SDavid du Colombier 96*3e12c5d1SDavid du Colombier case ORETURN: 97*3e12c5d1SDavid du Colombier retok = 1; 98*3e12c5d1SDavid du Colombier complex(n); 99*3e12c5d1SDavid du Colombier if(n->type == T) 100*3e12c5d1SDavid du Colombier break; 101*3e12c5d1SDavid du Colombier l = n->left; 102*3e12c5d1SDavid du Colombier if(l == Z) { 103*3e12c5d1SDavid du Colombier noretval(3); 104*3e12c5d1SDavid du Colombier gbranch(ORETURN); 105*3e12c5d1SDavid du Colombier break; 106*3e12c5d1SDavid du Colombier } 107*3e12c5d1SDavid du Colombier if(typesu[n->type->etype]) { 108*3e12c5d1SDavid du Colombier sugen(l, nodret, n->type->width); 109*3e12c5d1SDavid du Colombier noretval(3); 110*3e12c5d1SDavid du Colombier gbranch(ORETURN); 111*3e12c5d1SDavid du Colombier break; 112*3e12c5d1SDavid du Colombier } 113*3e12c5d1SDavid du Colombier regret(&nod, n); 114*3e12c5d1SDavid du Colombier cgen(l, &nod); 115*3e12c5d1SDavid du Colombier regfree(&nod); 116*3e12c5d1SDavid du Colombier if(typefdv[n->type->etype]) 117*3e12c5d1SDavid du Colombier noretval(1); 118*3e12c5d1SDavid du Colombier else 119*3e12c5d1SDavid du Colombier noretval(2); 120*3e12c5d1SDavid du Colombier gbranch(ORETURN); 121*3e12c5d1SDavid du Colombier break; 122*3e12c5d1SDavid du Colombier 123*3e12c5d1SDavid du Colombier case OLABEL: 124*3e12c5d1SDavid du Colombier l = n->left; 125*3e12c5d1SDavid du Colombier if(l) { 126*3e12c5d1SDavid du Colombier l->offset = pc; 127*3e12c5d1SDavid du Colombier if(l->label) 128*3e12c5d1SDavid du Colombier patch(l->label, pc); 129*3e12c5d1SDavid du Colombier } 130*3e12c5d1SDavid du Colombier gbranch(OGOTO); /* prevent self reference in reg */ 131*3e12c5d1SDavid du Colombier patch(p, pc); 132*3e12c5d1SDavid du Colombier goto rloop; 133*3e12c5d1SDavid du Colombier 134*3e12c5d1SDavid du Colombier case OGOTO: 135*3e12c5d1SDavid du Colombier retok = 1; 136*3e12c5d1SDavid du Colombier n = n->left; 137*3e12c5d1SDavid du Colombier if(n == Z) 138*3e12c5d1SDavid du Colombier return; 139*3e12c5d1SDavid du Colombier if(n->complex == 0) { 140*3e12c5d1SDavid du Colombier diag(Z, "label undefined: %s", n->sym->name); 141*3e12c5d1SDavid du Colombier return; 142*3e12c5d1SDavid du Colombier } 143*3e12c5d1SDavid du Colombier gbranch(OGOTO); 144*3e12c5d1SDavid du Colombier if(n->offset) { 145*3e12c5d1SDavid du Colombier patch(p, n->offset); 146*3e12c5d1SDavid du Colombier return; 147*3e12c5d1SDavid du Colombier } 148*3e12c5d1SDavid du Colombier if(n->label) 149*3e12c5d1SDavid du Colombier patch(n->label, pc-1); 150*3e12c5d1SDavid du Colombier n->label = p; 151*3e12c5d1SDavid du Colombier return; 152*3e12c5d1SDavid du Colombier 153*3e12c5d1SDavid du Colombier case OCASE: 154*3e12c5d1SDavid du Colombier l = n->left; 155*3e12c5d1SDavid du Colombier if(cases == C) 156*3e12c5d1SDavid du Colombier diag(n, "case/default outside a switch"); 157*3e12c5d1SDavid du Colombier if(l == Z) { 158*3e12c5d1SDavid du Colombier cas(); 159*3e12c5d1SDavid du Colombier cases->val = 0; 160*3e12c5d1SDavid du Colombier cases->def = 1; 161*3e12c5d1SDavid du Colombier cases->label = pc; 162*3e12c5d1SDavid du Colombier goto rloop; 163*3e12c5d1SDavid du Colombier } 164*3e12c5d1SDavid du Colombier complex(l); 165*3e12c5d1SDavid du Colombier if(l->type == T) 166*3e12c5d1SDavid du Colombier goto rloop; 167*3e12c5d1SDavid du Colombier if(l->op == OCONST) 168*3e12c5d1SDavid du Colombier if(typechl[l->type->etype]) { 169*3e12c5d1SDavid du Colombier cas(); 170*3e12c5d1SDavid du Colombier cases->val = l->offset; 171*3e12c5d1SDavid du Colombier cases->def = 0; 172*3e12c5d1SDavid du Colombier cases->label = pc; 173*3e12c5d1SDavid du Colombier goto rloop; 174*3e12c5d1SDavid du Colombier } 175*3e12c5d1SDavid du Colombier diag(n, "case expression must be integer constant"); 176*3e12c5d1SDavid du Colombier goto rloop; 177*3e12c5d1SDavid du Colombier 178*3e12c5d1SDavid du Colombier case OSWITCH: 179*3e12c5d1SDavid du Colombier l = n->left; 180*3e12c5d1SDavid du Colombier complex(l); 181*3e12c5d1SDavid du Colombier if(l->type == T) 182*3e12c5d1SDavid du Colombier break; 183*3e12c5d1SDavid du Colombier if(!typechl[l->type->etype]) { 184*3e12c5d1SDavid du Colombier diag(n, "switch expression must be integer"); 185*3e12c5d1SDavid du Colombier break; 186*3e12c5d1SDavid du Colombier } 187*3e12c5d1SDavid du Colombier 188*3e12c5d1SDavid du Colombier gbranch(OGOTO); /* entry */ 189*3e12c5d1SDavid du Colombier sp = p; 190*3e12c5d1SDavid du Colombier 191*3e12c5d1SDavid du Colombier cn = cases; 192*3e12c5d1SDavid du Colombier cases = C; 193*3e12c5d1SDavid du Colombier cas(); 194*3e12c5d1SDavid du Colombier 195*3e12c5d1SDavid du Colombier sbc = breakpc; 196*3e12c5d1SDavid du Colombier breakpc = pc; 197*3e12c5d1SDavid du Colombier gbranch(OGOTO); 198*3e12c5d1SDavid du Colombier spb = p; 199*3e12c5d1SDavid du Colombier 200*3e12c5d1SDavid du Colombier gen(n->right); 201*3e12c5d1SDavid du Colombier gbranch(OGOTO); 202*3e12c5d1SDavid du Colombier patch(p, breakpc); 203*3e12c5d1SDavid du Colombier 204*3e12c5d1SDavid du Colombier patch(sp, pc); 205*3e12c5d1SDavid du Colombier regalloc(&nod, l, Z); 206*3e12c5d1SDavid du Colombier nod.type = types[TLONG]; 207*3e12c5d1SDavid du Colombier cgen(l, &nod); 208*3e12c5d1SDavid du Colombier doswit(&nod); 209*3e12c5d1SDavid du Colombier regfree(&nod); 210*3e12c5d1SDavid du Colombier patch(spb, pc); 211*3e12c5d1SDavid du Colombier 212*3e12c5d1SDavid du Colombier cases = cn; 213*3e12c5d1SDavid du Colombier breakpc = sbc; 214*3e12c5d1SDavid du Colombier break; 215*3e12c5d1SDavid du Colombier 216*3e12c5d1SDavid du Colombier case OWHILE: 217*3e12c5d1SDavid du Colombier case ODWHILE: 218*3e12c5d1SDavid du Colombier l = n->left; 219*3e12c5d1SDavid du Colombier gbranch(OGOTO); /* entry */ 220*3e12c5d1SDavid du Colombier sp = p; 221*3e12c5d1SDavid du Colombier 222*3e12c5d1SDavid du Colombier scc = continpc; 223*3e12c5d1SDavid du Colombier continpc = pc; 224*3e12c5d1SDavid du Colombier gbranch(OGOTO); 225*3e12c5d1SDavid du Colombier spc = p; 226*3e12c5d1SDavid du Colombier 227*3e12c5d1SDavid du Colombier sbc = breakpc; 228*3e12c5d1SDavid du Colombier breakpc = pc; 229*3e12c5d1SDavid du Colombier gbranch(OGOTO); 230*3e12c5d1SDavid du Colombier spb = p; 231*3e12c5d1SDavid du Colombier 232*3e12c5d1SDavid du Colombier patch(spc, pc); 233*3e12c5d1SDavid du Colombier if(n->op == OWHILE) 234*3e12c5d1SDavid du Colombier patch(sp, pc); 235*3e12c5d1SDavid du Colombier bcomplex(l); /* test */ 236*3e12c5d1SDavid du Colombier patch(p, breakpc); 237*3e12c5d1SDavid du Colombier 238*3e12c5d1SDavid du Colombier if(n->op == ODWHILE) 239*3e12c5d1SDavid du Colombier patch(sp, pc); 240*3e12c5d1SDavid du Colombier gen(n->right); /* body */ 241*3e12c5d1SDavid du Colombier gbranch(OGOTO); 242*3e12c5d1SDavid du Colombier patch(p, continpc); 243*3e12c5d1SDavid du Colombier 244*3e12c5d1SDavid du Colombier patch(spb, pc); 245*3e12c5d1SDavid du Colombier continpc = scc; 246*3e12c5d1SDavid du Colombier breakpc = sbc; 247*3e12c5d1SDavid du Colombier break; 248*3e12c5d1SDavid du Colombier 249*3e12c5d1SDavid du Colombier case OFOR: 250*3e12c5d1SDavid du Colombier l = n->left; 251*3e12c5d1SDavid du Colombier gen(l->right->left); /* init */ 252*3e12c5d1SDavid du Colombier gbranch(OGOTO); /* entry */ 253*3e12c5d1SDavid du Colombier sp = p; 254*3e12c5d1SDavid du Colombier 255*3e12c5d1SDavid du Colombier scc = continpc; 256*3e12c5d1SDavid du Colombier continpc = pc; 257*3e12c5d1SDavid du Colombier gbranch(OGOTO); 258*3e12c5d1SDavid du Colombier spc = p; 259*3e12c5d1SDavid du Colombier 260*3e12c5d1SDavid du Colombier sbc = breakpc; 261*3e12c5d1SDavid du Colombier breakpc = pc; 262*3e12c5d1SDavid du Colombier gbranch(OGOTO); 263*3e12c5d1SDavid du Colombier spb = p; 264*3e12c5d1SDavid du Colombier 265*3e12c5d1SDavid du Colombier patch(spc, pc); 266*3e12c5d1SDavid du Colombier gen(l->right->right); /* inc */ 267*3e12c5d1SDavid du Colombier patch(sp, pc); 268*3e12c5d1SDavid du Colombier if(l->left != Z) { /* test */ 269*3e12c5d1SDavid du Colombier bcomplex(l->left); 270*3e12c5d1SDavid du Colombier patch(p, breakpc); 271*3e12c5d1SDavid du Colombier } 272*3e12c5d1SDavid du Colombier gen(n->right); /* body */ 273*3e12c5d1SDavid du Colombier gbranch(OGOTO); 274*3e12c5d1SDavid du Colombier patch(p, continpc); 275*3e12c5d1SDavid du Colombier 276*3e12c5d1SDavid du Colombier patch(spb, pc); 277*3e12c5d1SDavid du Colombier continpc = scc; 278*3e12c5d1SDavid du Colombier breakpc = sbc; 279*3e12c5d1SDavid du Colombier break; 280*3e12c5d1SDavid du Colombier 281*3e12c5d1SDavid du Colombier case OCONTINUE: 282*3e12c5d1SDavid du Colombier if(continpc < 0) { 283*3e12c5d1SDavid du Colombier diag(n, "continue not in a loop"); 284*3e12c5d1SDavid du Colombier break; 285*3e12c5d1SDavid du Colombier } 286*3e12c5d1SDavid du Colombier gbranch(OGOTO); 287*3e12c5d1SDavid du Colombier patch(p, continpc); 288*3e12c5d1SDavid du Colombier break; 289*3e12c5d1SDavid du Colombier 290*3e12c5d1SDavid du Colombier case OBREAK: 291*3e12c5d1SDavid du Colombier if(breakpc < 0) { 292*3e12c5d1SDavid du Colombier diag(n, "break not in a loop"); 293*3e12c5d1SDavid du Colombier break; 294*3e12c5d1SDavid du Colombier } 295*3e12c5d1SDavid du Colombier gbranch(OGOTO); 296*3e12c5d1SDavid du Colombier patch(p, breakpc); 297*3e12c5d1SDavid du Colombier break; 298*3e12c5d1SDavid du Colombier 299*3e12c5d1SDavid du Colombier case OIF: 300*3e12c5d1SDavid du Colombier l = n->left; 301*3e12c5d1SDavid du Colombier bcomplex(l); 302*3e12c5d1SDavid du Colombier sp = p; 303*3e12c5d1SDavid du Colombier if(n->right->left != Z) 304*3e12c5d1SDavid du Colombier gen(n->right->left); 305*3e12c5d1SDavid du Colombier if(n->right->right != Z) { 306*3e12c5d1SDavid du Colombier gbranch(OGOTO); 307*3e12c5d1SDavid du Colombier patch(sp, pc); 308*3e12c5d1SDavid du Colombier sp = p; 309*3e12c5d1SDavid du Colombier gen(n->right->right); 310*3e12c5d1SDavid du Colombier } 311*3e12c5d1SDavid du Colombier patch(sp, pc); 312*3e12c5d1SDavid du Colombier break; 313*3e12c5d1SDavid du Colombier 314*3e12c5d1SDavid du Colombier case OSET: 315*3e12c5d1SDavid du Colombier case OUSED: 316*3e12c5d1SDavid du Colombier n = n->left; 317*3e12c5d1SDavid du Colombier for(;;) { 318*3e12c5d1SDavid du Colombier if(n->op == OLIST) { 319*3e12c5d1SDavid du Colombier l = n->right; 320*3e12c5d1SDavid du Colombier n = n->left; 321*3e12c5d1SDavid du Colombier complex(l); 322*3e12c5d1SDavid du Colombier if(l->op == ONAME) { 323*3e12c5d1SDavid du Colombier if(o == OSET) 324*3e12c5d1SDavid du Colombier gins(ANOP, Z, l); 325*3e12c5d1SDavid du Colombier else 326*3e12c5d1SDavid du Colombier gins(ANOP, l, Z); 327*3e12c5d1SDavid du Colombier } 328*3e12c5d1SDavid du Colombier } else { 329*3e12c5d1SDavid du Colombier complex(n); 330*3e12c5d1SDavid du Colombier if(n->op == ONAME) { 331*3e12c5d1SDavid du Colombier if(o == OSET) 332*3e12c5d1SDavid du Colombier gins(ANOP, Z, n); 333*3e12c5d1SDavid du Colombier else 334*3e12c5d1SDavid du Colombier gins(ANOP, n, Z); 335*3e12c5d1SDavid du Colombier } 336*3e12c5d1SDavid du Colombier break; 337*3e12c5d1SDavid du Colombier } 338*3e12c5d1SDavid du Colombier } 339*3e12c5d1SDavid du Colombier break; 340*3e12c5d1SDavid du Colombier } 341*3e12c5d1SDavid du Colombier } 342*3e12c5d1SDavid du Colombier 343*3e12c5d1SDavid du Colombier void 344*3e12c5d1SDavid du Colombier noretval(int n) 345*3e12c5d1SDavid du Colombier { 346*3e12c5d1SDavid du Colombier 347*3e12c5d1SDavid du Colombier if(n & 1) { 348*3e12c5d1SDavid du Colombier gins(ANOP, Z, Z); 349*3e12c5d1SDavid du Colombier p->to.type = D_REG; 350*3e12c5d1SDavid du Colombier p->to.reg = REGRET; 351*3e12c5d1SDavid du Colombier } 352*3e12c5d1SDavid du Colombier if(n & 2) { 353*3e12c5d1SDavid du Colombier gins(ANOP, Z, Z); 354*3e12c5d1SDavid du Colombier p->to.type = D_FREG; 355*3e12c5d1SDavid du Colombier p->to.reg = FREGRET; 356*3e12c5d1SDavid du Colombier } 357*3e12c5d1SDavid du Colombier } 358*3e12c5d1SDavid du Colombier 359*3e12c5d1SDavid du Colombier /* 360*3e12c5d1SDavid du Colombier * calculate addressability as follows 361*3e12c5d1SDavid du Colombier * CONST ==> 20 $value 362*3e12c5d1SDavid du Colombier * NAME ==> 10 name 363*3e12c5d1SDavid du Colombier * REGISTER ==> 11 register 364*3e12c5d1SDavid du Colombier * INDREG ==> 12 *[(reg)+offset] 365*3e12c5d1SDavid du Colombier * &10 ==> 2 $name 366*3e12c5d1SDavid du Colombier * ADD(2, 20) ==> 2 $name+offset 367*3e12c5d1SDavid du Colombier * ADD(3, 20) ==> 3 $(reg)+offset 368*3e12c5d1SDavid du Colombier * &12 ==> 3 $(reg)+offset 369*3e12c5d1SDavid du Colombier * *11 ==> 11 ?? 370*3e12c5d1SDavid du Colombier * *2 ==> 10 name 371*3e12c5d1SDavid du Colombier * *3 ==> 12 *(reg)+offset 372*3e12c5d1SDavid du Colombier * calculate complexity (number of registers) 373*3e12c5d1SDavid du Colombier */ 374*3e12c5d1SDavid du Colombier void 375*3e12c5d1SDavid du Colombier xcom(Node *n) 376*3e12c5d1SDavid du Colombier { 377*3e12c5d1SDavid du Colombier Node *l, *r; 378*3e12c5d1SDavid du Colombier int t; 379*3e12c5d1SDavid du Colombier 380*3e12c5d1SDavid du Colombier if(n == Z) 381*3e12c5d1SDavid du Colombier return; 382*3e12c5d1SDavid du Colombier l = n->left; 383*3e12c5d1SDavid du Colombier r = n->right; 384*3e12c5d1SDavid du Colombier n->addable = 0; 385*3e12c5d1SDavid du Colombier n->complex = 0; 386*3e12c5d1SDavid du Colombier switch(n->op) { 387*3e12c5d1SDavid du Colombier case OCONST: 388*3e12c5d1SDavid du Colombier n->addable = 20; 389*3e12c5d1SDavid du Colombier return; 390*3e12c5d1SDavid du Colombier 391*3e12c5d1SDavid du Colombier case OREGISTER: 392*3e12c5d1SDavid du Colombier n->addable = 11; 393*3e12c5d1SDavid du Colombier return; 394*3e12c5d1SDavid du Colombier 395*3e12c5d1SDavid du Colombier case OINDREG: 396*3e12c5d1SDavid du Colombier n->addable = 12; 397*3e12c5d1SDavid du Colombier return; 398*3e12c5d1SDavid du Colombier 399*3e12c5d1SDavid du Colombier case ONAME: 400*3e12c5d1SDavid du Colombier n->addable = 10; 401*3e12c5d1SDavid du Colombier return; 402*3e12c5d1SDavid du Colombier 403*3e12c5d1SDavid du Colombier case OADDR: 404*3e12c5d1SDavid du Colombier xcom(l); 405*3e12c5d1SDavid du Colombier if(l->addable == 10) 406*3e12c5d1SDavid du Colombier n->addable = 2; 407*3e12c5d1SDavid du Colombier if(l->addable == 12) 408*3e12c5d1SDavid du Colombier n->addable = 3; 409*3e12c5d1SDavid du Colombier break; 410*3e12c5d1SDavid du Colombier 411*3e12c5d1SDavid du Colombier case OIND: 412*3e12c5d1SDavid du Colombier xcom(l); 413*3e12c5d1SDavid du Colombier if(l->addable == 11) 414*3e12c5d1SDavid du Colombier n->addable = 12; 415*3e12c5d1SDavid du Colombier if(l->addable == 3) 416*3e12c5d1SDavid du Colombier n->addable = 12; 417*3e12c5d1SDavid du Colombier if(l->addable == 2) 418*3e12c5d1SDavid du Colombier n->addable = 10; 419*3e12c5d1SDavid du Colombier break; 420*3e12c5d1SDavid du Colombier 421*3e12c5d1SDavid du Colombier case OADD: 422*3e12c5d1SDavid du Colombier xcom(l); 423*3e12c5d1SDavid du Colombier xcom(r); 424*3e12c5d1SDavid du Colombier if(l->addable == 20) { 425*3e12c5d1SDavid du Colombier if(r->addable == 2) 426*3e12c5d1SDavid du Colombier n->addable = 2; 427*3e12c5d1SDavid du Colombier if(r->addable == 3) 428*3e12c5d1SDavid du Colombier n->addable = 3; 429*3e12c5d1SDavid du Colombier } 430*3e12c5d1SDavid du Colombier if(r->addable == 20) { 431*3e12c5d1SDavid du Colombier if(l->addable == 2) 432*3e12c5d1SDavid du Colombier n->addable = 2; 433*3e12c5d1SDavid du Colombier if(l->addable == 3) 434*3e12c5d1SDavid du Colombier n->addable = 3; 435*3e12c5d1SDavid du Colombier } 436*3e12c5d1SDavid du Colombier break; 437*3e12c5d1SDavid du Colombier 438*3e12c5d1SDavid du Colombier case OASLMUL: 439*3e12c5d1SDavid du Colombier case OASMUL: 440*3e12c5d1SDavid du Colombier xcom(l); 441*3e12c5d1SDavid du Colombier xcom(r); 442*3e12c5d1SDavid du Colombier t = vlog(r); 443*3e12c5d1SDavid du Colombier if(t >= 0) { 444*3e12c5d1SDavid du Colombier n->op = OASASHL; 445*3e12c5d1SDavid du Colombier r->offset = t; 446*3e12c5d1SDavid du Colombier } 447*3e12c5d1SDavid du Colombier break; 448*3e12c5d1SDavid du Colombier 449*3e12c5d1SDavid du Colombier case OMUL: 450*3e12c5d1SDavid du Colombier case OLMUL: 451*3e12c5d1SDavid du Colombier xcom(l); 452*3e12c5d1SDavid du Colombier xcom(r); 453*3e12c5d1SDavid du Colombier t = vlog(r); 454*3e12c5d1SDavid du Colombier if(t >= 0) { 455*3e12c5d1SDavid du Colombier n->op = OASHL; 456*3e12c5d1SDavid du Colombier r->offset = t; 457*3e12c5d1SDavid du Colombier } 458*3e12c5d1SDavid du Colombier t = vlog(l); 459*3e12c5d1SDavid du Colombier if(t >= 0) { 460*3e12c5d1SDavid du Colombier n->op = OASHL; 461*3e12c5d1SDavid du Colombier n->left = r; 462*3e12c5d1SDavid du Colombier n->right = l; 463*3e12c5d1SDavid du Colombier r = l; 464*3e12c5d1SDavid du Colombier l = n->left; 465*3e12c5d1SDavid du Colombier r->offset = t; 466*3e12c5d1SDavid du Colombier } 467*3e12c5d1SDavid du Colombier break; 468*3e12c5d1SDavid du Colombier 469*3e12c5d1SDavid du Colombier case OASLDIV: 470*3e12c5d1SDavid du Colombier xcom(l); 471*3e12c5d1SDavid du Colombier xcom(r); 472*3e12c5d1SDavid du Colombier t = vlog(r); 473*3e12c5d1SDavid du Colombier if(t >= 0) { 474*3e12c5d1SDavid du Colombier n->op = OASLSHR; 475*3e12c5d1SDavid du Colombier r->offset = t; 476*3e12c5d1SDavid du Colombier } 477*3e12c5d1SDavid du Colombier break; 478*3e12c5d1SDavid du Colombier 479*3e12c5d1SDavid du Colombier case OLDIV: 480*3e12c5d1SDavid du Colombier xcom(l); 481*3e12c5d1SDavid du Colombier xcom(r); 482*3e12c5d1SDavid du Colombier t = vlog(r); 483*3e12c5d1SDavid du Colombier if(t >= 0) { 484*3e12c5d1SDavid du Colombier n->op = OLSHR; 485*3e12c5d1SDavid du Colombier r->offset = t; 486*3e12c5d1SDavid du Colombier } 487*3e12c5d1SDavid du Colombier break; 488*3e12c5d1SDavid du Colombier 489*3e12c5d1SDavid du Colombier case OASLMOD: 490*3e12c5d1SDavid du Colombier xcom(l); 491*3e12c5d1SDavid du Colombier xcom(r); 492*3e12c5d1SDavid du Colombier t = vlog(r); 493*3e12c5d1SDavid du Colombier if(t >= 0) { 494*3e12c5d1SDavid du Colombier n->op = OASAND; 495*3e12c5d1SDavid du Colombier r->offset--; 496*3e12c5d1SDavid du Colombier } 497*3e12c5d1SDavid du Colombier break; 498*3e12c5d1SDavid du Colombier 499*3e12c5d1SDavid du Colombier case OLMOD: 500*3e12c5d1SDavid du Colombier xcom(l); 501*3e12c5d1SDavid du Colombier xcom(r); 502*3e12c5d1SDavid du Colombier t = vlog(r); 503*3e12c5d1SDavid du Colombier if(t >= 0) { 504*3e12c5d1SDavid du Colombier n->op = OAND; 505*3e12c5d1SDavid du Colombier r->offset--; 506*3e12c5d1SDavid du Colombier } 507*3e12c5d1SDavid du Colombier break; 508*3e12c5d1SDavid du Colombier 509*3e12c5d1SDavid du Colombier default: 510*3e12c5d1SDavid du Colombier if(l != Z) 511*3e12c5d1SDavid du Colombier xcom(l); 512*3e12c5d1SDavid du Colombier if(r != Z) 513*3e12c5d1SDavid du Colombier xcom(r); 514*3e12c5d1SDavid du Colombier break; 515*3e12c5d1SDavid du Colombier } 516*3e12c5d1SDavid du Colombier if(n->addable >= 10) 517*3e12c5d1SDavid du Colombier return; 518*3e12c5d1SDavid du Colombier if(l != Z) 519*3e12c5d1SDavid du Colombier n->complex = l->complex; 520*3e12c5d1SDavid du Colombier if(r != Z) { 521*3e12c5d1SDavid du Colombier if(r->complex == n->complex) 522*3e12c5d1SDavid du Colombier n->complex = r->complex+1; else 523*3e12c5d1SDavid du Colombier if(r->complex > n->complex) 524*3e12c5d1SDavid du Colombier n->complex = r->complex; 525*3e12c5d1SDavid du Colombier } 526*3e12c5d1SDavid du Colombier if(n->complex == 0) 527*3e12c5d1SDavid du Colombier n->complex++; 528*3e12c5d1SDavid du Colombier switch(n->op) { 529*3e12c5d1SDavid du Colombier 530*3e12c5d1SDavid du Colombier case OFUNC: 531*3e12c5d1SDavid du Colombier n->complex = FNX; 532*3e12c5d1SDavid du Colombier break; 533*3e12c5d1SDavid du Colombier 534*3e12c5d1SDavid du Colombier case OADD: 535*3e12c5d1SDavid du Colombier case OXOR: 536*3e12c5d1SDavid du Colombier case OAND: 537*3e12c5d1SDavid du Colombier case OOR: 538*3e12c5d1SDavid du Colombier case OEQ: 539*3e12c5d1SDavid du Colombier case ONE: 540*3e12c5d1SDavid du Colombier /* 541*3e12c5d1SDavid du Colombier * immediate operators, make const on right 542*3e12c5d1SDavid du Colombier */ 543*3e12c5d1SDavid du Colombier if(l->op == OCONST) { 544*3e12c5d1SDavid du Colombier n->left = r; 545*3e12c5d1SDavid du Colombier n->right = l; 546*3e12c5d1SDavid du Colombier } 547*3e12c5d1SDavid du Colombier break; 548*3e12c5d1SDavid du Colombier } 549*3e12c5d1SDavid du Colombier } 550*3e12c5d1SDavid du Colombier 551*3e12c5d1SDavid du Colombier void 552*3e12c5d1SDavid du Colombier bcomplex(Node *n) 553*3e12c5d1SDavid du Colombier { 554*3e12c5d1SDavid du Colombier 555*3e12c5d1SDavid du Colombier complex(n); 556*3e12c5d1SDavid du Colombier if(n->type != T) 557*3e12c5d1SDavid du Colombier if(tcompat(n, T, n->type, tnot)) 558*3e12c5d1SDavid du Colombier n->type = T; 559*3e12c5d1SDavid du Colombier if(n->type != T) { 560*3e12c5d1SDavid du Colombier boolgen(n, 1, Z); 561*3e12c5d1SDavid du Colombier } else 562*3e12c5d1SDavid du Colombier gbranch(OGOTO); 563*3e12c5d1SDavid du Colombier } 564