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