1*3e12c5d1SDavid du Colombier #include "gc.h" 2*3e12c5d1SDavid du Colombier 3*3e12c5d1SDavid du Colombier void 4*3e12c5d1SDavid du Colombier cgen(Node *n, Node *nn) 5*3e12c5d1SDavid du Colombier { 6*3e12c5d1SDavid du Colombier Node *l, *r; 7*3e12c5d1SDavid du Colombier Prog *p1; 8*3e12c5d1SDavid du Colombier Node nod, nod1, nod2, nod3, nod4; 9*3e12c5d1SDavid du Colombier int o; 10*3e12c5d1SDavid du Colombier long v, curs; 11*3e12c5d1SDavid du Colombier 12*3e12c5d1SDavid du Colombier if(debug['g']) { 13*3e12c5d1SDavid du Colombier prtree(nn, "cgen lhs"); 14*3e12c5d1SDavid du Colombier prtree(n, "cgen"); 15*3e12c5d1SDavid du Colombier } 16*3e12c5d1SDavid du Colombier if(n == Z || n->type == T) 17*3e12c5d1SDavid du Colombier return; 18*3e12c5d1SDavid du Colombier if(typesu[n->type->etype]) { 19*3e12c5d1SDavid du Colombier sugen(n, nn, n->type->width); 20*3e12c5d1SDavid du Colombier return; 21*3e12c5d1SDavid du Colombier } 22*3e12c5d1SDavid du Colombier if(n->addable > INDEXED) { 23*3e12c5d1SDavid du Colombier if(nn != Z) 24*3e12c5d1SDavid du Colombier gmove(n, nn); 25*3e12c5d1SDavid du Colombier return; 26*3e12c5d1SDavid du Colombier } 27*3e12c5d1SDavid du Colombier curs = cursafe; 28*3e12c5d1SDavid du Colombier l = n->left; 29*3e12c5d1SDavid du Colombier r = n->right; 30*3e12c5d1SDavid du Colombier o = n->op; 31*3e12c5d1SDavid du Colombier 32*3e12c5d1SDavid du Colombier if(n->complex >= FNX) 33*3e12c5d1SDavid du Colombier if(l->complex >= FNX) 34*3e12c5d1SDavid du Colombier if(r != Z && r->complex >= FNX) 35*3e12c5d1SDavid du Colombier switch(o) { 36*3e12c5d1SDavid du Colombier default: 37*3e12c5d1SDavid du Colombier regret(&nod, r); 38*3e12c5d1SDavid du Colombier cgen(r, &nod); 39*3e12c5d1SDavid du Colombier 40*3e12c5d1SDavid du Colombier regsalloc(&nod1, r); 41*3e12c5d1SDavid du Colombier gopcode(OAS, &nod, Z, &nod1); 42*3e12c5d1SDavid du Colombier 43*3e12c5d1SDavid du Colombier regfree(&nod); 44*3e12c5d1SDavid du Colombier nod = *n; 45*3e12c5d1SDavid du Colombier nod.right = &nod1; 46*3e12c5d1SDavid du Colombier cgen(&nod, nn); 47*3e12c5d1SDavid du Colombier return; 48*3e12c5d1SDavid du Colombier 49*3e12c5d1SDavid du Colombier case OFUNC: 50*3e12c5d1SDavid du Colombier case OCOMMA: 51*3e12c5d1SDavid du Colombier case OANDAND: 52*3e12c5d1SDavid du Colombier case OOROR: 53*3e12c5d1SDavid du Colombier case OCOND: 54*3e12c5d1SDavid du Colombier case ODOT: 55*3e12c5d1SDavid du Colombier break; 56*3e12c5d1SDavid du Colombier } 57*3e12c5d1SDavid du Colombier 58*3e12c5d1SDavid du Colombier switch(o) { 59*3e12c5d1SDavid du Colombier default: 60*3e12c5d1SDavid du Colombier diag(n, "unknown op in cgen: %O", o); 61*3e12c5d1SDavid du Colombier break; 62*3e12c5d1SDavid du Colombier 63*3e12c5d1SDavid du Colombier case OAS: 64*3e12c5d1SDavid du Colombier if(l->op == OBIT) 65*3e12c5d1SDavid du Colombier goto bitas; 66*3e12c5d1SDavid du Colombier if(l->addable >= INDEXED && l->complex < FNX) { 67*3e12c5d1SDavid du Colombier if(nn != Z || r->addable < INDEXED) { 68*3e12c5d1SDavid du Colombier regalloc(&nod, r, nn); 69*3e12c5d1SDavid du Colombier cgen(r, &nod); 70*3e12c5d1SDavid du Colombier gmove(&nod, l); 71*3e12c5d1SDavid du Colombier regfree(&nod); 72*3e12c5d1SDavid du Colombier } else 73*3e12c5d1SDavid du Colombier gmove(r, l); 74*3e12c5d1SDavid du Colombier break; 75*3e12c5d1SDavid du Colombier } 76*3e12c5d1SDavid du Colombier if(l->complex >= r->complex) { 77*3e12c5d1SDavid du Colombier reglcgen(&nod1, l, Z); 78*3e12c5d1SDavid du Colombier if(r->addable >= INDEXED) { 79*3e12c5d1SDavid du Colombier gmove(r, &nod1); 80*3e12c5d1SDavid du Colombier if(nn != Z) 81*3e12c5d1SDavid du Colombier gmove(r, nn); 82*3e12c5d1SDavid du Colombier regfree(&nod1); 83*3e12c5d1SDavid du Colombier break; 84*3e12c5d1SDavid du Colombier } 85*3e12c5d1SDavid du Colombier regalloc(&nod, r, nn); 86*3e12c5d1SDavid du Colombier cgen(r, &nod); 87*3e12c5d1SDavid du Colombier } else { 88*3e12c5d1SDavid du Colombier regalloc(&nod, r, nn); 89*3e12c5d1SDavid du Colombier cgen(r, &nod); 90*3e12c5d1SDavid du Colombier reglcgen(&nod1, l, Z); 91*3e12c5d1SDavid du Colombier } 92*3e12c5d1SDavid du Colombier gmove(&nod, &nod1); 93*3e12c5d1SDavid du Colombier regfree(&nod); 94*3e12c5d1SDavid du Colombier regfree(&nod1); 95*3e12c5d1SDavid du Colombier break; 96*3e12c5d1SDavid du Colombier 97*3e12c5d1SDavid du Colombier bitas: 98*3e12c5d1SDavid du Colombier n = l->left; 99*3e12c5d1SDavid du Colombier regalloc(&nod, r, nn); 100*3e12c5d1SDavid du Colombier if(l->complex >= r->complex) { 101*3e12c5d1SDavid du Colombier reglcgen(&nod1, n, Z); 102*3e12c5d1SDavid du Colombier cgen(r, &nod); 103*3e12c5d1SDavid du Colombier } else { 104*3e12c5d1SDavid du Colombier cgen(r, &nod); 105*3e12c5d1SDavid du Colombier reglcgen(&nod1, n, Z); 106*3e12c5d1SDavid du Colombier } 107*3e12c5d1SDavid du Colombier regalloc(&nod2, n, Z); 108*3e12c5d1SDavid du Colombier gopcode(OAS, &nod1, Z, &nod2); 109*3e12c5d1SDavid du Colombier bitstore(l, &nod, &nod1, &nod2, nn); 110*3e12c5d1SDavid du Colombier break; 111*3e12c5d1SDavid du Colombier 112*3e12c5d1SDavid du Colombier case OBIT: 113*3e12c5d1SDavid du Colombier if(nn == Z) { 114*3e12c5d1SDavid du Colombier nullwarn(l, Z); 115*3e12c5d1SDavid du Colombier break; 116*3e12c5d1SDavid du Colombier } 117*3e12c5d1SDavid du Colombier bitload(n, &nod, Z, Z, nn); 118*3e12c5d1SDavid du Colombier gopcode(OAS, &nod, Z, nn); 119*3e12c5d1SDavid du Colombier regfree(&nod); 120*3e12c5d1SDavid du Colombier break; 121*3e12c5d1SDavid du Colombier 122*3e12c5d1SDavid du Colombier case OADD: 123*3e12c5d1SDavid du Colombier case OSUB: 124*3e12c5d1SDavid du Colombier case OAND: 125*3e12c5d1SDavid du Colombier case OOR: 126*3e12c5d1SDavid du Colombier case OXOR: 127*3e12c5d1SDavid du Colombier case OLSHR: 128*3e12c5d1SDavid du Colombier case OASHL: 129*3e12c5d1SDavid du Colombier case OASHR: 130*3e12c5d1SDavid du Colombier /* 131*3e12c5d1SDavid du Colombier * immediate operands 132*3e12c5d1SDavid du Colombier */ 133*3e12c5d1SDavid du Colombier if(nn != Z) 134*3e12c5d1SDavid du Colombier if(r->op == OCONST) 135*3e12c5d1SDavid du Colombier if(!typefdv[n->type->etype]) { 136*3e12c5d1SDavid du Colombier cgen(l, nn); 137*3e12c5d1SDavid du Colombier if(r->offset == 0) 138*3e12c5d1SDavid du Colombier if(o != OAND) 139*3e12c5d1SDavid du Colombier break; 140*3e12c5d1SDavid du Colombier if(nn != Z) 141*3e12c5d1SDavid du Colombier gopcode(o, r, Z, nn); 142*3e12c5d1SDavid du Colombier break; 143*3e12c5d1SDavid du Colombier } 144*3e12c5d1SDavid du Colombier 145*3e12c5d1SDavid du Colombier case OLMUL: 146*3e12c5d1SDavid du Colombier case OLDIV: 147*3e12c5d1SDavid du Colombier case OLMOD: 148*3e12c5d1SDavid du Colombier case OMUL: 149*3e12c5d1SDavid du Colombier case ODIV: 150*3e12c5d1SDavid du Colombier case OMOD: 151*3e12c5d1SDavid du Colombier if(nn == Z) { 152*3e12c5d1SDavid du Colombier nullwarn(l, r); 153*3e12c5d1SDavid du Colombier break; 154*3e12c5d1SDavid du Colombier } 155*3e12c5d1SDavid du Colombier if(l->complex >= r->complex) { 156*3e12c5d1SDavid du Colombier regalloc(&nod, l, nn); 157*3e12c5d1SDavid du Colombier cgen(l, &nod); 158*3e12c5d1SDavid du Colombier regalloc(&nod1, r, Z); 159*3e12c5d1SDavid du Colombier cgen(r, &nod1); 160*3e12c5d1SDavid du Colombier gopcode(o, &nod1, Z, &nod); 161*3e12c5d1SDavid du Colombier } else { 162*3e12c5d1SDavid du Colombier regalloc(&nod, r, nn); 163*3e12c5d1SDavid du Colombier cgen(r, &nod); 164*3e12c5d1SDavid du Colombier regalloc(&nod1, l, Z); 165*3e12c5d1SDavid du Colombier cgen(l, &nod1); 166*3e12c5d1SDavid du Colombier gopcode(o, &nod, &nod1, &nod); 167*3e12c5d1SDavid du Colombier } 168*3e12c5d1SDavid du Colombier gopcode(OAS, &nod, Z, nn); 169*3e12c5d1SDavid du Colombier regfree(&nod); 170*3e12c5d1SDavid du Colombier regfree(&nod1); 171*3e12c5d1SDavid du Colombier break; 172*3e12c5d1SDavid du Colombier 173*3e12c5d1SDavid du Colombier case OASLSHR: 174*3e12c5d1SDavid du Colombier case OASASHL: 175*3e12c5d1SDavid du Colombier case OASASHR: 176*3e12c5d1SDavid du Colombier case OASAND: 177*3e12c5d1SDavid du Colombier case OASADD: 178*3e12c5d1SDavid du Colombier case OASSUB: 179*3e12c5d1SDavid du Colombier case OASXOR: 180*3e12c5d1SDavid du Colombier case OASOR: 181*3e12c5d1SDavid du Colombier while(l->op == OCAST) 182*3e12c5d1SDavid du Colombier l = l->left; 183*3e12c5d1SDavid du Colombier if(l->op == OBIT) 184*3e12c5d1SDavid du Colombier goto asbitop; 185*3e12c5d1SDavid du Colombier if(r->op == OCONST) 186*3e12c5d1SDavid du Colombier if(!typefdv[n->type->etype]) { 187*3e12c5d1SDavid du Colombier if(l->addable < INDEXED) 188*3e12c5d1SDavid du Colombier reglcgen(&nod2, l, Z); 189*3e12c5d1SDavid du Colombier else 190*3e12c5d1SDavid du Colombier nod2 = *l; 191*3e12c5d1SDavid du Colombier regalloc(&nod, r, nn); 192*3e12c5d1SDavid du Colombier gopcode(OAS, &nod2, Z, &nod); 193*3e12c5d1SDavid du Colombier gopcode(o, r, Z, &nod); 194*3e12c5d1SDavid du Colombier gopcode(OAS, &nod, Z, &nod2); 195*3e12c5d1SDavid du Colombier 196*3e12c5d1SDavid du Colombier regfree(&nod); 197*3e12c5d1SDavid du Colombier if(l->addable < INDEXED) 198*3e12c5d1SDavid du Colombier regfree(&nod2); 199*3e12c5d1SDavid du Colombier break; 200*3e12c5d1SDavid du Colombier } 201*3e12c5d1SDavid du Colombier 202*3e12c5d1SDavid du Colombier case OASLMUL: 203*3e12c5d1SDavid du Colombier case OASLDIV: 204*3e12c5d1SDavid du Colombier case OASLMOD: 205*3e12c5d1SDavid du Colombier case OASMUL: 206*3e12c5d1SDavid du Colombier case OASDIV: 207*3e12c5d1SDavid du Colombier case OASMOD: 208*3e12c5d1SDavid du Colombier while(l->op == OCAST) 209*3e12c5d1SDavid du Colombier l = l->left; 210*3e12c5d1SDavid du Colombier if(l->op == OBIT) 211*3e12c5d1SDavid du Colombier goto asbitop; 212*3e12c5d1SDavid du Colombier if(l->complex >= r->complex) { 213*3e12c5d1SDavid du Colombier if(l->addable < INDEXED) 214*3e12c5d1SDavid du Colombier reglcgen(&nod2, l, Z); 215*3e12c5d1SDavid du Colombier else 216*3e12c5d1SDavid du Colombier nod2 = *l; 217*3e12c5d1SDavid du Colombier regalloc(&nod1, r, Z); 218*3e12c5d1SDavid du Colombier cgen(r, &nod1); 219*3e12c5d1SDavid du Colombier } else { 220*3e12c5d1SDavid du Colombier regalloc(&nod1, r, Z); 221*3e12c5d1SDavid du Colombier cgen(r, &nod1); 222*3e12c5d1SDavid du Colombier if(l->addable < INDEXED) 223*3e12c5d1SDavid du Colombier reglcgen(&nod2, l, Z); 224*3e12c5d1SDavid du Colombier else 225*3e12c5d1SDavid du Colombier nod2 = *l; 226*3e12c5d1SDavid du Colombier } 227*3e12c5d1SDavid du Colombier 228*3e12c5d1SDavid du Colombier regalloc(&nod, n, nn); 229*3e12c5d1SDavid du Colombier gmove(&nod2, &nod); 230*3e12c5d1SDavid du Colombier gopcode(o, &nod1, Z, &nod); 231*3e12c5d1SDavid du Colombier gmove(&nod, &nod2); 232*3e12c5d1SDavid du Colombier if(nn != Z) 233*3e12c5d1SDavid du Colombier gopcode(OAS, &nod, Z, nn); 234*3e12c5d1SDavid du Colombier regfree(&nod); 235*3e12c5d1SDavid du Colombier regfree(&nod1); 236*3e12c5d1SDavid du Colombier if(l->addable < INDEXED) 237*3e12c5d1SDavid du Colombier regfree(&nod2); 238*3e12c5d1SDavid du Colombier break; 239*3e12c5d1SDavid du Colombier 240*3e12c5d1SDavid du Colombier asbitop: 241*3e12c5d1SDavid du Colombier regalloc(&nod4, n, nn); 242*3e12c5d1SDavid du Colombier if(l->complex >= r->complex) { 243*3e12c5d1SDavid du Colombier bitload(l, &nod, &nod1, &nod2, &nod4); 244*3e12c5d1SDavid du Colombier regalloc(&nod3, r, Z); 245*3e12c5d1SDavid du Colombier cgen(r, &nod3); 246*3e12c5d1SDavid du Colombier } else { 247*3e12c5d1SDavid du Colombier regalloc(&nod3, r, Z); 248*3e12c5d1SDavid du Colombier cgen(r, &nod3); 249*3e12c5d1SDavid du Colombier bitload(l, &nod, &nod1, &nod2, &nod4); 250*3e12c5d1SDavid du Colombier } 251*3e12c5d1SDavid du Colombier gmove(&nod, &nod4); 252*3e12c5d1SDavid du Colombier gopcode(o, &nod3, Z, &nod4); 253*3e12c5d1SDavid du Colombier regfree(&nod3); 254*3e12c5d1SDavid du Colombier gmove(&nod4, &nod); 255*3e12c5d1SDavid du Colombier regfree(&nod4); 256*3e12c5d1SDavid du Colombier bitstore(l, &nod, &nod1, &nod2, nn); 257*3e12c5d1SDavid du Colombier break; 258*3e12c5d1SDavid du Colombier 259*3e12c5d1SDavid du Colombier case OADDR: 260*3e12c5d1SDavid du Colombier if(nn == Z) { 261*3e12c5d1SDavid du Colombier nullwarn(l, Z); 262*3e12c5d1SDavid du Colombier break; 263*3e12c5d1SDavid du Colombier } 264*3e12c5d1SDavid du Colombier lcgen(l, nn); 265*3e12c5d1SDavid du Colombier break; 266*3e12c5d1SDavid du Colombier 267*3e12c5d1SDavid du Colombier case OFUNC: 268*3e12c5d1SDavid du Colombier if(l->complex >= FNX) { 269*3e12c5d1SDavid du Colombier if(l->op != OIND) 270*3e12c5d1SDavid du Colombier diag(n, "bad function call"); 271*3e12c5d1SDavid du Colombier 272*3e12c5d1SDavid du Colombier regret(&nod, l->left); 273*3e12c5d1SDavid du Colombier cgen(l->left, &nod); 274*3e12c5d1SDavid du Colombier regsalloc(&nod1, l->left); 275*3e12c5d1SDavid du Colombier gopcode(OAS, &nod, Z, &nod1); 276*3e12c5d1SDavid du Colombier regfree(&nod); 277*3e12c5d1SDavid du Colombier 278*3e12c5d1SDavid du Colombier nod = *n; 279*3e12c5d1SDavid du Colombier nod.left = &nod2; 280*3e12c5d1SDavid du Colombier nod2 = *l; 281*3e12c5d1SDavid du Colombier nod2.left = &nod1; 282*3e12c5d1SDavid du Colombier nod2.complex = 1; 283*3e12c5d1SDavid du Colombier cgen(&nod, nn); 284*3e12c5d1SDavid du Colombier 285*3e12c5d1SDavid du Colombier return; 286*3e12c5d1SDavid du Colombier } 287*3e12c5d1SDavid du Colombier o = reg[REGARG]; 288*3e12c5d1SDavid du Colombier gargs(r, &nod, &nod1); 289*3e12c5d1SDavid du Colombier if(l->addable < INDEXED) { 290*3e12c5d1SDavid du Colombier reglcgen(&nod, l, Z); 291*3e12c5d1SDavid du Colombier gopcode(OFUNC, Z, Z, &nod); 292*3e12c5d1SDavid du Colombier regfree(&nod); 293*3e12c5d1SDavid du Colombier } else 294*3e12c5d1SDavid du Colombier gopcode(OFUNC, Z, Z, l); 295*3e12c5d1SDavid du Colombier if(REGARG) 296*3e12c5d1SDavid du Colombier if(o != reg[REGARG]) 297*3e12c5d1SDavid du Colombier reg[REGARG]--; 298*3e12c5d1SDavid du Colombier if(nn != Z) { 299*3e12c5d1SDavid du Colombier regret(&nod, n); 300*3e12c5d1SDavid du Colombier gopcode(OAS, &nod, Z, nn); 301*3e12c5d1SDavid du Colombier regfree(&nod); 302*3e12c5d1SDavid du Colombier } 303*3e12c5d1SDavid du Colombier break; 304*3e12c5d1SDavid du Colombier 305*3e12c5d1SDavid du Colombier case OIND: 306*3e12c5d1SDavid du Colombier if(nn == Z) { 307*3e12c5d1SDavid du Colombier nullwarn(l, Z); 308*3e12c5d1SDavid du Colombier break; 309*3e12c5d1SDavid du Colombier } 310*3e12c5d1SDavid du Colombier regialloc(&nod, n, nn); 311*3e12c5d1SDavid du Colombier r = l; 312*3e12c5d1SDavid du Colombier while(r->op == OADD) 313*3e12c5d1SDavid du Colombier r = r->right; 314*3e12c5d1SDavid du Colombier if(sconst(r)) { 315*3e12c5d1SDavid du Colombier v = r->offset; 316*3e12c5d1SDavid du Colombier r->offset = 0; 317*3e12c5d1SDavid du Colombier cgen(l, &nod); 318*3e12c5d1SDavid du Colombier nod.offset += v; 319*3e12c5d1SDavid du Colombier r->offset = v; 320*3e12c5d1SDavid du Colombier } else 321*3e12c5d1SDavid du Colombier cgen(l, &nod); 322*3e12c5d1SDavid du Colombier regind(&nod, n); 323*3e12c5d1SDavid du Colombier gopcode(OAS, &nod, Z, nn); 324*3e12c5d1SDavid du Colombier regfree(&nod); 325*3e12c5d1SDavid du Colombier break; 326*3e12c5d1SDavid du Colombier 327*3e12c5d1SDavid du Colombier case OEQ: 328*3e12c5d1SDavid du Colombier case ONE: 329*3e12c5d1SDavid du Colombier case OLE: 330*3e12c5d1SDavid du Colombier case OLT: 331*3e12c5d1SDavid du Colombier case OGE: 332*3e12c5d1SDavid du Colombier case OGT: 333*3e12c5d1SDavid du Colombier case OLO: 334*3e12c5d1SDavid du Colombier case OLS: 335*3e12c5d1SDavid du Colombier case OHI: 336*3e12c5d1SDavid du Colombier case OHS: 337*3e12c5d1SDavid du Colombier if(nn == Z) { 338*3e12c5d1SDavid du Colombier nullwarn(l, r); 339*3e12c5d1SDavid du Colombier break; 340*3e12c5d1SDavid du Colombier } 341*3e12c5d1SDavid du Colombier boolgen(n, 1, nn); 342*3e12c5d1SDavid du Colombier break; 343*3e12c5d1SDavid du Colombier 344*3e12c5d1SDavid du Colombier case OANDAND: 345*3e12c5d1SDavid du Colombier case OOROR: 346*3e12c5d1SDavid du Colombier boolgen(n, 1, nn); 347*3e12c5d1SDavid du Colombier if(nn == Z) 348*3e12c5d1SDavid du Colombier patch(p, pc); 349*3e12c5d1SDavid du Colombier break; 350*3e12c5d1SDavid du Colombier 351*3e12c5d1SDavid du Colombier case ONOT: 352*3e12c5d1SDavid du Colombier if(nn == Z) { 353*3e12c5d1SDavid du Colombier nullwarn(l, Z); 354*3e12c5d1SDavid du Colombier break; 355*3e12c5d1SDavid du Colombier } 356*3e12c5d1SDavid du Colombier boolgen(n, 1, nn); 357*3e12c5d1SDavid du Colombier break; 358*3e12c5d1SDavid du Colombier 359*3e12c5d1SDavid du Colombier case OCOMMA: 360*3e12c5d1SDavid du Colombier cgen(l, Z); 361*3e12c5d1SDavid du Colombier cgen(r, nn); 362*3e12c5d1SDavid du Colombier break; 363*3e12c5d1SDavid du Colombier 364*3e12c5d1SDavid du Colombier case OCAST: 365*3e12c5d1SDavid du Colombier if(nn == Z) { 366*3e12c5d1SDavid du Colombier nullwarn(l, Z); 367*3e12c5d1SDavid du Colombier break; 368*3e12c5d1SDavid du Colombier } 369*3e12c5d1SDavid du Colombier /* 370*3e12c5d1SDavid du Colombier * convert from types l->n->nn 371*3e12c5d1SDavid du Colombier */ 372*3e12c5d1SDavid du Colombier if(nocast(l->type, n->type)) { 373*3e12c5d1SDavid du Colombier if(nocast(n->type, nn->type)) { 374*3e12c5d1SDavid du Colombier cgen(l, nn); 375*3e12c5d1SDavid du Colombier break; 376*3e12c5d1SDavid du Colombier } 377*3e12c5d1SDavid du Colombier } 378*3e12c5d1SDavid du Colombier regalloc(&nod, l, nn); 379*3e12c5d1SDavid du Colombier cgen(l, &nod); 380*3e12c5d1SDavid du Colombier regalloc(&nod1, n, &nod); 381*3e12c5d1SDavid du Colombier gopcode(OAS, &nod, Z, &nod1); 382*3e12c5d1SDavid du Colombier gopcode(OAS, &nod1, Z, nn); 383*3e12c5d1SDavid du Colombier regfree(&nod1); 384*3e12c5d1SDavid du Colombier regfree(&nod); 385*3e12c5d1SDavid du Colombier break; 386*3e12c5d1SDavid du Colombier 387*3e12c5d1SDavid du Colombier case ODOT: 388*3e12c5d1SDavid du Colombier sugen(l, nodrat, l->type->width); 389*3e12c5d1SDavid du Colombier if(nn != Z) { 390*3e12c5d1SDavid du Colombier warn(n, "non-interruptable temporary"); 391*3e12c5d1SDavid du Colombier nod = *nodrat; 392*3e12c5d1SDavid du Colombier if(!r || r->op != OCONST) { 393*3e12c5d1SDavid du Colombier diag(n, "DOT and no offset"); 394*3e12c5d1SDavid du Colombier break; 395*3e12c5d1SDavid du Colombier } 396*3e12c5d1SDavid du Colombier nod.offset += r->offset; 397*3e12c5d1SDavid du Colombier nod.type = n->type; 398*3e12c5d1SDavid du Colombier cgen(&nod, nn); 399*3e12c5d1SDavid du Colombier } 400*3e12c5d1SDavid du Colombier break; 401*3e12c5d1SDavid du Colombier 402*3e12c5d1SDavid du Colombier case OCOND: 403*3e12c5d1SDavid du Colombier bcgen(l, 1); 404*3e12c5d1SDavid du Colombier p1 = p; 405*3e12c5d1SDavid du Colombier cgen(r->left, nn); 406*3e12c5d1SDavid du Colombier gbranch(OGOTO); 407*3e12c5d1SDavid du Colombier patch(p1, pc); 408*3e12c5d1SDavid du Colombier p1 = p; 409*3e12c5d1SDavid du Colombier cgen(r->right, nn); 410*3e12c5d1SDavid du Colombier patch(p1, pc); 411*3e12c5d1SDavid du Colombier break; 412*3e12c5d1SDavid du Colombier 413*3e12c5d1SDavid du Colombier case OPOSTINC: 414*3e12c5d1SDavid du Colombier case OPOSTDEC: 415*3e12c5d1SDavid du Colombier v = 1; 416*3e12c5d1SDavid du Colombier if(l->type->etype == TIND) 417*3e12c5d1SDavid du Colombier v = l->type->link->width; 418*3e12c5d1SDavid du Colombier if(o == OPOSTDEC) 419*3e12c5d1SDavid du Colombier v = -v; 420*3e12c5d1SDavid du Colombier if(l->op == OBIT) 421*3e12c5d1SDavid du Colombier goto bitinc; 422*3e12c5d1SDavid du Colombier if(nn == Z) 423*3e12c5d1SDavid du Colombier goto pre; 424*3e12c5d1SDavid du Colombier 425*3e12c5d1SDavid du Colombier if(l->addable < INDEXED) 426*3e12c5d1SDavid du Colombier reglcgen(&nod2, l, Z); 427*3e12c5d1SDavid du Colombier else 428*3e12c5d1SDavid du Colombier nod2 = *l; 429*3e12c5d1SDavid du Colombier 430*3e12c5d1SDavid du Colombier regalloc(&nod, l, nn); 431*3e12c5d1SDavid du Colombier gopcode(OAS, &nod2, Z, &nod); 432*3e12c5d1SDavid du Colombier regalloc(&nod1, l, Z); 433*3e12c5d1SDavid du Colombier if(typefdv[l->type->etype]) { 434*3e12c5d1SDavid du Colombier regalloc(&nod3, l, Z); 435*3e12c5d1SDavid du Colombier if(v < 0) { 436*3e12c5d1SDavid du Colombier gopcode(OAS, nodfconst(-v), Z, &nod3); 437*3e12c5d1SDavid du Colombier gopcode(OSUB, &nod3, &nod, &nod1); 438*3e12c5d1SDavid du Colombier } else { 439*3e12c5d1SDavid du Colombier gopcode(OAS, nodfconst(v), Z, &nod3); 440*3e12c5d1SDavid du Colombier gopcode(OADD, &nod3, &nod, &nod1); 441*3e12c5d1SDavid du Colombier } 442*3e12c5d1SDavid du Colombier regfree(&nod3); 443*3e12c5d1SDavid du Colombier } else 444*3e12c5d1SDavid du Colombier gopcode(OADD, nodconst(v), &nod, &nod1); 445*3e12c5d1SDavid du Colombier gopcode(OAS, &nod1, Z, &nod2); 446*3e12c5d1SDavid du Colombier 447*3e12c5d1SDavid du Colombier regfree(&nod); 448*3e12c5d1SDavid du Colombier regfree(&nod1); 449*3e12c5d1SDavid du Colombier if(l->addable < INDEXED) 450*3e12c5d1SDavid du Colombier regfree(&nod2); 451*3e12c5d1SDavid du Colombier break; 452*3e12c5d1SDavid du Colombier 453*3e12c5d1SDavid du Colombier case OPREINC: 454*3e12c5d1SDavid du Colombier case OPREDEC: 455*3e12c5d1SDavid du Colombier v = 1; 456*3e12c5d1SDavid du Colombier if(l->type->etype == TIND) 457*3e12c5d1SDavid du Colombier v = l->type->link->width; 458*3e12c5d1SDavid du Colombier if(o == OPREDEC) 459*3e12c5d1SDavid du Colombier v = -v; 460*3e12c5d1SDavid du Colombier if(l->op == OBIT) 461*3e12c5d1SDavid du Colombier goto bitinc; 462*3e12c5d1SDavid du Colombier 463*3e12c5d1SDavid du Colombier pre: 464*3e12c5d1SDavid du Colombier if(l->addable < INDEXED) 465*3e12c5d1SDavid du Colombier reglcgen(&nod2, l, Z); 466*3e12c5d1SDavid du Colombier else 467*3e12c5d1SDavid du Colombier nod2 = *l; 468*3e12c5d1SDavid du Colombier 469*3e12c5d1SDavid du Colombier regalloc(&nod, l, nn); 470*3e12c5d1SDavid du Colombier gopcode(OAS, &nod2, Z, &nod); 471*3e12c5d1SDavid du Colombier if(typefdv[l->type->etype]) { 472*3e12c5d1SDavid du Colombier regalloc(&nod3, l, Z); 473*3e12c5d1SDavid du Colombier if(v < 0) { 474*3e12c5d1SDavid du Colombier gopcode(OAS, nodfconst(-v), Z, &nod3); 475*3e12c5d1SDavid du Colombier gopcode(OSUB, &nod3, Z, &nod); 476*3e12c5d1SDavid du Colombier } else { 477*3e12c5d1SDavid du Colombier gopcode(OAS, nodfconst(v), Z, &nod3); 478*3e12c5d1SDavid du Colombier gopcode(OADD, &nod3, Z, &nod); 479*3e12c5d1SDavid du Colombier } 480*3e12c5d1SDavid du Colombier regfree(&nod3); 481*3e12c5d1SDavid du Colombier } else 482*3e12c5d1SDavid du Colombier gopcode(OADD, nodconst(v), Z, &nod); 483*3e12c5d1SDavid du Colombier gopcode(OAS, &nod, Z, &nod2); 484*3e12c5d1SDavid du Colombier 485*3e12c5d1SDavid du Colombier regfree(&nod); 486*3e12c5d1SDavid du Colombier if(l->addable < INDEXED) 487*3e12c5d1SDavid du Colombier regfree(&nod2); 488*3e12c5d1SDavid du Colombier break; 489*3e12c5d1SDavid du Colombier 490*3e12c5d1SDavid du Colombier bitinc: 491*3e12c5d1SDavid du Colombier if(nn != Z && (o == OPOSTINC || o == OPOSTDEC)) { 492*3e12c5d1SDavid du Colombier bitload(l, &nod, &nod1, &nod2, Z); 493*3e12c5d1SDavid du Colombier gopcode(OAS, &nod, Z, nn); 494*3e12c5d1SDavid du Colombier gopcode(OADD, nodconst(v), Z, &nod); 495*3e12c5d1SDavid du Colombier bitstore(l, &nod, &nod1, &nod2, Z); 496*3e12c5d1SDavid du Colombier break; 497*3e12c5d1SDavid du Colombier } 498*3e12c5d1SDavid du Colombier bitload(l, &nod, &nod1, &nod2, nn); 499*3e12c5d1SDavid du Colombier gopcode(OADD, nodconst(v), Z, &nod); 500*3e12c5d1SDavid du Colombier bitstore(l, &nod, &nod1, &nod2, nn); 501*3e12c5d1SDavid du Colombier break; 502*3e12c5d1SDavid du Colombier } 503*3e12c5d1SDavid du Colombier cursafe = curs; 504*3e12c5d1SDavid du Colombier return; 505*3e12c5d1SDavid du Colombier 506*3e12c5d1SDavid du Colombier bad: 507*3e12c5d1SDavid du Colombier cursafe = curs; 508*3e12c5d1SDavid du Colombier diag(n, "%O not implemented", o); 509*3e12c5d1SDavid du Colombier } 510*3e12c5d1SDavid du Colombier 511*3e12c5d1SDavid du Colombier void 512*3e12c5d1SDavid du Colombier reglcgen(Node *t, Node *n, Node *nn) 513*3e12c5d1SDavid du Colombier { 514*3e12c5d1SDavid du Colombier Node *r; 515*3e12c5d1SDavid du Colombier long v; 516*3e12c5d1SDavid du Colombier 517*3e12c5d1SDavid du Colombier regialloc(t, n, nn); 518*3e12c5d1SDavid du Colombier if(n->op == OIND) { 519*3e12c5d1SDavid du Colombier r = n->left; 520*3e12c5d1SDavid du Colombier while(r->op == OADD) 521*3e12c5d1SDavid du Colombier r = r->right; 522*3e12c5d1SDavid du Colombier if(sconst(r)) { 523*3e12c5d1SDavid du Colombier v = r->offset; 524*3e12c5d1SDavid du Colombier r->offset = 0; 525*3e12c5d1SDavid du Colombier lcgen(n, t); 526*3e12c5d1SDavid du Colombier t->offset += v; 527*3e12c5d1SDavid du Colombier r->offset = v; 528*3e12c5d1SDavid du Colombier regind(t, n); 529*3e12c5d1SDavid du Colombier return; 530*3e12c5d1SDavid du Colombier } 531*3e12c5d1SDavid du Colombier } 532*3e12c5d1SDavid du Colombier lcgen(n, t); 533*3e12c5d1SDavid du Colombier regind(t, n); 534*3e12c5d1SDavid du Colombier } 535*3e12c5d1SDavid du Colombier 536*3e12c5d1SDavid du Colombier void 537*3e12c5d1SDavid du Colombier lcgen(Node *n, Node *nn) 538*3e12c5d1SDavid du Colombier { 539*3e12c5d1SDavid du Colombier Prog *p1; 540*3e12c5d1SDavid du Colombier Node nod; 541*3e12c5d1SDavid du Colombier 542*3e12c5d1SDavid du Colombier if(debug['g']) { 543*3e12c5d1SDavid du Colombier prtree(nn, "lcgen lhs"); 544*3e12c5d1SDavid du Colombier prtree(n, "lcgen"); 545*3e12c5d1SDavid du Colombier } 546*3e12c5d1SDavid du Colombier if(n == Z || n->type == T) 547*3e12c5d1SDavid du Colombier return; 548*3e12c5d1SDavid du Colombier if(nn == Z) { 549*3e12c5d1SDavid du Colombier nn = &nod; 550*3e12c5d1SDavid du Colombier regalloc(&nod, n, Z); 551*3e12c5d1SDavid du Colombier } 552*3e12c5d1SDavid du Colombier switch(n->op) { 553*3e12c5d1SDavid du Colombier default: 554*3e12c5d1SDavid du Colombier if(n->addable < INDEXED) { 555*3e12c5d1SDavid du Colombier diag(n, "unknown op in lcgen: %O", n->op); 556*3e12c5d1SDavid du Colombier break; 557*3e12c5d1SDavid du Colombier } 558*3e12c5d1SDavid du Colombier nod = *n; 559*3e12c5d1SDavid du Colombier nod.op = OADDR; 560*3e12c5d1SDavid du Colombier nod.left = n; 561*3e12c5d1SDavid du Colombier nod.right = Z; 562*3e12c5d1SDavid du Colombier nod.type = types[TIND]; 563*3e12c5d1SDavid du Colombier gopcode(OAS, &nod, Z, nn); 564*3e12c5d1SDavid du Colombier break; 565*3e12c5d1SDavid du Colombier 566*3e12c5d1SDavid du Colombier case OCOMMA: 567*3e12c5d1SDavid du Colombier cgen(n->left, n->left); 568*3e12c5d1SDavid du Colombier lcgen(n->right, nn); 569*3e12c5d1SDavid du Colombier break; 570*3e12c5d1SDavid du Colombier 571*3e12c5d1SDavid du Colombier case OIND: 572*3e12c5d1SDavid du Colombier cgen(n->left, nn); 573*3e12c5d1SDavid du Colombier break; 574*3e12c5d1SDavid du Colombier 575*3e12c5d1SDavid du Colombier case OCOND: 576*3e12c5d1SDavid du Colombier bcgen(n->left, 1); 577*3e12c5d1SDavid du Colombier p1 = p; 578*3e12c5d1SDavid du Colombier lcgen(n->right->left, nn); 579*3e12c5d1SDavid du Colombier gbranch(OGOTO); 580*3e12c5d1SDavid du Colombier patch(p1, pc); 581*3e12c5d1SDavid du Colombier p1 = p; 582*3e12c5d1SDavid du Colombier lcgen(n->right->right, nn); 583*3e12c5d1SDavid du Colombier patch(p1, pc); 584*3e12c5d1SDavid du Colombier break; 585*3e12c5d1SDavid du Colombier } 586*3e12c5d1SDavid du Colombier } 587*3e12c5d1SDavid du Colombier 588*3e12c5d1SDavid du Colombier void 589*3e12c5d1SDavid du Colombier bcgen(Node *n, int true) 590*3e12c5d1SDavid du Colombier { 591*3e12c5d1SDavid du Colombier 592*3e12c5d1SDavid du Colombier if(n->type == T) 593*3e12c5d1SDavid du Colombier gbranch(OGOTO); 594*3e12c5d1SDavid du Colombier else 595*3e12c5d1SDavid du Colombier boolgen(n, true, Z); 596*3e12c5d1SDavid du Colombier } 597*3e12c5d1SDavid du Colombier 598*3e12c5d1SDavid du Colombier void 599*3e12c5d1SDavid du Colombier boolgen(Node *n, int true, Node *nn) 600*3e12c5d1SDavid du Colombier { 601*3e12c5d1SDavid du Colombier int o; 602*3e12c5d1SDavid du Colombier Prog *p1, *p2; 603*3e12c5d1SDavid du Colombier Node *l, *r, nod, nod1; 604*3e12c5d1SDavid du Colombier long curs; 605*3e12c5d1SDavid du Colombier 606*3e12c5d1SDavid du Colombier if(debug['g']) { 607*3e12c5d1SDavid du Colombier prtree(nn, "boolgen lhs"); 608*3e12c5d1SDavid du Colombier prtree(n, "boolgen"); 609*3e12c5d1SDavid du Colombier } 610*3e12c5d1SDavid du Colombier curs = cursafe; 611*3e12c5d1SDavid du Colombier l = n->left; 612*3e12c5d1SDavid du Colombier r = n->right; 613*3e12c5d1SDavid du Colombier switch(n->op) { 614*3e12c5d1SDavid du Colombier 615*3e12c5d1SDavid du Colombier default: 616*3e12c5d1SDavid du Colombier regalloc(&nod, n, nn); 617*3e12c5d1SDavid du Colombier cgen(n, &nod); 618*3e12c5d1SDavid du Colombier o = ONE; 619*3e12c5d1SDavid du Colombier if(true) 620*3e12c5d1SDavid du Colombier o = comrel[relindex(o)]; 621*3e12c5d1SDavid du Colombier if(typefdv[n->type->etype]) { 622*3e12c5d1SDavid du Colombier nodreg(&nod1, n, NREG+FREGZERO); 623*3e12c5d1SDavid du Colombier gopcode(o, &nod, &nod1, Z); 624*3e12c5d1SDavid du Colombier } else 625*3e12c5d1SDavid du Colombier gopcode(o, &nod, Z, Z); 626*3e12c5d1SDavid du Colombier regfree(&nod); 627*3e12c5d1SDavid du Colombier goto com; 628*3e12c5d1SDavid du Colombier 629*3e12c5d1SDavid du Colombier case OCONST: 630*3e12c5d1SDavid du Colombier o = vconst(n); 631*3e12c5d1SDavid du Colombier if(!true) 632*3e12c5d1SDavid du Colombier o = !o; 633*3e12c5d1SDavid du Colombier gbranch(OGOTO); 634*3e12c5d1SDavid du Colombier if(o) { 635*3e12c5d1SDavid du Colombier p1 = p; 636*3e12c5d1SDavid du Colombier gbranch(OGOTO); 637*3e12c5d1SDavid du Colombier patch(p1, pc); 638*3e12c5d1SDavid du Colombier } 639*3e12c5d1SDavid du Colombier goto com; 640*3e12c5d1SDavid du Colombier 641*3e12c5d1SDavid du Colombier case OCOMMA: 642*3e12c5d1SDavid du Colombier cgen(l, Z); 643*3e12c5d1SDavid du Colombier boolgen(r, true, nn); 644*3e12c5d1SDavid du Colombier break; 645*3e12c5d1SDavid du Colombier 646*3e12c5d1SDavid du Colombier case ONOT: 647*3e12c5d1SDavid du Colombier boolgen(l, !true, nn); 648*3e12c5d1SDavid du Colombier break; 649*3e12c5d1SDavid du Colombier 650*3e12c5d1SDavid du Colombier case OCOND: 651*3e12c5d1SDavid du Colombier bcgen(l, 1); 652*3e12c5d1SDavid du Colombier p1 = p; 653*3e12c5d1SDavid du Colombier bcgen(r->left, true); 654*3e12c5d1SDavid du Colombier p2 = p; 655*3e12c5d1SDavid du Colombier gbranch(OGOTO); 656*3e12c5d1SDavid du Colombier patch(p1, pc); 657*3e12c5d1SDavid du Colombier p1 = p; 658*3e12c5d1SDavid du Colombier bcgen(r->right, !true); 659*3e12c5d1SDavid du Colombier patch(p2, pc); 660*3e12c5d1SDavid du Colombier p2 = p; 661*3e12c5d1SDavid du Colombier gbranch(OGOTO); 662*3e12c5d1SDavid du Colombier patch(p1, pc); 663*3e12c5d1SDavid du Colombier patch(p2, pc); 664*3e12c5d1SDavid du Colombier goto com; 665*3e12c5d1SDavid du Colombier 666*3e12c5d1SDavid du Colombier case OANDAND: 667*3e12c5d1SDavid du Colombier if(!true) 668*3e12c5d1SDavid du Colombier goto caseor; 669*3e12c5d1SDavid du Colombier 670*3e12c5d1SDavid du Colombier caseand: 671*3e12c5d1SDavid du Colombier bcgen(l, true); 672*3e12c5d1SDavid du Colombier p1 = p; 673*3e12c5d1SDavid du Colombier bcgen(r, !true); 674*3e12c5d1SDavid du Colombier p2 = p; 675*3e12c5d1SDavid du Colombier patch(p1, pc); 676*3e12c5d1SDavid du Colombier gbranch(OGOTO); 677*3e12c5d1SDavid du Colombier patch(p2, pc); 678*3e12c5d1SDavid du Colombier goto com; 679*3e12c5d1SDavid du Colombier 680*3e12c5d1SDavid du Colombier case OOROR: 681*3e12c5d1SDavid du Colombier if(!true) 682*3e12c5d1SDavid du Colombier goto caseand; 683*3e12c5d1SDavid du Colombier 684*3e12c5d1SDavid du Colombier caseor: 685*3e12c5d1SDavid du Colombier bcgen(l, !true); 686*3e12c5d1SDavid du Colombier p1 = p; 687*3e12c5d1SDavid du Colombier bcgen(r, !true); 688*3e12c5d1SDavid du Colombier p2 = p; 689*3e12c5d1SDavid du Colombier gbranch(OGOTO); 690*3e12c5d1SDavid du Colombier patch(p1, pc); 691*3e12c5d1SDavid du Colombier patch(p2, pc); 692*3e12c5d1SDavid du Colombier goto com; 693*3e12c5d1SDavid du Colombier 694*3e12c5d1SDavid du Colombier case OEQ: 695*3e12c5d1SDavid du Colombier case ONE: 696*3e12c5d1SDavid du Colombier case OLE: 697*3e12c5d1SDavid du Colombier case OLT: 698*3e12c5d1SDavid du Colombier case OGE: 699*3e12c5d1SDavid du Colombier case OGT: 700*3e12c5d1SDavid du Colombier case OHI: 701*3e12c5d1SDavid du Colombier case OHS: 702*3e12c5d1SDavid du Colombier case OLO: 703*3e12c5d1SDavid du Colombier case OLS: 704*3e12c5d1SDavid du Colombier o = n->op; 705*3e12c5d1SDavid du Colombier if(true) 706*3e12c5d1SDavid du Colombier o = comrel[relindex(o)]; 707*3e12c5d1SDavid du Colombier if(l->complex >= FNX && r->complex >= FNX) { 708*3e12c5d1SDavid du Colombier regret(&nod, r); 709*3e12c5d1SDavid du Colombier cgen(r, &nod); 710*3e12c5d1SDavid du Colombier regsalloc(&nod1, r); 711*3e12c5d1SDavid du Colombier gopcode(OAS, &nod, Z, &nod1); 712*3e12c5d1SDavid du Colombier regfree(&nod); 713*3e12c5d1SDavid du Colombier nod = *n; 714*3e12c5d1SDavid du Colombier nod.right = &nod1; 715*3e12c5d1SDavid du Colombier boolgen(&nod, true, nn); 716*3e12c5d1SDavid du Colombier break; 717*3e12c5d1SDavid du Colombier } 718*3e12c5d1SDavid du Colombier if(sconst(l)) { 719*3e12c5d1SDavid du Colombier switch(o) { 720*3e12c5d1SDavid du Colombier default: 721*3e12c5d1SDavid du Colombier if(l->offset != 0) 722*3e12c5d1SDavid du Colombier break; 723*3e12c5d1SDavid du Colombier 724*3e12c5d1SDavid du Colombier case OGT: 725*3e12c5d1SDavid du Colombier case OHI: 726*3e12c5d1SDavid du Colombier case OLE: 727*3e12c5d1SDavid du Colombier case OLS: 728*3e12c5d1SDavid du Colombier regalloc(&nod, r, nn); 729*3e12c5d1SDavid du Colombier cgen(r, &nod); 730*3e12c5d1SDavid du Colombier gopcode(o, l, &nod, Z); 731*3e12c5d1SDavid du Colombier regfree(&nod); 732*3e12c5d1SDavid du Colombier goto com; 733*3e12c5d1SDavid du Colombier } 734*3e12c5d1SDavid du Colombier } 735*3e12c5d1SDavid du Colombier if(sconst(r)) { 736*3e12c5d1SDavid du Colombier switch(o) { 737*3e12c5d1SDavid du Colombier default: 738*3e12c5d1SDavid du Colombier if(r->offset != 0) 739*3e12c5d1SDavid du Colombier break; 740*3e12c5d1SDavid du Colombier 741*3e12c5d1SDavid du Colombier case OGE: 742*3e12c5d1SDavid du Colombier case OHS: 743*3e12c5d1SDavid du Colombier case OLT: 744*3e12c5d1SDavid du Colombier case OLO: 745*3e12c5d1SDavid du Colombier regalloc(&nod, l, nn); 746*3e12c5d1SDavid du Colombier cgen(l, &nod); 747*3e12c5d1SDavid du Colombier gopcode(o, &nod, r, Z); 748*3e12c5d1SDavid du Colombier regfree(&nod); 749*3e12c5d1SDavid du Colombier goto com; 750*3e12c5d1SDavid du Colombier } 751*3e12c5d1SDavid du Colombier } 752*3e12c5d1SDavid du Colombier if(l->complex >= r->complex) { 753*3e12c5d1SDavid du Colombier regalloc(&nod1, l, nn); 754*3e12c5d1SDavid du Colombier cgen(l, &nod1); 755*3e12c5d1SDavid du Colombier regalloc(&nod, r, Z); 756*3e12c5d1SDavid du Colombier cgen(r, &nod); 757*3e12c5d1SDavid du Colombier } else { 758*3e12c5d1SDavid du Colombier regalloc(&nod, r, nn); 759*3e12c5d1SDavid du Colombier cgen(r, &nod); 760*3e12c5d1SDavid du Colombier regalloc(&nod1, l, Z); 761*3e12c5d1SDavid du Colombier cgen(l, &nod1); 762*3e12c5d1SDavid du Colombier } 763*3e12c5d1SDavid du Colombier gopcode(o, &nod1, &nod, Z); 764*3e12c5d1SDavid du Colombier regfree(&nod); 765*3e12c5d1SDavid du Colombier regfree(&nod1); 766*3e12c5d1SDavid du Colombier 767*3e12c5d1SDavid du Colombier com: 768*3e12c5d1SDavid du Colombier if(nn != Z) { 769*3e12c5d1SDavid du Colombier p1 = p; 770*3e12c5d1SDavid du Colombier gopcode(OAS, nodconst(1L), Z, nn); 771*3e12c5d1SDavid du Colombier gbranch(OGOTO); 772*3e12c5d1SDavid du Colombier p2 = p; 773*3e12c5d1SDavid du Colombier patch(p1, pc); 774*3e12c5d1SDavid du Colombier gopcode(OAS, nodconst(0L), Z, nn); 775*3e12c5d1SDavid du Colombier patch(p2, pc); 776*3e12c5d1SDavid du Colombier } 777*3e12c5d1SDavid du Colombier break; 778*3e12c5d1SDavid du Colombier } 779*3e12c5d1SDavid du Colombier cursafe = curs; 780*3e12c5d1SDavid du Colombier } 781*3e12c5d1SDavid du Colombier 782*3e12c5d1SDavid du Colombier void 783*3e12c5d1SDavid du Colombier sugen(Node *n, Node *nn, long w) 784*3e12c5d1SDavid du Colombier { 785*3e12c5d1SDavid du Colombier Prog *p1; 786*3e12c5d1SDavid du Colombier Node nod0, nod1, nod2, nod3, nod4, *l, *r; 787*3e12c5d1SDavid du Colombier Type *t; 788*3e12c5d1SDavid du Colombier long pc1; 789*3e12c5d1SDavid du Colombier int i, m, c; 790*3e12c5d1SDavid du Colombier 791*3e12c5d1SDavid du Colombier if(n == Z || n->type == T) 792*3e12c5d1SDavid du Colombier return; 793*3e12c5d1SDavid du Colombier if(debug['g']) { 794*3e12c5d1SDavid du Colombier prtree(nn, "sugen lhs"); 795*3e12c5d1SDavid du Colombier prtree(n, "sugen"); 796*3e12c5d1SDavid du Colombier } 797*3e12c5d1SDavid du Colombier if(nn == nodrat) 798*3e12c5d1SDavid du Colombier if(w > nrathole) 799*3e12c5d1SDavid du Colombier nrathole = w; 800*3e12c5d1SDavid du Colombier switch(n->op) { 801*3e12c5d1SDavid du Colombier case OIND: 802*3e12c5d1SDavid du Colombier if(nn == Z) { 803*3e12c5d1SDavid du Colombier nullwarn(n->left, Z); 804*3e12c5d1SDavid du Colombier break; 805*3e12c5d1SDavid du Colombier } 806*3e12c5d1SDavid du Colombier 807*3e12c5d1SDavid du Colombier default: 808*3e12c5d1SDavid du Colombier goto copy; 809*3e12c5d1SDavid du Colombier 810*3e12c5d1SDavid du Colombier case ODOT: 811*3e12c5d1SDavid du Colombier l = n->left; 812*3e12c5d1SDavid du Colombier sugen(l, nodrat, l->type->width); 813*3e12c5d1SDavid du Colombier if(nn != Z) { 814*3e12c5d1SDavid du Colombier warn(n, "non-interruptable temporary"); 815*3e12c5d1SDavid du Colombier nod1 = *nodrat; 816*3e12c5d1SDavid du Colombier r = n->right; 817*3e12c5d1SDavid du Colombier if(!r || r->op != OCONST) { 818*3e12c5d1SDavid du Colombier diag(n, "DOT and no offset"); 819*3e12c5d1SDavid du Colombier break; 820*3e12c5d1SDavid du Colombier } 821*3e12c5d1SDavid du Colombier nod1.offset += r->offset; 822*3e12c5d1SDavid du Colombier nod1.type = n->type; 823*3e12c5d1SDavid du Colombier sugen(&nod1, nn, w); 824*3e12c5d1SDavid du Colombier } 825*3e12c5d1SDavid du Colombier break; 826*3e12c5d1SDavid du Colombier 827*3e12c5d1SDavid du Colombier case OSTRUCT: 828*3e12c5d1SDavid du Colombier r = n->left; 829*3e12c5d1SDavid du Colombier for(t = n->type->link; t != T; t = t->down) { 830*3e12c5d1SDavid du Colombier l = r; 831*3e12c5d1SDavid du Colombier if(r->op == OLIST) { 832*3e12c5d1SDavid du Colombier l = r->left; 833*3e12c5d1SDavid du Colombier r = r->right; 834*3e12c5d1SDavid du Colombier } 835*3e12c5d1SDavid du Colombier if(nn == Z) { 836*3e12c5d1SDavid du Colombier cgen(l, nn); 837*3e12c5d1SDavid du Colombier continue; 838*3e12c5d1SDavid du Colombier } 839*3e12c5d1SDavid du Colombier /* 840*3e12c5d1SDavid du Colombier * hand craft *(&nn + o) = l 841*3e12c5d1SDavid du Colombier */ 842*3e12c5d1SDavid du Colombier nod0 = znode; 843*3e12c5d1SDavid du Colombier nod0.op = OAS; 844*3e12c5d1SDavid du Colombier nod0.type = t; 845*3e12c5d1SDavid du Colombier nod0.left = &nod1; 846*3e12c5d1SDavid du Colombier nod0.right = l; 847*3e12c5d1SDavid du Colombier 848*3e12c5d1SDavid du Colombier nod1 = znode; 849*3e12c5d1SDavid du Colombier nod1.op = OIND; 850*3e12c5d1SDavid du Colombier nod1.type = t; 851*3e12c5d1SDavid du Colombier nod1.left = &nod2; 852*3e12c5d1SDavid du Colombier 853*3e12c5d1SDavid du Colombier nod2 = znode; 854*3e12c5d1SDavid du Colombier nod2.op = OADD; 855*3e12c5d1SDavid du Colombier nod2.type = typ(TIND, t); 856*3e12c5d1SDavid du Colombier nod2.left = &nod3; 857*3e12c5d1SDavid du Colombier nod2.right = &nod4; 858*3e12c5d1SDavid du Colombier 859*3e12c5d1SDavid du Colombier nod3 = znode; 860*3e12c5d1SDavid du Colombier nod3.op = OADDR; 861*3e12c5d1SDavid du Colombier nod3.type = nod2.type; 862*3e12c5d1SDavid du Colombier nod3.left = nn; 863*3e12c5d1SDavid du Colombier 864*3e12c5d1SDavid du Colombier nod4 = znode; 865*3e12c5d1SDavid du Colombier nod4.op = OCONST; 866*3e12c5d1SDavid du Colombier nod4.type = nod2.type; 867*3e12c5d1SDavid du Colombier nod4.offset = t->offset; 868*3e12c5d1SDavid du Colombier 869*3e12c5d1SDavid du Colombier ccom(&nod0); 870*3e12c5d1SDavid du Colombier acom(&nod0); 871*3e12c5d1SDavid du Colombier xcom(&nod0); 872*3e12c5d1SDavid du Colombier nod0.addable = 0; 873*3e12c5d1SDavid du Colombier 874*3e12c5d1SDavid du Colombier /* prtree(&nod0, "hand craft"); /* */ 875*3e12c5d1SDavid du Colombier cgen(&nod0, Z); 876*3e12c5d1SDavid du Colombier } 877*3e12c5d1SDavid du Colombier break; 878*3e12c5d1SDavid du Colombier 879*3e12c5d1SDavid du Colombier case OAS: 880*3e12c5d1SDavid du Colombier if(nn == Z) { 881*3e12c5d1SDavid du Colombier if(n->addable < INDEXED) 882*3e12c5d1SDavid du Colombier sugen(n->right, n->left, w); 883*3e12c5d1SDavid du Colombier break; 884*3e12c5d1SDavid du Colombier } 885*3e12c5d1SDavid du Colombier /* BOTCH -- functions can clobber rathole */ 886*3e12c5d1SDavid du Colombier sugen(n->right, nodrat, w); 887*3e12c5d1SDavid du Colombier warn(n, "non-interruptable temporary"); 888*3e12c5d1SDavid du Colombier sugen(nodrat, n->left, w); 889*3e12c5d1SDavid du Colombier sugen(nodrat, nn, w); 890*3e12c5d1SDavid du Colombier break; 891*3e12c5d1SDavid du Colombier 892*3e12c5d1SDavid du Colombier case OFUNC: 893*3e12c5d1SDavid du Colombier if(nn == Z) { 894*3e12c5d1SDavid du Colombier sugen(n, nodrat, w); 895*3e12c5d1SDavid du Colombier break; 896*3e12c5d1SDavid du Colombier } 897*3e12c5d1SDavid du Colombier if(nn->op != OIND) { 898*3e12c5d1SDavid du Colombier nn = new1(OADDR, nn, Z); 899*3e12c5d1SDavid du Colombier nn->type = types[TIND]; 900*3e12c5d1SDavid du Colombier nn->addable = 0; 901*3e12c5d1SDavid du Colombier } else 902*3e12c5d1SDavid du Colombier nn = nn->left; 903*3e12c5d1SDavid du Colombier n = new(OFUNC, n->left, new(OLIST, nn, n->right)); 904*3e12c5d1SDavid du Colombier n->type = types[TVOID]; 905*3e12c5d1SDavid du Colombier n->left->type = types[TVOID]; 906*3e12c5d1SDavid du Colombier cgen(n, Z); 907*3e12c5d1SDavid du Colombier break; 908*3e12c5d1SDavid du Colombier 909*3e12c5d1SDavid du Colombier case OCOND: 910*3e12c5d1SDavid du Colombier bcgen(n->left, 1); 911*3e12c5d1SDavid du Colombier p1 = p; 912*3e12c5d1SDavid du Colombier sugen(n->right->left, nn, w); 913*3e12c5d1SDavid du Colombier gbranch(OGOTO); 914*3e12c5d1SDavid du Colombier patch(p1, pc); 915*3e12c5d1SDavid du Colombier p1 = p; 916*3e12c5d1SDavid du Colombier sugen(n->right->right, nn, w); 917*3e12c5d1SDavid du Colombier patch(p1, pc); 918*3e12c5d1SDavid du Colombier break; 919*3e12c5d1SDavid du Colombier 920*3e12c5d1SDavid du Colombier case OCOMMA: 921*3e12c5d1SDavid du Colombier cgen(n->left, Z); 922*3e12c5d1SDavid du Colombier sugen(n->right, nn, w); 923*3e12c5d1SDavid du Colombier break; 924*3e12c5d1SDavid du Colombier } 925*3e12c5d1SDavid du Colombier return; 926*3e12c5d1SDavid du Colombier 927*3e12c5d1SDavid du Colombier copy: 928*3e12c5d1SDavid du Colombier if(nn == Z) 929*3e12c5d1SDavid du Colombier return; 930*3e12c5d1SDavid du Colombier if(n->complex >= FNX && nn->complex >= FNX) { 931*3e12c5d1SDavid du Colombier diag(n, "Ah, come on. Is that you, Rob?"); 932*3e12c5d1SDavid du Colombier return; 933*3e12c5d1SDavid du Colombier } 934*3e12c5d1SDavid du Colombier 935*3e12c5d1SDavid du Colombier if(n->complex > nn->complex) { 936*3e12c5d1SDavid du Colombier t = n->type; 937*3e12c5d1SDavid du Colombier n->type = types[TLONG]; 938*3e12c5d1SDavid du Colombier reglcgen(&nod1, n, Z); 939*3e12c5d1SDavid du Colombier n->type = t; 940*3e12c5d1SDavid du Colombier 941*3e12c5d1SDavid du Colombier t = nn->type; 942*3e12c5d1SDavid du Colombier nn->type = types[TLONG]; 943*3e12c5d1SDavid du Colombier reglcgen(&nod2, nn, Z); 944*3e12c5d1SDavid du Colombier nn->type = t; 945*3e12c5d1SDavid du Colombier } else { 946*3e12c5d1SDavid du Colombier t = nn->type; 947*3e12c5d1SDavid du Colombier nn->type = types[TLONG]; 948*3e12c5d1SDavid du Colombier reglcgen(&nod2, nn, Z); 949*3e12c5d1SDavid du Colombier nn->type = t; 950*3e12c5d1SDavid du Colombier 951*3e12c5d1SDavid du Colombier t = n->type; 952*3e12c5d1SDavid du Colombier n->type = types[TLONG]; 953*3e12c5d1SDavid du Colombier reglcgen(&nod1, n, Z); 954*3e12c5d1SDavid du Colombier n->type = t; 955*3e12c5d1SDavid du Colombier } 956*3e12c5d1SDavid du Colombier 957*3e12c5d1SDavid du Colombier w /= SZ_LONG; 958*3e12c5d1SDavid du Colombier if(w <= 5) { 959*3e12c5d1SDavid du Colombier layout(&nod1, &nod2, w, 0, Z); 960*3e12c5d1SDavid du Colombier goto out; 961*3e12c5d1SDavid du Colombier } 962*3e12c5d1SDavid du Colombier 963*3e12c5d1SDavid du Colombier /* 964*3e12c5d1SDavid du Colombier * minimize space for unrolling loop 965*3e12c5d1SDavid du Colombier * 3,4,5 times. (6 or more is never minimum) 966*3e12c5d1SDavid du Colombier * if small structure, try 2 also. 967*3e12c5d1SDavid du Colombier */ 968*3e12c5d1SDavid du Colombier c = 0; /* set */ 969*3e12c5d1SDavid du Colombier m = 100; 970*3e12c5d1SDavid du Colombier i = 3; 971*3e12c5d1SDavid du Colombier if(w <= 15) 972*3e12c5d1SDavid du Colombier i = 2; 973*3e12c5d1SDavid du Colombier for(; i<=5; i++) 974*3e12c5d1SDavid du Colombier if(i + w%i <= m) { 975*3e12c5d1SDavid du Colombier c = i; 976*3e12c5d1SDavid du Colombier m = c + w%c; 977*3e12c5d1SDavid du Colombier } 978*3e12c5d1SDavid du Colombier 979*3e12c5d1SDavid du Colombier regalloc(&nod3, ®node, Z); 980*3e12c5d1SDavid du Colombier layout(&nod1, &nod2, w%c, w/c, &nod3); 981*3e12c5d1SDavid du Colombier 982*3e12c5d1SDavid du Colombier pc1 = pc; 983*3e12c5d1SDavid du Colombier layout(&nod1, &nod2, c, 0, Z); 984*3e12c5d1SDavid du Colombier 985*3e12c5d1SDavid du Colombier gopcode(OSUB, nodconst(1L), Z, &nod3); 986*3e12c5d1SDavid du Colombier nod1.op = OREGISTER; 987*3e12c5d1SDavid du Colombier gopcode(OADD, nodconst(c*SZ_LONG), Z, &nod1); 988*3e12c5d1SDavid du Colombier nod2.op = OREGISTER; 989*3e12c5d1SDavid du Colombier gopcode(OADD, nodconst(c*SZ_LONG), Z, &nod2); 990*3e12c5d1SDavid du Colombier 991*3e12c5d1SDavid du Colombier gopcode(OEQ, &nod3, Z, Z); 992*3e12c5d1SDavid du Colombier p->as = ABGTZ; 993*3e12c5d1SDavid du Colombier patch(p, pc1); 994*3e12c5d1SDavid du Colombier 995*3e12c5d1SDavid du Colombier regfree(&nod3); 996*3e12c5d1SDavid du Colombier out: 997*3e12c5d1SDavid du Colombier regfree(&nod1); 998*3e12c5d1SDavid du Colombier regfree(&nod2); 999*3e12c5d1SDavid du Colombier } 1000*3e12c5d1SDavid du Colombier 1001*3e12c5d1SDavid du Colombier void 1002*3e12c5d1SDavid du Colombier layout(Node *f, Node *t, int c, int cv, Node *cn) 1003*3e12c5d1SDavid du Colombier { 1004*3e12c5d1SDavid du Colombier Node t1, t2; 1005*3e12c5d1SDavid du Colombier 1006*3e12c5d1SDavid du Colombier while(c > 3) { 1007*3e12c5d1SDavid du Colombier layout(f, t, 2, 0, Z); 1008*3e12c5d1SDavid du Colombier c -= 2; 1009*3e12c5d1SDavid du Colombier } 1010*3e12c5d1SDavid du Colombier 1011*3e12c5d1SDavid du Colombier regalloc(&t1, ®node, Z); 1012*3e12c5d1SDavid du Colombier regalloc(&t2, ®node, Z); 1013*3e12c5d1SDavid du Colombier if(c > 0) { 1014*3e12c5d1SDavid du Colombier gopcode(OAS, f, Z, &t1); 1015*3e12c5d1SDavid du Colombier f->offset += SZ_LONG; 1016*3e12c5d1SDavid du Colombier } 1017*3e12c5d1SDavid du Colombier if(cn != Z) 1018*3e12c5d1SDavid du Colombier gopcode(OAS, nodconst(cv), Z, cn); 1019*3e12c5d1SDavid du Colombier if(c > 1) { 1020*3e12c5d1SDavid du Colombier gopcode(OAS, f, Z, &t2); 1021*3e12c5d1SDavid du Colombier f->offset += SZ_LONG; 1022*3e12c5d1SDavid du Colombier } 1023*3e12c5d1SDavid du Colombier if(c > 0) { 1024*3e12c5d1SDavid du Colombier gopcode(OAS, &t1, Z, t); 1025*3e12c5d1SDavid du Colombier t->offset += SZ_LONG; 1026*3e12c5d1SDavid du Colombier } 1027*3e12c5d1SDavid du Colombier if(c > 2) { 1028*3e12c5d1SDavid du Colombier gopcode(OAS, f, Z, &t1); 1029*3e12c5d1SDavid du Colombier f->offset += SZ_LONG; 1030*3e12c5d1SDavid du Colombier } 1031*3e12c5d1SDavid du Colombier if(c > 1) { 1032*3e12c5d1SDavid du Colombier gopcode(OAS, &t2, Z, t); 1033*3e12c5d1SDavid du Colombier t->offset += SZ_LONG; 1034*3e12c5d1SDavid du Colombier } 1035*3e12c5d1SDavid du Colombier if(c > 2) { 1036*3e12c5d1SDavid du Colombier gopcode(OAS, &t1, Z, t); 1037*3e12c5d1SDavid du Colombier t->offset += SZ_LONG; 1038*3e12c5d1SDavid du Colombier } 1039*3e12c5d1SDavid du Colombier regfree(&t1); 1040*3e12c5d1SDavid du Colombier regfree(&t2); 1041*3e12c5d1SDavid du Colombier } 1042