16e84dc96SRichard Miller #include "gc.h"
26e84dc96SRichard Miller
36e84dc96SRichard Miller void
cgen(Node * n,Node * nn)46e84dc96SRichard Miller cgen(Node *n, Node *nn)
56e84dc96SRichard Miller {
66e84dc96SRichard Miller Node *l, *r;
76e84dc96SRichard Miller Prog *p1;
86e84dc96SRichard Miller Node nod, nod1, nod2, nod3, nod4;
96e84dc96SRichard Miller int o;
106e84dc96SRichard Miller long v, curs;
116e84dc96SRichard Miller
126e84dc96SRichard Miller if(debug['g']) {
136e84dc96SRichard Miller prtree(nn, "cgen lhs");
146e84dc96SRichard Miller prtree(n, "cgen");
156e84dc96SRichard Miller }
166e84dc96SRichard Miller if(n == Z || n->type == T)
176e84dc96SRichard Miller return;
186e84dc96SRichard Miller if(typecmplx[n->type->etype]) {
196e84dc96SRichard Miller sugen(n, nn, n->type->width);
206e84dc96SRichard Miller return;
216e84dc96SRichard Miller }
226e84dc96SRichard Miller l = n->left;
236e84dc96SRichard Miller r = n->right;
246e84dc96SRichard Miller o = n->op;
256e84dc96SRichard Miller if(n->addable >= INDEXED) {
266e84dc96SRichard Miller if(nn == Z) {
276e84dc96SRichard Miller switch(o) {
286e84dc96SRichard Miller default:
296e84dc96SRichard Miller nullwarn(Z, Z);
306e84dc96SRichard Miller break;
316e84dc96SRichard Miller case OINDEX:
326e84dc96SRichard Miller nullwarn(l, r);
336e84dc96SRichard Miller break;
346e84dc96SRichard Miller }
356e84dc96SRichard Miller return;
366e84dc96SRichard Miller }
376e84dc96SRichard Miller gmove(n, nn);
386e84dc96SRichard Miller return;
396e84dc96SRichard Miller }
406e84dc96SRichard Miller curs = cursafe;
416e84dc96SRichard Miller
426e84dc96SRichard Miller if(n->complex >= FNX)
436e84dc96SRichard Miller if(l->complex >= FNX)
446e84dc96SRichard Miller if(r != Z && r->complex >= FNX)
456e84dc96SRichard Miller switch(o) {
466e84dc96SRichard Miller default:
476e84dc96SRichard Miller regret(&nod, r);
486e84dc96SRichard Miller cgen(r, &nod);
496e84dc96SRichard Miller
506e84dc96SRichard Miller regsalloc(&nod1, r);
516e84dc96SRichard Miller gopcode(OAS, &nod, Z, &nod1);
526e84dc96SRichard Miller
536e84dc96SRichard Miller regfree(&nod);
546e84dc96SRichard Miller nod = *n;
556e84dc96SRichard Miller nod.right = &nod1;
566e84dc96SRichard Miller cgen(&nod, nn);
576e84dc96SRichard Miller return;
586e84dc96SRichard Miller
596e84dc96SRichard Miller case OFUNC:
606e84dc96SRichard Miller case OCOMMA:
616e84dc96SRichard Miller case OANDAND:
626e84dc96SRichard Miller case OOROR:
636e84dc96SRichard Miller case OCOND:
646e84dc96SRichard Miller case ODOT:
656e84dc96SRichard Miller break;
666e84dc96SRichard Miller }
676e84dc96SRichard Miller
686e84dc96SRichard Miller switch(o) {
696e84dc96SRichard Miller default:
706e84dc96SRichard Miller diag(n, "unknown op in cgen: %O", o);
716e84dc96SRichard Miller break;
726e84dc96SRichard Miller
736e84dc96SRichard Miller case OAS:
746e84dc96SRichard Miller if(l->op == OBIT)
756e84dc96SRichard Miller goto bitas;
766e84dc96SRichard Miller if(l->addable >= INDEXED && l->complex < FNX) {
776e84dc96SRichard Miller if(nn != Z || r->addable < INDEXED) {
786e84dc96SRichard Miller if(r->complex >= FNX && nn == Z)
796e84dc96SRichard Miller regret(&nod, r);
806e84dc96SRichard Miller else
816e84dc96SRichard Miller regalloc(&nod, r, nn);
826e84dc96SRichard Miller cgen(r, &nod);
836e84dc96SRichard Miller gmove(&nod, l);
846e84dc96SRichard Miller if(nn != Z)
856e84dc96SRichard Miller gmove(&nod, nn);
866e84dc96SRichard Miller regfree(&nod);
876e84dc96SRichard Miller } else
886e84dc96SRichard Miller gmove(r, l);
896e84dc96SRichard Miller break;
906e84dc96SRichard Miller }
916e84dc96SRichard Miller if(l->complex >= r->complex) {
926e84dc96SRichard Miller reglcgen(&nod1, l, Z);
936e84dc96SRichard Miller if(r->addable >= INDEXED) {
946e84dc96SRichard Miller gmove(r, &nod1);
956e84dc96SRichard Miller if(nn != Z)
966e84dc96SRichard Miller gmove(r, nn);
976e84dc96SRichard Miller regfree(&nod1);
986e84dc96SRichard Miller break;
996e84dc96SRichard Miller }
1006e84dc96SRichard Miller regalloc(&nod, r, nn);
1016e84dc96SRichard Miller cgen(r, &nod);
1026e84dc96SRichard Miller } else {
1036e84dc96SRichard Miller regalloc(&nod, r, nn);
1046e84dc96SRichard Miller cgen(r, &nod);
1056e84dc96SRichard Miller reglcgen(&nod1, l, Z);
1066e84dc96SRichard Miller }
1076e84dc96SRichard Miller gmove(&nod, &nod1);
1086e84dc96SRichard Miller regfree(&nod);
1096e84dc96SRichard Miller regfree(&nod1);
1106e84dc96SRichard Miller break;
1116e84dc96SRichard Miller
1126e84dc96SRichard Miller bitas:
1136e84dc96SRichard Miller n = l->left;
1146e84dc96SRichard Miller regalloc(&nod, r, nn);
1156e84dc96SRichard Miller if(l->complex >= r->complex) {
1166e84dc96SRichard Miller reglcgen(&nod1, n, Z);
1176e84dc96SRichard Miller cgen(r, &nod);
1186e84dc96SRichard Miller } else {
1196e84dc96SRichard Miller cgen(r, &nod);
1206e84dc96SRichard Miller reglcgen(&nod1, n, Z);
1216e84dc96SRichard Miller }
1226e84dc96SRichard Miller regalloc(&nod2, n, Z);
1236e84dc96SRichard Miller gopcode(OAS, &nod1, Z, &nod2);
1246e84dc96SRichard Miller bitstore(l, &nod, &nod1, &nod2, nn);
1256e84dc96SRichard Miller break;
1266e84dc96SRichard Miller
1276e84dc96SRichard Miller case OBIT:
1286e84dc96SRichard Miller if(nn == Z) {
1296e84dc96SRichard Miller nullwarn(l, Z);
1306e84dc96SRichard Miller break;
1316e84dc96SRichard Miller }
1326e84dc96SRichard Miller bitload(n, &nod, Z, Z, nn);
1336e84dc96SRichard Miller gopcode(OAS, &nod, Z, nn);
1346e84dc96SRichard Miller regfree(&nod);
1356e84dc96SRichard Miller break;
1366e84dc96SRichard Miller
1376e84dc96SRichard Miller case OADD:
1386e84dc96SRichard Miller case OSUB:
1396e84dc96SRichard Miller case OAND:
1406e84dc96SRichard Miller case OOR:
1416e84dc96SRichard Miller case OXOR:
1426e84dc96SRichard Miller case OLSHR:
1436e84dc96SRichard Miller case OASHL:
1446e84dc96SRichard Miller case OASHR:
1456e84dc96SRichard Miller /*
1466e84dc96SRichard Miller * immediate operands
1476e84dc96SRichard Miller */
1486e84dc96SRichard Miller if(nn != Z)
1496e84dc96SRichard Miller if(sconst(r))
1506e84dc96SRichard Miller if(!typefd[n->type->etype])
1516e84dc96SRichard Miller if(r->vconst >= -2048 && r->vconst < 2048) {
1526e84dc96SRichard Miller cgen(l, nn);
1536e84dc96SRichard Miller if(r->vconst == 0)
1546e84dc96SRichard Miller if(o != OAND)
1556e84dc96SRichard Miller break;
1566e84dc96SRichard Miller if(nn != Z)
1576e84dc96SRichard Miller gopcode(o, r, Z, nn);
1586e84dc96SRichard Miller break;
1596e84dc96SRichard Miller }
1606e84dc96SRichard Miller
1616e84dc96SRichard Miller case OLMUL:
1626e84dc96SRichard Miller case OLDIV:
1636e84dc96SRichard Miller case OLMOD:
1646e84dc96SRichard Miller case OMUL:
1656e84dc96SRichard Miller case ODIV:
1666e84dc96SRichard Miller case OMOD:
1676e84dc96SRichard Miller if(nn == Z) {
1686e84dc96SRichard Miller nullwarn(l, r);
1696e84dc96SRichard Miller break;
1706e84dc96SRichard Miller }
1716e84dc96SRichard Miller if(o == OMUL || o == OLMUL) {
1726e84dc96SRichard Miller if(mulcon(n, nn))
1736e84dc96SRichard Miller break;
1746e84dc96SRichard Miller }
1756e84dc96SRichard Miller if(l->complex >= r->complex) {
1766e84dc96SRichard Miller regalloc(&nod, l, nn);
1776e84dc96SRichard Miller cgen(l, &nod);
1786e84dc96SRichard Miller regalloc(&nod1, r, Z);
1796e84dc96SRichard Miller cgen(r, &nod1);
1806e84dc96SRichard Miller gopcode(o, &nod1, Z, &nod);
1816e84dc96SRichard Miller } else {
182*cc8e9823SRichard Miller if(typev[n->type->etype] &&
183*cc8e9823SRichard Miller (o == OLSHR || o == OASHL || o == OASHR)){
184*cc8e9823SRichard Miller /* vlong shifts: result has type of l, not type of r */
185*cc8e9823SRichard Miller regalloc(&nod1, r, Z);
186*cc8e9823SRichard Miller cgen(r, &nod1);
187*cc8e9823SRichard Miller regalloc(&nod, l, nn);
188*cc8e9823SRichard Miller cgen(l, &nod);
189*cc8e9823SRichard Miller gopcode(o, &nod1, Z, &nod);
190*cc8e9823SRichard Miller }else{
1916e84dc96SRichard Miller regalloc(&nod, r, nn);
1926e84dc96SRichard Miller cgen(r, &nod);
1936e84dc96SRichard Miller regalloc(&nod1, l, Z);
1946e84dc96SRichard Miller cgen(l, &nod1);
1956e84dc96SRichard Miller gopcode(o, &nod, &nod1, &nod);
1966e84dc96SRichard Miller }
197*cc8e9823SRichard Miller }
1986e84dc96SRichard Miller gopcode(OAS, &nod, Z, nn);
1996e84dc96SRichard Miller regfree(&nod);
2006e84dc96SRichard Miller regfree(&nod1);
2016e84dc96SRichard Miller break;
2026e84dc96SRichard Miller
2036e84dc96SRichard Miller case OASLSHR:
2046e84dc96SRichard Miller case OASASHL:
2056e84dc96SRichard Miller case OASASHR:
2066e84dc96SRichard Miller case OASAND:
2076e84dc96SRichard Miller case OASADD:
2086e84dc96SRichard Miller case OASSUB:
2096e84dc96SRichard Miller case OASXOR:
2106e84dc96SRichard Miller case OASOR:
2116e84dc96SRichard Miller if(l->op == OBIT)
2126e84dc96SRichard Miller goto asbitop;
2136e84dc96SRichard Miller if(sconst(r))
2146e84dc96SRichard Miller if(!typefd[n->type->etype]) {
2156e84dc96SRichard Miller if(l->addable < INDEXED)
2166e84dc96SRichard Miller reglcgen(&nod2, l, Z);
2176e84dc96SRichard Miller else
2186e84dc96SRichard Miller nod2 = *l;
2196e84dc96SRichard Miller regalloc(&nod, r, nn);
2206e84dc96SRichard Miller gopcode(OAS, &nod2, Z, &nod);
2216e84dc96SRichard Miller gopcode(o, r, Z, &nod);
2226e84dc96SRichard Miller gopcode(OAS, &nod, Z, &nod2);
2236e84dc96SRichard Miller
2246e84dc96SRichard Miller regfree(&nod);
2256e84dc96SRichard Miller if(l->addable < INDEXED)
2266e84dc96SRichard Miller regfree(&nod2);
2276e84dc96SRichard Miller break;
2286e84dc96SRichard Miller }
2296e84dc96SRichard Miller
2306e84dc96SRichard Miller case OASLMUL:
2316e84dc96SRichard Miller case OASLDIV:
2326e84dc96SRichard Miller case OASLMOD:
2336e84dc96SRichard Miller case OASMUL:
2346e84dc96SRichard Miller case OASDIV:
2356e84dc96SRichard Miller case OASMOD:
2366e84dc96SRichard Miller if(l->op == OBIT)
2376e84dc96SRichard Miller goto asbitop;
2386e84dc96SRichard Miller if(l->complex >= r->complex) {
2396e84dc96SRichard Miller if(l->addable < INDEXED)
2406e84dc96SRichard Miller reglcgen(&nod2, l, Z);
2416e84dc96SRichard Miller else
2426e84dc96SRichard Miller nod2 = *l;
2436e84dc96SRichard Miller regalloc(&nod1, r, Z);
2446e84dc96SRichard Miller cgen(r, &nod1);
2456e84dc96SRichard Miller } else {
2466e84dc96SRichard Miller regalloc(&nod1, r, Z);
2476e84dc96SRichard Miller cgen(r, &nod1);
2486e84dc96SRichard Miller if(l->addable < INDEXED)
2496e84dc96SRichard Miller reglcgen(&nod2, l, Z);
2506e84dc96SRichard Miller else
2516e84dc96SRichard Miller nod2 = *l;
2526e84dc96SRichard Miller }
2536e84dc96SRichard Miller
2546e84dc96SRichard Miller regalloc(&nod, n, nn);
2556e84dc96SRichard Miller gmove(&nod2, &nod);
2566e84dc96SRichard Miller gopcode(o, &nod1, Z, &nod);
2576e84dc96SRichard Miller gmove(&nod, &nod2);
2586e84dc96SRichard Miller if(nn != Z)
2596e84dc96SRichard Miller gopcode(OAS, &nod, Z, nn);
2606e84dc96SRichard Miller regfree(&nod);
2616e84dc96SRichard Miller regfree(&nod1);
2626e84dc96SRichard Miller if(l->addable < INDEXED)
2636e84dc96SRichard Miller regfree(&nod2);
2646e84dc96SRichard Miller break;
2656e84dc96SRichard Miller
2666e84dc96SRichard Miller asbitop:
2676e84dc96SRichard Miller regalloc(&nod4, n, nn);
2686e84dc96SRichard Miller if(l->complex >= r->complex) {
2696e84dc96SRichard Miller bitload(l, &nod, &nod1, &nod2, &nod4);
2706e84dc96SRichard Miller regalloc(&nod3, r, Z);
2716e84dc96SRichard Miller cgen(r, &nod3);
2726e84dc96SRichard Miller } else {
2736e84dc96SRichard Miller regalloc(&nod3, r, Z);
2746e84dc96SRichard Miller cgen(r, &nod3);
2756e84dc96SRichard Miller bitload(l, &nod, &nod1, &nod2, &nod4);
2766e84dc96SRichard Miller }
2776e84dc96SRichard Miller gmove(&nod, &nod4);
2786e84dc96SRichard Miller gopcode(o, &nod3, Z, &nod4);
2796e84dc96SRichard Miller regfree(&nod3);
2806e84dc96SRichard Miller gmove(&nod4, &nod);
2816e84dc96SRichard Miller regfree(&nod4);
2826e84dc96SRichard Miller bitstore(l, &nod, &nod1, &nod2, nn);
2836e84dc96SRichard Miller break;
2846e84dc96SRichard Miller
2856e84dc96SRichard Miller case OADDR:
2866e84dc96SRichard Miller if(nn == Z) {
2876e84dc96SRichard Miller nullwarn(l, Z);
2886e84dc96SRichard Miller break;
2896e84dc96SRichard Miller }
2906e84dc96SRichard Miller lcgen(l, nn);
2916e84dc96SRichard Miller break;
2926e84dc96SRichard Miller
2936e84dc96SRichard Miller case OFUNC:
2946e84dc96SRichard Miller if(l->complex >= FNX) {
2956e84dc96SRichard Miller if(l->op != OIND)
2966e84dc96SRichard Miller diag(n, "bad function call");
2976e84dc96SRichard Miller
2986e84dc96SRichard Miller regret(&nod, l->left);
2996e84dc96SRichard Miller cgen(l->left, &nod);
3006e84dc96SRichard Miller regsalloc(&nod1, l->left);
3016e84dc96SRichard Miller gopcode(OAS, &nod, Z, &nod1);
3026e84dc96SRichard Miller regfree(&nod);
3036e84dc96SRichard Miller
3046e84dc96SRichard Miller nod = *n;
3056e84dc96SRichard Miller nod.left = &nod2;
3066e84dc96SRichard Miller nod2 = *l;
3076e84dc96SRichard Miller nod2.left = &nod1;
3086e84dc96SRichard Miller nod2.complex = 1;
3096e84dc96SRichard Miller cgen(&nod, nn);
3106e84dc96SRichard Miller
3116e84dc96SRichard Miller return;
3126e84dc96SRichard Miller }
3136e84dc96SRichard Miller o = reg[REGARG];
3146e84dc96SRichard Miller gargs(r, &nod, &nod1);
3156e84dc96SRichard Miller if(l->addable < INDEXED) {
3166e84dc96SRichard Miller reglcgen(&nod, l, Z);
3176e84dc96SRichard Miller gopcode(OFUNC, Z, Z, &nod);
3186e84dc96SRichard Miller regfree(&nod);
3196e84dc96SRichard Miller } else
3206e84dc96SRichard Miller gopcode(OFUNC, Z, Z, l);
3216e84dc96SRichard Miller if(REGARG)
3226e84dc96SRichard Miller if(o != reg[REGARG])
3236e84dc96SRichard Miller reg[REGARG]--;
3246e84dc96SRichard Miller if(nn != Z) {
3256e84dc96SRichard Miller regret(&nod, n);
3266e84dc96SRichard Miller gopcode(OAS, &nod, Z, nn);
3276e84dc96SRichard Miller regfree(&nod);
3286e84dc96SRichard Miller }
3296e84dc96SRichard Miller break;
3306e84dc96SRichard Miller
3316e84dc96SRichard Miller case OIND:
3326e84dc96SRichard Miller if(nn == Z) {
3336e84dc96SRichard Miller nullwarn(l, Z);
3346e84dc96SRichard Miller break;
3356e84dc96SRichard Miller }
3366e84dc96SRichard Miller regialloc(&nod, n, nn);
3376e84dc96SRichard Miller r = l;
3386e84dc96SRichard Miller while(r->op == OADD)
3396e84dc96SRichard Miller r = r->right;
3406e84dc96SRichard Miller if(sconst(r)) {
3416e84dc96SRichard Miller v = r->vconst;
3426e84dc96SRichard Miller r->vconst = 0;
3436e84dc96SRichard Miller cgen(l, &nod);
3446e84dc96SRichard Miller nod.xoffset += v;
3456e84dc96SRichard Miller r->vconst = v;
3466e84dc96SRichard Miller } else
3476e84dc96SRichard Miller cgen(l, &nod);
3486e84dc96SRichard Miller regind(&nod, n);
3496e84dc96SRichard Miller gopcode(OAS, &nod, Z, nn);
3506e84dc96SRichard Miller regfree(&nod);
3516e84dc96SRichard Miller break;
3526e84dc96SRichard Miller
3536e84dc96SRichard Miller case OEQ:
3546e84dc96SRichard Miller case ONE:
3556e84dc96SRichard Miller case OLE:
3566e84dc96SRichard Miller case OLT:
3576e84dc96SRichard Miller case OGE:
3586e84dc96SRichard Miller case OGT:
3596e84dc96SRichard Miller case OLO:
3606e84dc96SRichard Miller case OLS:
3616e84dc96SRichard Miller case OHI:
3626e84dc96SRichard Miller case OHS:
3636e84dc96SRichard Miller if(nn == Z) {
3646e84dc96SRichard Miller nullwarn(l, r);
3656e84dc96SRichard Miller break;
3666e84dc96SRichard Miller }
3676e84dc96SRichard Miller boolgen(n, 1, nn);
3686e84dc96SRichard Miller break;
3696e84dc96SRichard Miller
3706e84dc96SRichard Miller case OANDAND:
3716e84dc96SRichard Miller case OOROR:
3726e84dc96SRichard Miller boolgen(n, 1, nn);
3736e84dc96SRichard Miller if(nn == Z)
3746e84dc96SRichard Miller patch(p, pc);
3756e84dc96SRichard Miller break;
3766e84dc96SRichard Miller
3776e84dc96SRichard Miller case ONOT:
3786e84dc96SRichard Miller if(nn == Z) {
3796e84dc96SRichard Miller nullwarn(l, Z);
3806e84dc96SRichard Miller break;
3816e84dc96SRichard Miller }
3826e84dc96SRichard Miller boolgen(n, 1, nn);
3836e84dc96SRichard Miller break;
3846e84dc96SRichard Miller
3856e84dc96SRichard Miller case OCOMMA:
3866e84dc96SRichard Miller cgen(l, Z);
3876e84dc96SRichard Miller cgen(r, nn);
3886e84dc96SRichard Miller break;
3896e84dc96SRichard Miller
3906e84dc96SRichard Miller case OCAST:
3916e84dc96SRichard Miller if(nn == Z) {
3926e84dc96SRichard Miller nullwarn(l, Z);
3936e84dc96SRichard Miller break;
3946e84dc96SRichard Miller }
3956e84dc96SRichard Miller /*
3966e84dc96SRichard Miller * convert from types l->n->nn
3976e84dc96SRichard Miller */
3986e84dc96SRichard Miller if(nocast(l->type, n->type)) {
3996e84dc96SRichard Miller if(nocast(n->type, nn->type)) {
4006e84dc96SRichard Miller cgen(l, nn);
4016e84dc96SRichard Miller break;
4026e84dc96SRichard Miller }
4036e84dc96SRichard Miller }
4046e84dc96SRichard Miller regalloc(&nod, l, nn);
4056e84dc96SRichard Miller cgen(l, &nod);
4066e84dc96SRichard Miller #ifdef maybe
4076e84dc96SRichard Miller if(l->op == ONAME || l->op == OINDREG || l->op == OIND)
4086e84dc96SRichard Miller if(typechlp[l->type->etype] && typeilp[nn->type->etype]){
4096e84dc96SRichard Miller /* load effectively does the cast */
4106e84dc96SRichard Miller nod.type = types[TLONG];
4116e84dc96SRichard Miller gopcode(OAS, &nod, Z, nn);
4126e84dc96SRichard Miller regfree(&nod);
4136e84dc96SRichard Miller break;
4146e84dc96SRichard Miller }
4156e84dc96SRichard Miller #endif
4166e84dc96SRichard Miller regalloc(&nod1, n, &nod);
4176e84dc96SRichard Miller gopcode(OAS, &nod, Z, &nod1);
4186e84dc96SRichard Miller gopcode(OAS, &nod1, Z, nn);
4196e84dc96SRichard Miller regfree(&nod1);
4206e84dc96SRichard Miller regfree(&nod);
4216e84dc96SRichard Miller break;
4226e84dc96SRichard Miller
4236e84dc96SRichard Miller case ODOT:
4246e84dc96SRichard Miller sugen(l, nodrat, l->type->width);
4256e84dc96SRichard Miller if(nn != Z) {
4266e84dc96SRichard Miller warn(n, "non-interruptable temporary");
4276e84dc96SRichard Miller nod = *nodrat;
4286e84dc96SRichard Miller if(!r || r->op != OCONST) {
4296e84dc96SRichard Miller diag(n, "DOT and no offset");
4306e84dc96SRichard Miller break;
4316e84dc96SRichard Miller }
4326e84dc96SRichard Miller nod.xoffset += (long)r->vconst;
4336e84dc96SRichard Miller nod.type = n->type;
4346e84dc96SRichard Miller cgen(&nod, nn);
4356e84dc96SRichard Miller }
4366e84dc96SRichard Miller break;
4376e84dc96SRichard Miller
4386e84dc96SRichard Miller case OCOND:
4396e84dc96SRichard Miller bcgen(l, 1);
4406e84dc96SRichard Miller p1 = p;
4416e84dc96SRichard Miller cgen(r->left, nn);
4426e84dc96SRichard Miller gbranch(OGOTO);
4436e84dc96SRichard Miller patch(p1, pc);
4446e84dc96SRichard Miller p1 = p;
4456e84dc96SRichard Miller cgen(r->right, nn);
4466e84dc96SRichard Miller patch(p1, pc);
4476e84dc96SRichard Miller break;
4486e84dc96SRichard Miller
4496e84dc96SRichard Miller case OPOSTINC:
4506e84dc96SRichard Miller case OPOSTDEC:
4516e84dc96SRichard Miller v = 1;
4526e84dc96SRichard Miller if(l->type->etype == TIND)
4536e84dc96SRichard Miller v = l->type->link->width;
4546e84dc96SRichard Miller if(o == OPOSTDEC)
4556e84dc96SRichard Miller v = -v;
4566e84dc96SRichard Miller if(l->op == OBIT)
4576e84dc96SRichard Miller goto bitinc;
4586e84dc96SRichard Miller if(nn == Z)
4596e84dc96SRichard Miller goto pre;
4606e84dc96SRichard Miller
4616e84dc96SRichard Miller if(l->addable < INDEXED)
4626e84dc96SRichard Miller reglcgen(&nod2, l, Z);
4636e84dc96SRichard Miller else
4646e84dc96SRichard Miller nod2 = *l;
4656e84dc96SRichard Miller
4666e84dc96SRichard Miller regalloc(&nod, l, nn);
4676e84dc96SRichard Miller gopcode(OAS, &nod2, Z, &nod);
4686e84dc96SRichard Miller regalloc(&nod1, l, Z);
4696e84dc96SRichard Miller if(typefd[l->type->etype]) {
4706e84dc96SRichard Miller regalloc(&nod3, l, Z);
4716e84dc96SRichard Miller if(v < 0) {
4726e84dc96SRichard Miller gopcode(OAS, nodfconst(-v), Z, &nod3);
4736e84dc96SRichard Miller gopcode(OSUB, &nod3, &nod, &nod1);
4746e84dc96SRichard Miller } else {
4756e84dc96SRichard Miller gopcode(OAS, nodfconst(v), Z, &nod3);
4766e84dc96SRichard Miller gopcode(OADD, &nod3, &nod, &nod1);
4776e84dc96SRichard Miller }
4786e84dc96SRichard Miller regfree(&nod3);
4796e84dc96SRichard Miller } else
4806e84dc96SRichard Miller gopcode(OADD, nodconst(v), &nod, &nod1);
4816e84dc96SRichard Miller gopcode(OAS, &nod1, Z, &nod2);
4826e84dc96SRichard Miller
4836e84dc96SRichard Miller regfree(&nod);
4846e84dc96SRichard Miller regfree(&nod1);
4856e84dc96SRichard Miller if(l->addable < INDEXED)
4866e84dc96SRichard Miller regfree(&nod2);
4876e84dc96SRichard Miller break;
4886e84dc96SRichard Miller
4896e84dc96SRichard Miller case OPREINC:
4906e84dc96SRichard Miller case OPREDEC:
4916e84dc96SRichard Miller v = 1;
4926e84dc96SRichard Miller if(l->type->etype == TIND)
4936e84dc96SRichard Miller v = l->type->link->width;
4946e84dc96SRichard Miller if(o == OPREDEC)
4956e84dc96SRichard Miller v = -v;
4966e84dc96SRichard Miller if(l->op == OBIT)
4976e84dc96SRichard Miller goto bitinc;
4986e84dc96SRichard Miller
4996e84dc96SRichard Miller pre:
5006e84dc96SRichard Miller if(l->addable < INDEXED)
5016e84dc96SRichard Miller reglcgen(&nod2, l, Z);
5026e84dc96SRichard Miller else
5036e84dc96SRichard Miller nod2 = *l;
5046e84dc96SRichard Miller
5056e84dc96SRichard Miller regalloc(&nod, l, nn);
5066e84dc96SRichard Miller gopcode(OAS, &nod2, Z, &nod);
5076e84dc96SRichard Miller if(typefd[l->type->etype]) {
5086e84dc96SRichard Miller regalloc(&nod3, l, Z);
5096e84dc96SRichard Miller if(v < 0) {
5106e84dc96SRichard Miller gopcode(OAS, nodfconst(-v), Z, &nod3);
5116e84dc96SRichard Miller gopcode(OSUB, &nod3, Z, &nod);
5126e84dc96SRichard Miller } else {
5136e84dc96SRichard Miller gopcode(OAS, nodfconst(v), Z, &nod3);
5146e84dc96SRichard Miller gopcode(OADD, &nod3, Z, &nod);
5156e84dc96SRichard Miller }
5166e84dc96SRichard Miller regfree(&nod3);
5176e84dc96SRichard Miller } else
5186e84dc96SRichard Miller gopcode(OADD, nodconst(v), Z, &nod);
5196e84dc96SRichard Miller gopcode(OAS, &nod, Z, &nod2);
5206e84dc96SRichard Miller if(nn && l->op == ONAME) /* in x=++i, emit USED(i) */
5216e84dc96SRichard Miller gins(ANOP, l, Z);
5226e84dc96SRichard Miller
5236e84dc96SRichard Miller regfree(&nod);
5246e84dc96SRichard Miller if(l->addable < INDEXED)
5256e84dc96SRichard Miller regfree(&nod2);
5266e84dc96SRichard Miller break;
5276e84dc96SRichard Miller
5286e84dc96SRichard Miller bitinc:
5296e84dc96SRichard Miller if(nn != Z && (o == OPOSTINC || o == OPOSTDEC)) {
5306e84dc96SRichard Miller bitload(l, &nod, &nod1, &nod2, Z);
5316e84dc96SRichard Miller gopcode(OAS, &nod, Z, nn);
5326e84dc96SRichard Miller gopcode(OADD, nodconst(v), Z, &nod);
5336e84dc96SRichard Miller bitstore(l, &nod, &nod1, &nod2, Z);
5346e84dc96SRichard Miller break;
5356e84dc96SRichard Miller }
5366e84dc96SRichard Miller bitload(l, &nod, &nod1, &nod2, nn);
5376e84dc96SRichard Miller gopcode(OADD, nodconst(v), Z, &nod);
5386e84dc96SRichard Miller bitstore(l, &nod, &nod1, &nod2, nn);
5396e84dc96SRichard Miller break;
5406e84dc96SRichard Miller }
5416e84dc96SRichard Miller cursafe = curs;
5426e84dc96SRichard Miller }
5436e84dc96SRichard Miller
5446e84dc96SRichard Miller void
reglcgen(Node * t,Node * n,Node * nn)5456e84dc96SRichard Miller reglcgen(Node *t, Node *n, Node *nn)
5466e84dc96SRichard Miller {
5476e84dc96SRichard Miller Node *r;
5486e84dc96SRichard Miller long v;
5496e84dc96SRichard Miller
5506e84dc96SRichard Miller regialloc(t, n, nn);
5516e84dc96SRichard Miller if(n->op == OIND) {
5526e84dc96SRichard Miller r = n->left;
5536e84dc96SRichard Miller while(r->op == OADD)
5546e84dc96SRichard Miller r = r->right;
5556e84dc96SRichard Miller if(sconst(r)) {
5566e84dc96SRichard Miller v = r->vconst;
5576e84dc96SRichard Miller r->vconst = 0;
5586e84dc96SRichard Miller lcgen(n, t);
5596e84dc96SRichard Miller t->xoffset += v;
5606e84dc96SRichard Miller r->vconst = v;
5616e84dc96SRichard Miller regind(t, n);
5626e84dc96SRichard Miller return;
5636e84dc96SRichard Miller }
5646e84dc96SRichard Miller }
5656e84dc96SRichard Miller lcgen(n, t);
5666e84dc96SRichard Miller regind(t, n);
5676e84dc96SRichard Miller }
5686e84dc96SRichard Miller
5696e84dc96SRichard Miller void
lcgen(Node * n,Node * nn)5706e84dc96SRichard Miller lcgen(Node *n, Node *nn)
5716e84dc96SRichard Miller {
5726e84dc96SRichard Miller Prog *p1;
5736e84dc96SRichard Miller Node nod;
5746e84dc96SRichard Miller
5756e84dc96SRichard Miller if(debug['g']) {
5766e84dc96SRichard Miller prtree(nn, "lcgen lhs");
5776e84dc96SRichard Miller prtree(n, "lcgen");
5786e84dc96SRichard Miller }
5796e84dc96SRichard Miller if(n == Z || n->type == T)
5806e84dc96SRichard Miller return;
5816e84dc96SRichard Miller if(nn == Z) {
5826e84dc96SRichard Miller nn = &nod;
5836e84dc96SRichard Miller regalloc(&nod, n, Z);
5846e84dc96SRichard Miller }
5856e84dc96SRichard Miller switch(n->op) {
5866e84dc96SRichard Miller default:
5876e84dc96SRichard Miller if(n->addable < INDEXED) {
5886e84dc96SRichard Miller diag(n, "unknown op in lcgen: %O", n->op);
5896e84dc96SRichard Miller break;
5906e84dc96SRichard Miller }
5916e84dc96SRichard Miller nod = *n;
5926e84dc96SRichard Miller nod.op = OADDR;
5936e84dc96SRichard Miller nod.left = n;
5946e84dc96SRichard Miller nod.right = Z;
5956e84dc96SRichard Miller nod.type = types[TIND];
5966e84dc96SRichard Miller gopcode(OAS, &nod, Z, nn);
5976e84dc96SRichard Miller break;
5986e84dc96SRichard Miller
5996e84dc96SRichard Miller case OCOMMA:
6006e84dc96SRichard Miller cgen(n->left, n->left);
6016e84dc96SRichard Miller lcgen(n->right, nn);
6026e84dc96SRichard Miller break;
6036e84dc96SRichard Miller
6046e84dc96SRichard Miller case OIND:
6056e84dc96SRichard Miller cgen(n->left, nn);
6066e84dc96SRichard Miller break;
6076e84dc96SRichard Miller
6086e84dc96SRichard Miller case OCOND:
6096e84dc96SRichard Miller bcgen(n->left, 1);
6106e84dc96SRichard Miller p1 = p;
6116e84dc96SRichard Miller lcgen(n->right->left, nn);
6126e84dc96SRichard Miller gbranch(OGOTO);
6136e84dc96SRichard Miller patch(p1, pc);
6146e84dc96SRichard Miller p1 = p;
6156e84dc96SRichard Miller lcgen(n->right->right, nn);
6166e84dc96SRichard Miller patch(p1, pc);
6176e84dc96SRichard Miller break;
6186e84dc96SRichard Miller }
6196e84dc96SRichard Miller }
6206e84dc96SRichard Miller
6216e84dc96SRichard Miller /*
6226e84dc96SRichard Miller * Conditional branch if bool(n) != true
6236e84dc96SRichard Miller */
6246e84dc96SRichard Miller void
bcgen(Node * n,int true)6256e84dc96SRichard Miller bcgen(Node *n, int true)
6266e84dc96SRichard Miller {
6276e84dc96SRichard Miller
6286e84dc96SRichard Miller if(n->type == T)
6296e84dc96SRichard Miller gbranch(OGOTO);
6306e84dc96SRichard Miller else
6316e84dc96SRichard Miller boolgen(n, true, Z);
6326e84dc96SRichard Miller }
6336e84dc96SRichard Miller
6346e84dc96SRichard Miller /*
6356e84dc96SRichard Miller * If nn == Z, conditional branch if bool(n) != true
6366e84dc96SRichard Miller * If nn != Z, assign n = (bool(n) == true)
6376e84dc96SRichard Miller */
6386e84dc96SRichard Miller void
boolgen(Node * n,int true,Node * nn)6396e84dc96SRichard Miller boolgen(Node *n, int true, Node *nn)
6406e84dc96SRichard Miller {
6416e84dc96SRichard Miller int o;
6426e84dc96SRichard Miller Prog *p1, *p2;
6436e84dc96SRichard Miller Node *l, *r, nod, nod1, nod2;
6446e84dc96SRichard Miller long curs;
6456e84dc96SRichard Miller
6466e84dc96SRichard Miller if(debug['g']) {
6476e84dc96SRichard Miller prtree(nn, "boolgen lhs");
6486e84dc96SRichard Miller prtree(n, true? "boolgen true" : "boolgen false");
6496e84dc96SRichard Miller }
6506e84dc96SRichard Miller curs = cursafe;
6516e84dc96SRichard Miller l = n->left;
6526e84dc96SRichard Miller r = n->right;
6536e84dc96SRichard Miller switch(n->op) {
6546e84dc96SRichard Miller
6556e84dc96SRichard Miller default:
6566e84dc96SRichard Miller regalloc(&nod, n, nn);
6576e84dc96SRichard Miller cgen(n, &nod);
6586e84dc96SRichard Miller if(nn == Z) {
6596e84dc96SRichard Miller o = true? OEQ : ONE;
6606e84dc96SRichard Miller if(typefd[n->type->etype]) {
6616e84dc96SRichard Miller nodreg(&nod1, n, NREG+FREGZERO);
6626e84dc96SRichard Miller gopcode(o, &nod, &nod1, Z);
6636e84dc96SRichard Miller } else
6646e84dc96SRichard Miller gopcode(o, &nod, Z, Z);
6656e84dc96SRichard Miller regfree(&nod);
6666e84dc96SRichard Miller break;
6676e84dc96SRichard Miller }
6686e84dc96SRichard Miller if(typefd[n->type->etype]) {
6696e84dc96SRichard Miller regalloc(&nod2, nn, nn);
6706e84dc96SRichard Miller o = true? ONE : OEQ;
6716e84dc96SRichard Miller nodreg(&nod1, n, NREG+FREGZERO);
6726e84dc96SRichard Miller gopcode(o, &nod, &nod1, &nod2);
6736e84dc96SRichard Miller gopcode(OAS, &nod2, Z, nn);
6746e84dc96SRichard Miller regfree(&nod2);
6756e84dc96SRichard Miller regfree(&nod);
6766e84dc96SRichard Miller break;
6776e84dc96SRichard Miller }
6786e84dc96SRichard Miller if(true)
6796e84dc96SRichard Miller gopcode(OCOND, &nod, nodconst(0), &nod);
6806e84dc96SRichard Miller else
6816e84dc96SRichard Miller gopcode(OCOND, nodconst(1), &nod, &nod);
6826e84dc96SRichard Miller gopcode(OAS, &nod, Z, nn);
6836e84dc96SRichard Miller regfree(&nod);
6846e84dc96SRichard Miller break;
6856e84dc96SRichard Miller
6866e84dc96SRichard Miller case OCONST:
6876e84dc96SRichard Miller o = vconst(n);
6886e84dc96SRichard Miller if(!true)
6896e84dc96SRichard Miller o = !o;
6906e84dc96SRichard Miller gbranch(OGOTO);
6916e84dc96SRichard Miller if(o) {
6926e84dc96SRichard Miller p1 = p;
6936e84dc96SRichard Miller gbranch(OGOTO);
6946e84dc96SRichard Miller patch(p1, pc);
6956e84dc96SRichard Miller }
6966e84dc96SRichard Miller goto com;
6976e84dc96SRichard Miller
6986e84dc96SRichard Miller case OCOMMA:
6996e84dc96SRichard Miller cgen(l, Z);
7006e84dc96SRichard Miller boolgen(r, true, nn);
7016e84dc96SRichard Miller break;
7026e84dc96SRichard Miller
7036e84dc96SRichard Miller case ONOT:
7046e84dc96SRichard Miller boolgen(l, !true, nn);
7056e84dc96SRichard Miller break;
7066e84dc96SRichard Miller
7076e84dc96SRichard Miller case OCOND:
7086e84dc96SRichard Miller bcgen(l, 1);
7096e84dc96SRichard Miller p1 = p;
7106e84dc96SRichard Miller bcgen(r->left, true);
7116e84dc96SRichard Miller p2 = p;
7126e84dc96SRichard Miller gbranch(OGOTO);
7136e84dc96SRichard Miller patch(p1, pc);
7146e84dc96SRichard Miller p1 = p;
7156e84dc96SRichard Miller bcgen(r->right, !true);
7166e84dc96SRichard Miller patch(p2, pc);
7176e84dc96SRichard Miller p2 = p;
7186e84dc96SRichard Miller gbranch(OGOTO);
7196e84dc96SRichard Miller patch(p1, pc);
7206e84dc96SRichard Miller patch(p2, pc);
7216e84dc96SRichard Miller goto com;
7226e84dc96SRichard Miller
7236e84dc96SRichard Miller case OANDAND:
7246e84dc96SRichard Miller if(!true)
7256e84dc96SRichard Miller goto caseor;
7266e84dc96SRichard Miller
7276e84dc96SRichard Miller caseand:
7286e84dc96SRichard Miller bcgen(l, true);
7296e84dc96SRichard Miller p1 = p;
7306e84dc96SRichard Miller bcgen(r, !true);
7316e84dc96SRichard Miller p2 = p;
7326e84dc96SRichard Miller patch(p1, pc);
7336e84dc96SRichard Miller gbranch(OGOTO);
7346e84dc96SRichard Miller patch(p2, pc);
7356e84dc96SRichard Miller goto com;
7366e84dc96SRichard Miller
7376e84dc96SRichard Miller case OOROR:
7386e84dc96SRichard Miller if(!true)
7396e84dc96SRichard Miller goto caseand;
7406e84dc96SRichard Miller
7416e84dc96SRichard Miller caseor:
7426e84dc96SRichard Miller bcgen(l, !true);
7436e84dc96SRichard Miller p1 = p;
7446e84dc96SRichard Miller bcgen(r, !true);
7456e84dc96SRichard Miller p2 = p;
7466e84dc96SRichard Miller gbranch(OGOTO);
7476e84dc96SRichard Miller patch(p1, pc);
7486e84dc96SRichard Miller patch(p2, pc);
7496e84dc96SRichard Miller goto com;
7506e84dc96SRichard Miller
7516e84dc96SRichard Miller case OEQ:
7526e84dc96SRichard Miller case ONE:
7536e84dc96SRichard Miller case OLE:
7546e84dc96SRichard Miller case OLT:
7556e84dc96SRichard Miller case OGE:
7566e84dc96SRichard Miller case OGT:
7576e84dc96SRichard Miller case OHI:
7586e84dc96SRichard Miller case OHS:
7596e84dc96SRichard Miller case OLO:
7606e84dc96SRichard Miller case OLS:
7616e84dc96SRichard Miller o = n->op;
7626e84dc96SRichard Miller if(l->complex >= FNX && r->complex >= FNX) {
7636e84dc96SRichard Miller regret(&nod, r);
7646e84dc96SRichard Miller cgen(r, &nod);
7656e84dc96SRichard Miller regsalloc(&nod1, r);
7666e84dc96SRichard Miller gopcode(OAS, &nod, Z, &nod1);
7676e84dc96SRichard Miller regfree(&nod);
7686e84dc96SRichard Miller nod = *n;
7696e84dc96SRichard Miller nod.right = &nod1;
7706e84dc96SRichard Miller boolgen(&nod, true, nn);
7716e84dc96SRichard Miller break;
7726e84dc96SRichard Miller }
7736e84dc96SRichard Miller if(true)
7746e84dc96SRichard Miller o = comrel[relindex(o)];
7756e84dc96SRichard Miller if(nn != Z || typefd[l->type->etype]) {
7766e84dc96SRichard Miller if(l->complex >= r->complex) {
7776e84dc96SRichard Miller regalloc(&nod1, l, nn);
7786e84dc96SRichard Miller cgen(l, &nod1);
7796e84dc96SRichard Miller regalloc(&nod, r, Z);
7806e84dc96SRichard Miller cgen(r, &nod);
7816e84dc96SRichard Miller } else {
7826e84dc96SRichard Miller regalloc(&nod, r, nn);
7836e84dc96SRichard Miller cgen(r, &nod);
7846e84dc96SRichard Miller regalloc(&nod1, l, Z);
7856e84dc96SRichard Miller cgen(l, &nod1);
7866e84dc96SRichard Miller }
7876e84dc96SRichard Miller if(typefd[l->type->etype]) {
7886e84dc96SRichard Miller if(nn != Z) {
7896e84dc96SRichard Miller /* fp compare for assignment */
7906e84dc96SRichard Miller regalloc(&nod2, nn, nn);
7916e84dc96SRichard Miller gopcode(o, &nod, &nod1, &nod2);
7926e84dc96SRichard Miller regfree(&nod2);
7936e84dc96SRichard Miller } else
7946e84dc96SRichard Miller /* fp compare for branch */
7956e84dc96SRichard Miller gopcode(o, &nod, &nod1, Z);
7966e84dc96SRichard Miller regfree(&nod);
7976e84dc96SRichard Miller regfree(&nod1);
7986e84dc96SRichard Miller break;
7996e84dc96SRichard Miller }
8006e84dc96SRichard Miller /* int compare for assignment */
8016e84dc96SRichard Miller switch(o) {
8026e84dc96SRichard Miller case OEQ:
8036e84dc96SRichard Miller gopcode(OSUB, &nod1, &nod, &nod);
8046e84dc96SRichard Miller gopcode(OCOND, &nod, nodconst(0), &nod);
8056e84dc96SRichard Miller break;
8066e84dc96SRichard Miller case ONE:
8076e84dc96SRichard Miller gopcode(OSUB, &nod1, &nod, &nod);
8086e84dc96SRichard Miller gopcode(OCOND, nodconst(1), &nod, &nod);
8096e84dc96SRichard Miller break;
8106e84dc96SRichard Miller case OLE:
8116e84dc96SRichard Miller gopcode(OCOMMA, &nod1, &nod, &nod);
8126e84dc96SRichard Miller break;
8136e84dc96SRichard Miller case OGT:
8146e84dc96SRichard Miller gopcode(OCOMMA, &nod1, &nod, &nod);
8156e84dc96SRichard Miller gopcode(OXOR, nodconst(1), &nod, &nod);
8166e84dc96SRichard Miller break;
8176e84dc96SRichard Miller case OLT:
8186e84dc96SRichard Miller gopcode(OCOMMA, &nod, &nod1, &nod);
8196e84dc96SRichard Miller gopcode(OXOR, nodconst(1), &nod, &nod);
8206e84dc96SRichard Miller break;
8216e84dc96SRichard Miller case OGE:
8226e84dc96SRichard Miller gopcode(OCOMMA, &nod, &nod1, &nod);
8236e84dc96SRichard Miller break;
8246e84dc96SRichard Miller case OLS:
8256e84dc96SRichard Miller gopcode(OCOND, &nod1, &nod, &nod);
8266e84dc96SRichard Miller break;
8276e84dc96SRichard Miller case OHI:
8286e84dc96SRichard Miller gopcode(OCOND, &nod1, &nod, &nod);
8296e84dc96SRichard Miller gopcode(OXOR, nodconst(1), &nod, &nod);
8306e84dc96SRichard Miller break;
8316e84dc96SRichard Miller case OLO:
8326e84dc96SRichard Miller gopcode(OCOND, &nod, &nod1, &nod);
8336e84dc96SRichard Miller gopcode(OXOR, nodconst(1), &nod, &nod);
8346e84dc96SRichard Miller break;
8356e84dc96SRichard Miller case OHS:
8366e84dc96SRichard Miller gopcode(OCOND, &nod, &nod1, &nod);
8376e84dc96SRichard Miller break;
8386e84dc96SRichard Miller }
8396e84dc96SRichard Miller gopcode(OAS, &nod, Z, nn);
8406e84dc96SRichard Miller regfree(&nod);
8416e84dc96SRichard Miller regfree(&nod1);
8426e84dc96SRichard Miller break;
8436e84dc96SRichard Miller }
8446e84dc96SRichard Miller /* int compare for branch */
8456e84dc96SRichard Miller if(0 && sconst(l)) {
8466e84dc96SRichard Miller if(l->vconst == 0) {
8476e84dc96SRichard Miller regalloc(&nod, r, nn);
8486e84dc96SRichard Miller cgen(r, &nod);
8496e84dc96SRichard Miller gopcode(o, l, &nod, Z);
8506e84dc96SRichard Miller regfree(&nod);
8516e84dc96SRichard Miller goto com;
8526e84dc96SRichard Miller }
8536e84dc96SRichard Miller }
8546e84dc96SRichard Miller if(0 && sconst(r)) {
8556e84dc96SRichard Miller if(r->vconst == 0) {
8566e84dc96SRichard Miller regalloc(&nod, l, nn);
8576e84dc96SRichard Miller cgen(l, &nod);
8586e84dc96SRichard Miller gopcode(o, &nod, r, Z);
8596e84dc96SRichard Miller regfree(&nod);
8606e84dc96SRichard Miller goto com;
8616e84dc96SRichard Miller }
8626e84dc96SRichard Miller }
8636e84dc96SRichard Miller if(l->complex >= r->complex) {
8646e84dc96SRichard Miller regalloc(&nod1, l, nn);
8656e84dc96SRichard Miller cgen(l, &nod1);
8666e84dc96SRichard Miller regalloc(&nod, r, Z);
8676e84dc96SRichard Miller cgen(r, &nod);
8686e84dc96SRichard Miller } else {
8696e84dc96SRichard Miller regalloc(&nod, r, nn);
8706e84dc96SRichard Miller cgen(r, &nod);
8716e84dc96SRichard Miller regalloc(&nod1, l, Z);
8726e84dc96SRichard Miller cgen(l, &nod1);
8736e84dc96SRichard Miller }
8746e84dc96SRichard Miller
8756e84dc96SRichard Miller gopcode(o, &nod, &nod1, Z);
8766e84dc96SRichard Miller regfree(&nod);
8776e84dc96SRichard Miller regfree(&nod1);
8786e84dc96SRichard Miller
8796e84dc96SRichard Miller com:
8806e84dc96SRichard Miller if(nn != Z) {
8816e84dc96SRichard Miller p1 = p;
8826e84dc96SRichard Miller gopcode(OAS, nodconst(1), Z, nn);
8836e84dc96SRichard Miller gbranch(OGOTO);
8846e84dc96SRichard Miller p2 = p;
8856e84dc96SRichard Miller patch(p1, pc);
8866e84dc96SRichard Miller gopcode(OAS, nodconst(0), Z, nn);
8876e84dc96SRichard Miller patch(p2, pc);
8886e84dc96SRichard Miller }
8896e84dc96SRichard Miller break;
8906e84dc96SRichard Miller }
8916e84dc96SRichard Miller cursafe = curs;
8926e84dc96SRichard Miller }
8936e84dc96SRichard Miller
8946e84dc96SRichard Miller void
sugen(Node * n,Node * nn,long w)8956e84dc96SRichard Miller sugen(Node *n, Node *nn, long w)
8966e84dc96SRichard Miller {
8976e84dc96SRichard Miller Prog *p1;
8986e84dc96SRichard Miller Node nod0, nod1, nod2, nod3, nod4, *l, *r;
8996e84dc96SRichard Miller Type *t;
9006e84dc96SRichard Miller long pc1;
9016e84dc96SRichard Miller int i, m, c;
9026e84dc96SRichard Miller
9036e84dc96SRichard Miller if(n == Z || n->type == T)
9046e84dc96SRichard Miller return;
9056e84dc96SRichard Miller if(debug['g']) {
9066e84dc96SRichard Miller prtree(nn, "sugen lhs");
9076e84dc96SRichard Miller prtree(n, "sugen");
9086e84dc96SRichard Miller }
9096e84dc96SRichard Miller if(nn == nodrat)
9106e84dc96SRichard Miller if(w > nrathole)
9116e84dc96SRichard Miller nrathole = w;
9126e84dc96SRichard Miller switch(n->op) {
9136e84dc96SRichard Miller case OIND:
9146e84dc96SRichard Miller if(nn == Z) {
9156e84dc96SRichard Miller nullwarn(n->left, Z);
9166e84dc96SRichard Miller break;
9176e84dc96SRichard Miller }
9186e84dc96SRichard Miller
9196e84dc96SRichard Miller default:
9206e84dc96SRichard Miller goto copy;
9216e84dc96SRichard Miller
9226e84dc96SRichard Miller case OCONST:
9236e84dc96SRichard Miller if(n->type && typev[n->type->etype]) {
9246e84dc96SRichard Miller if(nn == Z) {
9256e84dc96SRichard Miller nullwarn(n->left, Z);
9266e84dc96SRichard Miller break;
9276e84dc96SRichard Miller }
9286e84dc96SRichard Miller
9296e84dc96SRichard Miller t = nn->type;
9306e84dc96SRichard Miller nn->type = types[TLONG];
9316e84dc96SRichard Miller reglcgen(&nod1, nn, Z);
9326e84dc96SRichard Miller nn->type = t;
9336e84dc96SRichard Miller
9346e84dc96SRichard Miller gopcode(OAS, nod32const(n->vconst), Z, &nod1);
9356e84dc96SRichard Miller nod1.xoffset += SZ_LONG;
9366e84dc96SRichard Miller gopcode(OAS, nod32const(n->vconst>>32), Z, &nod1);
9376e84dc96SRichard Miller
9386e84dc96SRichard Miller regfree(&nod1);
9396e84dc96SRichard Miller break;
9406e84dc96SRichard Miller }
9416e84dc96SRichard Miller goto copy;
9426e84dc96SRichard Miller
9436e84dc96SRichard Miller case ODOT:
9446e84dc96SRichard Miller l = n->left;
9456e84dc96SRichard Miller sugen(l, nodrat, l->type->width);
9466e84dc96SRichard Miller if(nn != Z) {
9476e84dc96SRichard Miller warn(n, "non-interruptable temporary");
9486e84dc96SRichard Miller nod1 = *nodrat;
9496e84dc96SRichard Miller r = n->right;
9506e84dc96SRichard Miller if(!r || r->op != OCONST) {
9516e84dc96SRichard Miller diag(n, "DOT and no offset");
9526e84dc96SRichard Miller break;
9536e84dc96SRichard Miller }
9546e84dc96SRichard Miller nod1.xoffset += (long)r->vconst;
9556e84dc96SRichard Miller nod1.type = n->type;
9566e84dc96SRichard Miller sugen(&nod1, nn, w);
9576e84dc96SRichard Miller }
9586e84dc96SRichard Miller break;
9596e84dc96SRichard Miller
9606e84dc96SRichard Miller case OSTRUCT:
9616e84dc96SRichard Miller /*
9626e84dc96SRichard Miller * rewrite so lhs has no fn call
9636e84dc96SRichard Miller */
9646e84dc96SRichard Miller if(nn != Z && nn->complex >= FNX) {
9656e84dc96SRichard Miller nod1 = *n;
9666e84dc96SRichard Miller nod1.type = typ(TIND, n->type);
9676e84dc96SRichard Miller regret(&nod2, &nod1);
9686e84dc96SRichard Miller lcgen(nn, &nod2);
9696e84dc96SRichard Miller regsalloc(&nod0, &nod1);
9706e84dc96SRichard Miller gopcode(OAS, &nod2, Z, &nod0);
9716e84dc96SRichard Miller regfree(&nod2);
9726e84dc96SRichard Miller
9736e84dc96SRichard Miller nod1 = *n;
9746e84dc96SRichard Miller nod1.op = OIND;
9756e84dc96SRichard Miller nod1.left = &nod0;
9766e84dc96SRichard Miller nod1.right = Z;
9776e84dc96SRichard Miller nod1.complex = 1;
9786e84dc96SRichard Miller
9796e84dc96SRichard Miller sugen(n, &nod1, w);
9806e84dc96SRichard Miller return;
9816e84dc96SRichard Miller }
9826e84dc96SRichard Miller
9836e84dc96SRichard Miller r = n->left;
9846e84dc96SRichard Miller for(t = n->type->link; t != T; t = t->down) {
9856e84dc96SRichard Miller l = r;
9866e84dc96SRichard Miller if(r->op == OLIST) {
9876e84dc96SRichard Miller l = r->left;
9886e84dc96SRichard Miller r = r->right;
9896e84dc96SRichard Miller }
9906e84dc96SRichard Miller if(nn == Z) {
9916e84dc96SRichard Miller cgen(l, nn);
9926e84dc96SRichard Miller continue;
9936e84dc96SRichard Miller }
9946e84dc96SRichard Miller /*
9956e84dc96SRichard Miller * hand craft *(&nn + o) = l
9966e84dc96SRichard Miller */
9976e84dc96SRichard Miller nod0 = znode;
9986e84dc96SRichard Miller nod0.op = OAS;
9996e84dc96SRichard Miller nod0.type = t;
10006e84dc96SRichard Miller nod0.left = &nod1;
10016e84dc96SRichard Miller nod0.right = l;
10026e84dc96SRichard Miller
10036e84dc96SRichard Miller nod1 = znode;
10046e84dc96SRichard Miller nod1.op = OIND;
10056e84dc96SRichard Miller nod1.type = t;
10066e84dc96SRichard Miller nod1.left = &nod2;
10076e84dc96SRichard Miller
10086e84dc96SRichard Miller nod2 = znode;
10096e84dc96SRichard Miller nod2.op = OADD;
10106e84dc96SRichard Miller nod2.type = typ(TIND, t);
10116e84dc96SRichard Miller nod2.left = &nod3;
10126e84dc96SRichard Miller nod2.right = &nod4;
10136e84dc96SRichard Miller
10146e84dc96SRichard Miller nod3 = znode;
10156e84dc96SRichard Miller nod3.op = OADDR;
10166e84dc96SRichard Miller nod3.type = nod2.type;
10176e84dc96SRichard Miller nod3.left = nn;
10186e84dc96SRichard Miller
10196e84dc96SRichard Miller nod4 = znode;
10206e84dc96SRichard Miller nod4.op = OCONST;
10216e84dc96SRichard Miller nod4.type = nod2.type;
10226e84dc96SRichard Miller nod4.vconst = t->offset;
10236e84dc96SRichard Miller
10246e84dc96SRichard Miller ccom(&nod0);
10256e84dc96SRichard Miller acom(&nod0);
10266e84dc96SRichard Miller xcom(&nod0);
10276e84dc96SRichard Miller nod0.addable = 0;
10286e84dc96SRichard Miller
10296e84dc96SRichard Miller cgen(&nod0, Z);
10306e84dc96SRichard Miller }
10316e84dc96SRichard Miller break;
10326e84dc96SRichard Miller
10336e84dc96SRichard Miller case OAS:
10346e84dc96SRichard Miller if(nn == Z) {
10356e84dc96SRichard Miller if(n->addable < INDEXED)
10366e84dc96SRichard Miller sugen(n->right, n->left, w);
10376e84dc96SRichard Miller break;
10386e84dc96SRichard Miller }
10396e84dc96SRichard Miller sugen(n->right, nodrat, w);
10406e84dc96SRichard Miller warn(n, "non-interruptable temporary");
10416e84dc96SRichard Miller sugen(nodrat, n->left, w);
10426e84dc96SRichard Miller sugen(nodrat, nn, w);
10436e84dc96SRichard Miller break;
10446e84dc96SRichard Miller
10456e84dc96SRichard Miller case OFUNC:
10466e84dc96SRichard Miller if(nn == Z) {
10476e84dc96SRichard Miller sugen(n, nodrat, w);
10486e84dc96SRichard Miller break;
10496e84dc96SRichard Miller }
10506e84dc96SRichard Miller if(nn->op != OIND) {
10516e84dc96SRichard Miller nn = new1(OADDR, nn, Z);
10526e84dc96SRichard Miller nn->type = types[TIND];
10536e84dc96SRichard Miller nn->addable = 0;
10546e84dc96SRichard Miller } else
10556e84dc96SRichard Miller nn = nn->left;
10566e84dc96SRichard Miller n = new(OFUNC, n->left, new(OLIST, nn, n->right));
10576e84dc96SRichard Miller n->type = types[TVOID];
10586e84dc96SRichard Miller n->left->type = types[TVOID];
10596e84dc96SRichard Miller cgen(n, Z);
10606e84dc96SRichard Miller break;
10616e84dc96SRichard Miller
10626e84dc96SRichard Miller case OCOND:
10636e84dc96SRichard Miller bcgen(n->left, 1);
10646e84dc96SRichard Miller p1 = p;
10656e84dc96SRichard Miller sugen(n->right->left, nn, w);
10666e84dc96SRichard Miller gbranch(OGOTO);
10676e84dc96SRichard Miller patch(p1, pc);
10686e84dc96SRichard Miller p1 = p;
10696e84dc96SRichard Miller sugen(n->right->right, nn, w);
10706e84dc96SRichard Miller patch(p1, pc);
10716e84dc96SRichard Miller break;
10726e84dc96SRichard Miller
10736e84dc96SRichard Miller case OCOMMA:
10746e84dc96SRichard Miller cgen(n->left, Z);
10756e84dc96SRichard Miller sugen(n->right, nn, w);
10766e84dc96SRichard Miller break;
10776e84dc96SRichard Miller }
10786e84dc96SRichard Miller return;
10796e84dc96SRichard Miller
10806e84dc96SRichard Miller copy:
10816e84dc96SRichard Miller if(nn == Z)
10826e84dc96SRichard Miller return;
10836e84dc96SRichard Miller if(n->complex >= FNX && nn->complex >= FNX) {
10846e84dc96SRichard Miller t = nn->type;
10856e84dc96SRichard Miller nn->type = types[TLONG];
10866e84dc96SRichard Miller regialloc(&nod1, nn, Z);
10876e84dc96SRichard Miller lcgen(nn, &nod1);
10886e84dc96SRichard Miller regsalloc(&nod2, nn);
10896e84dc96SRichard Miller nn->type = t;
10906e84dc96SRichard Miller
10916e84dc96SRichard Miller gopcode(OAS, &nod1, Z, &nod2);
10926e84dc96SRichard Miller regfree(&nod1);
10936e84dc96SRichard Miller
10946e84dc96SRichard Miller nod2.type = typ(TIND, t);
10956e84dc96SRichard Miller
10966e84dc96SRichard Miller nod1 = nod2;
10976e84dc96SRichard Miller nod1.op = OIND;
10986e84dc96SRichard Miller nod1.left = &nod2;
10996e84dc96SRichard Miller nod1.right = Z;
11006e84dc96SRichard Miller nod1.complex = 1;
11016e84dc96SRichard Miller nod1.type = t;
11026e84dc96SRichard Miller
11036e84dc96SRichard Miller sugen(n, &nod1, w);
11046e84dc96SRichard Miller return;
11056e84dc96SRichard Miller }
11066e84dc96SRichard Miller
11076e84dc96SRichard Miller if(n->complex > nn->complex) {
11086e84dc96SRichard Miller t = n->type;
11096e84dc96SRichard Miller n->type = types[TLONG];
11106e84dc96SRichard Miller reglcgen(&nod1, n, Z);
11116e84dc96SRichard Miller n->type = t;
11126e84dc96SRichard Miller
11136e84dc96SRichard Miller t = nn->type;
11146e84dc96SRichard Miller nn->type = types[TLONG];
11156e84dc96SRichard Miller reglcgen(&nod2, nn, Z);
11166e84dc96SRichard Miller nn->type = t;
11176e84dc96SRichard Miller } else {
11186e84dc96SRichard Miller t = nn->type;
11196e84dc96SRichard Miller nn->type = types[TLONG];
11206e84dc96SRichard Miller reglcgen(&nod2, nn, Z);
11216e84dc96SRichard Miller nn->type = t;
11226e84dc96SRichard Miller
11236e84dc96SRichard Miller t = n->type;
11246e84dc96SRichard Miller n->type = types[TLONG];
11256e84dc96SRichard Miller reglcgen(&nod1, n, Z);
11266e84dc96SRichard Miller n->type = t;
11276e84dc96SRichard Miller }
11286e84dc96SRichard Miller
11296e84dc96SRichard Miller w /= SZ_LONG;
11306e84dc96SRichard Miller if(w <= 5) {
11316e84dc96SRichard Miller layout(&nod1, &nod2, w, 0, Z);
11326e84dc96SRichard Miller goto out;
11336e84dc96SRichard Miller }
11346e84dc96SRichard Miller
11356e84dc96SRichard Miller /*
11366e84dc96SRichard Miller * minimize space for unrolling loop
11376e84dc96SRichard Miller * 3,4,5 times. (6 or more is never minimum)
11386e84dc96SRichard Miller * if small structure, try 2 also.
11396e84dc96SRichard Miller */
11406e84dc96SRichard Miller c = 0; /* set */
11416e84dc96SRichard Miller m = 100;
11426e84dc96SRichard Miller i = 3;
11436e84dc96SRichard Miller if(w <= 15)
11446e84dc96SRichard Miller i = 2;
11456e84dc96SRichard Miller for(; i<=5; i++)
11466e84dc96SRichard Miller if(i + w%i <= m) {
11476e84dc96SRichard Miller c = i;
11486e84dc96SRichard Miller m = c + w%c;
11496e84dc96SRichard Miller }
11506e84dc96SRichard Miller
11516e84dc96SRichard Miller regalloc(&nod3, ®node, Z);
11526e84dc96SRichard Miller layout(&nod1, &nod2, w%c, w/c, &nod3);
11536e84dc96SRichard Miller
11546e84dc96SRichard Miller pc1 = pc;
11556e84dc96SRichard Miller layout(&nod1, &nod2, c, 0, Z);
11566e84dc96SRichard Miller
11576e84dc96SRichard Miller gopcode(OSUB, nodconst(1), Z, &nod3);
11586e84dc96SRichard Miller nod1.op = OREGISTER;
11596e84dc96SRichard Miller nod1.type = types[TIND];
11606e84dc96SRichard Miller gopcode(OADD, nodconst(c*SZ_LONG), Z, &nod1);
11616e84dc96SRichard Miller nod2.op = OREGISTER;
11626e84dc96SRichard Miller nod2.type = types[TIND];
11636e84dc96SRichard Miller gopcode(OADD, nodconst(c*SZ_LONG), Z, &nod2);
11646e84dc96SRichard Miller
11656e84dc96SRichard Miller gopcode(OEQ, &nod3, Z, Z);
11666e84dc96SRichard Miller p->as = ABGT;
11676e84dc96SRichard Miller patch(p, pc1);
11686e84dc96SRichard Miller
11696e84dc96SRichard Miller regfree(&nod3);
11706e84dc96SRichard Miller out:
11716e84dc96SRichard Miller regfree(&nod1);
11726e84dc96SRichard Miller regfree(&nod2);
11736e84dc96SRichard Miller }
11746e84dc96SRichard Miller
11756e84dc96SRichard Miller void
layout(Node * f,Node * t,int c,int cv,Node * cn)11766e84dc96SRichard Miller layout(Node *f, Node *t, int c, int cv, Node *cn)
11776e84dc96SRichard Miller {
11786e84dc96SRichard Miller Node t1, t2;
11796e84dc96SRichard Miller
11806e84dc96SRichard Miller while(c > 3) {
11816e84dc96SRichard Miller layout(f, t, 2, 0, Z);
11826e84dc96SRichard Miller c -= 2;
11836e84dc96SRichard Miller }
11846e84dc96SRichard Miller
11856e84dc96SRichard Miller regalloc(&t1, ®node, Z);
11866e84dc96SRichard Miller regalloc(&t2, ®node, Z);
11876e84dc96SRichard Miller t1.type = types[TLONG];
11886e84dc96SRichard Miller t2.type = types[TLONG];
11896e84dc96SRichard Miller if(c > 0) {
11906e84dc96SRichard Miller gopcode(OAS, f, Z, &t1);
11916e84dc96SRichard Miller f->xoffset += SZ_LONG;
11926e84dc96SRichard Miller }
11936e84dc96SRichard Miller if(cn != Z)
11946e84dc96SRichard Miller gopcode(OAS, nodconst(cv), Z, cn);
11956e84dc96SRichard Miller if(c > 1) {
11966e84dc96SRichard Miller gopcode(OAS, f, Z, &t2);
11976e84dc96SRichard Miller f->xoffset += SZ_LONG;
11986e84dc96SRichard Miller }
11996e84dc96SRichard Miller if(c > 0) {
12006e84dc96SRichard Miller gopcode(OAS, &t1, Z, t);
12016e84dc96SRichard Miller t->xoffset += SZ_LONG;
12026e84dc96SRichard Miller }
12036e84dc96SRichard Miller if(c > 2) {
12046e84dc96SRichard Miller gopcode(OAS, f, Z, &t1);
12056e84dc96SRichard Miller f->xoffset += SZ_LONG;
12066e84dc96SRichard Miller }
12076e84dc96SRichard Miller if(c > 1) {
12086e84dc96SRichard Miller gopcode(OAS, &t2, Z, t);
12096e84dc96SRichard Miller t->xoffset += SZ_LONG;
12106e84dc96SRichard Miller }
12116e84dc96SRichard Miller if(c > 2) {
12126e84dc96SRichard Miller gopcode(OAS, &t1, Z, t);
12136e84dc96SRichard Miller t->xoffset += SZ_LONG;
12146e84dc96SRichard Miller }
12156e84dc96SRichard Miller regfree(&t1);
12166e84dc96SRichard Miller regfree(&t2);
12176e84dc96SRichard Miller }
1218