xref: /plan9-contrib/sys/src/cmd/6c/cgen.c (revision 40d015479ed36701ae6dcfd8814f849fc6285e8d)
1e887ea33SDavid du Colombier #include "gc.h"
2e887ea33SDavid du Colombier 
3e887ea33SDavid du Colombier /* ,x/^(print|prtree)\(/i/\/\/ */
4e887ea33SDavid du Colombier int castup(Type*, Type*);
5e887ea33SDavid du Colombier 
6e887ea33SDavid du Colombier void
cgen(Node * n,Node * nn)7e887ea33SDavid du Colombier cgen(Node *n, Node *nn)
8e887ea33SDavid du Colombier {
9e887ea33SDavid du Colombier 	Node *l, *r, *t;
10e887ea33SDavid du Colombier 	Prog *p1;
11e887ea33SDavid du Colombier 	Node nod, nod1, nod2, nod3, nod4;
12e887ea33SDavid du Colombier 	int o, hardleft;
13e887ea33SDavid du Colombier 	long v, curs;
14e887ea33SDavid du Colombier 	vlong c;
15e887ea33SDavid du Colombier 
16e887ea33SDavid du Colombier 	if(debug['g']) {
17e887ea33SDavid du Colombier 		prtree(nn, "cgen lhs");
18e887ea33SDavid du Colombier 		prtree(n, "cgen");
19e887ea33SDavid du Colombier 	}
20e887ea33SDavid du Colombier 	if(n == Z || n->type == T)
21e887ea33SDavid du Colombier 		return;
22e887ea33SDavid du Colombier 	if(typesu[n->type->etype]) {
23e887ea33SDavid du Colombier 		sugen(n, nn, n->type->width);
24e887ea33SDavid du Colombier 		return;
25e887ea33SDavid du Colombier 	}
26e887ea33SDavid du Colombier 	l = n->left;
27e887ea33SDavid du Colombier 	r = n->right;
28e887ea33SDavid du Colombier 	o = n->op;
29e887ea33SDavid du Colombier 	if(n->addable >= INDEXED) {
30e887ea33SDavid du Colombier 		if(nn == Z) {
31e887ea33SDavid du Colombier 			switch(o) {
32e887ea33SDavid du Colombier 			default:
33e887ea33SDavid du Colombier 				nullwarn(Z, Z);
34e887ea33SDavid du Colombier 				break;
35e887ea33SDavid du Colombier 			case OINDEX:
36e887ea33SDavid du Colombier 				nullwarn(l, r);
37e887ea33SDavid du Colombier 				break;
38e887ea33SDavid du Colombier 			}
39e887ea33SDavid du Colombier 			return;
40e887ea33SDavid du Colombier 		}
41e887ea33SDavid du Colombier 		gmove(n, nn);
42e887ea33SDavid du Colombier 		return;
43e887ea33SDavid du Colombier 	}
44e887ea33SDavid du Colombier 	curs = cursafe;
45e887ea33SDavid du Colombier 
46e887ea33SDavid du Colombier 	if(l->complex >= FNX)
47e887ea33SDavid du Colombier 	if(r != Z && r->complex >= FNX)
48e887ea33SDavid du Colombier 	switch(o) {
49e887ea33SDavid du Colombier 	default:
50e887ea33SDavid du Colombier 		if(cond(o) && typesu[l->type->etype])
51e887ea33SDavid du Colombier 			break;
52e887ea33SDavid du Colombier 
53e887ea33SDavid du Colombier 		regret(&nod, r);
54e887ea33SDavid du Colombier 		cgen(r, &nod);
55e887ea33SDavid du Colombier 
56e887ea33SDavid du Colombier 		regsalloc(&nod1, r);
57e887ea33SDavid du Colombier 		gmove(&nod, &nod1);
58e887ea33SDavid du Colombier 
59e887ea33SDavid du Colombier 		regfree(&nod);
60e887ea33SDavid du Colombier 		nod = *n;
61e887ea33SDavid du Colombier 		nod.right = &nod1;
62e887ea33SDavid du Colombier 
63e887ea33SDavid du Colombier 		cgen(&nod, nn);
64e887ea33SDavid du Colombier 		return;
65e887ea33SDavid du Colombier 
66e887ea33SDavid du Colombier 	case OFUNC:
67e887ea33SDavid du Colombier 	case OCOMMA:
68e887ea33SDavid du Colombier 	case OANDAND:
69e887ea33SDavid du Colombier 	case OOROR:
70e887ea33SDavid du Colombier 	case OCOND:
71e887ea33SDavid du Colombier 	case ODOT:
72e887ea33SDavid du Colombier 		break;
73e887ea33SDavid du Colombier 	}
74e887ea33SDavid du Colombier 
75e887ea33SDavid du Colombier 	hardleft = l->addable < INDEXED || l->complex >= FNX;
76e887ea33SDavid du Colombier 	switch(o) {
77e887ea33SDavid du Colombier 	default:
78e887ea33SDavid du Colombier 		diag(n, "unknown op in cgen: %O", o);
79e887ea33SDavid du Colombier 		break;
80e887ea33SDavid du Colombier 
81e887ea33SDavid du Colombier 	case ONEG:
82e887ea33SDavid du Colombier 	case OCOM:
83e887ea33SDavid du Colombier 		if(nn == Z) {
84e887ea33SDavid du Colombier 			nullwarn(l, Z);
85e887ea33SDavid du Colombier 			break;
86e887ea33SDavid du Colombier 		}
87e887ea33SDavid du Colombier 		regalloc(&nod, l, nn);
88e887ea33SDavid du Colombier 		cgen(l, &nod);
89e887ea33SDavid du Colombier 		gopcode(o, n->type, Z, &nod);
90e887ea33SDavid du Colombier 		gmove(&nod, nn);
91e887ea33SDavid du Colombier 		regfree(&nod);
92e887ea33SDavid du Colombier 		break;
93e887ea33SDavid du Colombier 
94e887ea33SDavid du Colombier 	case OAS:
95e887ea33SDavid du Colombier 		if(l->op == OBIT)
96e887ea33SDavid du Colombier 			goto bitas;
97e887ea33SDavid du Colombier 		if(!hardleft) {
98e887ea33SDavid du Colombier 			if(nn != Z || r->addable < INDEXED || hardconst(r)) {
99e887ea33SDavid du Colombier 				if(r->complex >= FNX && nn == Z)
100e887ea33SDavid du Colombier 					regret(&nod, r);
101e887ea33SDavid du Colombier 				else
102e887ea33SDavid du Colombier 					regalloc(&nod, r, nn);
103e887ea33SDavid du Colombier 				cgen(r, &nod);
104e887ea33SDavid du Colombier 				gmove(&nod, l);
105e887ea33SDavid du Colombier 				if(nn != Z)
106e887ea33SDavid du Colombier 					gmove(&nod, nn);
107e887ea33SDavid du Colombier 				regfree(&nod);
108e887ea33SDavid du Colombier 			} else
109e887ea33SDavid du Colombier 				gmove(r, l);
110e887ea33SDavid du Colombier 			break;
111e887ea33SDavid du Colombier 		}
112e887ea33SDavid du Colombier 		if(l->complex >= r->complex) {
113e887ea33SDavid du Colombier 			if(l->op == OINDEX && immconst(r)) {
114e887ea33SDavid du Colombier 				gmove(r, l);
115e887ea33SDavid du Colombier 				break;
116e887ea33SDavid du Colombier 			}
117e887ea33SDavid du Colombier 			reglcgen(&nod1, l, Z);
118e887ea33SDavid du Colombier 			if(r->addable >= INDEXED && !hardconst(r)) {
119e887ea33SDavid du Colombier 				gmove(r, &nod1);
120e887ea33SDavid du Colombier 				if(nn != Z)
121e887ea33SDavid du Colombier 					gmove(r, nn);
122e887ea33SDavid du Colombier 				regfree(&nod1);
123e887ea33SDavid du Colombier 				break;
124e887ea33SDavid du Colombier 			}
125e887ea33SDavid du Colombier 			regalloc(&nod, r, nn);
126e887ea33SDavid du Colombier 			cgen(r, &nod);
127e887ea33SDavid du Colombier 		} else {
128e887ea33SDavid du Colombier 			regalloc(&nod, r, nn);
129e887ea33SDavid du Colombier 			cgen(r, &nod);
130e887ea33SDavid du Colombier 			reglcgen(&nod1, l, Z);
131e887ea33SDavid du Colombier 		}
132e887ea33SDavid du Colombier 		gmove(&nod, &nod1);
133e887ea33SDavid du Colombier 		regfree(&nod);
134e887ea33SDavid du Colombier 		regfree(&nod1);
135e887ea33SDavid du Colombier 		break;
136e887ea33SDavid du Colombier 
137e887ea33SDavid du Colombier 	bitas:
138e887ea33SDavid du Colombier 		n = l->left;
139e887ea33SDavid du Colombier 		regalloc(&nod, r, nn);
140e887ea33SDavid du Colombier 		if(l->complex >= r->complex) {
141e887ea33SDavid du Colombier 			reglcgen(&nod1, n, Z);
142e887ea33SDavid du Colombier 			cgen(r, &nod);
143e887ea33SDavid du Colombier 		} else {
144e887ea33SDavid du Colombier 			cgen(r, &nod);
145e887ea33SDavid du Colombier 			reglcgen(&nod1, n, Z);
146e887ea33SDavid du Colombier 		}
147e887ea33SDavid du Colombier 		regalloc(&nod2, n, Z);
148e887ea33SDavid du Colombier 		gmove(&nod1, &nod2);
149e887ea33SDavid du Colombier 		bitstore(l, &nod, &nod1, &nod2, nn);
150e887ea33SDavid du Colombier 		break;
151e887ea33SDavid du Colombier 
152e887ea33SDavid du Colombier 	case OBIT:
153e887ea33SDavid du Colombier 		if(nn == Z) {
154e887ea33SDavid du Colombier 			nullwarn(l, Z);
155e887ea33SDavid du Colombier 			break;
156e887ea33SDavid du Colombier 		}
157e887ea33SDavid du Colombier 		bitload(n, &nod, Z, Z, nn);
158e887ea33SDavid du Colombier 		gmove(&nod, nn);
159e887ea33SDavid du Colombier 		regfree(&nod);
160e887ea33SDavid du Colombier 		break;
161e887ea33SDavid du Colombier 
162e887ea33SDavid du Colombier 	case OLSHR:
163e887ea33SDavid du Colombier 	case OASHL:
164e887ea33SDavid du Colombier 	case OASHR:
165e887ea33SDavid du Colombier 		if(nn == Z) {
166e887ea33SDavid du Colombier 			nullwarn(l, r);
167e887ea33SDavid du Colombier 			break;
168e887ea33SDavid du Colombier 		}
169e887ea33SDavid du Colombier 		if(r->op == OCONST) {
170e887ea33SDavid du Colombier 			if(r->vconst == 0) {
171e887ea33SDavid du Colombier 				cgen(l, nn);
172e887ea33SDavid du Colombier 				break;
173e887ea33SDavid du Colombier 			}
174e887ea33SDavid du Colombier 			regalloc(&nod, l, nn);
175e887ea33SDavid du Colombier 			cgen(l, &nod);
176e887ea33SDavid du Colombier 			if(o == OASHL && r->vconst == 1)
177e887ea33SDavid du Colombier 				gopcode(OADD, n->type, &nod, &nod);
178e887ea33SDavid du Colombier 			else
179e887ea33SDavid du Colombier 				gopcode(o, n->type, r, &nod);
180e887ea33SDavid du Colombier 			gmove(&nod, nn);
181e887ea33SDavid du Colombier 			regfree(&nod);
182e887ea33SDavid du Colombier 			break;
183e887ea33SDavid du Colombier 		}
184e887ea33SDavid du Colombier 
185e887ea33SDavid du Colombier 		/*
186e887ea33SDavid du Colombier 		 * get nod to be D_CX
187e887ea33SDavid du Colombier 		 */
188e887ea33SDavid du Colombier 		if(nodreg(&nod, nn, D_CX)) {
189e887ea33SDavid du Colombier 			regsalloc(&nod1, n);
190e887ea33SDavid du Colombier 			gmove(&nod, &nod1);
191e887ea33SDavid du Colombier 			cgen(n, &nod);		/* probably a bug */
192e887ea33SDavid du Colombier 			gmove(&nod, nn);
193e887ea33SDavid du Colombier 			gmove(&nod1, &nod);
194e887ea33SDavid du Colombier 			break;
195e887ea33SDavid du Colombier 		}
196e887ea33SDavid du Colombier 		reg[D_CX]++;
197e887ea33SDavid du Colombier 		if(nn->op == OREGISTER && nn->reg == D_CX)
198e887ea33SDavid du Colombier 			regalloc(&nod1, l, Z);
199e887ea33SDavid du Colombier 		else
200e887ea33SDavid du Colombier 			regalloc(&nod1, l, nn);
201e887ea33SDavid du Colombier 		if(r->complex >= l->complex) {
202e887ea33SDavid du Colombier 			cgen(r, &nod);
203e887ea33SDavid du Colombier 			cgen(l, &nod1);
204e887ea33SDavid du Colombier 		} else {
205e887ea33SDavid du Colombier 			cgen(l, &nod1);
206e887ea33SDavid du Colombier 			cgen(r, &nod);
207e887ea33SDavid du Colombier 		}
208e887ea33SDavid du Colombier 		gopcode(o, n->type, &nod, &nod1);
209e887ea33SDavid du Colombier 		gmove(&nod1, nn);
210e887ea33SDavid du Colombier 		regfree(&nod);
211e887ea33SDavid du Colombier 		regfree(&nod1);
212e887ea33SDavid du Colombier 		break;
213e887ea33SDavid du Colombier 
214e887ea33SDavid du Colombier 	case OADD:
215e887ea33SDavid du Colombier 	case OSUB:
216e887ea33SDavid du Colombier 	case OOR:
217e887ea33SDavid du Colombier 	case OXOR:
218e887ea33SDavid du Colombier 	case OAND:
219e887ea33SDavid du Colombier 		if(nn == Z) {
220e887ea33SDavid du Colombier 			nullwarn(l, r);
221e887ea33SDavid du Colombier 			break;
222e887ea33SDavid du Colombier 		}
223e887ea33SDavid du Colombier 		if(typefd[n->type->etype])
224e887ea33SDavid du Colombier 			goto fop;
225e887ea33SDavid du Colombier 		if(r->op == OCONST) {
226e887ea33SDavid du Colombier 			if(r->vconst == 0 && o != OAND) {
227e887ea33SDavid du Colombier 				cgen(l, nn);
228e887ea33SDavid du Colombier 				break;
229e887ea33SDavid du Colombier 			}
230e887ea33SDavid du Colombier 		}
231e887ea33SDavid du Colombier 		if(n->op == OADD && l->op == OASHL && l->right->op == OCONST
232e887ea33SDavid du Colombier 		&& (r->op != OCONST || r->vconst < -128 || r->vconst > 127)) {
233e887ea33SDavid du Colombier 			c = l->right->vconst;
234e887ea33SDavid du Colombier 			if(c > 0 && c <= 3) {
235e887ea33SDavid du Colombier 				if(l->left->complex >= r->complex) {
236e887ea33SDavid du Colombier 					regalloc(&nod, l->left, nn);
237e887ea33SDavid du Colombier 					cgen(l->left, &nod);
238e887ea33SDavid du Colombier 					if(r->addable < INDEXED) {
239e887ea33SDavid du Colombier 						regalloc(&nod1, r, Z);
240e887ea33SDavid du Colombier 						cgen(r, &nod1);
241e887ea33SDavid du Colombier 						genmuladd(&nod, &nod, 1 << c, &nod1);
242e887ea33SDavid du Colombier 						regfree(&nod1);
243e887ea33SDavid du Colombier 					}
244e887ea33SDavid du Colombier 					else
245e887ea33SDavid du Colombier 						genmuladd(&nod, &nod, 1 << c, r);
246e887ea33SDavid du Colombier 				}
247e887ea33SDavid du Colombier 				else {
248e887ea33SDavid du Colombier 					regalloc(&nod, r, nn);
249e887ea33SDavid du Colombier 					cgen(r, &nod);
250e887ea33SDavid du Colombier 					regalloc(&nod1, l->left, Z);
251e887ea33SDavid du Colombier 					cgen(l->left, &nod1);
252e887ea33SDavid du Colombier 					genmuladd(&nod, &nod1, 1 << c, &nod);
253e887ea33SDavid du Colombier 					regfree(&nod1);
254e887ea33SDavid du Colombier 				}
255e887ea33SDavid du Colombier 				gmove(&nod, nn);
256e887ea33SDavid du Colombier 				regfree(&nod);
257e887ea33SDavid du Colombier 				break;
258e887ea33SDavid du Colombier 			}
259e887ea33SDavid du Colombier 		}
260e887ea33SDavid du Colombier 		if(r->addable >= INDEXED && !hardconst(r)) {
261e887ea33SDavid du Colombier 			regalloc(&nod, l, nn);
262e887ea33SDavid du Colombier 			cgen(l, &nod);
263e887ea33SDavid du Colombier 			gopcode(o, n->type, r, &nod);
264e887ea33SDavid du Colombier 			gmove(&nod, nn);
265e887ea33SDavid du Colombier 			regfree(&nod);
266e887ea33SDavid du Colombier 			break;
267e887ea33SDavid du Colombier 		}
268e887ea33SDavid du Colombier 		if(l->complex >= r->complex) {
269e887ea33SDavid du Colombier 			regalloc(&nod, l, nn);
270e887ea33SDavid du Colombier 			cgen(l, &nod);
271e887ea33SDavid du Colombier 			regalloc(&nod1, r, Z);
272e887ea33SDavid du Colombier 			cgen(r, &nod1);
273e887ea33SDavid du Colombier 			gopcode(o, n->type, &nod1, &nod);
274e887ea33SDavid du Colombier 		} else {
275e887ea33SDavid du Colombier 			regalloc(&nod1, r, nn);
276e887ea33SDavid du Colombier 			cgen(r, &nod1);
277e887ea33SDavid du Colombier 			regalloc(&nod, l, Z);
278e887ea33SDavid du Colombier 			cgen(l, &nod);
279e887ea33SDavid du Colombier 			gopcode(o, n->type, &nod1, &nod);
280e887ea33SDavid du Colombier 		}
281e887ea33SDavid du Colombier 		gmove(&nod, nn);
282e887ea33SDavid du Colombier 		regfree(&nod);
283e887ea33SDavid du Colombier 		regfree(&nod1);
284e887ea33SDavid du Colombier 		break;
285e887ea33SDavid du Colombier 
286e887ea33SDavid du Colombier 	case OLMOD:
287e887ea33SDavid du Colombier 	case OMOD:
288e887ea33SDavid du Colombier 	case OLMUL:
289e887ea33SDavid du Colombier 	case OLDIV:
290e887ea33SDavid du Colombier 	case OMUL:
291e887ea33SDavid du Colombier 	case ODIV:
292e887ea33SDavid du Colombier 		if(nn == Z) {
293e887ea33SDavid du Colombier 			nullwarn(l, r);
294e887ea33SDavid du Colombier 			break;
295e887ea33SDavid du Colombier 		}
296e887ea33SDavid du Colombier 		if(typefd[n->type->etype])
297e887ea33SDavid du Colombier 			goto fop;
298e887ea33SDavid du Colombier 		if(r->op == OCONST && typechl[n->type->etype]) {	/* TO DO */
299e887ea33SDavid du Colombier 			SET(v);
300e887ea33SDavid du Colombier 			switch(o) {
301e887ea33SDavid du Colombier 			case ODIV:
302e887ea33SDavid du Colombier 			case OMOD:
303e887ea33SDavid du Colombier 				c = r->vconst;
304e887ea33SDavid du Colombier 				if(c < 0)
305e887ea33SDavid du Colombier 					c = -c;
306e887ea33SDavid du Colombier 				v = log2(c);
307e887ea33SDavid du Colombier 				if(v < 0)
308e887ea33SDavid du Colombier 					break;
309e887ea33SDavid du Colombier 				/* fall thru */
310e887ea33SDavid du Colombier 			case OMUL:
311e887ea33SDavid du Colombier 			case OLMUL:
312e887ea33SDavid du Colombier 				regalloc(&nod, l, nn);
313e887ea33SDavid du Colombier 				cgen(l, &nod);
314e887ea33SDavid du Colombier 				switch(o) {
315e887ea33SDavid du Colombier 				case OMUL:
316e887ea33SDavid du Colombier 				case OLMUL:
317e887ea33SDavid du Colombier 					mulgen(n->type, r, &nod);
318e887ea33SDavid du Colombier 					break;
319e887ea33SDavid du Colombier 				case ODIV:
320e887ea33SDavid du Colombier 					sdiv2(r->vconst, v, l, &nod);
321e887ea33SDavid du Colombier 					break;
322e887ea33SDavid du Colombier 				case OMOD:
323e887ea33SDavid du Colombier 					smod2(r->vconst, v, l, &nod);
324e887ea33SDavid du Colombier 					break;
325e887ea33SDavid du Colombier 				}
326e887ea33SDavid du Colombier 				gmove(&nod, nn);
327e887ea33SDavid du Colombier 				regfree(&nod);
328e887ea33SDavid du Colombier 				goto done;
329e887ea33SDavid du Colombier 			case OLDIV:
330e887ea33SDavid du Colombier 				c = r->vconst;
331e887ea33SDavid du Colombier 				if((c & 0x80000000) == 0)
332e887ea33SDavid du Colombier 					break;
333e887ea33SDavid du Colombier 				regalloc(&nod1, l, Z);
334e887ea33SDavid du Colombier 				cgen(l, &nod1);
335e887ea33SDavid du Colombier 				regalloc(&nod, l, nn);
336e887ea33SDavid du Colombier 				zeroregm(&nod);
337e887ea33SDavid du Colombier 				gins(ACMPL, &nod1, nodconst(c));
338e887ea33SDavid du Colombier 				gins(ASBBL, nodconst(-1), &nod);
339e887ea33SDavid du Colombier 				regfree(&nod1);
340e887ea33SDavid du Colombier 				gmove(&nod, nn);
341e887ea33SDavid du Colombier 				regfree(&nod);
342e887ea33SDavid du Colombier 				goto done;
343e887ea33SDavid du Colombier 			}
344e887ea33SDavid du Colombier 		}
345e887ea33SDavid du Colombier 
346e887ea33SDavid du Colombier 		if(o == OMUL) {
347e887ea33SDavid du Colombier 			if(l->addable >= INDEXED) {
348e887ea33SDavid du Colombier 				t = l;
349e887ea33SDavid du Colombier 				l = r;
350e887ea33SDavid du Colombier 				r = t;
351e887ea33SDavid du Colombier 			}
352e887ea33SDavid du Colombier 			/* should favour AX */
353e887ea33SDavid du Colombier 			regalloc(&nod, l, nn);
354e887ea33SDavid du Colombier 			cgen(l, &nod);
355e887ea33SDavid du Colombier 			if(r->addable < INDEXED || hardconst(r)) {
356e887ea33SDavid du Colombier 				regalloc(&nod1, r, Z);
357e887ea33SDavid du Colombier 				cgen(r, &nod1);
358e887ea33SDavid du Colombier 				gopcode(OMUL, n->type, &nod1, &nod);
359e887ea33SDavid du Colombier 				regfree(&nod1);
360e887ea33SDavid du Colombier 			}else
361e887ea33SDavid du Colombier 				gopcode(OMUL, n->type, r, &nod);	/* addressible */
362e887ea33SDavid du Colombier 			gmove(&nod, nn);
363e887ea33SDavid du Colombier 			regfree(&nod);
364e887ea33SDavid du Colombier 			break;
365e887ea33SDavid du Colombier 		}
366e887ea33SDavid du Colombier 
367e887ea33SDavid du Colombier 		/*
368e887ea33SDavid du Colombier 		 * get nod to be D_AX
369e887ea33SDavid du Colombier 		 * get nod1 to be D_DX
370e887ea33SDavid du Colombier 		 */
371e887ea33SDavid du Colombier 		if(nodreg(&nod, nn, D_AX)) {
372e887ea33SDavid du Colombier 			regsalloc(&nod2, n);
373e887ea33SDavid du Colombier 			gmove(&nod, &nod2);
374e887ea33SDavid du Colombier 			v = reg[D_AX];
375e887ea33SDavid du Colombier 			reg[D_AX] = 0;
376e887ea33SDavid du Colombier 
377e887ea33SDavid du Colombier 			if(isreg(l, D_AX)) {
378e887ea33SDavid du Colombier 				nod3 = *n;
379e887ea33SDavid du Colombier 				nod3.left = &nod2;
380e887ea33SDavid du Colombier 				cgen(&nod3, nn);
381e887ea33SDavid du Colombier 			} else
382e887ea33SDavid du Colombier 			if(isreg(r, D_AX)) {
383e887ea33SDavid du Colombier 				nod3 = *n;
384e887ea33SDavid du Colombier 				nod3.right = &nod2;
385e887ea33SDavid du Colombier 				cgen(&nod3, nn);
386e887ea33SDavid du Colombier 			} else
387e887ea33SDavid du Colombier 				cgen(n, nn);
388e887ea33SDavid du Colombier 
389e887ea33SDavid du Colombier 			gmove(&nod2, &nod);
390e887ea33SDavid du Colombier 			reg[D_AX] = v;
391e887ea33SDavid du Colombier 			break;
392e887ea33SDavid du Colombier 		}
393e887ea33SDavid du Colombier 		if(nodreg(&nod1, nn, D_DX)) {
394e887ea33SDavid du Colombier 			regsalloc(&nod2, n);
395e887ea33SDavid du Colombier 			gmove(&nod1, &nod2);
396e887ea33SDavid du Colombier 			v = reg[D_DX];
397e887ea33SDavid du Colombier 			reg[D_DX] = 0;
398e887ea33SDavid du Colombier 
399e887ea33SDavid du Colombier 			if(isreg(l, D_DX)) {
400e887ea33SDavid du Colombier 				nod3 = *n;
401e887ea33SDavid du Colombier 				nod3.left = &nod2;
402e887ea33SDavid du Colombier 				cgen(&nod3, nn);
403e887ea33SDavid du Colombier 			} else
404e887ea33SDavid du Colombier 			if(isreg(r, D_DX)) {
405e887ea33SDavid du Colombier 				nod3 = *n;
406e887ea33SDavid du Colombier 				nod3.right = &nod2;
407e887ea33SDavid du Colombier 				cgen(&nod3, nn);
408e887ea33SDavid du Colombier 			} else
409e887ea33SDavid du Colombier 				cgen(n, nn);
410e887ea33SDavid du Colombier 
411e887ea33SDavid du Colombier 			gmove(&nod2, &nod1);
412e887ea33SDavid du Colombier 			reg[D_DX] = v;
413e887ea33SDavid du Colombier 			break;
414e887ea33SDavid du Colombier 		}
415e887ea33SDavid du Colombier 		reg[D_AX]++;
416e887ea33SDavid du Colombier 
417e887ea33SDavid du Colombier 		if(r->op == OCONST && (o == ODIV || o == OLDIV) && immconst(r) && typechl[r->type->etype]) {
418e887ea33SDavid du Colombier 			reg[D_DX]++;
419e887ea33SDavid du Colombier 			if(l->addable < INDEXED) {
420e887ea33SDavid du Colombier 				regalloc(&nod2, l, Z);
421e887ea33SDavid du Colombier 				cgen(l, &nod2);
422e887ea33SDavid du Colombier 				l = &nod2;
423e887ea33SDavid du Colombier 			}
424e887ea33SDavid du Colombier 			if(o == ODIV)
425e887ea33SDavid du Colombier 				sdivgen(l, r, &nod, &nod1);
426e887ea33SDavid du Colombier 			else
427e887ea33SDavid du Colombier 				udivgen(l, r, &nod, &nod1);
428e887ea33SDavid du Colombier 			gmove(&nod1, nn);
429e887ea33SDavid du Colombier 			if(l == &nod2)
430e887ea33SDavid du Colombier 				regfree(l);
431e887ea33SDavid du Colombier 			goto freeaxdx;
432e887ea33SDavid du Colombier 		}
433e887ea33SDavid du Colombier 
434e887ea33SDavid du Colombier 		if(l->complex >= r->complex) {
435e887ea33SDavid du Colombier 			cgen(l, &nod);
436e887ea33SDavid du Colombier 			reg[D_DX]++;
437e887ea33SDavid du Colombier 			if(o == ODIV || o == OMOD)
438e887ea33SDavid du Colombier 				gins(typechl[l->type->etype]? ACDQ: ACQO, Z, Z);
439e887ea33SDavid du Colombier 			if(o == OLDIV || o == OLMOD)
440e887ea33SDavid du Colombier 				zeroregm(&nod1);
441e887ea33SDavid du Colombier 			if(r->addable < INDEXED || r->op == OCONST) {
442e887ea33SDavid du Colombier 				regalloc(&nod3, r, Z);
443e887ea33SDavid du Colombier 				cgen(r, &nod3);
444e887ea33SDavid du Colombier 				gopcode(o, n->type, &nod3, Z);
445e887ea33SDavid du Colombier 				regfree(&nod3);
446e887ea33SDavid du Colombier 			} else
447e887ea33SDavid du Colombier 				gopcode(o, n->type, r, Z);
448e887ea33SDavid du Colombier 		} else {
449e887ea33SDavid du Colombier 			regsalloc(&nod3, r);
450e887ea33SDavid du Colombier 			cgen(r, &nod3);
451e887ea33SDavid du Colombier 			cgen(l, &nod);
452e887ea33SDavid du Colombier 			reg[D_DX]++;
453e887ea33SDavid du Colombier 			if(o == ODIV || o == OMOD)
454e887ea33SDavid du Colombier 				gins(typechl[l->type->etype]? ACDQ: ACQO, Z, Z);
455e887ea33SDavid du Colombier 			if(o == OLDIV || o == OLMOD)
456e887ea33SDavid du Colombier 				zeroregm(&nod1);
457e887ea33SDavid du Colombier 			gopcode(o, n->type, &nod3, Z);
458e887ea33SDavid du Colombier 		}
459e887ea33SDavid du Colombier 		if(o == OMOD || o == OLMOD)
460e887ea33SDavid du Colombier 			gmove(&nod1, nn);
461e887ea33SDavid du Colombier 		else
462e887ea33SDavid du Colombier 			gmove(&nod, nn);
463e887ea33SDavid du Colombier 	freeaxdx:
464e887ea33SDavid du Colombier 		regfree(&nod);
465e887ea33SDavid du Colombier 		regfree(&nod1);
466e887ea33SDavid du Colombier 		break;
467e887ea33SDavid du Colombier 
468e887ea33SDavid du Colombier 	case OASLSHR:
469e887ea33SDavid du Colombier 	case OASASHL:
470e887ea33SDavid du Colombier 	case OASASHR:
471e887ea33SDavid du Colombier 		if(r->op == OCONST)
472e887ea33SDavid du Colombier 			goto asand;
473e887ea33SDavid du Colombier 		if(l->op == OBIT)
474e887ea33SDavid du Colombier 			goto asbitop;
475e887ea33SDavid du Colombier 
476e887ea33SDavid du Colombier 		/*
477e887ea33SDavid du Colombier 		 * get nod to be D_CX
478e887ea33SDavid du Colombier 		 */
479e887ea33SDavid du Colombier 		if(nodreg(&nod, nn, D_CX)) {
480e887ea33SDavid du Colombier 			regsalloc(&nod1, n);
481e887ea33SDavid du Colombier 			gmove(&nod, &nod1);
482e887ea33SDavid du Colombier 			cgen(n, &nod);
483e887ea33SDavid du Colombier 			if(nn != Z)
484e887ea33SDavid du Colombier 				gmove(&nod, nn);
485e887ea33SDavid du Colombier 			gmove(&nod1, &nod);
486e887ea33SDavid du Colombier 			break;
487e887ea33SDavid du Colombier 		}
488e887ea33SDavid du Colombier 		reg[D_CX]++;
489e887ea33SDavid du Colombier 
490e887ea33SDavid du Colombier 		if(r->complex >= l->complex) {
491e887ea33SDavid du Colombier 			cgen(r, &nod);
492e887ea33SDavid du Colombier 			if(hardleft)
493e887ea33SDavid du Colombier 				reglcgen(&nod1, l, Z);
494e887ea33SDavid du Colombier 			else
495e887ea33SDavid du Colombier 				nod1 = *l;
496e887ea33SDavid du Colombier 		} else {
497e887ea33SDavid du Colombier 			if(hardleft)
498e887ea33SDavid du Colombier 				reglcgen(&nod1, l, Z);
499e887ea33SDavid du Colombier 			else
500e887ea33SDavid du Colombier 				nod1 = *l;
501e887ea33SDavid du Colombier 			cgen(r, &nod);
502e887ea33SDavid du Colombier 		}
503e887ea33SDavid du Colombier 
504e887ea33SDavid du Colombier 		gopcode(o, l->type, &nod, &nod1);
505e887ea33SDavid du Colombier 		regfree(&nod);
506e887ea33SDavid du Colombier 		if(nn != Z)
507e887ea33SDavid du Colombier 			gmove(&nod1, nn);
508e887ea33SDavid du Colombier 		if(hardleft)
509e887ea33SDavid du Colombier 			regfree(&nod1);
510e887ea33SDavid du Colombier 		break;
511e887ea33SDavid du Colombier 
512e887ea33SDavid du Colombier 	case OASAND:
513e887ea33SDavid du Colombier 	case OASADD:
514e887ea33SDavid du Colombier 	case OASSUB:
515e887ea33SDavid du Colombier 	case OASXOR:
516e887ea33SDavid du Colombier 	case OASOR:
517e887ea33SDavid du Colombier 	asand:
518e887ea33SDavid du Colombier 		if(l->op == OBIT)
519e887ea33SDavid du Colombier 			goto asbitop;
520e887ea33SDavid du Colombier 		if(typefd[l->type->etype] || typefd[r->type->etype])
521e887ea33SDavid du Colombier 			goto asfop;
522e887ea33SDavid du Colombier 		if(l->complex >= r->complex) {
523e887ea33SDavid du Colombier 			if(hardleft)
524e887ea33SDavid du Colombier 				reglcgen(&nod, l, Z);
525e887ea33SDavid du Colombier 			else
526e887ea33SDavid du Colombier 				nod = *l;
527e887ea33SDavid du Colombier 			if(!immconst(r)) {
528e887ea33SDavid du Colombier 				regalloc(&nod1, r, nn);
529e887ea33SDavid du Colombier 				cgen(r, &nod1);
530e887ea33SDavid du Colombier 				gopcode(o, l->type, &nod1, &nod);
531e887ea33SDavid du Colombier 				regfree(&nod1);
532e887ea33SDavid du Colombier 			} else
533e887ea33SDavid du Colombier 				gopcode(o, l->type, r, &nod);
534e887ea33SDavid du Colombier 		} else {
535e887ea33SDavid du Colombier 			regalloc(&nod1, r, nn);
536e887ea33SDavid du Colombier 			cgen(r, &nod1);
537e887ea33SDavid du Colombier 			if(hardleft)
538e887ea33SDavid du Colombier 				reglcgen(&nod, l, Z);
539e887ea33SDavid du Colombier 			else
540e887ea33SDavid du Colombier 				nod = *l;
541e887ea33SDavid du Colombier 			gopcode(o, l->type, &nod1, &nod);
542e887ea33SDavid du Colombier 			regfree(&nod1);
543e887ea33SDavid du Colombier 		}
544e887ea33SDavid du Colombier 		if(nn != Z)
545e887ea33SDavid du Colombier 			gmove(&nod, nn);
546e887ea33SDavid du Colombier 		if(hardleft)
547e887ea33SDavid du Colombier 			regfree(&nod);
548e887ea33SDavid du Colombier 		break;
549e887ea33SDavid du Colombier 
550e887ea33SDavid du Colombier 	asfop:
551e887ea33SDavid du Colombier 		if(l->complex >= r->complex) {
552e887ea33SDavid du Colombier 			if(hardleft)
553e887ea33SDavid du Colombier 				reglcgen(&nod, l, Z);
554e887ea33SDavid du Colombier 			else
555e887ea33SDavid du Colombier 				nod = *l;
556e887ea33SDavid du Colombier 			if(r->addable < INDEXED){
557e887ea33SDavid du Colombier 				regalloc(&nod1, r, nn);
558e887ea33SDavid du Colombier 				cgen(r, &nod1);
559e887ea33SDavid du Colombier 			}else
560e887ea33SDavid du Colombier 				nod1 = *r;
561e887ea33SDavid du Colombier 			regalloc(&nod2, r, Z);
562e887ea33SDavid du Colombier 			gmove(&nod, &nod2);
563e887ea33SDavid du Colombier 			gopcode(o, r->type, &nod1, &nod2);
564e887ea33SDavid du Colombier 			gmove(&nod2, &nod);
565e887ea33SDavid du Colombier 			regfree(&nod2);
566e887ea33SDavid du Colombier 			if(r->addable < INDEXED)
567e887ea33SDavid du Colombier 				regfree(&nod1);
568e887ea33SDavid du Colombier 		} else {
569e887ea33SDavid du Colombier 			regalloc(&nod1, r, nn);
570e887ea33SDavid du Colombier 			cgen(r, &nod1);
571e887ea33SDavid du Colombier 			if(hardleft)
572e887ea33SDavid du Colombier 				reglcgen(&nod, l, Z);
573e887ea33SDavid du Colombier 			else
574e887ea33SDavid du Colombier 				nod = *l;
5752e8f027cSDavid du Colombier 			if(o != OASMUL && o != OASADD || !typefd[l->type->etype]) {
576e887ea33SDavid du Colombier 				regalloc(&nod2, r, Z);
577e887ea33SDavid du Colombier 				gmove(&nod, &nod2);
578e887ea33SDavid du Colombier 				gopcode(o, r->type, &nod1, &nod2);
579e887ea33SDavid du Colombier 				regfree(&nod1);
580e887ea33SDavid du Colombier 				gmove(&nod2, &nod);
581e887ea33SDavid du Colombier 				regfree(&nod2);
582e887ea33SDavid du Colombier 			} else {
583e887ea33SDavid du Colombier 				gopcode(o, r->type, &nod, &nod1);
584e887ea33SDavid du Colombier 				gmove(&nod1, &nod);
585e887ea33SDavid du Colombier 				regfree(&nod1);
586e887ea33SDavid du Colombier 			}
587e887ea33SDavid du Colombier 		}
588e887ea33SDavid du Colombier 		if(nn != Z)
589e887ea33SDavid du Colombier 			gmove(&nod, nn);
590e887ea33SDavid du Colombier 		if(hardleft)
591e887ea33SDavid du Colombier 			regfree(&nod);
592e887ea33SDavid du Colombier 		break;
593e887ea33SDavid du Colombier 
594e887ea33SDavid du Colombier 	case OASLMUL:
595e887ea33SDavid du Colombier 	case OASLDIV:
596e887ea33SDavid du Colombier 	case OASLMOD:
597e887ea33SDavid du Colombier 	case OASMUL:
598e887ea33SDavid du Colombier 	case OASDIV:
599e887ea33SDavid du Colombier 	case OASMOD:
600e887ea33SDavid du Colombier 		if(l->op == OBIT)
601e887ea33SDavid du Colombier 			goto asbitop;
602e887ea33SDavid du Colombier 		if(typefd[n->type->etype] || typefd[r->type->etype])
603e887ea33SDavid du Colombier 			goto asfop;
604e887ea33SDavid du Colombier 		if(r->op == OCONST && typechl[n->type->etype]) {
605e887ea33SDavid du Colombier 			SET(v);
606e887ea33SDavid du Colombier 			switch(o) {
607e887ea33SDavid du Colombier 			case OASDIV:
608e887ea33SDavid du Colombier 			case OASMOD:
609e887ea33SDavid du Colombier 				c = r->vconst;
610e887ea33SDavid du Colombier 				if(c < 0)
611e887ea33SDavid du Colombier 					c = -c;
612e887ea33SDavid du Colombier 				v = log2(c);
613e887ea33SDavid du Colombier 				if(v < 0)
614e887ea33SDavid du Colombier 					break;
615e887ea33SDavid du Colombier 				/* fall thru */
616e887ea33SDavid du Colombier 			case OASMUL:
617e887ea33SDavid du Colombier 			case OASLMUL:
618e887ea33SDavid du Colombier 				if(hardleft)
619e887ea33SDavid du Colombier 					reglcgen(&nod2, l, Z);
620e887ea33SDavid du Colombier 				else
621e887ea33SDavid du Colombier 					nod2 = *l;
622e887ea33SDavid du Colombier 				regalloc(&nod, l, nn);
623e887ea33SDavid du Colombier 				cgen(&nod2, &nod);
624e887ea33SDavid du Colombier 				switch(o) {
625e887ea33SDavid du Colombier 				case OASMUL:
626e887ea33SDavid du Colombier 				case OASLMUL:
627e887ea33SDavid du Colombier 					mulgen(n->type, r, &nod);
628e887ea33SDavid du Colombier 					break;
629e887ea33SDavid du Colombier 				case OASDIV:
630e887ea33SDavid du Colombier 					sdiv2(r->vconst, v, l, &nod);
631e887ea33SDavid du Colombier 					break;
632e887ea33SDavid du Colombier 				case OASMOD:
633e887ea33SDavid du Colombier 					smod2(r->vconst, v, l, &nod);
634e887ea33SDavid du Colombier 					break;
635e887ea33SDavid du Colombier 				}
636e887ea33SDavid du Colombier 			havev:
637e887ea33SDavid du Colombier 				gmove(&nod, &nod2);
638e887ea33SDavid du Colombier 				if(nn != Z)
639e887ea33SDavid du Colombier 					gmove(&nod, nn);
640e887ea33SDavid du Colombier 				if(hardleft)
641e887ea33SDavid du Colombier 					regfree(&nod2);
642e887ea33SDavid du Colombier 				regfree(&nod);
643e887ea33SDavid du Colombier 				goto done;
644e887ea33SDavid du Colombier 			case OASLDIV:
645e887ea33SDavid du Colombier 				c = r->vconst;
646e887ea33SDavid du Colombier 				if((c & 0x80000000) == 0)
647e887ea33SDavid du Colombier 					break;
648e887ea33SDavid du Colombier 				if(hardleft)
649e887ea33SDavid du Colombier 					reglcgen(&nod2, l, Z);
650e887ea33SDavid du Colombier 				else
651e887ea33SDavid du Colombier 					nod2 = *l;
652e887ea33SDavid du Colombier 				regalloc(&nod1, l, nn);
653e887ea33SDavid du Colombier 				cgen(&nod2, &nod1);
654e887ea33SDavid du Colombier 				regalloc(&nod, l, nn);
655e887ea33SDavid du Colombier 				zeroregm(&nod);
656e887ea33SDavid du Colombier 				gins(ACMPL, &nod1, nodconst(c));
657e887ea33SDavid du Colombier 				gins(ASBBL, nodconst(-1), &nod);
658e887ea33SDavid du Colombier 				regfree(&nod1);
659e887ea33SDavid du Colombier 				goto havev;
660e887ea33SDavid du Colombier 			}
661e887ea33SDavid du Colombier 		}
662e887ea33SDavid du Colombier 
663e887ea33SDavid du Colombier 		if(o == OASMUL) {
664e887ea33SDavid du Colombier 			/* should favour AX */
665e887ea33SDavid du Colombier 			regalloc(&nod, l, nn);
666e887ea33SDavid du Colombier 			if(r->complex >= FNX) {
667e887ea33SDavid du Colombier 				regalloc(&nod1, r, Z);
668e887ea33SDavid du Colombier 				cgen(r, &nod1);
669e887ea33SDavid du Colombier 				r = &nod1;
670e887ea33SDavid du Colombier 			}
671e887ea33SDavid du Colombier 			if(hardleft)
672e887ea33SDavid du Colombier 				reglcgen(&nod2, l, Z);
673e887ea33SDavid du Colombier 			else
674e887ea33SDavid du Colombier 				nod2 = *l;
675e887ea33SDavid du Colombier 			cgen(&nod2, &nod);
676e887ea33SDavid du Colombier 			if(r->addable < INDEXED || hardconst(r)) {
677e887ea33SDavid du Colombier 				if(r->complex < FNX) {
678e887ea33SDavid du Colombier 					regalloc(&nod1, r, Z);
679e887ea33SDavid du Colombier 					cgen(r, &nod1);
680e887ea33SDavid du Colombier 				}
681e887ea33SDavid du Colombier 				gopcode(OASMUL, n->type, &nod1, &nod);
682e887ea33SDavid du Colombier 				regfree(&nod1);
683e887ea33SDavid du Colombier 			}
684e887ea33SDavid du Colombier 			else
685e887ea33SDavid du Colombier 				gopcode(OASMUL, n->type, r, &nod);
686e887ea33SDavid du Colombier 			if(r == &nod1)
687e887ea33SDavid du Colombier 				regfree(r);
688e887ea33SDavid du Colombier 			gmove(&nod, &nod2);
689e887ea33SDavid du Colombier 			if(nn != Z)
690e887ea33SDavid du Colombier 				gmove(&nod, nn);
691e887ea33SDavid du Colombier 			regfree(&nod);
692e887ea33SDavid du Colombier 			if(hardleft)
693e887ea33SDavid du Colombier 				regfree(&nod2);
694e887ea33SDavid du Colombier 			break;
695e887ea33SDavid du Colombier 		}
696e887ea33SDavid du Colombier 
697e887ea33SDavid du Colombier 		/*
698e887ea33SDavid du Colombier 		 * get nod to be D_AX
699e887ea33SDavid du Colombier 		 * get nod1 to be D_DX
700e887ea33SDavid du Colombier 		 */
701e887ea33SDavid du Colombier 		if(nodreg(&nod, nn, D_AX)) {
702e887ea33SDavid du Colombier 			regsalloc(&nod2, n);
703e887ea33SDavid du Colombier 			gmove(&nod, &nod2);
704e887ea33SDavid du Colombier 			v = reg[D_AX];
705e887ea33SDavid du Colombier 			reg[D_AX] = 0;
706e887ea33SDavid du Colombier 
707e887ea33SDavid du Colombier 			if(isreg(l, D_AX)) {
708e887ea33SDavid du Colombier 				nod3 = *n;
709e887ea33SDavid du Colombier 				nod3.left = &nod2;
710e887ea33SDavid du Colombier 				cgen(&nod3, nn);
711e887ea33SDavid du Colombier 			} else
712e887ea33SDavid du Colombier 			if(isreg(r, D_AX)) {
713e887ea33SDavid du Colombier 				nod3 = *n;
714e887ea33SDavid du Colombier 				nod3.right = &nod2;
715e887ea33SDavid du Colombier 				cgen(&nod3, nn);
716e887ea33SDavid du Colombier 			} else
717e887ea33SDavid du Colombier 				cgen(n, nn);
718e887ea33SDavid du Colombier 
719e887ea33SDavid du Colombier 			gmove(&nod2, &nod);
720e887ea33SDavid du Colombier 			reg[D_AX] = v;
721e887ea33SDavid du Colombier 			break;
722e887ea33SDavid du Colombier 		}
723e887ea33SDavid du Colombier 		if(nodreg(&nod1, nn, D_DX)) {
724e887ea33SDavid du Colombier 			regsalloc(&nod2, n);
725e887ea33SDavid du Colombier 			gmove(&nod1, &nod2);
726e887ea33SDavid du Colombier 			v = reg[D_DX];
727e887ea33SDavid du Colombier 			reg[D_DX] = 0;
728e887ea33SDavid du Colombier 
729e887ea33SDavid du Colombier 			if(isreg(l, D_DX)) {
730e887ea33SDavid du Colombier 				nod3 = *n;
731e887ea33SDavid du Colombier 				nod3.left = &nod2;
732e887ea33SDavid du Colombier 				cgen(&nod3, nn);
733e887ea33SDavid du Colombier 			} else
734e887ea33SDavid du Colombier 			if(isreg(r, D_DX)) {
735e887ea33SDavid du Colombier 				nod3 = *n;
736e887ea33SDavid du Colombier 				nod3.right = &nod2;
737e887ea33SDavid du Colombier 				cgen(&nod3, nn);
738e887ea33SDavid du Colombier 			} else
739e887ea33SDavid du Colombier 				cgen(n, nn);
740e887ea33SDavid du Colombier 
741e887ea33SDavid du Colombier 			gmove(&nod2, &nod1);
742e887ea33SDavid du Colombier 			reg[D_DX] = v;
743e887ea33SDavid du Colombier 			break;
744e887ea33SDavid du Colombier 		}
745e887ea33SDavid du Colombier 		reg[D_AX]++;
746e887ea33SDavid du Colombier 		reg[D_DX]++;
747e887ea33SDavid du Colombier 
748e887ea33SDavid du Colombier 		if(l->complex >= r->complex) {
749e887ea33SDavid du Colombier 			if(hardleft)
750e887ea33SDavid du Colombier 				reglcgen(&nod2, l, Z);
751e887ea33SDavid du Colombier 			else
752e887ea33SDavid du Colombier 				nod2 = *l;
753e887ea33SDavid du Colombier 			cgen(&nod2, &nod);
754e887ea33SDavid du Colombier 			if(r->op == OCONST && typechl[r->type->etype]) {
755e887ea33SDavid du Colombier 				switch(o) {
756e887ea33SDavid du Colombier 				case OASDIV:
757e887ea33SDavid du Colombier 					sdivgen(&nod2, r, &nod, &nod1);
758e887ea33SDavid du Colombier 					goto divdone;
759e887ea33SDavid du Colombier 				case OASLDIV:
760e887ea33SDavid du Colombier 					udivgen(&nod2, r, &nod, &nod1);
761e887ea33SDavid du Colombier 				divdone:
762e887ea33SDavid du Colombier 					gmove(&nod1, &nod2);
763e887ea33SDavid du Colombier 					if(nn != Z)
764e887ea33SDavid du Colombier 						gmove(&nod1, nn);
765e887ea33SDavid du Colombier 					goto freelxaxdx;
766e887ea33SDavid du Colombier 				}
767e887ea33SDavid du Colombier 			}
768e887ea33SDavid du Colombier 			if(o == OASDIV || o == OASMOD)
769e887ea33SDavid du Colombier 				gins(typechl[l->type->etype]? ACDQ: ACQO, Z, Z);
770e887ea33SDavid du Colombier 			if(o == OASLDIV || o == OASLMOD)
771e887ea33SDavid du Colombier 				zeroregm(&nod1);
772e887ea33SDavid du Colombier 			if(r->addable < INDEXED || r->op == OCONST ||
773e887ea33SDavid du Colombier 			   !typeil[r->type->etype]) {
774e887ea33SDavid du Colombier 				regalloc(&nod3, r, Z);
775e887ea33SDavid du Colombier 				cgen(r, &nod3);
776e887ea33SDavid du Colombier 				gopcode(o, l->type, &nod3, Z);
777e887ea33SDavid du Colombier 				regfree(&nod3);
778e887ea33SDavid du Colombier 			} else
779e887ea33SDavid du Colombier 				gopcode(o, n->type, r, Z);
780e887ea33SDavid du Colombier 		} else {
781e887ea33SDavid du Colombier 			regalloc(&nod3, r, Z);
782e887ea33SDavid du Colombier 			cgen(r, &nod3);
783e887ea33SDavid du Colombier 			if(hardleft)
784e887ea33SDavid du Colombier 				reglcgen(&nod2, l, Z);
785e887ea33SDavid du Colombier 			else
786e887ea33SDavid du Colombier 				nod2 = *l;
787e887ea33SDavid du Colombier 			cgen(&nod2, &nod);
788e887ea33SDavid du Colombier 			if(o == OASDIV || o == OASMOD)
789e887ea33SDavid du Colombier 				gins(typechl[l->type->etype]? ACDQ: ACQO, Z, Z);
790e887ea33SDavid du Colombier 			if(o == OASLDIV || o == OASLMOD)
791e887ea33SDavid du Colombier 				zeroregm(&nod1);
792e887ea33SDavid du Colombier 			gopcode(o, l->type, &nod3, Z);
793e887ea33SDavid du Colombier 			regfree(&nod3);
794e887ea33SDavid du Colombier 		}
795e887ea33SDavid du Colombier 		if(o == OASMOD || o == OASLMOD) {
796e887ea33SDavid du Colombier 			gmove(&nod1, &nod2);
797e887ea33SDavid du Colombier 			if(nn != Z)
798e887ea33SDavid du Colombier 				gmove(&nod1, nn);
799e887ea33SDavid du Colombier 		} else {
800e887ea33SDavid du Colombier 			gmove(&nod, &nod2);
801e887ea33SDavid du Colombier 			if(nn != Z)
802e887ea33SDavid du Colombier 				gmove(&nod, nn);
803e887ea33SDavid du Colombier 		}
804e887ea33SDavid du Colombier 	freelxaxdx:
805e887ea33SDavid du Colombier 		if(hardleft)
806e887ea33SDavid du Colombier 			regfree(&nod2);
807e887ea33SDavid du Colombier 		regfree(&nod);
808e887ea33SDavid du Colombier 		regfree(&nod1);
809e887ea33SDavid du Colombier 		break;
810e887ea33SDavid du Colombier 
811e887ea33SDavid du Colombier 	fop:
812e887ea33SDavid du Colombier 		if(l->complex >= r->complex) {
813e887ea33SDavid du Colombier 			regalloc(&nod, l, nn);
814e887ea33SDavid du Colombier 			cgen(l, &nod);
815e887ea33SDavid du Colombier 			if(r->addable < INDEXED) {
816e887ea33SDavid du Colombier 				regalloc(&nod1, r, Z);
817e887ea33SDavid du Colombier 				cgen(r, &nod1);
818e887ea33SDavid du Colombier 				gopcode(o, n->type, &nod1, &nod);
819e887ea33SDavid du Colombier 				regfree(&nod1);
820e887ea33SDavid du Colombier 			} else
821e887ea33SDavid du Colombier 				gopcode(o, n->type, r, &nod);
822e887ea33SDavid du Colombier 		} else {
823e887ea33SDavid du Colombier 			/* TO DO: could do better with r->addable >= INDEXED */
824e887ea33SDavid du Colombier 			regalloc(&nod1, r, Z);
825e887ea33SDavid du Colombier 			cgen(r, &nod1);
826e887ea33SDavid du Colombier 			regalloc(&nod, l, nn);
827e887ea33SDavid du Colombier 			cgen(l, &nod);
828e887ea33SDavid du Colombier 			gopcode(o, n->type, &nod1, &nod);
829e887ea33SDavid du Colombier 			regfree(&nod1);
830e887ea33SDavid du Colombier 		}
831e887ea33SDavid du Colombier 		gmove(&nod, nn);
832e887ea33SDavid du Colombier 		regfree(&nod);
833e887ea33SDavid du Colombier 		break;
834e887ea33SDavid du Colombier 
835e887ea33SDavid du Colombier 	asbitop:
836e887ea33SDavid du Colombier 		regalloc(&nod4, n, nn);
837e887ea33SDavid du Colombier 		if(l->complex >= r->complex) {
838e887ea33SDavid du Colombier 			bitload(l, &nod, &nod1, &nod2, &nod4);
839e887ea33SDavid du Colombier 			regalloc(&nod3, r, Z);
840e887ea33SDavid du Colombier 			cgen(r, &nod3);
841e887ea33SDavid du Colombier 		} else {
842e887ea33SDavid du Colombier 			regalloc(&nod3, r, Z);
843e887ea33SDavid du Colombier 			cgen(r, &nod3);
844e887ea33SDavid du Colombier 			bitload(l, &nod, &nod1, &nod2, &nod4);
845e887ea33SDavid du Colombier 		}
846e887ea33SDavid du Colombier 		gmove(&nod, &nod4);
847e887ea33SDavid du Colombier 
848e887ea33SDavid du Colombier 		{	/* TO DO: check floating point source */
849e887ea33SDavid du Colombier 			Node onod;
850e887ea33SDavid du Colombier 
851e887ea33SDavid du Colombier 			/* incredible grot ... */
852e887ea33SDavid du Colombier 			onod = nod3;
853e887ea33SDavid du Colombier 			onod.op = o;
854e887ea33SDavid du Colombier 			onod.complex = 2;
855e887ea33SDavid du Colombier 			onod.addable = 0;
856e887ea33SDavid du Colombier 			onod.type = tfield;
857e887ea33SDavid du Colombier 			onod.left = &nod4;
858e887ea33SDavid du Colombier 			onod.right = &nod3;
859e887ea33SDavid du Colombier 			cgen(&onod, Z);
860e887ea33SDavid du Colombier 		}
861e887ea33SDavid du Colombier 		regfree(&nod3);
862e887ea33SDavid du Colombier 		gmove(&nod4, &nod);
863e887ea33SDavid du Colombier 		regfree(&nod4);
864e887ea33SDavid du Colombier 		bitstore(l, &nod, &nod1, &nod2, nn);
865e887ea33SDavid du Colombier 		break;
866e887ea33SDavid du Colombier 
867e887ea33SDavid du Colombier 	case OADDR:
868e887ea33SDavid du Colombier 		if(nn == Z) {
869e887ea33SDavid du Colombier 			nullwarn(l, Z);
870e887ea33SDavid du Colombier 			break;
871e887ea33SDavid du Colombier 		}
872e887ea33SDavid du Colombier 		lcgen(l, nn);
873e887ea33SDavid du Colombier 		break;
874e887ea33SDavid du Colombier 
875e887ea33SDavid du Colombier 	case OFUNC:
876e887ea33SDavid du Colombier 		if(l->complex >= FNX) {
877e887ea33SDavid du Colombier 			if(l->op != OIND)
878e887ea33SDavid du Colombier 				diag(n, "bad function call");
879e887ea33SDavid du Colombier 
880e887ea33SDavid du Colombier 			regret(&nod, l->left);
881e887ea33SDavid du Colombier 			cgen(l->left, &nod);
882e887ea33SDavid du Colombier 			regsalloc(&nod1, l->left);
883e887ea33SDavid du Colombier 			gmove(&nod, &nod1);
884e887ea33SDavid du Colombier 			regfree(&nod);
885e887ea33SDavid du Colombier 
886e887ea33SDavid du Colombier 			nod = *n;
887e887ea33SDavid du Colombier 			nod.left = &nod2;
888e887ea33SDavid du Colombier 			nod2 = *l;
889e887ea33SDavid du Colombier 			nod2.left = &nod1;
890e887ea33SDavid du Colombier 			nod2.complex = 1;
891e887ea33SDavid du Colombier 			cgen(&nod, nn);
892e887ea33SDavid du Colombier 
893e887ea33SDavid du Colombier 			return;
894e887ea33SDavid du Colombier 		}
895e887ea33SDavid du Colombier 		o = reg[REGARG];
896e887ea33SDavid du Colombier 		gargs(r, &nod, &nod1);
897e887ea33SDavid du Colombier 		if(l->addable < INDEXED) {
898e887ea33SDavid du Colombier 			reglcgen(&nod, l, nn);
899e887ea33SDavid du Colombier 			nod.op = OREGISTER;
900e887ea33SDavid du Colombier 			gopcode(OFUNC, n->type, Z, &nod);
901e887ea33SDavid du Colombier 			regfree(&nod);
902e887ea33SDavid du Colombier 		} else
903e887ea33SDavid du Colombier 			gopcode(OFUNC, n->type, Z, l);
904e887ea33SDavid du Colombier 		if(REGARG)
905e887ea33SDavid du Colombier 			if(o != reg[REGARG])
906e887ea33SDavid du Colombier 				reg[REGARG]--;
907e887ea33SDavid du Colombier 		if(nn != Z) {
908e887ea33SDavid du Colombier 			regret(&nod, n);
909e887ea33SDavid du Colombier 			gmove(&nod, nn);
910e887ea33SDavid du Colombier 			regfree(&nod);
911e887ea33SDavid du Colombier 		}
912e887ea33SDavid du Colombier 		break;
913e887ea33SDavid du Colombier 
914e887ea33SDavid du Colombier 	case OIND:
915e887ea33SDavid du Colombier 		if(nn == Z) {
916e887ea33SDavid du Colombier 			nullwarn(l, Z);
917e887ea33SDavid du Colombier 			break;
918e887ea33SDavid du Colombier 		}
919e887ea33SDavid du Colombier 		regialloc(&nod, n, nn);
920e887ea33SDavid du Colombier 		r = l;
921e887ea33SDavid du Colombier 		while(r->op == OADD)
922e887ea33SDavid du Colombier 			r = r->right;
923e887ea33SDavid du Colombier 		if(sconst(r)) {
924e887ea33SDavid du Colombier 			v = r->vconst;
925e887ea33SDavid du Colombier 			r->vconst = 0;
926e887ea33SDavid du Colombier 			cgen(l, &nod);
927e887ea33SDavid du Colombier 			nod.xoffset += v;
928e887ea33SDavid du Colombier 			r->vconst = v;
929e887ea33SDavid du Colombier 		} else
930e887ea33SDavid du Colombier 			cgen(l, &nod);
931e887ea33SDavid du Colombier 		regind(&nod, n);
932e887ea33SDavid du Colombier 		gmove(&nod, nn);
933e887ea33SDavid du Colombier 		regfree(&nod);
934e887ea33SDavid du Colombier 		break;
935e887ea33SDavid du Colombier 
936e887ea33SDavid du Colombier 	case OEQ:
937e887ea33SDavid du Colombier 	case ONE:
938e887ea33SDavid du Colombier 	case OLE:
939e887ea33SDavid du Colombier 	case OLT:
940e887ea33SDavid du Colombier 	case OGE:
941e887ea33SDavid du Colombier 	case OGT:
942e887ea33SDavid du Colombier 	case OLO:
943e887ea33SDavid du Colombier 	case OLS:
944e887ea33SDavid du Colombier 	case OHI:
945e887ea33SDavid du Colombier 	case OHS:
946e887ea33SDavid du Colombier 		if(nn == Z) {
947e887ea33SDavid du Colombier 			nullwarn(l, r);
948e887ea33SDavid du Colombier 			break;
949e887ea33SDavid du Colombier 		}
950e887ea33SDavid du Colombier 		boolgen(n, 1, nn);
951e887ea33SDavid du Colombier 		break;
952e887ea33SDavid du Colombier 
953e887ea33SDavid du Colombier 	case OANDAND:
954e887ea33SDavid du Colombier 	case OOROR:
955e887ea33SDavid du Colombier 		boolgen(n, 1, nn);
956e887ea33SDavid du Colombier 		if(nn == Z)
957e887ea33SDavid du Colombier 			patch(p, pc);
958e887ea33SDavid du Colombier 		break;
959e887ea33SDavid du Colombier 
960e887ea33SDavid du Colombier 	case ONOT:
961e887ea33SDavid du Colombier 		if(nn == Z) {
962e887ea33SDavid du Colombier 			nullwarn(l, Z);
963e887ea33SDavid du Colombier 			break;
964e887ea33SDavid du Colombier 		}
965e887ea33SDavid du Colombier 		boolgen(n, 1, nn);
966e887ea33SDavid du Colombier 		break;
967e887ea33SDavid du Colombier 
968e887ea33SDavid du Colombier 	case OCOMMA:
969e887ea33SDavid du Colombier 		cgen(l, Z);
970e887ea33SDavid du Colombier 		cgen(r, nn);
971e887ea33SDavid du Colombier 		break;
972e887ea33SDavid du Colombier 
973e887ea33SDavid du Colombier 	case OCAST:
974e887ea33SDavid du Colombier 		if(nn == Z) {
975e887ea33SDavid du Colombier 			nullwarn(l, Z);
976e887ea33SDavid du Colombier 			break;
977e887ea33SDavid du Colombier 		}
978e887ea33SDavid du Colombier 		/*
979e887ea33SDavid du Colombier 		 * convert from types l->n->nn
980e887ea33SDavid du Colombier 		 */
981e887ea33SDavid du Colombier 		if(nocast(l->type, n->type) && nocast(n->type, nn->type)) {
982e887ea33SDavid du Colombier 			/* both null, gen l->nn */
983e887ea33SDavid du Colombier 			cgen(l, nn);
984e887ea33SDavid du Colombier 			break;
985e887ea33SDavid du Colombier 		}
986e887ea33SDavid du Colombier 		if(ewidth[n->type->etype] < ewidth[l->type->etype]){
987e887ea33SDavid du Colombier 			if(l->type->etype == TIND && typechlp[n->type->etype])
988e887ea33SDavid du Colombier 				warn(n, "conversion of pointer to shorter integer");
989e887ea33SDavid du Colombier 		}else if(0){
990e887ea33SDavid du Colombier 			if(nocast(n->type, nn->type) || castup(n->type, nn->type)){
991e887ea33SDavid du Colombier 				if(typefd[l->type->etype] != typefd[nn->type->etype])
992e887ea33SDavid du Colombier 					regalloc(&nod, l, nn);
993e887ea33SDavid du Colombier 				else
994e887ea33SDavid du Colombier 					regalloc(&nod, nn, nn);
995e887ea33SDavid du Colombier 				cgen(l, &nod);
996e887ea33SDavid du Colombier 				gmove(&nod, nn);
997e887ea33SDavid du Colombier 				regfree(&nod);
998e887ea33SDavid du Colombier 				break;
999e887ea33SDavid du Colombier 			}
1000e887ea33SDavid du Colombier 		}
1001e887ea33SDavid du Colombier 		regalloc(&nod, l, nn);
1002e887ea33SDavid du Colombier 		cgen(l, &nod);
1003e887ea33SDavid du Colombier 		regalloc(&nod1, n, &nod);
1004e887ea33SDavid du Colombier 		gmove(&nod, &nod1);
1005e887ea33SDavid du Colombier 		gmove(&nod1, nn);
1006e887ea33SDavid du Colombier 		regfree(&nod1);
1007e887ea33SDavid du Colombier 		regfree(&nod);
1008e887ea33SDavid du Colombier 		break;
1009e887ea33SDavid du Colombier 
1010e887ea33SDavid du Colombier 	case ODOT:
1011e887ea33SDavid du Colombier 		sugen(l, nodrat, l->type->width);
1012e887ea33SDavid du Colombier 		if(nn == Z)
1013e887ea33SDavid du Colombier 			break;
1014e887ea33SDavid du Colombier 		warn(n, "non-interruptable temporary");
1015e887ea33SDavid du Colombier 		nod = *nodrat;
1016e887ea33SDavid du Colombier 		if(!r || r->op != OCONST) {
1017e887ea33SDavid du Colombier 			diag(n, "DOT and no offset");
1018e887ea33SDavid du Colombier 			break;
1019e887ea33SDavid du Colombier 		}
1020e887ea33SDavid du Colombier 		nod.xoffset += (long)r->vconst;
1021e887ea33SDavid du Colombier 		nod.type = n->type;
1022e887ea33SDavid du Colombier 		cgen(&nod, nn);
1023e887ea33SDavid du Colombier 		break;
1024e887ea33SDavid du Colombier 
1025e887ea33SDavid du Colombier 	case OCOND:
1026e887ea33SDavid du Colombier 		bcgen(l, 1);
1027e887ea33SDavid du Colombier 		p1 = p;
1028e887ea33SDavid du Colombier 		cgen(r->left, nn);
1029e887ea33SDavid du Colombier 		gbranch(OGOTO);
1030e887ea33SDavid du Colombier 		patch(p1, pc);
1031e887ea33SDavid du Colombier 		p1 = p;
1032e887ea33SDavid du Colombier 		cgen(r->right, nn);
1033e887ea33SDavid du Colombier 		patch(p1, pc);
1034e887ea33SDavid du Colombier 		break;
1035e887ea33SDavid du Colombier 
1036e887ea33SDavid du Colombier 	case OPOSTINC:
1037e887ea33SDavid du Colombier 	case OPOSTDEC:
1038e887ea33SDavid du Colombier 		v = 1;
1039e887ea33SDavid du Colombier 		if(l->type->etype == TIND)
1040e887ea33SDavid du Colombier 			v = l->type->link->width;
1041e887ea33SDavid du Colombier 		if(o == OPOSTDEC)
1042e887ea33SDavid du Colombier 			v = -v;
1043e887ea33SDavid du Colombier 		if(l->op == OBIT)
1044e887ea33SDavid du Colombier 			goto bitinc;
1045e887ea33SDavid du Colombier 		if(nn == Z)
1046e887ea33SDavid du Colombier 			goto pre;
1047e887ea33SDavid du Colombier 
1048e887ea33SDavid du Colombier 		if(hardleft)
1049e887ea33SDavid du Colombier 			reglcgen(&nod, l, Z);
1050e887ea33SDavid du Colombier 		else
1051e887ea33SDavid du Colombier 			nod = *l;
1052e887ea33SDavid du Colombier 
1053e887ea33SDavid du Colombier 		gmove(&nod, nn);
1054e887ea33SDavid du Colombier 		if(typefd[n->type->etype]) {
1055e887ea33SDavid du Colombier 			regalloc(&nod1, l, Z);
1056e887ea33SDavid du Colombier 			gmove(&nod, &nod1);
1057e887ea33SDavid du Colombier 			if(v < 0)
1058e887ea33SDavid du Colombier 				gopcode(OSUB, n->type, nodfconst(-v), &nod1);
1059e887ea33SDavid du Colombier 			else
1060e887ea33SDavid du Colombier 				gopcode(OADD, n->type, nodfconst(v), &nod1);
1061e887ea33SDavid du Colombier 			gmove(&nod1, &nod);
1062e887ea33SDavid du Colombier 			regfree(&nod1);
1063e887ea33SDavid du Colombier 		} else
1064e887ea33SDavid du Colombier 			gopcode(OADD, n->type, nodconst(v), &nod);
1065e887ea33SDavid du Colombier 		if(hardleft)
1066e887ea33SDavid du Colombier 			regfree(&nod);
1067e887ea33SDavid du Colombier 		break;
1068e887ea33SDavid du Colombier 
1069e887ea33SDavid du Colombier 	case OPREINC:
1070e887ea33SDavid du Colombier 	case OPREDEC:
1071e887ea33SDavid du Colombier 		v = 1;
1072e887ea33SDavid du Colombier 		if(l->type->etype == TIND)
1073e887ea33SDavid du Colombier 			v = l->type->link->width;
1074e887ea33SDavid du Colombier 		if(o == OPREDEC)
1075e887ea33SDavid du Colombier 			v = -v;
1076e887ea33SDavid du Colombier 		if(l->op == OBIT)
1077e887ea33SDavid du Colombier 			goto bitinc;
1078e887ea33SDavid du Colombier 
1079e887ea33SDavid du Colombier 	pre:
1080e887ea33SDavid du Colombier 		if(hardleft)
1081e887ea33SDavid du Colombier 			reglcgen(&nod, l, Z);
1082e887ea33SDavid du Colombier 		else
1083e887ea33SDavid du Colombier 			nod = *l;
1084e887ea33SDavid du Colombier 		if(typefd[n->type->etype]) {
1085e887ea33SDavid du Colombier 			regalloc(&nod1, l, Z);
1086e887ea33SDavid du Colombier 			gmove(&nod, &nod1);
1087e887ea33SDavid du Colombier 			if(v < 0)
1088e887ea33SDavid du Colombier 				gopcode(OSUB, n->type, nodfconst(-v), &nod1);
1089e887ea33SDavid du Colombier 			else
1090e887ea33SDavid du Colombier 				gopcode(OADD, n->type, nodfconst(v), &nod1);
1091e887ea33SDavid du Colombier 			gmove(&nod1, &nod);
1092e887ea33SDavid du Colombier 			regfree(&nod1);
1093e887ea33SDavid du Colombier 		} else
1094e887ea33SDavid du Colombier 			gopcode(OADD, n->type, nodconst(v), &nod);
1095e887ea33SDavid du Colombier 		if(nn != Z)
1096e887ea33SDavid du Colombier 			gmove(&nod, nn);
1097e887ea33SDavid du Colombier 		if(hardleft)
1098e887ea33SDavid du Colombier 			regfree(&nod);
1099e887ea33SDavid du Colombier 		break;
1100e887ea33SDavid du Colombier 
1101e887ea33SDavid du Colombier 	bitinc:
1102e887ea33SDavid du Colombier 		if(nn != Z && (o == OPOSTINC || o == OPOSTDEC)) {
1103e887ea33SDavid du Colombier 			bitload(l, &nod, &nod1, &nod2, Z);
1104e887ea33SDavid du Colombier 			gmove(&nod, nn);
1105e887ea33SDavid du Colombier 			gopcode(OADD, tfield, nodconst(v), &nod);
1106e887ea33SDavid du Colombier 			bitstore(l, &nod, &nod1, &nod2, Z);
1107e887ea33SDavid du Colombier 			break;
1108e887ea33SDavid du Colombier 		}
1109e887ea33SDavid du Colombier 		bitload(l, &nod, &nod1, &nod2, nn);
1110e887ea33SDavid du Colombier 		gopcode(OADD, tfield, nodconst(v), &nod);
1111e887ea33SDavid du Colombier 		bitstore(l, &nod, &nod1, &nod2, nn);
1112e887ea33SDavid du Colombier 		break;
1113e887ea33SDavid du Colombier 	}
1114e887ea33SDavid du Colombier done:
1115e887ea33SDavid du Colombier 	cursafe = curs;
1116e887ea33SDavid du Colombier }
1117e887ea33SDavid du Colombier 
1118e887ea33SDavid du Colombier void
reglcgen(Node * t,Node * n,Node * nn)1119e887ea33SDavid du Colombier reglcgen(Node *t, Node *n, Node *nn)
1120e887ea33SDavid du Colombier {
1121e887ea33SDavid du Colombier 	Node *r;
1122e887ea33SDavid du Colombier 	long v;
1123e887ea33SDavid du Colombier 
1124e887ea33SDavid du Colombier 	regialloc(t, n, nn);
1125e887ea33SDavid du Colombier 	if(n->op == OIND) {
1126e887ea33SDavid du Colombier 		r = n->left;
1127e887ea33SDavid du Colombier 		while(r->op == OADD)
1128e887ea33SDavid du Colombier 			r = r->right;
1129e887ea33SDavid du Colombier 		if(sconst(r)) {
1130e887ea33SDavid du Colombier 			v = r->vconst;
1131e887ea33SDavid du Colombier 			r->vconst = 0;
1132e887ea33SDavid du Colombier 			lcgen(n, t);
1133e887ea33SDavid du Colombier 			t->xoffset += v;
1134e887ea33SDavid du Colombier 			r->vconst = v;
1135e887ea33SDavid du Colombier 			regind(t, n);
1136e887ea33SDavid du Colombier 			return;
1137e887ea33SDavid du Colombier 		}
1138e887ea33SDavid du Colombier 	}
1139e887ea33SDavid du Colombier 	lcgen(n, t);
1140e887ea33SDavid du Colombier 	regind(t, n);
1141e887ea33SDavid du Colombier }
1142e887ea33SDavid du Colombier 
1143e887ea33SDavid du Colombier void
lcgen(Node * n,Node * nn)1144e887ea33SDavid du Colombier lcgen(Node *n, Node *nn)
1145e887ea33SDavid du Colombier {
1146e887ea33SDavid du Colombier 	Prog *p1;
1147e887ea33SDavid du Colombier 	Node nod;
1148e887ea33SDavid du Colombier 
1149e887ea33SDavid du Colombier 	if(debug['g']) {
1150e887ea33SDavid du Colombier 		prtree(nn, "lcgen lhs");
1151e887ea33SDavid du Colombier 		prtree(n, "lcgen");
1152e887ea33SDavid du Colombier 	}
1153e887ea33SDavid du Colombier 	if(n == Z || n->type == T)
1154e887ea33SDavid du Colombier 		return;
1155e887ea33SDavid du Colombier 	if(nn == Z) {
1156e887ea33SDavid du Colombier 		nn = &nod;
1157e887ea33SDavid du Colombier 		regalloc(&nod, n, Z);
1158e887ea33SDavid du Colombier 	}
1159e887ea33SDavid du Colombier 	switch(n->op) {
1160e887ea33SDavid du Colombier 	default:
1161e887ea33SDavid du Colombier 		if(n->addable < INDEXED) {
1162e887ea33SDavid du Colombier 			diag(n, "unknown op in lcgen: %O", n->op);
1163e887ea33SDavid du Colombier 			break;
1164e887ea33SDavid du Colombier 		}
1165e887ea33SDavid du Colombier 		gopcode(OADDR, n->type, n, nn);
1166e887ea33SDavid du Colombier 		break;
1167e887ea33SDavid du Colombier 
1168e887ea33SDavid du Colombier 	case OCOMMA:
1169e887ea33SDavid du Colombier 		cgen(n->left, n->left);
1170e887ea33SDavid du Colombier 		lcgen(n->right, nn);
1171e887ea33SDavid du Colombier 		break;
1172e887ea33SDavid du Colombier 
1173e887ea33SDavid du Colombier 	case OIND:
1174e887ea33SDavid du Colombier 		cgen(n->left, nn);
1175e887ea33SDavid du Colombier 		break;
1176e887ea33SDavid du Colombier 
1177e887ea33SDavid du Colombier 	case OCOND:
1178e887ea33SDavid du Colombier 		bcgen(n->left, 1);
1179e887ea33SDavid du Colombier 		p1 = p;
1180e887ea33SDavid du Colombier 		lcgen(n->right->left, nn);
1181e887ea33SDavid du Colombier 		gbranch(OGOTO);
1182e887ea33SDavid du Colombier 		patch(p1, pc);
1183e887ea33SDavid du Colombier 		p1 = p;
1184e887ea33SDavid du Colombier 		lcgen(n->right->right, nn);
1185e887ea33SDavid du Colombier 		patch(p1, pc);
1186e887ea33SDavid du Colombier 		break;
1187e887ea33SDavid du Colombier 	}
1188e887ea33SDavid du Colombier }
1189e887ea33SDavid du Colombier 
1190e887ea33SDavid du Colombier void
bcgen(Node * n,int true)1191e887ea33SDavid du Colombier bcgen(Node *n, int true)
1192e887ea33SDavid du Colombier {
1193e887ea33SDavid du Colombier 
1194e887ea33SDavid du Colombier 	if(n->type == T)
1195e887ea33SDavid du Colombier 		gbranch(OGOTO);
1196e887ea33SDavid du Colombier 	else
1197e887ea33SDavid du Colombier 		boolgen(n, true, Z);
1198e887ea33SDavid du Colombier }
1199e887ea33SDavid du Colombier 
1200e887ea33SDavid du Colombier void
boolgen(Node * n,int true,Node * nn)1201e887ea33SDavid du Colombier boolgen(Node *n, int true, Node *nn)
1202e887ea33SDavid du Colombier {
1203e887ea33SDavid du Colombier 	int o;
1204e887ea33SDavid du Colombier 	Prog *p1, *p2;
1205e887ea33SDavid du Colombier 	Node *l, *r, nod, nod1;
1206e887ea33SDavid du Colombier 	long curs;
1207e887ea33SDavid du Colombier 
1208e887ea33SDavid du Colombier 	if(debug['g']) {
1209e887ea33SDavid du Colombier 		prtree(nn, "boolgen lhs");
1210e887ea33SDavid du Colombier 		prtree(n, "boolgen");
1211e887ea33SDavid du Colombier 	}
1212e887ea33SDavid du Colombier 	curs = cursafe;
1213e887ea33SDavid du Colombier 	l = n->left;
1214e887ea33SDavid du Colombier 	r = n->right;
1215e887ea33SDavid du Colombier 	switch(n->op) {
1216e887ea33SDavid du Colombier 
1217e887ea33SDavid du Colombier 	default:
1218e887ea33SDavid du Colombier 		o = ONE;
1219e887ea33SDavid du Colombier 		if(true)
1220e887ea33SDavid du Colombier 			o = OEQ;
1221e887ea33SDavid du Colombier 		/* bad, 13 is address of external that becomes constant */
1222e887ea33SDavid du Colombier 		if(n->addable >= INDEXED && n->addable != 13) {
1223e887ea33SDavid du Colombier 			if(typefd[n->type->etype]) {
1224e887ea33SDavid du Colombier 				regalloc(&nod1, n, Z);
1225e887ea33SDavid du Colombier 				gmove(nodfconst(0.0), &nod1);	/* TO DO: FREGZERO */
1226e887ea33SDavid du Colombier 				gopcode(o, n->type, n, &nod1);
1227e887ea33SDavid du Colombier 				regfree(&nod1);
1228e887ea33SDavid du Colombier 			} else
1229e887ea33SDavid du Colombier 				gopcode(o, n->type, n, nodconst(0));
1230e887ea33SDavid du Colombier 			goto com;
1231e887ea33SDavid du Colombier 		}
1232e887ea33SDavid du Colombier 		regalloc(&nod, n, nn);
1233e887ea33SDavid du Colombier 		cgen(n, &nod);
1234e887ea33SDavid du Colombier 		if(typefd[n->type->etype]) {
1235e887ea33SDavid du Colombier 			regalloc(&nod1, n, Z);
1236e887ea33SDavid du Colombier 			gmove(nodfconst(0.0), &nod1);	/* TO DO: FREGZERO */
1237e887ea33SDavid du Colombier 			gopcode(o, n->type, &nod, &nod1);
1238e887ea33SDavid du Colombier 			regfree(&nod1);
1239e887ea33SDavid du Colombier 		} else
1240e887ea33SDavid du Colombier 			gopcode(o, n->type, &nod, nodconst(0));
1241e887ea33SDavid du Colombier 		regfree(&nod);
1242e887ea33SDavid du Colombier 		goto com;
1243e887ea33SDavid du Colombier 
1244e887ea33SDavid du Colombier 	case OCONST:
1245e887ea33SDavid du Colombier 		o = vconst(n);
1246e887ea33SDavid du Colombier 		if(!true)
1247e887ea33SDavid du Colombier 			o = !o;
1248e887ea33SDavid du Colombier 		gbranch(OGOTO);
1249e887ea33SDavid du Colombier 		if(o) {
1250e887ea33SDavid du Colombier 			p1 = p;
1251e887ea33SDavid du Colombier 			gbranch(OGOTO);
1252e887ea33SDavid du Colombier 			patch(p1, pc);
1253e887ea33SDavid du Colombier 		}
1254e887ea33SDavid du Colombier 		goto com;
1255e887ea33SDavid du Colombier 
1256e887ea33SDavid du Colombier 	case OCOMMA:
1257e887ea33SDavid du Colombier 		cgen(l, Z);
1258e887ea33SDavid du Colombier 		boolgen(r, true, nn);
1259e887ea33SDavid du Colombier 		break;
1260e887ea33SDavid du Colombier 
1261e887ea33SDavid du Colombier 	case ONOT:
1262e887ea33SDavid du Colombier 		boolgen(l, !true, nn);
1263e887ea33SDavid du Colombier 		break;
1264e887ea33SDavid du Colombier 
1265e887ea33SDavid du Colombier 	case OCOND:
1266e887ea33SDavid du Colombier 		bcgen(l, 1);
1267e887ea33SDavid du Colombier 		p1 = p;
1268e887ea33SDavid du Colombier 		bcgen(r->left, true);
1269e887ea33SDavid du Colombier 		p2 = p;
1270e887ea33SDavid du Colombier 		gbranch(OGOTO);
1271e887ea33SDavid du Colombier 		patch(p1, pc);
1272e887ea33SDavid du Colombier 		p1 = p;
1273e887ea33SDavid du Colombier 		bcgen(r->right, !true);
1274e887ea33SDavid du Colombier 		patch(p2, pc);
1275e887ea33SDavid du Colombier 		p2 = p;
1276e887ea33SDavid du Colombier 		gbranch(OGOTO);
1277e887ea33SDavid du Colombier 		patch(p1, pc);
1278e887ea33SDavid du Colombier 		patch(p2, pc);
1279e887ea33SDavid du Colombier 		goto com;
1280e887ea33SDavid du Colombier 
1281e887ea33SDavid du Colombier 	case OANDAND:
1282e887ea33SDavid du Colombier 		if(!true)
1283e887ea33SDavid du Colombier 			goto caseor;
1284e887ea33SDavid du Colombier 
1285e887ea33SDavid du Colombier 	caseand:
1286e887ea33SDavid du Colombier 		bcgen(l, true);
1287e887ea33SDavid du Colombier 		p1 = p;
1288e887ea33SDavid du Colombier 		bcgen(r, !true);
1289e887ea33SDavid du Colombier 		p2 = p;
1290e887ea33SDavid du Colombier 		patch(p1, pc);
1291e887ea33SDavid du Colombier 		gbranch(OGOTO);
1292e887ea33SDavid du Colombier 		patch(p2, pc);
1293e887ea33SDavid du Colombier 		goto com;
1294e887ea33SDavid du Colombier 
1295e887ea33SDavid du Colombier 	case OOROR:
1296e887ea33SDavid du Colombier 		if(!true)
1297e887ea33SDavid du Colombier 			goto caseand;
1298e887ea33SDavid du Colombier 
1299e887ea33SDavid du Colombier 	caseor:
1300e887ea33SDavid du Colombier 		bcgen(l, !true);
1301e887ea33SDavid du Colombier 		p1 = p;
1302e887ea33SDavid du Colombier 		bcgen(r, !true);
1303e887ea33SDavid du Colombier 		p2 = p;
1304e887ea33SDavid du Colombier 		gbranch(OGOTO);
1305e887ea33SDavid du Colombier 		patch(p1, pc);
1306e887ea33SDavid du Colombier 		patch(p2, pc);
1307e887ea33SDavid du Colombier 		goto com;
1308e887ea33SDavid du Colombier 
1309e887ea33SDavid du Colombier 	case OEQ:
1310e887ea33SDavid du Colombier 	case ONE:
1311e887ea33SDavid du Colombier 	case OLE:
1312e887ea33SDavid du Colombier 	case OLT:
1313e887ea33SDavid du Colombier 	case OGE:
1314e887ea33SDavid du Colombier 	case OGT:
1315e887ea33SDavid du Colombier 	case OHI:
1316e887ea33SDavid du Colombier 	case OHS:
1317e887ea33SDavid du Colombier 	case OLO:
1318e887ea33SDavid du Colombier 	case OLS:
1319e887ea33SDavid du Colombier 		o = n->op;
1320e887ea33SDavid du Colombier 		if(true)
1321e887ea33SDavid du Colombier 			o = comrel[relindex(o)];
1322e887ea33SDavid du Colombier 		if(l->complex >= FNX && r->complex >= FNX) {
1323e887ea33SDavid du Colombier 			regret(&nod, r);
1324e887ea33SDavid du Colombier 			cgen(r, &nod);
1325e887ea33SDavid du Colombier 			regsalloc(&nod1, r);
1326e887ea33SDavid du Colombier 			gmove(&nod, &nod1);
1327e887ea33SDavid du Colombier 			regfree(&nod);
1328e887ea33SDavid du Colombier 			nod = *n;
1329e887ea33SDavid du Colombier 			nod.right = &nod1;
1330e887ea33SDavid du Colombier 			boolgen(&nod, true, nn);
1331e887ea33SDavid du Colombier 			break;
1332e887ea33SDavid du Colombier 		}
1333e887ea33SDavid du Colombier 		if(immconst(l)) {
1334e887ea33SDavid du Colombier 			o = invrel[relindex(o)];
1335e887ea33SDavid du Colombier 			/* bad, 13 is address of external that becomes constant */
1336e887ea33SDavid du Colombier 			if(r->addable < INDEXED || r->addable == 13) {
1337e887ea33SDavid du Colombier 				regalloc(&nod, r, nn);
1338e887ea33SDavid du Colombier 				cgen(r, &nod);
1339e887ea33SDavid du Colombier 				gopcode(o, l->type, &nod, l);
1340e887ea33SDavid du Colombier 				regfree(&nod);
1341e887ea33SDavid du Colombier 			} else
1342e887ea33SDavid du Colombier 				gopcode(o, l->type, r, l);
1343e887ea33SDavid du Colombier 			goto com;
1344e887ea33SDavid du Colombier 		}
1345e887ea33SDavid du Colombier 		if(typefd[l->type->etype])
1346e887ea33SDavid du Colombier 			o = invrel[relindex(logrel[relindex(o)])];
1347e887ea33SDavid du Colombier 		if(l->complex >= r->complex) {
1348e887ea33SDavid du Colombier 			regalloc(&nod, l, nn);
1349e887ea33SDavid du Colombier 			cgen(l, &nod);
1350e887ea33SDavid du Colombier 			if(r->addable < INDEXED || hardconst(r) || typefd[l->type->etype]) {
1351e887ea33SDavid du Colombier 				regalloc(&nod1, r, Z);
1352e887ea33SDavid du Colombier 				cgen(r, &nod1);
1353e887ea33SDavid du Colombier 				gopcode(o, l->type, &nod, &nod1);
1354e887ea33SDavid du Colombier 				regfree(&nod1);
1355e887ea33SDavid du Colombier 			} else
1356e887ea33SDavid du Colombier 				gopcode(o, l->type, &nod, r);
1357e887ea33SDavid du Colombier 			regfree(&nod);
1358e887ea33SDavid du Colombier 			goto com;
1359e887ea33SDavid du Colombier 		}
1360e887ea33SDavid du Colombier 		regalloc(&nod, r, nn);
1361e887ea33SDavid du Colombier 		cgen(r, &nod);
1362e887ea33SDavid du Colombier 		if(l->addable < INDEXED || l->addable == 13 || hardconst(l)) {
1363e887ea33SDavid du Colombier 			regalloc(&nod1, l, Z);
1364e887ea33SDavid du Colombier 			cgen(l, &nod1);
1365e887ea33SDavid du Colombier 			if(typechl[l->type->etype] && ewidth[l->type->etype] <= ewidth[TINT])
1366e887ea33SDavid du Colombier 				gopcode(o, types[TINT], &nod1, &nod);
1367e887ea33SDavid du Colombier 			else
1368e887ea33SDavid du Colombier 				gopcode(o, l->type, &nod1, &nod);
1369e887ea33SDavid du Colombier 			regfree(&nod1);
1370e887ea33SDavid du Colombier 		} else
1371e887ea33SDavid du Colombier 			gopcode(o, l->type, l, &nod);
1372e887ea33SDavid du Colombier 		regfree(&nod);
1373e887ea33SDavid du Colombier 
1374e887ea33SDavid du Colombier 	com:
1375e887ea33SDavid du Colombier 		if(nn != Z) {
1376e887ea33SDavid du Colombier 			p1 = p;
1377e887ea33SDavid du Colombier 			gmove(nodconst(1L), nn);
1378e887ea33SDavid du Colombier 			gbranch(OGOTO);
1379e887ea33SDavid du Colombier 			p2 = p;
1380e887ea33SDavid du Colombier 			patch(p1, pc);
1381e887ea33SDavid du Colombier 			gmove(nodconst(0L), nn);
1382e887ea33SDavid du Colombier 			patch(p2, pc);
1383e887ea33SDavid du Colombier 		}
1384e887ea33SDavid du Colombier 		break;
1385e887ea33SDavid du Colombier 	}
1386e887ea33SDavid du Colombier 	cursafe = curs;
1387e887ea33SDavid du Colombier }
1388e887ea33SDavid du Colombier 
1389e887ea33SDavid du Colombier void
sugen(Node * n,Node * nn,long w)1390e887ea33SDavid du Colombier sugen(Node *n, Node *nn, long w)
1391e887ea33SDavid du Colombier {
1392e887ea33SDavid du Colombier 	Prog *p1;
1393e887ea33SDavid du Colombier 	Node nod0, nod1, nod2, nod3, nod4, *l, *r;
1394e887ea33SDavid du Colombier 	Type *t;
1395e887ea33SDavid du Colombier 	int c, mt, mo;
1396e887ea33SDavid du Colombier 	vlong o0, o1;
1397e887ea33SDavid du Colombier 
1398e887ea33SDavid du Colombier 	if(n == Z || n->type == T)
1399e887ea33SDavid du Colombier 		return;
1400e887ea33SDavid du Colombier 	if(debug['g']) {
1401e887ea33SDavid du Colombier 		prtree(nn, "sugen lhs");
1402e887ea33SDavid du Colombier 		prtree(n, "sugen");
1403e887ea33SDavid du Colombier 	}
1404e887ea33SDavid du Colombier 	if(nn == nodrat)
1405e887ea33SDavid du Colombier 		if(w > nrathole)
1406e887ea33SDavid du Colombier 			nrathole = w;
1407e887ea33SDavid du Colombier 	switch(n->op) {
1408e887ea33SDavid du Colombier 	case OIND:
1409e887ea33SDavid du Colombier 		if(nn == Z) {
1410e887ea33SDavid du Colombier 			nullwarn(n->left, Z);
1411e887ea33SDavid du Colombier 			break;
1412e887ea33SDavid du Colombier 		}
1413e887ea33SDavid du Colombier 
1414e887ea33SDavid du Colombier 	default:
1415e887ea33SDavid du Colombier 		goto copy;
1416e887ea33SDavid du Colombier 
1417e887ea33SDavid du Colombier 	case OCONST:
1418e887ea33SDavid du Colombier 		goto copy;
1419e887ea33SDavid du Colombier 
1420e887ea33SDavid du Colombier 	case ODOT:
1421e887ea33SDavid du Colombier 		l = n->left;
1422e887ea33SDavid du Colombier 		sugen(l, nodrat, l->type->width);
1423e887ea33SDavid du Colombier 		if(nn == Z)
1424e887ea33SDavid du Colombier 			break;
1425e887ea33SDavid du Colombier 		warn(n, "non-interruptable temporary");
1426e887ea33SDavid du Colombier 		nod1 = *nodrat;
1427e887ea33SDavid du Colombier 		r = n->right;
1428e887ea33SDavid du Colombier 		if(!r || r->op != OCONST) {
1429e887ea33SDavid du Colombier 			diag(n, "DOT and no offset");
1430e887ea33SDavid du Colombier 			break;
1431e887ea33SDavid du Colombier 		}
1432e887ea33SDavid du Colombier 		nod1.xoffset += (long)r->vconst;
1433e887ea33SDavid du Colombier 		nod1.type = n->type;
1434e887ea33SDavid du Colombier 		sugen(&nod1, nn, w);
1435e887ea33SDavid du Colombier 		break;
1436e887ea33SDavid du Colombier 
1437e887ea33SDavid du Colombier 	case OSTRUCT:
1438e887ea33SDavid du Colombier 		/*
1439e887ea33SDavid du Colombier 		 * rewrite so lhs has no fn call
1440e887ea33SDavid du Colombier 		 */
1441e887ea33SDavid du Colombier 		if(nn != Z && side(nn)) {
1442e887ea33SDavid du Colombier 			nod1 = *n;
1443e887ea33SDavid du Colombier 			nod1.type = typ(TIND, n->type);
1444e887ea33SDavid du Colombier 			regret(&nod2, &nod1);
1445e887ea33SDavid du Colombier 			lcgen(nn, &nod2);
1446e887ea33SDavid du Colombier 			regsalloc(&nod0, &nod1);
1447e887ea33SDavid du Colombier 			cgen(&nod2, &nod0);
1448e887ea33SDavid du Colombier 			regfree(&nod2);
1449e887ea33SDavid du Colombier 
1450e887ea33SDavid du Colombier 			nod1 = *n;
1451e887ea33SDavid du Colombier 			nod1.op = OIND;
1452e887ea33SDavid du Colombier 			nod1.left = &nod0;
1453e887ea33SDavid du Colombier 			nod1.right = Z;
1454e887ea33SDavid du Colombier 			nod1.complex = 1;
1455e887ea33SDavid du Colombier 
1456e887ea33SDavid du Colombier 			sugen(n, &nod1, w);
1457e887ea33SDavid du Colombier 			return;
1458e887ea33SDavid du Colombier 		}
1459e887ea33SDavid du Colombier 
1460e887ea33SDavid du Colombier 		r = n->left;
1461e887ea33SDavid du Colombier 		for(t = n->type->link; t != T; t = t->down) {
1462e887ea33SDavid du Colombier 			l = r;
1463e887ea33SDavid du Colombier 			if(r->op == OLIST) {
1464e887ea33SDavid du Colombier 				l = r->left;
1465e887ea33SDavid du Colombier 				r = r->right;
1466e887ea33SDavid du Colombier 			}
1467e887ea33SDavid du Colombier 			if(nn == Z) {
1468e887ea33SDavid du Colombier 				cgen(l, nn);
1469e887ea33SDavid du Colombier 				continue;
1470e887ea33SDavid du Colombier 			}
1471e887ea33SDavid du Colombier 			/*
1472e887ea33SDavid du Colombier 			 * hand craft *(&nn + o) = l
1473e887ea33SDavid du Colombier 			 */
1474e887ea33SDavid du Colombier 			nod0 = znode;
1475e887ea33SDavid du Colombier 			nod0.op = OAS;
1476e887ea33SDavid du Colombier 			nod0.type = t;
1477e887ea33SDavid du Colombier 			nod0.left = &nod1;
1478e887ea33SDavid du Colombier 			nod0.right = nil;
1479e887ea33SDavid du Colombier 
1480e887ea33SDavid du Colombier 			nod1 = znode;
1481e887ea33SDavid du Colombier 			nod1.op = OIND;
1482e887ea33SDavid du Colombier 			nod1.type = t;
1483e887ea33SDavid du Colombier 			nod1.left = &nod2;
1484e887ea33SDavid du Colombier 
1485e887ea33SDavid du Colombier 			nod2 = znode;
1486e887ea33SDavid du Colombier 			nod2.op = OADD;
1487e887ea33SDavid du Colombier 			nod2.type = typ(TIND, t);
1488e887ea33SDavid du Colombier 			nod2.left = &nod3;
1489e887ea33SDavid du Colombier 			nod2.right = &nod4;
1490e887ea33SDavid du Colombier 
1491e887ea33SDavid du Colombier 			nod3 = znode;
1492e887ea33SDavid du Colombier 			nod3.op = OADDR;
1493e887ea33SDavid du Colombier 			nod3.type = nod2.type;
1494e887ea33SDavid du Colombier 			nod3.left = nn;
1495e887ea33SDavid du Colombier 
1496e887ea33SDavid du Colombier 			nod4 = znode;
1497e887ea33SDavid du Colombier 			nod4.op = OCONST;
1498e887ea33SDavid du Colombier 			nod4.type = nod2.type;
1499e887ea33SDavid du Colombier 			nod4.vconst = t->offset;
1500e887ea33SDavid du Colombier 
1501e887ea33SDavid du Colombier 			ccom(&nod0);
1502e887ea33SDavid du Colombier 			acom(&nod0);
1503e887ea33SDavid du Colombier 			xcom(&nod0);
1504e887ea33SDavid du Colombier 			nod0.addable = 0;
1505e887ea33SDavid du Colombier 			nod0.right = l;
1506e887ea33SDavid du Colombier 
1507e887ea33SDavid du Colombier 			/* prtree(&nod0, "hand craft"); /* */
1508e887ea33SDavid du Colombier 			cgen(&nod0, Z);
1509e887ea33SDavid du Colombier 		}
1510e887ea33SDavid du Colombier 		break;
1511e887ea33SDavid du Colombier 
1512e887ea33SDavid du Colombier 	case OAS:
1513e887ea33SDavid du Colombier 		if(nn == Z) {
1514e887ea33SDavid du Colombier 			if(n->addable < INDEXED)
1515e887ea33SDavid du Colombier 				sugen(n->right, n->left, w);
1516e887ea33SDavid du Colombier 			break;
1517e887ea33SDavid du Colombier 		}
1518e887ea33SDavid du Colombier 
1519e887ea33SDavid du Colombier 		sugen(n->right, nodrat, w);
1520e887ea33SDavid du Colombier 		warn(n, "non-interruptable temporary");
1521e887ea33SDavid du Colombier 		sugen(nodrat, n->left, w);
1522e887ea33SDavid du Colombier 		sugen(nodrat, nn, w);
1523e887ea33SDavid du Colombier 		break;
1524e887ea33SDavid du Colombier 
1525e887ea33SDavid du Colombier 	case OFUNC:
1526e887ea33SDavid du Colombier 		if(nn == Z) {
1527e887ea33SDavid du Colombier 			sugen(n, nodrat, w);
1528e887ea33SDavid du Colombier 			break;
1529e887ea33SDavid du Colombier 		}
1530e887ea33SDavid du Colombier 		if(nn->op != OIND) {
1531e887ea33SDavid du Colombier 			nn = new1(OADDR, nn, Z);
1532e887ea33SDavid du Colombier 			nn->type = types[TIND];
1533e887ea33SDavid du Colombier 			nn->addable = 0;
1534e887ea33SDavid du Colombier 		} else
1535e887ea33SDavid du Colombier 			nn = nn->left;
1536e887ea33SDavid du Colombier 		n = new(OFUNC, n->left, new(OLIST, nn, n->right));
1537e887ea33SDavid du Colombier 		n->type = types[TVOID];
1538e887ea33SDavid du Colombier 		n->left->type = types[TVOID];
1539e887ea33SDavid du Colombier 		cgen(n, Z);
1540e887ea33SDavid du Colombier 		break;
1541e887ea33SDavid du Colombier 
1542e887ea33SDavid du Colombier 	case OCOND:
1543e887ea33SDavid du Colombier 		bcgen(n->left, 1);
1544e887ea33SDavid du Colombier 		p1 = p;
1545e887ea33SDavid du Colombier 		sugen(n->right->left, nn, w);
1546e887ea33SDavid du Colombier 		gbranch(OGOTO);
1547e887ea33SDavid du Colombier 		patch(p1, pc);
1548e887ea33SDavid du Colombier 		p1 = p;
1549e887ea33SDavid du Colombier 		sugen(n->right->right, nn, w);
1550e887ea33SDavid du Colombier 		patch(p1, pc);
1551e887ea33SDavid du Colombier 		break;
1552e887ea33SDavid du Colombier 
1553e887ea33SDavid du Colombier 	case OCOMMA:
1554e887ea33SDavid du Colombier 		cgen(n->left, Z);
1555e887ea33SDavid du Colombier 		sugen(n->right, nn, w);
1556e887ea33SDavid du Colombier 		break;
1557e887ea33SDavid du Colombier 	}
1558e887ea33SDavid du Colombier 	return;
1559e887ea33SDavid du Colombier 
1560e887ea33SDavid du Colombier copy:
1561e887ea33SDavid du Colombier 	if(nn == Z) {
1562e887ea33SDavid du Colombier 		switch(n->op) {
1563e887ea33SDavid du Colombier 		case OASADD:
1564e887ea33SDavid du Colombier 		case OASSUB:
1565e887ea33SDavid du Colombier 		case OASAND:
1566e887ea33SDavid du Colombier 		case OASOR:
1567e887ea33SDavid du Colombier 		case OASXOR:
1568e887ea33SDavid du Colombier 
1569e887ea33SDavid du Colombier 		case OASMUL:
1570e887ea33SDavid du Colombier 		case OASLMUL:
1571e887ea33SDavid du Colombier 
1572e887ea33SDavid du Colombier 
1573e887ea33SDavid du Colombier 		case OASASHL:
1574e887ea33SDavid du Colombier 		case OASASHR:
1575e887ea33SDavid du Colombier 		case OASLSHR:
1576e887ea33SDavid du Colombier 			break;
1577e887ea33SDavid du Colombier 
1578e887ea33SDavid du Colombier 		case OPOSTINC:
1579e887ea33SDavid du Colombier 		case OPOSTDEC:
1580e887ea33SDavid du Colombier 		case OPREINC:
1581e887ea33SDavid du Colombier 		case OPREDEC:
1582e887ea33SDavid du Colombier 			break;
1583e887ea33SDavid du Colombier 
1584e887ea33SDavid du Colombier 		default:
1585e887ea33SDavid du Colombier 			return;
1586e887ea33SDavid du Colombier 		}
1587e887ea33SDavid du Colombier 	}
1588e887ea33SDavid du Colombier 
1589e887ea33SDavid du Colombier 	if(n->complex >= FNX && nn != nil && nn->complex >= FNX) {
1590e887ea33SDavid du Colombier 		t = nn->type;
1591e887ea33SDavid du Colombier 		nn->type = types[TLONG];
1592e887ea33SDavid du Colombier 		regialloc(&nod1, nn, Z);
1593e887ea33SDavid du Colombier 		lcgen(nn, &nod1);
1594e887ea33SDavid du Colombier 		regsalloc(&nod2, nn);
1595e887ea33SDavid du Colombier 		nn->type = t;
1596e887ea33SDavid du Colombier 
1597*1936bb65SDavid du Colombier 		gins(AMOVQ, &nod1, &nod2);
1598e887ea33SDavid du Colombier 		regfree(&nod1);
1599e887ea33SDavid du Colombier 
1600e887ea33SDavid du Colombier 		nod2.type = typ(TIND, t);
1601e887ea33SDavid du Colombier 
1602e887ea33SDavid du Colombier 		nod1 = nod2;
1603e887ea33SDavid du Colombier 		nod1.op = OIND;
1604e887ea33SDavid du Colombier 		nod1.left = &nod2;
1605e887ea33SDavid du Colombier 		nod1.right = Z;
1606e887ea33SDavid du Colombier 		nod1.complex = 1;
1607e887ea33SDavid du Colombier 		nod1.type = t;
1608e887ea33SDavid du Colombier 
1609e887ea33SDavid du Colombier 		sugen(n, &nod1, w);
1610e887ea33SDavid du Colombier 		return;
1611e887ea33SDavid du Colombier 	}
1612e887ea33SDavid du Colombier 
1613e887ea33SDavid du Colombier 	if(w <= 32) {
1614e887ea33SDavid du Colombier 		c = cursafe;
1615e887ea33SDavid du Colombier 		if(n->left != Z && n->left->complex >= FNX
1616e887ea33SDavid du Colombier 		&& n->right != Z && n->right->complex >= FNX) {
1617e887ea33SDavid du Colombier 			regsalloc(&nod1, n->right);
1618e887ea33SDavid du Colombier 			cgen(n->right, &nod1);
1619e887ea33SDavid du Colombier 			nod2 = *n;
1620e887ea33SDavid du Colombier 			nod2.right = &nod1;
1621e887ea33SDavid du Colombier 			cgen(&nod2, nn);
1622e887ea33SDavid du Colombier 			cursafe = c;
1623e887ea33SDavid du Colombier 			return;
1624e887ea33SDavid du Colombier 		}
1625e887ea33SDavid du Colombier 		if(w & 7) {
1626e887ea33SDavid du Colombier 			mt = TLONG;
1627e887ea33SDavid du Colombier 			mo = AMOVL;
1628e887ea33SDavid du Colombier 		} else {
1629e887ea33SDavid du Colombier 			mt = TVLONG;
1630e887ea33SDavid du Colombier 			mo = AMOVQ;
1631e887ea33SDavid du Colombier 		}
1632e887ea33SDavid du Colombier 		if(n->complex > nn->complex) {
1633e887ea33SDavid du Colombier 			t = n->type;
1634e887ea33SDavid du Colombier 			n->type = types[mt];
1635e887ea33SDavid du Colombier 			regalloc(&nod0, n, Z);
1636e887ea33SDavid du Colombier 			if(!vaddr(n, 0)) {
1637e887ea33SDavid du Colombier 				reglcgen(&nod1, n, Z);
1638e887ea33SDavid du Colombier 				n->type = t;
1639e887ea33SDavid du Colombier 				n = &nod1;
1640e887ea33SDavid du Colombier 			}
1641e887ea33SDavid du Colombier 			else
1642e887ea33SDavid du Colombier 				n->type = t;
1643e887ea33SDavid du Colombier 
1644e887ea33SDavid du Colombier 			t = nn->type;
1645e887ea33SDavid du Colombier 			nn->type = types[mt];
1646e887ea33SDavid du Colombier 			if(!vaddr(nn, 0)) {
1647e887ea33SDavid du Colombier 				reglcgen(&nod2, nn, Z);
1648e887ea33SDavid du Colombier 				nn->type = t;
1649e887ea33SDavid du Colombier 				nn = &nod2;
1650e887ea33SDavid du Colombier 			}
1651e887ea33SDavid du Colombier 			else
1652e887ea33SDavid du Colombier 				nn->type = t;
1653e887ea33SDavid du Colombier 		} else {
1654e887ea33SDavid du Colombier 			t = nn->type;
1655e887ea33SDavid du Colombier 			nn->type = types[mt];
1656e887ea33SDavid du Colombier 			regalloc(&nod0, nn, Z);
1657e887ea33SDavid du Colombier 			if(!vaddr(nn, 0)) {
1658e887ea33SDavid du Colombier 				reglcgen(&nod2, nn, Z);
1659e887ea33SDavid du Colombier 				nn->type = t;
1660e887ea33SDavid du Colombier 				nn = &nod2;
1661e887ea33SDavid du Colombier 			}
1662e887ea33SDavid du Colombier 			else
1663e887ea33SDavid du Colombier 				nn->type = t;
1664e887ea33SDavid du Colombier 
1665e887ea33SDavid du Colombier 			t = n->type;
1666e887ea33SDavid du Colombier 			n->type = types[mt];
1667e887ea33SDavid du Colombier 			if(!vaddr(n, 0)) {
1668e887ea33SDavid du Colombier 				reglcgen(&nod1, n, Z);
1669e887ea33SDavid du Colombier 				n->type = t;
1670e887ea33SDavid du Colombier 				n = &nod1;
1671e887ea33SDavid du Colombier 			}
1672e887ea33SDavid du Colombier 			else
1673e887ea33SDavid du Colombier 				n->type = t;
1674e887ea33SDavid du Colombier 		}
1675e887ea33SDavid du Colombier 		o0 = n->xoffset;
1676e887ea33SDavid du Colombier 		o1 = nn->xoffset;
1677e887ea33SDavid du Colombier 		w /= ewidth[mt];
1678e887ea33SDavid du Colombier 		while(--w >= 0) {
1679e887ea33SDavid du Colombier 			gins(mo, n, &nod0);
1680e887ea33SDavid du Colombier 			gins(mo, &nod0, nn);
1681e887ea33SDavid du Colombier 			n->xoffset += ewidth[mt];
1682e887ea33SDavid du Colombier 			nn->xoffset += ewidth[mt];
1683e887ea33SDavid du Colombier 		}
1684e887ea33SDavid du Colombier 		n->xoffset = o0;
1685e887ea33SDavid du Colombier 		nn->xoffset = o1;
1686e887ea33SDavid du Colombier 		if(nn == &nod2)
1687e887ea33SDavid du Colombier 			regfree(&nod2);
1688e887ea33SDavid du Colombier 		if(n == &nod1)
1689e887ea33SDavid du Colombier 			regfree(&nod1);
1690e887ea33SDavid du Colombier 		regfree(&nod0);
1691e887ea33SDavid du Colombier 		return;
1692e887ea33SDavid du Colombier 	}
1693e887ea33SDavid du Colombier 
1694e887ea33SDavid du Colombier 	/* botch, need to save in .safe */
1695e887ea33SDavid du Colombier 	c = 0;
1696e887ea33SDavid du Colombier 	if(n->complex > nn->complex) {
1697e887ea33SDavid du Colombier 		t = n->type;
1698*1936bb65SDavid du Colombier 		n->type = types[TIND];
1699e887ea33SDavid du Colombier 		nodreg(&nod1, n, D_SI);
1700e887ea33SDavid du Colombier 		if(reg[D_SI]) {
1701e887ea33SDavid du Colombier 			gins(APUSHQ, &nod1, Z);
1702e887ea33SDavid du Colombier 			c |= 1;
1703e887ea33SDavid du Colombier 			reg[D_SI]++;
1704e887ea33SDavid du Colombier 		}
1705e887ea33SDavid du Colombier 		lcgen(n, &nod1);
1706e887ea33SDavid du Colombier 		n->type = t;
1707e887ea33SDavid du Colombier 
1708e887ea33SDavid du Colombier 		t = nn->type;
1709*1936bb65SDavid du Colombier 		nn->type = types[TIND];
1710e887ea33SDavid du Colombier 		nodreg(&nod2, nn, D_DI);
1711e887ea33SDavid du Colombier 		if(reg[D_DI]) {
1712e887ea33SDavid du Colombier warn(Z, "DI botch");
1713e887ea33SDavid du Colombier 			gins(APUSHQ, &nod2, Z);
1714e887ea33SDavid du Colombier 			c |= 2;
1715e887ea33SDavid du Colombier 			reg[D_DI]++;
1716e887ea33SDavid du Colombier 		}
1717e887ea33SDavid du Colombier 		lcgen(nn, &nod2);
1718e887ea33SDavid du Colombier 		nn->type = t;
1719e887ea33SDavid du Colombier 	} else {
1720e887ea33SDavid du Colombier 		t = nn->type;
1721*1936bb65SDavid du Colombier 		nn->type = types[TIND];
1722e887ea33SDavid du Colombier 		nodreg(&nod2, nn, D_DI);
1723e887ea33SDavid du Colombier 		if(reg[D_DI]) {
1724e887ea33SDavid du Colombier warn(Z, "DI botch");
1725e887ea33SDavid du Colombier 			gins(APUSHQ, &nod2, Z);
1726e887ea33SDavid du Colombier 			c |= 2;
1727e887ea33SDavid du Colombier 			reg[D_DI]++;
1728e887ea33SDavid du Colombier 		}
1729e887ea33SDavid du Colombier 		lcgen(nn, &nod2);
1730e887ea33SDavid du Colombier 		nn->type = t;
1731e887ea33SDavid du Colombier 
1732e887ea33SDavid du Colombier 		t = n->type;
1733*1936bb65SDavid du Colombier 		n->type = types[TIND];
1734e887ea33SDavid du Colombier 		nodreg(&nod1, n, D_SI);
1735e887ea33SDavid du Colombier 		if(reg[D_SI]) {
1736e887ea33SDavid du Colombier 			gins(APUSHQ, &nod1, Z);
1737e887ea33SDavid du Colombier 			c |= 1;
1738e887ea33SDavid du Colombier 			reg[D_SI]++;
1739e887ea33SDavid du Colombier 		}
1740e887ea33SDavid du Colombier 		lcgen(n, &nod1);
1741e887ea33SDavid du Colombier 		n->type = t;
1742e887ea33SDavid du Colombier 	}
1743e887ea33SDavid du Colombier 	nodreg(&nod3, n, D_CX);
1744e887ea33SDavid du Colombier 	if(reg[D_CX]) {
1745e887ea33SDavid du Colombier 		gins(APUSHQ, &nod3, Z);
1746e887ea33SDavid du Colombier 		c |= 4;
1747e887ea33SDavid du Colombier 		reg[D_CX]++;
1748e887ea33SDavid du Colombier 	}
1749e887ea33SDavid du Colombier 	gins(AMOVL, nodconst(w/SZ_INT), &nod3);
1750e887ea33SDavid du Colombier 	gins(ACLD, Z, Z);
1751e887ea33SDavid du Colombier 	gins(AREP, Z, Z);
1752e887ea33SDavid du Colombier 	gins(AMOVSL, Z, Z);
1753e887ea33SDavid du Colombier 	if(c & 4) {
1754e887ea33SDavid du Colombier 		gins(APOPQ, Z, &nod3);
1755e887ea33SDavid du Colombier 		reg[D_CX]--;
1756e887ea33SDavid du Colombier 	}
1757e887ea33SDavid du Colombier 	if(c & 2) {
1758e887ea33SDavid du Colombier 		gins(APOPQ, Z, &nod2);
1759e887ea33SDavid du Colombier 		reg[nod2.reg]--;
1760e887ea33SDavid du Colombier 	}
1761e887ea33SDavid du Colombier 	if(c & 1) {
1762e887ea33SDavid du Colombier 		gins(APOPQ, Z, &nod1);
1763e887ea33SDavid du Colombier 		reg[nod1.reg]--;
1764e887ea33SDavid du Colombier 	}
1765e887ea33SDavid du Colombier }
1766e887ea33SDavid du Colombier 
1767e887ea33SDavid du Colombier /*
1768e887ea33SDavid du Colombier  * TO DO
1769e887ea33SDavid du Colombier  */
1770e887ea33SDavid du Colombier void
layout(Node * f,Node * t,int c,int cv,Node * cn)1771e887ea33SDavid du Colombier layout(Node *f, Node *t, int c, int cv, Node *cn)
1772e887ea33SDavid du Colombier {
1773e887ea33SDavid du Colombier 	Node t1, t2;
1774e887ea33SDavid du Colombier 
1775e887ea33SDavid du Colombier 	while(c > 3) {
1776e887ea33SDavid du Colombier 		layout(f, t, 2, 0, Z);
1777e887ea33SDavid du Colombier 		c -= 2;
1778e887ea33SDavid du Colombier 	}
1779e887ea33SDavid du Colombier 
1780e887ea33SDavid du Colombier 	regalloc(&t1, &lregnode, Z);
1781e887ea33SDavid du Colombier 	regalloc(&t2, &lregnode, Z);
1782e887ea33SDavid du Colombier 	if(c > 0) {
1783e887ea33SDavid du Colombier 		gmove(f, &t1);
1784e887ea33SDavid du Colombier 		f->xoffset += SZ_INT;
1785e887ea33SDavid du Colombier 	}
1786e887ea33SDavid du Colombier 	if(cn != Z)
1787e887ea33SDavid du Colombier 		gmove(nodconst(cv), cn);
1788e887ea33SDavid du Colombier 	if(c > 1) {
1789e887ea33SDavid du Colombier 		gmove(f, &t2);
1790e887ea33SDavid du Colombier 		f->xoffset += SZ_INT;
1791e887ea33SDavid du Colombier 	}
1792e887ea33SDavid du Colombier 	if(c > 0) {
1793e887ea33SDavid du Colombier 		gmove(&t1, t);
1794e887ea33SDavid du Colombier 		t->xoffset += SZ_INT;
1795e887ea33SDavid du Colombier 	}
1796e887ea33SDavid du Colombier 	if(c > 2) {
1797e887ea33SDavid du Colombier 		gmove(f, &t1);
1798e887ea33SDavid du Colombier 		f->xoffset += SZ_INT;
1799e887ea33SDavid du Colombier 	}
1800e887ea33SDavid du Colombier 	if(c > 1) {
1801e887ea33SDavid du Colombier 		gmove(&t2, t);
1802e887ea33SDavid du Colombier 		t->xoffset += SZ_INT;
1803e887ea33SDavid du Colombier 	}
1804e887ea33SDavid du Colombier 	if(c > 2) {
1805e887ea33SDavid du Colombier 		gmove(&t1, t);
1806e887ea33SDavid du Colombier 		t->xoffset += SZ_INT;
1807e887ea33SDavid du Colombier 	}
1808e887ea33SDavid du Colombier 	regfree(&t1);
1809e887ea33SDavid du Colombier 	regfree(&t2);
1810e887ea33SDavid du Colombier }
1811e887ea33SDavid du Colombier 
1812e887ea33SDavid du Colombier /*
1813e887ea33SDavid du Colombier  * constant is not vlong or fits as 32-bit signed immediate
1814e887ea33SDavid du Colombier  */
1815e887ea33SDavid du Colombier int
immconst(Node * n)1816e887ea33SDavid du Colombier immconst(Node *n)
1817e887ea33SDavid du Colombier {
1818e887ea33SDavid du Colombier 	long v;
1819e887ea33SDavid du Colombier 
1820e887ea33SDavid du Colombier 	if(n->op != OCONST || !typechlpv[n->type->etype])
1821e887ea33SDavid du Colombier 		return 0;
1822e887ea33SDavid du Colombier 	if(typechl[n->type->etype])
1823e887ea33SDavid du Colombier 		return 1;
1824e887ea33SDavid du Colombier 	v = n->vconst;
1825e887ea33SDavid du Colombier 	return n->vconst == (vlong)v;
1826e887ea33SDavid du Colombier }
1827e887ea33SDavid du Colombier 
1828e887ea33SDavid du Colombier /*
1829e887ea33SDavid du Colombier  * if a constant and vlong, doesn't fit as 32-bit signed immediate
1830e887ea33SDavid du Colombier  */
1831e887ea33SDavid du Colombier int
hardconst(Node * n)1832e887ea33SDavid du Colombier hardconst(Node *n)
1833e887ea33SDavid du Colombier {
1834e887ea33SDavid du Colombier 	return n->op == OCONST && !immconst(n);
1835e887ea33SDavid du Colombier }
1836e887ea33SDavid du Colombier 
1837e887ea33SDavid du Colombier /*
1838e887ea33SDavid du Colombier  * casting up to t2 covers an intermediate cast to t1
1839e887ea33SDavid du Colombier  */
1840e887ea33SDavid du Colombier int
castup(Type * t1,Type * t2)1841e887ea33SDavid du Colombier castup(Type *t1, Type *t2)
1842e887ea33SDavid du Colombier {
1843e887ea33SDavid du Colombier 	int ft;
1844e887ea33SDavid du Colombier 
1845e887ea33SDavid du Colombier 	if(!nilcast(t1, t2))
1846e887ea33SDavid du Colombier 		return 0;
1847e887ea33SDavid du Colombier 	/* known to be small to large */
1848e887ea33SDavid du Colombier 	ft = t1->etype;
1849e887ea33SDavid du Colombier 	switch(t2->etype){
1850e887ea33SDavid du Colombier 	case TINT:
1851e887ea33SDavid du Colombier 	case TLONG:
1852e887ea33SDavid du Colombier 		return ft == TLONG || ft == TINT || ft == TSHORT || ft == TCHAR;
1853e887ea33SDavid du Colombier 	case TUINT:
1854e887ea33SDavid du Colombier 	case TULONG:
1855e887ea33SDavid du Colombier 		return ft == TULONG || ft == TUINT || ft == TUSHORT || ft == TUCHAR;
1856e887ea33SDavid du Colombier 	case TVLONG:
1857e887ea33SDavid du Colombier 		return ft == TLONG || ft == TINT || ft == TSHORT;
1858e887ea33SDavid du Colombier 	case TUVLONG:
1859e887ea33SDavid du Colombier 		return ft == TULONG || ft == TUINT || ft == TUSHORT;
1860e887ea33SDavid du Colombier 	}
1861e887ea33SDavid du Colombier 	return 0;
1862e887ea33SDavid du Colombier }
1863e887ea33SDavid du Colombier 
1864e887ea33SDavid du Colombier void
zeroregm(Node * n)1865e887ea33SDavid du Colombier zeroregm(Node *n)
1866e887ea33SDavid du Colombier {
1867e887ea33SDavid du Colombier 	gins(AMOVL, nodconst(0), n);
1868e887ea33SDavid du Colombier }
1869e887ea33SDavid du Colombier 
1870e887ea33SDavid du Colombier /* do we need to load the address of a vlong? */
1871e887ea33SDavid du Colombier int
vaddr(Node * n,int a)1872e887ea33SDavid du Colombier vaddr(Node *n, int a)
1873e887ea33SDavid du Colombier {
1874e887ea33SDavid du Colombier 	switch(n->op) {
1875e887ea33SDavid du Colombier 	case ONAME:
1876e887ea33SDavid du Colombier 		if(a)
1877e887ea33SDavid du Colombier 			return 1;
1878e887ea33SDavid du Colombier 		return !(n->class == CEXTERN || n->class == CGLOBL || n->class == CSTATIC);
1879e887ea33SDavid du Colombier 
1880e887ea33SDavid du Colombier 	case OCONST:
1881e887ea33SDavid du Colombier 	case OREGISTER:
1882e887ea33SDavid du Colombier 	case OINDREG:
1883e887ea33SDavid du Colombier 		return 1;
1884e887ea33SDavid du Colombier 	}
1885e887ea33SDavid du Colombier 	return 0;
1886e887ea33SDavid du Colombier }
1887e887ea33SDavid du Colombier 
1888e887ea33SDavid du Colombier long
hi64v(Node * n)1889e887ea33SDavid du Colombier hi64v(Node *n)
1890e887ea33SDavid du Colombier {
1891e887ea33SDavid du Colombier 	if(align(0, types[TCHAR], Aarg1))	/* isbigendian */
1892e887ea33SDavid du Colombier 		return (long)(n->vconst) & ~0L;
1893e887ea33SDavid du Colombier 	else
1894e887ea33SDavid du Colombier 		return (long)((uvlong)n->vconst>>32) & ~0L;
1895e887ea33SDavid du Colombier }
1896e887ea33SDavid du Colombier 
1897e887ea33SDavid du Colombier long
lo64v(Node * n)1898e887ea33SDavid du Colombier lo64v(Node *n)
1899e887ea33SDavid du Colombier {
1900e887ea33SDavid du Colombier 	if(align(0, types[TCHAR], Aarg1))	/* isbigendian */
1901e887ea33SDavid du Colombier 		return (long)((uvlong)n->vconst>>32) & ~0L;
1902e887ea33SDavid du Colombier 	else
1903e887ea33SDavid du Colombier 		return (long)(n->vconst) & ~0L;
1904e887ea33SDavid du Colombier }
1905e887ea33SDavid du Colombier 
1906e887ea33SDavid du Colombier Node *
hi64(Node * n)1907e887ea33SDavid du Colombier hi64(Node *n)
1908e887ea33SDavid du Colombier {
1909e887ea33SDavid du Colombier 	return nodconst(hi64v(n));
1910e887ea33SDavid du Colombier }
1911e887ea33SDavid du Colombier 
1912e887ea33SDavid du Colombier Node *
lo64(Node * n)1913e887ea33SDavid du Colombier lo64(Node *n)
1914e887ea33SDavid du Colombier {
1915e887ea33SDavid du Colombier 	return nodconst(lo64v(n));
1916e887ea33SDavid du Colombier }
1917e887ea33SDavid du Colombier 
1918e887ea33SDavid du Colombier int
cond(int op)1919e887ea33SDavid du Colombier cond(int op)
1920e887ea33SDavid du Colombier {
1921e887ea33SDavid du Colombier 	switch(op) {
1922e887ea33SDavid du Colombier 	case OANDAND:
1923e887ea33SDavid du Colombier 	case OOROR:
1924e887ea33SDavid du Colombier 	case ONOT:
1925e887ea33SDavid du Colombier 		return 1;
1926e887ea33SDavid du Colombier 
1927e887ea33SDavid du Colombier 	case OEQ:
1928e887ea33SDavid du Colombier 	case ONE:
1929e887ea33SDavid du Colombier 	case OLE:
1930e887ea33SDavid du Colombier 	case OLT:
1931e887ea33SDavid du Colombier 	case OGE:
1932e887ea33SDavid du Colombier 	case OGT:
1933e887ea33SDavid du Colombier 	case OHI:
1934e887ea33SDavid du Colombier 	case OHS:
1935e887ea33SDavid du Colombier 	case OLO:
1936e887ea33SDavid du Colombier 	case OLS:
1937e887ea33SDavid du Colombier 		return 1;
1938e887ea33SDavid du Colombier 	}
1939e887ea33SDavid du Colombier 	return 0;
1940e887ea33SDavid du Colombier }
1941