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) {
142 /* n is not OREGPAIR, nn is */
144 loadpair(Node *n, Node *nn)
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;
157 /* steal the right register for the laddr */
159 nod.reg = nn->right->reg;
165 gins(AMOVL, n, nn->left);
166 n->xoffset += SZ_LONG;
167 gins(AMOVL, n, nn->right);
168 n->xoffset -= SZ_LONG;
171 /* n is OREGPAIR, nn is not */
173 storepair(Node *n, Node *nn, int f)
178 reglcgen(&nod, nn, Z);
181 gins(AMOVL, n->left, nn);
182 nn->xoffset += SZ_LONG;
183 gins(AMOVL, n->right, nn);
184 nn->xoffset -= SZ_LONG;
191 /* generate a cast t from n to tt */
193 cast(Node *n, Type *t, Node *nn)
197 r = new(OCAST, n, Z);
203 swapregs(Node *a, Node *b)
213 swappairs(Node *a, Node *b)
215 swapregs(a->left, b->left);
216 swapregs(a->right, b->right);
225 return r >= D_AX && r <= D_DI;
229 saveit(Node *n, Node *t, Node *r)
236 r->xoffset += SZ_LONG;
238 regalloc(&nod, n, Z);
246 restoreit(Node *n, Node *t, Node *r)
251 r->xoffset += SZ_LONG;
265 whatof(Node *n, int a)
269 return !vaddr(n, a) ? WHARD : WADDR;
272 /* can upgrade an extern to addr for AND */
276 return lo64v(n) == 0 || hi64v(n) == 0;
304 * for a func operand call it and then return
308 vfunc(Node *n, Node *nn)
315 if(nn == Z || nn == nodret)
323 forcereg(Node *d, int r, int o, Node *t)
328 diag(Z, "force alloc");
342 /* try to steal a reg */
344 getreg(Node **np, Node *t, int r)
361 snarfreg(Node *n, Node *t, int r, Node *d, Node *c)
363 if(n == Z || n->op != OREGPAIR || (!getreg(&n->left, t, r) && !getreg(&n->right, t, r))) {
364 if(nodreg(t, Z, r)) {
508 static uchar testi[][VLEN] =
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},
515 {VT, V_p0, V_p1, VF, V_p2},
519 /* shift left general case */
520 static uchar shll00[][VLEN] =
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},
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},
531 /* shift left rp, const < 32 */
532 static uchar shllc0[][VLEN] =
534 {Vinsl, ASHLL, O_r, O_l_rp},
535 {Vshll, O_r, O_l_lo, Vend},
538 /* shift left rp, const == 32 */
539 static uchar shllc1[][VLEN] =
541 {Vins, AMOVL, O_l_lo, O_l_hi},
542 {Vzero, O_l_lo, Vend},
545 /* shift left rp, const > 32 */
546 static uchar shllc2[][VLEN] =
548 {Vshll, O_r, O_l_lo},
549 {Vins, AMOVL, O_l_lo, O_l_hi},
550 {Vzero, O_l_lo, Vend},
553 /* shift left addr, const == 32 */
554 static uchar shllac3[][VLEN] =
556 {Vins, AMOVL, O_l_lo, O_t_hi},
557 {Vzero, O_t_lo, Vend},
560 /* shift left addr, const > 32 */
561 static uchar shllac4[][VLEN] =
563 {Vins, AMOVL, O_l_lo, O_t_hi},
564 {Vshll, O_r, O_t_hi},
565 {Vzero, O_t_lo, Vend},
568 /* shift left of constant */
569 static uchar shll10[][VLEN] =
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},
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},
582 static uchar (*shlltab[])[VLEN] =
593 /* shift right general case */
594 static uchar shrl00[][VLEN] =
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},
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},
607 /* shift right rp, const < 32 */
608 static uchar shrlc0[][VLEN] =
610 {Vinsr, ASHRL, O_r, O_l_rp},
611 {Vins, O_a0, O_r, O_l_hi, Vend},
614 /* shift right rp, const == 32 */
615 static uchar shrlc1[][VLEN] =
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},
623 /* shift right rp, const > 32 */
624 static uchar shrlc2[][VLEN] =
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},
633 /* shift right addr, const == 32 */
634 static uchar shrlac3[][VLEN] =
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},
643 /* shift right addr, const > 32 */
644 static uchar shrlac4[][VLEN] =
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},
654 /* shift right of constant */
655 static uchar shrl10[][VLEN] =
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},
663 {Vins, AMOVL, O_l_hi, O_t_lo},
664 {V_l_hi_t, Vins, O_a0, O_r, O_t_lo},
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},
672 static uchar (*shrltab[])[VLEN] =
683 /* shift asop left general case */
684 static uchar asshllgen[][VLEN] =
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},
695 {Vins, AMOVL, O_l_lo, O_r0},
697 {Vins, ASHLL, O_r, O_r0},
698 {Vins, AMOVL, O_r0, O_l_hi, V_p0},
702 /* shift asop left, const < 32 */
703 static uchar asshllclo[][VLEN] =
706 {Vins, AMOVL, O_l_lo, O_r0},
707 {Vins, AMOVL, O_l_hi, O_r1},
708 {Vinsla, ASHLL, O_r, O_r0},
710 {Vins, AMOVL, O_r1, O_l_hi},
711 {Vins, AMOVL, O_r0, O_l_lo},
715 /* shift asop left, const == 32 */
716 static uchar asshllc32[][VLEN] =
719 {Vins, AMOVL, O_l_lo, O_r0},
721 {Vins, AMOVL, O_r0, O_l_hi},
725 /* shift asop left, const > 32 */
726 static uchar asshllchi[][VLEN] =
729 {Vins, AMOVL, O_l_lo, O_r0},
732 {Vins, AMOVL, O_r0, O_l_hi},
736 /* shift asop dest left general case */
737 static uchar asdshllgen[][VLEN] =
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},
747 {Vins, AMOVL, O_l_lo, O_t_hi},
749 {Vins, ASHLL, O_r, O_t_hi},
751 {Vins, AMOVL, O_t_hi, O_l_hi, V_p0},
755 /* shift asop dest left, const < 32 */
756 static uchar asdshllclo[][VLEN] =
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},
767 /* shift asop dest left, const == 32 */
768 static uchar asdshllc32[][VLEN] =
770 {Vins, AMOVL, O_l_lo, O_t_hi},
772 {Vins, AMOVL, O_t_hi, O_l_hi},
773 {Vins, AMOVL, O_t_lo, O_l_lo},
777 /* shift asop dest, const > 32 */
778 static uchar asdshllchi[][VLEN] =
780 {Vins, AMOVL, O_l_lo, O_t_hi},
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},
788 static uchar (*asshlltab[])[VLEN] =
800 /* shift asop right general case */
801 static uchar asshrlgen[][VLEN] =
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},
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},
821 /* shift asop right, const < 32 */
822 static uchar asshrlclo[][VLEN] =
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},
834 /* shift asop right, const == 32 */
835 static uchar asshrlc32[][VLEN] =
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},
846 /* shift asop right, const > 32 */
847 static uchar asshrlchi[][VLEN] =
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},
859 /* shift asop dest right general case */
860 static uchar asdshrlgen[][VLEN] =
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},
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},
879 /* shift asop dest right, const < 32 */
880 static uchar asdshrlclo[][VLEN] =
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},
891 /* shift asop dest right, const == 32 */
892 static uchar asdshrlc32[][VLEN] =
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},
903 /* shift asop dest, const > 32 */
904 static uchar asdshrlchi[][VLEN] =
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},
918 static uchar (*asshrltab[])[VLEN] =
930 static uchar shrlargs[] = { ASHRL, 1 };
931 static uchar sarlargs[] = { ASARL, 0 };
934 static uchar incdec[][VLEN] =
936 {Vinsx, Bop0, C01, O_l_lo},
937 {Vinsx, Bop1, C00, O_l_hi, Vend},
941 static uchar incdecpre[][VLEN] =
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},
952 static uchar incdecpost[][VLEN] =
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},
961 static uchar binop00[][VLEN] =
963 {Vinsx, Bop0, O_r_lo, O_l_lo},
964 {Vinsx, Bop1, O_r_hi, O_l_hi, Vend},
969 static uchar binoptmp[][VLEN] =
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},
978 /* binop t = *a op *b */
979 static uchar binop11[][VLEN] =
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},
987 /* binop t = rp +- c */
988 static uchar add0c[][VLEN] =
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},
996 /* binop t = rp & c */
997 static uchar and0c[][VLEN] =
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},
1006 /* binop t = rp | c */
1007 static uchar or0c[][VLEN] =
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},
1014 /* binop t = c - rp */
1015 static uchar sub10[][VLEN] =
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},
1024 /* binop t = c + *b */
1025 static uchar addca[][VLEN] =
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},
1035 /* binop t = c & *b */
1036 static uchar andca[][VLEN] =
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},
1047 /* binop t = c | *b */
1048 static uchar orca[][VLEN] =
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},
1057 /* binop t = c - *b */
1058 static uchar subca[][VLEN] =
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},
1067 /* binop t = *a +- c */
1068 static uchar addac[][VLEN] =
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},
1078 /* binop t = *a | c */
1079 static uchar orac[][VLEN] =
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},
1088 /* binop t = *a & c */
1089 static uchar andac[][VLEN] =
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},
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 };
1106 static uchar (*ADDtab[])[VLEN] =
1108 add0c, addca, addac,
1111 static uchar (*ANDtab[])[VLEN] =
1113 and0c, andca, andac,
1116 static uchar (*ORtab[])[VLEN] =
1121 static uchar (*SUBtab[])[VLEN] =
1123 add0c, subca, addac,
1126 /* mul of const32 */
1127 static uchar mulc32[][VLEN] =
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},
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},
1141 /* mul of const64 */
1142 static uchar mulc64[][VLEN] =
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},
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},
1161 static uchar mull[][VLEN] =
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},
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},
1179 /* cast rp l to rp t */
1180 static uchar castrp[][VLEN] =
1183 {VT, Vins, AMOVL, O_t_lo, O_t_hi},
1184 {VT, Vins, ASARL, C31, O_t_hi},
1185 {VF, Vzero, O_t_hi},
1189 /* cast rp l to addr t */
1190 static uchar castrpa[][VLEN] =
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},
1197 {VF, Vmv, O_l, O_t_lo},
1198 {VF, Vzero, O_t_hi},
1202 static uchar netab0i[][VLEN] =
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},
1209 {VT, V_p0, V_p1, VF, V_p2},
1213 static uchar netabii[][VLEN] =
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},
1222 {VT, V_p0, V_p1, VF, V_p2},
1226 static uchar cmptab0i[][VLEN] =
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},
1240 static uchar cmptabii[][VLEN] =
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},
1256 static uchar (*NEtab[])[VLEN] =
1261 static uchar (*cmptab[])[VLEN] =
1266 static uchar GEargs[] = { OGT, OHS };
1267 static uchar GTargs[] = { OGT, OHI };
1268 static uchar HIargs[] = { OHI, OHI };
1269 static uchar HSargs[] = { OHI, OHS };
1273 biggen(Node *l, Node *r, Node *t, int true, uchar code[][VLEN], uchar *a)
1275 int i, j, g, oc, op, lo, ro, to, xo, *xp;
1278 Node *ot, *tl, *tr, tmps[2];
1279 uchar *c, (*cp)[VLEN], args[VARGS];
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");
1294 //print("code %d %d %d %d %d\n", c[0], c[1], c[2], c[3], c[4]);
1310 args[c[i - 1]] = args[c[i - 2]];
1322 case Vspazz: // nasty hack to save a reg in SUB
1325 //print("hi %R lo %R t %R\n", r->right->reg, r->left->reg, tmps[0].reg);
1332 //print("hi %R lo %R t %R\n", r->right->reg, r->left->reg, tmps[0].reg);
1354 gins(c[i - 1], Z, Z);
1395 ot = l; xp = &lo; xo = 0;
1398 ot = l; xp = &lo; xo = SZ_LONG;
1402 ot = r; xp = &ro; xo = 0;
1405 ot = r; xp = &ro; xo = SZ_LONG;
1408 ot = t; xp = &to; xo = 0;
1411 ot = t; xp = &to; xo = SZ_LONG;
1424 ot = &tmps[c[j] - O_r0];
1448 ot->xoffset += xo - *xp;
1455 diag(l, "bad V_lop");
1468 if(op == Vinsx || op == Vopx) {
1469 //print("%d -> %d\n", oc, args[oc]);
1476 oc = args[oc - O_a0];
1482 mulgen(tr->type, tl, tr);
1488 shiftit(tr->type, tl, tr);
1492 gopcode(oc, types[TULONG], tl, tr);
1499 gins(oc, tl, tr->right);
1500 p->from.index = tr->left->reg;
1503 gins(oc, tl, tr->left);
1504 p->from.index = tr->right->reg;
1507 gins(oc, tl, tr + 1);
1508 p->from.index = tr->reg;
1512 p->from.index = (tr + 1)->reg;
1526 case V_T0: case V_T1:
1527 g = args[op - V_T0];
1531 case V_F0: case V_F1:
1532 g = !args[op - V_F0];
1536 case V_C0: case V_C1:
1538 args[op - V_C0] = 0;
1542 case V_S0: case V_S1:
1544 args[op - V_S0] = 1;
1600 case V_a0: case V_a1:
1603 l->type = types[TULONG];
1604 regalloc(&tmps[op - V_a0], l, Z);
1610 case V_f0: case V_f1:
1612 regfree(&tmps[op - V_f0]);
1616 case V_p0: case V_p1: case V_p2: case V_p3: case V_p4:
1618 patch(pr[op - V_p0], pc);
1622 case V_s0: case V_s1: case V_s2: case V_s3: case V_s4:
1629 diag(l, "bad biggen: %d", op);
1632 if(i == VLEN || c[i] == 0)
1646 cgen64(Node *n, Node *nn)
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;
1654 prtree(nn, "cgen64 lhs");
1655 prtree(n, "cgen64");
1656 print("AX = %d\n", reg[D_AX]);
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);
1671 if(!vaddr(n->left, 0) || !vaddr(nn, 0))
1675 sugen(n->left, d, 8);
1676 gins(ANOTL, Z, d->left);
1677 gins(ANOTL, Z, d->right);
1767 dr = nn != Z && nn->op == OREGPAIR;
1768 l = vfunc(n->left, nn);
1772 r = vfunc(n->right, nn);
1774 li = l->op == ONAME || l->op == OINDREG || l->op == OCONST;
1775 ri = r->op == ONAME || r->op == OINDREG || r->op == OCONST;
1777 #define IMM(l, r) ((l) | ((r) << 1))
1781 /* find out what is so easy about some operands */
1783 li = whatof(l, sh | cmp);
1785 ri = whatof(r, cmp);
1793 /* evaluate hard subexps, stealing nn if possible. */
1797 if(l->complex > r->complex) {
1829 if(n->op == OSUB && l->op == OCONST && hi64v(l) == 0) {
1844 #define WW(l, r) ((l) | ((r) << 2))
1847 nn->type = types[TLONG];
1851 biggen(l, r, Z, 0, binop00, args);
1856 diag(r, "bad whatof\n");
1859 biggen(l, r, Z, 0, optab[B0c], args);
1862 reglcgen(&nod2, r, Z);
1866 biggen(l, r, Z, 0, binoptmp, args);
1876 diag(l, "bad whatof\n");
1879 reglcgen(&nod2, l, Z);
1884 biggen(l, r, Z, 0, sub10, args);
1893 diag(l, "bad whatof\n");
1896 biggen(r, l, Z, 0, optab[B0c], args);
1899 reglcgen(&nod2, l, Z);
1903 biggen(r, l, Z, 0, binoptmp, args);
1911 switch(WW(li, ri)) {
1912 case WW(WCONST, WHARD):
1913 if(r->op == ONAME && n->op == OAND && reduxv(l))
1916 case WW(WHARD, WCONST):
1917 if(l->op == ONAME && n->op == OAND && reduxv(r))
1922 reglcgen(&nod3, l, Z);
1926 reglcgen(&nod2, r, 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);
1937 case WW(WADDR, WCONST):
1938 case WW(WHARD, WCONST):
1939 biggen(l, r, d, 0, optab[Bac], args);
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);
1950 diag(r, "bad whatof pair %d %d\n", li, ri);
1971 storepair(l, nn, 1);
1975 storepair(r, nn, 1);
1985 /* evaluate hard subexps, stealing nn if possible. */
1986 /* must also secure CX. not as many optims as binop. */
1990 if(l->complex + 1 > r->complex) {
1998 c = snarfreg(l, t, D_CX, r, &nod2);
2004 c = snarfreg(nn, t, D_CX, r, &nod2);
2035 c = snarfreg(nn, t, D_CX, r, &nod2);
2055 biggen(l, r, Z, 0, optab[S00], args);
2062 diag(r, "bad whatof\n");
2073 biggen(l, s, Z, 0, cp, args);
2081 biggen(l, r, d, 0, optab[S10], args);
2087 switch(WW(li, ri)) {
2088 case WW(WADDR, WCONST):
2100 biggen(l, s, d, 0, cp, args);
2104 diag(r, "bad whatof pair %d %d\n", li, ri);
2124 storepair(l, nn, 1);
2136 /* evaluate hard subexps */
2139 if(l->complex > r->complex) {
2161 op = invrel[relindex(op)];
2211 diag(n, "bad cmp\n");
2217 biggen(l, r, Z, true, optab[T0i], args);
2223 diag(l, "bad whatof\n");
2226 biggen(l, r, Z, true, optab[T0i], args);
2229 reglcgen(&nod2, r, Z);
2233 biggen(l, r, Z, true, optab[T0i], args);
2241 reglcgen(&nod3, l, Z);
2245 reglcgen(&nod2, r, Z);
2248 biggen(l, r, Z, true, optab[Tii], args);
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) {
2290 else if(!vaddr(l, 1)) {
2291 reglcgen(&nod5, l, Z);
2301 if(l->complex <= r->complex && !m && !vaddr(l, 1)) {
2302 reglcgen(&nod5, l, Z);
2313 if(!nodreg(&nod1, t->left, D_AX)) {
2314 if(t->left->reg != D_AX){
2315 t->left->reg = D_AX;
2317 }else if(reg[D_AX] == 0)
2318 fatal(Z, "vlong mul AX botch");
2320 if(!nodreg(&nod2, t->right, D_DX)) {
2321 if(t->right->reg != D_DX){
2322 t->right->reg = D_DX;
2324 }else if(reg[D_DX] == 0)
2325 fatal(Z, "vlong mul DX botch");
2331 if(t->left->reg != D_AX) {
2333 regsalloc(c, t->left);
2335 gmove(t->left, &nod1);
2338 if(t->right->reg != D_DX) {
2340 regsalloc(d, t->right);
2342 gmove(t->right, &nod2);
2345 if(c != Z || d != Z) {
2352 if(r->op == OCONST) {
2354 biggen(s, r, Z, 0, mulc32, nil);
2356 biggen(s, r, Z, 0, mulc64, nil);
2359 biggen(s, r, Z, 0, mull, nil);
2362 gmove(&nod1, t->left);
2363 gmove(&nod3, &nod1);
2366 gmove(&nod2, t->right);
2367 gmove(&nod4, &nod2);
2369 if(r->op == OREGPAIR)
2377 storepair(t, nn, 1);
2402 dr = nn != Z && nn->op == OREGPAIR;
2404 if(l->complex > r->complex) {
2406 reglcgen(&nod1, l, Z);
2409 if(!vaddr(r, 1) || nn != Z || r->op == OCONST) {
2420 if(!vaddr(r, 1) || nn != Z || r->op == OCONST) {
2430 reglcgen(&nod1, l, Z);
2436 biggen(l, r, Z, 0, sub10, args);
2438 biggen(r, l, Z, 0, binoptmp, args);
2443 biggen(l, r, Z, 0, binop00, args);
2445 biggen(l, r, Z, 0, binoptmp, args);
2453 storepair(r, nn, 1);
2474 if(r->op == OCONST) {
2485 if(l->complex > r->complex) {
2487 reglcgen(&nod1, l, Z);
2492 if(l->reg == D_CX) {
2499 c = snarfreg(nn, t, D_CX, r, &nod3);
2507 c = snarfreg(nn, t, D_CX, r, &nod3);
2512 reglcgen(&nod1, l, Z);
2518 m += SAdgen - SAgen;
2521 biggen(l, r, d, 0, optab[m], args);
2526 if(r == &nod2 && c == Z) {
2531 storepair(d, nn, 1);
2534 biggen(l, r, Z, 0, optab[m], args);
2566 reglcgen(&nod1, l, Z);
2573 biggen(l, Z, d, 0, cp, args);
2579 storepair(d, nn, 1);
2582 biggen(l, Z, Z, 0, incdec, args);
2590 if(typev[l->type->etype]) {
2592 if(l->complex + 1 > nn->complex) {
2596 reglcgen(&nod1, nn, Z);
2604 reglcgen(&nod1, nn, Z);
2612 // d->left->type = r->type;
2613 d->left->type = types[TLONG];
2618 if(nn->op != OREGISTER && !vaddr(nn, 1)) {
2619 reglcgen(&nod1, nn, Z);
2624 // l->type = r->type;
2625 l->type = types[TLONG];
2632 if(typeu[l->type->etype] || cond(l->op))
2636 regalloc(&nod1, l, Z);
2638 if(nn->op == OREGPAIR) {
2639 m = instpair(nn, &nod1);
2640 biggen(&nod1, Z, nn, si == TSIGNED, castrp, nil);
2644 if(!vaddr(nn, si != TSIGNED)) {
2646 nn->type = types[TLONG];
2647 reglcgen(&nod2, nn, Z);
2652 nn->type = types[TLONG];
2653 biggen(&nod1, Z, nn, si == TSIGNED, castrpa, nil);
2664 if(n->op == OREGPAIR) {
2665 storepair(n, nn, 1);
2668 if(nn->op == OREGPAIR) {
2676 storepair(d, nn, 1);
2681 testv(Node *n, int true)
2688 b->op = true ? ONE : OEQ;
2690 b->right = new(0, Z, Z);
2691 *b->right = *nodconst(0);
2692 b->right->type = n->type;
2693 b->type = types[TLONG];
2701 biggen(n, Z, Z, true, testi, nil);
2706 if(n->addable >= INDEXED) {
2708 n->type = types[TLONG];
2709 reglcgen(&nod, n, Z);
2712 biggen(n, Z, Z, true, testi, nil);
2719 biggen(nn, Z, Z, true, testi, nil);