13e12c5d1SDavid du Colombier #include "gc.h"
23e12c5d1SDavid du Colombier
3da51d93aSDavid du Colombier /* ,x/^(print|prtree)\(/i/\/\/ */
4da51d93aSDavid du Colombier
53e12c5d1SDavid du Colombier void
cgen(Node * n,Node * nn)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;
28*d40255d8SDavid du Colombier // Go's version does the following, but it's the wrong place: doesn't allow assignment
29*d40255d8SDavid du Colombier // if(o == OEXREG || nn != Z && nn->op == OEXREG) {
30*d40255d8SDavid du Colombier // gmove(n, nn);
31*d40255d8SDavid du Colombier // return;
32*d40255d8SDavid du Colombier // }
33*d40255d8SDavid du Colombier
343e12c5d1SDavid du Colombier if(n->addable >= INDEXED) {
357dd7cddfSDavid du Colombier if(nn == Z) {
367dd7cddfSDavid du Colombier switch(o) {
377dd7cddfSDavid du Colombier default:
387dd7cddfSDavid du Colombier nullwarn(Z, Z);
397dd7cddfSDavid du Colombier break;
407dd7cddfSDavid du Colombier case OINDEX:
417dd7cddfSDavid du Colombier nullwarn(l, r);
427dd7cddfSDavid du Colombier break;
437dd7cddfSDavid du Colombier }
447dd7cddfSDavid du Colombier return;
457dd7cddfSDavid du Colombier }
463e12c5d1SDavid du Colombier gmove(n, nn);
473e12c5d1SDavid du Colombier return;
483e12c5d1SDavid du Colombier }
493e12c5d1SDavid du Colombier curs = cursafe;
503e12c5d1SDavid du Colombier
513e12c5d1SDavid du Colombier if(l->complex >= FNX)
523e12c5d1SDavid du Colombier if(r != Z && r->complex >= FNX)
533e12c5d1SDavid du Colombier switch(o) {
543e12c5d1SDavid du Colombier default:
55da51d93aSDavid du Colombier if(cond(o) && typesuv[l->type->etype])
56da51d93aSDavid du Colombier break;
57da51d93aSDavid du Colombier
583e12c5d1SDavid du Colombier regret(&nod, r);
593e12c5d1SDavid du Colombier cgen(r, &nod);
603e12c5d1SDavid du Colombier
613e12c5d1SDavid du Colombier regsalloc(&nod1, r);
623e12c5d1SDavid du Colombier gmove(&nod, &nod1);
633e12c5d1SDavid du Colombier
643e12c5d1SDavid du Colombier regfree(&nod);
653e12c5d1SDavid du Colombier nod = *n;
663e12c5d1SDavid du Colombier nod.right = &nod1;
673e12c5d1SDavid du Colombier
683e12c5d1SDavid du Colombier cgen(&nod, nn);
693e12c5d1SDavid du Colombier return;
703e12c5d1SDavid du Colombier
713e12c5d1SDavid du Colombier case OFUNC:
723e12c5d1SDavid du Colombier case OCOMMA:
733e12c5d1SDavid du Colombier case OANDAND:
743e12c5d1SDavid du Colombier case OOROR:
753e12c5d1SDavid du Colombier case OCOND:
763e12c5d1SDavid du Colombier case ODOT:
773e12c5d1SDavid du Colombier break;
783e12c5d1SDavid du Colombier }
793e12c5d1SDavid du Colombier
807dd7cddfSDavid du Colombier hardleft = l->addable < INDEXED || l->complex >= FNX;
813e12c5d1SDavid du Colombier switch(o) {
823e12c5d1SDavid du Colombier default:
833e12c5d1SDavid du Colombier diag(n, "unknown op in cgen: %O", o);
843e12c5d1SDavid du Colombier break;
853e12c5d1SDavid du Colombier
86da51d93aSDavid du Colombier case ONEG:
87da51d93aSDavid du Colombier case OCOM:
88da51d93aSDavid du Colombier if(nn == Z) {
89da51d93aSDavid du Colombier nullwarn(l, Z);
90da51d93aSDavid du Colombier break;
91da51d93aSDavid du Colombier }
92da51d93aSDavid du Colombier regalloc(&nod, l, nn);
93da51d93aSDavid du Colombier cgen(l, &nod);
94da51d93aSDavid du Colombier gopcode(o, n->type, Z, &nod);
95da51d93aSDavid du Colombier gmove(&nod, nn);
96da51d93aSDavid du Colombier regfree(&nod);
97da51d93aSDavid du Colombier break;
98da51d93aSDavid du Colombier
993e12c5d1SDavid du Colombier case OAS:
100219b2ee8SDavid du Colombier if(typefd[n->type->etype]) {
1013e12c5d1SDavid du Colombier cgen(r, &fregnode0);
1023e12c5d1SDavid du Colombier if(nn != Z)
1033e12c5d1SDavid du Colombier gins(AFMOVD, &fregnode0, &fregnode0);
1043e12c5d1SDavid du Colombier if(l->addable < INDEXED) {
1053e12c5d1SDavid du Colombier reglcgen(&nod, l, Z);
1063e12c5d1SDavid du Colombier gmove(&fregnode0, &nod);
1073e12c5d1SDavid du Colombier regfree(&nod);
1083e12c5d1SDavid du Colombier } else
1093e12c5d1SDavid du Colombier gmove(&fregnode0, l);
1103e12c5d1SDavid du Colombier if(nn != Z)
1113e12c5d1SDavid du Colombier gmove(&fregnode0, nn);
1123e12c5d1SDavid du Colombier return;
1133e12c5d1SDavid du Colombier }
1143e12c5d1SDavid du Colombier if(l->op == OBIT)
1153e12c5d1SDavid du Colombier goto bitas;
1167dd7cddfSDavid du Colombier if(!hardleft) {
1173e12c5d1SDavid du Colombier if(nn != Z || r->addable < INDEXED) {
1187dd7cddfSDavid du Colombier if(r->complex >= FNX && nn == Z)
1197dd7cddfSDavid du Colombier regret(&nod, r);
1207dd7cddfSDavid du Colombier else
1213e12c5d1SDavid du Colombier regalloc(&nod, r, nn);
1223e12c5d1SDavid du Colombier cgen(r, &nod);
1233e12c5d1SDavid du Colombier gmove(&nod, l);
1247dd7cddfSDavid du Colombier if(nn != Z)
1257dd7cddfSDavid du Colombier gmove(&nod, nn);
1263e12c5d1SDavid du Colombier regfree(&nod);
1273e12c5d1SDavid du Colombier } else
1283e12c5d1SDavid du Colombier gmove(r, l);
1293e12c5d1SDavid du Colombier break;
1303e12c5d1SDavid du Colombier }
1313e12c5d1SDavid du Colombier if(l->complex >= r->complex) {
13280ee5cbfSDavid du Colombier if(l->op == OINDEX && r->op == OCONST) {
13380ee5cbfSDavid du Colombier gmove(r, l);
13480ee5cbfSDavid du Colombier break;
13580ee5cbfSDavid du Colombier }
1363e12c5d1SDavid du Colombier reglcgen(&nod1, l, Z);
1373e12c5d1SDavid du Colombier if(r->addable >= INDEXED) {
1383e12c5d1SDavid du Colombier gmove(r, &nod1);
1393e12c5d1SDavid du Colombier if(nn != Z)
1403e12c5d1SDavid du Colombier gmove(r, nn);
1413e12c5d1SDavid du Colombier regfree(&nod1);
1423e12c5d1SDavid du Colombier break;
1433e12c5d1SDavid du Colombier }
1443e12c5d1SDavid du Colombier regalloc(&nod, r, nn);
1453e12c5d1SDavid du Colombier cgen(r, &nod);
1463e12c5d1SDavid du Colombier } else {
1473e12c5d1SDavid du Colombier regalloc(&nod, r, nn);
1483e12c5d1SDavid du Colombier cgen(r, &nod);
1493e12c5d1SDavid du Colombier reglcgen(&nod1, l, Z);
1503e12c5d1SDavid du Colombier }
1513e12c5d1SDavid du Colombier gmove(&nod, &nod1);
1523e12c5d1SDavid du Colombier regfree(&nod);
1533e12c5d1SDavid du Colombier regfree(&nod1);
1543e12c5d1SDavid du Colombier break;
1553e12c5d1SDavid du Colombier
1563e12c5d1SDavid du Colombier bitas:
1573e12c5d1SDavid du Colombier n = l->left;
1583e12c5d1SDavid du Colombier regalloc(&nod, r, nn);
1593e12c5d1SDavid du Colombier if(l->complex >= r->complex) {
1603e12c5d1SDavid du Colombier reglcgen(&nod1, n, Z);
1613e12c5d1SDavid du Colombier cgen(r, &nod);
1623e12c5d1SDavid du Colombier } else {
1633e12c5d1SDavid du Colombier cgen(r, &nod);
1643e12c5d1SDavid du Colombier reglcgen(&nod1, n, Z);
1653e12c5d1SDavid du Colombier }
1663e12c5d1SDavid du Colombier regalloc(&nod2, n, Z);
1673e12c5d1SDavid du Colombier gmove(&nod1, &nod2);
1683e12c5d1SDavid du Colombier bitstore(l, &nod, &nod1, &nod2, nn);
1693e12c5d1SDavid du Colombier break;
1703e12c5d1SDavid du Colombier
1713e12c5d1SDavid du Colombier case OBIT:
1723e12c5d1SDavid du Colombier if(nn == Z) {
1733e12c5d1SDavid du Colombier nullwarn(l, Z);
1743e12c5d1SDavid du Colombier break;
1753e12c5d1SDavid du Colombier }
1763e12c5d1SDavid du Colombier bitload(n, &nod, Z, Z, nn);
1773e12c5d1SDavid du Colombier gmove(&nod, nn);
1783e12c5d1SDavid du Colombier regfree(&nod);
1793e12c5d1SDavid du Colombier break;
1803e12c5d1SDavid du Colombier
1813e12c5d1SDavid du Colombier case OLSHR:
1823e12c5d1SDavid du Colombier case OASHL:
1833e12c5d1SDavid du Colombier case OASHR:
1843e12c5d1SDavid du Colombier if(nn == Z) {
1853e12c5d1SDavid du Colombier nullwarn(l, r);
1863e12c5d1SDavid du Colombier break;
1873e12c5d1SDavid du Colombier }
1883e12c5d1SDavid du Colombier if(r->op == OCONST) {
189219b2ee8SDavid du Colombier if(r->vconst == 0) {
1903e12c5d1SDavid du Colombier cgen(l, nn);
1913e12c5d1SDavid du Colombier break;
1923e12c5d1SDavid du Colombier }
1933e12c5d1SDavid du Colombier regalloc(&nod, l, nn);
1943e12c5d1SDavid du Colombier cgen(l, &nod);
195375daca8SDavid du Colombier if(o == OASHL && r->vconst == 1)
196375daca8SDavid du Colombier gopcode(OADD, n->type, &nod, &nod);
197375daca8SDavid du Colombier else
1983e12c5d1SDavid du Colombier gopcode(o, n->type, r, &nod);
1993e12c5d1SDavid du Colombier gmove(&nod, nn);
2003e12c5d1SDavid du Colombier regfree(&nod);
2013e12c5d1SDavid du Colombier break;
2023e12c5d1SDavid du Colombier }
2033e12c5d1SDavid du Colombier
2043e12c5d1SDavid du Colombier /*
2053e12c5d1SDavid du Colombier * get nod to be D_CX
2063e12c5d1SDavid du Colombier */
2073e12c5d1SDavid du Colombier if(nodreg(&nod, nn, D_CX)) {
2083e12c5d1SDavid du Colombier regsalloc(&nod1, n);
2093e12c5d1SDavid du Colombier gmove(&nod, &nod1);
2103e12c5d1SDavid du Colombier cgen(n, &nod); /* probably a bug */
2113e12c5d1SDavid du Colombier gmove(&nod, nn);
2123e12c5d1SDavid du Colombier gmove(&nod1, &nod);
2133e12c5d1SDavid du Colombier break;
2143e12c5d1SDavid du Colombier }
2153e12c5d1SDavid du Colombier reg[D_CX]++;
2163e12c5d1SDavid du Colombier if(nn->op == OREGISTER && nn->reg == D_CX)
2173e12c5d1SDavid du Colombier regalloc(&nod1, l, Z);
2183e12c5d1SDavid du Colombier else
2193e12c5d1SDavid du Colombier regalloc(&nod1, l, nn);
2203e12c5d1SDavid du Colombier if(r->complex >= l->complex) {
2213e12c5d1SDavid du Colombier cgen(r, &nod);
2223e12c5d1SDavid du Colombier cgen(l, &nod1);
2233e12c5d1SDavid du Colombier } else {
2243e12c5d1SDavid du Colombier cgen(l, &nod1);
2253e12c5d1SDavid du Colombier cgen(r, &nod);
2263e12c5d1SDavid du Colombier }
2273e12c5d1SDavid du Colombier gopcode(o, n->type, &nod, &nod1);
2283e12c5d1SDavid du Colombier gmove(&nod1, nn);
2293e12c5d1SDavid du Colombier regfree(&nod);
2303e12c5d1SDavid du Colombier regfree(&nod1);
2313e12c5d1SDavid du Colombier break;
2323e12c5d1SDavid du Colombier
2333e12c5d1SDavid du Colombier case OADD:
2343e12c5d1SDavid du Colombier case OSUB:
2353e12c5d1SDavid du Colombier case OOR:
2363e12c5d1SDavid du Colombier case OXOR:
2373e12c5d1SDavid du Colombier case OAND:
2383e12c5d1SDavid du Colombier if(nn == Z) {
2393e12c5d1SDavid du Colombier nullwarn(l, r);
2403e12c5d1SDavid du Colombier break;
2413e12c5d1SDavid du Colombier }
242219b2ee8SDavid du Colombier if(typefd[n->type->etype])
2433e12c5d1SDavid du Colombier goto fop;
244219b2ee8SDavid du Colombier if(r->op == OCONST) {
245219b2ee8SDavid du Colombier if(r->vconst == 0 && o != OAND) {
2463e12c5d1SDavid du Colombier cgen(l, nn);
2473e12c5d1SDavid du Colombier break;
2483e12c5d1SDavid du Colombier }
249219b2ee8SDavid du Colombier }
250375daca8SDavid du Colombier if(n->op == OADD && l->op == OASHL && l->right->op == OCONST
251375daca8SDavid du Colombier && (r->op != OCONST || r->vconst < -128 || r->vconst > 127)) {
252375daca8SDavid du Colombier c = l->right->vconst;
253*d40255d8SDavid du Colombier if(c > 0 && c <= 3 && nareg(1) >= 4) {
254375daca8SDavid du Colombier if(l->left->complex >= r->complex) {
255375daca8SDavid du Colombier regalloc(&nod, l->left, nn);
256375daca8SDavid du Colombier cgen(l->left, &nod);
257375daca8SDavid du Colombier if(r->addable < INDEXED) {
258375daca8SDavid du Colombier regalloc(&nod1, r, Z);
259375daca8SDavid du Colombier cgen(r, &nod1);
260375daca8SDavid du Colombier genmuladd(&nod, &nod, 1 << c, &nod1);
261375daca8SDavid du Colombier regfree(&nod1);
262375daca8SDavid du Colombier }
263375daca8SDavid du Colombier else
264375daca8SDavid du Colombier genmuladd(&nod, &nod, 1 << c, r);
265375daca8SDavid du Colombier }
266375daca8SDavid du Colombier else {
267375daca8SDavid du Colombier regalloc(&nod, r, nn);
268375daca8SDavid du Colombier cgen(r, &nod);
269375daca8SDavid du Colombier regalloc(&nod1, l->left, Z);
270375daca8SDavid du Colombier cgen(l->left, &nod1);
271375daca8SDavid du Colombier genmuladd(&nod, &nod1, 1 << c, &nod);
272375daca8SDavid du Colombier regfree(&nod1);
273375daca8SDavid du Colombier }
274375daca8SDavid du Colombier gmove(&nod, nn);
275375daca8SDavid du Colombier regfree(&nod);
276375daca8SDavid du Colombier break;
277375daca8SDavid du Colombier }
278375daca8SDavid du Colombier }
2793e12c5d1SDavid du Colombier if(r->addable >= INDEXED) {
2803e12c5d1SDavid du Colombier regalloc(&nod, l, nn);
2813e12c5d1SDavid du Colombier cgen(l, &nod);
2823e12c5d1SDavid du Colombier gopcode(o, n->type, r, &nod);
2833e12c5d1SDavid du Colombier gmove(&nod, nn);
2843e12c5d1SDavid du Colombier regfree(&nod);
2853e12c5d1SDavid du Colombier break;
2863e12c5d1SDavid du Colombier }
2873e12c5d1SDavid du Colombier if(l->complex >= r->complex) {
2883e12c5d1SDavid du Colombier regalloc(&nod, l, nn);
2893e12c5d1SDavid du Colombier cgen(l, &nod);
2903e12c5d1SDavid du Colombier regalloc(&nod1, r, Z);
2913e12c5d1SDavid du Colombier cgen(r, &nod1);
2923e12c5d1SDavid du Colombier gopcode(o, n->type, &nod1, &nod);
2933e12c5d1SDavid du Colombier } else {
2943e12c5d1SDavid du Colombier regalloc(&nod1, r, nn);
2953e12c5d1SDavid du Colombier cgen(r, &nod1);
2963e12c5d1SDavid du Colombier regalloc(&nod, l, Z);
2973e12c5d1SDavid du Colombier cgen(l, &nod);
2983e12c5d1SDavid du Colombier gopcode(o, n->type, &nod1, &nod);
2993e12c5d1SDavid du Colombier }
3003e12c5d1SDavid du Colombier gmove(&nod, nn);
3013e12c5d1SDavid du Colombier regfree(&nod);
3023e12c5d1SDavid du Colombier regfree(&nod1);
3033e12c5d1SDavid du Colombier break;
3043e12c5d1SDavid du Colombier
3053e12c5d1SDavid du Colombier case OLMOD:
3063e12c5d1SDavid du Colombier case OMOD:
3073e12c5d1SDavid du Colombier case OLMUL:
3083e12c5d1SDavid du Colombier case OLDIV:
3093e12c5d1SDavid du Colombier case OMUL:
3103e12c5d1SDavid du Colombier case ODIV:
3113e12c5d1SDavid du Colombier if(nn == Z) {
3123e12c5d1SDavid du Colombier nullwarn(l, r);
3133e12c5d1SDavid du Colombier break;
3143e12c5d1SDavid du Colombier }
315219b2ee8SDavid du Colombier if(typefd[n->type->etype])
3163e12c5d1SDavid du Colombier goto fop;
317375daca8SDavid du Colombier if(r->op == OCONST) {
318375daca8SDavid du Colombier SET(v);
319375daca8SDavid du Colombier switch(o) {
320375daca8SDavid du Colombier case ODIV:
321375daca8SDavid du Colombier case OMOD:
322375daca8SDavid du Colombier c = r->vconst;
323375daca8SDavid du Colombier if(c < 0)
324375daca8SDavid du Colombier c = -c;
325375daca8SDavid du Colombier v = log2(c);
326375daca8SDavid du Colombier if(v < 0)
327375daca8SDavid du Colombier break;
328375daca8SDavid du Colombier /* fall thru */
329375daca8SDavid du Colombier case OMUL:
330375daca8SDavid du Colombier case OLMUL:
3319a747e4fSDavid du Colombier regalloc(&nod, l, nn);
3329a747e4fSDavid du Colombier cgen(l, &nod);
333375daca8SDavid du Colombier switch(o) {
334375daca8SDavid du Colombier case OMUL:
335375daca8SDavid du Colombier case OLMUL:
336375daca8SDavid du Colombier mulgen(n->type, r, &nod);
337375daca8SDavid du Colombier break;
338375daca8SDavid du Colombier case ODIV:
339375daca8SDavid du Colombier sdiv2(r->vconst, v, l, &nod);
340375daca8SDavid du Colombier break;
341375daca8SDavid du Colombier case OMOD:
342375daca8SDavid du Colombier smod2(r->vconst, v, l, &nod);
3439a747e4fSDavid du Colombier break;
3449a747e4fSDavid du Colombier }
345375daca8SDavid du Colombier gmove(&nod, nn);
346375daca8SDavid du Colombier regfree(&nod);
347375daca8SDavid du Colombier goto done;
348375daca8SDavid du Colombier case OLDIV:
349375daca8SDavid du Colombier c = r->vconst;
350375daca8SDavid du Colombier if((c & 0x80000000) == 0)
351375daca8SDavid du Colombier break;
352375daca8SDavid du Colombier regalloc(&nod1, l, Z);
353375daca8SDavid du Colombier cgen(l, &nod1);
354375daca8SDavid du Colombier regalloc(&nod, l, nn);
355375daca8SDavid du Colombier zeroregm(&nod);
356375daca8SDavid du Colombier gins(ACMPL, &nod1, nodconst(c));
357375daca8SDavid du Colombier gins(ASBBL, nodconst(-1), &nod);
358375daca8SDavid du Colombier regfree(&nod1);
359375daca8SDavid du Colombier gmove(&nod, nn);
360375daca8SDavid du Colombier regfree(&nod);
361375daca8SDavid du Colombier goto done;
362375daca8SDavid du Colombier }
363375daca8SDavid du Colombier }
364375daca8SDavid du Colombier
365375daca8SDavid du Colombier if(o == OMUL) {
366375daca8SDavid du Colombier if(l->addable >= INDEXED) {
367375daca8SDavid du Colombier t = l;
368375daca8SDavid du Colombier l = r;
369375daca8SDavid du Colombier r = t;
370375daca8SDavid du Colombier goto imula;
371375daca8SDavid du Colombier }
372375daca8SDavid du Colombier else if(r->addable >= INDEXED) {
373375daca8SDavid du Colombier imula:
374375daca8SDavid du Colombier /* should favour AX */
375375daca8SDavid du Colombier regalloc(&nod, l, nn);
376375daca8SDavid du Colombier cgen(l, &nod);
377375daca8SDavid du Colombier gopcode(OMUL, n->type, r, &nod);
378375daca8SDavid du Colombier }
379375daca8SDavid du Colombier else {
380375daca8SDavid du Colombier /* should favour AX */
381375daca8SDavid du Colombier regalloc(&nod, l, nn);
382375daca8SDavid du Colombier cgen(l, &nod);
383375daca8SDavid du Colombier regalloc(&nod1, r, Z);
384375daca8SDavid du Colombier cgen(r, &nod1);
385375daca8SDavid du Colombier gopcode(OMUL, n->type, &nod1, &nod);
386375daca8SDavid du Colombier regfree(&nod1);
387375daca8SDavid du Colombier }
388375daca8SDavid du Colombier gmove(&nod, nn);
389375daca8SDavid du Colombier regfree(&nod);
390375daca8SDavid du Colombier goto done;
391375daca8SDavid du Colombier }
392375daca8SDavid du Colombier
3933e12c5d1SDavid du Colombier /*
3943e12c5d1SDavid du Colombier * get nod to be D_AX
3953e12c5d1SDavid du Colombier * get nod1 to be D_DX
3963e12c5d1SDavid du Colombier */
3973e12c5d1SDavid du Colombier if(nodreg(&nod, nn, D_AX)) {
3983e12c5d1SDavid du Colombier regsalloc(&nod2, n);
3993e12c5d1SDavid du Colombier gmove(&nod, &nod2);
4003e12c5d1SDavid du Colombier v = reg[D_AX];
4013e12c5d1SDavid du Colombier reg[D_AX] = 0;
4023e12c5d1SDavid du Colombier
4033e12c5d1SDavid du Colombier if(isreg(l, D_AX)) {
4043e12c5d1SDavid du Colombier nod3 = *n;
4053e12c5d1SDavid du Colombier nod3.left = &nod2;
4063e12c5d1SDavid du Colombier cgen(&nod3, nn);
4073e12c5d1SDavid du Colombier } else
4083e12c5d1SDavid du Colombier if(isreg(r, D_AX)) {
4093e12c5d1SDavid du Colombier nod3 = *n;
4103e12c5d1SDavid du Colombier nod3.right = &nod2;
4113e12c5d1SDavid du Colombier cgen(&nod3, nn);
4123e12c5d1SDavid du Colombier } else
4133e12c5d1SDavid du Colombier cgen(n, nn);
4143e12c5d1SDavid du Colombier
4153e12c5d1SDavid du Colombier gmove(&nod2, &nod);
4163e12c5d1SDavid du Colombier reg[D_AX] = v;
4173e12c5d1SDavid du Colombier break;
4183e12c5d1SDavid du Colombier }
4193e12c5d1SDavid du Colombier if(nodreg(&nod1, nn, D_DX)) {
4203e12c5d1SDavid du Colombier regsalloc(&nod2, n);
4213e12c5d1SDavid du Colombier gmove(&nod1, &nod2);
4223e12c5d1SDavid du Colombier v = reg[D_DX];
4233e12c5d1SDavid du Colombier reg[D_DX] = 0;
4243e12c5d1SDavid du Colombier
4253e12c5d1SDavid du Colombier if(isreg(l, D_DX)) {
4263e12c5d1SDavid du Colombier nod3 = *n;
4273e12c5d1SDavid du Colombier nod3.left = &nod2;
4283e12c5d1SDavid du Colombier cgen(&nod3, nn);
4293e12c5d1SDavid du Colombier } else
4303e12c5d1SDavid du Colombier if(isreg(r, D_DX)) {
4313e12c5d1SDavid du Colombier nod3 = *n;
4323e12c5d1SDavid du Colombier nod3.right = &nod2;
4333e12c5d1SDavid du Colombier cgen(&nod3, nn);
4343e12c5d1SDavid du Colombier } else
4353e12c5d1SDavid du Colombier cgen(n, nn);
4363e12c5d1SDavid du Colombier
4373e12c5d1SDavid du Colombier gmove(&nod2, &nod1);
4383e12c5d1SDavid du Colombier reg[D_DX] = v;
4393e12c5d1SDavid du Colombier break;
4403e12c5d1SDavid du Colombier }
4413e12c5d1SDavid du Colombier reg[D_AX]++;
4423e12c5d1SDavid du Colombier
443375daca8SDavid du Colombier if(r->op == OCONST) {
444375daca8SDavid du Colombier switch(o) {
445375daca8SDavid du Colombier case ODIV:
446375daca8SDavid du Colombier reg[D_DX]++;
447375daca8SDavid du Colombier if(l->addable < INDEXED) {
448375daca8SDavid du Colombier regalloc(&nod2, l, Z);
449375daca8SDavid du Colombier cgen(l, &nod2);
450375daca8SDavid du Colombier l = &nod2;
451375daca8SDavid du Colombier }
452375daca8SDavid du Colombier sdivgen(l, r, &nod, &nod1);
453375daca8SDavid du Colombier gmove(&nod1, nn);
454375daca8SDavid du Colombier if(l == &nod2)
455375daca8SDavid du Colombier regfree(l);
456375daca8SDavid du Colombier goto freeaxdx;
457375daca8SDavid du Colombier case OLDIV:
458375daca8SDavid du Colombier reg[D_DX]++;
459375daca8SDavid du Colombier if(l->addable < INDEXED) {
460375daca8SDavid du Colombier regalloc(&nod2, l, Z);
461375daca8SDavid du Colombier cgen(l, &nod2);
462375daca8SDavid du Colombier l = &nod2;
463375daca8SDavid du Colombier }
464375daca8SDavid du Colombier udivgen(l, r, &nod, &nod1);
465375daca8SDavid du Colombier gmove(&nod1, nn);
466375daca8SDavid du Colombier if(l == &nod2)
467375daca8SDavid du Colombier regfree(l);
468375daca8SDavid du Colombier goto freeaxdx;
469375daca8SDavid du Colombier }
470375daca8SDavid du Colombier }
471375daca8SDavid du Colombier
4723e12c5d1SDavid du Colombier if(l->complex >= r->complex) {
4733e12c5d1SDavid du Colombier cgen(l, &nod);
4743e12c5d1SDavid du Colombier reg[D_DX]++;
4753e12c5d1SDavid du Colombier if(o == ODIV || o == OMOD)
4763e12c5d1SDavid du Colombier gins(ACDQ, Z, Z);
4773e12c5d1SDavid du Colombier if(o == OLDIV || o == OLMOD)
478da51d93aSDavid du Colombier zeroregm(&nod1);
4793e12c5d1SDavid du Colombier if(r->addable < INDEXED || r->op == OCONST) {
4803e12c5d1SDavid du Colombier regsalloc(&nod3, r);
4813e12c5d1SDavid du Colombier cgen(r, &nod3);
4823e12c5d1SDavid du Colombier gopcode(o, n->type, &nod3, Z);
4833e12c5d1SDavid du Colombier } else
4843e12c5d1SDavid du Colombier gopcode(o, n->type, r, Z);
4853e12c5d1SDavid du Colombier } else {
4863e12c5d1SDavid du Colombier regsalloc(&nod3, r);
4873e12c5d1SDavid du Colombier cgen(r, &nod3);
4883e12c5d1SDavid du Colombier cgen(l, &nod);
4893e12c5d1SDavid du Colombier reg[D_DX]++;
4903e12c5d1SDavid du Colombier if(o == ODIV || o == OMOD)
4913e12c5d1SDavid du Colombier gins(ACDQ, Z, Z);
4923e12c5d1SDavid du Colombier if(o == OLDIV || o == OLMOD)
493da51d93aSDavid du Colombier zeroregm(&nod1);
4943e12c5d1SDavid du Colombier gopcode(o, n->type, &nod3, Z);
4953e12c5d1SDavid du Colombier }
4963e12c5d1SDavid du Colombier if(o == OMOD || o == OLMOD)
4973e12c5d1SDavid du Colombier gmove(&nod1, nn);
4983e12c5d1SDavid du Colombier else
4993e12c5d1SDavid du Colombier gmove(&nod, nn);
500375daca8SDavid du Colombier freeaxdx:
5013e12c5d1SDavid du Colombier regfree(&nod);
5023e12c5d1SDavid du Colombier regfree(&nod1);
5033e12c5d1SDavid du Colombier break;
5043e12c5d1SDavid du Colombier
5053e12c5d1SDavid du Colombier case OASLSHR:
5063e12c5d1SDavid du Colombier case OASASHL:
5073e12c5d1SDavid du Colombier case OASASHR:
5083e12c5d1SDavid du Colombier if(r->op == OCONST)
5093e12c5d1SDavid du Colombier goto asand;
5103e12c5d1SDavid du Colombier if(l->op == OBIT)
5113e12c5d1SDavid du Colombier goto asbitop;
512219b2ee8SDavid du Colombier if(typefd[n->type->etype])
5133e12c5d1SDavid du Colombier goto asfop;
5143e12c5d1SDavid du Colombier
5153e12c5d1SDavid du Colombier /*
5163e12c5d1SDavid du Colombier * get nod to be D_CX
5173e12c5d1SDavid du Colombier */
5183e12c5d1SDavid du Colombier if(nodreg(&nod, nn, D_CX)) {
5193e12c5d1SDavid du Colombier regsalloc(&nod1, n);
5203e12c5d1SDavid du Colombier gmove(&nod, &nod1);
5213e12c5d1SDavid du Colombier cgen(n, &nod);
5223e12c5d1SDavid du Colombier if(nn != Z)
5233e12c5d1SDavid du Colombier gmove(&nod, nn);
5243e12c5d1SDavid du Colombier gmove(&nod1, &nod);
5253e12c5d1SDavid du Colombier break;
5263e12c5d1SDavid du Colombier }
5273e12c5d1SDavid du Colombier reg[D_CX]++;
5283e12c5d1SDavid du Colombier
5293e12c5d1SDavid du Colombier if(r->complex >= l->complex) {
5303e12c5d1SDavid du Colombier cgen(r, &nod);
5317dd7cddfSDavid du Colombier if(hardleft)
5323e12c5d1SDavid du Colombier reglcgen(&nod1, l, Z);
5333e12c5d1SDavid du Colombier else
5343e12c5d1SDavid du Colombier nod1 = *l;
5353e12c5d1SDavid du Colombier } else {
5367dd7cddfSDavid du Colombier if(hardleft)
5373e12c5d1SDavid du Colombier reglcgen(&nod1, l, Z);
5383e12c5d1SDavid du Colombier else
5393e12c5d1SDavid du Colombier nod1 = *l;
5403e12c5d1SDavid du Colombier cgen(r, &nod);
5413e12c5d1SDavid du Colombier }
5423e12c5d1SDavid du Colombier
5433e12c5d1SDavid du Colombier gopcode(o, l->type, &nod, &nod1);
5443e12c5d1SDavid du Colombier regfree(&nod);
5453e12c5d1SDavid du Colombier if(nn != Z)
5463e12c5d1SDavid du Colombier gmove(&nod1, nn);
5477dd7cddfSDavid du Colombier if(hardleft)
5483e12c5d1SDavid du Colombier regfree(&nod1);
5493e12c5d1SDavid du Colombier break;
5503e12c5d1SDavid du Colombier
5513e12c5d1SDavid du Colombier case OASAND:
5523e12c5d1SDavid du Colombier case OASADD:
5533e12c5d1SDavid du Colombier case OASSUB:
5543e12c5d1SDavid du Colombier case OASXOR:
5553e12c5d1SDavid du Colombier case OASOR:
5563e12c5d1SDavid du Colombier asand:
5573e12c5d1SDavid du Colombier if(l->op == OBIT)
5583e12c5d1SDavid du Colombier goto asbitop;
559fc375d71SDavid du Colombier if(typefd[n->type->etype]||typefd[r->type->etype])
5603e12c5d1SDavid du Colombier goto asfop;
5613e12c5d1SDavid du Colombier if(l->complex >= r->complex) {
5627dd7cddfSDavid du Colombier if(hardleft)
5633e12c5d1SDavid du Colombier reglcgen(&nod, l, Z);
5643e12c5d1SDavid du Colombier else
5653e12c5d1SDavid du Colombier nod = *l;
5663e12c5d1SDavid du Colombier if(r->op != OCONST) {
5673e12c5d1SDavid du Colombier regalloc(&nod1, r, nn);
5683e12c5d1SDavid du Colombier cgen(r, &nod1);
5693e12c5d1SDavid du Colombier gopcode(o, l->type, &nod1, &nod);
5703e12c5d1SDavid du Colombier regfree(&nod1);
5713e12c5d1SDavid du Colombier } else
5723e12c5d1SDavid du Colombier gopcode(o, l->type, r, &nod);
5733e12c5d1SDavid du Colombier } else {
5743e12c5d1SDavid du Colombier regalloc(&nod1, r, nn);
5753e12c5d1SDavid du Colombier cgen(r, &nod1);
5767dd7cddfSDavid du Colombier if(hardleft)
5773e12c5d1SDavid du Colombier reglcgen(&nod, l, Z);
5783e12c5d1SDavid du Colombier else
5793e12c5d1SDavid du Colombier nod = *l;
580219b2ee8SDavid du Colombier gopcode(o, l->type, &nod1, &nod);
5813e12c5d1SDavid du Colombier regfree(&nod1);
5823e12c5d1SDavid du Colombier }
5833e12c5d1SDavid du Colombier if(nn != Z)
5843e12c5d1SDavid du Colombier gmove(&nod, nn);
5857dd7cddfSDavid du Colombier if(hardleft)
5863e12c5d1SDavid du Colombier regfree(&nod);
5873e12c5d1SDavid du Colombier break;
5883e12c5d1SDavid du Colombier
5893e12c5d1SDavid du Colombier case OASLMUL:
5903e12c5d1SDavid du Colombier case OASLDIV:
5913e12c5d1SDavid du Colombier case OASLMOD:
5923e12c5d1SDavid du Colombier case OASMUL:
5933e12c5d1SDavid du Colombier case OASDIV:
5943e12c5d1SDavid du Colombier case OASMOD:
5953e12c5d1SDavid du Colombier if(l->op == OBIT)
5963e12c5d1SDavid du Colombier goto asbitop;
597fc375d71SDavid du Colombier if(typefd[n->type->etype]||typefd[r->type->etype])
5983e12c5d1SDavid du Colombier goto asfop;
599375daca8SDavid du Colombier if(r->op == OCONST) {
600375daca8SDavid du Colombier SET(v);
601375daca8SDavid du Colombier switch(o) {
602375daca8SDavid du Colombier case OASDIV:
603375daca8SDavid du Colombier case OASMOD:
604375daca8SDavid du Colombier c = r->vconst;
605375daca8SDavid du Colombier if(c < 0)
606375daca8SDavid du Colombier c = -c;
607375daca8SDavid du Colombier v = log2(c);
608375daca8SDavid du Colombier if(v < 0)
609375daca8SDavid du Colombier break;
610375daca8SDavid du Colombier /* fall thru */
611375daca8SDavid du Colombier case OASMUL:
612375daca8SDavid du Colombier case OASLMUL:
6139a747e4fSDavid du Colombier if(hardleft)
6149a747e4fSDavid du Colombier reglcgen(&nod2, l, Z);
6159a747e4fSDavid du Colombier else
6169a747e4fSDavid du Colombier nod2 = *l;
6179a747e4fSDavid du Colombier regalloc(&nod, l, nn);
6189a747e4fSDavid du Colombier cgen(&nod2, &nod);
619375daca8SDavid du Colombier switch(o) {
620375daca8SDavid du Colombier case OASMUL:
621375daca8SDavid du Colombier case OASLMUL:
622375daca8SDavid du Colombier mulgen(n->type, r, &nod);
623375daca8SDavid du Colombier break;
624375daca8SDavid du Colombier case OASDIV:
625375daca8SDavid du Colombier sdiv2(r->vconst, v, l, &nod);
626375daca8SDavid du Colombier break;
627375daca8SDavid du Colombier case OASMOD:
628375daca8SDavid du Colombier smod2(r->vconst, v, l, &nod);
629375daca8SDavid du Colombier break;
630375daca8SDavid du Colombier }
631375daca8SDavid du Colombier havev:
6329a747e4fSDavid du Colombier gmove(&nod, &nod2);
6339a747e4fSDavid du Colombier if(nn != Z)
6349a747e4fSDavid du Colombier gmove(&nod, nn);
6359a747e4fSDavid du Colombier if(hardleft)
6369a747e4fSDavid du Colombier regfree(&nod2);
6379a747e4fSDavid du Colombier regfree(&nod);
638375daca8SDavid du Colombier goto done;
639375daca8SDavid du Colombier case OASLDIV:
640375daca8SDavid du Colombier c = r->vconst;
641375daca8SDavid du Colombier if((c & 0x80000000) == 0)
6429a747e4fSDavid du Colombier break;
643375daca8SDavid du Colombier if(hardleft)
644375daca8SDavid du Colombier reglcgen(&nod2, l, Z);
645375daca8SDavid du Colombier else
646375daca8SDavid du Colombier nod2 = *l;
647375daca8SDavid du Colombier regalloc(&nod1, l, nn);
648375daca8SDavid du Colombier cgen(&nod2, &nod1);
649375daca8SDavid du Colombier regalloc(&nod, l, nn);
650375daca8SDavid du Colombier zeroregm(&nod);
651375daca8SDavid du Colombier gins(ACMPL, &nod1, nodconst(c));
652375daca8SDavid du Colombier gins(ASBBL, nodconst(-1), &nod);
653375daca8SDavid du Colombier regfree(&nod1);
654375daca8SDavid du Colombier goto havev;
6559a747e4fSDavid du Colombier }
656375daca8SDavid du Colombier }
657375daca8SDavid du Colombier
658375daca8SDavid du Colombier if(o == OASMUL) {
659375daca8SDavid du Colombier /* should favour AX */
660375daca8SDavid du Colombier regalloc(&nod, l, nn);
661375daca8SDavid du Colombier if(r->complex >= FNX) {
662375daca8SDavid du Colombier regalloc(&nod1, r, Z);
663375daca8SDavid du Colombier cgen(r, &nod1);
664375daca8SDavid du Colombier r = &nod1;
665375daca8SDavid du Colombier }
666375daca8SDavid du Colombier if(hardleft)
667375daca8SDavid du Colombier reglcgen(&nod2, l, Z);
668375daca8SDavid du Colombier else
669375daca8SDavid du Colombier nod2 = *l;
670375daca8SDavid du Colombier cgen(&nod2, &nod);
671375daca8SDavid du Colombier if(r->addable < INDEXED) {
672375daca8SDavid du Colombier if(r->complex < FNX) {
673375daca8SDavid du Colombier regalloc(&nod1, r, Z);
674375daca8SDavid du Colombier cgen(r, &nod1);
675375daca8SDavid du Colombier }
676375daca8SDavid du Colombier gopcode(OASMUL, n->type, &nod1, &nod);
677375daca8SDavid du Colombier regfree(&nod1);
678375daca8SDavid du Colombier }
679375daca8SDavid du Colombier else
680375daca8SDavid du Colombier gopcode(OASMUL, n->type, r, &nod);
681375daca8SDavid du Colombier if(r == &nod1)
682375daca8SDavid du Colombier regfree(r);
683375daca8SDavid du Colombier gmove(&nod, &nod2);
684375daca8SDavid du Colombier if(nn != Z)
685375daca8SDavid du Colombier gmove(&nod, nn);
686375daca8SDavid du Colombier regfree(&nod);
687375daca8SDavid du Colombier if(hardleft)
688375daca8SDavid du Colombier regfree(&nod2);
689375daca8SDavid du Colombier goto done;
690375daca8SDavid du Colombier }
691375daca8SDavid du Colombier
6923e12c5d1SDavid du Colombier /*
6933e12c5d1SDavid du Colombier * get nod to be D_AX
6943e12c5d1SDavid du Colombier * get nod1 to be D_DX
6953e12c5d1SDavid du Colombier */
6963e12c5d1SDavid du Colombier if(nodreg(&nod, nn, D_AX)) {
6973e12c5d1SDavid du Colombier regsalloc(&nod2, n);
6983e12c5d1SDavid du Colombier gmove(&nod, &nod2);
6993e12c5d1SDavid du Colombier v = reg[D_AX];
7003e12c5d1SDavid du Colombier reg[D_AX] = 0;
7013e12c5d1SDavid du Colombier
7023e12c5d1SDavid du Colombier if(isreg(l, D_AX)) {
7033e12c5d1SDavid du Colombier nod3 = *n;
7043e12c5d1SDavid du Colombier nod3.left = &nod2;
7053e12c5d1SDavid du Colombier cgen(&nod3, nn);
7063e12c5d1SDavid du Colombier } else
7073e12c5d1SDavid du Colombier if(isreg(r, D_AX)) {
7083e12c5d1SDavid du Colombier nod3 = *n;
7093e12c5d1SDavid du Colombier nod3.right = &nod2;
7103e12c5d1SDavid du Colombier cgen(&nod3, nn);
7113e12c5d1SDavid du Colombier } else
7123e12c5d1SDavid du Colombier cgen(n, nn);
7133e12c5d1SDavid du Colombier
7143e12c5d1SDavid du Colombier gmove(&nod2, &nod);
7153e12c5d1SDavid du Colombier reg[D_AX] = v;
7163e12c5d1SDavid du Colombier break;
7173e12c5d1SDavid du Colombier }
7183e12c5d1SDavid du Colombier if(nodreg(&nod1, nn, D_DX)) {
7193e12c5d1SDavid du Colombier regsalloc(&nod2, n);
7203e12c5d1SDavid du Colombier gmove(&nod1, &nod2);
7213e12c5d1SDavid du Colombier v = reg[D_DX];
7223e12c5d1SDavid du Colombier reg[D_DX] = 0;
7233e12c5d1SDavid du Colombier
7243e12c5d1SDavid du Colombier if(isreg(l, D_DX)) {
7253e12c5d1SDavid du Colombier nod3 = *n;
7263e12c5d1SDavid du Colombier nod3.left = &nod2;
7273e12c5d1SDavid du Colombier cgen(&nod3, nn);
7283e12c5d1SDavid du Colombier } else
7293e12c5d1SDavid du Colombier if(isreg(r, D_DX)) {
7303e12c5d1SDavid du Colombier nod3 = *n;
7313e12c5d1SDavid du Colombier nod3.right = &nod2;
7323e12c5d1SDavid du Colombier cgen(&nod3, nn);
7333e12c5d1SDavid du Colombier } else
7343e12c5d1SDavid du Colombier cgen(n, nn);
7353e12c5d1SDavid du Colombier
7363e12c5d1SDavid du Colombier gmove(&nod2, &nod1);
7373e12c5d1SDavid du Colombier reg[D_DX] = v;
7383e12c5d1SDavid du Colombier break;
7393e12c5d1SDavid du Colombier }
7403e12c5d1SDavid du Colombier reg[D_AX]++;
7413e12c5d1SDavid du Colombier reg[D_DX]++;
7423e12c5d1SDavid du Colombier
7433e12c5d1SDavid du Colombier if(l->complex >= r->complex) {
7447dd7cddfSDavid du Colombier if(hardleft)
7453e12c5d1SDavid du Colombier reglcgen(&nod2, l, Z);
7463e12c5d1SDavid du Colombier else
7473e12c5d1SDavid du Colombier nod2 = *l;
7483e12c5d1SDavid du Colombier cgen(&nod2, &nod);
749375daca8SDavid du Colombier if(r->op == OCONST) {
750375daca8SDavid du Colombier switch(o) {
751375daca8SDavid du Colombier case OASDIV:
752375daca8SDavid du Colombier sdivgen(&nod2, r, &nod, &nod1);
753375daca8SDavid du Colombier goto divdone;
754375daca8SDavid du Colombier case OASLDIV:
755375daca8SDavid du Colombier udivgen(&nod2, r, &nod, &nod1);
756375daca8SDavid du Colombier divdone:
757375daca8SDavid du Colombier gmove(&nod1, &nod2);
758375daca8SDavid du Colombier if(nn != Z)
759375daca8SDavid du Colombier gmove(&nod1, nn);
760375daca8SDavid du Colombier goto freelxaxdx;
761375daca8SDavid du Colombier }
762375daca8SDavid du Colombier }
7633e12c5d1SDavid du Colombier if(o == OASDIV || o == OASMOD)
7643e12c5d1SDavid du Colombier gins(ACDQ, Z, Z);
7653e12c5d1SDavid du Colombier if(o == OASLDIV || o == OASLMOD)
766da51d93aSDavid du Colombier zeroregm(&nod1);
7673e12c5d1SDavid du Colombier if(r->addable < INDEXED || r->op == OCONST ||
7687dd7cddfSDavid du Colombier !typeil[r->type->etype]) {
7693e12c5d1SDavid du Colombier regalloc(&nod3, r, Z);
7703e12c5d1SDavid du Colombier cgen(r, &nod3);
7713e12c5d1SDavid du Colombier gopcode(o, l->type, &nod3, Z);
7723e12c5d1SDavid du Colombier regfree(&nod3);
7733e12c5d1SDavid du Colombier } else
7743e12c5d1SDavid du Colombier gopcode(o, n->type, r, Z);
7753e12c5d1SDavid du Colombier } else {
7763e12c5d1SDavid du Colombier regalloc(&nod3, r, Z);
7773e12c5d1SDavid du Colombier cgen(r, &nod3);
7787dd7cddfSDavid du Colombier if(hardleft)
7793e12c5d1SDavid du Colombier reglcgen(&nod2, l, Z);
7803e12c5d1SDavid du Colombier else
7813e12c5d1SDavid du Colombier nod2 = *l;
7823e12c5d1SDavid du Colombier cgen(&nod2, &nod);
7833e12c5d1SDavid du Colombier if(o == OASDIV || o == OASMOD)
7843e12c5d1SDavid du Colombier gins(ACDQ, Z, Z);
7853e12c5d1SDavid du Colombier if(o == OASLDIV || o == OASLMOD)
786da51d93aSDavid du Colombier zeroregm(&nod1);
7873e12c5d1SDavid du Colombier gopcode(o, l->type, &nod3, Z);
7883e12c5d1SDavid du Colombier regfree(&nod3);
7893e12c5d1SDavid du Colombier }
7903e12c5d1SDavid du Colombier if(o == OASMOD || o == OASLMOD) {
7913e12c5d1SDavid du Colombier gmove(&nod1, &nod2);
7923e12c5d1SDavid du Colombier if(nn != Z)
7933e12c5d1SDavid du Colombier gmove(&nod1, nn);
7943e12c5d1SDavid du Colombier } else {
7953e12c5d1SDavid du Colombier gmove(&nod, &nod2);
7963e12c5d1SDavid du Colombier if(nn != Z)
7973e12c5d1SDavid du Colombier gmove(&nod, nn);
7983e12c5d1SDavid du Colombier }
799375daca8SDavid du Colombier freelxaxdx:
8007dd7cddfSDavid du Colombier if(hardleft)
8013e12c5d1SDavid du Colombier regfree(&nod2);
8023e12c5d1SDavid du Colombier regfree(&nod);
8033e12c5d1SDavid du Colombier regfree(&nod1);
8043e12c5d1SDavid du Colombier break;
8053e12c5d1SDavid du Colombier
8063e12c5d1SDavid du Colombier fop:
8073e12c5d1SDavid du Colombier if(l->complex >= r->complex) {
8083e12c5d1SDavid du Colombier cgen(l, &fregnode0);
8093e12c5d1SDavid du Colombier if(r->addable < INDEXED) {
8103e12c5d1SDavid du Colombier cgen(r, &fregnode0);
8113e12c5d1SDavid du Colombier fgopcode(o, &fregnode0, &fregnode1, 1, 0);
8123e12c5d1SDavid du Colombier } else
8133e12c5d1SDavid du Colombier fgopcode(o, r, &fregnode0, 0, 0);
8143e12c5d1SDavid du Colombier } else {
8153e12c5d1SDavid du Colombier cgen(r, &fregnode0);
8163e12c5d1SDavid du Colombier if(l->addable < INDEXED) {
8173e12c5d1SDavid du Colombier cgen(l, &fregnode0);
8183e12c5d1SDavid du Colombier fgopcode(o, &fregnode0, &fregnode1, 1, 1);
8193e12c5d1SDavid du Colombier } else
8203e12c5d1SDavid du Colombier fgopcode(o, l, &fregnode0, 0, 1);
8213e12c5d1SDavid du Colombier }
8223e12c5d1SDavid du Colombier gmove(&fregnode0, nn);
8233e12c5d1SDavid du Colombier break;
8243e12c5d1SDavid du Colombier
8253e12c5d1SDavid du Colombier asfop:
8263e12c5d1SDavid du Colombier if(l->complex >= r->complex) {
8277dd7cddfSDavid du Colombier if(hardleft)
8283e12c5d1SDavid du Colombier reglcgen(&nod, l, Z);
8293e12c5d1SDavid du Colombier else
8303e12c5d1SDavid du Colombier nod = *l;
8313e12c5d1SDavid du Colombier cgen(r, &fregnode0);
8323e12c5d1SDavid du Colombier } else {
8333e12c5d1SDavid du Colombier cgen(r, &fregnode0);
8347dd7cddfSDavid du Colombier if(hardleft)
8353e12c5d1SDavid du Colombier reglcgen(&nod, l, Z);
8363e12c5d1SDavid du Colombier else
8373e12c5d1SDavid du Colombier nod = *l;
8383e12c5d1SDavid du Colombier }
839219b2ee8SDavid du Colombier if(!typefd[l->type->etype]) {
8403e12c5d1SDavid du Colombier gmove(&nod, &fregnode0);
8413e12c5d1SDavid du Colombier fgopcode(o, &fregnode0, &fregnode1, 1, 1);
8423e12c5d1SDavid du Colombier } else
8433e12c5d1SDavid du Colombier fgopcode(o, &nod, &fregnode0, 0, 1);
8443e12c5d1SDavid du Colombier if(nn != Z)
8453e12c5d1SDavid du Colombier gins(AFMOVD, &fregnode0, &fregnode0);
8463e12c5d1SDavid du Colombier gmove(&fregnode0, &nod);
8473e12c5d1SDavid du Colombier if(nn != Z)
8483e12c5d1SDavid du Colombier gmove(&fregnode0, nn);
8497dd7cddfSDavid du Colombier if(hardleft)
8503e12c5d1SDavid du Colombier regfree(&nod);
8513e12c5d1SDavid du Colombier break;
8523e12c5d1SDavid du Colombier
8533e12c5d1SDavid du Colombier asbitop:
8543e12c5d1SDavid du Colombier regalloc(&nod4, n, nn);
8553e12c5d1SDavid du Colombier if(l->complex >= r->complex) {
8563e12c5d1SDavid du Colombier bitload(l, &nod, &nod1, &nod2, &nod4);
8573e12c5d1SDavid du Colombier regalloc(&nod3, r, Z);
8583e12c5d1SDavid du Colombier cgen(r, &nod3);
8593e12c5d1SDavid du Colombier } else {
8603e12c5d1SDavid du Colombier regalloc(&nod3, r, Z);
8613e12c5d1SDavid du Colombier cgen(r, &nod3);
8623e12c5d1SDavid du Colombier bitload(l, &nod, &nod1, &nod2, &nod4);
8633e12c5d1SDavid du Colombier }
8643e12c5d1SDavid du Colombier gmove(&nod, &nod4);
8653e12c5d1SDavid du Colombier
866219b2ee8SDavid du Colombier if(typefd[nod3.type->etype])
8673e12c5d1SDavid du Colombier fgopcode(o, &fregnode0, &fregnode1, 1, 1);
8683e12c5d1SDavid du Colombier else {
8693e12c5d1SDavid du Colombier Node onod;
8703e12c5d1SDavid du Colombier
8713e12c5d1SDavid du Colombier /* incredible grot ... */
8723e12c5d1SDavid du Colombier onod = nod3;
8733e12c5d1SDavid du Colombier onod.op = o;
8743e12c5d1SDavid du Colombier onod.complex = 2;
8753e12c5d1SDavid du Colombier onod.addable = 0;
8767dd7cddfSDavid du Colombier onod.type = tfield;
8773e12c5d1SDavid du Colombier onod.left = &nod4;
8783e12c5d1SDavid du Colombier onod.right = &nod3;
8793e12c5d1SDavid du Colombier cgen(&onod, Z);
8803e12c5d1SDavid du Colombier }
8813e12c5d1SDavid du Colombier regfree(&nod3);
8823e12c5d1SDavid du Colombier gmove(&nod4, &nod);
8833e12c5d1SDavid du Colombier regfree(&nod4);
8843e12c5d1SDavid du Colombier bitstore(l, &nod, &nod1, &nod2, nn);
8853e12c5d1SDavid du Colombier break;
8863e12c5d1SDavid du Colombier
8873e12c5d1SDavid du Colombier case OADDR:
8883e12c5d1SDavid du Colombier if(nn == Z) {
8893e12c5d1SDavid du Colombier nullwarn(l, Z);
8903e12c5d1SDavid du Colombier break;
8913e12c5d1SDavid du Colombier }
8923e12c5d1SDavid du Colombier lcgen(l, nn);
8933e12c5d1SDavid du Colombier break;
8943e12c5d1SDavid du Colombier
8953e12c5d1SDavid du Colombier case OFUNC:
896*d40255d8SDavid du Colombier l = uncomma(l);
8973e12c5d1SDavid du Colombier if(l->complex >= FNX) {
8983e12c5d1SDavid du Colombier if(l->op != OIND)
8993e12c5d1SDavid du Colombier diag(n, "bad function call");
9003e12c5d1SDavid du Colombier
9013e12c5d1SDavid du Colombier regret(&nod, l->left);
9023e12c5d1SDavid du Colombier cgen(l->left, &nod);
9033e12c5d1SDavid du Colombier regsalloc(&nod1, l->left);
9043e12c5d1SDavid du Colombier gmove(&nod, &nod1);
9053e12c5d1SDavid du Colombier regfree(&nod);
9063e12c5d1SDavid du Colombier
9073e12c5d1SDavid du Colombier nod = *n;
9083e12c5d1SDavid du Colombier nod.left = &nod2;
9093e12c5d1SDavid du Colombier nod2 = *l;
9103e12c5d1SDavid du Colombier nod2.left = &nod1;
9113e12c5d1SDavid du Colombier nod2.complex = 1;
9123e12c5d1SDavid du Colombier cgen(&nod, nn);
9133e12c5d1SDavid du Colombier
9143e12c5d1SDavid du Colombier return;
9153e12c5d1SDavid du Colombier }
9163e12c5d1SDavid du Colombier gargs(r, &nod, &nod1);
9173e12c5d1SDavid du Colombier if(l->addable < INDEXED) {
9183e12c5d1SDavid du Colombier reglcgen(&nod, l, nn);
9193e12c5d1SDavid du Colombier nod.op = OREGISTER;
9203e12c5d1SDavid du Colombier gopcode(OFUNC, n->type, Z, &nod);
9213e12c5d1SDavid du Colombier regfree(&nod);
9223e12c5d1SDavid du Colombier } else
9233e12c5d1SDavid du Colombier gopcode(OFUNC, n->type, Z, l);
9244ac975e2SDavid du Colombier if(REGARG>=0 && reg[REGARG])
9253e12c5d1SDavid du Colombier reg[REGARG]--;
9263e12c5d1SDavid du Colombier if(nn != Z) {
9273e12c5d1SDavid du Colombier regret(&nod, n);
9283e12c5d1SDavid du Colombier gmove(&nod, nn);
9293e12c5d1SDavid du Colombier regfree(&nod);
9303e12c5d1SDavid du Colombier } else
931219b2ee8SDavid du Colombier if(typefd[n->type->etype])
9323e12c5d1SDavid du Colombier gins(AFMOVDP, &fregnode0, &fregnode0);
9333e12c5d1SDavid du Colombier break;
9343e12c5d1SDavid du Colombier
9353e12c5d1SDavid du Colombier case OIND:
9363e12c5d1SDavid du Colombier if(nn == Z) {
9373e12c5d1SDavid du Colombier nullwarn(l, Z);
9383e12c5d1SDavid du Colombier break;
9393e12c5d1SDavid du Colombier }
9403e12c5d1SDavid du Colombier regialloc(&nod, n, nn);
9413e12c5d1SDavid du Colombier r = l;
9423e12c5d1SDavid du Colombier while(r->op == OADD)
9433e12c5d1SDavid du Colombier r = r->right;
9443e12c5d1SDavid du Colombier if(sconst(r)) {
945219b2ee8SDavid du Colombier v = r->vconst;
946219b2ee8SDavid du Colombier r->vconst = 0;
9473e12c5d1SDavid du Colombier cgen(l, &nod);
948219b2ee8SDavid du Colombier nod.xoffset += v;
949219b2ee8SDavid du Colombier r->vconst = v;
9503e12c5d1SDavid du Colombier } else
9513e12c5d1SDavid du Colombier cgen(l, &nod);
9523e12c5d1SDavid du Colombier regind(&nod, n);
9533e12c5d1SDavid du Colombier gmove(&nod, nn);
9543e12c5d1SDavid du Colombier regfree(&nod);
9553e12c5d1SDavid du Colombier break;
9563e12c5d1SDavid du Colombier
9573e12c5d1SDavid du Colombier case OEQ:
9583e12c5d1SDavid du Colombier case ONE:
9593e12c5d1SDavid du Colombier case OLE:
9603e12c5d1SDavid du Colombier case OLT:
9613e12c5d1SDavid du Colombier case OGE:
9623e12c5d1SDavid du Colombier case OGT:
9633e12c5d1SDavid du Colombier case OLO:
9643e12c5d1SDavid du Colombier case OLS:
9653e12c5d1SDavid du Colombier case OHI:
9663e12c5d1SDavid du Colombier case OHS:
9673e12c5d1SDavid du Colombier if(nn == Z) {
9683e12c5d1SDavid du Colombier nullwarn(l, r);
9693e12c5d1SDavid du Colombier break;
9703e12c5d1SDavid du Colombier }
9713e12c5d1SDavid du Colombier boolgen(n, 1, nn);
9723e12c5d1SDavid du Colombier break;
9733e12c5d1SDavid du Colombier
9743e12c5d1SDavid du Colombier case OANDAND:
9753e12c5d1SDavid du Colombier case OOROR:
9763e12c5d1SDavid du Colombier boolgen(n, 1, nn);
9773e12c5d1SDavid du Colombier if(nn == Z)
9783e12c5d1SDavid du Colombier patch(p, pc);
9793e12c5d1SDavid du Colombier break;
9803e12c5d1SDavid du Colombier
9813e12c5d1SDavid du Colombier case ONOT:
9823e12c5d1SDavid du Colombier if(nn == Z) {
9833e12c5d1SDavid du Colombier nullwarn(l, Z);
9843e12c5d1SDavid du Colombier break;
9853e12c5d1SDavid du Colombier }
9863e12c5d1SDavid du Colombier boolgen(n, 1, nn);
9873e12c5d1SDavid du Colombier break;
9883e12c5d1SDavid du Colombier
9893e12c5d1SDavid du Colombier case OCOMMA:
9903e12c5d1SDavid du Colombier cgen(l, Z);
9913e12c5d1SDavid du Colombier cgen(r, nn);
9923e12c5d1SDavid du Colombier break;
9933e12c5d1SDavid du Colombier
9943e12c5d1SDavid du Colombier case OCAST:
9953e12c5d1SDavid du Colombier if(nn == Z) {
9963e12c5d1SDavid du Colombier nullwarn(l, Z);
9973e12c5d1SDavid du Colombier break;
9983e12c5d1SDavid du Colombier }
9993e12c5d1SDavid du Colombier /*
10003e12c5d1SDavid du Colombier * convert from types l->n->nn
10013e12c5d1SDavid du Colombier */
10023e12c5d1SDavid du Colombier if(nocast(l->type, n->type) && nocast(n->type, nn->type)) {
10033e12c5d1SDavid du Colombier /* both null, gen l->nn */
10043e12c5d1SDavid du Colombier cgen(l, nn);
10053e12c5d1SDavid du Colombier break;
10063e12c5d1SDavid du Colombier }
1007da51d93aSDavid du Colombier if(typev[l->type->etype]) {
1008da51d93aSDavid du Colombier cgen64(n, nn);
1009da51d93aSDavid du Colombier break;
1010da51d93aSDavid du Colombier }
10113e12c5d1SDavid du Colombier regalloc(&nod, l, nn);
10123e12c5d1SDavid du Colombier cgen(l, &nod);
10133e12c5d1SDavid du Colombier regalloc(&nod1, n, &nod);
10143e12c5d1SDavid du Colombier gmove(&nod, &nod1);
10153e12c5d1SDavid du Colombier gmove(&nod1, nn);
10163e12c5d1SDavid du Colombier regfree(&nod1);
10173e12c5d1SDavid du Colombier regfree(&nod);
10183e12c5d1SDavid du Colombier break;
10193e12c5d1SDavid du Colombier
10203e12c5d1SDavid du Colombier case ODOT:
10213e12c5d1SDavid du Colombier sugen(l, nodrat, l->type->width);
10227dd7cddfSDavid du Colombier if(nn == Z)
10237dd7cddfSDavid du Colombier break;
10243e12c5d1SDavid du Colombier warn(n, "non-interruptable temporary");
10253e12c5d1SDavid du Colombier nod = *nodrat;
10263e12c5d1SDavid du Colombier if(!r || r->op != OCONST) {
10273e12c5d1SDavid du Colombier diag(n, "DOT and no offset");
10283e12c5d1SDavid du Colombier break;
10293e12c5d1SDavid du Colombier }
1030219b2ee8SDavid du Colombier nod.xoffset += (long)r->vconst;
10313e12c5d1SDavid du Colombier nod.type = n->type;
10323e12c5d1SDavid du Colombier cgen(&nod, nn);
10333e12c5d1SDavid du Colombier break;
10343e12c5d1SDavid du Colombier
10353e12c5d1SDavid du Colombier case OCOND:
10363e12c5d1SDavid du Colombier bcgen(l, 1);
10373e12c5d1SDavid du Colombier p1 = p;
10383e12c5d1SDavid du Colombier cgen(r->left, nn);
10393e12c5d1SDavid du Colombier gbranch(OGOTO);
10403e12c5d1SDavid du Colombier patch(p1, pc);
10413e12c5d1SDavid du Colombier p1 = p;
10423e12c5d1SDavid du Colombier cgen(r->right, nn);
10433e12c5d1SDavid du Colombier patch(p1, pc);
10443e12c5d1SDavid du Colombier break;
10453e12c5d1SDavid du Colombier
10463e12c5d1SDavid du Colombier case OPOSTINC:
10473e12c5d1SDavid du Colombier case OPOSTDEC:
10483e12c5d1SDavid du Colombier v = 1;
10493e12c5d1SDavid du Colombier if(l->type->etype == TIND)
10503e12c5d1SDavid du Colombier v = l->type->link->width;
10513e12c5d1SDavid du Colombier if(o == OPOSTDEC)
10523e12c5d1SDavid du Colombier v = -v;
10533e12c5d1SDavid du Colombier if(l->op == OBIT)
10543e12c5d1SDavid du Colombier goto bitinc;
10553e12c5d1SDavid du Colombier if(nn == Z)
10563e12c5d1SDavid du Colombier goto pre;
10573e12c5d1SDavid du Colombier
10587dd7cddfSDavid du Colombier if(hardleft)
10593e12c5d1SDavid du Colombier reglcgen(&nod, l, Z);
10603e12c5d1SDavid du Colombier else
10613e12c5d1SDavid du Colombier nod = *l;
10623e12c5d1SDavid du Colombier
1063219b2ee8SDavid du Colombier if(typefd[n->type->etype])
10643e12c5d1SDavid du Colombier goto fltinc;
10653e12c5d1SDavid du Colombier gmove(&nod, nn);
10663e12c5d1SDavid du Colombier gopcode(OADD, n->type, nodconst(v), &nod);
10677dd7cddfSDavid du Colombier if(hardleft)
10683e12c5d1SDavid du Colombier regfree(&nod);
10693e12c5d1SDavid du Colombier break;
10703e12c5d1SDavid du Colombier
10713e12c5d1SDavid du Colombier case OPREINC:
10723e12c5d1SDavid du Colombier case OPREDEC:
10733e12c5d1SDavid du Colombier v = 1;
10743e12c5d1SDavid du Colombier if(l->type->etype == TIND)
10753e12c5d1SDavid du Colombier v = l->type->link->width;
10763e12c5d1SDavid du Colombier if(o == OPREDEC)
10773e12c5d1SDavid du Colombier v = -v;
10783e12c5d1SDavid du Colombier if(l->op == OBIT)
10793e12c5d1SDavid du Colombier goto bitinc;
10803e12c5d1SDavid du Colombier
10813e12c5d1SDavid du Colombier pre:
10827dd7cddfSDavid du Colombier if(hardleft)
10833e12c5d1SDavid du Colombier reglcgen(&nod, l, Z);
10843e12c5d1SDavid du Colombier else
10853e12c5d1SDavid du Colombier nod = *l;
1086219b2ee8SDavid du Colombier if(typefd[n->type->etype])
10873e12c5d1SDavid du Colombier goto fltinc;
10883e12c5d1SDavid du Colombier gopcode(OADD, n->type, nodconst(v), &nod);
10893e12c5d1SDavid du Colombier if(nn != Z)
10903e12c5d1SDavid du Colombier gmove(&nod, nn);
10917dd7cddfSDavid du Colombier if(hardleft)
10923e12c5d1SDavid du Colombier regfree(&nod);
10933e12c5d1SDavid du Colombier break;
10943e12c5d1SDavid du Colombier
10953e12c5d1SDavid du Colombier fltinc:
10963e12c5d1SDavid du Colombier gmove(&nod, &fregnode0);
10973e12c5d1SDavid du Colombier if(nn != Z && (o == OPOSTINC || o == OPOSTDEC))
10983e12c5d1SDavid du Colombier gins(AFMOVD, &fregnode0, &fregnode0);
10993e12c5d1SDavid du Colombier gins(AFLD1, Z, Z);
11003e12c5d1SDavid du Colombier if(v < 0)
11013e12c5d1SDavid du Colombier fgopcode(OSUB, &fregnode0, &fregnode1, 1, 0);
11023e12c5d1SDavid du Colombier else
11033e12c5d1SDavid du Colombier fgopcode(OADD, &fregnode0, &fregnode1, 1, 0);
11043e12c5d1SDavid du Colombier if(nn != Z && (o == OPREINC || o == OPREDEC))
11053e12c5d1SDavid du Colombier gins(AFMOVD, &fregnode0, &fregnode0);
11063e12c5d1SDavid du Colombier gmove(&fregnode0, &nod);
11077dd7cddfSDavid du Colombier if(hardleft)
11083e12c5d1SDavid du Colombier regfree(&nod);
11093e12c5d1SDavid du Colombier break;
11103e12c5d1SDavid du Colombier
11113e12c5d1SDavid du Colombier bitinc:
11123e12c5d1SDavid du Colombier if(nn != Z && (o == OPOSTINC || o == OPOSTDEC)) {
11133e12c5d1SDavid du Colombier bitload(l, &nod, &nod1, &nod2, Z);
11143e12c5d1SDavid du Colombier gmove(&nod, nn);
11157dd7cddfSDavid du Colombier gopcode(OADD, tfield, nodconst(v), &nod);
11163e12c5d1SDavid du Colombier bitstore(l, &nod, &nod1, &nod2, Z);
11173e12c5d1SDavid du Colombier break;
11183e12c5d1SDavid du Colombier }
11193e12c5d1SDavid du Colombier bitload(l, &nod, &nod1, &nod2, nn);
11207dd7cddfSDavid du Colombier gopcode(OADD, tfield, nodconst(v), &nod);
11213e12c5d1SDavid du Colombier bitstore(l, &nod, &nod1, &nod2, nn);
11223e12c5d1SDavid du Colombier break;
11233e12c5d1SDavid du Colombier }
1124375daca8SDavid du Colombier done:
11253e12c5d1SDavid du Colombier cursafe = curs;
11263e12c5d1SDavid du Colombier }
11273e12c5d1SDavid du Colombier
11283e12c5d1SDavid du Colombier void
reglcgen(Node * t,Node * n,Node * nn)11293e12c5d1SDavid du Colombier reglcgen(Node *t, Node *n, Node *nn)
11303e12c5d1SDavid du Colombier {
11313e12c5d1SDavid du Colombier Node *r;
11323e12c5d1SDavid du Colombier long v;
11333e12c5d1SDavid du Colombier
11343e12c5d1SDavid du Colombier regialloc(t, n, nn);
11353e12c5d1SDavid du Colombier if(n->op == OIND) {
11363e12c5d1SDavid du Colombier r = n->left;
11373e12c5d1SDavid du Colombier while(r->op == OADD)
11383e12c5d1SDavid du Colombier r = r->right;
11393e12c5d1SDavid du Colombier if(sconst(r)) {
1140219b2ee8SDavid du Colombier v = r->vconst;
1141219b2ee8SDavid du Colombier r->vconst = 0;
11423e12c5d1SDavid du Colombier lcgen(n, t);
1143219b2ee8SDavid du Colombier t->xoffset += v;
1144219b2ee8SDavid du Colombier r->vconst = v;
11453e12c5d1SDavid du Colombier regind(t, n);
11463e12c5d1SDavid du Colombier return;
11473e12c5d1SDavid du Colombier }
11483e12c5d1SDavid du Colombier }
11493e12c5d1SDavid du Colombier lcgen(n, t);
11503e12c5d1SDavid du Colombier regind(t, n);
11513e12c5d1SDavid du Colombier }
11523e12c5d1SDavid du Colombier
11533e12c5d1SDavid du Colombier void
lcgen(Node * n,Node * nn)11543e12c5d1SDavid du Colombier lcgen(Node *n, Node *nn)
11553e12c5d1SDavid du Colombier {
11563e12c5d1SDavid du Colombier Prog *p1;
11573e12c5d1SDavid du Colombier Node nod;
11583e12c5d1SDavid du Colombier
11593e12c5d1SDavid du Colombier if(debug['g']) {
11603e12c5d1SDavid du Colombier prtree(nn, "lcgen lhs");
11613e12c5d1SDavid du Colombier prtree(n, "lcgen");
11623e12c5d1SDavid du Colombier }
11633e12c5d1SDavid du Colombier if(n == Z || n->type == T)
11643e12c5d1SDavid du Colombier return;
11653e12c5d1SDavid du Colombier if(nn == Z) {
11663e12c5d1SDavid du Colombier nn = &nod;
11673e12c5d1SDavid du Colombier regalloc(&nod, n, Z);
11683e12c5d1SDavid du Colombier }
11693e12c5d1SDavid du Colombier switch(n->op) {
11703e12c5d1SDavid du Colombier default:
11713e12c5d1SDavid du Colombier if(n->addable < INDEXED) {
11723e12c5d1SDavid du Colombier diag(n, "unknown op in lcgen: %O", n->op);
11733e12c5d1SDavid du Colombier break;
11743e12c5d1SDavid du Colombier }
11753e12c5d1SDavid du Colombier gopcode(OADDR, n->type, n, nn);
11763e12c5d1SDavid du Colombier break;
11773e12c5d1SDavid du Colombier
11783e12c5d1SDavid du Colombier case OCOMMA:
11793e12c5d1SDavid du Colombier cgen(n->left, n->left);
11803e12c5d1SDavid du Colombier lcgen(n->right, nn);
11813e12c5d1SDavid du Colombier break;
11823e12c5d1SDavid du Colombier
11833e12c5d1SDavid du Colombier case OIND:
11843e12c5d1SDavid du Colombier cgen(n->left, nn);
11853e12c5d1SDavid du Colombier break;
11863e12c5d1SDavid du Colombier
11873e12c5d1SDavid du Colombier case OCOND:
11883e12c5d1SDavid du Colombier bcgen(n->left, 1);
11893e12c5d1SDavid du Colombier p1 = p;
11903e12c5d1SDavid du Colombier lcgen(n->right->left, nn);
11913e12c5d1SDavid du Colombier gbranch(OGOTO);
11923e12c5d1SDavid du Colombier patch(p1, pc);
11933e12c5d1SDavid du Colombier p1 = p;
11943e12c5d1SDavid du Colombier lcgen(n->right->right, nn);
11953e12c5d1SDavid du Colombier patch(p1, pc);
11963e12c5d1SDavid du Colombier break;
11973e12c5d1SDavid du Colombier }
11983e12c5d1SDavid du Colombier }
11993e12c5d1SDavid du Colombier
12003e12c5d1SDavid du Colombier void
bcgen(Node * n,int true)12013e12c5d1SDavid du Colombier bcgen(Node *n, int true)
12023e12c5d1SDavid du Colombier {
12033e12c5d1SDavid du Colombier
12043e12c5d1SDavid du Colombier if(n->type == T)
12053e12c5d1SDavid du Colombier gbranch(OGOTO);
12063e12c5d1SDavid du Colombier else
12073e12c5d1SDavid du Colombier boolgen(n, true, Z);
12083e12c5d1SDavid du Colombier }
12093e12c5d1SDavid du Colombier
12103e12c5d1SDavid du Colombier void
boolgen(Node * n,int true,Node * nn)12113e12c5d1SDavid du Colombier boolgen(Node *n, int true, Node *nn)
12123e12c5d1SDavid du Colombier {
12133e12c5d1SDavid du Colombier int o;
12143e12c5d1SDavid du Colombier Prog *p1, *p2;
12153e12c5d1SDavid du Colombier Node *l, *r, nod, nod1;
12163e12c5d1SDavid du Colombier long curs;
12173e12c5d1SDavid du Colombier
12183e12c5d1SDavid du Colombier if(debug['g']) {
12193e12c5d1SDavid du Colombier prtree(nn, "boolgen lhs");
12203e12c5d1SDavid du Colombier prtree(n, "boolgen");
12213e12c5d1SDavid du Colombier }
12223e12c5d1SDavid du Colombier curs = cursafe;
12233e12c5d1SDavid du Colombier l = n->left;
12243e12c5d1SDavid du Colombier r = n->right;
12253e12c5d1SDavid du Colombier switch(n->op) {
12263e12c5d1SDavid du Colombier
12273e12c5d1SDavid du Colombier default:
1228da51d93aSDavid du Colombier if(typev[n->type->etype]) {
1229da51d93aSDavid du Colombier testv(n, true);
1230da51d93aSDavid du Colombier goto com;
1231da51d93aSDavid du Colombier }
12323e12c5d1SDavid du Colombier o = ONE;
12333e12c5d1SDavid du Colombier if(true)
12343e12c5d1SDavid du Colombier o = OEQ;
1235219b2ee8SDavid du Colombier if(typefd[n->type->etype]) {
12363e12c5d1SDavid du Colombier if(n->addable < INDEXED) {
12373e12c5d1SDavid du Colombier cgen(n, &fregnode0);
12383e12c5d1SDavid du Colombier gins(AFLDZ, Z, Z);
12393e12c5d1SDavid du Colombier fgopcode(o, &fregnode0, &fregnode1, 1, 1);
12403e12c5d1SDavid du Colombier } else {
12413e12c5d1SDavid du Colombier gins(AFLDZ, Z, Z);
12423e12c5d1SDavid du Colombier fgopcode(o, n, &fregnode0, 0, 1);
12433e12c5d1SDavid du Colombier }
12443e12c5d1SDavid du Colombier goto com;
12453e12c5d1SDavid du Colombier }
1246219b2ee8SDavid du Colombier /* bad, 13 is address of external that becomes constant */
1247219b2ee8SDavid du Colombier if(n->addable >= INDEXED && n->addable != 13) {
12483e12c5d1SDavid du Colombier gopcode(o, n->type, n, nodconst(0));
12493e12c5d1SDavid du Colombier goto com;
12503e12c5d1SDavid du Colombier }
12513e12c5d1SDavid du Colombier regalloc(&nod, n, nn);
12523e12c5d1SDavid du Colombier cgen(n, &nod);
12533e12c5d1SDavid du Colombier gopcode(o, n->type, &nod, nodconst(0));
12543e12c5d1SDavid du Colombier regfree(&nod);
12553e12c5d1SDavid du Colombier goto com;
12563e12c5d1SDavid du Colombier
12573e12c5d1SDavid du Colombier case OCONST:
12583e12c5d1SDavid du Colombier o = vconst(n);
12593e12c5d1SDavid du Colombier if(!true)
12603e12c5d1SDavid du Colombier o = !o;
12613e12c5d1SDavid du Colombier gbranch(OGOTO);
12623e12c5d1SDavid du Colombier if(o) {
12633e12c5d1SDavid du Colombier p1 = p;
12643e12c5d1SDavid du Colombier gbranch(OGOTO);
12653e12c5d1SDavid du Colombier patch(p1, pc);
12663e12c5d1SDavid du Colombier }
12673e12c5d1SDavid du Colombier goto com;
12683e12c5d1SDavid du Colombier
12693e12c5d1SDavid du Colombier case OCOMMA:
12703e12c5d1SDavid du Colombier cgen(l, Z);
12713e12c5d1SDavid du Colombier boolgen(r, true, nn);
12723e12c5d1SDavid du Colombier break;
12733e12c5d1SDavid du Colombier
12743e12c5d1SDavid du Colombier case ONOT:
12753e12c5d1SDavid du Colombier boolgen(l, !true, nn);
12763e12c5d1SDavid du Colombier break;
12773e12c5d1SDavid du Colombier
12783e12c5d1SDavid du Colombier case OCOND:
12793e12c5d1SDavid du Colombier bcgen(l, 1);
12803e12c5d1SDavid du Colombier p1 = p;
12813e12c5d1SDavid du Colombier bcgen(r->left, true);
12823e12c5d1SDavid du Colombier p2 = p;
12833e12c5d1SDavid du Colombier gbranch(OGOTO);
12843e12c5d1SDavid du Colombier patch(p1, pc);
12853e12c5d1SDavid du Colombier p1 = p;
12863e12c5d1SDavid du Colombier bcgen(r->right, !true);
12873e12c5d1SDavid du Colombier patch(p2, pc);
12883e12c5d1SDavid du Colombier p2 = p;
12893e12c5d1SDavid du Colombier gbranch(OGOTO);
12903e12c5d1SDavid du Colombier patch(p1, pc);
12913e12c5d1SDavid du Colombier patch(p2, pc);
12923e12c5d1SDavid du Colombier goto com;
12933e12c5d1SDavid du Colombier
12943e12c5d1SDavid du Colombier case OANDAND:
12953e12c5d1SDavid du Colombier if(!true)
12963e12c5d1SDavid du Colombier goto caseor;
12973e12c5d1SDavid du Colombier
12983e12c5d1SDavid du Colombier caseand:
12993e12c5d1SDavid du Colombier bcgen(l, true);
13003e12c5d1SDavid du Colombier p1 = p;
13013e12c5d1SDavid du Colombier bcgen(r, !true);
13023e12c5d1SDavid du Colombier p2 = p;
13033e12c5d1SDavid du Colombier patch(p1, pc);
13043e12c5d1SDavid du Colombier gbranch(OGOTO);
13053e12c5d1SDavid du Colombier patch(p2, pc);
13063e12c5d1SDavid du Colombier goto com;
13073e12c5d1SDavid du Colombier
13083e12c5d1SDavid du Colombier case OOROR:
13093e12c5d1SDavid du Colombier if(!true)
13103e12c5d1SDavid du Colombier goto caseand;
13113e12c5d1SDavid du Colombier
13123e12c5d1SDavid du Colombier caseor:
13133e12c5d1SDavid du Colombier bcgen(l, !true);
13143e12c5d1SDavid du Colombier p1 = p;
13153e12c5d1SDavid du Colombier bcgen(r, !true);
13163e12c5d1SDavid du Colombier p2 = p;
13173e12c5d1SDavid du Colombier gbranch(OGOTO);
13183e12c5d1SDavid du Colombier patch(p1, pc);
13193e12c5d1SDavid du Colombier patch(p2, pc);
13203e12c5d1SDavid du Colombier goto com;
13213e12c5d1SDavid du Colombier
13223e12c5d1SDavid du Colombier case OEQ:
13233e12c5d1SDavid du Colombier case ONE:
13243e12c5d1SDavid du Colombier case OLE:
13253e12c5d1SDavid du Colombier case OLT:
13263e12c5d1SDavid du Colombier case OGE:
13273e12c5d1SDavid du Colombier case OGT:
13283e12c5d1SDavid du Colombier case OHI:
13293e12c5d1SDavid du Colombier case OHS:
13303e12c5d1SDavid du Colombier case OLO:
13313e12c5d1SDavid du Colombier case OLS:
13323e12c5d1SDavid du Colombier o = n->op;
1333da51d93aSDavid du Colombier if(typev[l->type->etype]) {
1334da51d93aSDavid du Colombier if(!true)
1335da51d93aSDavid du Colombier n->op = comrel[relindex(o)];
1336da51d93aSDavid du Colombier cgen64(n, Z);
1337da51d93aSDavid du Colombier goto com;
1338da51d93aSDavid du Colombier }
13393e12c5d1SDavid du Colombier if(true)
13403e12c5d1SDavid du Colombier o = comrel[relindex(o)];
13413e12c5d1SDavid du Colombier if(l->complex >= FNX && r->complex >= FNX) {
13423e12c5d1SDavid du Colombier regret(&nod, r);
13433e12c5d1SDavid du Colombier cgen(r, &nod);
13443e12c5d1SDavid du Colombier regsalloc(&nod1, r);
13453e12c5d1SDavid du Colombier gmove(&nod, &nod1);
13463e12c5d1SDavid du Colombier regfree(&nod);
13473e12c5d1SDavid du Colombier nod = *n;
13483e12c5d1SDavid du Colombier nod.right = &nod1;
13493e12c5d1SDavid du Colombier boolgen(&nod, true, nn);
13503e12c5d1SDavid du Colombier break;
13513e12c5d1SDavid du Colombier }
1352219b2ee8SDavid du Colombier if(typefd[l->type->etype]) {
13533e12c5d1SDavid du Colombier if(l->complex >= r->complex) {
13543e12c5d1SDavid du Colombier cgen(l, &fregnode0);
13553e12c5d1SDavid du Colombier if(r->addable < INDEXED) {
13563e12c5d1SDavid du Colombier cgen(r, &fregnode0);
13573e12c5d1SDavid du Colombier o = invrel[relindex(o)];
13583e12c5d1SDavid du Colombier fgopcode(o, &fregnode0, &fregnode1, 1, 1);
13593e12c5d1SDavid du Colombier } else
13603e12c5d1SDavid du Colombier fgopcode(o, r, &fregnode0, 0, 1);
13613e12c5d1SDavid du Colombier } else {
13623e12c5d1SDavid du Colombier o = invrel[relindex(o)];
13633e12c5d1SDavid du Colombier cgen(r, &fregnode0);
13643e12c5d1SDavid du Colombier if(l->addable < INDEXED) {
13653e12c5d1SDavid du Colombier cgen(l, &fregnode0);
13663e12c5d1SDavid du Colombier o = invrel[relindex(o)];
13673e12c5d1SDavid du Colombier fgopcode(o, &fregnode0, &fregnode1, 1, 1);
13683e12c5d1SDavid du Colombier } else
13693e12c5d1SDavid du Colombier fgopcode(o, l, &fregnode0, 0, 1);
13703e12c5d1SDavid du Colombier }
13713e12c5d1SDavid du Colombier goto com;
13723e12c5d1SDavid du Colombier }
13733e12c5d1SDavid du Colombier if(l->op == OCONST) {
13743e12c5d1SDavid du Colombier o = invrel[relindex(o)];
13753e12c5d1SDavid du Colombier /* bad, 13 is address of external that becomes constant */
13763e12c5d1SDavid du Colombier if(r->addable < INDEXED || r->addable == 13) {
13773e12c5d1SDavid du Colombier regalloc(&nod, r, nn);
13783e12c5d1SDavid du Colombier cgen(r, &nod);
13793e12c5d1SDavid du Colombier gopcode(o, l->type, &nod, l);
13803e12c5d1SDavid du Colombier regfree(&nod);
13813e12c5d1SDavid du Colombier } else
13823e12c5d1SDavid du Colombier gopcode(o, l->type, r, l);
13833e12c5d1SDavid du Colombier goto com;
13843e12c5d1SDavid du Colombier }
13853e12c5d1SDavid du Colombier if(l->complex >= r->complex) {
13863e12c5d1SDavid du Colombier regalloc(&nod, l, nn);
13873e12c5d1SDavid du Colombier cgen(l, &nod);
13883e12c5d1SDavid du Colombier if(r->addable < INDEXED) {
13893e12c5d1SDavid du Colombier regalloc(&nod1, r, Z);
13903e12c5d1SDavid du Colombier cgen(r, &nod1);
13913e12c5d1SDavid du Colombier gopcode(o, l->type, &nod, &nod1);
13923e12c5d1SDavid du Colombier regfree(&nod1);
13933e12c5d1SDavid du Colombier } else
13943e12c5d1SDavid du Colombier gopcode(o, l->type, &nod, r);
13953e12c5d1SDavid du Colombier regfree(&nod);
13963e12c5d1SDavid du Colombier goto com;
13973e12c5d1SDavid du Colombier }
13983e12c5d1SDavid du Colombier regalloc(&nod, r, nn);
13993e12c5d1SDavid du Colombier cgen(r, &nod);
14003e12c5d1SDavid du Colombier if(l->addable < INDEXED || l->addable == 13) {
14013e12c5d1SDavid du Colombier regalloc(&nod1, l, Z);
14023e12c5d1SDavid du Colombier cgen(l, &nod1);
1403da51d93aSDavid du Colombier if(typechlp[l->type->etype])
1404da51d93aSDavid du Colombier gopcode(o, types[TINT], &nod1, &nod);
1405da51d93aSDavid du Colombier else
14063e12c5d1SDavid du Colombier gopcode(o, l->type, &nod1, &nod);
14073e12c5d1SDavid du Colombier regfree(&nod1);
14083e12c5d1SDavid du Colombier } else
14093e12c5d1SDavid du Colombier gopcode(o, l->type, l, &nod);
14103e12c5d1SDavid du Colombier regfree(&nod);
14113e12c5d1SDavid du Colombier
14123e12c5d1SDavid du Colombier com:
14133e12c5d1SDavid du Colombier if(nn != Z) {
14143e12c5d1SDavid du Colombier p1 = p;
14153e12c5d1SDavid du Colombier gmove(nodconst(1L), nn);
14163e12c5d1SDavid du Colombier gbranch(OGOTO);
14173e12c5d1SDavid du Colombier p2 = p;
14183e12c5d1SDavid du Colombier patch(p1, pc);
14193e12c5d1SDavid du Colombier gmove(nodconst(0L), nn);
14203e12c5d1SDavid du Colombier patch(p2, pc);
14213e12c5d1SDavid du Colombier }
14223e12c5d1SDavid du Colombier break;
14233e12c5d1SDavid du Colombier }
14243e12c5d1SDavid du Colombier cursafe = curs;
14253e12c5d1SDavid du Colombier }
14263e12c5d1SDavid du Colombier
14273e12c5d1SDavid du Colombier void
sugen(Node * n,Node * nn,long w)14283e12c5d1SDavid du Colombier sugen(Node *n, Node *nn, long w)
14293e12c5d1SDavid du Colombier {
14303e12c5d1SDavid du Colombier Prog *p1;
1431da51d93aSDavid du Colombier Node nod0, nod1, nod2, nod3, nod4, *h, *l, *r;
14323e12c5d1SDavid du Colombier Type *t;
1433da51d93aSDavid du Colombier int c, v, x;
14343e12c5d1SDavid du Colombier
14353e12c5d1SDavid du Colombier if(n == Z || n->type == T)
14363e12c5d1SDavid du Colombier return;
14373e12c5d1SDavid du Colombier if(debug['g']) {
14383e12c5d1SDavid du Colombier prtree(nn, "sugen lhs");
14393e12c5d1SDavid du Colombier prtree(n, "sugen");
14403e12c5d1SDavid du Colombier }
14413e12c5d1SDavid du Colombier if(nn == nodrat)
14423e12c5d1SDavid du Colombier if(w > nrathole)
14433e12c5d1SDavid du Colombier nrathole = w;
14443e12c5d1SDavid du Colombier switch(n->op) {
14453e12c5d1SDavid du Colombier case OIND:
14463e12c5d1SDavid du Colombier if(nn == Z) {
14473e12c5d1SDavid du Colombier nullwarn(n->left, Z);
14483e12c5d1SDavid du Colombier break;
14493e12c5d1SDavid du Colombier }
14503e12c5d1SDavid du Colombier
14513e12c5d1SDavid du Colombier default:
14523e12c5d1SDavid du Colombier goto copy;
14533e12c5d1SDavid du Colombier
1454219b2ee8SDavid du Colombier case OCONST:
1455219b2ee8SDavid du Colombier if(n->type && typev[n->type->etype]) {
1456219b2ee8SDavid du Colombier if(nn == Z) {
1457219b2ee8SDavid du Colombier nullwarn(n->left, Z);
1458219b2ee8SDavid du Colombier break;
1459219b2ee8SDavid du Colombier }
1460219b2ee8SDavid du Colombier
1461da51d93aSDavid du Colombier if(nn->op == OREGPAIR) {
1462da51d93aSDavid du Colombier loadpair(n, nn);
1463da51d93aSDavid du Colombier break;
1464da51d93aSDavid du Colombier }
1465375daca8SDavid du Colombier else if(!vaddr(nn, 0)) {
1466219b2ee8SDavid du Colombier t = nn->type;
1467219b2ee8SDavid du Colombier nn->type = types[TLONG];
1468219b2ee8SDavid du Colombier reglcgen(&nod1, nn, Z);
1469219b2ee8SDavid du Colombier nn->type = t;
1470219b2ee8SDavid du Colombier
1471375daca8SDavid du Colombier gmove(lo64(n), &nod1);
1472219b2ee8SDavid du Colombier nod1.xoffset += SZ_LONG;
1473375daca8SDavid du Colombier gmove(hi64(n), &nod1);
1474219b2ee8SDavid du Colombier regfree(&nod1);
1475da51d93aSDavid du Colombier }
1476da51d93aSDavid du Colombier else {
1477375daca8SDavid du Colombier gins(AMOVL, lo64(n), nn);
147880ee5cbfSDavid du Colombier nn->xoffset += SZ_LONG;
1479375daca8SDavid du Colombier gins(AMOVL, hi64(n), nn);
148080ee5cbfSDavid du Colombier nn->xoffset -= SZ_LONG;
148180ee5cbfSDavid du Colombier break;
148280ee5cbfSDavid du Colombier }
148380ee5cbfSDavid du Colombier break;
1484219b2ee8SDavid du Colombier }
1485219b2ee8SDavid du Colombier goto copy;
1486219b2ee8SDavid du Colombier
14873e12c5d1SDavid du Colombier case ODOT:
14883e12c5d1SDavid du Colombier l = n->left;
14893e12c5d1SDavid du Colombier sugen(l, nodrat, l->type->width);
14907dd7cddfSDavid du Colombier if(nn == Z)
14917dd7cddfSDavid du Colombier break;
14923e12c5d1SDavid du Colombier warn(n, "non-interruptable temporary");
14933e12c5d1SDavid du Colombier nod1 = *nodrat;
14943e12c5d1SDavid du Colombier r = n->right;
14953e12c5d1SDavid du Colombier if(!r || r->op != OCONST) {
14963e12c5d1SDavid du Colombier diag(n, "DOT and no offset");
14973e12c5d1SDavid du Colombier break;
14983e12c5d1SDavid du Colombier }
1499219b2ee8SDavid du Colombier nod1.xoffset += (long)r->vconst;
15003e12c5d1SDavid du Colombier nod1.type = n->type;
15013e12c5d1SDavid du Colombier sugen(&nod1, nn, w);
15023e12c5d1SDavid du Colombier break;
15033e12c5d1SDavid du Colombier
15043e12c5d1SDavid du Colombier case OSTRUCT:
1505219b2ee8SDavid du Colombier /*
1506219b2ee8SDavid du Colombier * rewrite so lhs has no fn call
1507219b2ee8SDavid du Colombier */
150880ee5cbfSDavid du Colombier if(nn != Z && side(nn)) {
1509219b2ee8SDavid du Colombier nod1 = *n;
1510219b2ee8SDavid du Colombier nod1.type = typ(TIND, n->type);
1511219b2ee8SDavid du Colombier regret(&nod2, &nod1);
1512219b2ee8SDavid du Colombier lcgen(nn, &nod2);
1513219b2ee8SDavid du Colombier regsalloc(&nod0, &nod1);
1514219b2ee8SDavid du Colombier cgen(&nod2, &nod0);
1515219b2ee8SDavid du Colombier regfree(&nod2);
1516219b2ee8SDavid du Colombier
1517219b2ee8SDavid du Colombier nod1 = *n;
1518219b2ee8SDavid du Colombier nod1.op = OIND;
1519219b2ee8SDavid du Colombier nod1.left = &nod0;
1520219b2ee8SDavid du Colombier nod1.right = Z;
1521219b2ee8SDavid du Colombier nod1.complex = 1;
1522219b2ee8SDavid du Colombier
1523219b2ee8SDavid du Colombier sugen(n, &nod1, w);
1524219b2ee8SDavid du Colombier return;
1525219b2ee8SDavid du Colombier }
1526219b2ee8SDavid du Colombier
15273e12c5d1SDavid du Colombier r = n->left;
15283e12c5d1SDavid du Colombier for(t = n->type->link; t != T; t = t->down) {
15293e12c5d1SDavid du Colombier l = r;
15303e12c5d1SDavid du Colombier if(r->op == OLIST) {
15313e12c5d1SDavid du Colombier l = r->left;
15323e12c5d1SDavid du Colombier r = r->right;
15333e12c5d1SDavid du Colombier }
15343e12c5d1SDavid du Colombier if(nn == Z) {
15353e12c5d1SDavid du Colombier cgen(l, nn);
15363e12c5d1SDavid du Colombier continue;
15373e12c5d1SDavid du Colombier }
15383e12c5d1SDavid du Colombier /*
15393e12c5d1SDavid du Colombier * hand craft *(&nn + o) = l
15403e12c5d1SDavid du Colombier */
15413e12c5d1SDavid du Colombier nod0 = znode;
15423e12c5d1SDavid du Colombier nod0.op = OAS;
15433e12c5d1SDavid du Colombier nod0.type = t;
15443e12c5d1SDavid du Colombier nod0.left = &nod1;
154580ee5cbfSDavid du Colombier nod0.right = nil;
15463e12c5d1SDavid du Colombier
15473e12c5d1SDavid du Colombier nod1 = znode;
15483e12c5d1SDavid du Colombier nod1.op = OIND;
15493e12c5d1SDavid du Colombier nod1.type = t;
15503e12c5d1SDavid du Colombier nod1.left = &nod2;
15513e12c5d1SDavid du Colombier
15523e12c5d1SDavid du Colombier nod2 = znode;
15533e12c5d1SDavid du Colombier nod2.op = OADD;
15543e12c5d1SDavid du Colombier nod2.type = typ(TIND, t);
15553e12c5d1SDavid du Colombier nod2.left = &nod3;
15563e12c5d1SDavid du Colombier nod2.right = &nod4;
15573e12c5d1SDavid du Colombier
15583e12c5d1SDavid du Colombier nod3 = znode;
15593e12c5d1SDavid du Colombier nod3.op = OADDR;
15603e12c5d1SDavid du Colombier nod3.type = nod2.type;
15613e12c5d1SDavid du Colombier nod3.left = nn;
15623e12c5d1SDavid du Colombier
15633e12c5d1SDavid du Colombier nod4 = znode;
15643e12c5d1SDavid du Colombier nod4.op = OCONST;
15653e12c5d1SDavid du Colombier nod4.type = nod2.type;
1566219b2ee8SDavid du Colombier nod4.vconst = t->offset;
15673e12c5d1SDavid du Colombier
15683e12c5d1SDavid du Colombier ccom(&nod0);
15693e12c5d1SDavid du Colombier acom(&nod0);
15703e12c5d1SDavid du Colombier xcom(&nod0);
15713e12c5d1SDavid du Colombier nod0.addable = 0;
15723e12c5d1SDavid du Colombier nod0.right = l;
15733e12c5d1SDavid du Colombier
15743e12c5d1SDavid du Colombier /* prtree(&nod0, "hand craft"); /* */
15753e12c5d1SDavid du Colombier cgen(&nod0, Z);
15763e12c5d1SDavid du Colombier }
15773e12c5d1SDavid du Colombier break;
15783e12c5d1SDavid du Colombier
15793e12c5d1SDavid du Colombier case OAS:
15803e12c5d1SDavid du Colombier if(nn == Z) {
15813e12c5d1SDavid du Colombier if(n->addable < INDEXED)
15823e12c5d1SDavid du Colombier sugen(n->right, n->left, w);
15833e12c5d1SDavid du Colombier break;
15843e12c5d1SDavid du Colombier }
15857dd7cddfSDavid du Colombier
15863e12c5d1SDavid du Colombier sugen(n->right, nodrat, w);
15873e12c5d1SDavid du Colombier warn(n, "non-interruptable temporary");
15883e12c5d1SDavid du Colombier sugen(nodrat, n->left, w);
15893e12c5d1SDavid du Colombier sugen(nodrat, nn, w);
15903e12c5d1SDavid du Colombier break;
15913e12c5d1SDavid du Colombier
15923e12c5d1SDavid du Colombier case OFUNC:
15933e12c5d1SDavid du Colombier if(nn == Z) {
15943e12c5d1SDavid du Colombier sugen(n, nodrat, w);
15953e12c5d1SDavid du Colombier break;
15963e12c5d1SDavid du Colombier }
1597da51d93aSDavid du Colombier h = nn;
1598da51d93aSDavid du Colombier if(nn->op == OREGPAIR) {
1599da51d93aSDavid du Colombier regsalloc(&nod1, nn);
1600da51d93aSDavid du Colombier nn = &nod1;
1601da51d93aSDavid du Colombier }
16023e12c5d1SDavid du Colombier if(nn->op != OIND) {
16033e12c5d1SDavid du Colombier nn = new1(OADDR, nn, Z);
16043e12c5d1SDavid du Colombier nn->type = types[TIND];
16053e12c5d1SDavid du Colombier nn->addable = 0;
16063e12c5d1SDavid du Colombier } else
16073e12c5d1SDavid du Colombier nn = nn->left;
16083e12c5d1SDavid du Colombier n = new(OFUNC, n->left, new(OLIST, nn, n->right));
16093e12c5d1SDavid du Colombier n->type = types[TVOID];
16103e12c5d1SDavid du Colombier n->left->type = types[TVOID];
16113e12c5d1SDavid du Colombier cgen(n, Z);
1612da51d93aSDavid du Colombier if(h->op == OREGPAIR)
1613da51d93aSDavid du Colombier loadpair(nn->left, h);
16143e12c5d1SDavid du Colombier break;
16153e12c5d1SDavid du Colombier
16163e12c5d1SDavid du Colombier case OCOND:
16173e12c5d1SDavid du Colombier bcgen(n->left, 1);
16183e12c5d1SDavid du Colombier p1 = p;
16193e12c5d1SDavid du Colombier sugen(n->right->left, nn, w);
16203e12c5d1SDavid du Colombier gbranch(OGOTO);
16213e12c5d1SDavid du Colombier patch(p1, pc);
16223e12c5d1SDavid du Colombier p1 = p;
16233e12c5d1SDavid du Colombier sugen(n->right->right, nn, w);
16243e12c5d1SDavid du Colombier patch(p1, pc);
16253e12c5d1SDavid du Colombier break;
16263e12c5d1SDavid du Colombier
16273e12c5d1SDavid du Colombier case OCOMMA:
16283e12c5d1SDavid du Colombier cgen(n->left, Z);
16293e12c5d1SDavid du Colombier sugen(n->right, nn, w);
16303e12c5d1SDavid du Colombier break;
16313e12c5d1SDavid du Colombier }
16323e12c5d1SDavid du Colombier return;
16333e12c5d1SDavid du Colombier
16343e12c5d1SDavid du Colombier copy:
1635da51d93aSDavid du Colombier if(nn == Z) {
1636da51d93aSDavid du Colombier switch(n->op) {
1637da51d93aSDavid du Colombier case OASADD:
1638da51d93aSDavid du Colombier case OASSUB:
1639da51d93aSDavid du Colombier case OASAND:
1640da51d93aSDavid du Colombier case OASOR:
1641da51d93aSDavid du Colombier case OASXOR:
1642da51d93aSDavid du Colombier
1643375daca8SDavid du Colombier case OASMUL:
1644375daca8SDavid du Colombier case OASLMUL:
1645375daca8SDavid du Colombier
1646da51d93aSDavid du Colombier case OASASHL:
1647da51d93aSDavid du Colombier case OASASHR:
1648da51d93aSDavid du Colombier case OASLSHR:
1649da51d93aSDavid du Colombier break;
1650da51d93aSDavid du Colombier
1651da51d93aSDavid du Colombier case OPOSTINC:
1652da51d93aSDavid du Colombier case OPOSTDEC:
1653da51d93aSDavid du Colombier case OPREINC:
1654da51d93aSDavid du Colombier case OPREDEC:
1655da51d93aSDavid du Colombier break;
1656da51d93aSDavid du Colombier
1657da51d93aSDavid du Colombier default:
16583e12c5d1SDavid du Colombier return;
1659da51d93aSDavid du Colombier }
1660da51d93aSDavid du Colombier }
1661da51d93aSDavid du Colombier
1662da51d93aSDavid du Colombier if(n->complex >= FNX && nn != nil && nn->complex >= FNX) {
1663219b2ee8SDavid du Colombier t = nn->type;
1664219b2ee8SDavid du Colombier nn->type = types[TLONG];
1665219b2ee8SDavid du Colombier regialloc(&nod1, nn, Z);
1666219b2ee8SDavid du Colombier lcgen(nn, &nod1);
1667219b2ee8SDavid du Colombier regsalloc(&nod2, nn);
1668219b2ee8SDavid du Colombier nn->type = t;
1669219b2ee8SDavid du Colombier
1670219b2ee8SDavid du Colombier gins(AMOVL, &nod1, &nod2);
1671219b2ee8SDavid du Colombier regfree(&nod1);
1672219b2ee8SDavid du Colombier
1673219b2ee8SDavid du Colombier nod2.type = typ(TIND, t);
1674219b2ee8SDavid du Colombier
1675219b2ee8SDavid du Colombier nod1 = nod2;
1676219b2ee8SDavid du Colombier nod1.op = OIND;
1677219b2ee8SDavid du Colombier nod1.left = &nod2;
1678219b2ee8SDavid du Colombier nod1.right = Z;
1679219b2ee8SDavid du Colombier nod1.complex = 1;
1680219b2ee8SDavid du Colombier nod1.type = t;
1681219b2ee8SDavid du Colombier
1682219b2ee8SDavid du Colombier sugen(n, &nod1, w);
16833e12c5d1SDavid du Colombier return;
16843e12c5d1SDavid du Colombier }
16853e12c5d1SDavid du Colombier
1686da51d93aSDavid du Colombier x = 0;
1687da51d93aSDavid du Colombier v = w == 8;
1688da51d93aSDavid du Colombier if(v) {
1689da51d93aSDavid du Colombier c = cursafe;
1690375daca8SDavid du Colombier if(n->left != Z && n->left->complex >= FNX
1691375daca8SDavid du Colombier && n->right != Z && n->right->complex >= FNX) {
1692375daca8SDavid du Colombier // warn(n, "toughie");
1693375daca8SDavid du Colombier regsalloc(&nod1, n->right);
1694375daca8SDavid du Colombier cgen(n->right, &nod1);
1695375daca8SDavid du Colombier nod2 = *n;
1696375daca8SDavid du Colombier nod2.right = &nod1;
1697375daca8SDavid du Colombier cgen(&nod2, nn);
1698375daca8SDavid du Colombier cursafe = c;
1699375daca8SDavid du Colombier return;
1700375daca8SDavid du Colombier }
1701da51d93aSDavid du Colombier if(cgen64(n, nn)) {
1702da51d93aSDavid du Colombier cursafe = c;
170380ee5cbfSDavid du Colombier return;
170480ee5cbfSDavid du Colombier }
1705da51d93aSDavid du Colombier if(n->op == OCOM) {
1706da51d93aSDavid du Colombier n = n->left;
1707da51d93aSDavid du Colombier x = 1;
1708da51d93aSDavid du Colombier }
1709da51d93aSDavid du Colombier }
171080ee5cbfSDavid du Colombier
17113e12c5d1SDavid du Colombier /* botch, need to save in .safe */
17123e12c5d1SDavid du Colombier c = 0;
17133e12c5d1SDavid du Colombier if(n->complex > nn->complex) {
17143e12c5d1SDavid du Colombier t = n->type;
17153e12c5d1SDavid du Colombier n->type = types[TLONG];
1716da51d93aSDavid du Colombier if(v) {
1717da51d93aSDavid du Colombier regalloc(&nod0, n, Z);
1718375daca8SDavid du Colombier if(!vaddr(n, 0)) {
1719da51d93aSDavid du Colombier reglcgen(&nod1, n, Z);
1720da51d93aSDavid du Colombier n->type = t;
1721da51d93aSDavid du Colombier n = &nod1;
1722da51d93aSDavid du Colombier }
1723da51d93aSDavid du Colombier else
1724da51d93aSDavid du Colombier n->type = t;
1725da51d93aSDavid du Colombier }
1726da51d93aSDavid du Colombier else {
17273e12c5d1SDavid du Colombier nodreg(&nod1, n, D_SI);
17283e12c5d1SDavid du Colombier if(reg[D_SI]) {
17293e12c5d1SDavid du Colombier gins(APUSHL, &nod1, Z);
17303e12c5d1SDavid du Colombier c |= 1;
17313e12c5d1SDavid du Colombier reg[D_SI]++;
17323e12c5d1SDavid du Colombier }
17333e12c5d1SDavid du Colombier lcgen(n, &nod1);
17343e12c5d1SDavid du Colombier n->type = t;
1735da51d93aSDavid du Colombier }
17363e12c5d1SDavid du Colombier
17373e12c5d1SDavid du Colombier t = nn->type;
17383e12c5d1SDavid du Colombier nn->type = types[TLONG];
1739da51d93aSDavid du Colombier if(v) {
1740375daca8SDavid du Colombier if(!vaddr(nn, 0)) {
1741da51d93aSDavid du Colombier reglcgen(&nod2, nn, Z);
1742da51d93aSDavid du Colombier nn->type = t;
1743da51d93aSDavid du Colombier nn = &nod2;
1744da51d93aSDavid du Colombier }
1745da51d93aSDavid du Colombier else
1746da51d93aSDavid du Colombier nn->type = t;
1747da51d93aSDavid du Colombier }
1748da51d93aSDavid du Colombier else {
17493e12c5d1SDavid du Colombier nodreg(&nod2, nn, D_DI);
17503e12c5d1SDavid du Colombier if(reg[D_DI]) {
17513e12c5d1SDavid du Colombier gins(APUSHL, &nod2, Z);
17523e12c5d1SDavid du Colombier c |= 2;
17533e12c5d1SDavid du Colombier reg[D_DI]++;
17543e12c5d1SDavid du Colombier }
17553e12c5d1SDavid du Colombier lcgen(nn, &nod2);
17563e12c5d1SDavid du Colombier nn->type = t;
1757da51d93aSDavid du Colombier }
17583e12c5d1SDavid du Colombier } else {
17593e12c5d1SDavid du Colombier t = nn->type;
17603e12c5d1SDavid du Colombier nn->type = types[TLONG];
1761da51d93aSDavid du Colombier if(v) {
1762da51d93aSDavid du Colombier regalloc(&nod0, nn, Z);
1763375daca8SDavid du Colombier if(!vaddr(nn, 0)) {
1764da51d93aSDavid du Colombier reglcgen(&nod2, nn, Z);
1765da51d93aSDavid du Colombier nn->type = t;
1766da51d93aSDavid du Colombier nn = &nod2;
1767da51d93aSDavid du Colombier }
1768da51d93aSDavid du Colombier else
1769da51d93aSDavid du Colombier nn->type = t;
1770da51d93aSDavid du Colombier }
1771da51d93aSDavid du Colombier else {
1772da51d93aSDavid du Colombier nodreg(&nod2, nn, D_DI);
17733e12c5d1SDavid du Colombier if(reg[D_DI]) {
1774da51d93aSDavid du Colombier gins(APUSHL, &nod2, Z);
1775da51d93aSDavid du Colombier c |= 2;
17763e12c5d1SDavid du Colombier reg[D_DI]++;
17773e12c5d1SDavid du Colombier }
1778da51d93aSDavid du Colombier lcgen(nn, &nod2);
17793e12c5d1SDavid du Colombier nn->type = t;
1780da51d93aSDavid du Colombier }
17813e12c5d1SDavid du Colombier
17823e12c5d1SDavid du Colombier t = n->type;
17833e12c5d1SDavid du Colombier n->type = types[TLONG];
1784da51d93aSDavid du Colombier if(v) {
1785375daca8SDavid du Colombier if(!vaddr(n, 0)) {
1786da51d93aSDavid du Colombier reglcgen(&nod1, n, Z);
1787da51d93aSDavid du Colombier n->type = t;
1788da51d93aSDavid du Colombier n = &nod1;
1789da51d93aSDavid du Colombier }
1790da51d93aSDavid du Colombier else
1791da51d93aSDavid du Colombier n->type = t;
1792da51d93aSDavid du Colombier }
1793da51d93aSDavid du Colombier else {
1794da51d93aSDavid du Colombier nodreg(&nod1, n, D_SI);
17953e12c5d1SDavid du Colombier if(reg[D_SI]) {
1796da51d93aSDavid du Colombier gins(APUSHL, &nod1, Z);
1797da51d93aSDavid du Colombier c |= 1;
17983e12c5d1SDavid du Colombier reg[D_SI]++;
17993e12c5d1SDavid du Colombier }
1800da51d93aSDavid du Colombier lcgen(n, &nod1);
18013e12c5d1SDavid du Colombier n->type = t;
18023e12c5d1SDavid du Colombier }
1803da51d93aSDavid du Colombier }
1804da51d93aSDavid du Colombier if(v) {
1805da51d93aSDavid du Colombier gins(AMOVL, n, &nod0);
1806da51d93aSDavid du Colombier if(x)
1807da51d93aSDavid du Colombier gins(ANOTL, Z, &nod0);
1808da51d93aSDavid du Colombier gins(AMOVL, &nod0, nn);
1809da51d93aSDavid du Colombier n->xoffset += SZ_LONG;
1810da51d93aSDavid du Colombier nn->xoffset += SZ_LONG;
1811da51d93aSDavid du Colombier gins(AMOVL, n, &nod0);
1812da51d93aSDavid du Colombier if(x)
1813da51d93aSDavid du Colombier gins(ANOTL, Z, &nod0);
1814da51d93aSDavid du Colombier gins(AMOVL, &nod0, nn);
1815da51d93aSDavid du Colombier n->xoffset -= SZ_LONG;
1816da51d93aSDavid du Colombier nn->xoffset -= SZ_LONG;
1817da51d93aSDavid du Colombier if(nn == &nod2)
1818da51d93aSDavid du Colombier regfree(&nod2);
1819da51d93aSDavid du Colombier if(n == &nod1)
1820da51d93aSDavid du Colombier regfree(&nod1);
1821da51d93aSDavid du Colombier regfree(&nod0);
1822da51d93aSDavid du Colombier return;
1823da51d93aSDavid du Colombier }
18243e12c5d1SDavid du Colombier nodreg(&nod3, n, D_CX);
18253e12c5d1SDavid du Colombier if(reg[D_CX]) {
18263e12c5d1SDavid du Colombier gins(APUSHL, &nod3, Z);
18273e12c5d1SDavid du Colombier c |= 4;
18283e12c5d1SDavid du Colombier reg[D_CX]++;
18293e12c5d1SDavid du Colombier }
18303e12c5d1SDavid du Colombier gins(AMOVL, nodconst(w/SZ_LONG), &nod3);
18313e12c5d1SDavid du Colombier gins(ACLD, Z, Z);
18323e12c5d1SDavid du Colombier gins(AREP, Z, Z);
18333e12c5d1SDavid du Colombier gins(AMOVSL, Z, Z);
1834*d40255d8SDavid du Colombier if(w & (SZ_LONG-1)) {
1835*d40255d8SDavid du Colombier /* odd length of packed structure */
1836*d40255d8SDavid du Colombier gins(AMOVL, nodconst(w & (SZ_LONG-1)), &nod3);
1837*d40255d8SDavid du Colombier gins(AREP, Z, Z);
1838*d40255d8SDavid du Colombier gins(AMOVSB, Z, Z);
1839*d40255d8SDavid du Colombier }
18403e12c5d1SDavid du Colombier if(c & 4) {
18413e12c5d1SDavid du Colombier gins(APOPL, Z, &nod3);
18423e12c5d1SDavid du Colombier reg[D_CX]--;
18433e12c5d1SDavid du Colombier }
18443e12c5d1SDavid du Colombier if(c & 2) {
18453e12c5d1SDavid du Colombier gins(APOPL, Z, &nod2);
18463e12c5d1SDavid du Colombier reg[nod2.reg]--;
18473e12c5d1SDavid du Colombier }
18483e12c5d1SDavid du Colombier if(c & 1) {
18493e12c5d1SDavid du Colombier gins(APOPL, Z, &nod1);
18503e12c5d1SDavid du Colombier reg[nod1.reg]--;
18513e12c5d1SDavid du Colombier }
18523e12c5d1SDavid du Colombier }
1853