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