]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/8c/cgen64.c
audiohda: fix syntax error
[plan9front.git] / sys / src / cmd / 8c / cgen64.c
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                 //prtree(n, "zapreg");
131                 regfree(n);
132                 n->reg = D_NONE;
133         }
134 }
135
136 static void
137 freepair(Node *n)
138 {
139         regfree(n->left);
140         regfree(n->right);
141 }
142
143 /* n is not OREGPAIR, nn is */
144 void
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
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
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
211 reduxv(Node *n)
212 {
213         return lo64v(n) == 0 || hi64v(n) == 0;
214 }
215
216 int
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 *
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
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 *
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
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
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         if(nn != Z && nn->complex >= FNX){
1579                 reglcgen(&nod1, nn, Z);
1580                 cgen(n, &nod1);
1581                 regfree(&nod1);
1582                 return 1;
1583         }
1584
1585         switch(n->op) {
1586         case ONEG:
1587                 d = regpair(nn, n);
1588                 sugen(n->left, d, 8);
1589                 gins(ANOTL, Z, d->right);
1590                 gins(ANEGL, Z, d->left);
1591                 gins(ASBBL, nodconst(-1), d->right);
1592                 break;
1593
1594         case OCOM:
1595                 if(!vaddr(n->left, 0) || !vaddr(nn, 0))
1596                         d = regpair(nn, n);
1597                 else
1598                         return 0;
1599                 sugen(n->left, d, 8);
1600                 gins(ANOTL, Z, d->left);
1601                 gins(ANOTL, Z, d->right);
1602                 break;
1603
1604         case OADD:
1605                 optab = ADDtab;
1606                 args = ADDargs;
1607                 goto twoop;
1608         case OAND:
1609                 optab = ANDtab;
1610                 args = ANDargs;
1611                 goto twoop;
1612         case OOR:
1613                 optab = ORtab;
1614                 args = ORargs;
1615                 goto twoop;
1616         case OSUB:
1617                 optab = SUBtab;
1618                 args = SUBargs;
1619                 goto twoop;
1620         case OXOR:
1621                 optab = ORtab;
1622                 args = XORargs;
1623                 goto twoop;
1624         case OASHL:
1625                 sh = 1;
1626                 args = nil;
1627                 optab = shlltab;
1628                 goto twoop;
1629         case OLSHR:
1630                 sh = 1;
1631                 args = shrlargs;
1632                 optab = shrltab;
1633                 goto twoop;
1634         case OASHR:
1635                 sh = 1;
1636                 args = sarlargs;
1637                 optab = shrltab;
1638                 goto twoop;
1639         case OEQ:
1640                 cmp = 1;
1641                 args = nil;
1642                 optab = nil;
1643                 goto twoop;
1644         case ONE:
1645                 cmp = 1;
1646                 args = nil;
1647                 optab = nil;
1648                 goto twoop;
1649         case OLE:
1650                 cmp = 1;
1651                 args = nil;
1652                 optab = nil;
1653                 goto twoop;
1654         case OLT:
1655                 cmp = 1;
1656                 args = nil;
1657                 optab = nil;
1658                 goto twoop;
1659         case OGE:
1660                 cmp = 1;
1661                 args = nil;
1662                 optab = nil;
1663                 goto twoop;
1664         case OGT:
1665                 cmp = 1;
1666                 args = nil;
1667                 optab = nil;
1668                 goto twoop;
1669         case OHI:
1670                 cmp = 1;
1671                 args = nil;
1672                 optab = nil;
1673                 goto twoop;
1674         case OHS:
1675                 cmp = 1;
1676                 args = nil;
1677                 optab = nil;
1678                 goto twoop;
1679         case OLO:
1680                 cmp = 1;
1681                 args = nil;
1682                 optab = nil;
1683                 goto twoop;
1684         case OLS:
1685                 cmp = 1;
1686                 args = nil;
1687                 optab = nil;
1688                 goto twoop;
1689
1690 twoop:
1691                 dr = nn != Z && nn->op == OREGPAIR;
1692                 l = vfunc(n->left, nn);
1693                 if(sh)
1694                         r = n->right;
1695                 else
1696                         r = vfunc(n->right, nn);
1697
1698                 li = l->op == ONAME || l->op == OINDREG || l->op == OCONST;
1699                 ri = r->op == ONAME || r->op == OINDREG || r->op == OCONST;
1700
1701 #define IMM(l, r)       ((l) | ((r) << 1))
1702
1703                 lri = IMM(li, ri);
1704
1705                 /* find out what is so easy about some operands */
1706                 if(li)
1707                         li = whatof(l, sh | cmp);
1708                 if(ri)
1709                         ri = whatof(r, cmp);
1710
1711                 if(sh)
1712                         goto shift;
1713
1714                 if(cmp)
1715                         goto cmp;
1716
1717                 /* evaluate hard subexps, stealing nn if possible. */
1718                 switch(lri) {
1719                 case IMM(0, 0):
1720                 bin00:
1721                         if(l->complex > r->complex) {
1722                                 if(dr)
1723                                         t = nn;
1724                                 else
1725                                         t = regpair(Z, n);
1726                                 sugen(l, t, 8);
1727                                 l = t;
1728                                 t = regpair(Z, n);
1729                                 sugen(r, t, 8);
1730                                 r = t;
1731                         }
1732                         else {
1733                                 t = regpair(Z, n);
1734                                 sugen(r, t, 8);
1735                                 r = t;
1736                                 if(dr)
1737                                         t = nn;
1738                                 else
1739                                         t = regpair(Z, n);
1740                                 sugen(l, t, 8);
1741                                 l = t;
1742                         }
1743                         break;
1744                 case IMM(0, 1):
1745                         if(dr)
1746                                 t = nn;
1747                         else
1748                                 t = regpair(Z, n);
1749                         sugen(l, t, 8);
1750                         l = t;
1751                         break;
1752                 case IMM(1, 0):
1753                         if(n->op == OSUB && l->op == OCONST && hi64v(l) == 0) {
1754                                 lri = IMM(0, 0);
1755                                 goto bin00;
1756                         }
1757                         if(dr)
1758                                 t = nn;
1759                         else
1760                                 t = regpair(Z, n);
1761                         sugen(r, t, 8);
1762                         r = t;
1763                         break;
1764                 case IMM(1, 1):
1765                         break;
1766                 }
1767
1768 #define WW(l, r)        ((l) | ((r) << 2))
1769                 d = Z;
1770                 dt = nn->type;
1771                 nn->type = types[TLONG];
1772
1773                 switch(lri) {
1774                 case IMM(0, 0):
1775                         biggen(l, r, Z, 0, binop00, args);
1776                         break;
1777                 case IMM(0, 1):
1778                         switch(ri) {
1779                         case WNONE:
1780                                 diag(r, "bad whatof\n");
1781                                 break;
1782                         case WCONST:
1783                                 biggen(l, r, Z, 0, optab[B0c], args);
1784                                 break;
1785                         case WHARD:
1786                                 reglcgen(&nod2, r, Z);
1787                                 r = &nod2;
1788                                 /* fall thru */
1789                         case WADDR:
1790                                 biggen(l, r, Z, 0, binoptmp, args);
1791                                 if(ri == WHARD)
1792                                         regfree(r);
1793                                 break;
1794                         }
1795                         break;
1796                 case IMM(1, 0):
1797                         if(n->op == OSUB) {
1798                                 switch(li) {
1799                                 case WNONE:
1800                                         diag(l, "bad whatof\n");
1801                                         break;
1802                                 case WHARD:
1803                                         reglcgen(&nod2, l, Z);
1804                                         l = &nod2;
1805                                         /* fall thru */
1806                                 case WADDR:
1807                                 case WCONST:
1808                                         biggen(l, r, Z, 0, sub10, args);
1809                                         break;
1810                                 }
1811                                 if(li == WHARD)
1812                                         regfree(l);
1813                         }
1814                         else {
1815                                 switch(li) {
1816                                 case WNONE:
1817                                         diag(l, "bad whatof\n");
1818                                         break;
1819                                 case WCONST:
1820                                         biggen(r, l, Z, 0, optab[B0c], args);
1821                                         break;
1822                                 case WHARD:
1823                                         reglcgen(&nod2, l, Z);
1824                                         l = &nod2;
1825                                         /* fall thru */
1826                                 case WADDR:
1827                                         biggen(r, l, Z, 0, binoptmp, args);
1828                                         if(li == WHARD)
1829                                                 regfree(l);
1830                                         break;
1831                                 }
1832                         }
1833                         break;
1834                 case IMM(1, 1):
1835                         switch(WW(li, ri)) {
1836                         case WW(WCONST, WHARD):
1837                                 if(r->op == ONAME && n->op == OAND && reduxv(l))
1838                                         ri = WADDR;
1839                                 break;
1840                         case WW(WHARD, WCONST):
1841                                 if(l->op == ONAME && n->op == OAND && reduxv(r))
1842                                         li = WADDR;
1843                                 break;
1844                         }
1845                         if(li == WHARD) {
1846                                 reglcgen(&nod3, l, Z);
1847                                 l = &nod3;
1848                         }
1849                         if(ri == WHARD) {
1850                                 reglcgen(&nod2, r, Z);
1851                                 r = &nod2;
1852                         }
1853                         d = regpair(nn, n);
1854                         instpair(d, Z);
1855                         switch(WW(li, ri)) {
1856                         case WW(WCONST, WADDR):
1857                         case WW(WCONST, WHARD):
1858                                 biggen(l, r, d, 0, optab[Bca], args);
1859                                 break;
1860
1861                         case WW(WADDR, WCONST):
1862                         case WW(WHARD, WCONST):
1863                                 biggen(l, r, d, 0, optab[Bac], args);
1864                                 break;
1865
1866                         case WW(WADDR, WADDR):
1867                         case WW(WADDR, WHARD):
1868                         case WW(WHARD, WADDR):
1869                         case WW(WHARD, WHARD):
1870                                 biggen(l, r, d, 0, binop11, args);
1871                                 break;
1872
1873                         default:
1874                                 diag(r, "bad whatof pair %d %d\n", li, ri);
1875                                 break;
1876                         }
1877                         if(li == WHARD)
1878                                 regfree(l);
1879                         if(ri == WHARD)
1880                                 regfree(r);
1881                         break;
1882                 }
1883
1884                 nn->type = dt;
1885
1886                 if(d != Z)
1887                         goto finished;
1888
1889                 switch(lri) {
1890                 case IMM(0, 0):
1891                         freepair(r);
1892                         /* fall thru */;
1893                 case IMM(0, 1):
1894                         if(!dr)
1895                                 storepair(l, nn, 1);
1896                         break;
1897                 case IMM(1, 0):
1898                         if(!dr)
1899                                 storepair(r, nn, 1);
1900                         break;
1901                 case IMM(1, 1):
1902                         break;
1903                 }
1904                 return 1;
1905
1906         shift:
1907                 c = Z;
1908
1909                 /* evaluate hard subexps, stealing nn if possible. */
1910                 /* must also secure CX.  not as many optims as binop. */
1911                 switch(lri) {
1912                 case IMM(0, 0):
1913                 imm00:
1914                         if(l->complex + 1 > r->complex) {
1915                                 if(dr)
1916                                         t = nn;
1917                                 else
1918                                         t = regpair(Z, l);
1919                                 sugen(l, t, 8);
1920                                 l = t;
1921                                 t = &nod1;
1922                                 c = snarfreg(l, t, D_CX, r, &nod2);
1923                                 cgen(r, t);
1924                                 r = t;
1925                         }
1926                         else {
1927                                 t = &nod1;
1928                                 c = snarfreg(nn, t, D_CX, r, &nod2);
1929                                 cgen(r, t);
1930                                 r = t;
1931                                 if(dr)
1932                                         t = nn;
1933                                 else
1934                                         t = regpair(Z, l);
1935                                 sugen(l, t, 8);
1936                                 l = t;
1937                         }
1938                         break;
1939                 case IMM(0, 1):
1940                 imm01:
1941                         if(ri != WCONST) {
1942                                 lri = IMM(0, 0);
1943                                 goto imm00;
1944                         }
1945                         if(dr)
1946                                 t = nn;
1947                         else
1948                                 t = regpair(Z, n);
1949                         sugen(l, t, 8);
1950                         l = t;
1951                         break;
1952                 case IMM(1, 0):
1953                 imm10:
1954                         if(li != WCONST) {
1955                                 lri = IMM(0, 0);
1956                                 goto imm00;
1957                         }
1958                         t = &nod1;
1959                         c = snarfreg(nn, t, D_CX, r, &nod2);
1960                         cgen(r, t);
1961                         r = t;
1962                         break;
1963                 case IMM(1, 1):
1964                         if(ri != WCONST) {
1965                                 lri = IMM(1, 0);
1966                                 goto imm10;
1967                         }
1968                         if(li == WHARD) {
1969                                 lri = IMM(0, 1);
1970                                 goto imm01;
1971                         }
1972                         break;
1973                 }
1974
1975                 d = Z;
1976
1977                 switch(lri) {
1978                 case IMM(0, 0):
1979                         biggen(l, r, Z, 0, optab[S00], args);
1980                         break;
1981                 case IMM(0, 1):
1982                         switch(ri) {
1983                         case WNONE:
1984                         case WADDR:
1985                         case WHARD:
1986                                 diag(r, "bad whatof\n");
1987                                 break;
1988                         case WCONST:
1989                                 m = r->vconst & 63;
1990                                 s = nodconst(m);
1991                                 if(m < 32)
1992                                         cp = optab[Sc0];
1993                                 else if(m == 32)
1994                                         cp = optab[Sc1];
1995                                 else
1996                                         cp = optab[Sc2];
1997                                 biggen(l, s, Z, 0, cp, args);
1998                                 break;
1999                         }
2000                         break;
2001                 case IMM(1, 0):
2002                         /* left is const */
2003                         d = regpair(nn, n);
2004                         instpair(d, Z);
2005                         biggen(l, r, d, 0, optab[S10], args);
2006                         regfree(r);
2007                         break;
2008                 case IMM(1, 1):
2009                         d = regpair(nn, n);
2010                         instpair(d, Z);
2011                         switch(WW(li, ri)) {
2012                         case WW(WADDR, WCONST):
2013                                 m = r->vconst & 63;
2014                                 s = nodconst(m);
2015                                 if(m < 32) {
2016                                         loadpair(l, d);
2017                                         l = d;
2018                                         cp = optab[Sc0];
2019                                 }
2020                                 else if(m == 32)
2021                                         cp = optab[Sac3];
2022                                 else
2023                                         cp = optab[Sac4];
2024                                 biggen(l, s, d, 0, cp, args);
2025                                 break;
2026
2027                         default:
2028                                 diag(r, "bad whatof pair %d %d\n", li, ri);
2029                                 break;
2030                         }
2031                         break;
2032                 }
2033
2034                 if(c != Z) {
2035                         gins(AMOVL, c, r);
2036                         regfree(c);
2037                 }
2038
2039                 if(d != Z)
2040                         goto finished;
2041
2042                 switch(lri) {
2043                 case IMM(0, 0):
2044                         regfree(r);
2045                         /* fall thru */
2046                 case IMM(0, 1):
2047                         if(!dr)
2048                                 storepair(l, nn, 1);
2049                         break;
2050                 case IMM(1, 0):
2051                         regfree(r);
2052                         break;
2053                 case IMM(1, 1):
2054                         break;
2055                 }
2056                 return 1;
2057
2058         cmp:
2059                 op = n->op;
2060                 /* evaluate hard subexps */
2061                 switch(lri) {
2062                 case IMM(0, 0):
2063                         if(l->complex > r->complex) {
2064                                 t = regpair(Z, l);
2065                                 sugen(l, t, 8);
2066                                 l = t;
2067                                 t = regpair(Z, r);
2068                                 sugen(r, t, 8);
2069                                 r = t;
2070                         }
2071                         else {
2072                                 t = regpair(Z, r);
2073                                 sugen(r, t, 8);
2074                                 r = t;
2075                                 t = regpair(Z, l);
2076                                 sugen(l, t, 8);
2077                                 l = t;
2078                         }
2079                         break;
2080                 case IMM(1, 0):
2081                         t = r;
2082                         r = l;
2083                         l = t;
2084                         ri = li;
2085                         op = invrel[relindex(op)];
2086                         /* fall thru */
2087                 case IMM(0, 1):
2088                         t = regpair(Z, l);
2089                         sugen(l, t, 8);
2090                         l = t;
2091                         break;
2092                 case IMM(1, 1):
2093                         break;
2094                 }
2095
2096                 true = 1;
2097                 optab = cmptab;
2098                 switch(op) {
2099                 case OEQ:
2100                         optab = NEtab;
2101                         true = 0;
2102                         break;
2103                 case ONE:
2104                         optab = NEtab;
2105                         break;
2106                 case OLE:
2107                         args = GTargs;
2108                         true = 0;
2109                         break;
2110                 case OGT:
2111                         args = GTargs;
2112                         break;
2113                 case OLS:
2114                         args = HIargs;
2115                         true = 0;
2116                         break;
2117                 case OHI:
2118                         args = HIargs;
2119                         break;
2120                 case OLT:
2121                         args = GEargs;
2122                         true = 0;
2123                         break;
2124                 case OGE:
2125                         args = GEargs;
2126                         break;
2127                 case OLO:
2128                         args = HSargs;
2129                         true = 0;
2130                         break;
2131                 case OHS:
2132                         args = HSargs;
2133                         break;
2134                 default:
2135                         diag(n, "bad cmp\n");
2136                         SET(optab);
2137                 }
2138
2139                 switch(lri) {
2140                 case IMM(0, 0):
2141                         biggen(l, r, Z, true, optab[T0i], args);
2142                         break;
2143                 case IMM(0, 1):
2144                 case IMM(1, 0):
2145                         switch(ri) {
2146                         case WNONE:
2147                                 diag(l, "bad whatof\n");
2148                                 break;
2149                         case WCONST:
2150                                 biggen(l, r, Z, true, optab[T0i], args);
2151                                 break;
2152                         case WHARD:
2153                                 reglcgen(&nod2, r, Z);
2154                                 r = &nod2;
2155                                 /* fall thru */
2156                         case WADDR:
2157                                 biggen(l, r, Z, true, optab[T0i], args);
2158                                 if(ri == WHARD)
2159                                         regfree(r);
2160                                 break;
2161                         }
2162                         break;
2163                 case IMM(1, 1):
2164                         if(li == WHARD) {
2165                                 reglcgen(&nod3, l, Z);
2166                                 l = &nod3;
2167                         }
2168                         if(ri == WHARD) {
2169                                 reglcgen(&nod2, r, Z);
2170                                 r = &nod2;
2171                         }
2172                         biggen(l, r, Z, true, optab[Tii], args);
2173                         if(li == WHARD)
2174                                 regfree(l);
2175                         if(ri == WHARD)
2176                                 regfree(r);
2177                         break;
2178                 }
2179
2180                 switch(lri) {
2181                 case IMM(0, 0):
2182                         freepair(r);
2183                         /* fall thru */;
2184                 case IMM(0, 1):
2185                 case IMM(1, 0):
2186                         freepair(l);
2187                         break;
2188                 case IMM(1, 1):
2189                         break;
2190                 }
2191                 return 1;
2192
2193         case OASMUL:
2194         case OASLMUL:
2195                 m = 0;
2196                 goto mulop;
2197
2198         case OMUL:
2199         case OLMUL:
2200                 m = 1;
2201                 goto mulop;
2202
2203         mulop:
2204                 dr = nn != Z && nn->op == OREGPAIR;
2205                 l = vfunc(n->left, nn);
2206                 r = vfunc(n->right, nn);
2207                 if(r->op != OCONST) {
2208                         if(l->complex > r->complex) {
2209                                 if(m) {
2210                                         t = l;
2211                                         l = r;
2212                                         r = t;
2213                                 }
2214                                 else if(!vaddr(l, 1)) {
2215                                         reglcgen(&nod5, l, Z);
2216                                         l = &nod5;
2217                                         evacaxdx(l);
2218                                 }
2219                         }
2220                         t = regpair(Z, n);
2221                         sugen(r, t, 8);
2222                         r = t;
2223                         evacaxdx(r->left);
2224                         evacaxdx(r->right);
2225                         if(l->complex <= r->complex && !m && !vaddr(l, 1)) {
2226                                 reglcgen(&nod5, l, Z);
2227                                 l = &nod5;
2228                                 evacaxdx(l);
2229                         }
2230                 }
2231                 if(dr)
2232                         t = nn;
2233                 else
2234                         t = regpair(Z, n);
2235                 //print("dr=%d ", dr); prtree(t, "t");
2236                 c = Z;
2237                 d = Z;
2238                 if(!nodreg(&nod1, t->left, D_AX)) {
2239                         if(t->left->reg != D_AX){
2240                                 t->left->reg = D_AX;
2241                                 reg[D_AX]++;
2242                         }else if(reg[D_AX] == 0)
2243                                 fatal(Z, "vlong mul AX botch");
2244                 }
2245                 if(!nodreg(&nod2, t->right, D_DX)) {
2246                         if(t->right->reg != D_DX){
2247                                 t->right->reg = D_DX;
2248                                 reg[D_DX]++;
2249                         }else if(reg[D_DX] == 0)
2250                                 fatal(Z, "vlong mul DX botch");
2251                 }
2252                 //prtree(t, "t1"); print("reg/ax = %d reg/dx = %d\n", reg[D_AX], reg[D_DX]);
2253                 if(m)
2254                         sugen(l, t, 8);
2255                 else
2256                         loadpair(l, t);
2257                 //prtree(t, "t2"); print("reg/ax = %d reg/dx = %d\n", reg[D_AX], reg[D_DX]);
2258                 if(t->left->reg != D_AX) {
2259                         c = &nod3;
2260                         regsalloc(c, t->left);
2261                         gmove(&nod1, c);
2262                         gmove(t->left, &nod1);
2263                         zapreg(t->left);
2264                 }
2265                 //print("reg/ax = %d reg/dx = %d\n", reg[D_AX], reg[D_DX]);
2266                 if(t->right->reg != D_DX) {
2267                         d = &nod4;
2268                         regsalloc(d, t->right);
2269                         gmove(&nod2, d);
2270                         if(t->right->reg == D_AX && c != nil){
2271                                 /* need previous value of AX in DX */
2272                                 gmove(c, &nod2);
2273                         }else
2274                                 gmove(t->right, &nod2);
2275                         zapreg(t->right);
2276                 }
2277                 if(c != Z || d != Z) {
2278                         s = regpair(Z, n);
2279                         s->left = &nod1;
2280                         s->right = &nod2;
2281                 }
2282                 else
2283                         s = t;
2284                 reg[D_AX]++;    /* don't allow biggen to allocate AX or DX (smashed by MUL) as temp */
2285                 reg[D_DX]++;
2286                 if(r->op == OCONST) {
2287                         if(hi64v(r) == 0)
2288                                 biggen(s, r, Z, 0, mulc32, nil);
2289                         else
2290                                 biggen(s, r, Z, 0, mulc64, nil);
2291                 }
2292                 else
2293                         biggen(s, r, Z, 0, mull, nil);
2294                 instpair(t, Z);
2295                 reg[D_AX]--;
2296                 reg[D_DX]--;
2297                 if(c != Z) {
2298                         gmove(&nod1, t->left);
2299                         gmove(&nod3, &nod1);
2300                 }
2301                 if(d != Z) {
2302                         gmove(&nod2, t->right);
2303                         gmove(&nod4, &nod2);
2304                 }
2305
2306                 if(r->op == OREGPAIR)
2307                         freepair(r);
2308                 if(!m)
2309                         storepair(t, l, 0);
2310                 if(l == &nod5)
2311                         regfree(l);
2312
2313                 if(!dr) {
2314                         if(nn != Z)
2315                                 storepair(t, nn, 1);
2316                         else
2317                                 freepair(t);
2318                 }
2319                 return 1;
2320
2321         case OASADD:
2322                 args = ADDargs;
2323                 goto vasop;
2324         case OASAND:
2325                 args = ANDargs;
2326                 goto vasop;
2327         case OASOR:
2328                 args = ORargs;
2329                 goto vasop;
2330         case OASSUB:
2331                 args = SUBargs;
2332                 goto vasop;
2333         case OASXOR:
2334                 args = XORargs;
2335                 goto vasop;
2336
2337         vasop:
2338                 l = n->left;
2339                 r = n->right;
2340                 dr = nn != Z && nn->op == OREGPAIR;
2341                 m = 0;
2342                 if(l->complex > r->complex) {
2343                         if(!vaddr(l, 1)) {
2344                                 reglcgen(&nod1, l, Z);
2345                                 l = &nod1;
2346                         }
2347                         if(!vaddr(r, 1) || nn != Z || r->op == OCONST) {
2348                                 if(dr)
2349                                         t = nn;
2350                                 else
2351                                         t = regpair(Z, r);
2352                                 sugen(r, t, 8);
2353                                 r = t;
2354                                 m = 1;
2355                         }
2356                 }
2357                 else {
2358                         if(!vaddr(r, 1) || nn != Z || r->op == OCONST) {
2359                                 if(dr)
2360                                         t = nn;
2361                                 else
2362                                         t = regpair(Z, r);
2363                                 sugen(r, t, 8);
2364                                 r = t;
2365                                 m = 1;
2366                         }
2367                         if(!vaddr(l, 1)) {
2368                                 reglcgen(&nod1, l, Z);
2369                                 l = &nod1;
2370                         }
2371                 }
2372                 if(nn != Z) {
2373                         if(n->op == OASSUB)
2374                                 biggen(l, r, Z, 0, sub10, args);
2375                         else
2376                                 biggen(r, l, Z, 0, binoptmp, args);
2377                         storepair(r, l, 0);
2378                 }
2379                 else {
2380                         if(m)
2381                                 biggen(l, r, Z, 0, binop00, args);
2382                         else
2383                                 biggen(l, r, Z, 0, binoptmp, args);
2384                 }
2385                 if(l == &nod1)
2386                         regfree(&nod1);
2387                 if(m) {
2388                         if(nn == Z)
2389                                 freepair(r);
2390                         else if(!dr)
2391                                 storepair(r, nn, 1);
2392                 }
2393                 return 1;
2394
2395         case OASASHL:
2396                 args = nil;
2397                 optab = asshlltab;
2398                 goto assh;
2399         case OASLSHR:
2400                 args = shrlargs;
2401                 optab = asshrltab;
2402                 goto assh;
2403         case OASASHR:
2404                 args = sarlargs;
2405                 optab = asshrltab;
2406                 goto assh;
2407
2408         assh:
2409                 c = Z;
2410                 l = n->left;
2411                 r = n->right;
2412                 if(r->op == OCONST) {
2413                         m = r->vconst & 63;
2414                         if(m < 32)
2415                                 m = SAclo;
2416                         else if(m == 32)
2417                                 m = SAc32;
2418                         else
2419                                 m = SAchi;
2420                 }
2421                 else
2422                         m = SAgen;
2423                 if(l->complex > r->complex) {
2424                         if(!vaddr(l, 0)) {
2425                                 reglcgen(&nod1, l, Z);
2426                                 l = &nod1;
2427                         }
2428                         if(m == SAgen) {
2429                                 t = &nod2;
2430                                 if(l->reg == D_CX) {
2431                                         regalloc(t, r, Z);
2432                                         gmove(l, t);
2433                                         l->reg = t->reg;
2434                                         t->reg = D_CX;
2435                                 }
2436                                 else
2437                                         c = snarfreg(nn, t, D_CX, r, &nod3);
2438                                 cgen(r, t);
2439                                 r = t;
2440                         }
2441                 }
2442                 else {
2443                         if(m == SAgen) {
2444                                 t = &nod2;
2445                                 c = snarfreg(nn, t, D_CX, r, &nod3);
2446                                 cgen(r, t);
2447                                 r = t;
2448                         }
2449                         if(!vaddr(l, 0)) {
2450                                 reglcgen(&nod1, l, Z);
2451                                 l = &nod1;
2452                         }
2453                 }
2454
2455                 if(nn != Z) {
2456                         m += SAdgen - SAgen;
2457                         d = regpair(nn, n);
2458                         instpair(d, Z);
2459                         biggen(l, r, d, 0, optab[m], args);
2460                         if(l == &nod1) {
2461                                 regfree(&nod1);
2462                                 l = Z;
2463                         }
2464                         if(r == &nod2 && c == Z) {
2465                                 regfree(&nod2);
2466                                 r = Z;
2467                         }
2468                         if(d != nn)
2469                                 storepair(d, nn, 1);
2470                 }
2471                 else
2472                         biggen(l, r, Z, 0, optab[m], args);
2473
2474                 if(c != Z) {
2475                         gins(AMOVL, c, r);
2476                         regfree(c);
2477                 }
2478                 if(l == &nod1)
2479                         regfree(&nod1);
2480                 if(r == &nod2)
2481                         regfree(&nod2);
2482                 return 1;
2483
2484         case OPOSTINC:
2485                 args = ADDargs;
2486                 cp = incdecpost;
2487                 goto vinc;
2488         case OPOSTDEC:
2489                 args = SUBargs;
2490                 cp = incdecpost;
2491                 goto vinc;
2492         case OPREINC:
2493                 args = ADDargs;
2494                 cp = incdecpre;
2495                 goto vinc;
2496         case OPREDEC:
2497                 args = SUBargs;
2498                 cp = incdecpre;
2499                 goto vinc;
2500
2501         vinc:
2502                 l = n->left;
2503                 if(!vaddr(l, 1)) {
2504                         reglcgen(&nod1, l, Z);
2505                         l = &nod1;
2506                 }
2507                 
2508                 if(nn != Z) {
2509                         d = regpair(nn, n);
2510                         instpair(d, Z);
2511                         biggen(l, Z, d, 0, cp, args);
2512                         if(l == &nod1) {
2513                                 regfree(&nod1);
2514                                 l = Z;
2515                         }
2516                         if(d != nn)
2517                                 storepair(d, nn, 1);
2518                 }
2519                 else
2520                         biggen(l, Z, Z, 0, incdec, args);
2521
2522                 if(l == &nod1)
2523                         regfree(&nod1);
2524                 return 1;
2525
2526         case OCAST:
2527                 l = n->left;
2528                 if(typev[l->type->etype]) {
2529                         if(!vaddr(l, 1) && l->op != OINDEX) {   // theres no 64 bit indexing
2530                                 if(l->complex + 1 > nn->complex) {
2531                                         d = regpair(Z, l);
2532                                         sugen(l, d, 8);
2533                                         if(!vaddr(nn, 1)) {
2534                                                 reglcgen(&nod1, nn, Z);
2535                                                 r = &nod1;
2536                                         }
2537                                         else
2538                                                 r = nn;
2539                                 }
2540                                 else {
2541                                         if(!vaddr(nn, 1)) {
2542                                                 reglcgen(&nod1, nn, Z);
2543                                                 r = &nod1;
2544                                         }
2545                                         else
2546                                                 r = nn;
2547                                         d = regpair(Z, l);
2548                                         sugen(l, d, 8);
2549                                 }
2550 //                              d->left->type = r->type;
2551                                 d->left->type = types[TLONG];
2552                                 gmove(d->left, r);
2553                                 freepair(d);
2554                         }
2555                         else {
2556                                 if(nn->op != OREGISTER && !vaddr(nn, 1)) {
2557                                         reglcgen(&nod1, nn, Z);
2558                                         r = &nod1;
2559                                 }
2560                                 else
2561                                         r = nn;
2562 //                              l->type = r->type;
2563                                 l->type = types[TLONG];
2564                                 gmove(l, r);
2565                         }
2566                         if(r != nn)
2567                                 regfree(r);
2568                 }
2569                 else {
2570                         if(typeu[l->type->etype] || cond(l->op))
2571                                 si = TUNSIGNED;
2572                         else
2573                                 si = TSIGNED;
2574                         regalloc(&nod1, l, Z);
2575                         cgen(l, &nod1);
2576                         if(nn->op == OREGPAIR) {
2577                                 m = instpair(nn, &nod1);
2578                                 biggen(&nod1, Z, nn, si == TSIGNED, castrp, nil);
2579                         }
2580                         else {
2581                                 m = 0;
2582                                 if(!vaddr(nn, si != TSIGNED)) {
2583                                         dt = nn->type;
2584                                         nn->type = types[TLONG];
2585                                         reglcgen(&nod2, nn, Z);
2586                                         nn->type = dt;
2587                                         nn = &nod2;
2588                                 }
2589                                 dt = nn->type;
2590                                 nn->type = types[TLONG];
2591                                 biggen(&nod1, Z, nn, si == TSIGNED, castrpa, nil);
2592                                 nn->type = dt;
2593                                 if(nn == &nod2)
2594                                         regfree(&nod2);
2595                         }
2596                         if(!m)
2597                                 regfree(&nod1);
2598                 }
2599                 return 1;
2600
2601         default:
2602                 if(n->op == OREGPAIR) {
2603                         storepair(n, nn, 1);
2604                         return 1;
2605                 }
2606                 if(nn->op == OREGPAIR) {
2607                         loadpair(n, nn);
2608                         return 1;
2609                 }
2610                 return 0;
2611         }
2612 finished:
2613         if(d != nn)
2614                 storepair(d, nn, 1);
2615         return 1;
2616 }
2617
2618 void
2619 testv(Node *n, int true)
2620 {
2621         Type *t;
2622         Node *nn, nod, *b;
2623
2624         if(machcap(Z)) {
2625                 b = &nod;
2626                 b->op = true ? ONE : OEQ;
2627                 b->left = n;
2628                 b->right = new(0, Z, Z);
2629                 *b->right = *nodconst(0);
2630                 b->right->type = n->type;
2631                 b->type = types[TLONG];
2632                 cgen64(b, Z);
2633                 return;
2634         }
2635
2636         switch(n->op) {
2637         case OINDREG:
2638         case ONAME:
2639                 biggen(n, Z, Z, true, testi, nil);
2640                 break;
2641
2642         default:
2643                 n = vfunc(n, n);
2644                 if(n->addable >= INDEXED) {
2645                         t = n->type;
2646                         n->type = types[TLONG];
2647                         reglcgen(&nod, n, Z);
2648                         n->type = t;
2649                         n = &nod;
2650                         biggen(n, Z, Z, true, testi, nil);
2651                         if(n == &nod)
2652                                 regfree(n);
2653                 }
2654                 else {
2655                         nn = regpair(Z, n);
2656                         sugen(n, nn, 8);
2657                         biggen(nn, Z, Z, true, testi, nil);
2658                         freepair(nn);
2659                 }
2660         }
2661 }