13e12c5d1SDavid du Colombier #include "gc.h" 23e12c5d1SDavid du Colombier 3da51d93aSDavid du Colombier /* ,x/^(print|prtree)\(/i/\/\/ */ 4da51d93aSDavid du Colombier 53e12c5d1SDavid du Colombier void 63e12c5d1SDavid du Colombier cgen(Node *n, Node *nn) 73e12c5d1SDavid du Colombier { 8375daca8SDavid du Colombier Node *l, *r, *t; 93e12c5d1SDavid du Colombier Prog *p1; 103e12c5d1SDavid du Colombier Node nod, nod1, nod2, nod3, nod4; 117dd7cddfSDavid du Colombier int o, hardleft; 123e12c5d1SDavid du Colombier long v, curs; 13375daca8SDavid du Colombier vlong c; 143e12c5d1SDavid du Colombier 153e12c5d1SDavid du Colombier if(debug['g']) { 163e12c5d1SDavid du Colombier prtree(nn, "cgen lhs"); 173e12c5d1SDavid du Colombier prtree(n, "cgen"); 183e12c5d1SDavid du Colombier } 193e12c5d1SDavid du Colombier if(n == Z || n->type == T) 203e12c5d1SDavid du Colombier return; 217dd7cddfSDavid du Colombier if(typesuv[n->type->etype]) { 223e12c5d1SDavid du Colombier sugen(n, nn, n->type->width); 233e12c5d1SDavid du Colombier return; 243e12c5d1SDavid du Colombier } 257dd7cddfSDavid du Colombier l = n->left; 267dd7cddfSDavid du Colombier r = n->right; 277dd7cddfSDavid du Colombier o = n->op; 283e12c5d1SDavid du Colombier if(n->addable >= INDEXED) { 297dd7cddfSDavid du Colombier if(nn == Z) { 307dd7cddfSDavid du Colombier switch(o) { 317dd7cddfSDavid du Colombier default: 327dd7cddfSDavid du Colombier nullwarn(Z, Z); 337dd7cddfSDavid du Colombier break; 347dd7cddfSDavid du Colombier case OINDEX: 357dd7cddfSDavid du Colombier nullwarn(l, r); 367dd7cddfSDavid du Colombier break; 377dd7cddfSDavid du Colombier } 387dd7cddfSDavid du Colombier return; 397dd7cddfSDavid du Colombier } 403e12c5d1SDavid du Colombier gmove(n, nn); 413e12c5d1SDavid du Colombier return; 423e12c5d1SDavid du Colombier } 433e12c5d1SDavid du Colombier curs = cursafe; 443e12c5d1SDavid du Colombier 453e12c5d1SDavid du Colombier if(l->complex >= FNX) 463e12c5d1SDavid du Colombier if(r != Z && r->complex >= FNX) 473e12c5d1SDavid du Colombier switch(o) { 483e12c5d1SDavid du Colombier default: 49da51d93aSDavid du Colombier if(cond(o) && typesuv[l->type->etype]) 50da51d93aSDavid du Colombier break; 51da51d93aSDavid du Colombier 523e12c5d1SDavid du Colombier regret(&nod, r); 533e12c5d1SDavid du Colombier cgen(r, &nod); 543e12c5d1SDavid du Colombier 553e12c5d1SDavid du Colombier regsalloc(&nod1, r); 563e12c5d1SDavid du Colombier gmove(&nod, &nod1); 573e12c5d1SDavid du Colombier 583e12c5d1SDavid du Colombier regfree(&nod); 593e12c5d1SDavid du Colombier nod = *n; 603e12c5d1SDavid du Colombier nod.right = &nod1; 613e12c5d1SDavid du Colombier 623e12c5d1SDavid du Colombier cgen(&nod, nn); 633e12c5d1SDavid du Colombier return; 643e12c5d1SDavid du Colombier 653e12c5d1SDavid du Colombier case OFUNC: 663e12c5d1SDavid du Colombier case OCOMMA: 673e12c5d1SDavid du Colombier case OANDAND: 683e12c5d1SDavid du Colombier case OOROR: 693e12c5d1SDavid du Colombier case OCOND: 703e12c5d1SDavid du Colombier case ODOT: 713e12c5d1SDavid du Colombier break; 723e12c5d1SDavid du Colombier } 733e12c5d1SDavid du Colombier 747dd7cddfSDavid du Colombier hardleft = l->addable < INDEXED || l->complex >= FNX; 753e12c5d1SDavid du Colombier switch(o) { 763e12c5d1SDavid du Colombier default: 773e12c5d1SDavid du Colombier diag(n, "unknown op in cgen: %O", o); 783e12c5d1SDavid du Colombier break; 793e12c5d1SDavid du Colombier 80da51d93aSDavid du Colombier case ONEG: 81da51d93aSDavid du Colombier case OCOM: 82da51d93aSDavid du Colombier if(nn == Z) { 83da51d93aSDavid du Colombier nullwarn(l, Z); 84da51d93aSDavid du Colombier break; 85da51d93aSDavid du Colombier } 86da51d93aSDavid du Colombier regalloc(&nod, l, nn); 87da51d93aSDavid du Colombier cgen(l, &nod); 88da51d93aSDavid du Colombier gopcode(o, n->type, Z, &nod); 89da51d93aSDavid du Colombier gmove(&nod, nn); 90da51d93aSDavid du Colombier regfree(&nod); 91da51d93aSDavid du Colombier break; 92da51d93aSDavid du Colombier 933e12c5d1SDavid du Colombier case OAS: 94219b2ee8SDavid du Colombier if(typefd[n->type->etype]) { 953e12c5d1SDavid du Colombier cgen(r, &fregnode0); 963e12c5d1SDavid du Colombier if(nn != Z) 973e12c5d1SDavid du Colombier gins(AFMOVD, &fregnode0, &fregnode0); 983e12c5d1SDavid du Colombier if(l->addable < INDEXED) { 993e12c5d1SDavid du Colombier reglcgen(&nod, l, Z); 1003e12c5d1SDavid du Colombier gmove(&fregnode0, &nod); 1013e12c5d1SDavid du Colombier regfree(&nod); 1023e12c5d1SDavid du Colombier } else 1033e12c5d1SDavid du Colombier gmove(&fregnode0, l); 1043e12c5d1SDavid du Colombier if(nn != Z) 1053e12c5d1SDavid du Colombier gmove(&fregnode0, nn); 1063e12c5d1SDavid du Colombier return; 1073e12c5d1SDavid du Colombier } 1083e12c5d1SDavid du Colombier if(l->op == OBIT) 1093e12c5d1SDavid du Colombier goto bitas; 1107dd7cddfSDavid du Colombier if(!hardleft) { 1113e12c5d1SDavid du Colombier if(nn != Z || r->addable < INDEXED) { 1127dd7cddfSDavid du Colombier if(r->complex >= FNX && nn == Z) 1137dd7cddfSDavid du Colombier regret(&nod, r); 1147dd7cddfSDavid du Colombier else 1153e12c5d1SDavid du Colombier regalloc(&nod, r, nn); 1163e12c5d1SDavid du Colombier cgen(r, &nod); 1173e12c5d1SDavid du Colombier gmove(&nod, l); 1187dd7cddfSDavid du Colombier if(nn != Z) 1197dd7cddfSDavid du Colombier gmove(&nod, nn); 1203e12c5d1SDavid du Colombier regfree(&nod); 1213e12c5d1SDavid du Colombier } else 1223e12c5d1SDavid du Colombier gmove(r, l); 1233e12c5d1SDavid du Colombier break; 1243e12c5d1SDavid du Colombier } 1253e12c5d1SDavid du Colombier if(l->complex >= r->complex) { 12680ee5cbfSDavid du Colombier if(l->op == OINDEX && r->op == OCONST) { 12780ee5cbfSDavid du Colombier gmove(r, l); 12880ee5cbfSDavid du Colombier break; 12980ee5cbfSDavid du Colombier } 1303e12c5d1SDavid du Colombier reglcgen(&nod1, l, Z); 1313e12c5d1SDavid du Colombier if(r->addable >= INDEXED) { 1323e12c5d1SDavid du Colombier gmove(r, &nod1); 1333e12c5d1SDavid du Colombier if(nn != Z) 1343e12c5d1SDavid du Colombier gmove(r, nn); 1353e12c5d1SDavid du Colombier regfree(&nod1); 1363e12c5d1SDavid du Colombier break; 1373e12c5d1SDavid du Colombier } 1383e12c5d1SDavid du Colombier regalloc(&nod, r, nn); 1393e12c5d1SDavid du Colombier cgen(r, &nod); 1403e12c5d1SDavid du Colombier } else { 1413e12c5d1SDavid du Colombier regalloc(&nod, r, nn); 1423e12c5d1SDavid du Colombier cgen(r, &nod); 1433e12c5d1SDavid du Colombier reglcgen(&nod1, l, Z); 1443e12c5d1SDavid du Colombier } 1453e12c5d1SDavid du Colombier gmove(&nod, &nod1); 1463e12c5d1SDavid du Colombier regfree(&nod); 1473e12c5d1SDavid du Colombier regfree(&nod1); 1483e12c5d1SDavid du Colombier break; 1493e12c5d1SDavid du Colombier 1503e12c5d1SDavid du Colombier bitas: 1513e12c5d1SDavid du Colombier n = l->left; 1523e12c5d1SDavid du Colombier regalloc(&nod, r, nn); 1533e12c5d1SDavid du Colombier if(l->complex >= r->complex) { 1543e12c5d1SDavid du Colombier reglcgen(&nod1, n, Z); 1553e12c5d1SDavid du Colombier cgen(r, &nod); 1563e12c5d1SDavid du Colombier } else { 1573e12c5d1SDavid du Colombier cgen(r, &nod); 1583e12c5d1SDavid du Colombier reglcgen(&nod1, n, Z); 1593e12c5d1SDavid du Colombier } 1603e12c5d1SDavid du Colombier regalloc(&nod2, n, Z); 1613e12c5d1SDavid du Colombier gmove(&nod1, &nod2); 1623e12c5d1SDavid du Colombier bitstore(l, &nod, &nod1, &nod2, nn); 1633e12c5d1SDavid du Colombier break; 1643e12c5d1SDavid du Colombier 1653e12c5d1SDavid du Colombier case OBIT: 1663e12c5d1SDavid du Colombier if(nn == Z) { 1673e12c5d1SDavid du Colombier nullwarn(l, Z); 1683e12c5d1SDavid du Colombier break; 1693e12c5d1SDavid du Colombier } 1703e12c5d1SDavid du Colombier bitload(n, &nod, Z, Z, nn); 1713e12c5d1SDavid du Colombier gmove(&nod, nn); 1723e12c5d1SDavid du Colombier regfree(&nod); 1733e12c5d1SDavid du Colombier break; 1743e12c5d1SDavid du Colombier 1753e12c5d1SDavid du Colombier case OLSHR: 1763e12c5d1SDavid du Colombier case OASHL: 1773e12c5d1SDavid du Colombier case OASHR: 1783e12c5d1SDavid du Colombier if(nn == Z) { 1793e12c5d1SDavid du Colombier nullwarn(l, r); 1803e12c5d1SDavid du Colombier break; 1813e12c5d1SDavid du Colombier } 1823e12c5d1SDavid du Colombier if(r->op == OCONST) { 183219b2ee8SDavid du Colombier if(r->vconst == 0) { 1843e12c5d1SDavid du Colombier cgen(l, nn); 1853e12c5d1SDavid du Colombier break; 1863e12c5d1SDavid du Colombier } 1873e12c5d1SDavid du Colombier regalloc(&nod, l, nn); 1883e12c5d1SDavid du Colombier cgen(l, &nod); 189375daca8SDavid du Colombier if(o == OASHL && r->vconst == 1) 190375daca8SDavid du Colombier gopcode(OADD, n->type, &nod, &nod); 191375daca8SDavid du Colombier else 1923e12c5d1SDavid du Colombier gopcode(o, n->type, r, &nod); 1933e12c5d1SDavid du Colombier gmove(&nod, nn); 1943e12c5d1SDavid du Colombier regfree(&nod); 1953e12c5d1SDavid du Colombier break; 1963e12c5d1SDavid du Colombier } 1973e12c5d1SDavid du Colombier 1983e12c5d1SDavid du Colombier /* 1993e12c5d1SDavid du Colombier * get nod to be D_CX 2003e12c5d1SDavid du Colombier */ 2013e12c5d1SDavid du Colombier if(nodreg(&nod, nn, D_CX)) { 2023e12c5d1SDavid du Colombier regsalloc(&nod1, n); 2033e12c5d1SDavid du Colombier gmove(&nod, &nod1); 2043e12c5d1SDavid du Colombier cgen(n, &nod); /* probably a bug */ 2053e12c5d1SDavid du Colombier gmove(&nod, nn); 2063e12c5d1SDavid du Colombier gmove(&nod1, &nod); 2073e12c5d1SDavid du Colombier break; 2083e12c5d1SDavid du Colombier } 2093e12c5d1SDavid du Colombier reg[D_CX]++; 2103e12c5d1SDavid du Colombier if(nn->op == OREGISTER && nn->reg == D_CX) 2113e12c5d1SDavid du Colombier regalloc(&nod1, l, Z); 2123e12c5d1SDavid du Colombier else 2133e12c5d1SDavid du Colombier regalloc(&nod1, l, nn); 2143e12c5d1SDavid du Colombier if(r->complex >= l->complex) { 2153e12c5d1SDavid du Colombier cgen(r, &nod); 2163e12c5d1SDavid du Colombier cgen(l, &nod1); 2173e12c5d1SDavid du Colombier } else { 2183e12c5d1SDavid du Colombier cgen(l, &nod1); 2193e12c5d1SDavid du Colombier cgen(r, &nod); 2203e12c5d1SDavid du Colombier } 2213e12c5d1SDavid du Colombier gopcode(o, n->type, &nod, &nod1); 2223e12c5d1SDavid du Colombier gmove(&nod1, nn); 2233e12c5d1SDavid du Colombier regfree(&nod); 2243e12c5d1SDavid du Colombier regfree(&nod1); 2253e12c5d1SDavid du Colombier break; 2263e12c5d1SDavid du Colombier 2273e12c5d1SDavid du Colombier case OADD: 2283e12c5d1SDavid du Colombier case OSUB: 2293e12c5d1SDavid du Colombier case OOR: 2303e12c5d1SDavid du Colombier case OXOR: 2313e12c5d1SDavid du Colombier case OAND: 2323e12c5d1SDavid du Colombier if(nn == Z) { 2333e12c5d1SDavid du Colombier nullwarn(l, r); 2343e12c5d1SDavid du Colombier break; 2353e12c5d1SDavid du Colombier } 236219b2ee8SDavid du Colombier if(typefd[n->type->etype]) 2373e12c5d1SDavid du Colombier goto fop; 238219b2ee8SDavid du Colombier if(r->op == OCONST) { 239219b2ee8SDavid du Colombier if(r->vconst == 0 && o != OAND) { 2403e12c5d1SDavid du Colombier cgen(l, nn); 2413e12c5d1SDavid du Colombier break; 2423e12c5d1SDavid du Colombier } 243219b2ee8SDavid du Colombier } 244375daca8SDavid du Colombier if(n->op == OADD && l->op == OASHL && l->right->op == OCONST 245375daca8SDavid du Colombier && (r->op != OCONST || r->vconst < -128 || r->vconst > 127)) { 246375daca8SDavid du Colombier c = l->right->vconst; 247375daca8SDavid du Colombier if(c > 0 && c <= 3) { 248375daca8SDavid du Colombier if(l->left->complex >= r->complex) { 249375daca8SDavid du Colombier regalloc(&nod, l->left, nn); 250375daca8SDavid du Colombier cgen(l->left, &nod); 251375daca8SDavid du Colombier if(r->addable < INDEXED) { 252375daca8SDavid du Colombier regalloc(&nod1, r, Z); 253375daca8SDavid du Colombier cgen(r, &nod1); 254375daca8SDavid du Colombier genmuladd(&nod, &nod, 1 << c, &nod1); 255375daca8SDavid du Colombier regfree(&nod1); 256375daca8SDavid du Colombier } 257375daca8SDavid du Colombier else 258375daca8SDavid du Colombier genmuladd(&nod, &nod, 1 << c, r); 259375daca8SDavid du Colombier } 260375daca8SDavid du Colombier else { 261375daca8SDavid du Colombier regalloc(&nod, r, nn); 262375daca8SDavid du Colombier cgen(r, &nod); 263375daca8SDavid du Colombier regalloc(&nod1, l->left, Z); 264375daca8SDavid du Colombier cgen(l->left, &nod1); 265375daca8SDavid du Colombier genmuladd(&nod, &nod1, 1 << c, &nod); 266375daca8SDavid du Colombier regfree(&nod1); 267375daca8SDavid du Colombier } 268375daca8SDavid du Colombier gmove(&nod, nn); 269375daca8SDavid du Colombier regfree(&nod); 270375daca8SDavid du Colombier break; 271375daca8SDavid du Colombier } 272375daca8SDavid du Colombier } 2733e12c5d1SDavid du Colombier if(r->addable >= INDEXED) { 2743e12c5d1SDavid du Colombier regalloc(&nod, l, nn); 2753e12c5d1SDavid du Colombier cgen(l, &nod); 2763e12c5d1SDavid du Colombier gopcode(o, n->type, r, &nod); 2773e12c5d1SDavid du Colombier gmove(&nod, nn); 2783e12c5d1SDavid du Colombier regfree(&nod); 2793e12c5d1SDavid du Colombier break; 2803e12c5d1SDavid du Colombier } 2813e12c5d1SDavid du Colombier if(l->complex >= r->complex) { 2823e12c5d1SDavid du Colombier regalloc(&nod, l, nn); 2833e12c5d1SDavid du Colombier cgen(l, &nod); 2843e12c5d1SDavid du Colombier regalloc(&nod1, r, Z); 2853e12c5d1SDavid du Colombier cgen(r, &nod1); 2863e12c5d1SDavid du Colombier gopcode(o, n->type, &nod1, &nod); 2873e12c5d1SDavid du Colombier } else { 2883e12c5d1SDavid du Colombier regalloc(&nod1, r, nn); 2893e12c5d1SDavid du Colombier cgen(r, &nod1); 2903e12c5d1SDavid du Colombier regalloc(&nod, l, Z); 2913e12c5d1SDavid du Colombier cgen(l, &nod); 2923e12c5d1SDavid du Colombier gopcode(o, n->type, &nod1, &nod); 2933e12c5d1SDavid du Colombier } 2943e12c5d1SDavid du Colombier gmove(&nod, nn); 2953e12c5d1SDavid du Colombier regfree(&nod); 2963e12c5d1SDavid du Colombier regfree(&nod1); 2973e12c5d1SDavid du Colombier break; 2983e12c5d1SDavid du Colombier 2993e12c5d1SDavid du Colombier case OLMOD: 3003e12c5d1SDavid du Colombier case OMOD: 3013e12c5d1SDavid du Colombier case OLMUL: 3023e12c5d1SDavid du Colombier case OLDIV: 3033e12c5d1SDavid du Colombier case OMUL: 3043e12c5d1SDavid du Colombier case ODIV: 3053e12c5d1SDavid du Colombier if(nn == Z) { 3063e12c5d1SDavid du Colombier nullwarn(l, r); 3073e12c5d1SDavid du Colombier break; 3083e12c5d1SDavid du Colombier } 309219b2ee8SDavid du Colombier if(typefd[n->type->etype]) 3103e12c5d1SDavid du Colombier goto fop; 311375daca8SDavid du Colombier if(r->op == OCONST) { 312375daca8SDavid du Colombier SET(v); 313375daca8SDavid du Colombier switch(o) { 314375daca8SDavid du Colombier case ODIV: 315375daca8SDavid du Colombier case OMOD: 316375daca8SDavid du Colombier c = r->vconst; 317375daca8SDavid du Colombier if(c < 0) 318375daca8SDavid du Colombier c = -c; 319375daca8SDavid du Colombier v = log2(c); 320375daca8SDavid du Colombier if(v < 0) 321375daca8SDavid du Colombier break; 322375daca8SDavid du Colombier /* fall thru */ 323375daca8SDavid du Colombier case OMUL: 324375daca8SDavid du Colombier case OLMUL: 3259a747e4fSDavid du Colombier regalloc(&nod, l, nn); 3269a747e4fSDavid du Colombier cgen(l, &nod); 327375daca8SDavid du Colombier switch(o) { 328375daca8SDavid du Colombier case OMUL: 329375daca8SDavid du Colombier case OLMUL: 330375daca8SDavid du Colombier mulgen(n->type, r, &nod); 331375daca8SDavid du Colombier break; 332375daca8SDavid du Colombier case ODIV: 333375daca8SDavid du Colombier sdiv2(r->vconst, v, l, &nod); 334375daca8SDavid du Colombier break; 335375daca8SDavid du Colombier case OMOD: 336375daca8SDavid du Colombier smod2(r->vconst, v, l, &nod); 3379a747e4fSDavid du Colombier break; 3389a747e4fSDavid du Colombier } 339375daca8SDavid du Colombier gmove(&nod, nn); 340375daca8SDavid du Colombier regfree(&nod); 341375daca8SDavid du Colombier goto done; 342375daca8SDavid du Colombier case OLDIV: 343375daca8SDavid du Colombier c = r->vconst; 344375daca8SDavid du Colombier if((c & 0x80000000) == 0) 345375daca8SDavid du Colombier break; 346375daca8SDavid du Colombier regalloc(&nod1, l, Z); 347375daca8SDavid du Colombier cgen(l, &nod1); 348375daca8SDavid du Colombier regalloc(&nod, l, nn); 349375daca8SDavid du Colombier zeroregm(&nod); 350375daca8SDavid du Colombier gins(ACMPL, &nod1, nodconst(c)); 351375daca8SDavid du Colombier gins(ASBBL, nodconst(-1), &nod); 352375daca8SDavid du Colombier regfree(&nod1); 353375daca8SDavid du Colombier gmove(&nod, nn); 354375daca8SDavid du Colombier regfree(&nod); 355375daca8SDavid du Colombier goto done; 356375daca8SDavid du Colombier } 357375daca8SDavid du Colombier } 358375daca8SDavid du Colombier 359375daca8SDavid du Colombier if(o == OMUL) { 360375daca8SDavid du Colombier if(l->addable >= INDEXED) { 361375daca8SDavid du Colombier t = l; 362375daca8SDavid du Colombier l = r; 363375daca8SDavid du Colombier r = t; 364375daca8SDavid du Colombier goto imula; 365375daca8SDavid du Colombier } 366375daca8SDavid du Colombier else if(r->addable >= INDEXED) { 367375daca8SDavid du Colombier imula: 368375daca8SDavid du Colombier /* should favour AX */ 369375daca8SDavid du Colombier regalloc(&nod, l, nn); 370375daca8SDavid du Colombier cgen(l, &nod); 371375daca8SDavid du Colombier gopcode(OMUL, n->type, r, &nod); 372375daca8SDavid du Colombier } 373375daca8SDavid du Colombier else { 374375daca8SDavid du Colombier /* should favour AX */ 375375daca8SDavid du Colombier regalloc(&nod, l, nn); 376375daca8SDavid du Colombier cgen(l, &nod); 377375daca8SDavid du Colombier regalloc(&nod1, r, Z); 378375daca8SDavid du Colombier cgen(r, &nod1); 379375daca8SDavid du Colombier gopcode(OMUL, n->type, &nod1, &nod); 380375daca8SDavid du Colombier regfree(&nod1); 381375daca8SDavid du Colombier } 382375daca8SDavid du Colombier gmove(&nod, nn); 383375daca8SDavid du Colombier regfree(&nod); 384375daca8SDavid du Colombier goto done; 385375daca8SDavid du Colombier } 386375daca8SDavid du Colombier 3873e12c5d1SDavid du Colombier /* 3883e12c5d1SDavid du Colombier * get nod to be D_AX 3893e12c5d1SDavid du Colombier * get nod1 to be D_DX 3903e12c5d1SDavid du Colombier */ 3913e12c5d1SDavid du Colombier if(nodreg(&nod, nn, D_AX)) { 3923e12c5d1SDavid du Colombier regsalloc(&nod2, n); 3933e12c5d1SDavid du Colombier gmove(&nod, &nod2); 3943e12c5d1SDavid du Colombier v = reg[D_AX]; 3953e12c5d1SDavid du Colombier reg[D_AX] = 0; 3963e12c5d1SDavid du Colombier 3973e12c5d1SDavid du Colombier if(isreg(l, D_AX)) { 3983e12c5d1SDavid du Colombier nod3 = *n; 3993e12c5d1SDavid du Colombier nod3.left = &nod2; 4003e12c5d1SDavid du Colombier cgen(&nod3, nn); 4013e12c5d1SDavid du Colombier } else 4023e12c5d1SDavid du Colombier if(isreg(r, D_AX)) { 4033e12c5d1SDavid du Colombier nod3 = *n; 4043e12c5d1SDavid du Colombier nod3.right = &nod2; 4053e12c5d1SDavid du Colombier cgen(&nod3, nn); 4063e12c5d1SDavid du Colombier } else 4073e12c5d1SDavid du Colombier cgen(n, nn); 4083e12c5d1SDavid du Colombier 4093e12c5d1SDavid du Colombier gmove(&nod2, &nod); 4103e12c5d1SDavid du Colombier reg[D_AX] = v; 4113e12c5d1SDavid du Colombier break; 4123e12c5d1SDavid du Colombier } 4133e12c5d1SDavid du Colombier if(nodreg(&nod1, nn, D_DX)) { 4143e12c5d1SDavid du Colombier regsalloc(&nod2, n); 4153e12c5d1SDavid du Colombier gmove(&nod1, &nod2); 4163e12c5d1SDavid du Colombier v = reg[D_DX]; 4173e12c5d1SDavid du Colombier reg[D_DX] = 0; 4183e12c5d1SDavid du Colombier 4193e12c5d1SDavid du Colombier if(isreg(l, D_DX)) { 4203e12c5d1SDavid du Colombier nod3 = *n; 4213e12c5d1SDavid du Colombier nod3.left = &nod2; 4223e12c5d1SDavid du Colombier cgen(&nod3, nn); 4233e12c5d1SDavid du Colombier } else 4243e12c5d1SDavid du Colombier if(isreg(r, D_DX)) { 4253e12c5d1SDavid du Colombier nod3 = *n; 4263e12c5d1SDavid du Colombier nod3.right = &nod2; 4273e12c5d1SDavid du Colombier cgen(&nod3, nn); 4283e12c5d1SDavid du Colombier } else 4293e12c5d1SDavid du Colombier cgen(n, nn); 4303e12c5d1SDavid du Colombier 4313e12c5d1SDavid du Colombier gmove(&nod2, &nod1); 4323e12c5d1SDavid du Colombier reg[D_DX] = v; 4333e12c5d1SDavid du Colombier break; 4343e12c5d1SDavid du Colombier } 4353e12c5d1SDavid du Colombier reg[D_AX]++; 4363e12c5d1SDavid du Colombier 437375daca8SDavid du Colombier if(r->op == OCONST) { 438375daca8SDavid du Colombier switch(o) { 439375daca8SDavid du Colombier case ODIV: 440375daca8SDavid du Colombier reg[D_DX]++; 441375daca8SDavid du Colombier if(l->addable < INDEXED) { 442375daca8SDavid du Colombier regalloc(&nod2, l, Z); 443375daca8SDavid du Colombier cgen(l, &nod2); 444375daca8SDavid du Colombier l = &nod2; 445375daca8SDavid du Colombier } 446375daca8SDavid du Colombier sdivgen(l, r, &nod, &nod1); 447375daca8SDavid du Colombier gmove(&nod1, nn); 448375daca8SDavid du Colombier if(l == &nod2) 449375daca8SDavid du Colombier regfree(l); 450375daca8SDavid du Colombier goto freeaxdx; 451375daca8SDavid du Colombier case OLDIV: 452375daca8SDavid du Colombier reg[D_DX]++; 453375daca8SDavid du Colombier if(l->addable < INDEXED) { 454375daca8SDavid du Colombier regalloc(&nod2, l, Z); 455375daca8SDavid du Colombier cgen(l, &nod2); 456375daca8SDavid du Colombier l = &nod2; 457375daca8SDavid du Colombier } 458375daca8SDavid du Colombier udivgen(l, r, &nod, &nod1); 459375daca8SDavid du Colombier gmove(&nod1, nn); 460375daca8SDavid du Colombier if(l == &nod2) 461375daca8SDavid du Colombier regfree(l); 462375daca8SDavid du Colombier goto freeaxdx; 463375daca8SDavid du Colombier } 464375daca8SDavid du Colombier } 465375daca8SDavid du Colombier 4663e12c5d1SDavid du Colombier if(l->complex >= r->complex) { 4673e12c5d1SDavid du Colombier cgen(l, &nod); 4683e12c5d1SDavid du Colombier reg[D_DX]++; 4693e12c5d1SDavid du Colombier if(o == ODIV || o == OMOD) 4703e12c5d1SDavid du Colombier gins(ACDQ, Z, Z); 4713e12c5d1SDavid du Colombier if(o == OLDIV || o == OLMOD) 472da51d93aSDavid du Colombier zeroregm(&nod1); 4733e12c5d1SDavid du Colombier if(r->addable < INDEXED || r->op == OCONST) { 4743e12c5d1SDavid du Colombier regsalloc(&nod3, r); 4753e12c5d1SDavid du Colombier cgen(r, &nod3); 4763e12c5d1SDavid du Colombier gopcode(o, n->type, &nod3, Z); 4773e12c5d1SDavid du Colombier } else 4783e12c5d1SDavid du Colombier gopcode(o, n->type, r, Z); 4793e12c5d1SDavid du Colombier } else { 4803e12c5d1SDavid du Colombier regsalloc(&nod3, r); 4813e12c5d1SDavid du Colombier cgen(r, &nod3); 4823e12c5d1SDavid du Colombier cgen(l, &nod); 4833e12c5d1SDavid du Colombier reg[D_DX]++; 4843e12c5d1SDavid du Colombier if(o == ODIV || o == OMOD) 4853e12c5d1SDavid du Colombier gins(ACDQ, Z, Z); 4863e12c5d1SDavid du Colombier if(o == OLDIV || o == OLMOD) 487da51d93aSDavid du Colombier zeroregm(&nod1); 4883e12c5d1SDavid du Colombier gopcode(o, n->type, &nod3, Z); 4893e12c5d1SDavid du Colombier } 4903e12c5d1SDavid du Colombier if(o == OMOD || o == OLMOD) 4913e12c5d1SDavid du Colombier gmove(&nod1, nn); 4923e12c5d1SDavid du Colombier else 4933e12c5d1SDavid du Colombier gmove(&nod, nn); 494375daca8SDavid du Colombier freeaxdx: 4953e12c5d1SDavid du Colombier regfree(&nod); 4963e12c5d1SDavid du Colombier regfree(&nod1); 4973e12c5d1SDavid du Colombier break; 4983e12c5d1SDavid du Colombier 4993e12c5d1SDavid du Colombier case OASLSHR: 5003e12c5d1SDavid du Colombier case OASASHL: 5013e12c5d1SDavid du Colombier case OASASHR: 5023e12c5d1SDavid du Colombier if(r->op == OCONST) 5033e12c5d1SDavid du Colombier goto asand; 5043e12c5d1SDavid du Colombier if(l->op == OBIT) 5053e12c5d1SDavid du Colombier goto asbitop; 506219b2ee8SDavid du Colombier if(typefd[n->type->etype]) 5073e12c5d1SDavid du Colombier goto asfop; 5083e12c5d1SDavid du Colombier 5093e12c5d1SDavid du Colombier /* 5103e12c5d1SDavid du Colombier * get nod to be D_CX 5113e12c5d1SDavid du Colombier */ 5123e12c5d1SDavid du Colombier if(nodreg(&nod, nn, D_CX)) { 5133e12c5d1SDavid du Colombier regsalloc(&nod1, n); 5143e12c5d1SDavid du Colombier gmove(&nod, &nod1); 5153e12c5d1SDavid du Colombier cgen(n, &nod); 5163e12c5d1SDavid du Colombier if(nn != Z) 5173e12c5d1SDavid du Colombier gmove(&nod, nn); 5183e12c5d1SDavid du Colombier gmove(&nod1, &nod); 5193e12c5d1SDavid du Colombier break; 5203e12c5d1SDavid du Colombier } 5213e12c5d1SDavid du Colombier reg[D_CX]++; 5223e12c5d1SDavid du Colombier 5233e12c5d1SDavid du Colombier if(r->complex >= l->complex) { 5243e12c5d1SDavid du Colombier cgen(r, &nod); 5257dd7cddfSDavid du Colombier if(hardleft) 5263e12c5d1SDavid du Colombier reglcgen(&nod1, l, Z); 5273e12c5d1SDavid du Colombier else 5283e12c5d1SDavid du Colombier nod1 = *l; 5293e12c5d1SDavid du Colombier } else { 5307dd7cddfSDavid du Colombier if(hardleft) 5313e12c5d1SDavid du Colombier reglcgen(&nod1, l, Z); 5323e12c5d1SDavid du Colombier else 5333e12c5d1SDavid du Colombier nod1 = *l; 5343e12c5d1SDavid du Colombier cgen(r, &nod); 5353e12c5d1SDavid du Colombier } 5363e12c5d1SDavid du Colombier 5373e12c5d1SDavid du Colombier gopcode(o, l->type, &nod, &nod1); 5383e12c5d1SDavid du Colombier regfree(&nod); 5393e12c5d1SDavid du Colombier if(nn != Z) 5403e12c5d1SDavid du Colombier gmove(&nod1, nn); 5417dd7cddfSDavid du Colombier if(hardleft) 5423e12c5d1SDavid du Colombier regfree(&nod1); 5433e12c5d1SDavid du Colombier break; 5443e12c5d1SDavid du Colombier 5453e12c5d1SDavid du Colombier case OASAND: 5463e12c5d1SDavid du Colombier case OASADD: 5473e12c5d1SDavid du Colombier case OASSUB: 5483e12c5d1SDavid du Colombier case OASXOR: 5493e12c5d1SDavid du Colombier case OASOR: 5503e12c5d1SDavid du Colombier asand: 5513e12c5d1SDavid du Colombier if(l->op == OBIT) 5523e12c5d1SDavid du Colombier goto asbitop; 553fc375d71SDavid du Colombier if(typefd[n->type->etype]||typefd[r->type->etype]) 5543e12c5d1SDavid du Colombier goto asfop; 5553e12c5d1SDavid du Colombier if(l->complex >= r->complex) { 5567dd7cddfSDavid du Colombier if(hardleft) 5573e12c5d1SDavid du Colombier reglcgen(&nod, l, Z); 5583e12c5d1SDavid du Colombier else 5593e12c5d1SDavid du Colombier nod = *l; 5603e12c5d1SDavid du Colombier if(r->op != OCONST) { 5613e12c5d1SDavid du Colombier regalloc(&nod1, r, nn); 5623e12c5d1SDavid du Colombier cgen(r, &nod1); 5633e12c5d1SDavid du Colombier gopcode(o, l->type, &nod1, &nod); 5643e12c5d1SDavid du Colombier regfree(&nod1); 5653e12c5d1SDavid du Colombier } else 5663e12c5d1SDavid du Colombier gopcode(o, l->type, r, &nod); 5673e12c5d1SDavid du Colombier } else { 5683e12c5d1SDavid du Colombier regalloc(&nod1, r, nn); 5693e12c5d1SDavid du Colombier cgen(r, &nod1); 5707dd7cddfSDavid du Colombier if(hardleft) 5713e12c5d1SDavid du Colombier reglcgen(&nod, l, Z); 5723e12c5d1SDavid du Colombier else 5733e12c5d1SDavid du Colombier nod = *l; 574219b2ee8SDavid du Colombier gopcode(o, l->type, &nod1, &nod); 5753e12c5d1SDavid du Colombier regfree(&nod1); 5763e12c5d1SDavid du Colombier } 5773e12c5d1SDavid du Colombier if(nn != Z) 5783e12c5d1SDavid du Colombier gmove(&nod, nn); 5797dd7cddfSDavid du Colombier if(hardleft) 5803e12c5d1SDavid du Colombier regfree(&nod); 5813e12c5d1SDavid du Colombier break; 5823e12c5d1SDavid du Colombier 5833e12c5d1SDavid du Colombier case OASLMUL: 5843e12c5d1SDavid du Colombier case OASLDIV: 5853e12c5d1SDavid du Colombier case OASLMOD: 5863e12c5d1SDavid du Colombier case OASMUL: 5873e12c5d1SDavid du Colombier case OASDIV: 5883e12c5d1SDavid du Colombier case OASMOD: 5893e12c5d1SDavid du Colombier if(l->op == OBIT) 5903e12c5d1SDavid du Colombier goto asbitop; 591fc375d71SDavid du Colombier if(typefd[n->type->etype]||typefd[r->type->etype]) 5923e12c5d1SDavid du Colombier goto asfop; 593375daca8SDavid du Colombier if(r->op == OCONST) { 594375daca8SDavid du Colombier SET(v); 595375daca8SDavid du Colombier switch(o) { 596375daca8SDavid du Colombier case OASDIV: 597375daca8SDavid du Colombier case OASMOD: 598375daca8SDavid du Colombier c = r->vconst; 599375daca8SDavid du Colombier if(c < 0) 600375daca8SDavid du Colombier c = -c; 601375daca8SDavid du Colombier v = log2(c); 602375daca8SDavid du Colombier if(v < 0) 603375daca8SDavid du Colombier break; 604375daca8SDavid du Colombier /* fall thru */ 605375daca8SDavid du Colombier case OASMUL: 606375daca8SDavid du Colombier case OASLMUL: 6079a747e4fSDavid du Colombier if(hardleft) 6089a747e4fSDavid du Colombier reglcgen(&nod2, l, Z); 6099a747e4fSDavid du Colombier else 6109a747e4fSDavid du Colombier nod2 = *l; 6119a747e4fSDavid du Colombier regalloc(&nod, l, nn); 6129a747e4fSDavid du Colombier cgen(&nod2, &nod); 613375daca8SDavid du Colombier switch(o) { 614375daca8SDavid du Colombier case OASMUL: 615375daca8SDavid du Colombier case OASLMUL: 616375daca8SDavid du Colombier mulgen(n->type, r, &nod); 617375daca8SDavid du Colombier break; 618375daca8SDavid du Colombier case OASDIV: 619375daca8SDavid du Colombier sdiv2(r->vconst, v, l, &nod); 620375daca8SDavid du Colombier break; 621375daca8SDavid du Colombier case OASMOD: 622375daca8SDavid du Colombier smod2(r->vconst, v, l, &nod); 623375daca8SDavid du Colombier break; 624375daca8SDavid du Colombier } 625375daca8SDavid du Colombier havev: 6269a747e4fSDavid du Colombier gmove(&nod, &nod2); 6279a747e4fSDavid du Colombier if(nn != Z) 6289a747e4fSDavid du Colombier gmove(&nod, nn); 6299a747e4fSDavid du Colombier if(hardleft) 6309a747e4fSDavid du Colombier regfree(&nod2); 6319a747e4fSDavid du Colombier regfree(&nod); 632375daca8SDavid du Colombier goto done; 633375daca8SDavid du Colombier case OASLDIV: 634375daca8SDavid du Colombier c = r->vconst; 635375daca8SDavid du Colombier if((c & 0x80000000) == 0) 6369a747e4fSDavid du Colombier break; 637375daca8SDavid du Colombier if(hardleft) 638375daca8SDavid du Colombier reglcgen(&nod2, l, Z); 639375daca8SDavid du Colombier else 640375daca8SDavid du Colombier nod2 = *l; 641375daca8SDavid du Colombier regalloc(&nod1, l, nn); 642375daca8SDavid du Colombier cgen(&nod2, &nod1); 643375daca8SDavid du Colombier regalloc(&nod, l, nn); 644375daca8SDavid du Colombier zeroregm(&nod); 645375daca8SDavid du Colombier gins(ACMPL, &nod1, nodconst(c)); 646375daca8SDavid du Colombier gins(ASBBL, nodconst(-1), &nod); 647375daca8SDavid du Colombier regfree(&nod1); 648375daca8SDavid du Colombier goto havev; 6499a747e4fSDavid du Colombier } 650375daca8SDavid du Colombier } 651375daca8SDavid du Colombier 652375daca8SDavid du Colombier if(o == OASMUL) { 653375daca8SDavid du Colombier /* should favour AX */ 654375daca8SDavid du Colombier regalloc(&nod, l, nn); 655375daca8SDavid du Colombier if(r->complex >= FNX) { 656375daca8SDavid du Colombier regalloc(&nod1, r, Z); 657375daca8SDavid du Colombier cgen(r, &nod1); 658375daca8SDavid du Colombier r = &nod1; 659375daca8SDavid du Colombier } 660375daca8SDavid du Colombier if(hardleft) 661375daca8SDavid du Colombier reglcgen(&nod2, l, Z); 662375daca8SDavid du Colombier else 663375daca8SDavid du Colombier nod2 = *l; 664375daca8SDavid du Colombier cgen(&nod2, &nod); 665375daca8SDavid du Colombier if(r->addable < INDEXED) { 666375daca8SDavid du Colombier if(r->complex < FNX) { 667375daca8SDavid du Colombier regalloc(&nod1, r, Z); 668375daca8SDavid du Colombier cgen(r, &nod1); 669375daca8SDavid du Colombier } 670375daca8SDavid du Colombier gopcode(OASMUL, n->type, &nod1, &nod); 671375daca8SDavid du Colombier regfree(&nod1); 672375daca8SDavid du Colombier } 673375daca8SDavid du Colombier else 674375daca8SDavid du Colombier gopcode(OASMUL, n->type, r, &nod); 675375daca8SDavid du Colombier if(r == &nod1) 676375daca8SDavid du Colombier regfree(r); 677375daca8SDavid du Colombier gmove(&nod, &nod2); 678375daca8SDavid du Colombier if(nn != Z) 679375daca8SDavid du Colombier gmove(&nod, nn); 680375daca8SDavid du Colombier regfree(&nod); 681375daca8SDavid du Colombier if(hardleft) 682375daca8SDavid du Colombier regfree(&nod2); 683375daca8SDavid du Colombier goto done; 684375daca8SDavid du Colombier } 685375daca8SDavid du Colombier 6863e12c5d1SDavid du Colombier /* 6873e12c5d1SDavid du Colombier * get nod to be D_AX 6883e12c5d1SDavid du Colombier * get nod1 to be D_DX 6893e12c5d1SDavid du Colombier */ 6903e12c5d1SDavid du Colombier if(nodreg(&nod, nn, D_AX)) { 6913e12c5d1SDavid du Colombier regsalloc(&nod2, n); 6923e12c5d1SDavid du Colombier gmove(&nod, &nod2); 6933e12c5d1SDavid du Colombier v = reg[D_AX]; 6943e12c5d1SDavid du Colombier reg[D_AX] = 0; 6953e12c5d1SDavid du Colombier 6963e12c5d1SDavid du Colombier if(isreg(l, D_AX)) { 6973e12c5d1SDavid du Colombier nod3 = *n; 6983e12c5d1SDavid du Colombier nod3.left = &nod2; 6993e12c5d1SDavid du Colombier cgen(&nod3, nn); 7003e12c5d1SDavid du Colombier } else 7013e12c5d1SDavid du Colombier if(isreg(r, D_AX)) { 7023e12c5d1SDavid du Colombier nod3 = *n; 7033e12c5d1SDavid du Colombier nod3.right = &nod2; 7043e12c5d1SDavid du Colombier cgen(&nod3, nn); 7053e12c5d1SDavid du Colombier } else 7063e12c5d1SDavid du Colombier cgen(n, nn); 7073e12c5d1SDavid du Colombier 7083e12c5d1SDavid du Colombier gmove(&nod2, &nod); 7093e12c5d1SDavid du Colombier reg[D_AX] = v; 7103e12c5d1SDavid du Colombier break; 7113e12c5d1SDavid du Colombier } 7123e12c5d1SDavid du Colombier if(nodreg(&nod1, nn, D_DX)) { 7133e12c5d1SDavid du Colombier regsalloc(&nod2, n); 7143e12c5d1SDavid du Colombier gmove(&nod1, &nod2); 7153e12c5d1SDavid du Colombier v = reg[D_DX]; 7163e12c5d1SDavid du Colombier reg[D_DX] = 0; 7173e12c5d1SDavid du Colombier 7183e12c5d1SDavid du Colombier if(isreg(l, D_DX)) { 7193e12c5d1SDavid du Colombier nod3 = *n; 7203e12c5d1SDavid du Colombier nod3.left = &nod2; 7213e12c5d1SDavid du Colombier cgen(&nod3, nn); 7223e12c5d1SDavid du Colombier } else 7233e12c5d1SDavid du Colombier if(isreg(r, D_DX)) { 7243e12c5d1SDavid du Colombier nod3 = *n; 7253e12c5d1SDavid du Colombier nod3.right = &nod2; 7263e12c5d1SDavid du Colombier cgen(&nod3, nn); 7273e12c5d1SDavid du Colombier } else 7283e12c5d1SDavid du Colombier cgen(n, nn); 7293e12c5d1SDavid du Colombier 7303e12c5d1SDavid du Colombier gmove(&nod2, &nod1); 7313e12c5d1SDavid du Colombier reg[D_DX] = v; 7323e12c5d1SDavid du Colombier break; 7333e12c5d1SDavid du Colombier } 7343e12c5d1SDavid du Colombier reg[D_AX]++; 7353e12c5d1SDavid du Colombier reg[D_DX]++; 7363e12c5d1SDavid du Colombier 7373e12c5d1SDavid du Colombier if(l->complex >= r->complex) { 7387dd7cddfSDavid du Colombier if(hardleft) 7393e12c5d1SDavid du Colombier reglcgen(&nod2, l, Z); 7403e12c5d1SDavid du Colombier else 7413e12c5d1SDavid du Colombier nod2 = *l; 7423e12c5d1SDavid du Colombier cgen(&nod2, &nod); 743375daca8SDavid du Colombier if(r->op == OCONST) { 744375daca8SDavid du Colombier switch(o) { 745375daca8SDavid du Colombier case OASDIV: 746375daca8SDavid du Colombier sdivgen(&nod2, r, &nod, &nod1); 747375daca8SDavid du Colombier goto divdone; 748375daca8SDavid du Colombier case OASLDIV: 749375daca8SDavid du Colombier udivgen(&nod2, r, &nod, &nod1); 750375daca8SDavid du Colombier divdone: 751375daca8SDavid du Colombier gmove(&nod1, &nod2); 752375daca8SDavid du Colombier if(nn != Z) 753375daca8SDavid du Colombier gmove(&nod1, nn); 754375daca8SDavid du Colombier goto freelxaxdx; 755375daca8SDavid du Colombier } 756375daca8SDavid du Colombier } 7573e12c5d1SDavid du Colombier if(o == OASDIV || o == OASMOD) 7583e12c5d1SDavid du Colombier gins(ACDQ, Z, Z); 7593e12c5d1SDavid du Colombier if(o == OASLDIV || o == OASLMOD) 760da51d93aSDavid du Colombier zeroregm(&nod1); 7613e12c5d1SDavid du Colombier if(r->addable < INDEXED || r->op == OCONST || 7627dd7cddfSDavid du Colombier !typeil[r->type->etype]) { 7633e12c5d1SDavid du Colombier regalloc(&nod3, r, Z); 7643e12c5d1SDavid du Colombier cgen(r, &nod3); 7653e12c5d1SDavid du Colombier gopcode(o, l->type, &nod3, Z); 7663e12c5d1SDavid du Colombier regfree(&nod3); 7673e12c5d1SDavid du Colombier } else 7683e12c5d1SDavid du Colombier gopcode(o, n->type, r, Z); 7693e12c5d1SDavid du Colombier } else { 7703e12c5d1SDavid du Colombier regalloc(&nod3, r, Z); 7713e12c5d1SDavid du Colombier cgen(r, &nod3); 7727dd7cddfSDavid du Colombier if(hardleft) 7733e12c5d1SDavid du Colombier reglcgen(&nod2, l, Z); 7743e12c5d1SDavid du Colombier else 7753e12c5d1SDavid du Colombier nod2 = *l; 7763e12c5d1SDavid du Colombier cgen(&nod2, &nod); 7773e12c5d1SDavid du Colombier if(o == OASDIV || o == OASMOD) 7783e12c5d1SDavid du Colombier gins(ACDQ, Z, Z); 7793e12c5d1SDavid du Colombier if(o == OASLDIV || o == OASLMOD) 780da51d93aSDavid du Colombier zeroregm(&nod1); 7813e12c5d1SDavid du Colombier gopcode(o, l->type, &nod3, Z); 7823e12c5d1SDavid du Colombier regfree(&nod3); 7833e12c5d1SDavid du Colombier } 7843e12c5d1SDavid du Colombier if(o == OASMOD || o == OASLMOD) { 7853e12c5d1SDavid du Colombier gmove(&nod1, &nod2); 7863e12c5d1SDavid du Colombier if(nn != Z) 7873e12c5d1SDavid du Colombier gmove(&nod1, nn); 7883e12c5d1SDavid du Colombier } else { 7893e12c5d1SDavid du Colombier gmove(&nod, &nod2); 7903e12c5d1SDavid du Colombier if(nn != Z) 7913e12c5d1SDavid du Colombier gmove(&nod, nn); 7923e12c5d1SDavid du Colombier } 793375daca8SDavid du Colombier freelxaxdx: 7947dd7cddfSDavid du Colombier if(hardleft) 7953e12c5d1SDavid du Colombier regfree(&nod2); 7963e12c5d1SDavid du Colombier regfree(&nod); 7973e12c5d1SDavid du Colombier regfree(&nod1); 7983e12c5d1SDavid du Colombier break; 7993e12c5d1SDavid du Colombier 8003e12c5d1SDavid du Colombier fop: 8013e12c5d1SDavid du Colombier if(l->complex >= r->complex) { 8023e12c5d1SDavid du Colombier cgen(l, &fregnode0); 8033e12c5d1SDavid du Colombier if(r->addable < INDEXED) { 8043e12c5d1SDavid du Colombier cgen(r, &fregnode0); 8053e12c5d1SDavid du Colombier fgopcode(o, &fregnode0, &fregnode1, 1, 0); 8063e12c5d1SDavid du Colombier } else 8073e12c5d1SDavid du Colombier fgopcode(o, r, &fregnode0, 0, 0); 8083e12c5d1SDavid du Colombier } else { 8093e12c5d1SDavid du Colombier cgen(r, &fregnode0); 8103e12c5d1SDavid du Colombier if(l->addable < INDEXED) { 8113e12c5d1SDavid du Colombier cgen(l, &fregnode0); 8123e12c5d1SDavid du Colombier fgopcode(o, &fregnode0, &fregnode1, 1, 1); 8133e12c5d1SDavid du Colombier } else 8143e12c5d1SDavid du Colombier fgopcode(o, l, &fregnode0, 0, 1); 8153e12c5d1SDavid du Colombier } 8163e12c5d1SDavid du Colombier gmove(&fregnode0, nn); 8173e12c5d1SDavid du Colombier break; 8183e12c5d1SDavid du Colombier 8193e12c5d1SDavid du Colombier asfop: 8203e12c5d1SDavid du Colombier if(l->complex >= r->complex) { 8217dd7cddfSDavid du Colombier if(hardleft) 8223e12c5d1SDavid du Colombier reglcgen(&nod, l, Z); 8233e12c5d1SDavid du Colombier else 8243e12c5d1SDavid du Colombier nod = *l; 8253e12c5d1SDavid du Colombier cgen(r, &fregnode0); 8263e12c5d1SDavid du Colombier } else { 8273e12c5d1SDavid du Colombier cgen(r, &fregnode0); 8287dd7cddfSDavid du Colombier if(hardleft) 8293e12c5d1SDavid du Colombier reglcgen(&nod, l, Z); 8303e12c5d1SDavid du Colombier else 8313e12c5d1SDavid du Colombier nod = *l; 8323e12c5d1SDavid du Colombier } 833219b2ee8SDavid du Colombier if(!typefd[l->type->etype]) { 8343e12c5d1SDavid du Colombier gmove(&nod, &fregnode0); 8353e12c5d1SDavid du Colombier fgopcode(o, &fregnode0, &fregnode1, 1, 1); 8363e12c5d1SDavid du Colombier } else 8373e12c5d1SDavid du Colombier fgopcode(o, &nod, &fregnode0, 0, 1); 8383e12c5d1SDavid du Colombier if(nn != Z) 8393e12c5d1SDavid du Colombier gins(AFMOVD, &fregnode0, &fregnode0); 8403e12c5d1SDavid du Colombier gmove(&fregnode0, &nod); 8413e12c5d1SDavid du Colombier if(nn != Z) 8423e12c5d1SDavid du Colombier gmove(&fregnode0, nn); 8437dd7cddfSDavid du Colombier if(hardleft) 8443e12c5d1SDavid du Colombier regfree(&nod); 8453e12c5d1SDavid du Colombier break; 8463e12c5d1SDavid du Colombier 8473e12c5d1SDavid du Colombier asbitop: 8483e12c5d1SDavid du Colombier regalloc(&nod4, n, nn); 8493e12c5d1SDavid du Colombier if(l->complex >= r->complex) { 8503e12c5d1SDavid du Colombier bitload(l, &nod, &nod1, &nod2, &nod4); 8513e12c5d1SDavid du Colombier regalloc(&nod3, r, Z); 8523e12c5d1SDavid du Colombier cgen(r, &nod3); 8533e12c5d1SDavid du Colombier } else { 8543e12c5d1SDavid du Colombier regalloc(&nod3, r, Z); 8553e12c5d1SDavid du Colombier cgen(r, &nod3); 8563e12c5d1SDavid du Colombier bitload(l, &nod, &nod1, &nod2, &nod4); 8573e12c5d1SDavid du Colombier } 8583e12c5d1SDavid du Colombier gmove(&nod, &nod4); 8593e12c5d1SDavid du Colombier 860219b2ee8SDavid du Colombier if(typefd[nod3.type->etype]) 8613e12c5d1SDavid du Colombier fgopcode(o, &fregnode0, &fregnode1, 1, 1); 8623e12c5d1SDavid du Colombier else { 8633e12c5d1SDavid du Colombier Node onod; 8643e12c5d1SDavid du Colombier 8653e12c5d1SDavid du Colombier /* incredible grot ... */ 8663e12c5d1SDavid du Colombier onod = nod3; 8673e12c5d1SDavid du Colombier onod.op = o; 8683e12c5d1SDavid du Colombier onod.complex = 2; 8693e12c5d1SDavid du Colombier onod.addable = 0; 8707dd7cddfSDavid du Colombier onod.type = tfield; 8713e12c5d1SDavid du Colombier onod.left = &nod4; 8723e12c5d1SDavid du Colombier onod.right = &nod3; 8733e12c5d1SDavid du Colombier cgen(&onod, Z); 8743e12c5d1SDavid du Colombier } 8753e12c5d1SDavid du Colombier regfree(&nod3); 8763e12c5d1SDavid du Colombier gmove(&nod4, &nod); 8773e12c5d1SDavid du Colombier regfree(&nod4); 8783e12c5d1SDavid du Colombier bitstore(l, &nod, &nod1, &nod2, nn); 8793e12c5d1SDavid du Colombier break; 8803e12c5d1SDavid du Colombier 8813e12c5d1SDavid du Colombier case OADDR: 8823e12c5d1SDavid du Colombier if(nn == Z) { 8833e12c5d1SDavid du Colombier nullwarn(l, Z); 8843e12c5d1SDavid du Colombier break; 8853e12c5d1SDavid du Colombier } 8863e12c5d1SDavid du Colombier lcgen(l, nn); 8873e12c5d1SDavid du Colombier break; 8883e12c5d1SDavid du Colombier 8893e12c5d1SDavid du Colombier case OFUNC: 8903e12c5d1SDavid du Colombier if(l->complex >= FNX) { 8913e12c5d1SDavid du Colombier if(l->op != OIND) 8923e12c5d1SDavid du Colombier diag(n, "bad function call"); 8933e12c5d1SDavid du Colombier 8943e12c5d1SDavid du Colombier regret(&nod, l->left); 8953e12c5d1SDavid du Colombier cgen(l->left, &nod); 8963e12c5d1SDavid du Colombier regsalloc(&nod1, l->left); 8973e12c5d1SDavid du Colombier gmove(&nod, &nod1); 8983e12c5d1SDavid du Colombier regfree(&nod); 8993e12c5d1SDavid du Colombier 9003e12c5d1SDavid du Colombier nod = *n; 9013e12c5d1SDavid du Colombier nod.left = &nod2; 9023e12c5d1SDavid du Colombier nod2 = *l; 9033e12c5d1SDavid du Colombier nod2.left = &nod1; 9043e12c5d1SDavid du Colombier nod2.complex = 1; 9053e12c5d1SDavid du Colombier cgen(&nod, nn); 9063e12c5d1SDavid du Colombier 9073e12c5d1SDavid du Colombier return; 9083e12c5d1SDavid du Colombier } 9093e12c5d1SDavid du Colombier gargs(r, &nod, &nod1); 9103e12c5d1SDavid du Colombier if(l->addable < INDEXED) { 9113e12c5d1SDavid du Colombier reglcgen(&nod, l, nn); 9123e12c5d1SDavid du Colombier nod.op = OREGISTER; 9133e12c5d1SDavid du Colombier gopcode(OFUNC, n->type, Z, &nod); 9143e12c5d1SDavid du Colombier regfree(&nod); 9153e12c5d1SDavid du Colombier } else 9163e12c5d1SDavid du Colombier gopcode(OFUNC, n->type, Z, l); 917*4ac975e2SDavid du Colombier if(REGARG>=0 && reg[REGARG]) 9183e12c5d1SDavid du Colombier reg[REGARG]--; 9193e12c5d1SDavid du Colombier if(nn != Z) { 9203e12c5d1SDavid du Colombier regret(&nod, n); 9213e12c5d1SDavid du Colombier gmove(&nod, nn); 9223e12c5d1SDavid du Colombier regfree(&nod); 9233e12c5d1SDavid du Colombier } else 924219b2ee8SDavid du Colombier if(typefd[n->type->etype]) 9253e12c5d1SDavid du Colombier gins(AFMOVDP, &fregnode0, &fregnode0); 9263e12c5d1SDavid du Colombier break; 9273e12c5d1SDavid du Colombier 9283e12c5d1SDavid du Colombier case OIND: 9293e12c5d1SDavid du Colombier if(nn == Z) { 9303e12c5d1SDavid du Colombier nullwarn(l, Z); 9313e12c5d1SDavid du Colombier break; 9323e12c5d1SDavid du Colombier } 9333e12c5d1SDavid du Colombier regialloc(&nod, n, nn); 9343e12c5d1SDavid du Colombier r = l; 9353e12c5d1SDavid du Colombier while(r->op == OADD) 9363e12c5d1SDavid du Colombier r = r->right; 9373e12c5d1SDavid du Colombier if(sconst(r)) { 938219b2ee8SDavid du Colombier v = r->vconst; 939219b2ee8SDavid du Colombier r->vconst = 0; 9403e12c5d1SDavid du Colombier cgen(l, &nod); 941219b2ee8SDavid du Colombier nod.xoffset += v; 942219b2ee8SDavid du Colombier r->vconst = v; 9433e12c5d1SDavid du Colombier } else 9443e12c5d1SDavid du Colombier cgen(l, &nod); 9453e12c5d1SDavid du Colombier regind(&nod, n); 9463e12c5d1SDavid du Colombier gmove(&nod, nn); 9473e12c5d1SDavid du Colombier regfree(&nod); 9483e12c5d1SDavid du Colombier break; 9493e12c5d1SDavid du Colombier 9503e12c5d1SDavid du Colombier case OEQ: 9513e12c5d1SDavid du Colombier case ONE: 9523e12c5d1SDavid du Colombier case OLE: 9533e12c5d1SDavid du Colombier case OLT: 9543e12c5d1SDavid du Colombier case OGE: 9553e12c5d1SDavid du Colombier case OGT: 9563e12c5d1SDavid du Colombier case OLO: 9573e12c5d1SDavid du Colombier case OLS: 9583e12c5d1SDavid du Colombier case OHI: 9593e12c5d1SDavid du Colombier case OHS: 9603e12c5d1SDavid du Colombier if(nn == Z) { 9613e12c5d1SDavid du Colombier nullwarn(l, r); 9623e12c5d1SDavid du Colombier break; 9633e12c5d1SDavid du Colombier } 9643e12c5d1SDavid du Colombier boolgen(n, 1, nn); 9653e12c5d1SDavid du Colombier break; 9663e12c5d1SDavid du Colombier 9673e12c5d1SDavid du Colombier case OANDAND: 9683e12c5d1SDavid du Colombier case OOROR: 9693e12c5d1SDavid du Colombier boolgen(n, 1, nn); 9703e12c5d1SDavid du Colombier if(nn == Z) 9713e12c5d1SDavid du Colombier patch(p, pc); 9723e12c5d1SDavid du Colombier break; 9733e12c5d1SDavid du Colombier 9743e12c5d1SDavid du Colombier case ONOT: 9753e12c5d1SDavid du Colombier if(nn == Z) { 9763e12c5d1SDavid du Colombier nullwarn(l, Z); 9773e12c5d1SDavid du Colombier break; 9783e12c5d1SDavid du Colombier } 9793e12c5d1SDavid du Colombier boolgen(n, 1, nn); 9803e12c5d1SDavid du Colombier break; 9813e12c5d1SDavid du Colombier 9823e12c5d1SDavid du Colombier case OCOMMA: 9833e12c5d1SDavid du Colombier cgen(l, Z); 9843e12c5d1SDavid du Colombier cgen(r, nn); 9853e12c5d1SDavid du Colombier break; 9863e12c5d1SDavid du Colombier 9873e12c5d1SDavid du Colombier case OCAST: 9883e12c5d1SDavid du Colombier if(nn == Z) { 9893e12c5d1SDavid du Colombier nullwarn(l, Z); 9903e12c5d1SDavid du Colombier break; 9913e12c5d1SDavid du Colombier } 9923e12c5d1SDavid du Colombier /* 9933e12c5d1SDavid du Colombier * convert from types l->n->nn 9943e12c5d1SDavid du Colombier */ 9953e12c5d1SDavid du Colombier if(nocast(l->type, n->type) && nocast(n->type, nn->type)) { 9963e12c5d1SDavid du Colombier /* both null, gen l->nn */ 9973e12c5d1SDavid du Colombier cgen(l, nn); 9983e12c5d1SDavid du Colombier break; 9993e12c5d1SDavid du Colombier } 1000da51d93aSDavid du Colombier if(typev[l->type->etype]) { 1001da51d93aSDavid du Colombier cgen64(n, nn); 1002da51d93aSDavid du Colombier break; 1003da51d93aSDavid du Colombier } 10043e12c5d1SDavid du Colombier regalloc(&nod, l, nn); 10053e12c5d1SDavid du Colombier cgen(l, &nod); 10063e12c5d1SDavid du Colombier regalloc(&nod1, n, &nod); 10073e12c5d1SDavid du Colombier gmove(&nod, &nod1); 10083e12c5d1SDavid du Colombier gmove(&nod1, nn); 10093e12c5d1SDavid du Colombier regfree(&nod1); 10103e12c5d1SDavid du Colombier regfree(&nod); 10113e12c5d1SDavid du Colombier break; 10123e12c5d1SDavid du Colombier 10133e12c5d1SDavid du Colombier case ODOT: 10143e12c5d1SDavid du Colombier sugen(l, nodrat, l->type->width); 10157dd7cddfSDavid du Colombier if(nn == Z) 10167dd7cddfSDavid du Colombier break; 10173e12c5d1SDavid du Colombier warn(n, "non-interruptable temporary"); 10183e12c5d1SDavid du Colombier nod = *nodrat; 10193e12c5d1SDavid du Colombier if(!r || r->op != OCONST) { 10203e12c5d1SDavid du Colombier diag(n, "DOT and no offset"); 10213e12c5d1SDavid du Colombier break; 10223e12c5d1SDavid du Colombier } 1023219b2ee8SDavid du Colombier nod.xoffset += (long)r->vconst; 10243e12c5d1SDavid du Colombier nod.type = n->type; 10253e12c5d1SDavid du Colombier cgen(&nod, nn); 10263e12c5d1SDavid du Colombier break; 10273e12c5d1SDavid du Colombier 10283e12c5d1SDavid du Colombier case OCOND: 10293e12c5d1SDavid du Colombier bcgen(l, 1); 10303e12c5d1SDavid du Colombier p1 = p; 10313e12c5d1SDavid du Colombier cgen(r->left, nn); 10323e12c5d1SDavid du Colombier gbranch(OGOTO); 10333e12c5d1SDavid du Colombier patch(p1, pc); 10343e12c5d1SDavid du Colombier p1 = p; 10353e12c5d1SDavid du Colombier cgen(r->right, nn); 10363e12c5d1SDavid du Colombier patch(p1, pc); 10373e12c5d1SDavid du Colombier break; 10383e12c5d1SDavid du Colombier 10393e12c5d1SDavid du Colombier case OPOSTINC: 10403e12c5d1SDavid du Colombier case OPOSTDEC: 10413e12c5d1SDavid du Colombier v = 1; 10423e12c5d1SDavid du Colombier if(l->type->etype == TIND) 10433e12c5d1SDavid du Colombier v = l->type->link->width; 10443e12c5d1SDavid du Colombier if(o == OPOSTDEC) 10453e12c5d1SDavid du Colombier v = -v; 10463e12c5d1SDavid du Colombier if(l->op == OBIT) 10473e12c5d1SDavid du Colombier goto bitinc; 10483e12c5d1SDavid du Colombier if(nn == Z) 10493e12c5d1SDavid du Colombier goto pre; 10503e12c5d1SDavid du Colombier 10517dd7cddfSDavid du Colombier if(hardleft) 10523e12c5d1SDavid du Colombier reglcgen(&nod, l, Z); 10533e12c5d1SDavid du Colombier else 10543e12c5d1SDavid du Colombier nod = *l; 10553e12c5d1SDavid du Colombier 1056219b2ee8SDavid du Colombier if(typefd[n->type->etype]) 10573e12c5d1SDavid du Colombier goto fltinc; 10583e12c5d1SDavid du Colombier gmove(&nod, nn); 10593e12c5d1SDavid du Colombier gopcode(OADD, n->type, nodconst(v), &nod); 10607dd7cddfSDavid du Colombier if(hardleft) 10613e12c5d1SDavid du Colombier regfree(&nod); 10623e12c5d1SDavid du Colombier break; 10633e12c5d1SDavid du Colombier 10643e12c5d1SDavid du Colombier case OPREINC: 10653e12c5d1SDavid du Colombier case OPREDEC: 10663e12c5d1SDavid du Colombier v = 1; 10673e12c5d1SDavid du Colombier if(l->type->etype == TIND) 10683e12c5d1SDavid du Colombier v = l->type->link->width; 10693e12c5d1SDavid du Colombier if(o == OPREDEC) 10703e12c5d1SDavid du Colombier v = -v; 10713e12c5d1SDavid du Colombier if(l->op == OBIT) 10723e12c5d1SDavid du Colombier goto bitinc; 10733e12c5d1SDavid du Colombier 10743e12c5d1SDavid du Colombier pre: 10757dd7cddfSDavid du Colombier if(hardleft) 10763e12c5d1SDavid du Colombier reglcgen(&nod, l, Z); 10773e12c5d1SDavid du Colombier else 10783e12c5d1SDavid du Colombier nod = *l; 1079219b2ee8SDavid du Colombier if(typefd[n->type->etype]) 10803e12c5d1SDavid du Colombier goto fltinc; 10813e12c5d1SDavid du Colombier gopcode(OADD, n->type, nodconst(v), &nod); 10823e12c5d1SDavid du Colombier if(nn != Z) 10833e12c5d1SDavid du Colombier gmove(&nod, nn); 10847dd7cddfSDavid du Colombier if(hardleft) 10853e12c5d1SDavid du Colombier regfree(&nod); 10863e12c5d1SDavid du Colombier break; 10873e12c5d1SDavid du Colombier 10883e12c5d1SDavid du Colombier fltinc: 10893e12c5d1SDavid du Colombier gmove(&nod, &fregnode0); 10903e12c5d1SDavid du Colombier if(nn != Z && (o == OPOSTINC || o == OPOSTDEC)) 10913e12c5d1SDavid du Colombier gins(AFMOVD, &fregnode0, &fregnode0); 10923e12c5d1SDavid du Colombier gins(AFLD1, Z, Z); 10933e12c5d1SDavid du Colombier if(v < 0) 10943e12c5d1SDavid du Colombier fgopcode(OSUB, &fregnode0, &fregnode1, 1, 0); 10953e12c5d1SDavid du Colombier else 10963e12c5d1SDavid du Colombier fgopcode(OADD, &fregnode0, &fregnode1, 1, 0); 10973e12c5d1SDavid du Colombier if(nn != Z && (o == OPREINC || o == OPREDEC)) 10983e12c5d1SDavid du Colombier gins(AFMOVD, &fregnode0, &fregnode0); 10993e12c5d1SDavid du Colombier gmove(&fregnode0, &nod); 11007dd7cddfSDavid du Colombier if(hardleft) 11013e12c5d1SDavid du Colombier regfree(&nod); 11023e12c5d1SDavid du Colombier break; 11033e12c5d1SDavid du Colombier 11043e12c5d1SDavid du Colombier bitinc: 11053e12c5d1SDavid du Colombier if(nn != Z && (o == OPOSTINC || o == OPOSTDEC)) { 11063e12c5d1SDavid du Colombier bitload(l, &nod, &nod1, &nod2, Z); 11073e12c5d1SDavid du Colombier gmove(&nod, nn); 11087dd7cddfSDavid du Colombier gopcode(OADD, tfield, nodconst(v), &nod); 11093e12c5d1SDavid du Colombier bitstore(l, &nod, &nod1, &nod2, Z); 11103e12c5d1SDavid du Colombier break; 11113e12c5d1SDavid du Colombier } 11123e12c5d1SDavid du Colombier bitload(l, &nod, &nod1, &nod2, nn); 11137dd7cddfSDavid du Colombier gopcode(OADD, tfield, nodconst(v), &nod); 11143e12c5d1SDavid du Colombier bitstore(l, &nod, &nod1, &nod2, nn); 11153e12c5d1SDavid du Colombier break; 11163e12c5d1SDavid du Colombier } 1117375daca8SDavid du Colombier done: 11183e12c5d1SDavid du Colombier cursafe = curs; 11193e12c5d1SDavid du Colombier } 11203e12c5d1SDavid du Colombier 11213e12c5d1SDavid du Colombier void 11223e12c5d1SDavid du Colombier reglcgen(Node *t, Node *n, Node *nn) 11233e12c5d1SDavid du Colombier { 11243e12c5d1SDavid du Colombier Node *r; 11253e12c5d1SDavid du Colombier long v; 11263e12c5d1SDavid du Colombier 11273e12c5d1SDavid du Colombier regialloc(t, n, nn); 11283e12c5d1SDavid du Colombier if(n->op == OIND) { 11293e12c5d1SDavid du Colombier r = n->left; 11303e12c5d1SDavid du Colombier while(r->op == OADD) 11313e12c5d1SDavid du Colombier r = r->right; 11323e12c5d1SDavid du Colombier if(sconst(r)) { 1133219b2ee8SDavid du Colombier v = r->vconst; 1134219b2ee8SDavid du Colombier r->vconst = 0; 11353e12c5d1SDavid du Colombier lcgen(n, t); 1136219b2ee8SDavid du Colombier t->xoffset += v; 1137219b2ee8SDavid du Colombier r->vconst = v; 11383e12c5d1SDavid du Colombier regind(t, n); 11393e12c5d1SDavid du Colombier return; 11403e12c5d1SDavid du Colombier } 11413e12c5d1SDavid du Colombier } 11423e12c5d1SDavid du Colombier lcgen(n, t); 11433e12c5d1SDavid du Colombier regind(t, n); 11443e12c5d1SDavid du Colombier } 11453e12c5d1SDavid du Colombier 11463e12c5d1SDavid du Colombier void 11473e12c5d1SDavid du Colombier lcgen(Node *n, Node *nn) 11483e12c5d1SDavid du Colombier { 11493e12c5d1SDavid du Colombier Prog *p1; 11503e12c5d1SDavid du Colombier Node nod; 11513e12c5d1SDavid du Colombier 11523e12c5d1SDavid du Colombier if(debug['g']) { 11533e12c5d1SDavid du Colombier prtree(nn, "lcgen lhs"); 11543e12c5d1SDavid du Colombier prtree(n, "lcgen"); 11553e12c5d1SDavid du Colombier } 11563e12c5d1SDavid du Colombier if(n == Z || n->type == T) 11573e12c5d1SDavid du Colombier return; 11583e12c5d1SDavid du Colombier if(nn == Z) { 11593e12c5d1SDavid du Colombier nn = &nod; 11603e12c5d1SDavid du Colombier regalloc(&nod, n, Z); 11613e12c5d1SDavid du Colombier } 11623e12c5d1SDavid du Colombier switch(n->op) { 11633e12c5d1SDavid du Colombier default: 11643e12c5d1SDavid du Colombier if(n->addable < INDEXED) { 11653e12c5d1SDavid du Colombier diag(n, "unknown op in lcgen: %O", n->op); 11663e12c5d1SDavid du Colombier break; 11673e12c5d1SDavid du Colombier } 11683e12c5d1SDavid du Colombier gopcode(OADDR, n->type, n, nn); 11693e12c5d1SDavid du Colombier break; 11703e12c5d1SDavid du Colombier 11713e12c5d1SDavid du Colombier case OCOMMA: 11723e12c5d1SDavid du Colombier cgen(n->left, n->left); 11733e12c5d1SDavid du Colombier lcgen(n->right, nn); 11743e12c5d1SDavid du Colombier break; 11753e12c5d1SDavid du Colombier 11763e12c5d1SDavid du Colombier case OIND: 11773e12c5d1SDavid du Colombier cgen(n->left, nn); 11783e12c5d1SDavid du Colombier break; 11793e12c5d1SDavid du Colombier 11803e12c5d1SDavid du Colombier case OCOND: 11813e12c5d1SDavid du Colombier bcgen(n->left, 1); 11823e12c5d1SDavid du Colombier p1 = p; 11833e12c5d1SDavid du Colombier lcgen(n->right->left, nn); 11843e12c5d1SDavid du Colombier gbranch(OGOTO); 11853e12c5d1SDavid du Colombier patch(p1, pc); 11863e12c5d1SDavid du Colombier p1 = p; 11873e12c5d1SDavid du Colombier lcgen(n->right->right, nn); 11883e12c5d1SDavid du Colombier patch(p1, pc); 11893e12c5d1SDavid du Colombier break; 11903e12c5d1SDavid du Colombier } 11913e12c5d1SDavid du Colombier } 11923e12c5d1SDavid du Colombier 11933e12c5d1SDavid du Colombier void 11943e12c5d1SDavid du Colombier bcgen(Node *n, int true) 11953e12c5d1SDavid du Colombier { 11963e12c5d1SDavid du Colombier 11973e12c5d1SDavid du Colombier if(n->type == T) 11983e12c5d1SDavid du Colombier gbranch(OGOTO); 11993e12c5d1SDavid du Colombier else 12003e12c5d1SDavid du Colombier boolgen(n, true, Z); 12013e12c5d1SDavid du Colombier } 12023e12c5d1SDavid du Colombier 12033e12c5d1SDavid du Colombier void 12043e12c5d1SDavid du Colombier boolgen(Node *n, int true, Node *nn) 12053e12c5d1SDavid du Colombier { 12063e12c5d1SDavid du Colombier int o; 12073e12c5d1SDavid du Colombier Prog *p1, *p2; 12083e12c5d1SDavid du Colombier Node *l, *r, nod, nod1; 12093e12c5d1SDavid du Colombier long curs; 12103e12c5d1SDavid du Colombier 12113e12c5d1SDavid du Colombier if(debug['g']) { 12123e12c5d1SDavid du Colombier prtree(nn, "boolgen lhs"); 12133e12c5d1SDavid du Colombier prtree(n, "boolgen"); 12143e12c5d1SDavid du Colombier } 12153e12c5d1SDavid du Colombier curs = cursafe; 12163e12c5d1SDavid du Colombier l = n->left; 12173e12c5d1SDavid du Colombier r = n->right; 12183e12c5d1SDavid du Colombier switch(n->op) { 12193e12c5d1SDavid du Colombier 12203e12c5d1SDavid du Colombier default: 1221da51d93aSDavid du Colombier if(typev[n->type->etype]) { 1222da51d93aSDavid du Colombier testv(n, true); 1223da51d93aSDavid du Colombier goto com; 1224da51d93aSDavid du Colombier } 12253e12c5d1SDavid du Colombier o = ONE; 12263e12c5d1SDavid du Colombier if(true) 12273e12c5d1SDavid du Colombier o = OEQ; 1228219b2ee8SDavid du Colombier if(typefd[n->type->etype]) { 12293e12c5d1SDavid du Colombier if(n->addable < INDEXED) { 12303e12c5d1SDavid du Colombier cgen(n, &fregnode0); 12313e12c5d1SDavid du Colombier gins(AFLDZ, Z, Z); 12323e12c5d1SDavid du Colombier fgopcode(o, &fregnode0, &fregnode1, 1, 1); 12333e12c5d1SDavid du Colombier } else { 12343e12c5d1SDavid du Colombier gins(AFLDZ, Z, Z); 12353e12c5d1SDavid du Colombier fgopcode(o, n, &fregnode0, 0, 1); 12363e12c5d1SDavid du Colombier } 12373e12c5d1SDavid du Colombier goto com; 12383e12c5d1SDavid du Colombier } 1239219b2ee8SDavid du Colombier /* bad, 13 is address of external that becomes constant */ 1240219b2ee8SDavid du Colombier if(n->addable >= INDEXED && n->addable != 13) { 12413e12c5d1SDavid du Colombier gopcode(o, n->type, n, nodconst(0)); 12423e12c5d1SDavid du Colombier goto com; 12433e12c5d1SDavid du Colombier } 12443e12c5d1SDavid du Colombier regalloc(&nod, n, nn); 12453e12c5d1SDavid du Colombier cgen(n, &nod); 12463e12c5d1SDavid du Colombier gopcode(o, n->type, &nod, nodconst(0)); 12473e12c5d1SDavid du Colombier regfree(&nod); 12483e12c5d1SDavid du Colombier goto com; 12493e12c5d1SDavid du Colombier 12503e12c5d1SDavid du Colombier case OCONST: 12513e12c5d1SDavid du Colombier o = vconst(n); 12523e12c5d1SDavid du Colombier if(!true) 12533e12c5d1SDavid du Colombier o = !o; 12543e12c5d1SDavid du Colombier gbranch(OGOTO); 12553e12c5d1SDavid du Colombier if(o) { 12563e12c5d1SDavid du Colombier p1 = p; 12573e12c5d1SDavid du Colombier gbranch(OGOTO); 12583e12c5d1SDavid du Colombier patch(p1, pc); 12593e12c5d1SDavid du Colombier } 12603e12c5d1SDavid du Colombier goto com; 12613e12c5d1SDavid du Colombier 12623e12c5d1SDavid du Colombier case OCOMMA: 12633e12c5d1SDavid du Colombier cgen(l, Z); 12643e12c5d1SDavid du Colombier boolgen(r, true, nn); 12653e12c5d1SDavid du Colombier break; 12663e12c5d1SDavid du Colombier 12673e12c5d1SDavid du Colombier case ONOT: 12683e12c5d1SDavid du Colombier boolgen(l, !true, nn); 12693e12c5d1SDavid du Colombier break; 12703e12c5d1SDavid du Colombier 12713e12c5d1SDavid du Colombier case OCOND: 12723e12c5d1SDavid du Colombier bcgen(l, 1); 12733e12c5d1SDavid du Colombier p1 = p; 12743e12c5d1SDavid du Colombier bcgen(r->left, true); 12753e12c5d1SDavid du Colombier p2 = p; 12763e12c5d1SDavid du Colombier gbranch(OGOTO); 12773e12c5d1SDavid du Colombier patch(p1, pc); 12783e12c5d1SDavid du Colombier p1 = p; 12793e12c5d1SDavid du Colombier bcgen(r->right, !true); 12803e12c5d1SDavid du Colombier patch(p2, pc); 12813e12c5d1SDavid du Colombier p2 = p; 12823e12c5d1SDavid du Colombier gbranch(OGOTO); 12833e12c5d1SDavid du Colombier patch(p1, pc); 12843e12c5d1SDavid du Colombier patch(p2, pc); 12853e12c5d1SDavid du Colombier goto com; 12863e12c5d1SDavid du Colombier 12873e12c5d1SDavid du Colombier case OANDAND: 12883e12c5d1SDavid du Colombier if(!true) 12893e12c5d1SDavid du Colombier goto caseor; 12903e12c5d1SDavid du Colombier 12913e12c5d1SDavid du Colombier caseand: 12923e12c5d1SDavid du Colombier bcgen(l, true); 12933e12c5d1SDavid du Colombier p1 = p; 12943e12c5d1SDavid du Colombier bcgen(r, !true); 12953e12c5d1SDavid du Colombier p2 = p; 12963e12c5d1SDavid du Colombier patch(p1, pc); 12973e12c5d1SDavid du Colombier gbranch(OGOTO); 12983e12c5d1SDavid du Colombier patch(p2, pc); 12993e12c5d1SDavid du Colombier goto com; 13003e12c5d1SDavid du Colombier 13013e12c5d1SDavid du Colombier case OOROR: 13023e12c5d1SDavid du Colombier if(!true) 13033e12c5d1SDavid du Colombier goto caseand; 13043e12c5d1SDavid du Colombier 13053e12c5d1SDavid du Colombier caseor: 13063e12c5d1SDavid du Colombier bcgen(l, !true); 13073e12c5d1SDavid du Colombier p1 = p; 13083e12c5d1SDavid du Colombier bcgen(r, !true); 13093e12c5d1SDavid du Colombier p2 = p; 13103e12c5d1SDavid du Colombier gbranch(OGOTO); 13113e12c5d1SDavid du Colombier patch(p1, pc); 13123e12c5d1SDavid du Colombier patch(p2, pc); 13133e12c5d1SDavid du Colombier goto com; 13143e12c5d1SDavid du Colombier 13153e12c5d1SDavid du Colombier case OEQ: 13163e12c5d1SDavid du Colombier case ONE: 13173e12c5d1SDavid du Colombier case OLE: 13183e12c5d1SDavid du Colombier case OLT: 13193e12c5d1SDavid du Colombier case OGE: 13203e12c5d1SDavid du Colombier case OGT: 13213e12c5d1SDavid du Colombier case OHI: 13223e12c5d1SDavid du Colombier case OHS: 13233e12c5d1SDavid du Colombier case OLO: 13243e12c5d1SDavid du Colombier case OLS: 13253e12c5d1SDavid du Colombier o = n->op; 1326da51d93aSDavid du Colombier if(typev[l->type->etype]) { 1327da51d93aSDavid du Colombier if(!true) 1328da51d93aSDavid du Colombier n->op = comrel[relindex(o)]; 1329da51d93aSDavid du Colombier cgen64(n, Z); 1330da51d93aSDavid du Colombier goto com; 1331da51d93aSDavid du Colombier } 13323e12c5d1SDavid du Colombier if(true) 13333e12c5d1SDavid du Colombier o = comrel[relindex(o)]; 13343e12c5d1SDavid du Colombier if(l->complex >= FNX && r->complex >= FNX) { 13353e12c5d1SDavid du Colombier regret(&nod, r); 13363e12c5d1SDavid du Colombier cgen(r, &nod); 13373e12c5d1SDavid du Colombier regsalloc(&nod1, r); 13383e12c5d1SDavid du Colombier gmove(&nod, &nod1); 13393e12c5d1SDavid du Colombier regfree(&nod); 13403e12c5d1SDavid du Colombier nod = *n; 13413e12c5d1SDavid du Colombier nod.right = &nod1; 13423e12c5d1SDavid du Colombier boolgen(&nod, true, nn); 13433e12c5d1SDavid du Colombier break; 13443e12c5d1SDavid du Colombier } 1345219b2ee8SDavid du Colombier if(typefd[l->type->etype]) { 13463e12c5d1SDavid du Colombier if(l->complex >= r->complex) { 13473e12c5d1SDavid du Colombier cgen(l, &fregnode0); 13483e12c5d1SDavid du Colombier if(r->addable < INDEXED) { 13493e12c5d1SDavid du Colombier cgen(r, &fregnode0); 13503e12c5d1SDavid du Colombier o = invrel[relindex(o)]; 13513e12c5d1SDavid du Colombier fgopcode(o, &fregnode0, &fregnode1, 1, 1); 13523e12c5d1SDavid du Colombier } else 13533e12c5d1SDavid du Colombier fgopcode(o, r, &fregnode0, 0, 1); 13543e12c5d1SDavid du Colombier } else { 13553e12c5d1SDavid du Colombier o = invrel[relindex(o)]; 13563e12c5d1SDavid du Colombier cgen(r, &fregnode0); 13573e12c5d1SDavid du Colombier if(l->addable < INDEXED) { 13583e12c5d1SDavid du Colombier cgen(l, &fregnode0); 13593e12c5d1SDavid du Colombier o = invrel[relindex(o)]; 13603e12c5d1SDavid du Colombier fgopcode(o, &fregnode0, &fregnode1, 1, 1); 13613e12c5d1SDavid du Colombier } else 13623e12c5d1SDavid du Colombier fgopcode(o, l, &fregnode0, 0, 1); 13633e12c5d1SDavid du Colombier } 13643e12c5d1SDavid du Colombier goto com; 13653e12c5d1SDavid du Colombier } 13663e12c5d1SDavid du Colombier if(l->op == OCONST) { 13673e12c5d1SDavid du Colombier o = invrel[relindex(o)]; 13683e12c5d1SDavid du Colombier /* bad, 13 is address of external that becomes constant */ 13693e12c5d1SDavid du Colombier if(r->addable < INDEXED || r->addable == 13) { 13703e12c5d1SDavid du Colombier regalloc(&nod, r, nn); 13713e12c5d1SDavid du Colombier cgen(r, &nod); 13723e12c5d1SDavid du Colombier gopcode(o, l->type, &nod, l); 13733e12c5d1SDavid du Colombier regfree(&nod); 13743e12c5d1SDavid du Colombier } else 13753e12c5d1SDavid du Colombier gopcode(o, l->type, r, l); 13763e12c5d1SDavid du Colombier goto com; 13773e12c5d1SDavid du Colombier } 13783e12c5d1SDavid du Colombier if(l->complex >= r->complex) { 13793e12c5d1SDavid du Colombier regalloc(&nod, l, nn); 13803e12c5d1SDavid du Colombier cgen(l, &nod); 13813e12c5d1SDavid du Colombier if(r->addable < INDEXED) { 13823e12c5d1SDavid du Colombier regalloc(&nod1, r, Z); 13833e12c5d1SDavid du Colombier cgen(r, &nod1); 13843e12c5d1SDavid du Colombier gopcode(o, l->type, &nod, &nod1); 13853e12c5d1SDavid du Colombier regfree(&nod1); 13863e12c5d1SDavid du Colombier } else 13873e12c5d1SDavid du Colombier gopcode(o, l->type, &nod, r); 13883e12c5d1SDavid du Colombier regfree(&nod); 13893e12c5d1SDavid du Colombier goto com; 13903e12c5d1SDavid du Colombier } 13913e12c5d1SDavid du Colombier regalloc(&nod, r, nn); 13923e12c5d1SDavid du Colombier cgen(r, &nod); 13933e12c5d1SDavid du Colombier if(l->addable < INDEXED || l->addable == 13) { 13943e12c5d1SDavid du Colombier regalloc(&nod1, l, Z); 13953e12c5d1SDavid du Colombier cgen(l, &nod1); 1396da51d93aSDavid du Colombier if(typechlp[l->type->etype]) 1397da51d93aSDavid du Colombier gopcode(o, types[TINT], &nod1, &nod); 1398da51d93aSDavid du Colombier else 13993e12c5d1SDavid du Colombier gopcode(o, l->type, &nod1, &nod); 14003e12c5d1SDavid du Colombier regfree(&nod1); 14013e12c5d1SDavid du Colombier } else 14023e12c5d1SDavid du Colombier gopcode(o, l->type, l, &nod); 14033e12c5d1SDavid du Colombier regfree(&nod); 14043e12c5d1SDavid du Colombier 14053e12c5d1SDavid du Colombier com: 14063e12c5d1SDavid du Colombier if(nn != Z) { 14073e12c5d1SDavid du Colombier p1 = p; 14083e12c5d1SDavid du Colombier gmove(nodconst(1L), nn); 14093e12c5d1SDavid du Colombier gbranch(OGOTO); 14103e12c5d1SDavid du Colombier p2 = p; 14113e12c5d1SDavid du Colombier patch(p1, pc); 14123e12c5d1SDavid du Colombier gmove(nodconst(0L), nn); 14133e12c5d1SDavid du Colombier patch(p2, pc); 14143e12c5d1SDavid du Colombier } 14153e12c5d1SDavid du Colombier break; 14163e12c5d1SDavid du Colombier } 14173e12c5d1SDavid du Colombier cursafe = curs; 14183e12c5d1SDavid du Colombier } 14193e12c5d1SDavid du Colombier 14203e12c5d1SDavid du Colombier void 14213e12c5d1SDavid du Colombier sugen(Node *n, Node *nn, long w) 14223e12c5d1SDavid du Colombier { 14233e12c5d1SDavid du Colombier Prog *p1; 1424da51d93aSDavid du Colombier Node nod0, nod1, nod2, nod3, nod4, *h, *l, *r; 14253e12c5d1SDavid du Colombier Type *t; 1426da51d93aSDavid du Colombier int c, v, x; 14273e12c5d1SDavid du Colombier 14283e12c5d1SDavid du Colombier if(n == Z || n->type == T) 14293e12c5d1SDavid du Colombier return; 14303e12c5d1SDavid du Colombier if(debug['g']) { 14313e12c5d1SDavid du Colombier prtree(nn, "sugen lhs"); 14323e12c5d1SDavid du Colombier prtree(n, "sugen"); 14333e12c5d1SDavid du Colombier } 14343e12c5d1SDavid du Colombier if(nn == nodrat) 14353e12c5d1SDavid du Colombier if(w > nrathole) 14363e12c5d1SDavid du Colombier nrathole = w; 14373e12c5d1SDavid du Colombier switch(n->op) { 14383e12c5d1SDavid du Colombier case OIND: 14393e12c5d1SDavid du Colombier if(nn == Z) { 14403e12c5d1SDavid du Colombier nullwarn(n->left, Z); 14413e12c5d1SDavid du Colombier break; 14423e12c5d1SDavid du Colombier } 14433e12c5d1SDavid du Colombier 14443e12c5d1SDavid du Colombier default: 14453e12c5d1SDavid du Colombier goto copy; 14463e12c5d1SDavid du Colombier 1447219b2ee8SDavid du Colombier case OCONST: 1448219b2ee8SDavid du Colombier if(n->type && typev[n->type->etype]) { 1449219b2ee8SDavid du Colombier if(nn == Z) { 1450219b2ee8SDavid du Colombier nullwarn(n->left, Z); 1451219b2ee8SDavid du Colombier break; 1452219b2ee8SDavid du Colombier } 1453219b2ee8SDavid du Colombier 1454da51d93aSDavid du Colombier if(nn->op == OREGPAIR) { 1455da51d93aSDavid du Colombier loadpair(n, nn); 1456da51d93aSDavid du Colombier break; 1457da51d93aSDavid du Colombier } 1458375daca8SDavid du Colombier else if(!vaddr(nn, 0)) { 1459219b2ee8SDavid du Colombier t = nn->type; 1460219b2ee8SDavid du Colombier nn->type = types[TLONG]; 1461219b2ee8SDavid du Colombier reglcgen(&nod1, nn, Z); 1462219b2ee8SDavid du Colombier nn->type = t; 1463219b2ee8SDavid du Colombier 1464375daca8SDavid du Colombier gmove(lo64(n), &nod1); 1465219b2ee8SDavid du Colombier nod1.xoffset += SZ_LONG; 1466375daca8SDavid du Colombier gmove(hi64(n), &nod1); 1467219b2ee8SDavid du Colombier regfree(&nod1); 1468da51d93aSDavid du Colombier } 1469da51d93aSDavid du Colombier else { 1470375daca8SDavid du Colombier gins(AMOVL, lo64(n), nn); 147180ee5cbfSDavid du Colombier nn->xoffset += SZ_LONG; 1472375daca8SDavid du Colombier gins(AMOVL, hi64(n), nn); 147380ee5cbfSDavid du Colombier nn->xoffset -= SZ_LONG; 147480ee5cbfSDavid du Colombier break; 147580ee5cbfSDavid du Colombier } 147680ee5cbfSDavid du Colombier break; 1477219b2ee8SDavid du Colombier } 1478219b2ee8SDavid du Colombier goto copy; 1479219b2ee8SDavid du Colombier 14803e12c5d1SDavid du Colombier case ODOT: 14813e12c5d1SDavid du Colombier l = n->left; 14823e12c5d1SDavid du Colombier sugen(l, nodrat, l->type->width); 14837dd7cddfSDavid du Colombier if(nn == Z) 14847dd7cddfSDavid du Colombier break; 14853e12c5d1SDavid du Colombier warn(n, "non-interruptable temporary"); 14863e12c5d1SDavid du Colombier nod1 = *nodrat; 14873e12c5d1SDavid du Colombier r = n->right; 14883e12c5d1SDavid du Colombier if(!r || r->op != OCONST) { 14893e12c5d1SDavid du Colombier diag(n, "DOT and no offset"); 14903e12c5d1SDavid du Colombier break; 14913e12c5d1SDavid du Colombier } 1492219b2ee8SDavid du Colombier nod1.xoffset += (long)r->vconst; 14933e12c5d1SDavid du Colombier nod1.type = n->type; 14943e12c5d1SDavid du Colombier sugen(&nod1, nn, w); 14953e12c5d1SDavid du Colombier break; 14963e12c5d1SDavid du Colombier 14973e12c5d1SDavid du Colombier case OSTRUCT: 1498219b2ee8SDavid du Colombier /* 1499219b2ee8SDavid du Colombier * rewrite so lhs has no fn call 1500219b2ee8SDavid du Colombier */ 150180ee5cbfSDavid du Colombier if(nn != Z && side(nn)) { 1502219b2ee8SDavid du Colombier nod1 = *n; 1503219b2ee8SDavid du Colombier nod1.type = typ(TIND, n->type); 1504219b2ee8SDavid du Colombier regret(&nod2, &nod1); 1505219b2ee8SDavid du Colombier lcgen(nn, &nod2); 1506219b2ee8SDavid du Colombier regsalloc(&nod0, &nod1); 1507219b2ee8SDavid du Colombier cgen(&nod2, &nod0); 1508219b2ee8SDavid du Colombier regfree(&nod2); 1509219b2ee8SDavid du Colombier 1510219b2ee8SDavid du Colombier nod1 = *n; 1511219b2ee8SDavid du Colombier nod1.op = OIND; 1512219b2ee8SDavid du Colombier nod1.left = &nod0; 1513219b2ee8SDavid du Colombier nod1.right = Z; 1514219b2ee8SDavid du Colombier nod1.complex = 1; 1515219b2ee8SDavid du Colombier 1516219b2ee8SDavid du Colombier sugen(n, &nod1, w); 1517219b2ee8SDavid du Colombier return; 1518219b2ee8SDavid du Colombier } 1519219b2ee8SDavid du Colombier 15203e12c5d1SDavid du Colombier r = n->left; 15213e12c5d1SDavid du Colombier for(t = n->type->link; t != T; t = t->down) { 15223e12c5d1SDavid du Colombier l = r; 15233e12c5d1SDavid du Colombier if(r->op == OLIST) { 15243e12c5d1SDavid du Colombier l = r->left; 15253e12c5d1SDavid du Colombier r = r->right; 15263e12c5d1SDavid du Colombier } 15273e12c5d1SDavid du Colombier if(nn == Z) { 15283e12c5d1SDavid du Colombier cgen(l, nn); 15293e12c5d1SDavid du Colombier continue; 15303e12c5d1SDavid du Colombier } 15313e12c5d1SDavid du Colombier /* 15323e12c5d1SDavid du Colombier * hand craft *(&nn + o) = l 15333e12c5d1SDavid du Colombier */ 15343e12c5d1SDavid du Colombier nod0 = znode; 15353e12c5d1SDavid du Colombier nod0.op = OAS; 15363e12c5d1SDavid du Colombier nod0.type = t; 15373e12c5d1SDavid du Colombier nod0.left = &nod1; 153880ee5cbfSDavid du Colombier nod0.right = nil; 15393e12c5d1SDavid du Colombier 15403e12c5d1SDavid du Colombier nod1 = znode; 15413e12c5d1SDavid du Colombier nod1.op = OIND; 15423e12c5d1SDavid du Colombier nod1.type = t; 15433e12c5d1SDavid du Colombier nod1.left = &nod2; 15443e12c5d1SDavid du Colombier 15453e12c5d1SDavid du Colombier nod2 = znode; 15463e12c5d1SDavid du Colombier nod2.op = OADD; 15473e12c5d1SDavid du Colombier nod2.type = typ(TIND, t); 15483e12c5d1SDavid du Colombier nod2.left = &nod3; 15493e12c5d1SDavid du Colombier nod2.right = &nod4; 15503e12c5d1SDavid du Colombier 15513e12c5d1SDavid du Colombier nod3 = znode; 15523e12c5d1SDavid du Colombier nod3.op = OADDR; 15533e12c5d1SDavid du Colombier nod3.type = nod2.type; 15543e12c5d1SDavid du Colombier nod3.left = nn; 15553e12c5d1SDavid du Colombier 15563e12c5d1SDavid du Colombier nod4 = znode; 15573e12c5d1SDavid du Colombier nod4.op = OCONST; 15583e12c5d1SDavid du Colombier nod4.type = nod2.type; 1559219b2ee8SDavid du Colombier nod4.vconst = t->offset; 15603e12c5d1SDavid du Colombier 15613e12c5d1SDavid du Colombier ccom(&nod0); 15623e12c5d1SDavid du Colombier acom(&nod0); 15633e12c5d1SDavid du Colombier xcom(&nod0); 15643e12c5d1SDavid du Colombier nod0.addable = 0; 15653e12c5d1SDavid du Colombier nod0.right = l; 15663e12c5d1SDavid du Colombier 15673e12c5d1SDavid du Colombier /* prtree(&nod0, "hand craft"); /* */ 15683e12c5d1SDavid du Colombier cgen(&nod0, Z); 15693e12c5d1SDavid du Colombier } 15703e12c5d1SDavid du Colombier break; 15713e12c5d1SDavid du Colombier 15723e12c5d1SDavid du Colombier case OAS: 15733e12c5d1SDavid du Colombier if(nn == Z) { 15743e12c5d1SDavid du Colombier if(n->addable < INDEXED) 15753e12c5d1SDavid du Colombier sugen(n->right, n->left, w); 15763e12c5d1SDavid du Colombier break; 15773e12c5d1SDavid du Colombier } 15787dd7cddfSDavid du Colombier 15793e12c5d1SDavid du Colombier sugen(n->right, nodrat, w); 15803e12c5d1SDavid du Colombier warn(n, "non-interruptable temporary"); 15813e12c5d1SDavid du Colombier sugen(nodrat, n->left, w); 15823e12c5d1SDavid du Colombier sugen(nodrat, nn, w); 15833e12c5d1SDavid du Colombier break; 15843e12c5d1SDavid du Colombier 15853e12c5d1SDavid du Colombier case OFUNC: 15863e12c5d1SDavid du Colombier if(nn == Z) { 15873e12c5d1SDavid du Colombier sugen(n, nodrat, w); 15883e12c5d1SDavid du Colombier break; 15893e12c5d1SDavid du Colombier } 1590da51d93aSDavid du Colombier h = nn; 1591da51d93aSDavid du Colombier if(nn->op == OREGPAIR) { 1592da51d93aSDavid du Colombier regsalloc(&nod1, nn); 1593da51d93aSDavid du Colombier nn = &nod1; 1594da51d93aSDavid du Colombier } 15953e12c5d1SDavid du Colombier if(nn->op != OIND) { 15963e12c5d1SDavid du Colombier nn = new1(OADDR, nn, Z); 15973e12c5d1SDavid du Colombier nn->type = types[TIND]; 15983e12c5d1SDavid du Colombier nn->addable = 0; 15993e12c5d1SDavid du Colombier } else 16003e12c5d1SDavid du Colombier nn = nn->left; 16013e12c5d1SDavid du Colombier n = new(OFUNC, n->left, new(OLIST, nn, n->right)); 16023e12c5d1SDavid du Colombier n->type = types[TVOID]; 16033e12c5d1SDavid du Colombier n->left->type = types[TVOID]; 16043e12c5d1SDavid du Colombier cgen(n, Z); 1605da51d93aSDavid du Colombier if(h->op == OREGPAIR) 1606da51d93aSDavid du Colombier loadpair(nn->left, h); 16073e12c5d1SDavid du Colombier break; 16083e12c5d1SDavid du Colombier 16093e12c5d1SDavid du Colombier case OCOND: 16103e12c5d1SDavid du Colombier bcgen(n->left, 1); 16113e12c5d1SDavid du Colombier p1 = p; 16123e12c5d1SDavid du Colombier sugen(n->right->left, nn, w); 16133e12c5d1SDavid du Colombier gbranch(OGOTO); 16143e12c5d1SDavid du Colombier patch(p1, pc); 16153e12c5d1SDavid du Colombier p1 = p; 16163e12c5d1SDavid du Colombier sugen(n->right->right, nn, w); 16173e12c5d1SDavid du Colombier patch(p1, pc); 16183e12c5d1SDavid du Colombier break; 16193e12c5d1SDavid du Colombier 16203e12c5d1SDavid du Colombier case OCOMMA: 16213e12c5d1SDavid du Colombier cgen(n->left, Z); 16223e12c5d1SDavid du Colombier sugen(n->right, nn, w); 16233e12c5d1SDavid du Colombier break; 16243e12c5d1SDavid du Colombier } 16253e12c5d1SDavid du Colombier return; 16263e12c5d1SDavid du Colombier 16273e12c5d1SDavid du Colombier copy: 1628da51d93aSDavid du Colombier if(nn == Z) { 1629da51d93aSDavid du Colombier switch(n->op) { 1630da51d93aSDavid du Colombier case OASADD: 1631da51d93aSDavid du Colombier case OASSUB: 1632da51d93aSDavid du Colombier case OASAND: 1633da51d93aSDavid du Colombier case OASOR: 1634da51d93aSDavid du Colombier case OASXOR: 1635da51d93aSDavid du Colombier 1636375daca8SDavid du Colombier case OASMUL: 1637375daca8SDavid du Colombier case OASLMUL: 1638375daca8SDavid du Colombier 1639da51d93aSDavid du Colombier case OASASHL: 1640da51d93aSDavid du Colombier case OASASHR: 1641da51d93aSDavid du Colombier case OASLSHR: 1642da51d93aSDavid du Colombier break; 1643da51d93aSDavid du Colombier 1644da51d93aSDavid du Colombier case OPOSTINC: 1645da51d93aSDavid du Colombier case OPOSTDEC: 1646da51d93aSDavid du Colombier case OPREINC: 1647da51d93aSDavid du Colombier case OPREDEC: 1648da51d93aSDavid du Colombier break; 1649da51d93aSDavid du Colombier 1650da51d93aSDavid du Colombier default: 16513e12c5d1SDavid du Colombier return; 1652da51d93aSDavid du Colombier } 1653da51d93aSDavid du Colombier } 1654da51d93aSDavid du Colombier 1655da51d93aSDavid du Colombier if(n->complex >= FNX && nn != nil && nn->complex >= FNX) { 1656219b2ee8SDavid du Colombier t = nn->type; 1657219b2ee8SDavid du Colombier nn->type = types[TLONG]; 1658219b2ee8SDavid du Colombier regialloc(&nod1, nn, Z); 1659219b2ee8SDavid du Colombier lcgen(nn, &nod1); 1660219b2ee8SDavid du Colombier regsalloc(&nod2, nn); 1661219b2ee8SDavid du Colombier nn->type = t; 1662219b2ee8SDavid du Colombier 1663219b2ee8SDavid du Colombier gins(AMOVL, &nod1, &nod2); 1664219b2ee8SDavid du Colombier regfree(&nod1); 1665219b2ee8SDavid du Colombier 1666219b2ee8SDavid du Colombier nod2.type = typ(TIND, t); 1667219b2ee8SDavid du Colombier 1668219b2ee8SDavid du Colombier nod1 = nod2; 1669219b2ee8SDavid du Colombier nod1.op = OIND; 1670219b2ee8SDavid du Colombier nod1.left = &nod2; 1671219b2ee8SDavid du Colombier nod1.right = Z; 1672219b2ee8SDavid du Colombier nod1.complex = 1; 1673219b2ee8SDavid du Colombier nod1.type = t; 1674219b2ee8SDavid du Colombier 1675219b2ee8SDavid du Colombier sugen(n, &nod1, w); 16763e12c5d1SDavid du Colombier return; 16773e12c5d1SDavid du Colombier } 16783e12c5d1SDavid du Colombier 1679da51d93aSDavid du Colombier x = 0; 1680da51d93aSDavid du Colombier v = w == 8; 1681da51d93aSDavid du Colombier if(v) { 1682da51d93aSDavid du Colombier c = cursafe; 1683375daca8SDavid du Colombier if(n->left != Z && n->left->complex >= FNX 1684375daca8SDavid du Colombier && n->right != Z && n->right->complex >= FNX) { 1685375daca8SDavid du Colombier // warn(n, "toughie"); 1686375daca8SDavid du Colombier regsalloc(&nod1, n->right); 1687375daca8SDavid du Colombier cgen(n->right, &nod1); 1688375daca8SDavid du Colombier nod2 = *n; 1689375daca8SDavid du Colombier nod2.right = &nod1; 1690375daca8SDavid du Colombier cgen(&nod2, nn); 1691375daca8SDavid du Colombier cursafe = c; 1692375daca8SDavid du Colombier return; 1693375daca8SDavid du Colombier } 1694da51d93aSDavid du Colombier if(cgen64(n, nn)) { 1695da51d93aSDavid du Colombier cursafe = c; 169680ee5cbfSDavid du Colombier return; 169780ee5cbfSDavid du Colombier } 1698da51d93aSDavid du Colombier if(n->op == OCOM) { 1699da51d93aSDavid du Colombier n = n->left; 1700da51d93aSDavid du Colombier x = 1; 1701da51d93aSDavid du Colombier } 1702da51d93aSDavid du Colombier } 170380ee5cbfSDavid du Colombier 17043e12c5d1SDavid du Colombier /* botch, need to save in .safe */ 17053e12c5d1SDavid du Colombier c = 0; 17063e12c5d1SDavid du Colombier if(n->complex > nn->complex) { 17073e12c5d1SDavid du Colombier t = n->type; 17083e12c5d1SDavid du Colombier n->type = types[TLONG]; 1709da51d93aSDavid du Colombier if(v) { 1710da51d93aSDavid du Colombier regalloc(&nod0, n, Z); 1711375daca8SDavid du Colombier if(!vaddr(n, 0)) { 1712da51d93aSDavid du Colombier reglcgen(&nod1, n, Z); 1713da51d93aSDavid du Colombier n->type = t; 1714da51d93aSDavid du Colombier n = &nod1; 1715da51d93aSDavid du Colombier } 1716da51d93aSDavid du Colombier else 1717da51d93aSDavid du Colombier n->type = t; 1718da51d93aSDavid du Colombier } 1719da51d93aSDavid du Colombier else { 17203e12c5d1SDavid du Colombier nodreg(&nod1, n, D_SI); 17213e12c5d1SDavid du Colombier if(reg[D_SI]) { 17223e12c5d1SDavid du Colombier gins(APUSHL, &nod1, Z); 17233e12c5d1SDavid du Colombier c |= 1; 17243e12c5d1SDavid du Colombier reg[D_SI]++; 17253e12c5d1SDavid du Colombier } 17263e12c5d1SDavid du Colombier lcgen(n, &nod1); 17273e12c5d1SDavid du Colombier n->type = t; 1728da51d93aSDavid du Colombier } 17293e12c5d1SDavid du Colombier 17303e12c5d1SDavid du Colombier t = nn->type; 17313e12c5d1SDavid du Colombier nn->type = types[TLONG]; 1732da51d93aSDavid du Colombier if(v) { 1733375daca8SDavid du Colombier if(!vaddr(nn, 0)) { 1734da51d93aSDavid du Colombier reglcgen(&nod2, nn, Z); 1735da51d93aSDavid du Colombier nn->type = t; 1736da51d93aSDavid du Colombier nn = &nod2; 1737da51d93aSDavid du Colombier } 1738da51d93aSDavid du Colombier else 1739da51d93aSDavid du Colombier nn->type = t; 1740da51d93aSDavid du Colombier } 1741da51d93aSDavid du Colombier else { 17423e12c5d1SDavid du Colombier nodreg(&nod2, nn, D_DI); 17433e12c5d1SDavid du Colombier if(reg[D_DI]) { 17443e12c5d1SDavid du Colombier gins(APUSHL, &nod2, Z); 17453e12c5d1SDavid du Colombier c |= 2; 17463e12c5d1SDavid du Colombier reg[D_DI]++; 17473e12c5d1SDavid du Colombier } 17483e12c5d1SDavid du Colombier lcgen(nn, &nod2); 17493e12c5d1SDavid du Colombier nn->type = t; 1750da51d93aSDavid du Colombier } 17513e12c5d1SDavid du Colombier } else { 17523e12c5d1SDavid du Colombier t = nn->type; 17533e12c5d1SDavid du Colombier nn->type = types[TLONG]; 1754da51d93aSDavid du Colombier if(v) { 1755da51d93aSDavid du Colombier regalloc(&nod0, nn, Z); 1756375daca8SDavid du Colombier if(!vaddr(nn, 0)) { 1757da51d93aSDavid du Colombier reglcgen(&nod2, nn, Z); 1758da51d93aSDavid du Colombier nn->type = t; 1759da51d93aSDavid du Colombier nn = &nod2; 1760da51d93aSDavid du Colombier } 1761da51d93aSDavid du Colombier else 1762da51d93aSDavid du Colombier nn->type = t; 1763da51d93aSDavid du Colombier } 1764da51d93aSDavid du Colombier else { 1765da51d93aSDavid du Colombier nodreg(&nod2, nn, D_DI); 17663e12c5d1SDavid du Colombier if(reg[D_DI]) { 1767da51d93aSDavid du Colombier gins(APUSHL, &nod2, Z); 1768da51d93aSDavid du Colombier c |= 2; 17693e12c5d1SDavid du Colombier reg[D_DI]++; 17703e12c5d1SDavid du Colombier } 1771da51d93aSDavid du Colombier lcgen(nn, &nod2); 17723e12c5d1SDavid du Colombier nn->type = t; 1773da51d93aSDavid du Colombier } 17743e12c5d1SDavid du Colombier 17753e12c5d1SDavid du Colombier t = n->type; 17763e12c5d1SDavid du Colombier n->type = types[TLONG]; 1777da51d93aSDavid du Colombier if(v) { 1778375daca8SDavid du Colombier if(!vaddr(n, 0)) { 1779da51d93aSDavid du Colombier reglcgen(&nod1, n, Z); 1780da51d93aSDavid du Colombier n->type = t; 1781da51d93aSDavid du Colombier n = &nod1; 1782da51d93aSDavid du Colombier } 1783da51d93aSDavid du Colombier else 1784da51d93aSDavid du Colombier n->type = t; 1785da51d93aSDavid du Colombier } 1786da51d93aSDavid du Colombier else { 1787da51d93aSDavid du Colombier nodreg(&nod1, n, D_SI); 17883e12c5d1SDavid du Colombier if(reg[D_SI]) { 1789da51d93aSDavid du Colombier gins(APUSHL, &nod1, Z); 1790da51d93aSDavid du Colombier c |= 1; 17913e12c5d1SDavid du Colombier reg[D_SI]++; 17923e12c5d1SDavid du Colombier } 1793da51d93aSDavid du Colombier lcgen(n, &nod1); 17943e12c5d1SDavid du Colombier n->type = t; 17953e12c5d1SDavid du Colombier } 1796da51d93aSDavid du Colombier } 1797da51d93aSDavid du Colombier if(v) { 1798da51d93aSDavid du Colombier gins(AMOVL, n, &nod0); 1799da51d93aSDavid du Colombier if(x) 1800da51d93aSDavid du Colombier gins(ANOTL, Z, &nod0); 1801da51d93aSDavid du Colombier gins(AMOVL, &nod0, nn); 1802da51d93aSDavid du Colombier n->xoffset += SZ_LONG; 1803da51d93aSDavid du Colombier nn->xoffset += SZ_LONG; 1804da51d93aSDavid du Colombier gins(AMOVL, n, &nod0); 1805da51d93aSDavid du Colombier if(x) 1806da51d93aSDavid du Colombier gins(ANOTL, Z, &nod0); 1807da51d93aSDavid du Colombier gins(AMOVL, &nod0, nn); 1808da51d93aSDavid du Colombier n->xoffset -= SZ_LONG; 1809da51d93aSDavid du Colombier nn->xoffset -= SZ_LONG; 1810da51d93aSDavid du Colombier if(nn == &nod2) 1811da51d93aSDavid du Colombier regfree(&nod2); 1812da51d93aSDavid du Colombier if(n == &nod1) 1813da51d93aSDavid du Colombier regfree(&nod1); 1814da51d93aSDavid du Colombier regfree(&nod0); 1815da51d93aSDavid du Colombier return; 1816da51d93aSDavid du Colombier } 18173e12c5d1SDavid du Colombier nodreg(&nod3, n, D_CX); 18183e12c5d1SDavid du Colombier if(reg[D_CX]) { 18193e12c5d1SDavid du Colombier gins(APUSHL, &nod3, Z); 18203e12c5d1SDavid du Colombier c |= 4; 18213e12c5d1SDavid du Colombier reg[D_CX]++; 18223e12c5d1SDavid du Colombier } 18233e12c5d1SDavid du Colombier gins(AMOVL, nodconst(w/SZ_LONG), &nod3); 18243e12c5d1SDavid du Colombier gins(ACLD, Z, Z); 18253e12c5d1SDavid du Colombier gins(AREP, Z, Z); 18263e12c5d1SDavid du Colombier gins(AMOVSL, Z, Z); 18273e12c5d1SDavid du Colombier if(c & 4) { 18283e12c5d1SDavid du Colombier gins(APOPL, Z, &nod3); 18293e12c5d1SDavid du Colombier reg[D_CX]--; 18303e12c5d1SDavid du Colombier } 18313e12c5d1SDavid du Colombier if(c & 2) { 18323e12c5d1SDavid du Colombier gins(APOPL, Z, &nod2); 18333e12c5d1SDavid du Colombier reg[nod2.reg]--; 18343e12c5d1SDavid du Colombier } 18353e12c5d1SDavid du Colombier if(c & 1) { 18363e12c5d1SDavid du Colombier gins(APOPL, Z, &nod1); 18373e12c5d1SDavid du Colombier reg[nod1.reg]--; 18383e12c5d1SDavid du Colombier } 18393e12c5d1SDavid du Colombier } 1840