xref: /plan9-contrib/sys/src/cmd/8c/cgen64.c (revision 4ac975e2e38b792d24bc60de7fce5e6173f046ea)
1da51d93aSDavid du Colombier #include "gc.h"
2da51d93aSDavid du Colombier 
3da51d93aSDavid du Colombier void
4da51d93aSDavid du Colombier zeroregm(Node *n)
5da51d93aSDavid du Colombier {
6da51d93aSDavid du Colombier 	gins(AMOVL, nodconst(0), n);
7da51d93aSDavid du Colombier }
8da51d93aSDavid du Colombier 
9da51d93aSDavid du Colombier /* do we need to load the address of a vlong? */
10da51d93aSDavid du Colombier int
11375daca8SDavid du Colombier vaddr(Node *n, int a)
12da51d93aSDavid du Colombier {
13da51d93aSDavid du Colombier 	switch(n->op) {
14da51d93aSDavid du Colombier 	case ONAME:
15da51d93aSDavid du Colombier 		if(a)
16375daca8SDavid du Colombier 			return 1;
17375daca8SDavid du Colombier 		return !(n->class == CEXTERN || n->class == CGLOBL || n->class == CSTATIC);
18da51d93aSDavid du Colombier 
19da51d93aSDavid du Colombier 	case OCONST:
20da51d93aSDavid du Colombier 	case OREGISTER:
21da51d93aSDavid du Colombier 	case OINDREG:
22da51d93aSDavid du Colombier 		return 1;
23da51d93aSDavid du Colombier 	}
24375daca8SDavid du Colombier 	return 0;
25375daca8SDavid du Colombier }
26da51d93aSDavid du Colombier 
27375daca8SDavid du Colombier long
28da51d93aSDavid du Colombier hi64v(Node *n)
29da51d93aSDavid du Colombier {
30da51d93aSDavid du Colombier 	if(align(0, types[TCHAR], Aarg1))	/* isbigendian */
31da51d93aSDavid du Colombier 		return (long)(n->vconst) & ~0L;
32da51d93aSDavid du Colombier 	else
33da51d93aSDavid du Colombier 		return (long)((uvlong)n->vconst>>32) & ~0L;
34da51d93aSDavid du Colombier }
35da51d93aSDavid du Colombier 
36375daca8SDavid du Colombier long
37da51d93aSDavid du Colombier lo64v(Node *n)
38da51d93aSDavid du Colombier {
39da51d93aSDavid du Colombier 	if(align(0, types[TCHAR], Aarg1))	/* isbigendian */
40da51d93aSDavid du Colombier 		return (long)((uvlong)n->vconst>>32) & ~0L;
41da51d93aSDavid du Colombier 	else
42da51d93aSDavid du Colombier 		return (long)(n->vconst) & ~0L;
43da51d93aSDavid du Colombier }
44da51d93aSDavid du Colombier 
45375daca8SDavid du Colombier Node *
46da51d93aSDavid du Colombier hi64(Node *n)
47da51d93aSDavid du Colombier {
48da51d93aSDavid du Colombier 	return nodconst(hi64v(n));
49da51d93aSDavid du Colombier }
50da51d93aSDavid du Colombier 
51375daca8SDavid du Colombier Node *
52da51d93aSDavid du Colombier lo64(Node *n)
53da51d93aSDavid du Colombier {
54da51d93aSDavid du Colombier 	return nodconst(lo64v(n));
55da51d93aSDavid du Colombier }
56da51d93aSDavid du Colombier 
57da51d93aSDavid du Colombier static Node *
58da51d93aSDavid du Colombier anonreg(void)
59da51d93aSDavid du Colombier {
60da51d93aSDavid du Colombier 	Node *n;
61da51d93aSDavid du Colombier 
62da51d93aSDavid du Colombier 	n = new(OREGISTER, Z, Z);
63da51d93aSDavid du Colombier 	n->reg = D_NONE;
64da51d93aSDavid du Colombier 	n->type = types[TLONG];
65da51d93aSDavid du Colombier 	return n;
66da51d93aSDavid du Colombier }
67da51d93aSDavid du Colombier 
68da51d93aSDavid du Colombier static Node *
69da51d93aSDavid du Colombier regpair(Node *n, Node *t)
70da51d93aSDavid du Colombier {
71da51d93aSDavid du Colombier 	Node *r;
72da51d93aSDavid du Colombier 
73da51d93aSDavid du Colombier 	if(n != Z && n->op == OREGPAIR)
74da51d93aSDavid du Colombier 		return n;
75da51d93aSDavid du Colombier 	r = new(OREGPAIR, anonreg(), anonreg());
76da51d93aSDavid du Colombier 	if(n != Z)
77da51d93aSDavid du Colombier 		r->type = n->type;
78da51d93aSDavid du Colombier 	else
79da51d93aSDavid du Colombier 		r->type = t->type;
80da51d93aSDavid du Colombier 	return r;
81da51d93aSDavid du Colombier }
82da51d93aSDavid du Colombier 
83da51d93aSDavid du Colombier static void
84375daca8SDavid du Colombier evacaxdx(Node *r)
85da51d93aSDavid du Colombier {
86375daca8SDavid du Colombier 	Node nod1, nod2;
87375daca8SDavid du Colombier 
88375daca8SDavid du Colombier 	if(r->reg == D_AX || r->reg == D_DX) {
89375daca8SDavid du Colombier 		reg[D_AX]++;
90375daca8SDavid du Colombier 		reg[D_DX]++;
91375daca8SDavid du Colombier 		/*
92375daca8SDavid du Colombier 		 * this is just an optim that should
93375daca8SDavid du Colombier 		 * check for spill
94375daca8SDavid du Colombier 		 */
95375daca8SDavid du Colombier 		r->type = types[TULONG];
96375daca8SDavid du Colombier 		regalloc(&nod1, r, Z);
97375daca8SDavid du Colombier 		nodreg(&nod2, Z, r->reg);
98375daca8SDavid du Colombier 		gins(AMOVL, &nod2, &nod1);
99375daca8SDavid du Colombier 		regfree(r);
100375daca8SDavid du Colombier 		r->reg = nod1.reg;
101375daca8SDavid du Colombier 		reg[D_AX]--;
102375daca8SDavid du Colombier 		reg[D_DX]--;
103375daca8SDavid du Colombier 	}
104375daca8SDavid du Colombier }
105375daca8SDavid du Colombier 
106375daca8SDavid du Colombier /* lazy instantiation of register pair */
107375daca8SDavid du Colombier static int
108375daca8SDavid du Colombier instpair(Node *n, Node *l)
109375daca8SDavid du Colombier {
110375daca8SDavid du Colombier 	int r;
111375daca8SDavid du Colombier 
112375daca8SDavid du Colombier 	r = 0;
113375daca8SDavid du Colombier 	if(n->left->reg == D_NONE) {
114375daca8SDavid du Colombier 		if(l != Z) {
115375daca8SDavid du Colombier 			n->left->reg = l->reg;
116375daca8SDavid du Colombier 			r = 1;
117375daca8SDavid du Colombier 		}
118375daca8SDavid du Colombier 		else
119da51d93aSDavid du Colombier 			regalloc(n->left, n->left, Z);
120375daca8SDavid du Colombier 	}
121375daca8SDavid du Colombier 	if(n->right->reg == D_NONE)
122da51d93aSDavid du Colombier 		regalloc(n->right, n->right, Z);
123375daca8SDavid du Colombier 	return r;
124375daca8SDavid du Colombier }
125375daca8SDavid du Colombier 
126375daca8SDavid du Colombier static void
127375daca8SDavid du Colombier zapreg(Node *n)
128375daca8SDavid du Colombier {
129375daca8SDavid du Colombier 	if(n->reg != D_NONE) {
130375daca8SDavid du Colombier 		regfree(n);
131375daca8SDavid du Colombier 		n->reg = D_NONE;
132375daca8SDavid du Colombier 	}
133da51d93aSDavid du Colombier }
134da51d93aSDavid du Colombier 
135da51d93aSDavid du Colombier static void
136da51d93aSDavid du Colombier freepair(Node *n)
137da51d93aSDavid du Colombier {
138da51d93aSDavid du Colombier 	regfree(n->left);
139da51d93aSDavid du Colombier 	regfree(n->right);
140da51d93aSDavid du Colombier }
141da51d93aSDavid du Colombier 
142da51d93aSDavid du Colombier /* n is not OREGPAIR, nn is */
143da51d93aSDavid du Colombier void
144da51d93aSDavid du Colombier loadpair(Node *n, Node *nn)
145da51d93aSDavid du Colombier {
146da51d93aSDavid du Colombier 	Node nod;
147da51d93aSDavid du Colombier 
148375daca8SDavid du Colombier 	instpair(nn, Z);
149da51d93aSDavid du Colombier 	if(n->op == OCONST) {
150da51d93aSDavid du Colombier 		gins(AMOVL, lo64(n), nn->left);
151da51d93aSDavid du Colombier 		n->xoffset += SZ_LONG;
152da51d93aSDavid du Colombier 		gins(AMOVL, hi64(n), nn->right);
153da51d93aSDavid du Colombier 		n->xoffset -= SZ_LONG;
154da51d93aSDavid du Colombier 		return;
155da51d93aSDavid du Colombier 	}
156375daca8SDavid du Colombier 	if(!vaddr(n, 0)) {
157da51d93aSDavid du Colombier 		/* steal the right register for the laddr */
158da51d93aSDavid du Colombier 		nod = regnode;
159da51d93aSDavid du Colombier 		nod.reg = nn->right->reg;
160da51d93aSDavid du Colombier 		lcgen(n, &nod);
161da51d93aSDavid du Colombier 		n = &nod;
162da51d93aSDavid du Colombier 		regind(n, n);
163da51d93aSDavid du Colombier 		n->xoffset = 0;
164da51d93aSDavid du Colombier 	}
165da51d93aSDavid du Colombier 	gins(AMOVL, n, nn->left);
166da51d93aSDavid du Colombier 	n->xoffset += SZ_LONG;
167da51d93aSDavid du Colombier 	gins(AMOVL, n, nn->right);
168da51d93aSDavid du Colombier 	n->xoffset -= SZ_LONG;
169da51d93aSDavid du Colombier }
170da51d93aSDavid du Colombier 
171da51d93aSDavid du Colombier /* n is OREGPAIR, nn is not */
172da51d93aSDavid du Colombier static void
173da51d93aSDavid du Colombier storepair(Node *n, Node *nn, int f)
174da51d93aSDavid du Colombier {
175da51d93aSDavid du Colombier 	Node nod;
176da51d93aSDavid du Colombier 
177375daca8SDavid du Colombier 	if(!vaddr(nn, 0)) {
178da51d93aSDavid du Colombier 		reglcgen(&nod, nn, Z);
179da51d93aSDavid du Colombier 		nn = &nod;
180da51d93aSDavid du Colombier 	}
181da51d93aSDavid du Colombier 	gins(AMOVL, n->left, nn);
182da51d93aSDavid du Colombier 	nn->xoffset += SZ_LONG;
183da51d93aSDavid du Colombier 	gins(AMOVL, n->right, nn);
184da51d93aSDavid du Colombier 	nn->xoffset -= SZ_LONG;
185da51d93aSDavid du Colombier 	if(nn == &nod)
186da51d93aSDavid du Colombier 		regfree(&nod);
187da51d93aSDavid du Colombier 	if(f)
188da51d93aSDavid du Colombier 		freepair(n);
189da51d93aSDavid du Colombier }
190da51d93aSDavid du Colombier 
191da51d93aSDavid du Colombier /* generate a cast t from n to tt */
192da51d93aSDavid du Colombier static void
193da51d93aSDavid du Colombier cast(Node *n, Type *t, Node *nn)
194da51d93aSDavid du Colombier {
195da51d93aSDavid du Colombier 	Node *r;
196da51d93aSDavid du Colombier 
197da51d93aSDavid du Colombier 	r = new(OCAST, n, Z);
198da51d93aSDavid du Colombier 	r->type = t;
199da51d93aSDavid du Colombier 	sugen(r, nn, 8);
200da51d93aSDavid du Colombier }
201da51d93aSDavid du Colombier 
202da51d93aSDavid du Colombier static void
203da51d93aSDavid du Colombier swapregs(Node *a, Node *b)
204da51d93aSDavid du Colombier {
205da51d93aSDavid du Colombier 	int t;
206da51d93aSDavid du Colombier 
207da51d93aSDavid du Colombier 	t = a->reg;
208da51d93aSDavid du Colombier 	a->reg = b->reg;
209da51d93aSDavid du Colombier 	b->reg = t;
210da51d93aSDavid du Colombier }
211da51d93aSDavid du Colombier 
212da51d93aSDavid du Colombier static void
213da51d93aSDavid du Colombier swappairs(Node *a, Node *b)
214da51d93aSDavid du Colombier {
215da51d93aSDavid du Colombier 	swapregs(a->left, b->left);
216da51d93aSDavid du Colombier 	swapregs(a->right, b->right);
217da51d93aSDavid du Colombier }
218da51d93aSDavid du Colombier 
219da51d93aSDavid du Colombier static int
220da51d93aSDavid du Colombier saveme(Node *n)
221da51d93aSDavid du Colombier {
222da51d93aSDavid du Colombier 	int r;
223da51d93aSDavid du Colombier 
224da51d93aSDavid du Colombier 	r = n->reg;
225da51d93aSDavid du Colombier 	return r >= D_AX && r <= D_DI;
226da51d93aSDavid du Colombier }
227da51d93aSDavid du Colombier 
228da51d93aSDavid du Colombier static void
229da51d93aSDavid du Colombier saveit(Node *n, Node *t, Node *r)
230da51d93aSDavid du Colombier {
231da51d93aSDavid du Colombier 	Node nod;
232da51d93aSDavid du Colombier 
233da51d93aSDavid du Colombier 	if(saveme(n)) {
234da51d93aSDavid du Colombier 		t->reg = n->reg;
235da51d93aSDavid du Colombier 		gins(AMOVL, t, r);
236da51d93aSDavid du Colombier 		r->xoffset += SZ_LONG;
237da51d93aSDavid du Colombier 		if(n->reg == D_AX) {
238da51d93aSDavid du Colombier 			regalloc(&nod, n, Z);
239da51d93aSDavid du Colombier 			regfree(n);
240da51d93aSDavid du Colombier 			n->reg = nod.reg;
241da51d93aSDavid du Colombier 		}
242da51d93aSDavid du Colombier 	}
243da51d93aSDavid du Colombier }
244da51d93aSDavid du Colombier 
245da51d93aSDavid du Colombier static void
246da51d93aSDavid du Colombier restoreit(Node *n, Node *t, Node *r)
247da51d93aSDavid du Colombier {
248da51d93aSDavid du Colombier 	if(saveme(n)) {
249da51d93aSDavid du Colombier 		t->reg = n->reg;
250da51d93aSDavid du Colombier 		gins(AMOVL, r, t);
251da51d93aSDavid du Colombier 		r->xoffset += SZ_LONG;
252da51d93aSDavid du Colombier 	}
253da51d93aSDavid du Colombier }
254da51d93aSDavid du Colombier 
255da51d93aSDavid du Colombier enum
256da51d93aSDavid du Colombier {
257da51d93aSDavid du Colombier /* 4 only, see WW */
258da51d93aSDavid du Colombier 	WNONE	= 0,
259da51d93aSDavid du Colombier 	WCONST,
260da51d93aSDavid du Colombier 	WADDR,
261da51d93aSDavid du Colombier 	WHARD,
262da51d93aSDavid du Colombier };
263da51d93aSDavid du Colombier 
264da51d93aSDavid du Colombier static int
265da51d93aSDavid du Colombier whatof(Node *n, int a)
266da51d93aSDavid du Colombier {
267da51d93aSDavid du Colombier 	if(n->op == OCONST)
268da51d93aSDavid du Colombier 		return WCONST;
269375daca8SDavid du Colombier 	return !vaddr(n, a) ? WHARD : WADDR;
270da51d93aSDavid du Colombier }
271da51d93aSDavid du Colombier 
272da51d93aSDavid du Colombier /* can upgrade an extern to addr for AND */
273da51d93aSDavid du Colombier static int
274da51d93aSDavid du Colombier reduxv(Node *n)
275da51d93aSDavid du Colombier {
276da51d93aSDavid du Colombier 	return lo64v(n) == 0 || hi64v(n) == 0;
277da51d93aSDavid du Colombier }
278da51d93aSDavid du Colombier 
279da51d93aSDavid du Colombier int
280da51d93aSDavid du Colombier cond(int op)
281da51d93aSDavid du Colombier {
282da51d93aSDavid du Colombier 	switch(op) {
283da51d93aSDavid du Colombier 	case OANDAND:
284da51d93aSDavid du Colombier 	case OOROR:
285da51d93aSDavid du Colombier 	case ONOT:
286da51d93aSDavid du Colombier 		return 1;
287da51d93aSDavid du Colombier 
288da51d93aSDavid du Colombier 	case OEQ:
289da51d93aSDavid du Colombier 	case ONE:
290da51d93aSDavid du Colombier 	case OLE:
291da51d93aSDavid du Colombier 	case OLT:
292da51d93aSDavid du Colombier 	case OGE:
293da51d93aSDavid du Colombier 	case OGT:
294da51d93aSDavid du Colombier 	case OHI:
295da51d93aSDavid du Colombier 	case OHS:
296da51d93aSDavid du Colombier 	case OLO:
297da51d93aSDavid du Colombier 	case OLS:
298da51d93aSDavid du Colombier 		return 1;
299da51d93aSDavid du Colombier 	}
300da51d93aSDavid du Colombier 	return 0;
301da51d93aSDavid du Colombier }
302da51d93aSDavid du Colombier 
303da51d93aSDavid du Colombier /*
304da51d93aSDavid du Colombier  * for a func operand call it and then return
305da51d93aSDavid du Colombier  * the safe node
306da51d93aSDavid du Colombier  */
307da51d93aSDavid du Colombier static Node *
308da51d93aSDavid du Colombier vfunc(Node *n, Node *nn)
309da51d93aSDavid du Colombier {
310da51d93aSDavid du Colombier 	Node *t;
311da51d93aSDavid du Colombier 
312da51d93aSDavid du Colombier 	if(n->op != OFUNC)
313da51d93aSDavid du Colombier 		return n;
314da51d93aSDavid du Colombier 	t = new(0, Z, Z);
315da51d93aSDavid du Colombier 	if(nn == Z || nn == nodret)
316da51d93aSDavid du Colombier 		nn = n;
317da51d93aSDavid du Colombier 	regsalloc(t, nn);
318da51d93aSDavid du Colombier 	sugen(n, t, 8);
319da51d93aSDavid du Colombier 	return t;
320da51d93aSDavid du Colombier }
321da51d93aSDavid du Colombier 
322da51d93aSDavid du Colombier static int
323375daca8SDavid du Colombier forcereg(Node *d, int r, int o, Node *t)
324375daca8SDavid du Colombier {
325375daca8SDavid du Colombier 	int a;
326375daca8SDavid du Colombier 
327375daca8SDavid du Colombier 	if(d->reg != D_NONE)
328375daca8SDavid du Colombier 		diag(Z, "force alloc");
329375daca8SDavid du Colombier 	d->reg = r;
330375daca8SDavid du Colombier 	a = 0;
331375daca8SDavid du Colombier 	if(reg[r]) {
332375daca8SDavid du Colombier 		reg[o]++;
333375daca8SDavid du Colombier 		regalloc(t, d, Z);
334375daca8SDavid du Colombier 		a = 1;
335375daca8SDavid du Colombier 		gins(AMOVL, d, t);
336375daca8SDavid du Colombier 		reg[o]--;
337375daca8SDavid du Colombier 	}
338375daca8SDavid du Colombier 	reg[r]++;
339375daca8SDavid du Colombier 	return a;
340375daca8SDavid du Colombier }
341375daca8SDavid du Colombier 
342375daca8SDavid du Colombier /* try to steal a reg */
343375daca8SDavid du Colombier static int
344375daca8SDavid du Colombier getreg(Node **np, Node *t, int r)
345da51d93aSDavid du Colombier {
346da51d93aSDavid du Colombier 	Node *n, *p;
347da51d93aSDavid du Colombier 
348da51d93aSDavid du Colombier 	n = *np;
349375daca8SDavid du Colombier 	if(n->reg == r) {
350da51d93aSDavid du Colombier 		p = new(0, Z, Z);
351da51d93aSDavid du Colombier 		regalloc(p, n, Z);
352da51d93aSDavid du Colombier 		gins(AMOVL, n, p);
353da51d93aSDavid du Colombier 		*t = *n;
354da51d93aSDavid du Colombier 		*np = p;
355da51d93aSDavid du Colombier 		return 1;
356da51d93aSDavid du Colombier 	}
357da51d93aSDavid du Colombier 	return 0;
358da51d93aSDavid du Colombier }
359da51d93aSDavid du Colombier 
360375daca8SDavid du Colombier static Node *
361375daca8SDavid du Colombier snarfreg(Node *n, Node *t, int r, Node *d, Node *c)
362375daca8SDavid du Colombier {
363375daca8SDavid du Colombier 	if(n == Z || n->op != OREGPAIR || (!getreg(&n->left, t, r) && !getreg(&n->right, t, r))) {
364375daca8SDavid du Colombier 		if(nodreg(t, Z, r)) {
365375daca8SDavid du Colombier 			regalloc(c, d, Z);
366375daca8SDavid du Colombier 			gins(AMOVL, t, c);
367375daca8SDavid du Colombier 			reg[r]++;
368375daca8SDavid du Colombier 			return c;
369375daca8SDavid du Colombier 		}
370375daca8SDavid du Colombier 		reg[r]++;
371375daca8SDavid du Colombier 	}
372375daca8SDavid du Colombier 	return Z;
373375daca8SDavid du Colombier }
374375daca8SDavid du Colombier 
375da51d93aSDavid du Colombier enum
376da51d93aSDavid du Colombier {
377da51d93aSDavid du Colombier 	Vstart	= OEND,
378da51d93aSDavid du Colombier 
379da51d93aSDavid du Colombier 	Vgo,
380da51d93aSDavid du Colombier 	Vamv,
381da51d93aSDavid du Colombier 	Vmv,
382da51d93aSDavid du Colombier 	Vzero,
383da51d93aSDavid du Colombier 	Vop,
384da51d93aSDavid du Colombier 	Vopx,
385da51d93aSDavid du Colombier 	Vins,
386da51d93aSDavid du Colombier 	Vins0,
387da51d93aSDavid du Colombier 	Vinsl,
388da51d93aSDavid du Colombier 	Vinsr,
389da51d93aSDavid du Colombier 	Vinsla,
390da51d93aSDavid du Colombier 	Vinsra,
391da51d93aSDavid du Colombier 	Vinsx,
392375daca8SDavid du Colombier 	Vmul,
393375daca8SDavid du Colombier 	Vshll,
394da51d93aSDavid du Colombier 	VT,
395da51d93aSDavid du Colombier 	VF,
396da51d93aSDavid du Colombier 	V_l_lo_f,
397da51d93aSDavid du Colombier 	V_l_hi_f,
398da51d93aSDavid du Colombier 	V_l_lo_t,
399da51d93aSDavid du Colombier 	V_l_hi_t,
400da51d93aSDavid du Colombier 	V_l_lo_u,
401da51d93aSDavid du Colombier 	V_l_hi_u,
402da51d93aSDavid du Colombier 	V_r_lo_f,
403da51d93aSDavid du Colombier 	V_r_hi_f,
404da51d93aSDavid du Colombier 	V_r_lo_t,
405da51d93aSDavid du Colombier 	V_r_hi_t,
406da51d93aSDavid du Colombier 	V_r_lo_u,
407da51d93aSDavid du Colombier 	V_r_hi_u,
408da51d93aSDavid du Colombier 	Vspazz,
409da51d93aSDavid du Colombier 	Vend,
410da51d93aSDavid du Colombier 
411da51d93aSDavid du Colombier 	V_T0,
412da51d93aSDavid du Colombier 	V_T1,
413da51d93aSDavid du Colombier 	V_F0,
414da51d93aSDavid du Colombier 	V_F1,
415da51d93aSDavid du Colombier 
416da51d93aSDavid du Colombier 	V_a0,
417da51d93aSDavid du Colombier 	V_a1,
418da51d93aSDavid du Colombier 	V_f0,
419da51d93aSDavid du Colombier 	V_f1,
420da51d93aSDavid du Colombier 
421da51d93aSDavid du Colombier 	V_p0,
422da51d93aSDavid du Colombier 	V_p1,
423da51d93aSDavid du Colombier 	V_p2,
424da51d93aSDavid du Colombier 	V_p3,
425da51d93aSDavid du Colombier 	V_p4,
426da51d93aSDavid du Colombier 
427da51d93aSDavid du Colombier 	V_s0,
428da51d93aSDavid du Colombier 	V_s1,
429da51d93aSDavid du Colombier 	V_s2,
430da51d93aSDavid du Colombier 	V_s3,
431da51d93aSDavid du Colombier 	V_s4,
432da51d93aSDavid du Colombier 
433da51d93aSDavid du Colombier 	C00,
434da51d93aSDavid du Colombier 	C01,
435da51d93aSDavid du Colombier 	C31,
436da51d93aSDavid du Colombier 	C32,
437da51d93aSDavid du Colombier 
438da51d93aSDavid du Colombier 	O_l_lo,
439da51d93aSDavid du Colombier 	O_l_hi,
440da51d93aSDavid du Colombier 	O_r_lo,
441da51d93aSDavid du Colombier 	O_r_hi,
442da51d93aSDavid du Colombier 	O_t_lo,
443da51d93aSDavid du Colombier 	O_t_hi,
444da51d93aSDavid du Colombier 	O_l,
445da51d93aSDavid du Colombier 	O_r,
446da51d93aSDavid du Colombier 	O_l_rp,
447da51d93aSDavid du Colombier 	O_r_rp,
448da51d93aSDavid du Colombier 	O_t_rp,
449da51d93aSDavid du Colombier 	O_r0,
450da51d93aSDavid du Colombier 	O_r1,
451375daca8SDavid du Colombier 	O_Zop,
452da51d93aSDavid du Colombier 
453da51d93aSDavid du Colombier 	O_a0,
454da51d93aSDavid du Colombier 	O_a1,
455da51d93aSDavid du Colombier 
456da51d93aSDavid du Colombier 	V_C0,
457da51d93aSDavid du Colombier 	V_C1,
458da51d93aSDavid du Colombier 
459da51d93aSDavid du Colombier 	V_S0,
460da51d93aSDavid du Colombier 	V_S1,
461da51d93aSDavid du Colombier 
462da51d93aSDavid du Colombier 	VOPS	= 5,
463da51d93aSDavid du Colombier 	VLEN	= 5,
464da51d93aSDavid du Colombier 	VARGS	= 2,
465da51d93aSDavid du Colombier 
466da51d93aSDavid du Colombier 	S00	= 0,
467da51d93aSDavid du Colombier 	Sc0,
468da51d93aSDavid du Colombier 	Sc1,
469da51d93aSDavid du Colombier 	Sc2,
470da51d93aSDavid du Colombier 	Sac3,
471da51d93aSDavid du Colombier 	Sac4,
472da51d93aSDavid du Colombier 	S10,
473da51d93aSDavid du Colombier 
474da51d93aSDavid du Colombier 	SAgen	= 0,
475da51d93aSDavid du Colombier 	SAclo,
476da51d93aSDavid du Colombier 	SAc32,
477da51d93aSDavid du Colombier 	SAchi,
478da51d93aSDavid du Colombier 	SAdgen,
479da51d93aSDavid du Colombier 	SAdclo,
480da51d93aSDavid du Colombier 	SAdc32,
481da51d93aSDavid du Colombier 	SAdchi,
482da51d93aSDavid du Colombier 
483da51d93aSDavid du Colombier 	B0c	= 0,
484da51d93aSDavid du Colombier 	Bca,
485da51d93aSDavid du Colombier 	Bac,
486da51d93aSDavid du Colombier 
487da51d93aSDavid du Colombier 	T0i	= 0,
488da51d93aSDavid du Colombier 	Tii,
489da51d93aSDavid du Colombier 
490da51d93aSDavid du Colombier 	Bop0	= 0,
491da51d93aSDavid du Colombier 	Bop1,
492da51d93aSDavid du Colombier };
493da51d93aSDavid du Colombier 
494da51d93aSDavid du Colombier /*
495da51d93aSDavid du Colombier  * _testv:
496da51d93aSDavid du Colombier  * 	CMPL	lo,$0
497da51d93aSDavid du Colombier  * 	JNE	true
498da51d93aSDavid du Colombier  * 	CMPL	hi,$0
499da51d93aSDavid du Colombier  * 	JNE	true
500da51d93aSDavid du Colombier  * 	GOTO	false
501da51d93aSDavid du Colombier  * false:
502da51d93aSDavid du Colombier  * 	GOTO	code
503da51d93aSDavid du Colombier  * true:
504da51d93aSDavid du Colombier  * 	GOTO	patchme
505da51d93aSDavid du Colombier  * code:
506da51d93aSDavid du Colombier  */
507da51d93aSDavid du Colombier 
508da51d93aSDavid du Colombier static uchar	testi[][VLEN] =
509da51d93aSDavid du Colombier {
510da51d93aSDavid du Colombier 	{Vop, ONE, O_l_lo, C00},
511da51d93aSDavid du Colombier 	{V_s0, Vop, ONE, O_l_hi, C00},
512da51d93aSDavid du Colombier 	{V_s1, Vgo, V_s2, Vgo, V_s3},
513da51d93aSDavid du Colombier 	{VF, V_p0, V_p1, VT, V_p2},
514da51d93aSDavid du Colombier 	{Vgo, V_p3},
515da51d93aSDavid du Colombier 	{VT, V_p0, V_p1, VF, V_p2},
516da51d93aSDavid du Colombier 	{Vend},
517da51d93aSDavid du Colombier };
518da51d93aSDavid du Colombier 
519da51d93aSDavid du Colombier /* shift left general case */
520da51d93aSDavid du Colombier static uchar	shll00[][VLEN] =
521da51d93aSDavid du Colombier {
522da51d93aSDavid du Colombier 	{Vop, OGE, O_r, C32},
523da51d93aSDavid du Colombier 	{V_s0, Vinsl, ASHLL, O_r, O_l_rp},
524da51d93aSDavid du Colombier 	{Vins, ASHLL, O_r, O_l_lo, Vgo},
525da51d93aSDavid du Colombier 	{V_p0, V_s0},
526da51d93aSDavid du Colombier 	{Vins, ASHLL, O_r, O_l_lo},
527da51d93aSDavid du Colombier 	{Vins, AMOVL, O_l_lo, O_l_hi},
528da51d93aSDavid du Colombier 	{Vzero, O_l_lo, V_p0, Vend},
529da51d93aSDavid du Colombier };
530da51d93aSDavid du Colombier 
531da51d93aSDavid du Colombier /* shift left rp, const < 32 */
532da51d93aSDavid du Colombier static uchar	shllc0[][VLEN] =
533da51d93aSDavid du Colombier {
534da51d93aSDavid du Colombier 	{Vinsl, ASHLL, O_r, O_l_rp},
535375daca8SDavid du Colombier 	{Vshll, O_r, O_l_lo, Vend},
536da51d93aSDavid du Colombier };
537da51d93aSDavid du Colombier 
538da51d93aSDavid du Colombier /* shift left rp, const == 32 */
539da51d93aSDavid du Colombier static uchar	shllc1[][VLEN] =
540da51d93aSDavid du Colombier {
541da51d93aSDavid du Colombier 	{Vins, AMOVL, O_l_lo, O_l_hi},
542da51d93aSDavid du Colombier 	{Vzero, O_l_lo, Vend},
543da51d93aSDavid du Colombier };
544da51d93aSDavid du Colombier 
545da51d93aSDavid du Colombier /* shift left rp, const > 32 */
546da51d93aSDavid du Colombier static uchar	shllc2[][VLEN] =
547da51d93aSDavid du Colombier {
548375daca8SDavid du Colombier 	{Vshll, O_r, O_l_lo},
549da51d93aSDavid du Colombier 	{Vins, AMOVL, O_l_lo, O_l_hi},
550da51d93aSDavid du Colombier 	{Vzero, O_l_lo, Vend},
551da51d93aSDavid du Colombier };
552da51d93aSDavid du Colombier 
553da51d93aSDavid du Colombier /* shift left addr, const == 32 */
554da51d93aSDavid du Colombier static uchar	shllac3[][VLEN] =
555da51d93aSDavid du Colombier {
556da51d93aSDavid du Colombier 	{Vins, AMOVL, O_l_lo, O_t_hi},
557da51d93aSDavid du Colombier 	{Vzero, O_t_lo, Vend},
558da51d93aSDavid du Colombier };
559da51d93aSDavid du Colombier 
560da51d93aSDavid du Colombier /* shift left addr, const > 32 */
561da51d93aSDavid du Colombier static uchar	shllac4[][VLEN] =
562da51d93aSDavid du Colombier {
563da51d93aSDavid du Colombier 	{Vins, AMOVL, O_l_lo, O_t_hi},
564375daca8SDavid du Colombier 	{Vshll, O_r, O_t_hi},
565da51d93aSDavid du Colombier 	{Vzero, O_t_lo, Vend},
566da51d93aSDavid du Colombier };
567da51d93aSDavid du Colombier 
568da51d93aSDavid du Colombier /* shift left of constant */
569da51d93aSDavid du Colombier static uchar	shll10[][VLEN] =
570da51d93aSDavid du Colombier {
571da51d93aSDavid du Colombier 	{Vop, OGE, O_r, C32},
572da51d93aSDavid du Colombier 	{V_s0, Vins, AMOVL, O_l_lo, O_t_lo},
573da51d93aSDavid du Colombier 	{Vins, AMOVL, O_l_hi, O_t_hi},
574da51d93aSDavid du Colombier 	{Vinsl, ASHLL, O_r, O_t_rp},
575da51d93aSDavid du Colombier 	{Vins, ASHLL, O_r, O_t_lo, Vgo},
576da51d93aSDavid du Colombier 	{V_p0, V_s0},
577da51d93aSDavid du Colombier 	{Vins, AMOVL, O_l_lo, O_t_hi},
578da51d93aSDavid du Colombier 	{V_l_lo_t, Vins, ASHLL, O_r, O_t_hi},
579da51d93aSDavid du Colombier 	{Vzero, O_t_lo, V_p0, Vend},
580da51d93aSDavid du Colombier };
581da51d93aSDavid du Colombier 
582da51d93aSDavid du Colombier static uchar	(*shlltab[])[VLEN] =
583da51d93aSDavid du Colombier {
584da51d93aSDavid du Colombier 	shll00,
585da51d93aSDavid du Colombier 	shllc0,
586da51d93aSDavid du Colombier 	shllc1,
587da51d93aSDavid du Colombier 	shllc2,
588da51d93aSDavid du Colombier 	shllac3,
589da51d93aSDavid du Colombier 	shllac4,
590da51d93aSDavid du Colombier 	shll10,
591da51d93aSDavid du Colombier };
592da51d93aSDavid du Colombier 
593da51d93aSDavid du Colombier /* shift right general case */
594da51d93aSDavid du Colombier static uchar	shrl00[][VLEN] =
595da51d93aSDavid du Colombier {
596da51d93aSDavid du Colombier 	{Vop, OGE, O_r, C32},
597da51d93aSDavid du Colombier 	{V_s0, Vinsr, ASHRL, O_r, O_l_rp},
598da51d93aSDavid du Colombier 	{Vins, O_a0, O_r, O_l_hi, Vgo},
599da51d93aSDavid du Colombier 	{V_p0, V_s0},
600da51d93aSDavid du Colombier 	{Vins, O_a0, O_r, O_l_hi},
601da51d93aSDavid du Colombier 	{Vins, AMOVL, O_l_hi, O_l_lo},
602da51d93aSDavid du Colombier 	{V_T1, Vzero, O_l_hi},
603da51d93aSDavid du Colombier 	{V_F1, Vins, ASARL, C31, O_l_hi},
604da51d93aSDavid du Colombier 	{V_p0, Vend},
605da51d93aSDavid du Colombier };
606da51d93aSDavid du Colombier 
607da51d93aSDavid du Colombier /* shift right rp, const < 32 */
608da51d93aSDavid du Colombier static uchar	shrlc0[][VLEN] =
609da51d93aSDavid du Colombier {
610da51d93aSDavid du Colombier 	{Vinsr, ASHRL, O_r, O_l_rp},
611da51d93aSDavid du Colombier 	{Vins, O_a0, O_r, O_l_hi, Vend},
612da51d93aSDavid du Colombier };
613da51d93aSDavid du Colombier 
614da51d93aSDavid du Colombier /* shift right rp, const == 32 */
615da51d93aSDavid du Colombier static uchar	shrlc1[][VLEN] =
616da51d93aSDavid du Colombier {
617da51d93aSDavid du Colombier 	{Vins, AMOVL, O_l_hi, O_l_lo},
618da51d93aSDavid du Colombier 	{V_T1, Vzero, O_l_hi},
619da51d93aSDavid du Colombier 	{V_F1, Vins, ASARL, C31, O_l_hi},
620da51d93aSDavid du Colombier 	{Vend},
621da51d93aSDavid du Colombier };
622da51d93aSDavid du Colombier 
623da51d93aSDavid du Colombier /* shift right rp, const > 32 */
624da51d93aSDavid du Colombier static uchar	shrlc2[][VLEN] =
625da51d93aSDavid du Colombier {
626da51d93aSDavid du Colombier 	{Vins, O_a0, O_r, O_l_hi},
627da51d93aSDavid du Colombier 	{Vins, AMOVL, O_l_hi, O_l_lo},
628da51d93aSDavid du Colombier 	{V_T1, Vzero, O_l_hi},
629da51d93aSDavid du Colombier 	{V_F1, Vins, ASARL, C31, O_l_hi},
630da51d93aSDavid du Colombier 	{Vend},
631da51d93aSDavid du Colombier };
632da51d93aSDavid du Colombier 
633da51d93aSDavid du Colombier /* shift right addr, const == 32 */
634da51d93aSDavid du Colombier static uchar	shrlac3[][VLEN] =
635da51d93aSDavid du Colombier {
636da51d93aSDavid du Colombier 	{Vins, AMOVL, O_l_hi, O_t_lo},
637da51d93aSDavid du Colombier 	{V_T1, Vzero, O_t_hi},
638da51d93aSDavid du Colombier 	{V_F1, Vins, AMOVL, O_t_lo, O_t_hi},
639da51d93aSDavid du Colombier 	{V_F1, Vins, ASARL, C31, O_t_hi},
640da51d93aSDavid du Colombier 	{Vend},
641da51d93aSDavid du Colombier };
642da51d93aSDavid du Colombier 
643da51d93aSDavid du Colombier /* shift right addr, const > 32 */
644da51d93aSDavid du Colombier static uchar	shrlac4[][VLEN] =
645da51d93aSDavid du Colombier {
646da51d93aSDavid du Colombier 	{Vins, AMOVL, O_l_hi, O_t_lo},
647da51d93aSDavid du Colombier 	{Vins, O_a0, O_r, O_t_lo},
648da51d93aSDavid du Colombier 	{V_T1, Vzero, O_t_hi},
649da51d93aSDavid du Colombier 	{V_F1, Vins, AMOVL, O_t_lo, O_t_hi},
650da51d93aSDavid du Colombier 	{V_F1, Vins, ASARL, C31, O_t_hi},
651da51d93aSDavid du Colombier 	{Vend},
652da51d93aSDavid du Colombier };
653da51d93aSDavid du Colombier 
654da51d93aSDavid du Colombier /* shift right of constant */
655da51d93aSDavid du Colombier static uchar	shrl10[][VLEN] =
656da51d93aSDavid du Colombier {
657da51d93aSDavid du Colombier 	{Vop, OGE, O_r, C32},
658da51d93aSDavid du Colombier 	{V_s0, Vins, AMOVL, O_l_lo, O_t_lo},
659da51d93aSDavid du Colombier 	{Vins, AMOVL, O_l_hi, O_t_hi},
660da51d93aSDavid du Colombier 	{Vinsr, ASHRL, O_r, O_t_rp},
661da51d93aSDavid du Colombier 	{Vins, O_a0, O_r, O_t_hi, Vgo},
662da51d93aSDavid du Colombier 	{V_p0, V_s0},
663da51d93aSDavid du Colombier 	{Vins, AMOVL, O_l_hi, O_t_lo},
664da51d93aSDavid du Colombier 	{V_l_hi_t, Vins, O_a0, O_r, O_t_lo},
665da51d93aSDavid du Colombier 	{V_l_hi_u, V_S1},
666da51d93aSDavid du Colombier 	{V_T1, Vzero, O_t_hi, V_p0},
667da51d93aSDavid du Colombier 	{V_F1, Vins, AMOVL, O_t_lo, O_t_hi},
668da51d93aSDavid du Colombier 	{V_F1, Vins, ASARL, C31, O_t_hi},
669da51d93aSDavid du Colombier 	{Vend},
670da51d93aSDavid du Colombier };
671da51d93aSDavid du Colombier 
672da51d93aSDavid du Colombier static uchar	(*shrltab[])[VLEN] =
673da51d93aSDavid du Colombier {
674da51d93aSDavid du Colombier 	shrl00,
675da51d93aSDavid du Colombier 	shrlc0,
676da51d93aSDavid du Colombier 	shrlc1,
677da51d93aSDavid du Colombier 	shrlc2,
678da51d93aSDavid du Colombier 	shrlac3,
679da51d93aSDavid du Colombier 	shrlac4,
680da51d93aSDavid du Colombier 	shrl10,
681da51d93aSDavid du Colombier };
682da51d93aSDavid du Colombier 
683da51d93aSDavid du Colombier /* shift asop left general case */
684da51d93aSDavid du Colombier static uchar	asshllgen[][VLEN] =
685da51d93aSDavid du Colombier {
686da51d93aSDavid du Colombier 	{V_a0, V_a1},
687da51d93aSDavid du Colombier 	{Vop, OGE, O_r, C32},
688da51d93aSDavid du Colombier 	{V_s0, Vins, AMOVL, O_l_lo, O_r0},
689da51d93aSDavid du Colombier 	{Vins, AMOVL, O_l_hi, O_r1},
690da51d93aSDavid du Colombier 	{Vinsla, ASHLL, O_r, O_r0},
691da51d93aSDavid du Colombier 	{Vins, ASHLL, O_r, O_r0},
692da51d93aSDavid du Colombier 	{Vins, AMOVL, O_r1, O_l_hi},
693da51d93aSDavid du Colombier 	{Vins, AMOVL, O_r0, O_l_lo, Vgo},
694da51d93aSDavid du Colombier 	{V_p0, V_s0},
695da51d93aSDavid du Colombier 	{Vins, AMOVL, O_l_lo, O_r0},
696da51d93aSDavid du Colombier 	{Vzero, O_l_lo},
697da51d93aSDavid du Colombier 	{Vins, ASHLL, O_r, O_r0},
698da51d93aSDavid du Colombier 	{Vins, AMOVL, O_r0, O_l_hi, V_p0},
699da51d93aSDavid du Colombier 	{V_f0, V_f1, Vend},
700da51d93aSDavid du Colombier };
701da51d93aSDavid du Colombier 
702da51d93aSDavid du Colombier /* shift asop left, const < 32 */
703da51d93aSDavid du Colombier static uchar	asshllclo[][VLEN] =
704da51d93aSDavid du Colombier {
705da51d93aSDavid du Colombier 	{V_a0, V_a1},
706da51d93aSDavid du Colombier 	{Vins, AMOVL, O_l_lo, O_r0},
707da51d93aSDavid du Colombier 	{Vins, AMOVL, O_l_hi, O_r1},
708da51d93aSDavid du Colombier 	{Vinsla, ASHLL, O_r, O_r0},
709375daca8SDavid du Colombier 	{Vshll, O_r, O_r0},
710da51d93aSDavid du Colombier 	{Vins, AMOVL, O_r1, O_l_hi},
711da51d93aSDavid du Colombier 	{Vins, AMOVL, O_r0, O_l_lo},
712da51d93aSDavid du Colombier 	{V_f0, V_f1, Vend},
713da51d93aSDavid du Colombier };
714da51d93aSDavid du Colombier 
715da51d93aSDavid du Colombier /* shift asop left, const == 32 */
716da51d93aSDavid du Colombier static uchar	asshllc32[][VLEN] =
717da51d93aSDavid du Colombier {
718da51d93aSDavid du Colombier 	{V_a0},
719da51d93aSDavid du Colombier 	{Vins, AMOVL, O_l_lo, O_r0},
720da51d93aSDavid du Colombier 	{Vzero, O_l_lo},
721da51d93aSDavid du Colombier 	{Vins, AMOVL, O_r0, O_l_hi},
722da51d93aSDavid du Colombier 	{V_f0, Vend},
723da51d93aSDavid du Colombier };
724da51d93aSDavid du Colombier 
725da51d93aSDavid du Colombier /* shift asop left, const > 32 */
726da51d93aSDavid du Colombier static uchar	asshllchi[][VLEN] =
727da51d93aSDavid du Colombier {
728da51d93aSDavid du Colombier 	{V_a0},
729da51d93aSDavid du Colombier 	{Vins, AMOVL, O_l_lo, O_r0},
730da51d93aSDavid du Colombier 	{Vzero, O_l_lo},
731375daca8SDavid du Colombier 	{Vshll, O_r, O_r0},
732da51d93aSDavid du Colombier 	{Vins, AMOVL, O_r0, O_l_hi},
733da51d93aSDavid du Colombier 	{V_f0, Vend},
734da51d93aSDavid du Colombier };
735da51d93aSDavid du Colombier 
736da51d93aSDavid du Colombier /* shift asop dest left general case */
737da51d93aSDavid du Colombier static uchar	asdshllgen[][VLEN] =
738da51d93aSDavid du Colombier {
739da51d93aSDavid du Colombier 	{Vop, OGE, O_r, C32},
740da51d93aSDavid du Colombier 	{V_s0, Vins, AMOVL, O_l_lo, O_t_lo},
741da51d93aSDavid du Colombier 	{Vins, AMOVL, O_l_hi, O_t_hi},
742da51d93aSDavid du Colombier 	{Vinsl, ASHLL, O_r, O_t_rp},
743da51d93aSDavid du Colombier 	{Vins, ASHLL, O_r, O_t_lo},
744da51d93aSDavid du Colombier 	{Vins, AMOVL, O_t_hi, O_l_hi},
745da51d93aSDavid du Colombier 	{Vins, AMOVL, O_t_lo, O_l_lo, Vgo},
746da51d93aSDavid du Colombier 	{V_p0, V_s0},
747da51d93aSDavid du Colombier 	{Vins, AMOVL, O_l_lo, O_t_hi},
748da51d93aSDavid du Colombier 	{Vzero, O_l_lo},
749da51d93aSDavid du Colombier 	{Vins, ASHLL, O_r, O_t_hi},
750da51d93aSDavid du Colombier 	{Vzero, O_t_lo},
751da51d93aSDavid du Colombier 	{Vins, AMOVL, O_t_hi, O_l_hi, V_p0},
752da51d93aSDavid du Colombier 	{Vend},
753da51d93aSDavid du Colombier };
754da51d93aSDavid du Colombier 
755da51d93aSDavid du Colombier /* shift asop dest left, const < 32 */
756da51d93aSDavid du Colombier static uchar	asdshllclo[][VLEN] =
757da51d93aSDavid du Colombier {
758da51d93aSDavid du Colombier 	{Vins, AMOVL, O_l_lo, O_t_lo},
759da51d93aSDavid du Colombier 	{Vins, AMOVL, O_l_hi, O_t_hi},
760da51d93aSDavid du Colombier 	{Vinsl, ASHLL, O_r, O_t_rp},
761375daca8SDavid du Colombier 	{Vshll, O_r, O_t_lo},
762da51d93aSDavid du Colombier 	{Vins, AMOVL, O_t_hi, O_l_hi},
763da51d93aSDavid du Colombier 	{Vins, AMOVL, O_t_lo, O_l_lo},
764da51d93aSDavid du Colombier 	{Vend},
765da51d93aSDavid du Colombier };
766da51d93aSDavid du Colombier 
767da51d93aSDavid du Colombier /* shift asop dest left, const == 32 */
768da51d93aSDavid du Colombier static uchar	asdshllc32[][VLEN] =
769da51d93aSDavid du Colombier {
770da51d93aSDavid du Colombier 	{Vins, AMOVL, O_l_lo, O_t_hi},
771da51d93aSDavid du Colombier 	{Vzero, O_t_lo},
772da51d93aSDavid du Colombier 	{Vins, AMOVL, O_t_hi, O_l_hi},
773da51d93aSDavid du Colombier 	{Vins, AMOVL, O_t_lo, O_l_lo},
774da51d93aSDavid du Colombier 	{Vend},
775da51d93aSDavid du Colombier };
776da51d93aSDavid du Colombier 
777da51d93aSDavid du Colombier /* shift asop dest, const > 32 */
778da51d93aSDavid du Colombier static uchar	asdshllchi[][VLEN] =
779da51d93aSDavid du Colombier {
780da51d93aSDavid du Colombier 	{Vins, AMOVL, O_l_lo, O_t_hi},
781da51d93aSDavid du Colombier 	{Vzero, O_t_lo},
782375daca8SDavid du Colombier 	{Vshll, O_r, O_t_hi},
783da51d93aSDavid du Colombier 	{Vins, AMOVL, O_t_lo, O_l_lo},
784da51d93aSDavid du Colombier 	{Vins, AMOVL, O_t_hi, O_l_hi},
785da51d93aSDavid du Colombier 	{Vend},
786da51d93aSDavid du Colombier };
787da51d93aSDavid du Colombier 
788da51d93aSDavid du Colombier static uchar	(*asshlltab[])[VLEN] =
789da51d93aSDavid du Colombier {
790da51d93aSDavid du Colombier 	asshllgen,
791da51d93aSDavid du Colombier 	asshllclo,
792da51d93aSDavid du Colombier 	asshllc32,
793da51d93aSDavid du Colombier 	asshllchi,
794da51d93aSDavid du Colombier 	asdshllgen,
795da51d93aSDavid du Colombier 	asdshllclo,
796da51d93aSDavid du Colombier 	asdshllc32,
797da51d93aSDavid du Colombier 	asdshllchi,
798da51d93aSDavid du Colombier };
799da51d93aSDavid du Colombier 
800da51d93aSDavid du Colombier /* shift asop right general case */
801da51d93aSDavid du Colombier static uchar	asshrlgen[][VLEN] =
802da51d93aSDavid du Colombier {
803da51d93aSDavid du Colombier 	{V_a0, V_a1},
804da51d93aSDavid du Colombier 	{Vop, OGE, O_r, C32},
805da51d93aSDavid du Colombier 	{V_s0, Vins, AMOVL, O_l_lo, O_r0},
806da51d93aSDavid du Colombier 	{Vins, AMOVL, O_l_hi, O_r1},
807da51d93aSDavid du Colombier 	{Vinsra, ASHRL, O_r, O_r0},
808da51d93aSDavid du Colombier 	{Vinsx, Bop0, O_r, O_r1},
809da51d93aSDavid du Colombier 	{Vins, AMOVL, O_r0, O_l_lo},
810da51d93aSDavid du Colombier 	{Vins, AMOVL, O_r1, O_l_hi, Vgo},
811da51d93aSDavid du Colombier 	{V_p0, V_s0},
812da51d93aSDavid du Colombier 	{Vins, AMOVL, O_l_hi, O_r0},
813da51d93aSDavid du Colombier 	{Vinsx, Bop0, O_r, O_r0},
814da51d93aSDavid du Colombier 	{V_T1, Vzero, O_l_hi},
815da51d93aSDavid du Colombier 	{Vins, AMOVL, O_r0, O_l_lo},
816da51d93aSDavid du Colombier 	{V_F1, Vins, ASARL, C31, O_r0},
817da51d93aSDavid du Colombier 	{V_F1, Vins, AMOVL, O_r0, O_l_hi},
818da51d93aSDavid du Colombier 	{V_p0, V_f0, V_f1, Vend},
819da51d93aSDavid du Colombier };
820da51d93aSDavid du Colombier 
821da51d93aSDavid du Colombier /* shift asop right, const < 32 */
822da51d93aSDavid du Colombier static uchar	asshrlclo[][VLEN] =
823da51d93aSDavid du Colombier {
824da51d93aSDavid du Colombier 	{V_a0, V_a1},
825da51d93aSDavid du Colombier 	{Vins, AMOVL, O_l_lo, O_r0},
826da51d93aSDavid du Colombier 	{Vins, AMOVL, O_l_hi, O_r1},
827da51d93aSDavid du Colombier 	{Vinsra, ASHRL, O_r, O_r0},
828da51d93aSDavid du Colombier 	{Vinsx, Bop0, O_r, O_r1},
829da51d93aSDavid du Colombier 	{Vins, AMOVL, O_r0, O_l_lo},
830da51d93aSDavid du Colombier 	{Vins, AMOVL, O_r1, O_l_hi},
831da51d93aSDavid du Colombier 	{V_f0, V_f1, Vend},
832da51d93aSDavid du Colombier };
833da51d93aSDavid du Colombier 
834da51d93aSDavid du Colombier /* shift asop right, const == 32 */
835da51d93aSDavid du Colombier static uchar	asshrlc32[][VLEN] =
836da51d93aSDavid du Colombier {
837da51d93aSDavid du Colombier 	{V_a0},
838da51d93aSDavid du Colombier 	{Vins, AMOVL, O_l_hi, O_r0},
839da51d93aSDavid du Colombier 	{V_T1, Vzero, O_l_hi},
840da51d93aSDavid du Colombier 	{Vins, AMOVL, O_r0, O_l_lo},
841da51d93aSDavid du Colombier 	{V_F1, Vins, ASARL, C31, O_r0},
842da51d93aSDavid du Colombier 	{V_F1, Vins, AMOVL, O_r0, O_l_hi},
843da51d93aSDavid du Colombier 	{V_f0, Vend},
844da51d93aSDavid du Colombier };
845da51d93aSDavid du Colombier 
846da51d93aSDavid du Colombier /* shift asop right, const > 32 */
847da51d93aSDavid du Colombier static uchar	asshrlchi[][VLEN] =
848da51d93aSDavid du Colombier {
849da51d93aSDavid du Colombier 	{V_a0},
850da51d93aSDavid du Colombier 	{Vins, AMOVL, O_l_hi, O_r0},
851da51d93aSDavid du Colombier 	{V_T1, Vzero, O_l_hi},
852da51d93aSDavid du Colombier 	{Vinsx, Bop0, O_r, O_r0},
853da51d93aSDavid du Colombier 	{Vins, AMOVL, O_r0, O_l_lo},
854da51d93aSDavid du Colombier 	{V_F1, Vins, ASARL, C31, O_r0},
855da51d93aSDavid du Colombier 	{V_F1, Vins, AMOVL, O_r0, O_l_hi},
856da51d93aSDavid du Colombier 	{V_f0, Vend},
857da51d93aSDavid du Colombier };
858da51d93aSDavid du Colombier 
859da51d93aSDavid du Colombier /* shift asop dest right general case */
860da51d93aSDavid du Colombier static uchar	asdshrlgen[][VLEN] =
861da51d93aSDavid du Colombier {
862da51d93aSDavid du Colombier 	{Vop, OGE, O_r, C32},
863da51d93aSDavid du Colombier 	{V_s0, Vins, AMOVL, O_l_lo, O_t_lo},
864da51d93aSDavid du Colombier 	{Vins, AMOVL, O_l_hi, O_t_hi},
865da51d93aSDavid du Colombier 	{Vinsr, ASHRL, O_r, O_t_rp},
866da51d93aSDavid du Colombier 	{Vinsx, Bop0, O_r, O_t_hi},
867da51d93aSDavid du Colombier 	{Vins, AMOVL, O_t_lo, O_l_lo},
868da51d93aSDavid du Colombier 	{Vins, AMOVL, O_t_hi, O_l_hi, Vgo},
869da51d93aSDavid du Colombier 	{V_p0, V_s0},
870da51d93aSDavid du Colombier 	{Vins, AMOVL, O_l_hi, O_t_lo},
871da51d93aSDavid du Colombier 	{V_T1, Vzero, O_t_hi},
872da51d93aSDavid du Colombier 	{Vinsx, Bop0, O_r, O_t_lo},
873da51d93aSDavid du Colombier 	{V_F1, Vins, AMOVL, O_t_lo, O_t_hi},
874da51d93aSDavid du Colombier 	{V_F1, Vins, ASARL, C31, O_t_hi},
875da51d93aSDavid du Colombier 	{Vins, AMOVL, O_t_hi, O_l_hi, V_p0},
876da51d93aSDavid du Colombier 	{Vend},
877da51d93aSDavid du Colombier };
878da51d93aSDavid du Colombier 
879da51d93aSDavid du Colombier /* shift asop dest right, const < 32 */
880da51d93aSDavid du Colombier static uchar	asdshrlclo[][VLEN] =
881da51d93aSDavid du Colombier {
882da51d93aSDavid du Colombier 	{Vins, AMOVL, O_l_lo, O_t_lo},
883da51d93aSDavid du Colombier 	{Vins, AMOVL, O_l_hi, O_t_hi},
884da51d93aSDavid du Colombier 	{Vinsr, ASHRL, O_r, O_t_rp},
885da51d93aSDavid du Colombier 	{Vinsx, Bop0, O_r, O_t_hi},
886da51d93aSDavid du Colombier 	{Vins, AMOVL, O_t_lo, O_l_lo},
887da51d93aSDavid du Colombier 	{Vins, AMOVL, O_t_hi, O_l_hi},
888da51d93aSDavid du Colombier 	{Vend},
889da51d93aSDavid du Colombier };
890da51d93aSDavid du Colombier 
891da51d93aSDavid du Colombier /* shift asop dest right, const == 32 */
892da51d93aSDavid du Colombier static uchar	asdshrlc32[][VLEN] =
893da51d93aSDavid du Colombier {
894da51d93aSDavid du Colombier 	{Vins, AMOVL, O_l_hi, O_t_lo},
895da51d93aSDavid du Colombier 	{V_T1, Vzero, O_t_hi},
896da51d93aSDavid du Colombier 	{V_F1, Vins, AMOVL, O_t_lo, O_t_hi},
897da51d93aSDavid du Colombier 	{V_F1, Vins, ASARL, C31, O_t_hi},
898da51d93aSDavid du Colombier 	{Vins, AMOVL, O_t_lo, O_l_lo},
899da51d93aSDavid du Colombier 	{Vins, AMOVL, O_t_hi, O_l_hi},
900da51d93aSDavid du Colombier 	{Vend},
901da51d93aSDavid du Colombier };
902da51d93aSDavid du Colombier 
903da51d93aSDavid du Colombier /* shift asop dest, const > 32 */
904da51d93aSDavid du Colombier static uchar	asdshrlchi[][VLEN] =
905da51d93aSDavid du Colombier {
906da51d93aSDavid du Colombier 	{Vins, AMOVL, O_l_hi, O_t_lo},
907da51d93aSDavid du Colombier 	{V_T1, Vzero, O_t_hi},
908da51d93aSDavid du Colombier 	{Vinsx, Bop0, O_r, O_t_lo},
909da51d93aSDavid du Colombier 	{V_T1, Vins, AMOVL, O_t_hi, O_l_hi},
910da51d93aSDavid du Colombier 	{V_T1, Vins, AMOVL, O_t_lo, O_l_lo},
911da51d93aSDavid du Colombier 	{V_F1, Vins, AMOVL, O_t_lo, O_t_hi},
912da51d93aSDavid du Colombier 	{V_F1, Vins, ASARL, C31, O_t_hi},
913da51d93aSDavid du Colombier 	{V_F1, Vins, AMOVL, O_t_lo, O_l_lo},
914da51d93aSDavid du Colombier 	{V_F1, Vins, AMOVL, O_t_hi, O_l_hi},
915da51d93aSDavid du Colombier 	{Vend},
916da51d93aSDavid du Colombier };
917da51d93aSDavid du Colombier 
918da51d93aSDavid du Colombier static uchar	(*asshrltab[])[VLEN] =
919da51d93aSDavid du Colombier {
920da51d93aSDavid du Colombier 	asshrlgen,
921da51d93aSDavid du Colombier 	asshrlclo,
922da51d93aSDavid du Colombier 	asshrlc32,
923da51d93aSDavid du Colombier 	asshrlchi,
924da51d93aSDavid du Colombier 	asdshrlgen,
925da51d93aSDavid du Colombier 	asdshrlclo,
926da51d93aSDavid du Colombier 	asdshrlc32,
927da51d93aSDavid du Colombier 	asdshrlchi,
928da51d93aSDavid du Colombier };
929da51d93aSDavid du Colombier 
930da51d93aSDavid du Colombier static uchar	shrlargs[]	= { ASHRL, 1 };
931da51d93aSDavid du Colombier static uchar	sarlargs[]	= { ASARL, 0 };
932da51d93aSDavid du Colombier 
933da51d93aSDavid du Colombier /* ++ -- */
934da51d93aSDavid du Colombier static uchar	incdec[][VLEN] =
935da51d93aSDavid du Colombier {
936da51d93aSDavid du Colombier 	{Vinsx, Bop0, C01, O_l_lo},
937da51d93aSDavid du Colombier 	{Vinsx, Bop1, C00, O_l_hi, Vend},
938da51d93aSDavid du Colombier };
939da51d93aSDavid du Colombier 
940da51d93aSDavid du Colombier /* ++ -- *p */
941da51d93aSDavid du Colombier static uchar	incdecpre[][VLEN] =
942da51d93aSDavid du Colombier {
943da51d93aSDavid du Colombier 	{Vins, AMOVL, O_l_lo, O_t_lo},
944da51d93aSDavid du Colombier 	{Vins, AMOVL, O_l_hi, O_t_hi},
945da51d93aSDavid du Colombier 	{Vinsx, Bop0, C01, O_t_lo},
946da51d93aSDavid du Colombier 	{Vinsx, Bop1, C00, O_t_hi},
947da51d93aSDavid du Colombier 	{Vins, AMOVL, O_t_lo, O_l_lo},
948da51d93aSDavid du Colombier 	{Vins, AMOVL, O_t_hi, O_l_hi, Vend},
949da51d93aSDavid du Colombier };
950da51d93aSDavid du Colombier 
951da51d93aSDavid du Colombier /* *p ++ -- */
952da51d93aSDavid du Colombier static uchar	incdecpost[][VLEN] =
953da51d93aSDavid du Colombier {
954da51d93aSDavid du Colombier 	{Vins, AMOVL, O_l_lo, O_t_lo},
955da51d93aSDavid du Colombier 	{Vins, AMOVL, O_l_hi, O_t_hi},
956da51d93aSDavid du Colombier 	{Vinsx, Bop0, C01, O_l_lo},
957da51d93aSDavid du Colombier 	{Vinsx, Bop1, C00, O_l_hi, Vend},
958da51d93aSDavid du Colombier };
959da51d93aSDavid du Colombier 
960da51d93aSDavid du Colombier /* binop rp, rp */
961da51d93aSDavid du Colombier static uchar	binop00[][VLEN] =
962da51d93aSDavid du Colombier {
963da51d93aSDavid du Colombier 	{Vinsx, Bop0, O_r_lo, O_l_lo},
964da51d93aSDavid du Colombier 	{Vinsx, Bop1, O_r_hi, O_l_hi, Vend},
965da51d93aSDavid du Colombier 	{Vend},
966da51d93aSDavid du Colombier };
967da51d93aSDavid du Colombier 
968da51d93aSDavid du Colombier /* binop rp, addr */
969da51d93aSDavid du Colombier static uchar	binoptmp[][VLEN] =
970da51d93aSDavid du Colombier {
971da51d93aSDavid du Colombier 	{V_a0, Vins, AMOVL, O_r_lo, O_r0},
972da51d93aSDavid du Colombier 	{Vinsx, Bop0, O_r0, O_l_lo},
973da51d93aSDavid du Colombier 	{Vins, AMOVL, O_r_hi, O_r0},
974da51d93aSDavid du Colombier 	{Vinsx, Bop1, O_r0, O_l_hi},
975da51d93aSDavid du Colombier 	{V_f0, Vend},
976da51d93aSDavid du Colombier };
977da51d93aSDavid du Colombier 
978da51d93aSDavid du Colombier /* binop t = *a op *b */
979da51d93aSDavid du Colombier static uchar	binop11[][VLEN] =
980da51d93aSDavid du Colombier {
981da51d93aSDavid du Colombier 	{Vins, AMOVL, O_l_lo, O_t_lo},
982da51d93aSDavid du Colombier 	{Vinsx, Bop0, O_r_lo, O_t_lo},
983da51d93aSDavid du Colombier 	{Vins, AMOVL, O_l_hi, O_t_hi},
984da51d93aSDavid du Colombier 	{Vinsx, Bop1, O_r_hi, O_t_hi, Vend},
985da51d93aSDavid du Colombier };
986da51d93aSDavid du Colombier 
987da51d93aSDavid du Colombier /* binop t = rp +- c */
988da51d93aSDavid du Colombier static uchar	add0c[][VLEN] =
989da51d93aSDavid du Colombier {
990da51d93aSDavid du Colombier 	{V_r_lo_t, Vinsx, Bop0, O_r_lo, O_l_lo},
991da51d93aSDavid du Colombier 	{V_r_lo_f, Vamv, Bop0, Bop1},
992da51d93aSDavid du Colombier 	{Vinsx, Bop1, O_r_hi, O_l_hi},
993da51d93aSDavid du Colombier 	{Vend},
994da51d93aSDavid du Colombier };
995da51d93aSDavid du Colombier 
996da51d93aSDavid du Colombier /* binop t = rp & c */
997da51d93aSDavid du Colombier static uchar	and0c[][VLEN] =
998da51d93aSDavid du Colombier {
999da51d93aSDavid du Colombier 	{V_r_lo_t, Vinsx, Bop0, O_r_lo, O_l_lo},
1000da51d93aSDavid du Colombier 	{V_r_lo_f, Vins, AMOVL, C00, O_l_lo},
1001da51d93aSDavid du Colombier 	{V_r_hi_t, Vinsx, Bop1, O_r_hi, O_l_hi},
1002da51d93aSDavid du Colombier 	{V_r_hi_f, Vins, AMOVL, C00, O_l_hi},
1003da51d93aSDavid du Colombier 	{Vend},
1004da51d93aSDavid du Colombier };
1005da51d93aSDavid du Colombier 
1006da51d93aSDavid du Colombier /* binop t = rp | c */
1007da51d93aSDavid du Colombier static uchar	or0c[][VLEN] =
1008da51d93aSDavid du Colombier {
1009da51d93aSDavid du Colombier 	{V_r_lo_t, Vinsx, Bop0, O_r_lo, O_l_lo},
1010da51d93aSDavid du Colombier 	{V_r_hi_t, Vinsx, Bop1, O_r_hi, O_l_hi},
1011da51d93aSDavid du Colombier 	{Vend},
1012da51d93aSDavid du Colombier };
1013da51d93aSDavid du Colombier 
1014da51d93aSDavid du Colombier /* binop t = c - rp */
1015da51d93aSDavid du Colombier static uchar	sub10[][VLEN] =
1016da51d93aSDavid du Colombier {
1017da51d93aSDavid du Colombier 	{V_a0, Vins, AMOVL, O_l_lo, O_r0},
1018da51d93aSDavid du Colombier 	{Vinsx, Bop0, O_r_lo, O_r0},
1019da51d93aSDavid du Colombier 	{Vins, AMOVL, O_l_hi, O_r_lo},
1020da51d93aSDavid du Colombier 	{Vinsx, Bop1, O_r_hi, O_r_lo},
1021da51d93aSDavid du Colombier 	{Vspazz, V_f0, Vend},
1022da51d93aSDavid du Colombier };
1023da51d93aSDavid du Colombier 
1024da51d93aSDavid du Colombier /* binop t = c + *b */
1025da51d93aSDavid du Colombier static uchar	addca[][VLEN] =
1026da51d93aSDavid du Colombier {
1027da51d93aSDavid du Colombier 	{Vins, AMOVL, O_r_lo, O_t_lo},
1028da51d93aSDavid du Colombier 	{V_l_lo_t, Vinsx, Bop0, O_l_lo, O_t_lo},
1029da51d93aSDavid du Colombier 	{V_l_lo_f, Vamv, Bop0, Bop1},
1030da51d93aSDavid du Colombier 	{Vins, AMOVL, O_r_hi, O_t_hi},
1031da51d93aSDavid du Colombier 	{Vinsx, Bop1, O_l_hi, O_t_hi},
1032da51d93aSDavid du Colombier 	{Vend},
1033da51d93aSDavid du Colombier };
1034da51d93aSDavid du Colombier 
1035da51d93aSDavid du Colombier /* binop t = c & *b */
1036da51d93aSDavid du Colombier static uchar	andca[][VLEN] =
1037da51d93aSDavid du Colombier {
1038da51d93aSDavid du Colombier 	{V_l_lo_t, Vins, AMOVL, O_r_lo, O_t_lo},
1039da51d93aSDavid du Colombier 	{V_l_lo_t, Vinsx, Bop0, O_l_lo, O_t_lo},
1040da51d93aSDavid du Colombier 	{V_l_lo_f, Vzero, O_t_lo},
1041da51d93aSDavid du Colombier 	{V_l_hi_t, Vins, AMOVL, O_r_hi, O_t_hi},
1042da51d93aSDavid du Colombier 	{V_l_hi_t, Vinsx, Bop1, O_l_hi, O_t_hi},
1043da51d93aSDavid du Colombier 	{V_l_hi_f, Vzero, O_t_hi},
1044da51d93aSDavid du Colombier 	{Vend},
1045da51d93aSDavid du Colombier };
1046da51d93aSDavid du Colombier 
1047da51d93aSDavid du Colombier /* binop t = c | *b */
1048da51d93aSDavid du Colombier static uchar	orca[][VLEN] =
1049da51d93aSDavid du Colombier {
1050da51d93aSDavid du Colombier 	{Vins, AMOVL, O_r_lo, O_t_lo},
1051da51d93aSDavid du Colombier 	{V_l_lo_t, Vinsx, Bop0, O_l_lo, O_t_lo},
1052da51d93aSDavid du Colombier 	{Vins, AMOVL, O_r_hi, O_t_hi},
1053da51d93aSDavid du Colombier 	{V_l_hi_t, Vinsx, Bop1, O_l_hi, O_t_hi},
1054da51d93aSDavid du Colombier 	{Vend},
1055da51d93aSDavid du Colombier };
1056da51d93aSDavid du Colombier 
1057da51d93aSDavid du Colombier /* binop t = c - *b */
1058da51d93aSDavid du Colombier static uchar	subca[][VLEN] =
1059da51d93aSDavid du Colombier {
1060da51d93aSDavid du Colombier 	{Vins, AMOVL, O_l_lo, O_t_lo},
1061da51d93aSDavid du Colombier 	{Vins, AMOVL, O_l_hi, O_t_hi},
1062da51d93aSDavid du Colombier 	{Vinsx, Bop0, O_r_lo, O_t_lo},
1063da51d93aSDavid du Colombier 	{Vinsx, Bop1, O_r_hi, O_t_hi},
1064da51d93aSDavid du Colombier 	{Vend},
1065da51d93aSDavid du Colombier };
1066da51d93aSDavid du Colombier 
1067da51d93aSDavid du Colombier /* binop t = *a +- c */
1068da51d93aSDavid du Colombier static uchar	addac[][VLEN] =
1069da51d93aSDavid du Colombier {
1070da51d93aSDavid du Colombier 	{Vins, AMOVL, O_l_lo, O_t_lo},
1071da51d93aSDavid du Colombier 	{V_r_lo_t, Vinsx, Bop0, O_r_lo, O_t_lo},
1072da51d93aSDavid du Colombier 	{V_r_lo_f, Vamv, Bop0, Bop1},
1073da51d93aSDavid du Colombier 	{Vins, AMOVL, O_l_hi, O_t_hi},
1074da51d93aSDavid du Colombier 	{Vinsx, Bop1, O_r_hi, O_t_hi},
1075da51d93aSDavid du Colombier 	{Vend},
1076da51d93aSDavid du Colombier };
1077da51d93aSDavid du Colombier 
1078da51d93aSDavid du Colombier /* binop t = *a | c */
1079da51d93aSDavid du Colombier static uchar	orac[][VLEN] =
1080da51d93aSDavid du Colombier {
1081da51d93aSDavid du Colombier 	{Vins, AMOVL, O_l_lo, O_t_lo},
1082da51d93aSDavid du Colombier 	{V_r_lo_t, Vinsx, Bop0, O_r_lo, O_t_lo},
1083da51d93aSDavid du Colombier 	{Vins, AMOVL, O_l_hi, O_t_hi},
1084da51d93aSDavid du Colombier 	{V_r_hi_t, Vinsx, Bop1, O_r_hi, O_t_hi},
1085da51d93aSDavid du Colombier 	{Vend},
1086da51d93aSDavid du Colombier };
1087da51d93aSDavid du Colombier 
1088da51d93aSDavid du Colombier /* binop t = *a & c */
1089da51d93aSDavid du Colombier static uchar	andac[][VLEN] =
1090da51d93aSDavid du Colombier {
1091da51d93aSDavid du Colombier 	{V_r_lo_t, Vins, AMOVL, O_l_lo, O_t_lo},
1092da51d93aSDavid du Colombier 	{V_r_lo_t, Vinsx, Bop0, O_r_lo, O_t_lo},
1093da51d93aSDavid du Colombier 	{V_r_lo_f, Vzero, O_t_lo},
1094da51d93aSDavid du Colombier 	{V_r_hi_t, Vins, AMOVL, O_l_hi, O_t_hi},
1095da51d93aSDavid du Colombier 	{V_r_hi_t, Vinsx, Bop0, O_r_hi, O_t_hi},
1096da51d93aSDavid du Colombier 	{V_r_hi_f, Vzero, O_t_hi},
1097da51d93aSDavid du Colombier 	{Vend},
1098da51d93aSDavid du Colombier };
1099da51d93aSDavid du Colombier 
1100da51d93aSDavid du Colombier static uchar	ADDargs[]	= { AADDL, AADCL };
1101da51d93aSDavid du Colombier static uchar	ANDargs[]	= { AANDL, AANDL };
1102da51d93aSDavid du Colombier static uchar	ORargs[]	= { AORL, AORL };
1103da51d93aSDavid du Colombier static uchar	SUBargs[]	= { ASUBL, ASBBL };
1104da51d93aSDavid du Colombier static uchar	XORargs[]	= { AXORL, AXORL };
1105da51d93aSDavid du Colombier 
1106da51d93aSDavid du Colombier static uchar	(*ADDtab[])[VLEN] =
1107da51d93aSDavid du Colombier {
1108da51d93aSDavid du Colombier 	add0c, addca, addac,
1109da51d93aSDavid du Colombier };
1110da51d93aSDavid du Colombier 
1111da51d93aSDavid du Colombier static uchar	(*ANDtab[])[VLEN] =
1112da51d93aSDavid du Colombier {
1113da51d93aSDavid du Colombier 	and0c, andca, andac,
1114da51d93aSDavid du Colombier };
1115da51d93aSDavid du Colombier 
1116da51d93aSDavid du Colombier static uchar	(*ORtab[])[VLEN] =
1117da51d93aSDavid du Colombier {
1118da51d93aSDavid du Colombier 	or0c, orca, orac,
1119da51d93aSDavid du Colombier };
1120da51d93aSDavid du Colombier 
1121da51d93aSDavid du Colombier static uchar	(*SUBtab[])[VLEN] =
1122da51d93aSDavid du Colombier {
1123da51d93aSDavid du Colombier 	add0c, subca, addac,
1124da51d93aSDavid du Colombier };
1125da51d93aSDavid du Colombier 
1126375daca8SDavid du Colombier /* mul of const32 */
1127375daca8SDavid du Colombier static uchar	mulc32[][VLEN] =
1128375daca8SDavid du Colombier {
1129375daca8SDavid du Colombier 	{V_a0, Vop, ONE, O_l_hi, C00},
1130375daca8SDavid du Colombier 	{V_s0, Vins, AMOVL, O_r_lo, O_r0},
1131375daca8SDavid du Colombier 	{Vins, AMULL, O_r0, O_Zop},
1132375daca8SDavid du Colombier 	{Vgo, V_p0, V_s0},
1133375daca8SDavid du Colombier 	{Vins, AMOVL, O_l_hi, O_r0},
1134375daca8SDavid du Colombier 	{Vmul, O_r_lo, O_r0},
1135375daca8SDavid du Colombier 	{Vins, AMOVL, O_r_lo, O_l_hi},
1136375daca8SDavid du Colombier 	{Vins, AMULL, O_l_hi, O_Zop},
1137375daca8SDavid du Colombier 	{Vins, AADDL, O_r0, O_l_hi},
1138375daca8SDavid du Colombier 	{V_f0, V_p0, Vend},
1139375daca8SDavid du Colombier };
1140375daca8SDavid du Colombier 
1141375daca8SDavid du Colombier /* mul of const64 */
1142375daca8SDavid du Colombier static uchar	mulc64[][VLEN] =
1143375daca8SDavid du Colombier {
1144375daca8SDavid du Colombier 	{V_a0, Vins, AMOVL, O_r_hi, O_r0},
1145375daca8SDavid du Colombier 	{Vop, OOR, O_l_hi, O_r0},
1146375daca8SDavid du Colombier 	{Vop, ONE, O_r0, C00},
1147375daca8SDavid du Colombier 	{V_s0, Vins, AMOVL, O_r_lo, O_r0},
1148375daca8SDavid du Colombier 	{Vins, AMULL, O_r0, O_Zop},
1149375daca8SDavid du Colombier 	{Vgo, V_p0, V_s0},
1150375daca8SDavid du Colombier 	{Vmul, O_r_lo, O_l_hi},
1151375daca8SDavid du Colombier 	{Vins, AMOVL, O_l_lo, O_r0},
1152375daca8SDavid du Colombier 	{Vmul, O_r_hi, O_r0},
1153375daca8SDavid du Colombier 	{Vins, AADDL, O_l_hi, O_r0},
1154375daca8SDavid du Colombier 	{Vins, AMOVL, O_r_lo, O_l_hi},
1155375daca8SDavid du Colombier 	{Vins, AMULL, O_l_hi, O_Zop},
1156375daca8SDavid du Colombier 	{Vins, AADDL, O_r0, O_l_hi},
1157375daca8SDavid du Colombier 	{V_f0, V_p0, Vend},
1158375daca8SDavid du Colombier };
1159375daca8SDavid du Colombier 
1160375daca8SDavid du Colombier /* mul general */
1161375daca8SDavid du Colombier static uchar	mull[][VLEN] =
1162375daca8SDavid du Colombier {
1163375daca8SDavid du Colombier 	{V_a0, Vins, AMOVL, O_r_hi, O_r0},
1164375daca8SDavid du Colombier 	{Vop, OOR, O_l_hi, O_r0},
1165375daca8SDavid du Colombier 	{Vop, ONE, O_r0, C00},
1166375daca8SDavid du Colombier 	{V_s0, Vins, AMOVL, O_r_lo, O_r0},
1167375daca8SDavid du Colombier 	{Vins, AMULL, O_r0, O_Zop},
1168375daca8SDavid du Colombier 	{Vgo, V_p0, V_s0},
1169375daca8SDavid du Colombier 	{Vins, AIMULL, O_r_lo, O_l_hi},
1170375daca8SDavid du Colombier 	{Vins, AMOVL, O_l_lo, O_r0},
1171375daca8SDavid du Colombier 	{Vins, AIMULL, O_r_hi, O_r0},
1172375daca8SDavid du Colombier 	{Vins, AADDL, O_l_hi, O_r0},
1173375daca8SDavid du Colombier 	{Vins, AMOVL, O_r_lo, O_l_hi},
1174375daca8SDavid du Colombier 	{Vins, AMULL, O_l_hi, O_Zop},
1175375daca8SDavid du Colombier 	{Vins, AADDL, O_r0, O_l_hi},
1176375daca8SDavid du Colombier 	{V_f0, V_p0, Vend},
1177375daca8SDavid du Colombier };
1178375daca8SDavid du Colombier 
1179da51d93aSDavid du Colombier /* cast rp l to rp t */
1180da51d93aSDavid du Colombier static uchar	castrp[][VLEN] =
1181da51d93aSDavid du Colombier {
1182da51d93aSDavid du Colombier 	{Vmv, O_l, O_t_lo},
1183da51d93aSDavid du Colombier 	{VT, Vins, AMOVL, O_t_lo, O_t_hi},
1184da51d93aSDavid du Colombier 	{VT, Vins, ASARL, C31, O_t_hi},
1185da51d93aSDavid du Colombier 	{VF, Vzero, O_t_hi},
1186da51d93aSDavid du Colombier 	{Vend},
1187da51d93aSDavid du Colombier };
1188da51d93aSDavid du Colombier 
1189da51d93aSDavid du Colombier /* cast rp l to addr t */
1190da51d93aSDavid du Colombier static uchar	castrpa[][VLEN] =
1191da51d93aSDavid du Colombier {
1192da51d93aSDavid du Colombier 	{VT, V_a0, Vmv, O_l, O_r0},
1193da51d93aSDavid du Colombier 	{VT, Vins, AMOVL, O_r0, O_t_lo},
1194da51d93aSDavid du Colombier 	{VT, Vins, ASARL, C31, O_r0},
1195da51d93aSDavid du Colombier 	{VT, Vins, AMOVL, O_r0, O_t_hi},
1196da51d93aSDavid du Colombier 	{VT, V_f0},
1197da51d93aSDavid du Colombier 	{VF, Vmv, O_l, O_t_lo},
1198da51d93aSDavid du Colombier 	{VF, Vzero, O_t_hi},
1199da51d93aSDavid du Colombier 	{Vend},
1200da51d93aSDavid du Colombier };
1201da51d93aSDavid du Colombier 
1202da51d93aSDavid du Colombier static uchar	netab0i[][VLEN] =
1203da51d93aSDavid du Colombier {
1204da51d93aSDavid du Colombier 	{Vop, ONE, O_l_lo, O_r_lo},
1205da51d93aSDavid du Colombier 	{V_s0, Vop, ONE, O_l_hi, O_r_hi},
1206da51d93aSDavid du Colombier 	{V_s1, Vgo, V_s2, Vgo, V_s3},
1207da51d93aSDavid du Colombier 	{VF, V_p0, V_p1, VT, V_p2},
1208da51d93aSDavid du Colombier 	{Vgo, V_p3},
1209da51d93aSDavid du Colombier 	{VT, V_p0, V_p1, VF, V_p2},
1210da51d93aSDavid du Colombier 	{Vend},
1211da51d93aSDavid du Colombier };
1212da51d93aSDavid du Colombier 
1213da51d93aSDavid du Colombier static uchar	netabii[][VLEN] =
1214da51d93aSDavid du Colombier {
1215da51d93aSDavid du Colombier 	{V_a0, Vins, AMOVL, O_l_lo, O_r0},
1216da51d93aSDavid du Colombier 	{Vop, ONE, O_r0, O_r_lo},
1217da51d93aSDavid du Colombier 	{V_s0, Vins, AMOVL, O_l_hi, O_r0},
1218da51d93aSDavid du Colombier 	{Vop, ONE, O_r0, O_r_hi},
1219da51d93aSDavid du Colombier 	{V_s1, Vgo, V_s2, Vgo, V_s3},
1220da51d93aSDavid du Colombier 	{VF, V_p0, V_p1, VT, V_p2},
1221da51d93aSDavid du Colombier 	{Vgo, V_p3},
1222da51d93aSDavid du Colombier 	{VT, V_p0, V_p1, VF, V_p2},
1223da51d93aSDavid du Colombier 	{V_f0, Vend},
1224da51d93aSDavid du Colombier };
1225da51d93aSDavid du Colombier 
1226da51d93aSDavid du Colombier static uchar	cmptab0i[][VLEN] =
1227da51d93aSDavid du Colombier {
1228da51d93aSDavid du Colombier 	{Vopx, Bop0, O_l_hi, O_r_hi},
1229da51d93aSDavid du Colombier 	{V_s0, Vins0, AJNE},
1230da51d93aSDavid du Colombier 	{V_s1, Vopx, Bop1, O_l_lo, O_r_lo},
1231da51d93aSDavid du Colombier 	{V_s2, Vgo, V_s3, Vgo, V_s4},
1232da51d93aSDavid du Colombier 	{VT, V_p1, V_p3},
1233da51d93aSDavid du Colombier 	{VF, V_p0, V_p2},
1234da51d93aSDavid du Colombier 	{Vgo, V_p4},
1235da51d93aSDavid du Colombier 	{VT, V_p0, V_p2},
1236da51d93aSDavid du Colombier 	{VF, V_p1, V_p3},
1237da51d93aSDavid du Colombier 	{Vend},
1238da51d93aSDavid du Colombier };
1239da51d93aSDavid du Colombier 
1240da51d93aSDavid du Colombier static uchar	cmptabii[][VLEN] =
1241da51d93aSDavid du Colombier {
1242da51d93aSDavid du Colombier 	{V_a0, Vins, AMOVL, O_l_hi, O_r0},
1243da51d93aSDavid du Colombier 	{Vopx, Bop0, O_r0, O_r_hi},
1244da51d93aSDavid du Colombier 	{V_s0, Vins0, AJNE},
1245da51d93aSDavid du Colombier 	{V_s1, Vins, AMOVL, O_l_lo, O_r0},
1246da51d93aSDavid du Colombier 	{Vopx, Bop1, O_r0, O_r_lo},
1247da51d93aSDavid du Colombier 	{V_s2, Vgo, V_s3, Vgo, V_s4},
1248da51d93aSDavid du Colombier 	{VT, V_p1, V_p3},
1249da51d93aSDavid du Colombier 	{VF, V_p0, V_p2},
1250da51d93aSDavid du Colombier 	{Vgo, V_p4},
1251da51d93aSDavid du Colombier 	{VT, V_p0, V_p2},
1252da51d93aSDavid du Colombier 	{VF, V_p1, V_p3},
1253da51d93aSDavid du Colombier 	{V_f0, Vend},
1254da51d93aSDavid du Colombier };
1255da51d93aSDavid du Colombier 
1256da51d93aSDavid du Colombier static uchar	(*NEtab[])[VLEN] =
1257da51d93aSDavid du Colombier {
1258da51d93aSDavid du Colombier 	netab0i, netabii,
1259da51d93aSDavid du Colombier };
1260da51d93aSDavid du Colombier 
1261da51d93aSDavid du Colombier static uchar	(*cmptab[])[VLEN] =
1262da51d93aSDavid du Colombier {
1263da51d93aSDavid du Colombier 	cmptab0i, cmptabii,
1264da51d93aSDavid du Colombier };
1265da51d93aSDavid du Colombier 
1266da51d93aSDavid du Colombier static uchar	GEargs[]	= { OGT, OHS };
1267da51d93aSDavid du Colombier static uchar	GTargs[]	= { OGT, OHI };
1268da51d93aSDavid du Colombier static uchar	HIargs[]	= { OHI, OHI };
1269da51d93aSDavid du Colombier static uchar	HSargs[]	= { OHI, OHS };
1270da51d93aSDavid du Colombier 
1271da51d93aSDavid du Colombier /* Big Generator */
1272da51d93aSDavid du Colombier static void
1273da51d93aSDavid du Colombier biggen(Node *l, Node *r, Node *t, int true, uchar code[][VLEN], uchar *a)
1274da51d93aSDavid du Colombier {
1275da51d93aSDavid du Colombier 	int i, j, g, oc, op, lo, ro, to, xo, *xp;
1276da51d93aSDavid du Colombier 	Type *lt;
1277da51d93aSDavid du Colombier 	Prog *pr[VOPS];
1278da51d93aSDavid du Colombier 	Node *ot, *tl, *tr, tmps[2];
1279da51d93aSDavid du Colombier 	uchar *c, (*cp)[VLEN], args[VARGS];
1280da51d93aSDavid du Colombier 
1281da51d93aSDavid du Colombier 	if(a != nil)
1282da51d93aSDavid du Colombier 		memmove(args, a, VARGS);
1283da51d93aSDavid du Colombier //print("biggen %d %d %d\n", args[0], args[1], args[2]);
1284da51d93aSDavid du Colombier //if(l) prtree(l, "l");
1285da51d93aSDavid du Colombier //if(r) prtree(r, "r");
1286da51d93aSDavid du Colombier //if(t) prtree(t, "t");
1287da51d93aSDavid du Colombier 	lo = ro = to = 0;
1288da51d93aSDavid du Colombier 	cp = code;
1289da51d93aSDavid du Colombier 
1290da51d93aSDavid du Colombier 	for (;;) {
1291da51d93aSDavid du Colombier 		c = *cp++;
1292da51d93aSDavid du Colombier 		g = 1;
1293da51d93aSDavid du Colombier 		i = 0;
1294da51d93aSDavid du Colombier //print("code %d %d %d %d %d\n", c[0], c[1], c[2], c[3], c[4]);
1295da51d93aSDavid du Colombier 		for(;;) {
1296da51d93aSDavid du Colombier 			switch(op = c[i]) {
1297da51d93aSDavid du Colombier 			case Vgo:
1298da51d93aSDavid du Colombier 				if(g)
1299da51d93aSDavid du Colombier 					gbranch(OGOTO);
1300da51d93aSDavid du Colombier 				i++;
1301da51d93aSDavid du Colombier 				break;
1302da51d93aSDavid du Colombier 
1303da51d93aSDavid du Colombier 			case Vamv:
1304da51d93aSDavid du Colombier 				i += 3;
1305da51d93aSDavid du Colombier 				if(i > VLEN) {
1306da51d93aSDavid du Colombier 					diag(l, "bad Vop");
1307da51d93aSDavid du Colombier 					return;
1308da51d93aSDavid du Colombier 				}
1309da51d93aSDavid du Colombier 				if(g)
1310da51d93aSDavid du Colombier 					args[c[i - 1]] = args[c[i - 2]];
1311da51d93aSDavid du Colombier 				break;
1312da51d93aSDavid du Colombier 
1313da51d93aSDavid du Colombier 			case Vzero:
1314da51d93aSDavid du Colombier 				i += 2;
1315da51d93aSDavid du Colombier 				if(i > VLEN) {
1316da51d93aSDavid du Colombier 					diag(l, "bad Vop");
1317da51d93aSDavid du Colombier 					return;
1318da51d93aSDavid du Colombier 				}
1319da51d93aSDavid du Colombier 				j = i - 1;
1320da51d93aSDavid du Colombier 				goto op;
1321da51d93aSDavid du Colombier 
1322da51d93aSDavid du Colombier 			case Vspazz:	// nasty hack to save a reg in SUB
1323da51d93aSDavid du Colombier //print("spazz\n");
1324da51d93aSDavid du Colombier 				if(g) {
1325da51d93aSDavid du Colombier //print("hi %R lo %R t %R\n", r->right->reg, r->left->reg, tmps[0].reg);
1326da51d93aSDavid du Colombier 					ot = r->right;
1327da51d93aSDavid du Colombier 					r->right = r->left;
1328da51d93aSDavid du Colombier 					tl = new(0, Z, Z);
1329da51d93aSDavid du Colombier 					*tl = tmps[0];
1330da51d93aSDavid du Colombier 					r->left = tl;
1331da51d93aSDavid du Colombier 					tmps[0] = *ot;
1332da51d93aSDavid du Colombier //print("hi %R lo %R t %R\n", r->right->reg, r->left->reg, tmps[0].reg);
1333da51d93aSDavid du Colombier 				}
1334da51d93aSDavid du Colombier 				i++;
1335da51d93aSDavid du Colombier 				break;
1336da51d93aSDavid du Colombier 
1337da51d93aSDavid du Colombier 			case Vmv:
1338375daca8SDavid du Colombier 			case Vmul:
1339375daca8SDavid du Colombier 			case Vshll:
1340da51d93aSDavid du Colombier 				i += 3;
1341da51d93aSDavid du Colombier 				if(i > VLEN) {
1342da51d93aSDavid du Colombier 					diag(l, "bad Vop");
1343da51d93aSDavid du Colombier 					return;
1344da51d93aSDavid du Colombier 				}
1345da51d93aSDavid du Colombier 				j = i - 2;
1346da51d93aSDavid du Colombier 				goto op;
1347da51d93aSDavid du Colombier 
1348da51d93aSDavid du Colombier 			case Vins0:
1349da51d93aSDavid du Colombier 				i += 2;
1350da51d93aSDavid du Colombier 				if(i > VLEN) {
1351da51d93aSDavid du Colombier 					diag(l, "bad Vop");
1352da51d93aSDavid du Colombier 					return;
1353da51d93aSDavid du Colombier 				}
1354da51d93aSDavid du Colombier 				gins(c[i - 1], Z, Z);
1355da51d93aSDavid du Colombier 				break;
1356da51d93aSDavid du Colombier 
1357da51d93aSDavid du Colombier 			case Vop:
1358da51d93aSDavid du Colombier 			case Vopx:
1359da51d93aSDavid du Colombier 			case Vins:
1360da51d93aSDavid du Colombier 			case Vinsl:
1361da51d93aSDavid du Colombier 			case Vinsr:
1362da51d93aSDavid du Colombier 			case Vinsla:
1363da51d93aSDavid du Colombier 			case Vinsra:
1364da51d93aSDavid du Colombier 			case Vinsx:
1365da51d93aSDavid du Colombier 				i += 4;
1366da51d93aSDavid du Colombier 				if(i > VLEN) {
1367da51d93aSDavid du Colombier 					diag(l, "bad Vop");
1368da51d93aSDavid du Colombier 					return;
1369da51d93aSDavid du Colombier 				}
1370da51d93aSDavid du Colombier 				j = i - 2;
1371da51d93aSDavid du Colombier 				goto op;
1372da51d93aSDavid du Colombier 
1373da51d93aSDavid du Colombier 			op:
1374da51d93aSDavid du Colombier 				if(!g)
1375da51d93aSDavid du Colombier 					break;
1376da51d93aSDavid du Colombier 				tl = Z;
1377da51d93aSDavid du Colombier 				tr = Z;
1378da51d93aSDavid du Colombier 				for(; j < i; j++) {
1379da51d93aSDavid du Colombier 					switch(c[j]) {
1380da51d93aSDavid du Colombier 					case C00:
1381da51d93aSDavid du Colombier 						ot = nodconst(0);
1382da51d93aSDavid du Colombier 						break;
1383da51d93aSDavid du Colombier 					case C01:
1384da51d93aSDavid du Colombier 						ot = nodconst(1);
1385da51d93aSDavid du Colombier 						break;
1386da51d93aSDavid du Colombier 					case C31:
1387da51d93aSDavid du Colombier 						ot = nodconst(31);
1388da51d93aSDavid du Colombier 						break;
1389da51d93aSDavid du Colombier 					case C32:
1390da51d93aSDavid du Colombier 						ot = nodconst(32);
1391da51d93aSDavid du Colombier 						break;
1392da51d93aSDavid du Colombier 
1393da51d93aSDavid du Colombier 					case O_l:
1394da51d93aSDavid du Colombier 					case O_l_lo:
1395da51d93aSDavid du Colombier 						ot = l; xp = &lo; xo = 0;
1396da51d93aSDavid du Colombier 						goto op0;
1397da51d93aSDavid du Colombier 					case O_l_hi:
1398da51d93aSDavid du Colombier 						ot = l; xp = &lo; xo = SZ_LONG;
1399da51d93aSDavid du Colombier 						goto op0;
1400da51d93aSDavid du Colombier 					case O_r:
1401da51d93aSDavid du Colombier 					case O_r_lo:
1402da51d93aSDavid du Colombier 						ot = r; xp = &ro; xo = 0;
1403da51d93aSDavid du Colombier 						goto op0;
1404da51d93aSDavid du Colombier 					case O_r_hi:
1405da51d93aSDavid du Colombier 						ot = r; xp = &ro; xo = SZ_LONG;
1406da51d93aSDavid du Colombier 						goto op0;
1407da51d93aSDavid du Colombier 					case O_t_lo:
1408da51d93aSDavid du Colombier 						ot = t; xp = &to; xo = 0;
1409da51d93aSDavid du Colombier 						goto op0;
1410da51d93aSDavid du Colombier 					case O_t_hi:
1411da51d93aSDavid du Colombier 						ot = t; xp = &to; xo = SZ_LONG;
1412da51d93aSDavid du Colombier 						goto op0;
1413da51d93aSDavid du Colombier 					case O_l_rp:
1414da51d93aSDavid du Colombier 						ot = l;
1415da51d93aSDavid du Colombier 						break;
1416da51d93aSDavid du Colombier 					case O_r_rp:
1417da51d93aSDavid du Colombier 						ot = r;
1418da51d93aSDavid du Colombier 						break;
1419da51d93aSDavid du Colombier 					case O_t_rp:
1420da51d93aSDavid du Colombier 						ot = t;
1421da51d93aSDavid du Colombier 						break;
1422da51d93aSDavid du Colombier 					case O_r0:
1423da51d93aSDavid du Colombier 					case O_r1:
1424da51d93aSDavid du Colombier 						ot = &tmps[c[j] - O_r0];
1425da51d93aSDavid du Colombier 						break;
1426375daca8SDavid du Colombier 					case O_Zop:
1427375daca8SDavid du Colombier 						ot = Z;
1428375daca8SDavid du Colombier 						break;
1429da51d93aSDavid du Colombier 
1430da51d93aSDavid du Colombier 					op0:
1431da51d93aSDavid du Colombier 						switch(ot->op) {
1432da51d93aSDavid du Colombier 						case OCONST:
1433da51d93aSDavid du Colombier 							if(xo)
1434da51d93aSDavid du Colombier 								ot = hi64(ot);
1435da51d93aSDavid du Colombier 							else
1436da51d93aSDavid du Colombier 								ot = lo64(ot);
1437da51d93aSDavid du Colombier 							break;
1438da51d93aSDavid du Colombier 						case OREGPAIR:
1439da51d93aSDavid du Colombier 							if(xo)
1440da51d93aSDavid du Colombier 								ot = ot->right;
1441da51d93aSDavid du Colombier 							else
1442da51d93aSDavid du Colombier 								ot = ot->left;
1443da51d93aSDavid du Colombier 							break;
1444da51d93aSDavid du Colombier 						case OREGISTER:
1445da51d93aSDavid du Colombier 							break;
1446da51d93aSDavid du Colombier 						default:
1447da51d93aSDavid du Colombier 							if(xo != *xp) {
1448da51d93aSDavid du Colombier 								ot->xoffset += xo - *xp;
1449da51d93aSDavid du Colombier 								*xp = xo;
1450da51d93aSDavid du Colombier 							}
1451da51d93aSDavid du Colombier 						}
1452da51d93aSDavid du Colombier 						break;
1453da51d93aSDavid du Colombier 
1454da51d93aSDavid du Colombier 					default:
1455da51d93aSDavid du Colombier 						diag(l, "bad V_lop");
1456da51d93aSDavid du Colombier 						return;
1457da51d93aSDavid du Colombier 					}
1458da51d93aSDavid du Colombier 					if(tl == nil)
1459da51d93aSDavid du Colombier 						tl = ot;
1460da51d93aSDavid du Colombier 					else
1461da51d93aSDavid du Colombier 						tr = ot;
1462da51d93aSDavid du Colombier 				}
1463da51d93aSDavid du Colombier 				if(op == Vzero) {
1464da51d93aSDavid du Colombier 					zeroregm(tl);
1465da51d93aSDavid du Colombier 					break;
1466da51d93aSDavid du Colombier 				}
1467da51d93aSDavid du Colombier 				oc = c[i - 3];
1468da51d93aSDavid du Colombier 				if(op == Vinsx || op == Vopx) {
1469da51d93aSDavid du Colombier //print("%d -> %d\n", oc, args[oc]);
1470da51d93aSDavid du Colombier 					oc = args[oc];
1471da51d93aSDavid du Colombier 				}
1472da51d93aSDavid du Colombier 				else {
1473da51d93aSDavid du Colombier 					switch(oc) {
1474da51d93aSDavid du Colombier 					case O_a0:
1475da51d93aSDavid du Colombier 					case O_a1:
1476da51d93aSDavid du Colombier 						oc = args[oc - O_a0];
1477da51d93aSDavid du Colombier 						break;
1478da51d93aSDavid du Colombier 					}
1479da51d93aSDavid du Colombier 				}
1480da51d93aSDavid du Colombier 				switch(op) {
1481375daca8SDavid du Colombier 				case Vmul:
1482375daca8SDavid du Colombier 					mulgen(tr->type, tl, tr);
1483375daca8SDavid du Colombier 					break;
1484da51d93aSDavid du Colombier 				case Vmv:
1485da51d93aSDavid du Colombier 					gmove(tl, tr);
1486da51d93aSDavid du Colombier 					break;
1487375daca8SDavid du Colombier 				case Vshll:
1488375daca8SDavid du Colombier 					shiftit(tr->type, tl, tr);
1489375daca8SDavid du Colombier 					break;
1490da51d93aSDavid du Colombier 				case Vop:
1491da51d93aSDavid du Colombier 				case Vopx:
1492da51d93aSDavid du Colombier 					gopcode(oc, types[TULONG], tl, tr);
1493da51d93aSDavid du Colombier 					break;
1494da51d93aSDavid du Colombier 				case Vins:
1495da51d93aSDavid du Colombier 				case Vinsx:
1496da51d93aSDavid du Colombier 					gins(oc, tl, tr);
1497da51d93aSDavid du Colombier 					break;
1498da51d93aSDavid du Colombier 				case Vinsl:
1499da51d93aSDavid du Colombier 					gins(oc, tl, tr->right);
1500da51d93aSDavid du Colombier 					p->from.index = tr->left->reg;
1501da51d93aSDavid du Colombier 					break;
1502da51d93aSDavid du Colombier 				case Vinsr:
1503da51d93aSDavid du Colombier 					gins(oc, tl, tr->left);
1504da51d93aSDavid du Colombier 					p->from.index = tr->right->reg;
1505da51d93aSDavid du Colombier 					break;
1506da51d93aSDavid du Colombier 				case Vinsla:
1507da51d93aSDavid du Colombier 					gins(oc, tl, tr + 1);
1508da51d93aSDavid du Colombier 					p->from.index = tr->reg;
1509da51d93aSDavid du Colombier 					break;
1510da51d93aSDavid du Colombier 				case Vinsra:
1511da51d93aSDavid du Colombier 					gins(oc, tl, tr);
1512da51d93aSDavid du Colombier 					p->from.index = (tr + 1)->reg;
1513da51d93aSDavid du Colombier 					break;
1514da51d93aSDavid du Colombier 				}
1515da51d93aSDavid du Colombier 				break;
1516da51d93aSDavid du Colombier 
1517da51d93aSDavid du Colombier 			case VT:
1518da51d93aSDavid du Colombier 				g = true;
1519da51d93aSDavid du Colombier 				i++;
1520da51d93aSDavid du Colombier 				break;
1521da51d93aSDavid du Colombier 			case VF:
1522da51d93aSDavid du Colombier 				g = !true;
1523da51d93aSDavid du Colombier 				i++;
1524da51d93aSDavid du Colombier 				break;
1525da51d93aSDavid du Colombier 
1526da51d93aSDavid du Colombier 			case V_T0: case V_T1:
1527da51d93aSDavid du Colombier 				g = args[op - V_T0];
1528da51d93aSDavid du Colombier 				i++;
1529da51d93aSDavid du Colombier 				break;
1530da51d93aSDavid du Colombier 
1531da51d93aSDavid du Colombier 			case V_F0: case V_F1:
1532da51d93aSDavid du Colombier 				g = !args[op - V_F0];
1533da51d93aSDavid du Colombier 				i++;
1534da51d93aSDavid du Colombier 				break;
1535da51d93aSDavid du Colombier 
1536da51d93aSDavid du Colombier 			case V_C0: case V_C1:
1537da51d93aSDavid du Colombier 				if(g)
1538da51d93aSDavid du Colombier 					args[op - V_C0] = 0;
1539da51d93aSDavid du Colombier 				i++;
1540da51d93aSDavid du Colombier 				break;
1541da51d93aSDavid du Colombier 
1542da51d93aSDavid du Colombier 			case V_S0: case V_S1:
1543da51d93aSDavid du Colombier 				if(g)
1544da51d93aSDavid du Colombier 					args[op - V_S0] = 1;
1545da51d93aSDavid du Colombier 				i++;
1546da51d93aSDavid du Colombier 				break;
1547da51d93aSDavid du Colombier 
1548da51d93aSDavid du Colombier 			case V_l_lo_f:
1549da51d93aSDavid du Colombier 				g = lo64v(l) == 0;
1550da51d93aSDavid du Colombier 				i++;
1551da51d93aSDavid du Colombier 				break;
1552da51d93aSDavid du Colombier 			case V_l_hi_f:
1553da51d93aSDavid du Colombier 				g = hi64v(l) == 0;
1554da51d93aSDavid du Colombier 				i++;
1555da51d93aSDavid du Colombier 				break;
1556da51d93aSDavid du Colombier 			case V_l_lo_t:
1557da51d93aSDavid du Colombier 				g = lo64v(l) != 0;
1558da51d93aSDavid du Colombier 				i++;
1559da51d93aSDavid du Colombier 				break;
1560da51d93aSDavid du Colombier 			case V_l_hi_t:
1561da51d93aSDavid du Colombier 				g = hi64v(l) != 0;
1562da51d93aSDavid du Colombier 				i++;
1563da51d93aSDavid du Colombier 				break;
1564da51d93aSDavid du Colombier 			case V_l_lo_u:
1565da51d93aSDavid du Colombier 				g = lo64v(l) >= 0;
1566da51d93aSDavid du Colombier 				i++;
1567da51d93aSDavid du Colombier 				break;
1568da51d93aSDavid du Colombier 			case V_l_hi_u:
1569da51d93aSDavid du Colombier 				g = hi64v(l) >= 0;
1570da51d93aSDavid du Colombier 				i++;
1571da51d93aSDavid du Colombier 				break;
1572da51d93aSDavid du Colombier 			case V_r_lo_f:
1573da51d93aSDavid du Colombier 				g = lo64v(r) == 0;
1574da51d93aSDavid du Colombier 				i++;
1575da51d93aSDavid du Colombier 				break;
1576da51d93aSDavid du Colombier 			case V_r_hi_f:
1577da51d93aSDavid du Colombier 				g = hi64v(r) == 0;
1578da51d93aSDavid du Colombier 				i++;
1579da51d93aSDavid du Colombier 				break;
1580da51d93aSDavid du Colombier 			case V_r_lo_t:
1581da51d93aSDavid du Colombier 				g = lo64v(r) != 0;
1582da51d93aSDavid du Colombier 				i++;
1583da51d93aSDavid du Colombier 				break;
1584da51d93aSDavid du Colombier 			case V_r_hi_t:
1585da51d93aSDavid du Colombier 				g = hi64v(r) != 0;
1586da51d93aSDavid du Colombier 				i++;
1587da51d93aSDavid du Colombier 				break;
1588da51d93aSDavid du Colombier 			case V_r_lo_u:
1589da51d93aSDavid du Colombier 				g = lo64v(r) >= 0;
1590da51d93aSDavid du Colombier 				i++;
1591da51d93aSDavid du Colombier 				break;
1592da51d93aSDavid du Colombier 			case V_r_hi_u:
1593da51d93aSDavid du Colombier 				g = hi64v(r) >= 0;
1594da51d93aSDavid du Colombier 				i++;
1595da51d93aSDavid du Colombier 				break;
1596da51d93aSDavid du Colombier 
1597da51d93aSDavid du Colombier 			case Vend:
1598da51d93aSDavid du Colombier 				goto out;
1599da51d93aSDavid du Colombier 
1600da51d93aSDavid du Colombier 			case V_a0: case V_a1:
1601da51d93aSDavid du Colombier 				if(g) {
1602da51d93aSDavid du Colombier 					lt = l->type;
1603da51d93aSDavid du Colombier 					l->type = types[TULONG];
1604da51d93aSDavid du Colombier 					regalloc(&tmps[op - V_a0], l, Z);
1605da51d93aSDavid du Colombier 					l->type = lt;
1606da51d93aSDavid du Colombier 				}
1607da51d93aSDavid du Colombier 				i++;
1608da51d93aSDavid du Colombier 				break;
1609da51d93aSDavid du Colombier 
1610da51d93aSDavid du Colombier 			case V_f0: case V_f1:
1611da51d93aSDavid du Colombier 				if(g)
1612da51d93aSDavid du Colombier 					regfree(&tmps[op - V_f0]);
1613da51d93aSDavid du Colombier 				i++;
1614da51d93aSDavid du Colombier 				break;
1615da51d93aSDavid du Colombier 
1616da51d93aSDavid du Colombier 			case V_p0: case V_p1: case V_p2: case V_p3: case V_p4:
1617da51d93aSDavid du Colombier 				if(g)
1618da51d93aSDavid du Colombier 					patch(pr[op - V_p0], pc);
1619da51d93aSDavid du Colombier 				i++;
1620da51d93aSDavid du Colombier 				break;
1621da51d93aSDavid du Colombier 
1622da51d93aSDavid du Colombier 			case V_s0: case V_s1: case V_s2: case V_s3: case V_s4:
1623da51d93aSDavid du Colombier 				if(g)
1624da51d93aSDavid du Colombier 					pr[op - V_s0] = p;
1625da51d93aSDavid du Colombier 				i++;
1626da51d93aSDavid du Colombier 				break;
1627da51d93aSDavid du Colombier 
1628da51d93aSDavid du Colombier 			default:
1629da51d93aSDavid du Colombier 				diag(l, "bad biggen: %d", op);
1630da51d93aSDavid du Colombier 				return;
1631da51d93aSDavid du Colombier 			}
1632da51d93aSDavid du Colombier 			if(i == VLEN || c[i] == 0)
1633da51d93aSDavid du Colombier 				break;
1634da51d93aSDavid du Colombier 		}
1635da51d93aSDavid du Colombier 	}
1636da51d93aSDavid du Colombier out:
1637da51d93aSDavid du Colombier 	if(lo)
1638da51d93aSDavid du Colombier 		l->xoffset -= lo;
1639da51d93aSDavid du Colombier 	if(ro)
1640da51d93aSDavid du Colombier 		r->xoffset -= ro;
1641da51d93aSDavid du Colombier 	if(to)
1642da51d93aSDavid du Colombier 		t->xoffset -= to;
1643da51d93aSDavid du Colombier }
1644da51d93aSDavid du Colombier 
1645da51d93aSDavid du Colombier int
1646da51d93aSDavid du Colombier cgen64(Node *n, Node *nn)
1647da51d93aSDavid du Colombier {
1648da51d93aSDavid du Colombier 	Type *dt;
1649da51d93aSDavid du Colombier 	uchar *args, (*cp)[VLEN], (**optab)[VLEN];
1650da51d93aSDavid du Colombier 	int li, ri, lri, dr, si, m, op, sh, cmp, true;
1651375daca8SDavid du Colombier 	Node *c, *d, *l, *r, *t, *s, nod1, nod2, nod3, nod4, nod5;
1652da51d93aSDavid du Colombier 
1653da51d93aSDavid du Colombier 	if(debug['g']) {
1654da51d93aSDavid du Colombier 		prtree(nn, "cgen64 lhs");
1655da51d93aSDavid du Colombier 		prtree(n, "cgen64");
1656375daca8SDavid du Colombier 		print("AX = %d\n", reg[D_AX]);
1657da51d93aSDavid du Colombier 	}
1658da51d93aSDavid du Colombier 	cmp = 0;
1659da51d93aSDavid du Colombier 	sh = 0;
1660da51d93aSDavid du Colombier 
1661da51d93aSDavid du Colombier 	switch(n->op) {
1662da51d93aSDavid du Colombier 	case ONEG:
1663da51d93aSDavid du Colombier 		d = regpair(nn, n);
1664da51d93aSDavid du Colombier 		sugen(n->left, d, 8);
1665da51d93aSDavid du Colombier 		gins(ANOTL, Z, d->right);
1666da51d93aSDavid du Colombier 		gins(ANEGL, Z, d->left);
1667da51d93aSDavid du Colombier 		gins(ASBBL, nodconst(-1), d->right);
1668da51d93aSDavid du Colombier 		break;
1669da51d93aSDavid du Colombier 
1670da51d93aSDavid du Colombier 	case OCOM:
1671375daca8SDavid du Colombier 		if(!vaddr(n->left, 0) || !vaddr(nn, 0))
1672da51d93aSDavid du Colombier 			d = regpair(nn, n);
1673da51d93aSDavid du Colombier 		else
1674da51d93aSDavid du Colombier 			return 0;
1675da51d93aSDavid du Colombier 		sugen(n->left, d, 8);
1676da51d93aSDavid du Colombier 		gins(ANOTL, Z, d->left);
1677da51d93aSDavid du Colombier 		gins(ANOTL, Z, d->right);
1678da51d93aSDavid du Colombier 		break;
1679da51d93aSDavid du Colombier 
1680da51d93aSDavid du Colombier 	case OADD:
1681da51d93aSDavid du Colombier 		optab = ADDtab;
1682da51d93aSDavid du Colombier 		args = ADDargs;
1683da51d93aSDavid du Colombier 		goto twoop;
1684da51d93aSDavid du Colombier 	case OAND:
1685da51d93aSDavid du Colombier 		optab = ANDtab;
1686da51d93aSDavid du Colombier 		args = ANDargs;
1687da51d93aSDavid du Colombier 		goto twoop;
1688da51d93aSDavid du Colombier 	case OOR:
1689da51d93aSDavid du Colombier 		optab = ORtab;
1690da51d93aSDavid du Colombier 		args = ORargs;
1691da51d93aSDavid du Colombier 		goto twoop;
1692da51d93aSDavid du Colombier 	case OSUB:
1693da51d93aSDavid du Colombier 		optab = SUBtab;
1694da51d93aSDavid du Colombier 		args = SUBargs;
1695da51d93aSDavid du Colombier 		goto twoop;
1696da51d93aSDavid du Colombier 	case OXOR:
1697da51d93aSDavid du Colombier 		optab = ORtab;
1698da51d93aSDavid du Colombier 		args = XORargs;
1699da51d93aSDavid du Colombier 		goto twoop;
1700da51d93aSDavid du Colombier 	case OASHL:
1701da51d93aSDavid du Colombier 		sh = 1;
1702da51d93aSDavid du Colombier 		args = nil;
1703da51d93aSDavid du Colombier 		optab = shlltab;
1704da51d93aSDavid du Colombier 		goto twoop;
1705da51d93aSDavid du Colombier 	case OLSHR:
1706da51d93aSDavid du Colombier 		sh = 1;
1707da51d93aSDavid du Colombier 		args = shrlargs;
1708da51d93aSDavid du Colombier 		optab = shrltab;
1709da51d93aSDavid du Colombier 		goto twoop;
1710da51d93aSDavid du Colombier 	case OASHR:
1711da51d93aSDavid du Colombier 		sh = 1;
1712da51d93aSDavid du Colombier 		args = sarlargs;
1713da51d93aSDavid du Colombier 		optab = shrltab;
1714da51d93aSDavid du Colombier 		goto twoop;
1715da51d93aSDavid du Colombier 	case OEQ:
1716da51d93aSDavid du Colombier 		cmp = 1;
1717da51d93aSDavid du Colombier 		args = nil;
1718da51d93aSDavid du Colombier 		optab = nil;
1719da51d93aSDavid du Colombier 		goto twoop;
1720da51d93aSDavid du Colombier 	case ONE:
1721da51d93aSDavid du Colombier 		cmp = 1;
1722da51d93aSDavid du Colombier 		args = nil;
1723da51d93aSDavid du Colombier 		optab = nil;
1724da51d93aSDavid du Colombier 		goto twoop;
1725da51d93aSDavid du Colombier 	case OLE:
1726da51d93aSDavid du Colombier 		cmp = 1;
1727da51d93aSDavid du Colombier 		args = nil;
1728da51d93aSDavid du Colombier 		optab = nil;
1729da51d93aSDavid du Colombier 		goto twoop;
1730da51d93aSDavid du Colombier 	case OLT:
1731da51d93aSDavid du Colombier 		cmp = 1;
1732da51d93aSDavid du Colombier 		args = nil;
1733da51d93aSDavid du Colombier 		optab = nil;
1734da51d93aSDavid du Colombier 		goto twoop;
1735da51d93aSDavid du Colombier 	case OGE:
1736da51d93aSDavid du Colombier 		cmp = 1;
1737da51d93aSDavid du Colombier 		args = nil;
1738da51d93aSDavid du Colombier 		optab = nil;
1739da51d93aSDavid du Colombier 		goto twoop;
1740da51d93aSDavid du Colombier 	case OGT:
1741da51d93aSDavid du Colombier 		cmp = 1;
1742da51d93aSDavid du Colombier 		args = nil;
1743da51d93aSDavid du Colombier 		optab = nil;
1744da51d93aSDavid du Colombier 		goto twoop;
1745da51d93aSDavid du Colombier 	case OHI:
1746da51d93aSDavid du Colombier 		cmp = 1;
1747da51d93aSDavid du Colombier 		args = nil;
1748da51d93aSDavid du Colombier 		optab = nil;
1749da51d93aSDavid du Colombier 		goto twoop;
1750da51d93aSDavid du Colombier 	case OHS:
1751da51d93aSDavid du Colombier 		cmp = 1;
1752da51d93aSDavid du Colombier 		args = nil;
1753da51d93aSDavid du Colombier 		optab = nil;
1754da51d93aSDavid du Colombier 		goto twoop;
1755da51d93aSDavid du Colombier 	case OLO:
1756da51d93aSDavid du Colombier 		cmp = 1;
1757da51d93aSDavid du Colombier 		args = nil;
1758da51d93aSDavid du Colombier 		optab = nil;
1759da51d93aSDavid du Colombier 		goto twoop;
1760da51d93aSDavid du Colombier 	case OLS:
1761da51d93aSDavid du Colombier 		cmp = 1;
1762da51d93aSDavid du Colombier 		args = nil;
1763da51d93aSDavid du Colombier 		optab = nil;
1764da51d93aSDavid du Colombier 		goto twoop;
1765da51d93aSDavid du Colombier 
1766da51d93aSDavid du Colombier twoop:
1767da51d93aSDavid du Colombier 		dr = nn != Z && nn->op == OREGPAIR;
1768da51d93aSDavid du Colombier 		l = vfunc(n->left, nn);
1769da51d93aSDavid du Colombier 		if(sh)
1770da51d93aSDavid du Colombier 			r = n->right;
1771da51d93aSDavid du Colombier 		else
1772da51d93aSDavid du Colombier 			r = vfunc(n->right, nn);
1773375daca8SDavid du Colombier 
1774da51d93aSDavid du Colombier 		li = l->op == ONAME || l->op == OINDREG || l->op == OCONST;
1775da51d93aSDavid du Colombier 		ri = r->op == ONAME || r->op == OINDREG || r->op == OCONST;
1776da51d93aSDavid du Colombier 
1777da51d93aSDavid du Colombier #define	IMM(l, r)	((l) | ((r) << 1))
1778da51d93aSDavid du Colombier 
1779da51d93aSDavid du Colombier 		lri = IMM(li, ri);
1780da51d93aSDavid du Colombier 
1781da51d93aSDavid du Colombier 		/* find out what is so easy about some operands */
1782da51d93aSDavid du Colombier 		if(li)
1783da51d93aSDavid du Colombier 			li = whatof(l, sh | cmp);
1784da51d93aSDavid du Colombier 		if(ri)
1785da51d93aSDavid du Colombier 			ri = whatof(r, cmp);
1786da51d93aSDavid du Colombier 
1787da51d93aSDavid du Colombier 		if(sh)
1788da51d93aSDavid du Colombier 			goto shift;
1789da51d93aSDavid du Colombier 
1790da51d93aSDavid du Colombier 		if(cmp)
1791da51d93aSDavid du Colombier 			goto cmp;
1792da51d93aSDavid du Colombier 
1793da51d93aSDavid du Colombier 		/* evaluate hard subexps, stealing nn if possible. */
1794da51d93aSDavid du Colombier 		switch(lri) {
1795da51d93aSDavid du Colombier 		case IMM(0, 0):
1796da51d93aSDavid du Colombier 		bin00:
1797da51d93aSDavid du Colombier 			if(l->complex > r->complex) {
1798da51d93aSDavid du Colombier 				if(dr)
1799da51d93aSDavid du Colombier 					t = nn;
1800da51d93aSDavid du Colombier 				else
1801da51d93aSDavid du Colombier 					t = regpair(Z, n);
1802da51d93aSDavid du Colombier 				sugen(l, t, 8);
1803da51d93aSDavid du Colombier 				l = t;
1804da51d93aSDavid du Colombier 				t = regpair(Z, n);
1805da51d93aSDavid du Colombier 				sugen(r, t, 8);
1806da51d93aSDavid du Colombier 				r = t;
1807da51d93aSDavid du Colombier 			}
1808da51d93aSDavid du Colombier 			else {
1809da51d93aSDavid du Colombier 				t = regpair(Z, n);
1810da51d93aSDavid du Colombier 				sugen(r, t, 8);
1811da51d93aSDavid du Colombier 				r = t;
1812da51d93aSDavid du Colombier 				if(dr)
1813da51d93aSDavid du Colombier 					t = nn;
1814da51d93aSDavid du Colombier 				else
1815da51d93aSDavid du Colombier 					t = regpair(Z, n);
1816da51d93aSDavid du Colombier 				sugen(l, t, 8);
1817da51d93aSDavid du Colombier 				l = t;
1818da51d93aSDavid du Colombier 			}
1819da51d93aSDavid du Colombier 			break;
1820da51d93aSDavid du Colombier 		case IMM(0, 1):
1821da51d93aSDavid du Colombier 			if(dr)
1822da51d93aSDavid du Colombier 				t = nn;
1823da51d93aSDavid du Colombier 			else
1824da51d93aSDavid du Colombier 				t = regpair(Z, n);
1825da51d93aSDavid du Colombier 			sugen(l, t, 8);
1826da51d93aSDavid du Colombier 			l = t;
1827da51d93aSDavid du Colombier 			break;
1828da51d93aSDavid du Colombier 		case IMM(1, 0):
1829da51d93aSDavid du Colombier 			if(n->op == OSUB && l->op == OCONST && hi64v(l) == 0) {
1830da51d93aSDavid du Colombier 				lri = IMM(0, 0);
1831da51d93aSDavid du Colombier 				goto bin00;
1832da51d93aSDavid du Colombier 			}
1833da51d93aSDavid du Colombier 			if(dr)
1834da51d93aSDavid du Colombier 				t = nn;
1835da51d93aSDavid du Colombier 			else
1836da51d93aSDavid du Colombier 				t = regpair(Z, n);
1837da51d93aSDavid du Colombier 			sugen(r, t, 8);
1838da51d93aSDavid du Colombier 			r = t;
1839da51d93aSDavid du Colombier 			break;
1840da51d93aSDavid du Colombier 		case IMM(1, 1):
1841da51d93aSDavid du Colombier 			break;
1842da51d93aSDavid du Colombier 		}
1843da51d93aSDavid du Colombier 
1844da51d93aSDavid du Colombier #define	WW(l, r)	((l) | ((r) << 2))
1845da51d93aSDavid du Colombier 		d = Z;
1846da51d93aSDavid du Colombier 		dt = nn->type;
1847da51d93aSDavid du Colombier 		nn->type = types[TLONG];
1848da51d93aSDavid du Colombier 
1849da51d93aSDavid du Colombier 		switch(lri) {
1850da51d93aSDavid du Colombier 		case IMM(0, 0):
1851da51d93aSDavid du Colombier 			biggen(l, r, Z, 0, binop00, args);
1852da51d93aSDavid du Colombier 			break;
1853da51d93aSDavid du Colombier 		case IMM(0, 1):
1854da51d93aSDavid du Colombier 			switch(ri) {
1855da51d93aSDavid du Colombier 			case WNONE:
1856da51d93aSDavid du Colombier 				diag(r, "bad whatof\n");
1857da51d93aSDavid du Colombier 				break;
1858da51d93aSDavid du Colombier 			case WCONST:
1859da51d93aSDavid du Colombier 				biggen(l, r, Z, 0, optab[B0c], args);
1860da51d93aSDavid du Colombier 				break;
1861da51d93aSDavid du Colombier 			case WHARD:
1862da51d93aSDavid du Colombier 				reglcgen(&nod2, r, Z);
1863da51d93aSDavid du Colombier 				r = &nod2;
1864da51d93aSDavid du Colombier 				/* fall thru */
1865da51d93aSDavid du Colombier 			case WADDR:
1866da51d93aSDavid du Colombier 				biggen(l, r, Z, 0, binoptmp, args);
1867da51d93aSDavid du Colombier 				if(ri == WHARD)
1868da51d93aSDavid du Colombier 					regfree(r);
1869da51d93aSDavid du Colombier 				break;
1870da51d93aSDavid du Colombier 			}
1871da51d93aSDavid du Colombier 			break;
1872da51d93aSDavid du Colombier 		case IMM(1, 0):
1873da51d93aSDavid du Colombier 			if(n->op == OSUB) {
1874da51d93aSDavid du Colombier 				switch(li) {
1875da51d93aSDavid du Colombier 				case WNONE:
1876da51d93aSDavid du Colombier 					diag(l, "bad whatof\n");
1877da51d93aSDavid du Colombier 					break;
1878da51d93aSDavid du Colombier 				case WHARD:
1879da51d93aSDavid du Colombier 					reglcgen(&nod2, l, Z);
1880da51d93aSDavid du Colombier 					l = &nod2;
1881da51d93aSDavid du Colombier 					/* fall thru */
1882da51d93aSDavid du Colombier 				case WADDR:
1883da51d93aSDavid du Colombier 				case WCONST:
1884da51d93aSDavid du Colombier 					biggen(l, r, Z, 0, sub10, args);
1885da51d93aSDavid du Colombier 					break;
1886da51d93aSDavid du Colombier 				}
1887da51d93aSDavid du Colombier 				if(li == WHARD)
1888da51d93aSDavid du Colombier 					regfree(l);
1889da51d93aSDavid du Colombier 			}
1890da51d93aSDavid du Colombier 			else {
1891da51d93aSDavid du Colombier 				switch(li) {
1892da51d93aSDavid du Colombier 				case WNONE:
1893da51d93aSDavid du Colombier 					diag(l, "bad whatof\n");
1894da51d93aSDavid du Colombier 					break;
1895da51d93aSDavid du Colombier 				case WCONST:
1896da51d93aSDavid du Colombier 					biggen(r, l, Z, 0, optab[B0c], args);
1897da51d93aSDavid du Colombier 					break;
1898da51d93aSDavid du Colombier 				case WHARD:
1899da51d93aSDavid du Colombier 					reglcgen(&nod2, l, Z);
1900da51d93aSDavid du Colombier 					l = &nod2;
1901da51d93aSDavid du Colombier 					/* fall thru */
1902da51d93aSDavid du Colombier 				case WADDR:
1903da51d93aSDavid du Colombier 					biggen(r, l, Z, 0, binoptmp, args);
1904da51d93aSDavid du Colombier 					if(li == WHARD)
1905da51d93aSDavid du Colombier 						regfree(l);
1906da51d93aSDavid du Colombier 					break;
1907da51d93aSDavid du Colombier 				}
1908da51d93aSDavid du Colombier 			}
1909da51d93aSDavid du Colombier 			break;
1910da51d93aSDavid du Colombier 		case IMM(1, 1):
1911da51d93aSDavid du Colombier 			switch(WW(li, ri)) {
1912da51d93aSDavid du Colombier 			case WW(WCONST, WHARD):
1913da51d93aSDavid du Colombier 				if(r->op == ONAME && n->op == OAND && reduxv(l))
1914da51d93aSDavid du Colombier 					ri = WADDR;
1915da51d93aSDavid du Colombier 				break;
1916da51d93aSDavid du Colombier 			case WW(WHARD, WCONST):
1917da51d93aSDavid du Colombier 				if(l->op == ONAME && n->op == OAND && reduxv(r))
1918da51d93aSDavid du Colombier 					li = WADDR;
1919da51d93aSDavid du Colombier 				break;
1920da51d93aSDavid du Colombier 			}
1921da51d93aSDavid du Colombier 			if(li == WHARD) {
1922da51d93aSDavid du Colombier 				reglcgen(&nod3, l, Z);
1923da51d93aSDavid du Colombier 				l = &nod3;
1924da51d93aSDavid du Colombier 			}
1925da51d93aSDavid du Colombier 			if(ri == WHARD) {
1926da51d93aSDavid du Colombier 				reglcgen(&nod2, r, Z);
1927da51d93aSDavid du Colombier 				r = &nod2;
1928da51d93aSDavid du Colombier 			}
1929da51d93aSDavid du Colombier 			d = regpair(nn, n);
1930375daca8SDavid du Colombier 			instpair(d, Z);
1931da51d93aSDavid du Colombier 			switch(WW(li, ri)) {
1932da51d93aSDavid du Colombier 			case WW(WCONST, WADDR):
1933da51d93aSDavid du Colombier 			case WW(WCONST, WHARD):
1934da51d93aSDavid du Colombier 				biggen(l, r, d, 0, optab[Bca], args);
1935da51d93aSDavid du Colombier 				break;
1936da51d93aSDavid du Colombier 
1937da51d93aSDavid du Colombier 			case WW(WADDR, WCONST):
1938da51d93aSDavid du Colombier 			case WW(WHARD, WCONST):
1939da51d93aSDavid du Colombier 				biggen(l, r, d, 0, optab[Bac], args);
1940da51d93aSDavid du Colombier 				break;
1941da51d93aSDavid du Colombier 
1942da51d93aSDavid du Colombier 			case WW(WADDR, WADDR):
1943da51d93aSDavid du Colombier 			case WW(WADDR, WHARD):
1944da51d93aSDavid du Colombier 			case WW(WHARD, WADDR):
1945da51d93aSDavid du Colombier 			case WW(WHARD, WHARD):
1946da51d93aSDavid du Colombier 				biggen(l, r, d, 0, binop11, args);
1947da51d93aSDavid du Colombier 				break;
1948da51d93aSDavid du Colombier 
1949da51d93aSDavid du Colombier 			default:
1950da51d93aSDavid du Colombier 				diag(r, "bad whatof pair %d %d\n", li, ri);
1951da51d93aSDavid du Colombier 				break;
1952da51d93aSDavid du Colombier 			}
1953da51d93aSDavid du Colombier 			if(li == WHARD)
1954da51d93aSDavid du Colombier 				regfree(l);
1955da51d93aSDavid du Colombier 			if(ri == WHARD)
1956da51d93aSDavid du Colombier 				regfree(r);
1957da51d93aSDavid du Colombier 			break;
1958da51d93aSDavid du Colombier 		}
1959da51d93aSDavid du Colombier 
1960da51d93aSDavid du Colombier 		nn->type = dt;
1961da51d93aSDavid du Colombier 
1962da51d93aSDavid du Colombier 		if(d != Z)
1963da51d93aSDavid du Colombier 			goto finished;
1964da51d93aSDavid du Colombier 
1965da51d93aSDavid du Colombier 		switch(lri) {
1966da51d93aSDavid du Colombier 		case IMM(0, 0):
1967da51d93aSDavid du Colombier 			freepair(r);
1968da51d93aSDavid du Colombier 			/* fall thru */;
1969da51d93aSDavid du Colombier 		case IMM(0, 1):
1970da51d93aSDavid du Colombier 			if(!dr)
1971da51d93aSDavid du Colombier 				storepair(l, nn, 1);
1972da51d93aSDavid du Colombier 			break;
1973da51d93aSDavid du Colombier 		case IMM(1, 0):
1974da51d93aSDavid du Colombier 			if(!dr)
1975da51d93aSDavid du Colombier 				storepair(r, nn, 1);
1976da51d93aSDavid du Colombier 			break;
1977da51d93aSDavid du Colombier 		case IMM(1, 1):
1978da51d93aSDavid du Colombier 			break;
1979da51d93aSDavid du Colombier 		}
1980da51d93aSDavid du Colombier 		return 1;
1981da51d93aSDavid du Colombier 
1982da51d93aSDavid du Colombier 	shift:
1983da51d93aSDavid du Colombier 		c = Z;
1984da51d93aSDavid du Colombier 
1985da51d93aSDavid du Colombier 		/* evaluate hard subexps, stealing nn if possible. */
1986da51d93aSDavid du Colombier 		/* must also secure CX.  not as many optims as binop. */
1987da51d93aSDavid du Colombier 		switch(lri) {
1988da51d93aSDavid du Colombier 		case IMM(0, 0):
1989da51d93aSDavid du Colombier 		imm00:
1990da51d93aSDavid du Colombier 			if(l->complex + 1 > r->complex) {
1991da51d93aSDavid du Colombier 				if(dr)
1992da51d93aSDavid du Colombier 					t = nn;
1993da51d93aSDavid du Colombier 				else
1994da51d93aSDavid du Colombier 					t = regpair(Z, l);
1995da51d93aSDavid du Colombier 				sugen(l, t, 8);
1996da51d93aSDavid du Colombier 				l = t;
1997da51d93aSDavid du Colombier 				t = &nod1;
1998375daca8SDavid du Colombier 				c = snarfreg(l, t, D_CX, r, &nod2);
1999da51d93aSDavid du Colombier 				cgen(r, t);
2000da51d93aSDavid du Colombier 				r = t;
2001da51d93aSDavid du Colombier 			}
2002da51d93aSDavid du Colombier 			else {
2003da51d93aSDavid du Colombier 				t = &nod1;
2004375daca8SDavid du Colombier 				c = snarfreg(nn, t, D_CX, r, &nod2);
2005da51d93aSDavid du Colombier 				cgen(r, t);
2006da51d93aSDavid du Colombier 				r = t;
2007da51d93aSDavid du Colombier 				if(dr)
2008da51d93aSDavid du Colombier 					t = nn;
2009da51d93aSDavid du Colombier 				else
2010da51d93aSDavid du Colombier 					t = regpair(Z, l);
2011da51d93aSDavid du Colombier 				sugen(l, t, 8);
2012da51d93aSDavid du Colombier 				l = t;
2013da51d93aSDavid du Colombier 			}
2014da51d93aSDavid du Colombier 			break;
2015da51d93aSDavid du Colombier 		case IMM(0, 1):
2016da51d93aSDavid du Colombier 		imm01:
2017da51d93aSDavid du Colombier 			if(ri != WCONST) {
2018da51d93aSDavid du Colombier 				lri = IMM(0, 0);
2019da51d93aSDavid du Colombier 				goto imm00;
2020da51d93aSDavid du Colombier 			}
2021da51d93aSDavid du Colombier 			if(dr)
2022da51d93aSDavid du Colombier 				t = nn;
2023da51d93aSDavid du Colombier 			else
2024da51d93aSDavid du Colombier 				t = regpair(Z, n);
2025da51d93aSDavid du Colombier 			sugen(l, t, 8);
2026da51d93aSDavid du Colombier 			l = t;
2027da51d93aSDavid du Colombier 			break;
2028da51d93aSDavid du Colombier 		case IMM(1, 0):
2029da51d93aSDavid du Colombier 		imm10:
2030da51d93aSDavid du Colombier 			if(li != WCONST) {
2031da51d93aSDavid du Colombier 				lri = IMM(0, 0);
2032da51d93aSDavid du Colombier 				goto imm00;
2033da51d93aSDavid du Colombier 			}
2034da51d93aSDavid du Colombier 			t = &nod1;
2035375daca8SDavid du Colombier 			c = snarfreg(nn, t, D_CX, r, &nod2);
2036da51d93aSDavid du Colombier 			cgen(r, t);
2037da51d93aSDavid du Colombier 			r = t;
2038da51d93aSDavid du Colombier 			break;
2039da51d93aSDavid du Colombier 		case IMM(1, 1):
2040da51d93aSDavid du Colombier 			if(ri != WCONST) {
2041da51d93aSDavid du Colombier 				lri = IMM(1, 0);
2042da51d93aSDavid du Colombier 				goto imm10;
2043da51d93aSDavid du Colombier 			}
2044da51d93aSDavid du Colombier 			if(li == WHARD) {
2045da51d93aSDavid du Colombier 				lri = IMM(0, 1);
2046da51d93aSDavid du Colombier 				goto imm01;
2047da51d93aSDavid du Colombier 			}
2048da51d93aSDavid du Colombier 			break;
2049da51d93aSDavid du Colombier 		}
2050da51d93aSDavid du Colombier 
2051da51d93aSDavid du Colombier 		d = Z;
2052da51d93aSDavid du Colombier 
2053da51d93aSDavid du Colombier 		switch(lri) {
2054da51d93aSDavid du Colombier 		case IMM(0, 0):
2055da51d93aSDavid du Colombier 			biggen(l, r, Z, 0, optab[S00], args);
2056da51d93aSDavid du Colombier 			break;
2057da51d93aSDavid du Colombier 		case IMM(0, 1):
2058da51d93aSDavid du Colombier 			switch(ri) {
2059da51d93aSDavid du Colombier 			case WNONE:
2060da51d93aSDavid du Colombier 			case WADDR:
2061da51d93aSDavid du Colombier 			case WHARD:
2062da51d93aSDavid du Colombier 				diag(r, "bad whatof\n");
2063da51d93aSDavid du Colombier 				break;
2064da51d93aSDavid du Colombier 			case WCONST:
2065da51d93aSDavid du Colombier 				m = r->vconst & 63;
2066da51d93aSDavid du Colombier 				s = nodconst(m);
2067da51d93aSDavid du Colombier 				if(m < 32)
2068da51d93aSDavid du Colombier 					cp = optab[Sc0];
2069da51d93aSDavid du Colombier 				else if(m == 32)
2070da51d93aSDavid du Colombier 					cp = optab[Sc1];
2071da51d93aSDavid du Colombier 				else
2072da51d93aSDavid du Colombier 					cp = optab[Sc2];
2073da51d93aSDavid du Colombier 				biggen(l, s, Z, 0, cp, args);
2074da51d93aSDavid du Colombier 				break;
2075da51d93aSDavid du Colombier 			}
2076da51d93aSDavid du Colombier 			break;
2077da51d93aSDavid du Colombier 		case IMM(1, 0):
2078da51d93aSDavid du Colombier 			/* left is const */
2079da51d93aSDavid du Colombier 			d = regpair(nn, n);
2080375daca8SDavid du Colombier 			instpair(d, Z);
2081da51d93aSDavid du Colombier 			biggen(l, r, d, 0, optab[S10], args);
2082da51d93aSDavid du Colombier 			regfree(r);
2083da51d93aSDavid du Colombier 			break;
2084da51d93aSDavid du Colombier 		case IMM(1, 1):
2085da51d93aSDavid du Colombier 			d = regpair(nn, n);
2086375daca8SDavid du Colombier 			instpair(d, Z);
2087da51d93aSDavid du Colombier 			switch(WW(li, ri)) {
2088da51d93aSDavid du Colombier 			case WW(WADDR, WCONST):
2089da51d93aSDavid du Colombier 				m = r->vconst & 63;
2090da51d93aSDavid du Colombier 				s = nodconst(m);
2091da51d93aSDavid du Colombier 				if(m < 32) {
2092da51d93aSDavid du Colombier 					loadpair(l, d);
2093da51d93aSDavid du Colombier 					l = d;
2094da51d93aSDavid du Colombier 					cp = optab[Sc0];
2095da51d93aSDavid du Colombier 				}
2096da51d93aSDavid du Colombier 				else if(m == 32)
2097da51d93aSDavid du Colombier 					cp = optab[Sac3];
2098da51d93aSDavid du Colombier 				else
2099da51d93aSDavid du Colombier 					cp = optab[Sac4];
2100da51d93aSDavid du Colombier 				biggen(l, s, d, 0, cp, args);
2101da51d93aSDavid du Colombier 				break;
2102da51d93aSDavid du Colombier 
2103da51d93aSDavid du Colombier 			default:
2104da51d93aSDavid du Colombier 				diag(r, "bad whatof pair %d %d\n", li, ri);
2105da51d93aSDavid du Colombier 				break;
2106da51d93aSDavid du Colombier 			}
2107da51d93aSDavid du Colombier 			break;
2108da51d93aSDavid du Colombier 		}
2109da51d93aSDavid du Colombier 
2110da51d93aSDavid du Colombier 		if(c != Z) {
2111da51d93aSDavid du Colombier 			gins(AMOVL, c, r);
2112da51d93aSDavid du Colombier 			regfree(c);
2113da51d93aSDavid du Colombier 		}
2114da51d93aSDavid du Colombier 
21156ede6e3fSDavid du Colombier 		if(d != Z)
21166ede6e3fSDavid du Colombier 			goto finished;
21176ede6e3fSDavid du Colombier 
2118da51d93aSDavid du Colombier 		switch(lri) {
2119da51d93aSDavid du Colombier 		case IMM(0, 0):
2120da51d93aSDavid du Colombier 			regfree(r);
2121da51d93aSDavid du Colombier 			/* fall thru */
2122da51d93aSDavid du Colombier 		case IMM(0, 1):
2123da51d93aSDavid du Colombier 			if(!dr)
2124da51d93aSDavid du Colombier 				storepair(l, nn, 1);
2125da51d93aSDavid du Colombier 			break;
2126da51d93aSDavid du Colombier 		case IMM(1, 0):
2127da51d93aSDavid du Colombier 			regfree(r);
2128da51d93aSDavid du Colombier 			break;
2129da51d93aSDavid du Colombier 		case IMM(1, 1):
2130da51d93aSDavid du Colombier 			break;
2131da51d93aSDavid du Colombier 		}
2132da51d93aSDavid du Colombier 		return 1;
2133da51d93aSDavid du Colombier 
2134da51d93aSDavid du Colombier 	cmp:
2135da51d93aSDavid du Colombier 		op = n->op;
2136da51d93aSDavid du Colombier 		/* evaluate hard subexps */
2137da51d93aSDavid du Colombier 		switch(lri) {
2138da51d93aSDavid du Colombier 		case IMM(0, 0):
2139da51d93aSDavid du Colombier 			if(l->complex > r->complex) {
2140da51d93aSDavid du Colombier 				t = regpair(Z, l);
2141da51d93aSDavid du Colombier 				sugen(l, t, 8);
2142da51d93aSDavid du Colombier 				l = t;
2143da51d93aSDavid du Colombier 				t = regpair(Z, r);
2144da51d93aSDavid du Colombier 				sugen(r, t, 8);
2145da51d93aSDavid du Colombier 				r = t;
2146da51d93aSDavid du Colombier 			}
2147da51d93aSDavid du Colombier 			else {
2148da51d93aSDavid du Colombier 				t = regpair(Z, r);
2149da51d93aSDavid du Colombier 				sugen(r, t, 8);
2150da51d93aSDavid du Colombier 				r = t;
2151da51d93aSDavid du Colombier 				t = regpair(Z, l);
2152da51d93aSDavid du Colombier 				sugen(l, t, 8);
2153da51d93aSDavid du Colombier 				l = t;
2154da51d93aSDavid du Colombier 			}
2155da51d93aSDavid du Colombier 			break;
2156da51d93aSDavid du Colombier 		case IMM(1, 0):
2157da51d93aSDavid du Colombier 			t = r;
2158da51d93aSDavid du Colombier 			r = l;
2159da51d93aSDavid du Colombier 			l = t;
2160da51d93aSDavid du Colombier 			ri = li;
2161da51d93aSDavid du Colombier 			op = invrel[relindex(op)];
2162da51d93aSDavid du Colombier 			/* fall thru */
2163da51d93aSDavid du Colombier 		case IMM(0, 1):
2164da51d93aSDavid du Colombier 			t = regpair(Z, l);
2165da51d93aSDavid du Colombier 			sugen(l, t, 8);
2166da51d93aSDavid du Colombier 			l = t;
2167da51d93aSDavid du Colombier 			break;
2168da51d93aSDavid du Colombier 		case IMM(1, 1):
2169da51d93aSDavid du Colombier 			break;
2170da51d93aSDavid du Colombier 		}
2171da51d93aSDavid du Colombier 
2172da51d93aSDavid du Colombier 		true = 1;
2173da51d93aSDavid du Colombier 		optab = cmptab;
2174da51d93aSDavid du Colombier 		switch(op) {
2175da51d93aSDavid du Colombier 		case OEQ:
2176da51d93aSDavid du Colombier 			optab = NEtab;
2177da51d93aSDavid du Colombier 			true = 0;
2178da51d93aSDavid du Colombier 			break;
2179da51d93aSDavid du Colombier 		case ONE:
2180da51d93aSDavid du Colombier 			optab = NEtab;
2181da51d93aSDavid du Colombier 			break;
2182da51d93aSDavid du Colombier 		case OLE:
2183da51d93aSDavid du Colombier 			args = GTargs;
2184da51d93aSDavid du Colombier 			true = 0;
2185da51d93aSDavid du Colombier 			break;
2186da51d93aSDavid du Colombier 		case OGT:
2187da51d93aSDavid du Colombier 			args = GTargs;
2188da51d93aSDavid du Colombier 			break;
2189da51d93aSDavid du Colombier 		case OLS:
2190da51d93aSDavid du Colombier 			args = HIargs;
2191da51d93aSDavid du Colombier 			true = 0;
2192da51d93aSDavid du Colombier 			break;
2193da51d93aSDavid du Colombier 		case OHI:
2194da51d93aSDavid du Colombier 			args = HIargs;
2195da51d93aSDavid du Colombier 			break;
2196da51d93aSDavid du Colombier 		case OLT:
2197da51d93aSDavid du Colombier 			args = GEargs;
2198da51d93aSDavid du Colombier 			true = 0;
2199da51d93aSDavid du Colombier 			break;
2200da51d93aSDavid du Colombier 		case OGE:
2201da51d93aSDavid du Colombier 			args = GEargs;
2202da51d93aSDavid du Colombier 			break;
2203da51d93aSDavid du Colombier 		case OLO:
2204da51d93aSDavid du Colombier 			args = HSargs;
2205da51d93aSDavid du Colombier 			true = 0;
2206da51d93aSDavid du Colombier 			break;
2207da51d93aSDavid du Colombier 		case OHS:
2208da51d93aSDavid du Colombier 			args = HSargs;
2209da51d93aSDavid du Colombier 			break;
2210da51d93aSDavid du Colombier 		default:
2211da51d93aSDavid du Colombier 			diag(n, "bad cmp\n");
2212da51d93aSDavid du Colombier 			SET(optab);
2213da51d93aSDavid du Colombier 		}
2214da51d93aSDavid du Colombier 
2215da51d93aSDavid du Colombier 		switch(lri) {
2216da51d93aSDavid du Colombier 		case IMM(0, 0):
2217da51d93aSDavid du Colombier 			biggen(l, r, Z, true, optab[T0i], args);
2218da51d93aSDavid du Colombier 			break;
2219da51d93aSDavid du Colombier 		case IMM(0, 1):
2220da51d93aSDavid du Colombier 		case IMM(1, 0):
2221da51d93aSDavid du Colombier 			switch(ri) {
2222da51d93aSDavid du Colombier 			case WNONE:
2223da51d93aSDavid du Colombier 				diag(l, "bad whatof\n");
2224da51d93aSDavid du Colombier 				break;
2225da51d93aSDavid du Colombier 			case WCONST:
2226da51d93aSDavid du Colombier 				biggen(l, r, Z, true, optab[T0i], args);
2227da51d93aSDavid du Colombier 				break;
2228da51d93aSDavid du Colombier 			case WHARD:
2229da51d93aSDavid du Colombier 				reglcgen(&nod2, r, Z);
2230da51d93aSDavid du Colombier 				r = &nod2;
2231da51d93aSDavid du Colombier 				/* fall thru */
2232da51d93aSDavid du Colombier 			case WADDR:
2233da51d93aSDavid du Colombier 				biggen(l, r, Z, true, optab[T0i], args);
2234da51d93aSDavid du Colombier 				if(ri == WHARD)
2235da51d93aSDavid du Colombier 					regfree(r);
2236da51d93aSDavid du Colombier 				break;
2237da51d93aSDavid du Colombier 			}
2238da51d93aSDavid du Colombier 			break;
2239da51d93aSDavid du Colombier 		case IMM(1, 1):
2240da51d93aSDavid du Colombier 			if(li == WHARD) {
2241da51d93aSDavid du Colombier 				reglcgen(&nod3, l, Z);
2242da51d93aSDavid du Colombier 				l = &nod3;
2243da51d93aSDavid du Colombier 			}
2244da51d93aSDavid du Colombier 			if(ri == WHARD) {
2245da51d93aSDavid du Colombier 				reglcgen(&nod2, r, Z);
2246da51d93aSDavid du Colombier 				r = &nod2;
2247da51d93aSDavid du Colombier 			}
2248da51d93aSDavid du Colombier 			biggen(l, r, Z, true, optab[Tii], args);
2249da51d93aSDavid du Colombier 			if(li == WHARD)
2250da51d93aSDavid du Colombier 				regfree(l);
2251da51d93aSDavid du Colombier 			if(ri == WHARD)
2252da51d93aSDavid du Colombier 				regfree(r);
2253da51d93aSDavid du Colombier 			break;
2254da51d93aSDavid du Colombier 		}
2255da51d93aSDavid du Colombier 
2256da51d93aSDavid du Colombier 		switch(lri) {
2257da51d93aSDavid du Colombier 		case IMM(0, 0):
2258da51d93aSDavid du Colombier 			freepair(r);
2259da51d93aSDavid du Colombier 			/* fall thru */;
2260da51d93aSDavid du Colombier 		case IMM(0, 1):
2261da51d93aSDavid du Colombier 		case IMM(1, 0):
2262da51d93aSDavid du Colombier 			freepair(l);
2263da51d93aSDavid du Colombier 			break;
2264da51d93aSDavid du Colombier 		case IMM(1, 1):
2265da51d93aSDavid du Colombier 			break;
2266da51d93aSDavid du Colombier 		}
2267da51d93aSDavid du Colombier 		return 1;
2268da51d93aSDavid du Colombier 
2269375daca8SDavid du Colombier 	case OASMUL:
2270375daca8SDavid du Colombier 	case OASLMUL:
2271375daca8SDavid du Colombier 		m = 0;
2272375daca8SDavid du Colombier 		goto mulop;
2273375daca8SDavid du Colombier 
2274375daca8SDavid du Colombier 	case OMUL:
2275375daca8SDavid du Colombier 	case OLMUL:
2276375daca8SDavid du Colombier 		m = 1;
2277375daca8SDavid du Colombier 		goto mulop;
2278375daca8SDavid du Colombier 
2279375daca8SDavid du Colombier 	mulop:
2280375daca8SDavid du Colombier 		dr = nn != Z && nn->op == OREGPAIR;
2281375daca8SDavid du Colombier 		l = vfunc(n->left, nn);
2282375daca8SDavid du Colombier 		r = vfunc(n->right, nn);
2283375daca8SDavid du Colombier 		if(r->op != OCONST) {
2284375daca8SDavid du Colombier 			if(l->complex > r->complex) {
2285375daca8SDavid du Colombier 				if(m) {
2286375daca8SDavid du Colombier 					t = l;
2287375daca8SDavid du Colombier 					l = r;
2288375daca8SDavid du Colombier 					r = t;
2289375daca8SDavid du Colombier 				}
2290375daca8SDavid du Colombier 				else if(!vaddr(l, 1)) {
2291375daca8SDavid du Colombier 					reglcgen(&nod5, l, Z);
2292375daca8SDavid du Colombier 					l = &nod5;
2293375daca8SDavid du Colombier 					evacaxdx(l);
2294375daca8SDavid du Colombier 				}
2295375daca8SDavid du Colombier 			}
2296375daca8SDavid du Colombier 			t = regpair(Z, n);
2297375daca8SDavid du Colombier 			sugen(r, t, 8);
2298375daca8SDavid du Colombier 			r = t;
2299375daca8SDavid du Colombier 			evacaxdx(r->left);
2300375daca8SDavid du Colombier 			evacaxdx(r->right);
2301375daca8SDavid du Colombier 			if(l->complex <= r->complex && !m && !vaddr(l, 1)) {
2302375daca8SDavid du Colombier 				reglcgen(&nod5, l, Z);
2303375daca8SDavid du Colombier 				l = &nod5;
2304375daca8SDavid du Colombier 				evacaxdx(l);
2305375daca8SDavid du Colombier 			}
2306375daca8SDavid du Colombier 		}
2307375daca8SDavid du Colombier 		if(dr)
2308375daca8SDavid du Colombier 			t = nn;
2309375daca8SDavid du Colombier 		else
2310375daca8SDavid du Colombier 			t = regpair(Z, n);
2311375daca8SDavid du Colombier 		c = Z;
2312375daca8SDavid du Colombier 		d = Z;
2313375daca8SDavid du Colombier 		if(!nodreg(&nod1, t->left, D_AX)) {
2314375daca8SDavid du Colombier 			if(t->left->reg != D_AX){
2315375daca8SDavid du Colombier 				t->left->reg = D_AX;
2316375daca8SDavid du Colombier 				reg[D_AX]++;
2317375daca8SDavid du Colombier 			}else if(reg[D_AX] == 0)
2318375daca8SDavid du Colombier 				fatal(Z, "vlong mul AX botch");
2319375daca8SDavid du Colombier 		}
2320375daca8SDavid du Colombier 		if(!nodreg(&nod2, t->right, D_DX)) {
2321375daca8SDavid du Colombier 			if(t->right->reg != D_DX){
2322375daca8SDavid du Colombier 				t->right->reg = D_DX;
2323375daca8SDavid du Colombier 				reg[D_DX]++;
2324375daca8SDavid du Colombier 			}else if(reg[D_DX] == 0)
2325375daca8SDavid du Colombier 				fatal(Z, "vlong mul DX botch");
2326375daca8SDavid du Colombier 		}
2327375daca8SDavid du Colombier 		if(m)
2328375daca8SDavid du Colombier 			sugen(l, t, 8);
2329375daca8SDavid du Colombier 		else
2330375daca8SDavid du Colombier 			loadpair(l, t);
2331375daca8SDavid du Colombier 		if(t->left->reg != D_AX) {
2332375daca8SDavid du Colombier 			c = &nod3;
2333375daca8SDavid du Colombier 			regsalloc(c, t->left);
2334375daca8SDavid du Colombier 			gmove(&nod1, c);
2335375daca8SDavid du Colombier 			gmove(t->left, &nod1);
2336375daca8SDavid du Colombier 			zapreg(t->left);
2337375daca8SDavid du Colombier 		}
2338375daca8SDavid du Colombier 		if(t->right->reg != D_DX) {
2339375daca8SDavid du Colombier 			d = &nod4;
2340375daca8SDavid du Colombier 			regsalloc(d, t->right);
2341375daca8SDavid du Colombier 			gmove(&nod2, d);
2342375daca8SDavid du Colombier 			gmove(t->right, &nod2);
2343375daca8SDavid du Colombier 			zapreg(t->right);
2344375daca8SDavid du Colombier 		}
2345375daca8SDavid du Colombier 		if(c != Z || d != Z) {
2346375daca8SDavid du Colombier 			s = regpair(Z, n);
2347375daca8SDavid du Colombier 			s->left = &nod1;
2348375daca8SDavid du Colombier 			s->right = &nod2;
2349375daca8SDavid du Colombier 		}
2350375daca8SDavid du Colombier 		else
2351375daca8SDavid du Colombier 			s = t;
2352375daca8SDavid du Colombier 		if(r->op == OCONST) {
2353375daca8SDavid du Colombier 			if(hi64v(r) == 0)
2354375daca8SDavid du Colombier 				biggen(s, r, Z, 0, mulc32, nil);
2355375daca8SDavid du Colombier 			else
2356375daca8SDavid du Colombier 				biggen(s, r, Z, 0, mulc64, nil);
2357375daca8SDavid du Colombier 		}
2358375daca8SDavid du Colombier 		else
2359375daca8SDavid du Colombier 			biggen(s, r, Z, 0, mull, nil);
2360375daca8SDavid du Colombier 		instpair(t, Z);
2361375daca8SDavid du Colombier 		if(c != Z) {
2362375daca8SDavid du Colombier 			gmove(&nod1, t->left);
2363375daca8SDavid du Colombier 			gmove(&nod3, &nod1);
2364375daca8SDavid du Colombier 		}
2365375daca8SDavid du Colombier 		if(d != Z) {
2366375daca8SDavid du Colombier 			gmove(&nod2, t->right);
2367375daca8SDavid du Colombier 			gmove(&nod4, &nod2);
2368375daca8SDavid du Colombier 		}
2369375daca8SDavid du Colombier 		if(r->op == OREGPAIR)
2370375daca8SDavid du Colombier 			freepair(r);
2371375daca8SDavid du Colombier 		if(!m)
2372375daca8SDavid du Colombier 			storepair(t, l, 0);
2373375daca8SDavid du Colombier 		if(l == &nod5)
2374375daca8SDavid du Colombier 			regfree(l);
2375375daca8SDavid du Colombier 		if(!dr) {
2376375daca8SDavid du Colombier 			if(nn != Z)
2377375daca8SDavid du Colombier 				storepair(t, nn, 1);
2378375daca8SDavid du Colombier 			else
2379375daca8SDavid du Colombier 				freepair(t);
2380375daca8SDavid du Colombier 		}
2381375daca8SDavid du Colombier 		return 1;
2382375daca8SDavid du Colombier 
2383da51d93aSDavid du Colombier 	case OASADD:
2384da51d93aSDavid du Colombier 		args = ADDargs;
2385da51d93aSDavid du Colombier 		goto vasop;
2386da51d93aSDavid du Colombier 	case OASAND:
2387da51d93aSDavid du Colombier 		args = ANDargs;
2388da51d93aSDavid du Colombier 		goto vasop;
2389da51d93aSDavid du Colombier 	case OASOR:
2390da51d93aSDavid du Colombier 		args = ORargs;
2391da51d93aSDavid du Colombier 		goto vasop;
2392da51d93aSDavid du Colombier 	case OASSUB:
2393da51d93aSDavid du Colombier 		args = SUBargs;
2394da51d93aSDavid du Colombier 		goto vasop;
2395da51d93aSDavid du Colombier 	case OASXOR:
2396da51d93aSDavid du Colombier 		args = XORargs;
2397da51d93aSDavid du Colombier 		goto vasop;
2398da51d93aSDavid du Colombier 
2399da51d93aSDavid du Colombier 	vasop:
2400da51d93aSDavid du Colombier 		l = n->left;
2401da51d93aSDavid du Colombier 		r = n->right;
2402da51d93aSDavid du Colombier 		dr = nn != Z && nn->op == OREGPAIR;
2403da51d93aSDavid du Colombier 		m = 0;
2404da51d93aSDavid du Colombier 		if(l->complex > r->complex) {
2405375daca8SDavid du Colombier 			if(!vaddr(l, 1)) {
2406da51d93aSDavid du Colombier 				reglcgen(&nod1, l, Z);
2407da51d93aSDavid du Colombier 				l = &nod1;
2408da51d93aSDavid du Colombier 			}
2409375daca8SDavid du Colombier 			if(!vaddr(r, 1) || nn != Z || r->op == OCONST) {
2410da51d93aSDavid du Colombier 				if(dr)
2411da51d93aSDavid du Colombier 					t = nn;
2412da51d93aSDavid du Colombier 				else
2413da51d93aSDavid du Colombier 					t = regpair(Z, r);
2414da51d93aSDavid du Colombier 				sugen(r, t, 8);
2415da51d93aSDavid du Colombier 				r = t;
2416da51d93aSDavid du Colombier 				m = 1;
2417da51d93aSDavid du Colombier 			}
2418da51d93aSDavid du Colombier 		}
2419da51d93aSDavid du Colombier 		else {
2420375daca8SDavid du Colombier 			if(!vaddr(r, 1) || nn != Z || r->op == OCONST) {
2421da51d93aSDavid du Colombier 				if(dr)
2422da51d93aSDavid du Colombier 					t = nn;
2423da51d93aSDavid du Colombier 				else
2424da51d93aSDavid du Colombier 					t = regpair(Z, r);
2425da51d93aSDavid du Colombier 				sugen(r, t, 8);
2426da51d93aSDavid du Colombier 				r = t;
2427da51d93aSDavid du Colombier 				m = 1;
2428da51d93aSDavid du Colombier 			}
2429375daca8SDavid du Colombier 			if(!vaddr(l, 1)) {
2430da51d93aSDavid du Colombier 				reglcgen(&nod1, l, Z);
2431da51d93aSDavid du Colombier 				l = &nod1;
2432da51d93aSDavid du Colombier 			}
2433da51d93aSDavid du Colombier 		}
2434da51d93aSDavid du Colombier 		if(nn != Z) {
2435da51d93aSDavid du Colombier 			if(n->op == OASSUB)
2436da51d93aSDavid du Colombier 				biggen(l, r, Z, 0, sub10, args);
2437da51d93aSDavid du Colombier 			else
2438da51d93aSDavid du Colombier 				biggen(r, l, Z, 0, binoptmp, args);
2439da51d93aSDavid du Colombier 			storepair(r, l, 0);
2440da51d93aSDavid du Colombier 		}
2441da51d93aSDavid du Colombier 		else {
2442da51d93aSDavid du Colombier 			if(m)
2443da51d93aSDavid du Colombier 				biggen(l, r, Z, 0, binop00, args);
2444da51d93aSDavid du Colombier 			else
2445da51d93aSDavid du Colombier 				biggen(l, r, Z, 0, binoptmp, args);
2446da51d93aSDavid du Colombier 		}
2447da51d93aSDavid du Colombier 		if(l == &nod1)
2448da51d93aSDavid du Colombier 			regfree(&nod1);
2449da51d93aSDavid du Colombier 		if(m) {
2450da51d93aSDavid du Colombier 			if(nn == Z)
2451da51d93aSDavid du Colombier 				freepair(r);
2452da51d93aSDavid du Colombier 			else if(!dr)
2453da51d93aSDavid du Colombier 				storepair(r, nn, 1);
2454da51d93aSDavid du Colombier 		}
2455da51d93aSDavid du Colombier 		return 1;
2456da51d93aSDavid du Colombier 
2457da51d93aSDavid du Colombier 	case OASASHL:
2458da51d93aSDavid du Colombier 		args = nil;
2459da51d93aSDavid du Colombier 		optab = asshlltab;
2460da51d93aSDavid du Colombier 		goto assh;
2461da51d93aSDavid du Colombier 	case OASLSHR:
2462da51d93aSDavid du Colombier 		args = shrlargs;
2463da51d93aSDavid du Colombier 		optab = asshrltab;
2464da51d93aSDavid du Colombier 		goto assh;
2465da51d93aSDavid du Colombier 	case OASASHR:
2466da51d93aSDavid du Colombier 		args = sarlargs;
2467da51d93aSDavid du Colombier 		optab = asshrltab;
2468da51d93aSDavid du Colombier 		goto assh;
2469da51d93aSDavid du Colombier 
2470da51d93aSDavid du Colombier 	assh:
2471da51d93aSDavid du Colombier 		c = Z;
2472da51d93aSDavid du Colombier 		l = n->left;
2473da51d93aSDavid du Colombier 		r = n->right;
2474da51d93aSDavid du Colombier 		if(r->op == OCONST) {
2475da51d93aSDavid du Colombier 			m = r->vconst & 63;
2476da51d93aSDavid du Colombier 			if(m < 32)
2477da51d93aSDavid du Colombier 				m = SAclo;
2478da51d93aSDavid du Colombier 			else if(m == 32)
2479da51d93aSDavid du Colombier 				m = SAc32;
2480da51d93aSDavid du Colombier 			else
2481da51d93aSDavid du Colombier 				m = SAchi;
2482da51d93aSDavid du Colombier 		}
2483da51d93aSDavid du Colombier 		else
2484da51d93aSDavid du Colombier 			m = SAgen;
2485da51d93aSDavid du Colombier 		if(l->complex > r->complex) {
2486375daca8SDavid du Colombier 			if(!vaddr(l, 0)) {
2487da51d93aSDavid du Colombier 				reglcgen(&nod1, l, Z);
2488da51d93aSDavid du Colombier 				l = &nod1;
2489da51d93aSDavid du Colombier 			}
2490da51d93aSDavid du Colombier 			if(m == SAgen) {
2491da51d93aSDavid du Colombier 				t = &nod2;
2492da51d93aSDavid du Colombier 				if(l->reg == D_CX) {
2493da51d93aSDavid du Colombier 					regalloc(t, r, Z);
2494da51d93aSDavid du Colombier 					gmove(l, t);
2495da51d93aSDavid du Colombier 					l->reg = t->reg;
2496da51d93aSDavid du Colombier 					t->reg = D_CX;
2497da51d93aSDavid du Colombier 				}
2498375daca8SDavid du Colombier 				else
2499375daca8SDavid du Colombier 					c = snarfreg(nn, t, D_CX, r, &nod3);
2500da51d93aSDavid du Colombier 				cgen(r, t);
2501da51d93aSDavid du Colombier 				r = t;
2502da51d93aSDavid du Colombier 			}
2503da51d93aSDavid du Colombier 		}
2504da51d93aSDavid du Colombier 		else {
2505da51d93aSDavid du Colombier 			if(m == SAgen) {
2506da51d93aSDavid du Colombier 				t = &nod2;
2507375daca8SDavid du Colombier 				c = snarfreg(nn, t, D_CX, r, &nod3);
2508da51d93aSDavid du Colombier 				cgen(r, t);
2509da51d93aSDavid du Colombier 				r = t;
2510da51d93aSDavid du Colombier 			}
2511375daca8SDavid du Colombier 			if(!vaddr(l, 0)) {
2512da51d93aSDavid du Colombier 				reglcgen(&nod1, l, Z);
2513da51d93aSDavid du Colombier 				l = &nod1;
2514da51d93aSDavid du Colombier 			}
2515da51d93aSDavid du Colombier 		}
2516da51d93aSDavid du Colombier 
2517da51d93aSDavid du Colombier 		if(nn != Z) {
2518da51d93aSDavid du Colombier 			m += SAdgen - SAgen;
2519da51d93aSDavid du Colombier 			d = regpair(nn, n);
2520375daca8SDavid du Colombier 			instpair(d, Z);
2521da51d93aSDavid du Colombier 			biggen(l, r, d, 0, optab[m], args);
2522375daca8SDavid du Colombier 			if(l == &nod1) {
2523375daca8SDavid du Colombier 				regfree(&nod1);
2524375daca8SDavid du Colombier 				l = Z;
2525375daca8SDavid du Colombier 			}
2526375daca8SDavid du Colombier 			if(r == &nod2 && c == Z) {
2527375daca8SDavid du Colombier 				regfree(&nod2);
2528375daca8SDavid du Colombier 				r = Z;
2529375daca8SDavid du Colombier 			}
2530da51d93aSDavid du Colombier 			if(d != nn)
2531da51d93aSDavid du Colombier 				storepair(d, nn, 1);
2532da51d93aSDavid du Colombier 		}
2533da51d93aSDavid du Colombier 		else
2534da51d93aSDavid du Colombier 			biggen(l, r, Z, 0, optab[m], args);
2535da51d93aSDavid du Colombier 
2536da51d93aSDavid du Colombier 		if(c != Z) {
2537da51d93aSDavid du Colombier 			gins(AMOVL, c, r);
2538da51d93aSDavid du Colombier 			regfree(c);
2539da51d93aSDavid du Colombier 		}
2540da51d93aSDavid du Colombier 		if(l == &nod1)
2541da51d93aSDavid du Colombier 			regfree(&nod1);
2542da51d93aSDavid du Colombier 		if(r == &nod2)
2543da51d93aSDavid du Colombier 			regfree(&nod2);
2544da51d93aSDavid du Colombier 		return 1;
2545da51d93aSDavid du Colombier 
2546da51d93aSDavid du Colombier 	case OPOSTINC:
2547da51d93aSDavid du Colombier 		args = ADDargs;
2548da51d93aSDavid du Colombier 		cp = incdecpost;
2549da51d93aSDavid du Colombier 		goto vinc;
2550da51d93aSDavid du Colombier 	case OPOSTDEC:
2551da51d93aSDavid du Colombier 		args = SUBargs;
2552da51d93aSDavid du Colombier 		cp = incdecpost;
2553da51d93aSDavid du Colombier 		goto vinc;
2554da51d93aSDavid du Colombier 	case OPREINC:
2555da51d93aSDavid du Colombier 		args = ADDargs;
2556da51d93aSDavid du Colombier 		cp = incdecpre;
2557da51d93aSDavid du Colombier 		goto vinc;
2558da51d93aSDavid du Colombier 	case OPREDEC:
2559da51d93aSDavid du Colombier 		args = SUBargs;
2560da51d93aSDavid du Colombier 		cp = incdecpre;
2561da51d93aSDavid du Colombier 		goto vinc;
2562da51d93aSDavid du Colombier 
2563da51d93aSDavid du Colombier 	vinc:
2564da51d93aSDavid du Colombier 		l = n->left;
2565375daca8SDavid du Colombier 		if(!vaddr(l, 1)) {
2566da51d93aSDavid du Colombier 			reglcgen(&nod1, l, Z);
2567da51d93aSDavid du Colombier 			l = &nod1;
2568da51d93aSDavid du Colombier 		}
2569da51d93aSDavid du Colombier 
2570da51d93aSDavid du Colombier 		if(nn != Z) {
2571da51d93aSDavid du Colombier 			d = regpair(nn, n);
2572375daca8SDavid du Colombier 			instpair(d, Z);
2573da51d93aSDavid du Colombier 			biggen(l, Z, d, 0, cp, args);
2574375daca8SDavid du Colombier 			if(l == &nod1) {
2575375daca8SDavid du Colombier 				regfree(&nod1);
2576375daca8SDavid du Colombier 				l = Z;
2577375daca8SDavid du Colombier 			}
2578da51d93aSDavid du Colombier 			if(d != nn)
2579da51d93aSDavid du Colombier 				storepair(d, nn, 1);
2580da51d93aSDavid du Colombier 		}
2581da51d93aSDavid du Colombier 		else
2582da51d93aSDavid du Colombier 			biggen(l, Z, Z, 0, incdec, args);
2583da51d93aSDavid du Colombier 
2584da51d93aSDavid du Colombier 		if(l == &nod1)
2585da51d93aSDavid du Colombier 			regfree(&nod1);
2586da51d93aSDavid du Colombier 		return 1;
2587da51d93aSDavid du Colombier 
2588da51d93aSDavid du Colombier 	case OCAST:
2589da51d93aSDavid du Colombier 		l = n->left;
2590da51d93aSDavid du Colombier 		if(typev[l->type->etype]) {
2591375daca8SDavid du Colombier 			if(!vaddr(l, 1)) {
2592da51d93aSDavid du Colombier 				if(l->complex + 1 > nn->complex) {
2593da51d93aSDavid du Colombier 					d = regpair(Z, l);
2594da51d93aSDavid du Colombier 					sugen(l, d, 8);
2595375daca8SDavid du Colombier 					if(!vaddr(nn, 1)) {
2596da51d93aSDavid du Colombier 						reglcgen(&nod1, nn, Z);
2597da51d93aSDavid du Colombier 						r = &nod1;
2598da51d93aSDavid du Colombier 					}
2599da51d93aSDavid du Colombier 					else
2600da51d93aSDavid du Colombier 						r = nn;
2601da51d93aSDavid du Colombier 				}
2602da51d93aSDavid du Colombier 				else {
2603375daca8SDavid du Colombier 					if(!vaddr(nn, 1)) {
2604da51d93aSDavid du Colombier 						reglcgen(&nod1, nn, Z);
2605da51d93aSDavid du Colombier 						r = &nod1;
2606da51d93aSDavid du Colombier 					}
2607da51d93aSDavid du Colombier 					else
2608da51d93aSDavid du Colombier 						r = nn;
2609da51d93aSDavid du Colombier 					d = regpair(Z, l);
2610da51d93aSDavid du Colombier 					sugen(l, d, 8);
2611da51d93aSDavid du Colombier 				}
2612da51d93aSDavid du Colombier //				d->left->type = r->type;
2613da51d93aSDavid du Colombier 				d->left->type = types[TLONG];
2614da51d93aSDavid du Colombier 				gmove(d->left, r);
2615da51d93aSDavid du Colombier 				freepair(d);
2616da51d93aSDavid du Colombier 			}
2617da51d93aSDavid du Colombier 			else {
2618375daca8SDavid du Colombier 				if(nn->op != OREGISTER && !vaddr(nn, 1)) {
2619da51d93aSDavid du Colombier 					reglcgen(&nod1, nn, Z);
2620da51d93aSDavid du Colombier 					r = &nod1;
2621da51d93aSDavid du Colombier 				}
2622da51d93aSDavid du Colombier 				else
2623da51d93aSDavid du Colombier 					r = nn;
2624da51d93aSDavid du Colombier //				l->type = r->type;
2625da51d93aSDavid du Colombier 				l->type = types[TLONG];
2626da51d93aSDavid du Colombier 				gmove(l, r);
2627da51d93aSDavid du Colombier 			}
2628da51d93aSDavid du Colombier 			if(r != nn)
2629da51d93aSDavid du Colombier 				regfree(r);
2630da51d93aSDavid du Colombier 		}
2631da51d93aSDavid du Colombier 		else {
2632da51d93aSDavid du Colombier 			if(typeu[l->type->etype] || cond(l->op))
2633da51d93aSDavid du Colombier 				si = TUNSIGNED;
2634da51d93aSDavid du Colombier 			else
2635da51d93aSDavid du Colombier 				si = TSIGNED;
2636da51d93aSDavid du Colombier 			regalloc(&nod1, l, Z);
2637da51d93aSDavid du Colombier 			cgen(l, &nod1);
2638da51d93aSDavid du Colombier 			if(nn->op == OREGPAIR) {
2639375daca8SDavid du Colombier 				m = instpair(nn, &nod1);
2640da51d93aSDavid du Colombier 				biggen(&nod1, Z, nn, si == TSIGNED, castrp, nil);
2641da51d93aSDavid du Colombier 			}
2642da51d93aSDavid du Colombier 			else {
2643375daca8SDavid du Colombier 				m = 0;
2644375daca8SDavid du Colombier 				if(!vaddr(nn, si != TSIGNED)) {
2645da51d93aSDavid du Colombier 					dt = nn->type;
2646da51d93aSDavid du Colombier 					nn->type = types[TLONG];
2647da51d93aSDavid du Colombier 					reglcgen(&nod2, nn, Z);
2648da51d93aSDavid du Colombier 					nn->type = dt;
2649da51d93aSDavid du Colombier 					nn = &nod2;
2650da51d93aSDavid du Colombier 				}
2651da51d93aSDavid du Colombier 				dt = nn->type;
2652da51d93aSDavid du Colombier 				nn->type = types[TLONG];
2653da51d93aSDavid du Colombier 				biggen(&nod1, Z, nn, si == TSIGNED, castrpa, nil);
2654da51d93aSDavid du Colombier 				nn->type = dt;
2655da51d93aSDavid du Colombier 				if(nn == &nod2)
2656da51d93aSDavid du Colombier 					regfree(&nod2);
2657da51d93aSDavid du Colombier 			}
2658375daca8SDavid du Colombier 			if(!m)
2659da51d93aSDavid du Colombier 				regfree(&nod1);
2660da51d93aSDavid du Colombier 		}
2661da51d93aSDavid du Colombier 		return 1;
2662da51d93aSDavid du Colombier 
2663da51d93aSDavid du Colombier 	default:
2664da51d93aSDavid du Colombier 		if(n->op == OREGPAIR) {
2665da51d93aSDavid du Colombier 			storepair(n, nn, 1);
2666da51d93aSDavid du Colombier 			return 1;
2667da51d93aSDavid du Colombier 		}
2668da51d93aSDavid du Colombier 		if(nn->op == OREGPAIR) {
2669da51d93aSDavid du Colombier 			loadpair(n, nn);
2670da51d93aSDavid du Colombier 			return 1;
2671da51d93aSDavid du Colombier 		}
2672da51d93aSDavid du Colombier 		return 0;
2673da51d93aSDavid du Colombier 	}
2674da51d93aSDavid du Colombier finished:
2675da51d93aSDavid du Colombier 	if(d != nn)
2676da51d93aSDavid du Colombier 		storepair(d, nn, 1);
2677da51d93aSDavid du Colombier 	return 1;
2678da51d93aSDavid du Colombier }
2679da51d93aSDavid du Colombier 
2680da51d93aSDavid du Colombier void
2681da51d93aSDavid du Colombier testv(Node *n, int true)
2682da51d93aSDavid du Colombier {
2683da51d93aSDavid du Colombier 	Type *t;
2684*4ac975e2SDavid du Colombier 	Node *nn, nod, *b;
2685*4ac975e2SDavid du Colombier 
2686*4ac975e2SDavid du Colombier 	if(machcap(Z)) {
2687*4ac975e2SDavid du Colombier 		b = &nod;
2688*4ac975e2SDavid du Colombier 		b->op = true ? ONE : OEQ;
2689*4ac975e2SDavid du Colombier 		b->left = n;
2690*4ac975e2SDavid du Colombier 		b->right = new(0, Z, Z);
2691*4ac975e2SDavid du Colombier 		*b->right = *nodconst(0);
2692*4ac975e2SDavid du Colombier 		b->right->type = n->type;
2693*4ac975e2SDavid du Colombier 		b->type = types[TLONG];
2694*4ac975e2SDavid du Colombier 		cgen64(b, Z);
2695*4ac975e2SDavid du Colombier 		return;
2696*4ac975e2SDavid du Colombier 	}
2697da51d93aSDavid du Colombier 
2698da51d93aSDavid du Colombier 	switch(n->op) {
2699da51d93aSDavid du Colombier 	case OINDREG:
2700da51d93aSDavid du Colombier 	case ONAME:
2701da51d93aSDavid du Colombier 		biggen(n, Z, Z, true, testi, nil);
2702da51d93aSDavid du Colombier 		break;
2703da51d93aSDavid du Colombier 
2704da51d93aSDavid du Colombier 	default:
2705da51d93aSDavid du Colombier 		n = vfunc(n, n);
2706da51d93aSDavid du Colombier 		if(n->addable >= INDEXED) {
2707da51d93aSDavid du Colombier 			t = n->type;
2708da51d93aSDavid du Colombier 			n->type = types[TLONG];
2709da51d93aSDavid du Colombier 			reglcgen(&nod, n, Z);
2710da51d93aSDavid du Colombier 			n->type = t;
2711da51d93aSDavid du Colombier 			n = &nod;
2712da51d93aSDavid du Colombier 			biggen(n, Z, Z, true, testi, nil);
2713da51d93aSDavid du Colombier 			if(n == &nod)
2714da51d93aSDavid du Colombier 				regfree(n);
2715da51d93aSDavid du Colombier 		}
2716da51d93aSDavid du Colombier 		else {
2717da51d93aSDavid du Colombier 			nn = regpair(Z, n);
2718da51d93aSDavid du Colombier 			sugen(n, nn, 8);
2719da51d93aSDavid du Colombier 			biggen(nn, Z, Z, true, testi, nil);
2720da51d93aSDavid du Colombier 			freepair(nn);
2721da51d93aSDavid du Colombier 		}
2722da51d93aSDavid du Colombier 	}
2723da51d93aSDavid du Colombier }
2724