xref: /plan9/sys/src/cmd/qc/cgen.c (revision 4ac975e2e38b792d24bc60de7fce5e6173f046ea)
17dd7cddfSDavid du Colombier #include "gc.h"
27dd7cddfSDavid du Colombier 
37dd7cddfSDavid du Colombier void
47dd7cddfSDavid du Colombier cgen(Node *n, Node *nn)
57dd7cddfSDavid du Colombier {
67dd7cddfSDavid du Colombier 	Node *l, *r;
77dd7cddfSDavid du Colombier 	Prog *p1;
87dd7cddfSDavid du Colombier 	Node nod, nod1, nod2, nod3, nod4;
97dd7cddfSDavid du Colombier 	int o;
107dd7cddfSDavid du Colombier 	long v, curs;
117dd7cddfSDavid du Colombier 
127dd7cddfSDavid du Colombier 	if(debug['g']) {
137dd7cddfSDavid du Colombier 		prtree(nn, "cgen lhs");
147dd7cddfSDavid du Colombier 		prtree(n, "cgen");
157dd7cddfSDavid du Colombier 	}
167dd7cddfSDavid du Colombier 	if(n == Z || n->type == T)
177dd7cddfSDavid du Colombier 		return;
187dd7cddfSDavid du Colombier 	if(typesuv[n->type->etype]) {
197dd7cddfSDavid du Colombier 		sugen(n, nn, n->type->width);
207dd7cddfSDavid du Colombier 		return;
217dd7cddfSDavid du Colombier 	}
227dd7cddfSDavid du Colombier 	l = n->left;
237dd7cddfSDavid du Colombier 	r = n->right;
247dd7cddfSDavid du Colombier 	o = n->op;
257dd7cddfSDavid du Colombier 	if(n->addable >= INDEXED) {
267dd7cddfSDavid du Colombier 		if(nn == Z) {
277dd7cddfSDavid du Colombier 			switch(o) {
287dd7cddfSDavid du Colombier 			default:
297dd7cddfSDavid du Colombier 				nullwarn(Z, Z);
307dd7cddfSDavid du Colombier 				break;
317dd7cddfSDavid du Colombier 			case OINDEX:
327dd7cddfSDavid du Colombier 				nullwarn(l, r);
337dd7cddfSDavid du Colombier 				break;
347dd7cddfSDavid du Colombier 			}
357dd7cddfSDavid du Colombier 			return;
367dd7cddfSDavid du Colombier 		}
377dd7cddfSDavid du Colombier 		gmove(n, nn);
387dd7cddfSDavid du Colombier 		return;
397dd7cddfSDavid du Colombier 	}
407dd7cddfSDavid du Colombier 	curs = cursafe;
417dd7cddfSDavid du Colombier 
427dd7cddfSDavid du Colombier 	if(n->complex >= FNX)
437dd7cddfSDavid du Colombier 	if(l->complex >= FNX)
447dd7cddfSDavid du Colombier 	if(r != Z && r->complex >= FNX)
457dd7cddfSDavid du Colombier 	switch(o) {
467dd7cddfSDavid du Colombier 	default:
477dd7cddfSDavid du Colombier 		regret(&nod, r);
487dd7cddfSDavid du Colombier 		cgen(r, &nod);
497dd7cddfSDavid du Colombier 
507dd7cddfSDavid du Colombier 		regsalloc(&nod1, r);
517dd7cddfSDavid du Colombier 		gopcode(OAS, &nod, Z, &nod1);
527dd7cddfSDavid du Colombier 
537dd7cddfSDavid du Colombier 		regfree(&nod);
547dd7cddfSDavid du Colombier 		nod = *n;
557dd7cddfSDavid du Colombier 		nod.right = &nod1;
567dd7cddfSDavid du Colombier 		cgen(&nod, nn);
577dd7cddfSDavid du Colombier 		return;
587dd7cddfSDavid du Colombier 
597dd7cddfSDavid du Colombier 	case OFUNC:
607dd7cddfSDavid du Colombier 	case OCOMMA:
617dd7cddfSDavid du Colombier 	case OANDAND:
627dd7cddfSDavid du Colombier 	case OOROR:
637dd7cddfSDavid du Colombier 	case OCOND:
647dd7cddfSDavid du Colombier 	case ODOT:
657dd7cddfSDavid du Colombier 		break;
667dd7cddfSDavid du Colombier 	}
677dd7cddfSDavid du Colombier 
687dd7cddfSDavid du Colombier 	switch(o) {
697dd7cddfSDavid du Colombier 	default:
707dd7cddfSDavid du Colombier 		diag(n, "unknown op in cgen: %O", o);
717dd7cddfSDavid du Colombier 		break;
727dd7cddfSDavid du Colombier 
737dd7cddfSDavid du Colombier 	case OAS:
747dd7cddfSDavid du Colombier 		if(l->op == OBIT)
757dd7cddfSDavid du Colombier 			goto bitas;
767dd7cddfSDavid du Colombier 		if(l->addable >= INDEXED) {
777dd7cddfSDavid du Colombier 			if(nn != Z || r->addable < INDEXED) {
787dd7cddfSDavid du Colombier 				regalloc(&nod, r, nn);
797dd7cddfSDavid du Colombier 				cgen(r, &nod);
807dd7cddfSDavid du Colombier 				gmove(&nod, l);
817dd7cddfSDavid du Colombier 				regfree(&nod);
827dd7cddfSDavid du Colombier 			} else
837dd7cddfSDavid du Colombier 				gmove(r, l);
847dd7cddfSDavid du Colombier 			break;
857dd7cddfSDavid du Colombier 		}
867dd7cddfSDavid du Colombier 		if(l->complex >= r->complex) {
877dd7cddfSDavid du Colombier 			reglcgen(&nod1, l, Z);
887dd7cddfSDavid du Colombier 			if(r->addable >= INDEXED) {
897dd7cddfSDavid du Colombier 				gmove(r, &nod1);
907dd7cddfSDavid du Colombier 				if(nn != Z)
917dd7cddfSDavid du Colombier 					gmove(r, nn);
927dd7cddfSDavid du Colombier 				regfree(&nod1);
937dd7cddfSDavid du Colombier 				break;
947dd7cddfSDavid du Colombier 			}
957dd7cddfSDavid du Colombier 			regalloc(&nod, r, nn);
967dd7cddfSDavid du Colombier 			cgen(r, &nod);
977dd7cddfSDavid du Colombier 		} else {
987dd7cddfSDavid du Colombier 			regalloc(&nod, r, nn);
997dd7cddfSDavid du Colombier 			cgen(r, &nod);
1007dd7cddfSDavid du Colombier 			reglcgen(&nod1, l, Z);
1017dd7cddfSDavid du Colombier 		}
1027dd7cddfSDavid du Colombier 		gmove(&nod, &nod1);
1037dd7cddfSDavid du Colombier 		regfree(&nod);
1047dd7cddfSDavid du Colombier 		regfree(&nod1);
1057dd7cddfSDavid du Colombier 		break;
1067dd7cddfSDavid du Colombier 
1077dd7cddfSDavid du Colombier 	bitas:
1087dd7cddfSDavid du Colombier 		n = l->left;
1097dd7cddfSDavid du Colombier 		regalloc(&nod, r, nn);
1107dd7cddfSDavid du Colombier 		if(l->complex >= r->complex) {
1117dd7cddfSDavid du Colombier 			reglcgen(&nod1, n, Z);
1127dd7cddfSDavid du Colombier 			cgen(r, &nod);
1137dd7cddfSDavid du Colombier 		} else {
1147dd7cddfSDavid du Colombier 			cgen(r, &nod);
1157dd7cddfSDavid du Colombier 			reglcgen(&nod1, n, Z);
1167dd7cddfSDavid du Colombier 		}
1177dd7cddfSDavid du Colombier 		regalloc(&nod2, n, Z);
1187dd7cddfSDavid du Colombier 		gopcode(OAS, &nod1, Z, &nod2);
1197dd7cddfSDavid du Colombier 		bitstore(l, &nod, &nod1, &nod2, nn);
1207dd7cddfSDavid du Colombier 		break;
1217dd7cddfSDavid du Colombier 
1227dd7cddfSDavid du Colombier 	case OBIT:
1237dd7cddfSDavid du Colombier 		if(nn == Z) {
1247dd7cddfSDavid du Colombier 			nullwarn(l, Z);
1257dd7cddfSDavid du Colombier 			break;
1267dd7cddfSDavid du Colombier 		}
1277dd7cddfSDavid du Colombier 		bitload(n, &nod, Z, Z, nn);
1287dd7cddfSDavid du Colombier 		gopcode(OAS, &nod, Z, nn);
1297dd7cddfSDavid du Colombier 		regfree(&nod);
1307dd7cddfSDavid du Colombier 		break;
1317dd7cddfSDavid du Colombier 
1327dd7cddfSDavid du Colombier 	case OXOR:
1337dd7cddfSDavid du Colombier 		if(nn != Z)
1347dd7cddfSDavid du Colombier 		if(r->op == OCONST && r->vconst == -1){
1357dd7cddfSDavid du Colombier 			cgen(l, nn);
1367dd7cddfSDavid du Colombier 			gopcode(OCOM, nn, Z, nn);
1377dd7cddfSDavid du Colombier 			break;
1387dd7cddfSDavid du Colombier 		}
1397dd7cddfSDavid du Colombier 
1407dd7cddfSDavid du Colombier 	case OADD:
1417dd7cddfSDavid du Colombier 	case OSUB:
1427dd7cddfSDavid du Colombier 	case OAND:
1437dd7cddfSDavid du Colombier 	case OOR:
1447dd7cddfSDavid du Colombier 	case OLSHR:
1457dd7cddfSDavid du Colombier 	case OASHL:
1467dd7cddfSDavid du Colombier 	case OASHR:
1477dd7cddfSDavid du Colombier 		/*
1487dd7cddfSDavid du Colombier 		 * immediate operands
1497dd7cddfSDavid du Colombier 		 */
1507dd7cddfSDavid du Colombier 		if(nn != Z)
1517dd7cddfSDavid du Colombier 		if(r->op == OCONST)
1527dd7cddfSDavid du Colombier 		if(!typefd[n->type->etype]) {
1537dd7cddfSDavid du Colombier 			cgen(l, nn);
1547dd7cddfSDavid du Colombier 			if(r->vconst == 0)
1557dd7cddfSDavid du Colombier 			if(o != OAND)
1567dd7cddfSDavid du Colombier 				break;
1577dd7cddfSDavid du Colombier 			if(nn != Z)
1587dd7cddfSDavid du Colombier 				gopcode(o, r, Z, nn);
1597dd7cddfSDavid du Colombier 			break;
1607dd7cddfSDavid du Colombier 		}
1617dd7cddfSDavid du Colombier 
1627dd7cddfSDavid du Colombier 	case OMUL:
1637dd7cddfSDavid du Colombier 	case OLMUL:
1647dd7cddfSDavid du Colombier 	case OLDIV:
1657dd7cddfSDavid du Colombier 	case OLMOD:
1667dd7cddfSDavid du Colombier 	case ODIV:
1677dd7cddfSDavid du Colombier 	case OMOD:
1687dd7cddfSDavid du Colombier 		if(nn == Z) {
1697dd7cddfSDavid du Colombier 			nullwarn(l, r);
1707dd7cddfSDavid du Colombier 			break;
1717dd7cddfSDavid du Colombier 		}
1727dd7cddfSDavid du Colombier 		if(o == OMUL || o == OLMUL) {
1737dd7cddfSDavid du Colombier 			if(mulcon(n, nn))
1747dd7cddfSDavid du Colombier 				break;
1757dd7cddfSDavid du Colombier 			if(debug['M'])
1767dd7cddfSDavid du Colombier 				print("%L multiply\n", n->lineno);
1777dd7cddfSDavid du Colombier 		}
1787dd7cddfSDavid du Colombier 		if(l->complex >= r->complex) {
1797dd7cddfSDavid du Colombier 			regalloc(&nod, l, nn);
1807dd7cddfSDavid du Colombier 			cgen(l, &nod);
1817dd7cddfSDavid du Colombier 			regalloc(&nod1, r, Z);
1827dd7cddfSDavid du Colombier 			cgen(r, &nod1);
1837dd7cddfSDavid du Colombier 			gopcode(o, &nod1, Z, &nod);
1847dd7cddfSDavid du Colombier 		} else {
1857dd7cddfSDavid du Colombier 			regalloc(&nod, r, nn);
1867dd7cddfSDavid du Colombier 			cgen(r, &nod);
1877dd7cddfSDavid du Colombier 			regalloc(&nod1, l, Z);
1887dd7cddfSDavid du Colombier 			cgen(l, &nod1);
1897dd7cddfSDavid du Colombier 			gopcode(o, &nod, &nod1, &nod);
1907dd7cddfSDavid du Colombier 		}
1917dd7cddfSDavid du Colombier 		gopcode(OAS, &nod, Z, nn);
1927dd7cddfSDavid du Colombier 		regfree(&nod);
1937dd7cddfSDavid du Colombier 		regfree(&nod1);
1947dd7cddfSDavid du Colombier 		break;
1957dd7cddfSDavid du Colombier 
1967dd7cddfSDavid du Colombier 	case OASLSHR:
1977dd7cddfSDavid du Colombier 	case OASASHL:
1987dd7cddfSDavid du Colombier 	case OASASHR:
1997dd7cddfSDavid du Colombier 	case OASAND:
2007dd7cddfSDavid du Colombier 	case OASADD:
2017dd7cddfSDavid du Colombier 	case OASSUB:
2027dd7cddfSDavid du Colombier 	case OASXOR:
2037dd7cddfSDavid du Colombier 	case OASOR:
2047dd7cddfSDavid du Colombier 		if(l->op == OBIT)
2057dd7cddfSDavid du Colombier 			goto asbitop;
2067dd7cddfSDavid du Colombier 		if(r->op == OCONST)
207fc375d71SDavid du Colombier 		if(!typefd[r->type->etype])
2087dd7cddfSDavid du Colombier 		if(!typefd[n->type->etype]) {
2097dd7cddfSDavid du Colombier 			if(l->addable < INDEXED)
2107dd7cddfSDavid du Colombier 				reglcgen(&nod2, l, Z);
2117dd7cddfSDavid du Colombier 			else
2127dd7cddfSDavid du Colombier 				nod2 = *l;
2137dd7cddfSDavid du Colombier 			regalloc(&nod, r, nn);
2147dd7cddfSDavid du Colombier 			gopcode(OAS, &nod2, Z, &nod);
2157dd7cddfSDavid du Colombier 			gopcode(o, r, Z, &nod);
2167dd7cddfSDavid du Colombier 			gopcode(OAS, &nod, Z, &nod2);
2177dd7cddfSDavid du Colombier 
2187dd7cddfSDavid du Colombier 			regfree(&nod);
2197dd7cddfSDavid du Colombier 			if(l->addable < INDEXED)
2207dd7cddfSDavid du Colombier 				regfree(&nod2);
2217dd7cddfSDavid du Colombier 			break;
2227dd7cddfSDavid du Colombier 		}
2237dd7cddfSDavid du Colombier 
2247dd7cddfSDavid du Colombier 	case OASLMUL:
2257dd7cddfSDavid du Colombier 	case OASLDIV:
2267dd7cddfSDavid du Colombier 	case OASLMOD:
2277dd7cddfSDavid du Colombier 	case OASMUL:
2287dd7cddfSDavid du Colombier 	case OASDIV:
2297dd7cddfSDavid du Colombier 	case OASMOD:
2307dd7cddfSDavid du Colombier 		if(l->op == OBIT)
2317dd7cddfSDavid du Colombier 			goto asbitop;
2327dd7cddfSDavid du Colombier 		if(l->complex >= r->complex) {
2337dd7cddfSDavid du Colombier 			if(l->addable < INDEXED)
2347dd7cddfSDavid du Colombier 				reglcgen(&nod2, l, Z);
2357dd7cddfSDavid du Colombier 			else
2367dd7cddfSDavid du Colombier 				nod2 = *l;
2377dd7cddfSDavid du Colombier 			regalloc(&nod, n, nn);
2387dd7cddfSDavid du Colombier 			cgen(r, &nod);
2397dd7cddfSDavid du Colombier 		} else {
2407dd7cddfSDavid du Colombier 			regalloc(&nod, n, nn);
2417dd7cddfSDavid du Colombier 			cgen(r, &nod);
2427dd7cddfSDavid du Colombier 			if(l->addable < INDEXED)
2437dd7cddfSDavid du Colombier 				reglcgen(&nod2, l, Z);
2447dd7cddfSDavid du Colombier 			else
2457dd7cddfSDavid du Colombier 				nod2 = *l;
2467dd7cddfSDavid du Colombier 		}
2477dd7cddfSDavid du Colombier 		regalloc(&nod1, n, Z);
2487dd7cddfSDavid du Colombier 		gopcode(OAS, &nod2, Z, &nod1);
2497dd7cddfSDavid du Colombier 		gopcode(o, &nod, &nod1, &nod);
2507dd7cddfSDavid du Colombier 		gopcode(OAS, &nod, Z, &nod2);
2517dd7cddfSDavid du Colombier 		regfree(&nod);
2527dd7cddfSDavid du Colombier 		regfree(&nod1);
2537dd7cddfSDavid du Colombier 		if(l->addable < INDEXED)
2547dd7cddfSDavid du Colombier 			regfree(&nod2);
2557dd7cddfSDavid du Colombier 		break;
2567dd7cddfSDavid du Colombier 
2577dd7cddfSDavid du Colombier 	asbitop:
2587dd7cddfSDavid du Colombier 		regalloc(&nod4, n, nn);
2597dd7cddfSDavid du Colombier 		regalloc(&nod3, r, Z);
2607dd7cddfSDavid du Colombier 		if(l->complex >= r->complex) {
2617dd7cddfSDavid du Colombier 			bitload(l, &nod, &nod1, &nod2, &nod4);
2627dd7cddfSDavid du Colombier 			cgen(r, &nod3);
2637dd7cddfSDavid du Colombier 		} else {
2647dd7cddfSDavid du Colombier 			cgen(r, &nod3);
2657dd7cddfSDavid du Colombier 			bitload(l, &nod, &nod1, &nod2, &nod4);
2667dd7cddfSDavid du Colombier 		}
2677dd7cddfSDavid du Colombier 		gmove(&nod, &nod4);
2687dd7cddfSDavid du Colombier 		gopcode(n->op, &nod3, Z, &nod4);
2697dd7cddfSDavid du Colombier 		regfree(&nod3);
2707dd7cddfSDavid du Colombier 		gmove(&nod4, &nod);
2717dd7cddfSDavid du Colombier 		regfree(&nod4);
2727dd7cddfSDavid du Colombier 		bitstore(l, &nod, &nod1, &nod2, nn);
2737dd7cddfSDavid du Colombier 		break;
2747dd7cddfSDavid du Colombier 
2757dd7cddfSDavid du Colombier 	case OADDR:
2767dd7cddfSDavid du Colombier 		if(nn == Z) {
2777dd7cddfSDavid du Colombier 			nullwarn(l, Z);
2787dd7cddfSDavid du Colombier 			break;
2797dd7cddfSDavid du Colombier 		}
2807dd7cddfSDavid du Colombier 		lcgen(l, nn);
2817dd7cddfSDavid du Colombier 		break;
2827dd7cddfSDavid du Colombier 
2837dd7cddfSDavid du Colombier 	case OFUNC:
2847dd7cddfSDavid du Colombier 		if(l->complex >= FNX) {
2857dd7cddfSDavid du Colombier 			if(l->op != OIND)
2867dd7cddfSDavid du Colombier 				diag(n, "bad function call");
2877dd7cddfSDavid du Colombier 
2887dd7cddfSDavid du Colombier 			regret(&nod, l->left);
2897dd7cddfSDavid du Colombier 			cgen(l->left, &nod);
2907dd7cddfSDavid du Colombier 			regsalloc(&nod1, l->left);
2917dd7cddfSDavid du Colombier 			gopcode(OAS, &nod, Z, &nod1);
2927dd7cddfSDavid du Colombier 			regfree(&nod);
2937dd7cddfSDavid du Colombier 
2947dd7cddfSDavid du Colombier 			nod = *n;
2957dd7cddfSDavid du Colombier 			nod.left = &nod2;
2967dd7cddfSDavid du Colombier 			nod2 = *l;
2977dd7cddfSDavid du Colombier 			nod2.left = &nod1;
2987dd7cddfSDavid du Colombier 			nod2.complex = 1;
2997dd7cddfSDavid du Colombier 			cgen(&nod, nn);
3007dd7cddfSDavid du Colombier 
3017dd7cddfSDavid du Colombier 			return;
3027dd7cddfSDavid du Colombier 		}
3037dd7cddfSDavid du Colombier 		o = reg[REGARG];
3047dd7cddfSDavid du Colombier 		gargs(r, &nod, &nod1);
3057dd7cddfSDavid du Colombier 		if(l->addable < INDEXED) {
3067dd7cddfSDavid du Colombier 			reglcgen(&nod, l, Z);
3077dd7cddfSDavid du Colombier 			gopcode(OFUNC, Z, Z, &nod);
3087dd7cddfSDavid du Colombier 			regfree(&nod);
3097dd7cddfSDavid du Colombier 		} else
3107dd7cddfSDavid du Colombier 			gopcode(OFUNC, Z, Z, l);
3117dd7cddfSDavid du Colombier 		if(REGARG)
3127dd7cddfSDavid du Colombier 			if(o != reg[REGARG])
3137dd7cddfSDavid du Colombier 				reg[REGARG]--;
3147dd7cddfSDavid du Colombier 		if(nn != Z) {
3157dd7cddfSDavid du Colombier 			regret(&nod, n);
3167dd7cddfSDavid du Colombier 			gopcode(OAS, &nod, Z, nn);
3177dd7cddfSDavid du Colombier 			regfree(&nod);
3187dd7cddfSDavid du Colombier 		}
3197dd7cddfSDavid du Colombier 		break;
3207dd7cddfSDavid du Colombier 
3217dd7cddfSDavid du Colombier 	case OIND:
3227dd7cddfSDavid du Colombier 		if(nn == Z) {
3237dd7cddfSDavid du Colombier 			cgen(l, nn);
3247dd7cddfSDavid du Colombier 			break;
3257dd7cddfSDavid du Colombier 		}
3267dd7cddfSDavid du Colombier 		regialloc(&nod, n, nn);
3277dd7cddfSDavid du Colombier 		r = l;
3287dd7cddfSDavid du Colombier 		while(r->op == OADD)
3297dd7cddfSDavid du Colombier 			r = r->right;
3307dd7cddfSDavid du Colombier 		if(sconst(r)) {
3317dd7cddfSDavid du Colombier 			v = r->vconst;
3327dd7cddfSDavid du Colombier 			r->vconst = 0;
3337dd7cddfSDavid du Colombier 			cgen(l, &nod);
3347dd7cddfSDavid du Colombier 			nod.xoffset += v;
3357dd7cddfSDavid du Colombier 			r->vconst = v;
3367dd7cddfSDavid du Colombier 		} else
3377dd7cddfSDavid du Colombier 			cgen(l, &nod);
3387dd7cddfSDavid du Colombier 		regind(&nod, n);
3397dd7cddfSDavid du Colombier 		gopcode(OAS, &nod, Z, nn);
3407dd7cddfSDavid du Colombier 		regfree(&nod);
3417dd7cddfSDavid du Colombier 		break;
3427dd7cddfSDavid du Colombier 
3437dd7cddfSDavid du Colombier 	case OEQ:
3447dd7cddfSDavid du Colombier 	case ONE:
3457dd7cddfSDavid du Colombier 	case OLE:
3467dd7cddfSDavid du Colombier 	case OLT:
3477dd7cddfSDavid du Colombier 	case OGE:
3487dd7cddfSDavid du Colombier 	case OGT:
3497dd7cddfSDavid du Colombier 	case OLO:
3507dd7cddfSDavid du Colombier 	case OLS:
3517dd7cddfSDavid du Colombier 	case OHI:
3527dd7cddfSDavid du Colombier 	case OHS:
3537dd7cddfSDavid du Colombier 		if(nn == Z) {
3547dd7cddfSDavid du Colombier 			nullwarn(l, r);
3557dd7cddfSDavid du Colombier 			break;
3567dd7cddfSDavid du Colombier 		}
3577dd7cddfSDavid du Colombier 		boolgen(n, 1, nn);
3587dd7cddfSDavid du Colombier 		break;
3597dd7cddfSDavid du Colombier 
3607dd7cddfSDavid du Colombier 	case OANDAND:
3617dd7cddfSDavid du Colombier 	case OOROR:
3627dd7cddfSDavid du Colombier 		boolgen(n, 1, nn);
3637dd7cddfSDavid du Colombier 		if(nn == Z)
3647dd7cddfSDavid du Colombier 			patch(p, pc);
3657dd7cddfSDavid du Colombier 		break;
3667dd7cddfSDavid du Colombier 
3677dd7cddfSDavid du Colombier 	case ONOT:
3687dd7cddfSDavid du Colombier 		if(nn == Z) {
3697dd7cddfSDavid du Colombier 			nullwarn(l, Z);
3707dd7cddfSDavid du Colombier 			break;
3717dd7cddfSDavid du Colombier 		}
3727dd7cddfSDavid du Colombier 		boolgen(n, 1, nn);
3737dd7cddfSDavid du Colombier 		break;
3747dd7cddfSDavid du Colombier 
3757dd7cddfSDavid du Colombier 	case OCOMMA:
3767dd7cddfSDavid du Colombier 		cgen(l, Z);
3777dd7cddfSDavid du Colombier 		cgen(r, nn);
3787dd7cddfSDavid du Colombier 		break;
3797dd7cddfSDavid du Colombier 
3807dd7cddfSDavid du Colombier 	case OCAST:
3817dd7cddfSDavid du Colombier 		if(nn == Z) {
3827dd7cddfSDavid du Colombier 			nullwarn(l, Z);
3837dd7cddfSDavid du Colombier 			break;
3847dd7cddfSDavid du Colombier 		}
3857dd7cddfSDavid du Colombier 		/*
3867dd7cddfSDavid du Colombier 		 * convert from types l->n->nn
3877dd7cddfSDavid du Colombier 		 */
3887dd7cddfSDavid du Colombier 		if(nocast(l->type, n->type) && nocast(n->type, nn->type)) {
3897dd7cddfSDavid du Colombier 			/* both null, gen l->nn */
3907dd7cddfSDavid du Colombier 			cgen(l, nn);
3917dd7cddfSDavid du Colombier 			break;
3927dd7cddfSDavid du Colombier 		}
3937dd7cddfSDavid du Colombier 		regalloc(&nod, l, nn);
3947dd7cddfSDavid du Colombier 		cgen(l, &nod);
3957dd7cddfSDavid du Colombier 		regalloc(&nod1, n, &nod);
3967dd7cddfSDavid du Colombier 		gopcode(OAS, &nod, Z, &nod1);
3977dd7cddfSDavid du Colombier 		gopcode(OAS, &nod1, Z, nn);
3987dd7cddfSDavid du Colombier 		regfree(&nod1);
3997dd7cddfSDavid du Colombier 		regfree(&nod);
4007dd7cddfSDavid du Colombier 		break;
4017dd7cddfSDavid du Colombier 
4027dd7cddfSDavid du Colombier 	case ODOT:
4037dd7cddfSDavid du Colombier 		sugen(l, nodrat, l->type->width);
4047dd7cddfSDavid du Colombier 		if(nn != Z) {
4057dd7cddfSDavid du Colombier 			warn(n, "non-interruptable temporary");
4067dd7cddfSDavid du Colombier 			nod = *nodrat;
4077dd7cddfSDavid du Colombier 			if(!r || r->op != OCONST) {
4087dd7cddfSDavid du Colombier 				diag(n, "DOT and no offset");
4097dd7cddfSDavid du Colombier 				break;
4107dd7cddfSDavid du Colombier 			}
4117dd7cddfSDavid du Colombier 			nod.xoffset += (long)r->vconst;
4127dd7cddfSDavid du Colombier 			nod.type = n->type;
4137dd7cddfSDavid du Colombier 			cgen(&nod, nn);
4147dd7cddfSDavid du Colombier 		}
4157dd7cddfSDavid du Colombier 		break;
4167dd7cddfSDavid du Colombier 
4177dd7cddfSDavid du Colombier 	case OCOND:
4187dd7cddfSDavid du Colombier 		bcgen(l, 1);
4197dd7cddfSDavid du Colombier 		p1 = p;
4207dd7cddfSDavid du Colombier 		cgen(r->left, nn);
4217dd7cddfSDavid du Colombier 		gbranch(OGOTO);
4227dd7cddfSDavid du Colombier 		patch(p1, pc);
4237dd7cddfSDavid du Colombier 		p1 = p;
4247dd7cddfSDavid du Colombier 		cgen(r->right, nn);
4257dd7cddfSDavid du Colombier 		patch(p1, pc);
4267dd7cddfSDavid du Colombier 		break;
4277dd7cddfSDavid du Colombier 
4287dd7cddfSDavid du Colombier 	case OPOSTINC:
4297dd7cddfSDavid du Colombier 	case OPOSTDEC:
4307dd7cddfSDavid du Colombier 		v = 1;
4317dd7cddfSDavid du Colombier 		if(l->type->etype == TIND)
4327dd7cddfSDavid du Colombier 			v = l->type->link->width;
4337dd7cddfSDavid du Colombier 		if(o == OPOSTDEC)
4347dd7cddfSDavid du Colombier 			v = -v;
4357dd7cddfSDavid du Colombier 		if(l->op == OBIT)
4367dd7cddfSDavid du Colombier 			goto bitinc;
4377dd7cddfSDavid du Colombier 		if(nn == Z)
4387dd7cddfSDavid du Colombier 			goto pre;
4397dd7cddfSDavid du Colombier 
4407dd7cddfSDavid du Colombier 		if(l->addable < INDEXED)
4417dd7cddfSDavid du Colombier 			reglcgen(&nod2, l, Z);
4427dd7cddfSDavid du Colombier 		else
4437dd7cddfSDavid du Colombier 			nod2 = *l;
4447dd7cddfSDavid du Colombier 
4457dd7cddfSDavid du Colombier 		regalloc(&nod, l, nn);
4467dd7cddfSDavid du Colombier 		gopcode(OAS, &nod2, Z, &nod);
4477dd7cddfSDavid du Colombier 		regalloc(&nod1, l, Z);
4487dd7cddfSDavid du Colombier 		if(typefd[l->type->etype]) {
4497dd7cddfSDavid du Colombier 			regalloc(&nod3, l, Z);
4507dd7cddfSDavid du Colombier 			if(v < 0) {
4517dd7cddfSDavid du Colombier 				gopcode(OAS, nodfconst(-v), Z, &nod3);
4527dd7cddfSDavid du Colombier 				gopcode(OSUB, &nod3, &nod, &nod1);
4537dd7cddfSDavid du Colombier 			} else {
4547dd7cddfSDavid du Colombier 				gopcode(OAS, nodfconst(v), Z, &nod3);
4557dd7cddfSDavid du Colombier 				gopcode(OADD, &nod3, &nod, &nod1);
4567dd7cddfSDavid du Colombier 			}
4577dd7cddfSDavid du Colombier 			regfree(&nod3);
4587dd7cddfSDavid du Colombier 		} else
4597dd7cddfSDavid du Colombier 			gopcode(OADD, nodconst(v), &nod, &nod1);
4607dd7cddfSDavid du Colombier 		gopcode(OAS, &nod1, Z, &nod2);
4617dd7cddfSDavid du Colombier 
4627dd7cddfSDavid du Colombier 		regfree(&nod);
4637dd7cddfSDavid du Colombier 		regfree(&nod1);
4647dd7cddfSDavid du Colombier 		if(l->addable < INDEXED)
4657dd7cddfSDavid du Colombier 			regfree(&nod2);
4667dd7cddfSDavid du Colombier 		break;
4677dd7cddfSDavid du Colombier 
4687dd7cddfSDavid du Colombier 	case OPREINC:
4697dd7cddfSDavid du Colombier 	case OPREDEC:
4707dd7cddfSDavid du Colombier 		v = 1;
4717dd7cddfSDavid du Colombier 		if(l->type->etype == TIND)
4727dd7cddfSDavid du Colombier 			v = l->type->link->width;
4737dd7cddfSDavid du Colombier 		if(o == OPREDEC)
4747dd7cddfSDavid du Colombier 			v = -v;
4757dd7cddfSDavid du Colombier 		if(l->op == OBIT)
4767dd7cddfSDavid du Colombier 			goto bitinc;
4777dd7cddfSDavid du Colombier 
4787dd7cddfSDavid du Colombier 	pre:
4797dd7cddfSDavid du Colombier 		if(l->addable < INDEXED)
4807dd7cddfSDavid du Colombier 			reglcgen(&nod2, l, Z);
4817dd7cddfSDavid du Colombier 		else
4827dd7cddfSDavid du Colombier 			nod2 = *l;
4837dd7cddfSDavid du Colombier 
4847dd7cddfSDavid du Colombier 		regalloc(&nod, l, nn);
4857dd7cddfSDavid du Colombier 		gopcode(OAS, &nod2, Z, &nod);
4867dd7cddfSDavid du Colombier 		if(typefd[l->type->etype]) {
4877dd7cddfSDavid du Colombier 			regalloc(&nod3, l, Z);
4887dd7cddfSDavid du Colombier 			if(v < 0) {
4897dd7cddfSDavid du Colombier 				gopcode(OAS, nodfconst(-v), Z, &nod3);
4907dd7cddfSDavid du Colombier 				gopcode(OSUB, &nod3, Z, &nod);
4917dd7cddfSDavid du Colombier 			} else {
4927dd7cddfSDavid du Colombier 				gopcode(OAS, nodfconst(v), Z, &nod3);
4937dd7cddfSDavid du Colombier 				gopcode(OADD, &nod3, Z, &nod);
4947dd7cddfSDavid du Colombier 			}
4957dd7cddfSDavid du Colombier 			regfree(&nod3);
4967dd7cddfSDavid du Colombier 		} else
4977dd7cddfSDavid du Colombier 			gopcode(OADD, nodconst(v), Z, &nod);
4987dd7cddfSDavid du Colombier 		gopcode(OAS, &nod, Z, &nod2);
499*4ac975e2SDavid du Colombier 		if(nn && l->op == ONAME)	/* in x=++i, emit USED(i) */
500*4ac975e2SDavid du Colombier 			gins(ANOP, l, Z);
5017dd7cddfSDavid du Colombier 
5027dd7cddfSDavid du Colombier 		regfree(&nod);
5037dd7cddfSDavid du Colombier 		if(l->addable < INDEXED)
5047dd7cddfSDavid du Colombier 			regfree(&nod2);
5057dd7cddfSDavid du Colombier 		break;
5067dd7cddfSDavid du Colombier 
5077dd7cddfSDavid du Colombier 	bitinc:
5087dd7cddfSDavid du Colombier 		if(nn != Z && (o == OPOSTINC || o == OPOSTDEC)) {
5097dd7cddfSDavid du Colombier 			bitload(l, &nod, &nod1, &nod2, Z);
5107dd7cddfSDavid du Colombier 			gopcode(OAS, &nod, Z, nn);
5117dd7cddfSDavid du Colombier 			gopcode(OADD, nodconst(v), Z, &nod);
5127dd7cddfSDavid du Colombier 			bitstore(l, &nod, &nod1, &nod2, Z);
5137dd7cddfSDavid du Colombier 			break;
5147dd7cddfSDavid du Colombier 		}
5157dd7cddfSDavid du Colombier 		bitload(l, &nod, &nod1, &nod2, nn);
5167dd7cddfSDavid du Colombier 		gopcode(OADD, nodconst(v), Z, &nod);
5177dd7cddfSDavid du Colombier 		bitstore(l, &nod, &nod1, &nod2, nn);
5187dd7cddfSDavid du Colombier 		break;
5197dd7cddfSDavid du Colombier 	}
5207dd7cddfSDavid du Colombier 	cursafe = curs;
5217dd7cddfSDavid du Colombier }
5227dd7cddfSDavid du Colombier 
5237dd7cddfSDavid du Colombier void
5247dd7cddfSDavid du Colombier reglcgen(Node *t, Node *n, Node *nn)
5257dd7cddfSDavid du Colombier {
5267dd7cddfSDavid du Colombier 	Node *r;
5277dd7cddfSDavid du Colombier 	long v;
5287dd7cddfSDavid du Colombier 
5297dd7cddfSDavid du Colombier 	regialloc(t, n, nn);
5307dd7cddfSDavid du Colombier 	if(n->op == OIND) {
5317dd7cddfSDavid du Colombier 		r = n->left;
5327dd7cddfSDavid du Colombier 		while(r->op == OADD)
5337dd7cddfSDavid du Colombier 			r = r->right;
5347dd7cddfSDavid du Colombier 		if(sconst(r)) {
5357dd7cddfSDavid du Colombier 			v = r->vconst;
5367dd7cddfSDavid du Colombier 			r->vconst = 0;
5377dd7cddfSDavid du Colombier 			lcgen(n, t);
5387dd7cddfSDavid du Colombier 			t->xoffset += v;
5397dd7cddfSDavid du Colombier 			r->vconst = v;
5407dd7cddfSDavid du Colombier 			regind(t, n);
5417dd7cddfSDavid du Colombier 			return;
5427dd7cddfSDavid du Colombier 		}
5437dd7cddfSDavid du Colombier 	}
5447dd7cddfSDavid du Colombier 	lcgen(n, t);
5457dd7cddfSDavid du Colombier 	regind(t, n);
5467dd7cddfSDavid du Colombier }
5477dd7cddfSDavid du Colombier 
5487dd7cddfSDavid du Colombier void
5497dd7cddfSDavid du Colombier lcgen(Node *n, Node *nn)
5507dd7cddfSDavid du Colombier {
5517dd7cddfSDavid du Colombier 	Prog *p1;
5527dd7cddfSDavid du Colombier 	Node nod;
5537dd7cddfSDavid du Colombier 
5547dd7cddfSDavid du Colombier 	if(debug['g']) {
5557dd7cddfSDavid du Colombier 		prtree(nn, "lcgen lhs");
5567dd7cddfSDavid du Colombier 		prtree(n, "lcgen");
5577dd7cddfSDavid du Colombier 	}
5587dd7cddfSDavid du Colombier 	if(n == Z || n->type == T)
5597dd7cddfSDavid du Colombier 		return;
5607dd7cddfSDavid du Colombier 	if(nn == Z) {
5617dd7cddfSDavid du Colombier 		nn = &nod;
5627dd7cddfSDavid du Colombier 		regalloc(&nod, n, Z);
5637dd7cddfSDavid du Colombier 	}
5647dd7cddfSDavid du Colombier 	switch(n->op) {
5657dd7cddfSDavid du Colombier 	default:
5667dd7cddfSDavid du Colombier 		if(n->addable < INDEXED) {
5677dd7cddfSDavid du Colombier 			diag(n, "unknown op in lcgen: %O", n->op);
5687dd7cddfSDavid du Colombier 			break;
5697dd7cddfSDavid du Colombier 		}
5707dd7cddfSDavid du Colombier 		nod = *n;
5717dd7cddfSDavid du Colombier 		nod.op = OADDR;
5727dd7cddfSDavid du Colombier 		nod.left = n;
5737dd7cddfSDavid du Colombier 		nod.right = Z;
5747dd7cddfSDavid du Colombier 		nod.type = types[TIND];
5757dd7cddfSDavid du Colombier 		gopcode(OAS, &nod, Z, nn);
5767dd7cddfSDavid du Colombier 		break;
5777dd7cddfSDavid du Colombier 
5787dd7cddfSDavid du Colombier 	case OCOMMA:
5797dd7cddfSDavid du Colombier 		cgen(n->left, n->left);
5807dd7cddfSDavid du Colombier 		lcgen(n->right, nn);
5817dd7cddfSDavid du Colombier 		break;
5827dd7cddfSDavid du Colombier 
5837dd7cddfSDavid du Colombier 	case OIND:
5847dd7cddfSDavid du Colombier 		cgen(n->left, nn);
5857dd7cddfSDavid du Colombier 		break;
5867dd7cddfSDavid du Colombier 
5877dd7cddfSDavid du Colombier 	case OCOND:
5887dd7cddfSDavid du Colombier 		bcgen(n->left, 1);
5897dd7cddfSDavid du Colombier 		p1 = p;
5907dd7cddfSDavid du Colombier 		lcgen(n->right->left, nn);
5917dd7cddfSDavid du Colombier 		gbranch(OGOTO);
5927dd7cddfSDavid du Colombier 		patch(p1, pc);
5937dd7cddfSDavid du Colombier 		p1 = p;
5947dd7cddfSDavid du Colombier 		lcgen(n->right->right, nn);
5957dd7cddfSDavid du Colombier 		patch(p1, pc);
5967dd7cddfSDavid du Colombier 		break;
5977dd7cddfSDavid du Colombier 	}
5987dd7cddfSDavid du Colombier }
5997dd7cddfSDavid du Colombier 
6007dd7cddfSDavid du Colombier void
6017dd7cddfSDavid du Colombier bcgen(Node *n, int true)
6027dd7cddfSDavid du Colombier {
6037dd7cddfSDavid du Colombier 
6047dd7cddfSDavid du Colombier 	if(n->type == T)
6057dd7cddfSDavid du Colombier 		gbranch(OGOTO);
6067dd7cddfSDavid du Colombier 	else
6077dd7cddfSDavid du Colombier 		boolgen(n, true, Z);
6087dd7cddfSDavid du Colombier }
6097dd7cddfSDavid du Colombier 
6107dd7cddfSDavid du Colombier void
6117dd7cddfSDavid du Colombier boolgen(Node *n, int true, Node *nn)
6127dd7cddfSDavid du Colombier {
6137dd7cddfSDavid du Colombier 	int o;
6147dd7cddfSDavid du Colombier 	Prog *p1, *p2;
6157dd7cddfSDavid du Colombier 	Node *l, *r, nod, nod1;
6167dd7cddfSDavid du Colombier 	long curs;
6177dd7cddfSDavid du Colombier 
6187dd7cddfSDavid du Colombier 	if(debug['g']) {
6197dd7cddfSDavid du Colombier 		prtree(nn, "boolgen lhs");
6207dd7cddfSDavid du Colombier 		prtree(n, "boolgen");
6217dd7cddfSDavid du Colombier 	}
6227dd7cddfSDavid du Colombier 	curs = cursafe;
6237dd7cddfSDavid du Colombier 	l = n->left;
6247dd7cddfSDavid du Colombier 	r = n->right;
6257dd7cddfSDavid du Colombier 	switch(n->op) {
6267dd7cddfSDavid du Colombier 
6277dd7cddfSDavid du Colombier 	default:
6287dd7cddfSDavid du Colombier 		if(n->op == OCONST) {
6297dd7cddfSDavid du Colombier 			o = vconst(n);
6307dd7cddfSDavid du Colombier 			if(!true)
6317dd7cddfSDavid du Colombier 				o = !o;
6327dd7cddfSDavid du Colombier 			gbranch(OGOTO);
6337dd7cddfSDavid du Colombier 			if(o) {
6347dd7cddfSDavid du Colombier 				p1 = p;
6357dd7cddfSDavid du Colombier 				gbranch(OGOTO);
6367dd7cddfSDavid du Colombier 				patch(p1, pc);
6377dd7cddfSDavid du Colombier 			}
6387dd7cddfSDavid du Colombier 			goto com;
6397dd7cddfSDavid du Colombier 		}
6407dd7cddfSDavid du Colombier 		regalloc(&nod, n, nn);
6417dd7cddfSDavid du Colombier 		cgen(n, &nod);
6427dd7cddfSDavid du Colombier 		o = ONE;
6437dd7cddfSDavid du Colombier 		if(true)
6447dd7cddfSDavid du Colombier 			o = comrel[relindex(o)];
6457dd7cddfSDavid du Colombier 		if(typefd[n->type->etype]) {
6467dd7cddfSDavid du Colombier 			nodreg(&nod1, n, NREG+FREGZERO);
6477dd7cddfSDavid du Colombier 			gopcode(o, &nod, Z, &nod1);
6487dd7cddfSDavid du Colombier 		} else
6497dd7cddfSDavid du Colombier 			gopcode(o, &nod, Z, nodconst(0));
6507dd7cddfSDavid du Colombier 		regfree(&nod);
6517dd7cddfSDavid du Colombier 		goto com;
6527dd7cddfSDavid du Colombier 
6537dd7cddfSDavid du Colombier 	case OCOMMA:
6547dd7cddfSDavid du Colombier 		cgen(l, Z);
6557dd7cddfSDavid du Colombier 		boolgen(r, true, nn);
6567dd7cddfSDavid du Colombier 		break;
6577dd7cddfSDavid du Colombier 
6587dd7cddfSDavid du Colombier 	case ONOT:
6597dd7cddfSDavid du Colombier 		boolgen(l, !true, nn);
6607dd7cddfSDavid du Colombier 		break;
6617dd7cddfSDavid du Colombier 
6627dd7cddfSDavid du Colombier 	case OCOND:
6637dd7cddfSDavid du Colombier 		bcgen(l, 1);
6647dd7cddfSDavid du Colombier 		p1 = p;
6657dd7cddfSDavid du Colombier 		bcgen(r->left, true);
6667dd7cddfSDavid du Colombier 		p2 = p;
6677dd7cddfSDavid du Colombier 		gbranch(OGOTO);
6687dd7cddfSDavid du Colombier 		patch(p1, pc);
6697dd7cddfSDavid du Colombier 		p1 = p;
6707dd7cddfSDavid du Colombier 		bcgen(r->right, !true);
6717dd7cddfSDavid du Colombier 		patch(p2, pc);
6727dd7cddfSDavid du Colombier 		p2 = p;
6737dd7cddfSDavid du Colombier 		gbranch(OGOTO);
6747dd7cddfSDavid du Colombier 		patch(p1, pc);
6757dd7cddfSDavid du Colombier 		patch(p2, pc);
6767dd7cddfSDavid du Colombier 		goto com;
6777dd7cddfSDavid du Colombier 
6787dd7cddfSDavid du Colombier 	case OANDAND:
6797dd7cddfSDavid du Colombier 		if(!true)
6807dd7cddfSDavid du Colombier 			goto caseor;
6817dd7cddfSDavid du Colombier 
6827dd7cddfSDavid du Colombier 	caseand:
6837dd7cddfSDavid du Colombier 		bcgen(l, true);
6847dd7cddfSDavid du Colombier 		p1 = p;
6857dd7cddfSDavid du Colombier 		bcgen(r, !true);
6867dd7cddfSDavid du Colombier 		p2 = p;
6877dd7cddfSDavid du Colombier 		patch(p1, pc);
6887dd7cddfSDavid du Colombier 		gbranch(OGOTO);
6897dd7cddfSDavid du Colombier 		patch(p2, pc);
6907dd7cddfSDavid du Colombier 		goto com;
6917dd7cddfSDavid du Colombier 
6927dd7cddfSDavid du Colombier 	case OOROR:
6937dd7cddfSDavid du Colombier 		if(!true)
6947dd7cddfSDavid du Colombier 			goto caseand;
6957dd7cddfSDavid du Colombier 
6967dd7cddfSDavid du Colombier 	caseor:
6977dd7cddfSDavid du Colombier 		bcgen(l, !true);
6987dd7cddfSDavid du Colombier 		p1 = p;
6997dd7cddfSDavid du Colombier 		bcgen(r, !true);
7007dd7cddfSDavid du Colombier 		p2 = p;
7017dd7cddfSDavid du Colombier 		gbranch(OGOTO);
7027dd7cddfSDavid du Colombier 		patch(p1, pc);
7037dd7cddfSDavid du Colombier 		patch(p2, pc);
7047dd7cddfSDavid du Colombier 		goto com;
7057dd7cddfSDavid du Colombier 
7067dd7cddfSDavid du Colombier 	case OEQ:
7077dd7cddfSDavid du Colombier 	case ONE:
7087dd7cddfSDavid du Colombier 	case OLE:
7097dd7cddfSDavid du Colombier 	case OLT:
7107dd7cddfSDavid du Colombier 	case OGE:
7117dd7cddfSDavid du Colombier 	case OGT:
7127dd7cddfSDavid du Colombier 	case OHI:
7137dd7cddfSDavid du Colombier 	case OHS:
7147dd7cddfSDavid du Colombier 	case OLO:
7157dd7cddfSDavid du Colombier 	case OLS:
7167dd7cddfSDavid du Colombier 		o = n->op;
7177dd7cddfSDavid du Colombier 		if(true)
7187dd7cddfSDavid du Colombier 			o = comrel[relindex(o)];
7197dd7cddfSDavid du Colombier 		if(l->complex >= FNX && r->complex >= FNX) {
7207dd7cddfSDavid du Colombier 			regret(&nod, r);
7217dd7cddfSDavid du Colombier 			cgen(r, &nod);
7227dd7cddfSDavid du Colombier 			regsalloc(&nod1, r);
7237dd7cddfSDavid du Colombier 			gopcode(OAS, &nod, Z, &nod1);
7247dd7cddfSDavid du Colombier 			regfree(&nod);
7257dd7cddfSDavid du Colombier 			nod = *n;
7267dd7cddfSDavid du Colombier 			nod.right = &nod1;
7277dd7cddfSDavid du Colombier 			boolgen(&nod, true, nn);
7287dd7cddfSDavid du Colombier 			break;
7297dd7cddfSDavid du Colombier 		}
7307dd7cddfSDavid du Colombier 		if(sconst(r)) {
7317dd7cddfSDavid du Colombier 			regalloc(&nod, l, nn);
7327dd7cddfSDavid du Colombier 			cgen(l, &nod);
7337dd7cddfSDavid du Colombier 			gopcode(o, &nod, Z, r);
7347dd7cddfSDavid du Colombier 			regfree(&nod);
7357dd7cddfSDavid du Colombier 			goto com;
7367dd7cddfSDavid du Colombier 		}
7377dd7cddfSDavid du Colombier 		if(l->complex >= r->complex) {
7387dd7cddfSDavid du Colombier 			regalloc(&nod1, l, nn);
7397dd7cddfSDavid du Colombier 			cgen(l, &nod1);
7407dd7cddfSDavid du Colombier 			regalloc(&nod, r, Z);
7417dd7cddfSDavid du Colombier 			cgen(r, &nod);
7427dd7cddfSDavid du Colombier 		} else {
7437dd7cddfSDavid du Colombier 			regalloc(&nod, r, nn);
7447dd7cddfSDavid du Colombier 			cgen(r, &nod);
7457dd7cddfSDavid du Colombier 			regalloc(&nod1, l, Z);
7467dd7cddfSDavid du Colombier 			cgen(l, &nod1);
7477dd7cddfSDavid du Colombier 		}
7487dd7cddfSDavid du Colombier 		gopcode(o, &nod1, Z, &nod);
7497dd7cddfSDavid du Colombier 		regfree(&nod);
7507dd7cddfSDavid du Colombier 		regfree(&nod1);
7517dd7cddfSDavid du Colombier 
7527dd7cddfSDavid du Colombier 	com:
7537dd7cddfSDavid du Colombier 		if(nn != Z) {
7547dd7cddfSDavid du Colombier 			p1 = p;
7557dd7cddfSDavid du Colombier 			gopcode(OAS, nodconst(1L), Z, nn);
7567dd7cddfSDavid du Colombier 			gbranch(OGOTO);
7577dd7cddfSDavid du Colombier 			p2 = p;
7587dd7cddfSDavid du Colombier 			patch(p1, pc);
7597dd7cddfSDavid du Colombier 			gopcode(OAS, nodconst(0L), Z, nn);
7607dd7cddfSDavid du Colombier 			patch(p2, pc);
7617dd7cddfSDavid du Colombier 		}
7627dd7cddfSDavid du Colombier 		break;
7637dd7cddfSDavid du Colombier 	}
7647dd7cddfSDavid du Colombier 	cursafe = curs;
7657dd7cddfSDavid du Colombier }
7667dd7cddfSDavid du Colombier 
7677dd7cddfSDavid du Colombier void
7687dd7cddfSDavid du Colombier sugen(Node *n, Node *nn, long w)
7697dd7cddfSDavid du Colombier {
7707dd7cddfSDavid du Colombier 	Prog *p1;
7717dd7cddfSDavid du Colombier 	Node nod0, nod1, nod2, nod3, nod4, *l, *r;
7727dd7cddfSDavid du Colombier 	Type *t;
7737dd7cddfSDavid du Colombier 	long pc1;
7747dd7cddfSDavid du Colombier 	int i, m, c;
7757dd7cddfSDavid du Colombier 
7767dd7cddfSDavid du Colombier 	if(n == Z || n->type == T)
7777dd7cddfSDavid du Colombier 		return;
7787dd7cddfSDavid du Colombier 	if(debug['g']) {
7797dd7cddfSDavid du Colombier 		prtree(nn, "sugen lhs");
7807dd7cddfSDavid du Colombier 		prtree(n, "sugen");
7817dd7cddfSDavid du Colombier 	}
7827dd7cddfSDavid du Colombier 	if(nn == nodrat)
7837dd7cddfSDavid du Colombier 		if(w > nrathole)
7847dd7cddfSDavid du Colombier 			nrathole = w;
7857dd7cddfSDavid du Colombier 	switch(n->op) {
7867dd7cddfSDavid du Colombier 	case OIND:
7877dd7cddfSDavid du Colombier 		if(nn == Z) {
7887dd7cddfSDavid du Colombier 			nullwarn(n->left, Z);
7897dd7cddfSDavid du Colombier 			break;
7907dd7cddfSDavid du Colombier 		}
7917dd7cddfSDavid du Colombier 
7927dd7cddfSDavid du Colombier 	default:
7937dd7cddfSDavid du Colombier 		goto copy;
7947dd7cddfSDavid du Colombier 
7957dd7cddfSDavid du Colombier 	case OCONST:
7967dd7cddfSDavid du Colombier 		if(n->type && typev[n->type->etype]) {
7977dd7cddfSDavid du Colombier 			if(nn == Z) {
7987dd7cddfSDavid du Colombier 				nullwarn(n->left, Z);
7997dd7cddfSDavid du Colombier 				break;
8007dd7cddfSDavid du Colombier 			}
8017dd7cddfSDavid du Colombier 
8027dd7cddfSDavid du Colombier 			t = nn->type;
8037dd7cddfSDavid du Colombier 			nn->type = types[TLONG];
8047dd7cddfSDavid du Colombier 			reglcgen(&nod1, nn, Z);
8057dd7cddfSDavid du Colombier 			nn->type = t;
8067dd7cddfSDavid du Colombier 
80780ee5cbfSDavid du Colombier 			if(align(0, types[TCHAR], Aarg1))	/* isbigendian */
8087dd7cddfSDavid du Colombier 				gopcode(OAS, nod32const(n->vconst>>32), Z, &nod1);
80980ee5cbfSDavid du Colombier 			else
8107dd7cddfSDavid du Colombier 				gopcode(OAS, nod32const(n->vconst), Z, &nod1);
81180ee5cbfSDavid du Colombier 			nod1.xoffset += SZ_LONG;
81280ee5cbfSDavid du Colombier 			if(align(0, types[TCHAR], Aarg1))	/* isbigendian */
81380ee5cbfSDavid du Colombier 				gopcode(OAS, nod32const(n->vconst), Z, &nod1);
81480ee5cbfSDavid du Colombier 			else
81580ee5cbfSDavid du Colombier 				gopcode(OAS, nod32const(n->vconst>>32), Z, &nod1);
8167dd7cddfSDavid du Colombier 
8177dd7cddfSDavid du Colombier 			regfree(&nod1);
8187dd7cddfSDavid du Colombier 			break;
8197dd7cddfSDavid du Colombier 		}
8207dd7cddfSDavid du Colombier 		goto copy;
8217dd7cddfSDavid du Colombier 
8227dd7cddfSDavid du Colombier 	case ODOT:
8237dd7cddfSDavid du Colombier 		l = n->left;
8247dd7cddfSDavid du Colombier 		sugen(l, nodrat, l->type->width);
8257dd7cddfSDavid du Colombier 		if(nn != Z) {
8267dd7cddfSDavid du Colombier 			warn(n, "non-interruptable temporary");
8277dd7cddfSDavid du Colombier 			nod1 = *nodrat;
8287dd7cddfSDavid du Colombier 			r = n->right;
8297dd7cddfSDavid du Colombier 			if(!r || r->op != OCONST) {
8307dd7cddfSDavid du Colombier 				diag(n, "DOT and no offset");
8317dd7cddfSDavid du Colombier 				break;
8327dd7cddfSDavid du Colombier 			}
8337dd7cddfSDavid du Colombier 			nod1.xoffset += (long)r->vconst;
8347dd7cddfSDavid du Colombier 			nod1.type = n->type;
8357dd7cddfSDavid du Colombier 			sugen(&nod1, nn, w);
8367dd7cddfSDavid du Colombier 		}
8377dd7cddfSDavid du Colombier 		break;
8387dd7cddfSDavid du Colombier 
8397dd7cddfSDavid du Colombier 	case OSTRUCT:
8407dd7cddfSDavid du Colombier 		/*
8417dd7cddfSDavid du Colombier 		 * rewrite so lhs has no side effects
8427dd7cddfSDavid du Colombier 		 */
8437dd7cddfSDavid du Colombier 		if(nn != Z && side(nn)) {
8447dd7cddfSDavid du Colombier 			nod1 = *n;
8457dd7cddfSDavid du Colombier 			nod1.type = typ(TIND, n->type);
8467dd7cddfSDavid du Colombier 			regalloc(&nod2, &nod1, Z);
8477dd7cddfSDavid du Colombier 			lcgen(nn, &nod2);
8487dd7cddfSDavid du Colombier 			regsalloc(&nod0, &nod1);
8497dd7cddfSDavid du Colombier 			gopcode(OAS, &nod2, Z, &nod0);
8507dd7cddfSDavid du Colombier 			regfree(&nod2);
8517dd7cddfSDavid du Colombier 
8527dd7cddfSDavid du Colombier 			nod1 = *n;
8537dd7cddfSDavid du Colombier 			nod1.op = OIND;
8547dd7cddfSDavid du Colombier 			nod1.left = &nod0;
8557dd7cddfSDavid du Colombier 			nod1.right = Z;
8567dd7cddfSDavid du Colombier 			nod1.complex = 1;
8577dd7cddfSDavid du Colombier 
8587dd7cddfSDavid du Colombier 			sugen(n, &nod1, w);
8597dd7cddfSDavid du Colombier 			return;
8607dd7cddfSDavid du Colombier 		}
8617dd7cddfSDavid du Colombier 
8627dd7cddfSDavid du Colombier 		r = n->left;
8637dd7cddfSDavid du Colombier 		for(t = n->type->link; t != T; t = t->down) {
8647dd7cddfSDavid du Colombier 			l = r;
8657dd7cddfSDavid du Colombier 			if(r->op == OLIST) {
8667dd7cddfSDavid du Colombier 				l = r->left;
8677dd7cddfSDavid du Colombier 				r = r->right;
8687dd7cddfSDavid du Colombier 			}
8697dd7cddfSDavid du Colombier 			if(nn == Z) {
8707dd7cddfSDavid du Colombier 				cgen(l, nn);
8717dd7cddfSDavid du Colombier 				continue;
8727dd7cddfSDavid du Colombier 			}
8737dd7cddfSDavid du Colombier 			/*
8747dd7cddfSDavid du Colombier 			 * hand craft *(&nn + o) = l
8757dd7cddfSDavid du Colombier 			 */
8767dd7cddfSDavid du Colombier 			nod0 = znode;
8777dd7cddfSDavid du Colombier 			nod0.op = OAS;
8787dd7cddfSDavid du Colombier 			nod0.type = t;
8797dd7cddfSDavid du Colombier 			nod0.left = &nod1;
8807dd7cddfSDavid du Colombier 			nod0.right = l;
8817dd7cddfSDavid du Colombier 
8827dd7cddfSDavid du Colombier 			nod1 = znode;
8837dd7cddfSDavid du Colombier 			nod1.op = OIND;
8847dd7cddfSDavid du Colombier 			nod1.type = t;
8857dd7cddfSDavid du Colombier 			nod1.left = &nod2;
8867dd7cddfSDavid du Colombier 
8877dd7cddfSDavid du Colombier 			nod2 = znode;
8887dd7cddfSDavid du Colombier 			nod2.op = OADD;
8897dd7cddfSDavid du Colombier 			nod2.type = typ(TIND, t);
8907dd7cddfSDavid du Colombier 			nod2.left = &nod3;
8917dd7cddfSDavid du Colombier 			nod2.right = &nod4;
8927dd7cddfSDavid du Colombier 
8937dd7cddfSDavid du Colombier 			nod3 = znode;
8947dd7cddfSDavid du Colombier 			nod3.op = OADDR;
8957dd7cddfSDavid du Colombier 			nod3.type = nod2.type;
8967dd7cddfSDavid du Colombier 			nod3.left = nn;
8977dd7cddfSDavid du Colombier 
8987dd7cddfSDavid du Colombier 			nod4 = znode;
8997dd7cddfSDavid du Colombier 			nod4.op = OCONST;
9007dd7cddfSDavid du Colombier 			nod4.type = nod2.type;
9017dd7cddfSDavid du Colombier 			nod4.vconst = t->offset;
9027dd7cddfSDavid du Colombier 
9037dd7cddfSDavid du Colombier 			ccom(&nod0);
9047dd7cddfSDavid du Colombier 			acom(&nod0);
9057dd7cddfSDavid du Colombier 			xcom(&nod0);
9067dd7cddfSDavid du Colombier 			nod0.addable = 0;
9077dd7cddfSDavid du Colombier 
9087dd7cddfSDavid du Colombier 			/* prtree(&nod0, "hand craft"); /* */
9097dd7cddfSDavid du Colombier 			cgen(&nod0, Z);
9107dd7cddfSDavid du Colombier 		}
9117dd7cddfSDavid du Colombier 		break;
9127dd7cddfSDavid du Colombier 
9137dd7cddfSDavid du Colombier 	case OAS:
9147dd7cddfSDavid du Colombier 		if(nn == Z) {
9157dd7cddfSDavid du Colombier 			if(n->addable < INDEXED)
9167dd7cddfSDavid du Colombier 				sugen(n->right, n->left, w);
9177dd7cddfSDavid du Colombier 			break;
9187dd7cddfSDavid du Colombier 		}
9197dd7cddfSDavid du Colombier 		/* BOTCH -- functions can clobber rathole */
9207dd7cddfSDavid du Colombier 		sugen(n->right, nodrat, w);
9217dd7cddfSDavid du Colombier 		warn(n, "non-interruptable temporary");
9227dd7cddfSDavid du Colombier 		sugen(nodrat, n->left, w);
9237dd7cddfSDavid du Colombier 		sugen(nodrat, nn, w);
9247dd7cddfSDavid du Colombier 		break;
9257dd7cddfSDavid du Colombier 
9267dd7cddfSDavid du Colombier 	case OFUNC:
9277dd7cddfSDavid du Colombier 		if(nn == Z) {
9287dd7cddfSDavid du Colombier 			sugen(n, nodrat, w);
9297dd7cddfSDavid du Colombier 			break;
9307dd7cddfSDavid du Colombier 		}
9317dd7cddfSDavid du Colombier 		if(nn->op != OIND) {
9327dd7cddfSDavid du Colombier 			nn = new1(OADDR, nn, Z);
9337dd7cddfSDavid du Colombier 			nn->type = types[TIND];
9347dd7cddfSDavid du Colombier 			nn->addable = 0;
9357dd7cddfSDavid du Colombier 		} else
9367dd7cddfSDavid du Colombier 			nn = nn->left;
9377dd7cddfSDavid du Colombier 		n = new(OFUNC, n->left, new(OLIST, nn, n->right));
9387dd7cddfSDavid du Colombier 		n->type = types[TVOID];
9397dd7cddfSDavid du Colombier 		n->left->type = types[TVOID];
9407dd7cddfSDavid du Colombier 		cgen(n, Z);
9417dd7cddfSDavid du Colombier 		break;
9427dd7cddfSDavid du Colombier 
9437dd7cddfSDavid du Colombier 	case OCOND:
9447dd7cddfSDavid du Colombier 		bcgen(n->left, 1);
9457dd7cddfSDavid du Colombier 		p1 = p;
9467dd7cddfSDavid du Colombier 		sugen(n->right->left, nn, w);
9477dd7cddfSDavid du Colombier 		gbranch(OGOTO);
9487dd7cddfSDavid du Colombier 		patch(p1, pc);
9497dd7cddfSDavid du Colombier 		p1 = p;
9507dd7cddfSDavid du Colombier 		sugen(n->right->right, nn, w);
9517dd7cddfSDavid du Colombier 		patch(p1, pc);
9527dd7cddfSDavid du Colombier 		break;
9537dd7cddfSDavid du Colombier 
9547dd7cddfSDavid du Colombier 	case OCOMMA:
9557dd7cddfSDavid du Colombier 		cgen(n->left, Z);
9567dd7cddfSDavid du Colombier 		sugen(n->right, nn, w);
9577dd7cddfSDavid du Colombier 		break;
9587dd7cddfSDavid du Colombier 	}
9597dd7cddfSDavid du Colombier 	return;
9607dd7cddfSDavid du Colombier 
9617dd7cddfSDavid du Colombier copy:
9627dd7cddfSDavid du Colombier 	if(nn == Z)
9637dd7cddfSDavid du Colombier 		return;
9647dd7cddfSDavid du Colombier 	if(n->complex >= FNX && nn->complex >= FNX) {
9657dd7cddfSDavid du Colombier 		t = nn->type;
9667dd7cddfSDavid du Colombier 		nn->type = types[TLONG];
9677dd7cddfSDavid du Colombier 		regialloc(&nod1, nn, Z);
9687dd7cddfSDavid du Colombier 		lcgen(nn, &nod1);
9697dd7cddfSDavid du Colombier 		regsalloc(&nod2, nn);
9707dd7cddfSDavid du Colombier 		nn->type = t;
9717dd7cddfSDavid du Colombier 
9727dd7cddfSDavid du Colombier 		gopcode(OAS, &nod1, Z, &nod2);
9737dd7cddfSDavid du Colombier 		regfree(&nod1);
9747dd7cddfSDavid du Colombier 
9757dd7cddfSDavid du Colombier 		nod2.type = typ(TIND, t);
9767dd7cddfSDavid du Colombier 
9777dd7cddfSDavid du Colombier 		nod1 = nod2;
9787dd7cddfSDavid du Colombier 		nod1.op = OIND;
9797dd7cddfSDavid du Colombier 		nod1.left = &nod2;
9807dd7cddfSDavid du Colombier 		nod1.right = Z;
9817dd7cddfSDavid du Colombier 		nod1.complex = 1;
9827dd7cddfSDavid du Colombier 		nod1.type = t;
9837dd7cddfSDavid du Colombier 
9847dd7cddfSDavid du Colombier 		sugen(n, &nod1, w);
9857dd7cddfSDavid du Colombier 		return;
9867dd7cddfSDavid du Colombier 	}
9877dd7cddfSDavid du Colombier 
9887dd7cddfSDavid du Colombier 	if(n->complex > nn->complex) {
9897dd7cddfSDavid du Colombier 		t = n->type;
9907dd7cddfSDavid du Colombier 		n->type = types[TLONG];
9917dd7cddfSDavid du Colombier 		reglcgen(&nod1, n, Z);
9927dd7cddfSDavid du Colombier 		n->type = t;
9937dd7cddfSDavid du Colombier 
9947dd7cddfSDavid du Colombier 		t = nn->type;
9957dd7cddfSDavid du Colombier 		nn->type = types[TLONG];
9967dd7cddfSDavid du Colombier 		reglcgen(&nod2, nn, Z);
9977dd7cddfSDavid du Colombier 		nn->type = t;
9987dd7cddfSDavid du Colombier 	} else {
9997dd7cddfSDavid du Colombier 		t = nn->type;
10007dd7cddfSDavid du Colombier 		nn->type = types[TLONG];
10017dd7cddfSDavid du Colombier 		reglcgen(&nod2, nn, Z);
10027dd7cddfSDavid du Colombier 		nn->type = t;
10037dd7cddfSDavid du Colombier 
10047dd7cddfSDavid du Colombier 		t = n->type;
10057dd7cddfSDavid du Colombier 		n->type = types[TLONG];
10067dd7cddfSDavid du Colombier 		reglcgen(&nod1, n, Z);
10077dd7cddfSDavid du Colombier 		n->type = t;
10087dd7cddfSDavid du Colombier 	}
10097dd7cddfSDavid du Colombier 
10107dd7cddfSDavid du Colombier 	w /= SZ_LONG;
10117dd7cddfSDavid du Colombier 	if(w <= 5) {
10127dd7cddfSDavid du Colombier 		layout(&nod1, &nod2, w, 0, Z);
10137dd7cddfSDavid du Colombier 		goto out;
10147dd7cddfSDavid du Colombier 	}
10157dd7cddfSDavid du Colombier 
10167dd7cddfSDavid du Colombier 	/*
10177dd7cddfSDavid du Colombier 	 * minimize space for unrolling loop
10187dd7cddfSDavid du Colombier 	 * 3,4,5 times. (6 or more is never minimum)
10197dd7cddfSDavid du Colombier 	 * if small structure, try 2 also.
10207dd7cddfSDavid du Colombier 	 */
10217dd7cddfSDavid du Colombier 	c = 0; /* set */
10227dd7cddfSDavid du Colombier 	m = 100;
10237dd7cddfSDavid du Colombier 	i = 3;
10247dd7cddfSDavid du Colombier 	if(w <= 15)
10257dd7cddfSDavid du Colombier 		i = 2;
10267dd7cddfSDavid du Colombier 	for(; i<=5; i++)
10277dd7cddfSDavid du Colombier 		if(i + w%i <= m) {
10287dd7cddfSDavid du Colombier 			c = i;
10297dd7cddfSDavid du Colombier 			m = c + w%c;
10307dd7cddfSDavid du Colombier 		}
10317dd7cddfSDavid du Colombier 
10327dd7cddfSDavid du Colombier 	regalloc(&nod3, &regnode, Z);
10337dd7cddfSDavid du Colombier 	layout(&nod1, &nod2, w%c, w/c, &nod3);
10347dd7cddfSDavid du Colombier 
10357dd7cddfSDavid du Colombier 	pc1 = pc;
10367dd7cddfSDavid du Colombier 	layout(&nod1, &nod2, c, 0, Z);
10377dd7cddfSDavid du Colombier 
10387dd7cddfSDavid du Colombier 	gopcode(OSUB, nodconst(1L), Z, &nod3);
10397dd7cddfSDavid du Colombier 	nod1.op = OREGISTER;
10407dd7cddfSDavid du Colombier 	gopcode(OADD, nodconst(c*SZ_LONG), Z, &nod1);
10417dd7cddfSDavid du Colombier 	nod2.op = OREGISTER;
10427dd7cddfSDavid du Colombier 	gopcode(OADD, nodconst(c*SZ_LONG), Z, &nod2);
10437dd7cddfSDavid du Colombier 
10447dd7cddfSDavid du Colombier 	gopcode(OGT, &nod3, Z, nodconst(0));
10457dd7cddfSDavid du Colombier 	patch(p, pc1);
10467dd7cddfSDavid du Colombier 
10477dd7cddfSDavid du Colombier 	regfree(&nod3);
10487dd7cddfSDavid du Colombier out:
10497dd7cddfSDavid du Colombier 	regfree(&nod1);
10507dd7cddfSDavid du Colombier 	regfree(&nod2);
10517dd7cddfSDavid du Colombier }
10527dd7cddfSDavid du Colombier 
10537dd7cddfSDavid du Colombier void
10547dd7cddfSDavid du Colombier layout(Node *f, Node *t, int c, int cv, Node *cn)
10557dd7cddfSDavid du Colombier {
10567dd7cddfSDavid du Colombier 	Node t1, t2;
10577dd7cddfSDavid du Colombier 
10587dd7cddfSDavid du Colombier 	while(c > 3) {
10597dd7cddfSDavid du Colombier 		layout(f, t, 2, 0, Z);
10607dd7cddfSDavid du Colombier 		c -= 2;
10617dd7cddfSDavid du Colombier 	}
10627dd7cddfSDavid du Colombier 
10637dd7cddfSDavid du Colombier 	regalloc(&t1, &regnode, Z);
10647dd7cddfSDavid du Colombier 	regalloc(&t2, &regnode, Z);
10657dd7cddfSDavid du Colombier 	if(c > 0) {
10667dd7cddfSDavid du Colombier 		gopcode(OAS, f, Z, &t1);
10677dd7cddfSDavid du Colombier 		f->xoffset += SZ_LONG;
10687dd7cddfSDavid du Colombier 	}
10697dd7cddfSDavid du Colombier 	if(cn != Z)
10707dd7cddfSDavid du Colombier 		gopcode(OAS, nodconst(cv), Z, cn);
10717dd7cddfSDavid du Colombier 	if(c > 1) {
10727dd7cddfSDavid du Colombier 		gopcode(OAS, f, Z, &t2);
10737dd7cddfSDavid du Colombier 		f->xoffset += SZ_LONG;
10747dd7cddfSDavid du Colombier 	}
10757dd7cddfSDavid du Colombier 	if(c > 0) {
10767dd7cddfSDavid du Colombier 		gopcode(OAS, &t1, Z, t);
10777dd7cddfSDavid du Colombier 		t->xoffset += SZ_LONG;
10787dd7cddfSDavid du Colombier 	}
10797dd7cddfSDavid du Colombier 	if(c > 2) {
10807dd7cddfSDavid du Colombier 		gopcode(OAS, f, Z, &t1);
10817dd7cddfSDavid du Colombier 		f->xoffset += SZ_LONG;
10827dd7cddfSDavid du Colombier 	}
10837dd7cddfSDavid du Colombier 	if(c > 1) {
10847dd7cddfSDavid du Colombier 		gopcode(OAS, &t2, Z, t);
10857dd7cddfSDavid du Colombier 		t->xoffset += SZ_LONG;
10867dd7cddfSDavid du Colombier 	}
10877dd7cddfSDavid du Colombier 	if(c > 2) {
10887dd7cddfSDavid du Colombier 		gopcode(OAS, &t1, Z, t);
10897dd7cddfSDavid du Colombier 		t->xoffset += SZ_LONG;
10907dd7cddfSDavid du Colombier 	}
10917dd7cddfSDavid du Colombier 	regfree(&t1);
10927dd7cddfSDavid du Colombier 	regfree(&t2);
10937dd7cddfSDavid du Colombier }
1094