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