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