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