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