6 gins(AMOVL, nodconst(0), n);
9 /* do we need to load the address of a vlong? */
17 return !(n->class == CEXTERN || n->class == CGLOBL || n->class == CSTATIC);
30 if(align(0, types[TCHAR], Aarg1)) /* isbigendian */
31 return (long)(n->vconst) & ~0L;
33 return (long)((uvlong)n->vconst>>32) & ~0L;
39 if(align(0, types[TCHAR], Aarg1)) /* isbigendian */
40 return (long)((uvlong)n->vconst>>32) & ~0L;
42 return (long)(n->vconst) & ~0L;
48 return nodconst(hi64v(n));
54 return nodconst(lo64v(n));
62 n = new(OREGISTER, Z, Z);
64 n->type = types[TLONG];
69 regpair(Node *n, Node *t)
73 if(n != Z && n->op == OREGPAIR)
75 r = new(OREGPAIR, anonreg(), anonreg());
88 if(r->reg == D_AX || r->reg == D_DX) {
92 * this is just an optim that should
95 r->type = types[TULONG];
96 regalloc(&nod1, r, Z);
97 nodreg(&nod2, Z, r->reg);
98 gins(AMOVL, &nod2, &nod1);
106 /* lazy instantiation of register pair */
108 instpair(Node *n, Node *l)
113 if(n->left->reg == D_NONE) {
115 n->left->reg = l->reg;
119 regalloc(n->left, n->left, Z);
121 if(n->right->reg == D_NONE)
122 regalloc(n->right, n->right, Z);
129 if(n->reg != D_NONE) {
130 //prtree(n, "zapreg");
143 /* n is not OREGPAIR, nn is */
145 loadpair(Node *n, Node *nn)
150 if(n->op == OCONST) {
151 gins(AMOVL, lo64(n), nn->left);
152 n->xoffset += SZ_LONG;
153 gins(AMOVL, hi64(n), nn->right);
154 n->xoffset -= SZ_LONG;
158 /* steal the right register for the laddr */
160 nod.reg = nn->right->reg;
166 gins(AMOVL, n, nn->left);
167 n->xoffset += SZ_LONG;
168 gins(AMOVL, n, nn->right);
169 n->xoffset -= SZ_LONG;
172 /* n is OREGPAIR, nn is not */
174 storepair(Node *n, Node *nn, int f)
179 reglcgen(&nod, nn, Z);
182 gins(AMOVL, n->left, nn);
183 nn->xoffset += SZ_LONG;
184 gins(AMOVL, n->right, nn);
185 nn->xoffset -= SZ_LONG;
202 whatof(Node *n, int a)
206 return !vaddr(n, a) ? WHARD : WADDR;
209 /* can upgrade an extern to addr for AND */
213 return lo64v(n) == 0 || hi64v(n) == 0;
241 * for a func operand call it and then return
245 vfunc(Node *n, Node *nn)
252 if(nn == Z || nn == nodret)
259 /* try to steal a reg */
261 getreg(Node **np, Node *t, int r)
278 snarfreg(Node *n, Node *t, int r, Node *d, Node *c)
280 if(n == Z || n->op != OREGPAIR || (!getreg(&n->left, t, r) && !getreg(&n->right, t, r))) {
281 if(nodreg(t, Z, r)) {
425 static uchar testi[][VLEN] =
427 {Vop, ONE, O_l_lo, C00},
428 {V_s0, Vop, ONE, O_l_hi, C00},
429 {V_s1, Vgo, V_s2, Vgo, V_s3},
430 {VF, V_p0, V_p1, VT, V_p2},
432 {VT, V_p0, V_p1, VF, V_p2},
436 /* shift left general case */
437 static uchar shll00[][VLEN] =
439 {Vop, OGE, O_r, C32},
440 {V_s0, Vinsl, ASHLL, O_r, O_l_rp},
441 {Vins, ASHLL, O_r, O_l_lo, Vgo},
443 {Vins, ASHLL, O_r, O_l_lo},
444 {Vins, AMOVL, O_l_lo, O_l_hi},
445 {Vzero, O_l_lo, V_p0, Vend},
448 /* shift left rp, const < 32 */
449 static uchar shllc0[][VLEN] =
451 {Vinsl, ASHLL, O_r, O_l_rp},
452 {Vshll, O_r, O_l_lo, Vend},
455 /* shift left rp, const == 32 */
456 static uchar shllc1[][VLEN] =
458 {Vins, AMOVL, O_l_lo, O_l_hi},
459 {Vzero, O_l_lo, Vend},
462 /* shift left rp, const > 32 */
463 static uchar shllc2[][VLEN] =
465 {Vshll, O_r, O_l_lo},
466 {Vins, AMOVL, O_l_lo, O_l_hi},
467 {Vzero, O_l_lo, Vend},
470 /* shift left addr, const == 32 */
471 static uchar shllac3[][VLEN] =
473 {Vins, AMOVL, O_l_lo, O_t_hi},
474 {Vzero, O_t_lo, Vend},
477 /* shift left addr, const > 32 */
478 static uchar shllac4[][VLEN] =
480 {Vins, AMOVL, O_l_lo, O_t_hi},
481 {Vshll, O_r, O_t_hi},
482 {Vzero, O_t_lo, Vend},
485 /* shift left of constant */
486 static uchar shll10[][VLEN] =
488 {Vop, OGE, O_r, C32},
489 {V_s0, Vins, AMOVL, O_l_lo, O_t_lo},
490 {Vins, AMOVL, O_l_hi, O_t_hi},
491 {Vinsl, ASHLL, O_r, O_t_rp},
492 {Vins, ASHLL, O_r, O_t_lo, Vgo},
494 {Vins, AMOVL, O_l_lo, O_t_hi},
495 {V_l_lo_t, Vins, ASHLL, O_r, O_t_hi},
496 {Vzero, O_t_lo, V_p0, Vend},
499 static uchar (*shlltab[])[VLEN] =
510 /* shift right general case */
511 static uchar shrl00[][VLEN] =
513 {Vop, OGE, O_r, C32},
514 {V_s0, Vinsr, ASHRL, O_r, O_l_rp},
515 {Vins, O_a0, O_r, O_l_hi, Vgo},
517 {Vins, O_a0, O_r, O_l_hi},
518 {Vins, AMOVL, O_l_hi, O_l_lo},
519 {V_T1, Vzero, O_l_hi},
520 {V_F1, Vins, ASARL, C31, O_l_hi},
524 /* shift right rp, const < 32 */
525 static uchar shrlc0[][VLEN] =
527 {Vinsr, ASHRL, O_r, O_l_rp},
528 {Vins, O_a0, O_r, O_l_hi, Vend},
531 /* shift right rp, const == 32 */
532 static uchar shrlc1[][VLEN] =
534 {Vins, AMOVL, O_l_hi, O_l_lo},
535 {V_T1, Vzero, O_l_hi},
536 {V_F1, Vins, ASARL, C31, O_l_hi},
540 /* shift right rp, const > 32 */
541 static uchar shrlc2[][VLEN] =
543 {Vins, O_a0, O_r, O_l_hi},
544 {Vins, AMOVL, O_l_hi, O_l_lo},
545 {V_T1, Vzero, O_l_hi},
546 {V_F1, Vins, ASARL, C31, O_l_hi},
550 /* shift right addr, const == 32 */
551 static uchar shrlac3[][VLEN] =
553 {Vins, AMOVL, O_l_hi, O_t_lo},
554 {V_T1, Vzero, O_t_hi},
555 {V_F1, Vins, AMOVL, O_t_lo, O_t_hi},
556 {V_F1, Vins, ASARL, C31, O_t_hi},
560 /* shift right addr, const > 32 */
561 static uchar shrlac4[][VLEN] =
563 {Vins, AMOVL, O_l_hi, O_t_lo},
564 {Vins, O_a0, O_r, O_t_lo},
565 {V_T1, Vzero, O_t_hi},
566 {V_F1, Vins, AMOVL, O_t_lo, O_t_hi},
567 {V_F1, Vins, ASARL, C31, O_t_hi},
571 /* shift right of constant */
572 static uchar shrl10[][VLEN] =
574 {Vop, OGE, O_r, C32},
575 {V_s0, Vins, AMOVL, O_l_lo, O_t_lo},
576 {Vins, AMOVL, O_l_hi, O_t_hi},
577 {Vinsr, ASHRL, O_r, O_t_rp},
578 {Vins, O_a0, O_r, O_t_hi, Vgo},
580 {Vins, AMOVL, O_l_hi, O_t_lo},
581 {V_l_hi_t, Vins, O_a0, O_r, O_t_lo},
583 {V_T1, Vzero, O_t_hi, V_p0},
584 {V_F1, Vins, AMOVL, O_t_lo, O_t_hi},
585 {V_F1, Vins, ASARL, C31, O_t_hi},
589 static uchar (*shrltab[])[VLEN] =
600 /* shift asop left general case */
601 static uchar asshllgen[][VLEN] =
604 {Vop, OGE, O_r, C32},
605 {V_s0, Vins, AMOVL, O_l_lo, O_r0},
606 {Vins, AMOVL, O_l_hi, O_r1},
607 {Vinsla, ASHLL, O_r, O_r0},
608 {Vins, ASHLL, O_r, O_r0},
609 {Vins, AMOVL, O_r1, O_l_hi},
610 {Vins, AMOVL, O_r0, O_l_lo, Vgo},
612 {Vins, AMOVL, O_l_lo, O_r0},
614 {Vins, ASHLL, O_r, O_r0},
615 {Vins, AMOVL, O_r0, O_l_hi, V_p0},
619 /* shift asop left, const < 32 */
620 static uchar asshllclo[][VLEN] =
623 {Vins, AMOVL, O_l_lo, O_r0},
624 {Vins, AMOVL, O_l_hi, O_r1},
625 {Vinsla, ASHLL, O_r, O_r0},
627 {Vins, AMOVL, O_r1, O_l_hi},
628 {Vins, AMOVL, O_r0, O_l_lo},
632 /* shift asop left, const == 32 */
633 static uchar asshllc32[][VLEN] =
636 {Vins, AMOVL, O_l_lo, O_r0},
638 {Vins, AMOVL, O_r0, O_l_hi},
642 /* shift asop left, const > 32 */
643 static uchar asshllchi[][VLEN] =
646 {Vins, AMOVL, O_l_lo, O_r0},
649 {Vins, AMOVL, O_r0, O_l_hi},
653 /* shift asop dest left general case */
654 static uchar asdshllgen[][VLEN] =
656 {Vop, OGE, O_r, C32},
657 {V_s0, Vins, AMOVL, O_l_lo, O_t_lo},
658 {Vins, AMOVL, O_l_hi, O_t_hi},
659 {Vinsl, ASHLL, O_r, O_t_rp},
660 {Vins, ASHLL, O_r, O_t_lo},
661 {Vins, AMOVL, O_t_hi, O_l_hi},
662 {Vins, AMOVL, O_t_lo, O_l_lo, Vgo},
664 {Vins, AMOVL, O_l_lo, O_t_hi},
666 {Vins, ASHLL, O_r, O_t_hi},
668 {Vins, AMOVL, O_t_hi, O_l_hi, V_p0},
672 /* shift asop dest left, const < 32 */
673 static uchar asdshllclo[][VLEN] =
675 {Vins, AMOVL, O_l_lo, O_t_lo},
676 {Vins, AMOVL, O_l_hi, O_t_hi},
677 {Vinsl, ASHLL, O_r, O_t_rp},
678 {Vshll, O_r, O_t_lo},
679 {Vins, AMOVL, O_t_hi, O_l_hi},
680 {Vins, AMOVL, O_t_lo, O_l_lo},
684 /* shift asop dest left, const == 32 */
685 static uchar asdshllc32[][VLEN] =
687 {Vins, AMOVL, O_l_lo, O_t_hi},
689 {Vins, AMOVL, O_t_hi, O_l_hi},
690 {Vins, AMOVL, O_t_lo, O_l_lo},
694 /* shift asop dest, const > 32 */
695 static uchar asdshllchi[][VLEN] =
697 {Vins, AMOVL, O_l_lo, O_t_hi},
699 {Vshll, O_r, O_t_hi},
700 {Vins, AMOVL, O_t_lo, O_l_lo},
701 {Vins, AMOVL, O_t_hi, O_l_hi},
705 static uchar (*asshlltab[])[VLEN] =
717 /* shift asop right general case */
718 static uchar asshrlgen[][VLEN] =
721 {Vop, OGE, O_r, C32},
722 {V_s0, Vins, AMOVL, O_l_lo, O_r0},
723 {Vins, AMOVL, O_l_hi, O_r1},
724 {Vinsra, ASHRL, O_r, O_r0},
725 {Vinsx, Bop0, O_r, O_r1},
726 {Vins, AMOVL, O_r0, O_l_lo},
727 {Vins, AMOVL, O_r1, O_l_hi, Vgo},
729 {Vins, AMOVL, O_l_hi, O_r0},
730 {Vinsx, Bop0, O_r, O_r0},
731 {V_T1, Vzero, O_l_hi},
732 {Vins, AMOVL, O_r0, O_l_lo},
733 {V_F1, Vins, ASARL, C31, O_r0},
734 {V_F1, Vins, AMOVL, O_r0, O_l_hi},
735 {V_p0, V_f0, V_f1, Vend},
738 /* shift asop right, const < 32 */
739 static uchar asshrlclo[][VLEN] =
742 {Vins, AMOVL, O_l_lo, O_r0},
743 {Vins, AMOVL, O_l_hi, O_r1},
744 {Vinsra, ASHRL, O_r, O_r0},
745 {Vinsx, Bop0, O_r, O_r1},
746 {Vins, AMOVL, O_r0, O_l_lo},
747 {Vins, AMOVL, O_r1, O_l_hi},
751 /* shift asop right, const == 32 */
752 static uchar asshrlc32[][VLEN] =
755 {Vins, AMOVL, O_l_hi, O_r0},
756 {V_T1, Vzero, O_l_hi},
757 {Vins, AMOVL, O_r0, O_l_lo},
758 {V_F1, Vins, ASARL, C31, O_r0},
759 {V_F1, Vins, AMOVL, O_r0, O_l_hi},
763 /* shift asop right, const > 32 */
764 static uchar asshrlchi[][VLEN] =
767 {Vins, AMOVL, O_l_hi, O_r0},
768 {V_T1, Vzero, O_l_hi},
769 {Vinsx, Bop0, O_r, O_r0},
770 {Vins, AMOVL, O_r0, O_l_lo},
771 {V_F1, Vins, ASARL, C31, O_r0},
772 {V_F1, Vins, AMOVL, O_r0, O_l_hi},
776 /* shift asop dest right general case */
777 static uchar asdshrlgen[][VLEN] =
779 {Vop, OGE, O_r, C32},
780 {V_s0, Vins, AMOVL, O_l_lo, O_t_lo},
781 {Vins, AMOVL, O_l_hi, O_t_hi},
782 {Vinsr, ASHRL, O_r, O_t_rp},
783 {Vinsx, Bop0, O_r, O_t_hi},
784 {Vins, AMOVL, O_t_lo, O_l_lo},
785 {Vins, AMOVL, O_t_hi, O_l_hi, Vgo},
787 {Vins, AMOVL, O_l_hi, O_t_lo},
788 {V_T1, Vzero, O_t_hi},
789 {Vinsx, Bop0, O_r, O_t_lo},
790 {V_F1, Vins, AMOVL, O_t_lo, O_t_hi},
791 {V_F1, Vins, ASARL, C31, O_t_hi},
792 {Vins, AMOVL, O_t_hi, O_l_hi, V_p0},
796 /* shift asop dest right, const < 32 */
797 static uchar asdshrlclo[][VLEN] =
799 {Vins, AMOVL, O_l_lo, O_t_lo},
800 {Vins, AMOVL, O_l_hi, O_t_hi},
801 {Vinsr, ASHRL, O_r, O_t_rp},
802 {Vinsx, Bop0, O_r, O_t_hi},
803 {Vins, AMOVL, O_t_lo, O_l_lo},
804 {Vins, AMOVL, O_t_hi, O_l_hi},
808 /* shift asop dest right, const == 32 */
809 static uchar asdshrlc32[][VLEN] =
811 {Vins, AMOVL, O_l_hi, O_t_lo},
812 {V_T1, Vzero, O_t_hi},
813 {V_F1, Vins, AMOVL, O_t_lo, O_t_hi},
814 {V_F1, Vins, ASARL, C31, O_t_hi},
815 {Vins, AMOVL, O_t_lo, O_l_lo},
816 {Vins, AMOVL, O_t_hi, O_l_hi},
820 /* shift asop dest, const > 32 */
821 static uchar asdshrlchi[][VLEN] =
823 {Vins, AMOVL, O_l_hi, O_t_lo},
824 {V_T1, Vzero, O_t_hi},
825 {Vinsx, Bop0, O_r, O_t_lo},
826 {V_T1, Vins, AMOVL, O_t_hi, O_l_hi},
827 {V_T1, Vins, AMOVL, O_t_lo, O_l_lo},
828 {V_F1, Vins, AMOVL, O_t_lo, O_t_hi},
829 {V_F1, Vins, ASARL, C31, O_t_hi},
830 {V_F1, Vins, AMOVL, O_t_lo, O_l_lo},
831 {V_F1, Vins, AMOVL, O_t_hi, O_l_hi},
835 static uchar (*asshrltab[])[VLEN] =
847 static uchar shrlargs[] = { ASHRL, 1 };
848 static uchar sarlargs[] = { ASARL, 0 };
851 static uchar incdec[][VLEN] =
853 {Vinsx, Bop0, C01, O_l_lo},
854 {Vinsx, Bop1, C00, O_l_hi, Vend},
858 static uchar incdecpre[][VLEN] =
860 {Vins, AMOVL, O_l_lo, O_t_lo},
861 {Vins, AMOVL, O_l_hi, O_t_hi},
862 {Vinsx, Bop0, C01, O_t_lo},
863 {Vinsx, Bop1, C00, O_t_hi},
864 {Vins, AMOVL, O_t_lo, O_l_lo},
865 {Vins, AMOVL, O_t_hi, O_l_hi, Vend},
869 static uchar incdecpost[][VLEN] =
871 {Vins, AMOVL, O_l_lo, O_t_lo},
872 {Vins, AMOVL, O_l_hi, O_t_hi},
873 {Vinsx, Bop0, C01, O_l_lo},
874 {Vinsx, Bop1, C00, O_l_hi, Vend},
878 static uchar binop00[][VLEN] =
880 {Vinsx, Bop0, O_r_lo, O_l_lo},
881 {Vinsx, Bop1, O_r_hi, O_l_hi, Vend},
886 static uchar binoptmp[][VLEN] =
888 {V_a0, Vins, AMOVL, O_r_lo, O_r0},
889 {Vinsx, Bop0, O_r0, O_l_lo},
890 {Vins, AMOVL, O_r_hi, O_r0},
891 {Vinsx, Bop1, O_r0, O_l_hi},
895 /* binop t = *a op *b */
896 static uchar binop11[][VLEN] =
898 {Vins, AMOVL, O_l_lo, O_t_lo},
899 {Vinsx, Bop0, O_r_lo, O_t_lo},
900 {Vins, AMOVL, O_l_hi, O_t_hi},
901 {Vinsx, Bop1, O_r_hi, O_t_hi, Vend},
904 /* binop t = rp +- c */
905 static uchar add0c[][VLEN] =
907 {V_r_lo_t, Vinsx, Bop0, O_r_lo, O_l_lo},
908 {V_r_lo_f, Vamv, Bop0, Bop1},
909 {Vinsx, Bop1, O_r_hi, O_l_hi},
913 /* binop t = rp & c */
914 static uchar and0c[][VLEN] =
916 {V_r_lo_t, Vinsx, Bop0, O_r_lo, O_l_lo},
917 {V_r_lo_f, Vins, AMOVL, C00, O_l_lo},
918 {V_r_hi_t, Vinsx, Bop1, O_r_hi, O_l_hi},
919 {V_r_hi_f, Vins, AMOVL, C00, O_l_hi},
923 /* binop t = rp | c */
924 static uchar or0c[][VLEN] =
926 {V_r_lo_t, Vinsx, Bop0, O_r_lo, O_l_lo},
927 {V_r_hi_t, Vinsx, Bop1, O_r_hi, O_l_hi},
931 /* binop t = c - rp */
932 static uchar sub10[][VLEN] =
934 {V_a0, Vins, AMOVL, O_l_lo, O_r0},
935 {Vinsx, Bop0, O_r_lo, O_r0},
936 {Vins, AMOVL, O_l_hi, O_r_lo},
937 {Vinsx, Bop1, O_r_hi, O_r_lo},
938 {Vspazz, V_f0, Vend},
941 /* binop t = c + *b */
942 static uchar addca[][VLEN] =
944 {Vins, AMOVL, O_r_lo, O_t_lo},
945 {V_l_lo_t, Vinsx, Bop0, O_l_lo, O_t_lo},
946 {V_l_lo_f, Vamv, Bop0, Bop1},
947 {Vins, AMOVL, O_r_hi, O_t_hi},
948 {Vinsx, Bop1, O_l_hi, O_t_hi},
952 /* binop t = c & *b */
953 static uchar andca[][VLEN] =
955 {V_l_lo_t, Vins, AMOVL, O_r_lo, O_t_lo},
956 {V_l_lo_t, Vinsx, Bop0, O_l_lo, O_t_lo},
957 {V_l_lo_f, Vzero, O_t_lo},
958 {V_l_hi_t, Vins, AMOVL, O_r_hi, O_t_hi},
959 {V_l_hi_t, Vinsx, Bop1, O_l_hi, O_t_hi},
960 {V_l_hi_f, Vzero, O_t_hi},
964 /* binop t = c | *b */
965 static uchar orca[][VLEN] =
967 {Vins, AMOVL, O_r_lo, O_t_lo},
968 {V_l_lo_t, Vinsx, Bop0, O_l_lo, O_t_lo},
969 {Vins, AMOVL, O_r_hi, O_t_hi},
970 {V_l_hi_t, Vinsx, Bop1, O_l_hi, O_t_hi},
974 /* binop t = c - *b */
975 static uchar subca[][VLEN] =
977 {Vins, AMOVL, O_l_lo, O_t_lo},
978 {Vins, AMOVL, O_l_hi, O_t_hi},
979 {Vinsx, Bop0, O_r_lo, O_t_lo},
980 {Vinsx, Bop1, O_r_hi, O_t_hi},
984 /* binop t = *a +- c */
985 static uchar addac[][VLEN] =
987 {Vins, AMOVL, O_l_lo, O_t_lo},
988 {V_r_lo_t, Vinsx, Bop0, O_r_lo, O_t_lo},
989 {V_r_lo_f, Vamv, Bop0, Bop1},
990 {Vins, AMOVL, O_l_hi, O_t_hi},
991 {Vinsx, Bop1, O_r_hi, O_t_hi},
995 /* binop t = *a | c */
996 static uchar orac[][VLEN] =
998 {Vins, AMOVL, O_l_lo, O_t_lo},
999 {V_r_lo_t, Vinsx, Bop0, O_r_lo, O_t_lo},
1000 {Vins, AMOVL, O_l_hi, O_t_hi},
1001 {V_r_hi_t, Vinsx, Bop1, O_r_hi, O_t_hi},
1005 /* binop t = *a & c */
1006 static uchar andac[][VLEN] =
1008 {V_r_lo_t, Vins, AMOVL, O_l_lo, O_t_lo},
1009 {V_r_lo_t, Vinsx, Bop0, O_r_lo, O_t_lo},
1010 {V_r_lo_f, Vzero, O_t_lo},
1011 {V_r_hi_t, Vins, AMOVL, O_l_hi, O_t_hi},
1012 {V_r_hi_t, Vinsx, Bop0, O_r_hi, O_t_hi},
1013 {V_r_hi_f, Vzero, O_t_hi},
1017 static uchar ADDargs[] = { AADDL, AADCL };
1018 static uchar ANDargs[] = { AANDL, AANDL };
1019 static uchar ORargs[] = { AORL, AORL };
1020 static uchar SUBargs[] = { ASUBL, ASBBL };
1021 static uchar XORargs[] = { AXORL, AXORL };
1023 static uchar (*ADDtab[])[VLEN] =
1025 add0c, addca, addac,
1028 static uchar (*ANDtab[])[VLEN] =
1030 and0c, andca, andac,
1033 static uchar (*ORtab[])[VLEN] =
1038 static uchar (*SUBtab[])[VLEN] =
1040 add0c, subca, addac,
1043 /* mul of const32 */
1044 static uchar mulc32[][VLEN] =
1046 {V_a0, Vop, ONE, O_l_hi, C00},
1047 {V_s0, Vins, AMOVL, O_r_lo, O_r0},
1048 {Vins, AMULL, O_r0, O_Zop},
1050 {Vins, AMOVL, O_l_hi, O_r0},
1051 {Vmul, O_r_lo, O_r0},
1052 {Vins, AMOVL, O_r_lo, O_l_hi},
1053 {Vins, AMULL, O_l_hi, O_Zop},
1054 {Vins, AADDL, O_r0, O_l_hi},
1058 /* mul of const64 */
1059 static uchar mulc64[][VLEN] =
1061 {V_a0, Vins, AMOVL, O_r_hi, O_r0},
1062 {Vop, OOR, O_l_hi, O_r0},
1063 {Vop, ONE, O_r0, C00},
1064 {V_s0, Vins, AMOVL, O_r_lo, O_r0},
1065 {Vins, AMULL, O_r0, O_Zop},
1067 {Vmul, O_r_lo, O_l_hi},
1068 {Vins, AMOVL, O_l_lo, O_r0},
1069 {Vmul, O_r_hi, O_r0},
1070 {Vins, AADDL, O_l_hi, O_r0},
1071 {Vins, AMOVL, O_r_lo, O_l_hi},
1072 {Vins, AMULL, O_l_hi, O_Zop},
1073 {Vins, AADDL, O_r0, O_l_hi},
1078 static uchar mull[][VLEN] =
1080 {V_a0, Vins, AMOVL, O_r_hi, O_r0},
1081 {Vop, OOR, O_l_hi, O_r0},
1082 {Vop, ONE, O_r0, C00},
1083 {V_s0, Vins, AMOVL, O_r_lo, O_r0},
1084 {Vins, AMULL, O_r0, O_Zop},
1086 {Vins, AIMULL, O_r_lo, O_l_hi},
1087 {Vins, AMOVL, O_l_lo, O_r0},
1088 {Vins, AIMULL, O_r_hi, O_r0},
1089 {Vins, AADDL, O_l_hi, O_r0},
1090 {Vins, AMOVL, O_r_lo, O_l_hi},
1091 {Vins, AMULL, O_l_hi, O_Zop},
1092 {Vins, AADDL, O_r0, O_l_hi},
1096 /* cast rp l to rp t */
1097 static uchar castrp[][VLEN] =
1100 {VT, Vins, AMOVL, O_t_lo, O_t_hi},
1101 {VT, Vins, ASARL, C31, O_t_hi},
1102 {VF, Vzero, O_t_hi},
1106 /* cast rp l to addr t */
1107 static uchar castrpa[][VLEN] =
1109 {VT, V_a0, Vmv, O_l, O_r0},
1110 {VT, Vins, AMOVL, O_r0, O_t_lo},
1111 {VT, Vins, ASARL, C31, O_r0},
1112 {VT, Vins, AMOVL, O_r0, O_t_hi},
1114 {VF, Vmv, O_l, O_t_lo},
1115 {VF, Vzero, O_t_hi},
1119 static uchar netab0i[][VLEN] =
1121 {Vop, ONE, O_l_lo, O_r_lo},
1122 {V_s0, Vop, ONE, O_l_hi, O_r_hi},
1123 {V_s1, Vgo, V_s2, Vgo, V_s3},
1124 {VF, V_p0, V_p1, VT, V_p2},
1126 {VT, V_p0, V_p1, VF, V_p2},
1130 static uchar netabii[][VLEN] =
1132 {V_a0, Vins, AMOVL, O_l_lo, O_r0},
1133 {Vop, ONE, O_r0, O_r_lo},
1134 {V_s0, Vins, AMOVL, O_l_hi, O_r0},
1135 {Vop, ONE, O_r0, O_r_hi},
1136 {V_s1, Vgo, V_s2, Vgo, V_s3},
1137 {VF, V_p0, V_p1, VT, V_p2},
1139 {VT, V_p0, V_p1, VF, V_p2},
1143 static uchar cmptab0i[][VLEN] =
1145 {Vopx, Bop0, O_l_hi, O_r_hi},
1146 {V_s0, Vins0, AJNE},
1147 {V_s1, Vopx, Bop1, O_l_lo, O_r_lo},
1148 {V_s2, Vgo, V_s3, Vgo, V_s4},
1157 static uchar cmptabii[][VLEN] =
1159 {V_a0, Vins, AMOVL, O_l_hi, O_r0},
1160 {Vopx, Bop0, O_r0, O_r_hi},
1161 {V_s0, Vins0, AJNE},
1162 {V_s1, Vins, AMOVL, O_l_lo, O_r0},
1163 {Vopx, Bop1, O_r0, O_r_lo},
1164 {V_s2, Vgo, V_s3, Vgo, V_s4},
1173 static uchar (*NEtab[])[VLEN] =
1178 static uchar (*cmptab[])[VLEN] =
1183 static uchar GEargs[] = { OGT, OHS };
1184 static uchar GTargs[] = { OGT, OHI };
1185 static uchar HIargs[] = { OHI, OHI };
1186 static uchar HSargs[] = { OHI, OHS };
1190 biggen(Node *l, Node *r, Node *t, int true, uchar code[][VLEN], uchar *a)
1192 int i, j, g, oc, op, lo, ro, to, xo, *xp;
1195 Node *ot, *tl, *tr, tmps[2];
1196 uchar *c, (*cp)[VLEN], args[VARGS];
1199 memmove(args, a, VARGS);
1200 //print("biggen %d %d %d\n", args[0], args[1], args[2]);
1201 //if(l) prtree(l, "l");
1202 //if(r) prtree(r, "r");
1203 //if(t) prtree(t, "t");
1211 //print("code %d %d %d %d %d\n", c[0], c[1], c[2], c[3], c[4]);
1227 args[c[i - 1]] = args[c[i - 2]];
1239 case Vspazz: // nasty hack to save a reg in SUB
1242 //print("hi %R lo %R t %R\n", r->right->reg, r->left->reg, tmps[0].reg);
1249 //print("hi %R lo %R t %R\n", r->right->reg, r->left->reg, tmps[0].reg);
1271 gins(c[i - 1], Z, Z);
1312 ot = l; xp = &lo; xo = 0;
1315 ot = l; xp = &lo; xo = SZ_LONG;
1319 ot = r; xp = &ro; xo = 0;
1322 ot = r; xp = &ro; xo = SZ_LONG;
1325 ot = t; xp = &to; xo = 0;
1328 ot = t; xp = &to; xo = SZ_LONG;
1341 ot = &tmps[c[j] - O_r0];
1365 ot->xoffset += xo - *xp;
1372 diag(l, "bad V_lop");
1385 if(op == Vinsx || op == Vopx) {
1386 //print("%d -> %d\n", oc, args[oc]);
1393 oc = args[oc - O_a0];
1399 mulgen(tr->type, tl, tr);
1405 shiftit(tr->type, tl, tr);
1409 gopcode(oc, types[TULONG], tl, tr);
1416 gins(oc, tl, tr->right);
1417 p->from.index = tr->left->reg;
1420 gins(oc, tl, tr->left);
1421 p->from.index = tr->right->reg;
1424 gins(oc, tl, tr + 1);
1425 p->from.index = tr->reg;
1429 p->from.index = (tr + 1)->reg;
1443 case V_T0: case V_T1:
1444 g = args[op - V_T0];
1448 case V_F0: case V_F1:
1449 g = !args[op - V_F0];
1453 case V_C0: case V_C1:
1455 args[op - V_C0] = 0;
1459 case V_S0: case V_S1:
1461 args[op - V_S0] = 1;
1517 case V_a0: case V_a1:
1520 l->type = types[TULONG];
1521 regalloc(&tmps[op - V_a0], l, Z);
1527 case V_f0: case V_f1:
1529 regfree(&tmps[op - V_f0]);
1533 case V_p0: case V_p1: case V_p2: case V_p3: case V_p4:
1535 patch(pr[op - V_p0], pc);
1539 case V_s0: case V_s1: case V_s2: case V_s3: case V_s4:
1546 diag(l, "bad biggen: %d", op);
1549 if(i == VLEN || c[i] == 0)
1563 cgen64(Node *n, Node *nn)
1566 uchar *args, (*cp)[VLEN], (**optab)[VLEN];
1567 int li, ri, lri, dr, si, m, op, sh, cmp, true;
1568 Node *c, *d, *l, *r, *t, *s, nod1, nod2, nod3, nod4, nod5;
1571 prtree(nn, "cgen64 lhs");
1572 prtree(n, "cgen64");
1573 print("AX = %d\n", reg[D_AX]);
1578 if(nn != Z && nn->complex >= FNX){
1579 reglcgen(&nod1, nn, Z);
1588 sugen(n->left, d, 8);
1589 gins(ANOTL, Z, d->right);
1590 gins(ANEGL, Z, d->left);
1591 gins(ASBBL, nodconst(-1), d->right);
1595 if(!vaddr(n->left, 0) || !vaddr(nn, 0))
1599 sugen(n->left, d, 8);
1600 gins(ANOTL, Z, d->left);
1601 gins(ANOTL, Z, d->right);
1691 dr = nn != Z && nn->op == OREGPAIR;
1692 l = vfunc(n->left, nn);
1696 r = vfunc(n->right, nn);
1698 li = l->op == ONAME || l->op == OINDREG || l->op == OCONST;
1699 ri = r->op == ONAME || r->op == OINDREG || r->op == OCONST;
1701 #define IMM(l, r) ((l) | ((r) << 1))
1705 /* find out what is so easy about some operands */
1707 li = whatof(l, sh | cmp);
1709 ri = whatof(r, cmp);
1717 /* evaluate hard subexps, stealing nn if possible. */
1721 if(l->complex > r->complex) {
1753 if(n->op == OSUB && l->op == OCONST && hi64v(l) == 0) {
1768 #define WW(l, r) ((l) | ((r) << 2))
1771 nn->type = types[TLONG];
1775 biggen(l, r, Z, 0, binop00, args);
1780 diag(r, "bad whatof\n");
1783 biggen(l, r, Z, 0, optab[B0c], args);
1786 reglcgen(&nod2, r, Z);
1790 biggen(l, r, Z, 0, binoptmp, args);
1800 diag(l, "bad whatof\n");
1803 reglcgen(&nod2, l, Z);
1808 biggen(l, r, Z, 0, sub10, args);
1817 diag(l, "bad whatof\n");
1820 biggen(r, l, Z, 0, optab[B0c], args);
1823 reglcgen(&nod2, l, Z);
1827 biggen(r, l, Z, 0, binoptmp, args);
1835 switch(WW(li, ri)) {
1836 case WW(WCONST, WHARD):
1837 if(r->op == ONAME && n->op == OAND && reduxv(l))
1840 case WW(WHARD, WCONST):
1841 if(l->op == ONAME && n->op == OAND && reduxv(r))
1846 reglcgen(&nod3, l, Z);
1850 reglcgen(&nod2, r, Z);
1855 switch(WW(li, ri)) {
1856 case WW(WCONST, WADDR):
1857 case WW(WCONST, WHARD):
1858 biggen(l, r, d, 0, optab[Bca], args);
1861 case WW(WADDR, WCONST):
1862 case WW(WHARD, WCONST):
1863 biggen(l, r, d, 0, optab[Bac], args);
1866 case WW(WADDR, WADDR):
1867 case WW(WADDR, WHARD):
1868 case WW(WHARD, WADDR):
1869 case WW(WHARD, WHARD):
1870 biggen(l, r, d, 0, binop11, args);
1874 diag(r, "bad whatof pair %d %d\n", li, ri);
1895 storepair(l, nn, 1);
1899 storepair(r, nn, 1);
1909 /* evaluate hard subexps, stealing nn if possible. */
1910 /* must also secure CX. not as many optims as binop. */
1914 if(l->complex + 1 > r->complex) {
1922 c = snarfreg(l, t, D_CX, r, &nod2);
1928 c = snarfreg(nn, t, D_CX, r, &nod2);
1959 c = snarfreg(nn, t, D_CX, r, &nod2);
1979 biggen(l, r, Z, 0, optab[S00], args);
1986 diag(r, "bad whatof\n");
1997 biggen(l, s, Z, 0, cp, args);
2005 biggen(l, r, d, 0, optab[S10], args);
2011 switch(WW(li, ri)) {
2012 case WW(WADDR, WCONST):
2024 biggen(l, s, d, 0, cp, args);
2028 diag(r, "bad whatof pair %d %d\n", li, ri);
2048 storepair(l, nn, 1);
2060 /* evaluate hard subexps */
2063 if(l->complex > r->complex) {
2085 op = invrel[relindex(op)];
2135 diag(n, "bad cmp\n");
2141 biggen(l, r, Z, true, optab[T0i], args);
2147 diag(l, "bad whatof\n");
2150 biggen(l, r, Z, true, optab[T0i], args);
2153 reglcgen(&nod2, r, Z);
2157 biggen(l, r, Z, true, optab[T0i], args);
2165 reglcgen(&nod3, l, Z);
2169 reglcgen(&nod2, r, Z);
2172 biggen(l, r, Z, true, optab[Tii], args);
2204 dr = nn != Z && nn->op == OREGPAIR;
2205 l = vfunc(n->left, nn);
2206 r = vfunc(n->right, nn);
2207 if(r->op != OCONST) {
2208 if(l->complex > r->complex) {
2214 else if(!vaddr(l, 1)) {
2215 reglcgen(&nod5, l, Z);
2225 if(l->complex <= r->complex && !m && !vaddr(l, 1)) {
2226 reglcgen(&nod5, l, Z);
2235 //print("dr=%d ", dr); prtree(t, "t");
2238 if(!nodreg(&nod1, t->left, D_AX)) {
2239 if(t->left->reg != D_AX){
2240 t->left->reg = D_AX;
2242 }else if(reg[D_AX] == 0)
2243 fatal(Z, "vlong mul AX botch");
2245 if(!nodreg(&nod2, t->right, D_DX)) {
2246 if(t->right->reg != D_DX){
2247 t->right->reg = D_DX;
2249 }else if(reg[D_DX] == 0)
2250 fatal(Z, "vlong mul DX botch");
2252 //prtree(t, "t1"); print("reg/ax = %d reg/dx = %d\n", reg[D_AX], reg[D_DX]);
2257 //prtree(t, "t2"); print("reg/ax = %d reg/dx = %d\n", reg[D_AX], reg[D_DX]);
2258 if(t->left->reg != D_AX) {
2260 regsalloc(c, t->left);
2262 gmove(t->left, &nod1);
2265 //print("reg/ax = %d reg/dx = %d\n", reg[D_AX], reg[D_DX]);
2266 if(t->right->reg != D_DX) {
2268 regsalloc(d, t->right);
2270 if(t->right->reg == D_AX && c != nil){
2271 /* need previous value of AX in DX */
2274 gmove(t->right, &nod2);
2277 if(c != Z || d != Z) {
2284 reg[D_AX]++; /* don't allow biggen to allocate AX or DX (smashed by MUL) as temp */
2286 if(r->op == OCONST) {
2288 biggen(s, r, Z, 0, mulc32, nil);
2290 biggen(s, r, Z, 0, mulc64, nil);
2293 biggen(s, r, Z, 0, mull, nil);
2298 gmove(&nod1, t->left);
2299 gmove(&nod3, &nod1);
2302 gmove(&nod2, t->right);
2303 gmove(&nod4, &nod2);
2306 if(r->op == OREGPAIR)
2315 storepair(t, nn, 1);
2340 dr = nn != Z && nn->op == OREGPAIR;
2342 if(l->complex > r->complex) {
2344 reglcgen(&nod1, l, Z);
2347 if(!vaddr(r, 1) || nn != Z || r->op == OCONST) {
2358 if(!vaddr(r, 1) || nn != Z || r->op == OCONST) {
2368 reglcgen(&nod1, l, Z);
2374 biggen(l, r, Z, 0, sub10, args);
2376 biggen(r, l, Z, 0, binoptmp, args);
2381 biggen(l, r, Z, 0, binop00, args);
2383 biggen(l, r, Z, 0, binoptmp, args);
2391 storepair(r, nn, 1);
2412 if(r->op == OCONST) {
2423 if(l->complex > r->complex) {
2425 reglcgen(&nod1, l, Z);
2430 if(l->reg == D_CX) {
2437 c = snarfreg(nn, t, D_CX, r, &nod3);
2445 c = snarfreg(nn, t, D_CX, r, &nod3);
2450 reglcgen(&nod1, l, Z);
2456 m += SAdgen - SAgen;
2459 biggen(l, r, d, 0, optab[m], args);
2464 if(r == &nod2 && c == Z) {
2469 storepair(d, nn, 1);
2472 biggen(l, r, Z, 0, optab[m], args);
2504 reglcgen(&nod1, l, Z);
2511 biggen(l, Z, d, 0, cp, args);
2517 storepair(d, nn, 1);
2520 biggen(l, Z, Z, 0, incdec, args);
2528 if(typev[l->type->etype]) {
2529 if(!vaddr(l, 1) && l->op != OINDEX) { // theres no 64 bit indexing
2530 if(l->complex + 1 > nn->complex) {
2534 reglcgen(&nod1, nn, Z);
2542 reglcgen(&nod1, nn, Z);
2550 // d->left->type = r->type;
2551 d->left->type = types[TLONG];
2556 if(nn->op != OREGISTER && !vaddr(nn, 1)) {
2557 reglcgen(&nod1, nn, Z);
2562 // l->type = r->type;
2563 l->type = types[TLONG];
2570 if(typeu[l->type->etype] || cond(l->op))
2574 regalloc(&nod1, l, Z);
2576 if(nn->op == OREGPAIR) {
2577 m = instpair(nn, &nod1);
2578 biggen(&nod1, Z, nn, si == TSIGNED, castrp, nil);
2582 if(!vaddr(nn, si != TSIGNED)) {
2584 nn->type = types[TLONG];
2585 reglcgen(&nod2, nn, Z);
2590 nn->type = types[TLONG];
2591 biggen(&nod1, Z, nn, si == TSIGNED, castrpa, nil);
2602 if(n->op == OREGPAIR) {
2603 storepair(n, nn, 1);
2606 if(nn->op == OREGPAIR) {
2614 storepair(d, nn, 1);
2619 testv(Node *n, int true)
2626 b->op = true ? ONE : OEQ;
2628 b->right = new(0, Z, Z);
2629 *b->right = *nodconst(0);
2630 b->right->type = n->type;
2631 b->type = types[TLONG];
2639 biggen(n, Z, Z, true, testi, nil);
2644 if(n->addable >= INDEXED) {
2646 n->type = types[TLONG];
2647 reglcgen(&nod, n, Z);
2650 biggen(n, Z, Z, true, testi, nil);
2657 biggen(nn, Z, Z, true, testi, nil);