OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <limits.h> // For LONG_MIN, LONG_MAX. | 5 #include <limits.h> // For LONG_MIN, LONG_MAX. |
6 | 6 |
7 #include "src/v8.h" | 7 #include "src/v8.h" |
8 | 8 |
9 #if V8_TARGET_ARCH_MIPS | 9 #if V8_TARGET_ARCH_MIPS |
10 | 10 |
(...skipping 623 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
634 DCHECK(!rs.is(at)); | 634 DCHECK(!rs.is(at)); |
635 li(at, rt); | 635 li(at, rt); |
636 subu(rd, rs, at); | 636 subu(rd, rs, at); |
637 } | 637 } |
638 } | 638 } |
639 } | 639 } |
640 | 640 |
641 | 641 |
642 void MacroAssembler::Mul(Register rd, Register rs, const Operand& rt) { | 642 void MacroAssembler::Mul(Register rd, Register rs, const Operand& rt) { |
643 if (rt.is_reg()) { | 643 if (rt.is_reg()) { |
644 if (IsMipsArchVariant(kLoongson)) { | 644 if (kArchVariant == kLoongson) { |
645 mult(rs, rt.rm()); | 645 mult(rs, rt.rm()); |
646 mflo(rd); | 646 mflo(rd); |
647 } else { | 647 } else { |
648 mul(rd, rs, rt.rm()); | 648 mul(rd, rs, rt.rm()); |
649 } | 649 } |
650 } else { | 650 } else { |
651 // li handles the relocation. | 651 // li handles the relocation. |
652 DCHECK(!rs.is(at)); | 652 DCHECK(!rs.is(at)); |
653 li(at, rt); | 653 li(at, rt); |
654 if (IsMipsArchVariant(kLoongson)) { | 654 if (kArchVariant == kLoongson) { |
655 mult(rs, at); | 655 mult(rs, at); |
656 mflo(rd); | 656 mflo(rd); |
657 } else { | 657 } else { |
658 mul(rd, rs, at); | 658 mul(rd, rs, at); |
659 } | 659 } |
660 } | 660 } |
661 } | 661 } |
662 | 662 |
663 | 663 |
664 void MacroAssembler::Mul(Register rd_hi, Register rd_lo, | |
665 Register rs, const Operand& rt) { | |
666 if (rt.is_reg()) { | |
667 if (!IsMipsArchVariant(kMips32r6)) { | |
668 mult(rs, rt.rm()); | |
669 mflo(rd_lo); | |
670 mfhi(rd_hi); | |
671 } else { | |
672 if (rd_lo.is(rs)) { | |
673 DCHECK(!rd_hi.is(rs)); | |
674 DCHECK(!rd_hi.is(rt.rm()) && !rd_lo.is(rt.rm())); | |
675 muh(rd_hi, rs, rt.rm()); | |
676 mul(rd_lo, rs, rt.rm()); | |
677 } else { | |
678 DCHECK(!rd_hi.is(rt.rm()) && !rd_lo.is(rt.rm())); | |
679 mul(rd_lo, rs, rt.rm()); | |
680 muh(rd_hi, rs, rt.rm()); | |
681 } | |
682 } | |
683 } else { | |
684 // li handles the relocation. | |
685 DCHECK(!rs.is(at)); | |
686 li(at, rt); | |
687 if (!IsMipsArchVariant(kMips32r6)) { | |
688 mult(rs, at); | |
689 mflo(rd_lo); | |
690 mfhi(rd_hi); | |
691 } else { | |
692 if (rd_lo.is(rs)) { | |
693 DCHECK(!rd_hi.is(rs)); | |
694 DCHECK(!rd_hi.is(at) && !rd_lo.is(at)); | |
695 muh(rd_hi, rs, at); | |
696 mul(rd_lo, rs, at); | |
697 } else { | |
698 DCHECK(!rd_hi.is(at) && !rd_lo.is(at)); | |
699 mul(rd_lo, rs, at); | |
700 muh(rd_hi, rs, at); | |
701 } | |
702 } | |
703 } | |
704 } | |
705 | |
706 | |
707 void MacroAssembler::Mulh(Register rd, Register rs, const Operand& rt) { | |
708 if (rt.is_reg()) { | |
709 if (!IsMipsArchVariant(kMips32r6)) { | |
710 mult(rs, rt.rm()); | |
711 mfhi(rd); | |
712 } else { | |
713 muh(rd, rs, rt.rm()); | |
714 } | |
715 } else { | |
716 // li handles the relocation. | |
717 DCHECK(!rs.is(at)); | |
718 li(at, rt); | |
719 if (!IsMipsArchVariant(kMips32r6)) { | |
720 mult(rs, at); | |
721 mfhi(rd); | |
722 } else { | |
723 muh(rd, rs, at); | |
724 } | |
725 } | |
726 } | |
727 | |
728 | |
729 void MacroAssembler::Mult(Register rs, const Operand& rt) { | 664 void MacroAssembler::Mult(Register rs, const Operand& rt) { |
730 if (rt.is_reg()) { | 665 if (rt.is_reg()) { |
731 mult(rs, rt.rm()); | 666 mult(rs, rt.rm()); |
732 } else { | 667 } else { |
733 // li handles the relocation. | 668 // li handles the relocation. |
734 DCHECK(!rs.is(at)); | 669 DCHECK(!rs.is(at)); |
735 li(at, rt); | 670 li(at, rt); |
736 mult(rs, at); | 671 mult(rs, at); |
737 } | 672 } |
738 } | 673 } |
(...skipping 16 matching lines...) Expand all Loading... |
755 div(rs, rt.rm()); | 690 div(rs, rt.rm()); |
756 } else { | 691 } else { |
757 // li handles the relocation. | 692 // li handles the relocation. |
758 DCHECK(!rs.is(at)); | 693 DCHECK(!rs.is(at)); |
759 li(at, rt); | 694 li(at, rt); |
760 div(rs, at); | 695 div(rs, at); |
761 } | 696 } |
762 } | 697 } |
763 | 698 |
764 | 699 |
765 void MacroAssembler::Div(Register rem, Register res, | |
766 Register rs, const Operand& rt) { | |
767 if (rt.is_reg()) { | |
768 if (!IsMipsArchVariant(kMips32r6)) { | |
769 div(rs, rt.rm()); | |
770 mflo(res); | |
771 mfhi(rem); | |
772 } else { | |
773 div(res, rs, rt.rm()); | |
774 mod(rem, rs, rt.rm()); | |
775 } | |
776 } else { | |
777 // li handles the relocation. | |
778 DCHECK(!rs.is(at)); | |
779 li(at, rt); | |
780 if (!IsMipsArchVariant(kMips32r6)) { | |
781 div(rs, at); | |
782 mflo(res); | |
783 mfhi(rem); | |
784 } else { | |
785 div(res, rs, at); | |
786 mod(rem, rs, at); | |
787 } | |
788 } | |
789 } | |
790 | |
791 | |
792 void MacroAssembler::Mod(Register rd, Register rs, const Operand& rt) { | |
793 if (rt.is_reg()) { | |
794 if (!IsMipsArchVariant(kMips32r6)) { | |
795 div(rs, rt.rm()); | |
796 mfhi(rd); | |
797 } else { | |
798 mod(rd, rs, rt.rm()); | |
799 } | |
800 } else { | |
801 // li handles the relocation. | |
802 DCHECK(!rs.is(at)); | |
803 li(at, rt); | |
804 if (!IsMipsArchVariant(kMips32r6)) { | |
805 div(rs, at); | |
806 mfhi(rd); | |
807 } else { | |
808 mod(rd, rs, at); | |
809 } | |
810 } | |
811 } | |
812 | |
813 | |
814 void MacroAssembler::Divu(Register rs, const Operand& rt) { | 700 void MacroAssembler::Divu(Register rs, const Operand& rt) { |
815 if (rt.is_reg()) { | 701 if (rt.is_reg()) { |
816 divu(rs, rt.rm()); | 702 divu(rs, rt.rm()); |
817 } else { | 703 } else { |
818 // li handles the relocation. | 704 // li handles the relocation. |
819 DCHECK(!rs.is(at)); | 705 DCHECK(!rs.is(at)); |
820 li(at, rt); | 706 li(at, rt); |
821 divu(rs, at); | 707 divu(rs, at); |
822 } | 708 } |
823 } | 709 } |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
918 // li handles the relocation. | 804 // li handles the relocation. |
919 DCHECK(!rs.is(at)); | 805 DCHECK(!rs.is(at)); |
920 li(at, rt); | 806 li(at, rt); |
921 sltu(rd, rs, at); | 807 sltu(rd, rs, at); |
922 } | 808 } |
923 } | 809 } |
924 } | 810 } |
925 | 811 |
926 | 812 |
927 void MacroAssembler::Ror(Register rd, Register rs, const Operand& rt) { | 813 void MacroAssembler::Ror(Register rd, Register rs, const Operand& rt) { |
928 if (IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) { | 814 if (kArchVariant == kMips32r2) { |
929 if (rt.is_reg()) { | 815 if (rt.is_reg()) { |
930 rotrv(rd, rs, rt.rm()); | 816 rotrv(rd, rs, rt.rm()); |
931 } else { | 817 } else { |
932 rotr(rd, rs, rt.imm32_); | 818 rotr(rd, rs, rt.imm32_); |
933 } | 819 } |
934 } else { | 820 } else { |
935 if (rt.is_reg()) { | 821 if (rt.is_reg()) { |
936 subu(at, zero_reg, rt.rm()); | 822 subu(at, zero_reg, rt.rm()); |
937 sllv(at, rs, at); | 823 sllv(at, rs, at); |
938 srlv(rd, rs, rt.rm()); | 824 srlv(rd, rs, rt.rm()); |
939 or_(rd, rd, at); | 825 or_(rd, rd, at); |
940 } else { | 826 } else { |
941 if (rt.imm32_ == 0) { | 827 if (rt.imm32_ == 0) { |
942 srl(rd, rs, 0); | 828 srl(rd, rs, 0); |
943 } else { | 829 } else { |
944 srl(at, rs, rt.imm32_); | 830 srl(at, rs, rt.imm32_); |
945 sll(rd, rs, (0x20 - rt.imm32_) & 0x1f); | 831 sll(rd, rs, (0x20 - rt.imm32_) & 0x1f); |
946 or_(rd, rd, at); | 832 or_(rd, rd, at); |
947 } | 833 } |
948 } | 834 } |
949 } | 835 } |
950 } | 836 } |
951 | 837 |
952 | 838 |
953 void MacroAssembler::Pref(int32_t hint, const MemOperand& rs) { | 839 void MacroAssembler::Pref(int32_t hint, const MemOperand& rs) { |
954 if (IsMipsArchVariant(kLoongson)) { | 840 if (kArchVariant == kLoongson) { |
955 lw(zero_reg, rs); | 841 lw(zero_reg, rs); |
956 } else { | 842 } else { |
957 pref(hint, rs); | 843 pref(hint, rs); |
958 } | 844 } |
959 } | 845 } |
960 | 846 |
961 | 847 |
962 // ------------Pseudo-instructions------------- | 848 // ------------Pseudo-instructions------------- |
963 | 849 |
964 void MacroAssembler::Ulw(Register rd, const MemOperand& rs) { | 850 void MacroAssembler::Ulw(Register rd, const MemOperand& rs) { |
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1140 } | 1026 } |
1141 | 1027 |
1142 | 1028 |
1143 void MacroAssembler::Ext(Register rt, | 1029 void MacroAssembler::Ext(Register rt, |
1144 Register rs, | 1030 Register rs, |
1145 uint16_t pos, | 1031 uint16_t pos, |
1146 uint16_t size) { | 1032 uint16_t size) { |
1147 DCHECK(pos < 32); | 1033 DCHECK(pos < 32); |
1148 DCHECK(pos + size < 33); | 1034 DCHECK(pos + size < 33); |
1149 | 1035 |
1150 if (IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) { | 1036 if (kArchVariant == kMips32r2) { |
1151 ext_(rt, rs, pos, size); | 1037 ext_(rt, rs, pos, size); |
1152 } else { | 1038 } else { |
1153 // Move rs to rt and shift it left then right to get the | 1039 // Move rs to rt and shift it left then right to get the |
1154 // desired bitfield on the right side and zeroes on the left. | 1040 // desired bitfield on the right side and zeroes on the left. |
1155 int shift_left = 32 - (pos + size); | 1041 int shift_left = 32 - (pos + size); |
1156 sll(rt, rs, shift_left); // Acts as a move if shift_left == 0. | 1042 sll(rt, rs, shift_left); // Acts as a move if shift_left == 0. |
1157 | 1043 |
1158 int shift_right = 32 - size; | 1044 int shift_right = 32 - size; |
1159 if (shift_right > 0) { | 1045 if (shift_right > 0) { |
1160 srl(rt, rt, shift_right); | 1046 srl(rt, rt, shift_right); |
1161 } | 1047 } |
1162 } | 1048 } |
1163 } | 1049 } |
1164 | 1050 |
1165 | 1051 |
1166 void MacroAssembler::Ins(Register rt, | 1052 void MacroAssembler::Ins(Register rt, |
1167 Register rs, | 1053 Register rs, |
1168 uint16_t pos, | 1054 uint16_t pos, |
1169 uint16_t size) { | 1055 uint16_t size) { |
1170 DCHECK(pos < 32); | 1056 DCHECK(pos < 32); |
1171 DCHECK(pos + size <= 32); | 1057 DCHECK(pos + size <= 32); |
1172 DCHECK(size != 0); | 1058 DCHECK(size != 0); |
1173 | 1059 |
1174 if (IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) { | 1060 if (kArchVariant == kMips32r2) { |
1175 ins_(rt, rs, pos, size); | 1061 ins_(rt, rs, pos, size); |
1176 } else { | 1062 } else { |
1177 DCHECK(!rt.is(t8) && !rs.is(t8)); | 1063 DCHECK(!rt.is(t8) && !rs.is(t8)); |
1178 Subu(at, zero_reg, Operand(1)); | 1064 Subu(at, zero_reg, Operand(1)); |
1179 srl(at, at, 32 - size); | 1065 srl(at, at, 32 - size); |
1180 and_(t8, rs, at); | 1066 and_(t8, rs, at); |
1181 sll(t8, t8, pos); | 1067 sll(t8, t8, pos); |
1182 sll(at, at, pos); | 1068 sll(at, at, pos); |
1183 nor(at, at, zero_reg); | 1069 nor(at, at, zero_reg); |
1184 and_(at, rt, at); | 1070 and_(at, rt, at); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1218 cvt_d_w(fd, fd); | 1104 cvt_d_w(fd, fd); |
1219 | 1105 |
1220 Label conversion_done; | 1106 Label conversion_done; |
1221 | 1107 |
1222 // If rs's MSB was 0, it's done. | 1108 // If rs's MSB was 0, it's done. |
1223 // Otherwise we need to add that to the FP register. | 1109 // Otherwise we need to add that to the FP register. |
1224 Branch(&conversion_done, eq, t9, Operand(zero_reg)); | 1110 Branch(&conversion_done, eq, t9, Operand(zero_reg)); |
1225 | 1111 |
1226 // Load 2^31 into f20 as its float representation. | 1112 // Load 2^31 into f20 as its float representation. |
1227 li(at, 0x41E00000); | 1113 li(at, 0x41E00000); |
| 1114 mtc1(at, FPURegister::from_code(scratch.code() + 1)); |
1228 mtc1(zero_reg, scratch); | 1115 mtc1(zero_reg, scratch); |
1229 Mthc1(at, scratch); | |
1230 // Add it to fd. | 1116 // Add it to fd. |
1231 add_d(fd, fd, scratch); | 1117 add_d(fd, fd, scratch); |
1232 | 1118 |
1233 bind(&conversion_done); | 1119 bind(&conversion_done); |
1234 } | 1120 } |
1235 | 1121 |
1236 | 1122 |
1237 void MacroAssembler::Trunc_uw_d(FPURegister fd, | 1123 void MacroAssembler::Trunc_uw_d(FPURegister fd, |
1238 FPURegister fs, | 1124 FPURegister fs, |
1239 FPURegister scratch) { | 1125 FPURegister scratch) { |
1240 Trunc_uw_d(fs, t8, scratch); | 1126 Trunc_uw_d(fs, t8, scratch); |
1241 mtc1(t8, fd); | 1127 mtc1(t8, fd); |
1242 } | 1128 } |
1243 | 1129 |
1244 | 1130 |
1245 void MacroAssembler::Trunc_w_d(FPURegister fd, FPURegister fs) { | 1131 void MacroAssembler::Trunc_w_d(FPURegister fd, FPURegister fs) { |
1246 if (IsMipsArchVariant(kLoongson) && fd.is(fs)) { | 1132 if (kArchVariant == kLoongson && fd.is(fs)) { |
1247 Mfhc1(t8, fs); | 1133 mfc1(t8, FPURegister::from_code(fs.code() + 1)); |
1248 trunc_w_d(fd, fs); | 1134 trunc_w_d(fd, fs); |
1249 Mthc1(t8, fs); | 1135 mtc1(t8, FPURegister::from_code(fs.code() + 1)); |
1250 } else { | 1136 } else { |
1251 trunc_w_d(fd, fs); | 1137 trunc_w_d(fd, fs); |
1252 } | 1138 } |
1253 } | 1139 } |
1254 | 1140 |
1255 | 1141 |
1256 void MacroAssembler::Round_w_d(FPURegister fd, FPURegister fs) { | 1142 void MacroAssembler::Round_w_d(FPURegister fd, FPURegister fs) { |
1257 if (IsMipsArchVariant(kLoongson) && fd.is(fs)) { | 1143 if (kArchVariant == kLoongson && fd.is(fs)) { |
1258 Mfhc1(t8, fs); | 1144 mfc1(t8, FPURegister::from_code(fs.code() + 1)); |
1259 round_w_d(fd, fs); | 1145 round_w_d(fd, fs); |
1260 Mthc1(t8, fs); | 1146 mtc1(t8, FPURegister::from_code(fs.code() + 1)); |
1261 } else { | 1147 } else { |
1262 round_w_d(fd, fs); | 1148 round_w_d(fd, fs); |
1263 } | 1149 } |
1264 } | 1150 } |
1265 | 1151 |
1266 | 1152 |
1267 void MacroAssembler::Floor_w_d(FPURegister fd, FPURegister fs) { | 1153 void MacroAssembler::Floor_w_d(FPURegister fd, FPURegister fs) { |
1268 if (IsMipsArchVariant(kLoongson) && fd.is(fs)) { | 1154 if (kArchVariant == kLoongson && fd.is(fs)) { |
1269 Mfhc1(t8, fs); | 1155 mfc1(t8, FPURegister::from_code(fs.code() + 1)); |
1270 floor_w_d(fd, fs); | 1156 floor_w_d(fd, fs); |
1271 Mthc1(t8, fs); | 1157 mtc1(t8, FPURegister::from_code(fs.code() + 1)); |
1272 } else { | 1158 } else { |
1273 floor_w_d(fd, fs); | 1159 floor_w_d(fd, fs); |
1274 } | 1160 } |
1275 } | 1161 } |
1276 | 1162 |
1277 | 1163 |
1278 void MacroAssembler::Ceil_w_d(FPURegister fd, FPURegister fs) { | 1164 void MacroAssembler::Ceil_w_d(FPURegister fd, FPURegister fs) { |
1279 if (IsMipsArchVariant(kLoongson) && fd.is(fs)) { | 1165 if (kArchVariant == kLoongson && fd.is(fs)) { |
1280 Mfhc1(t8, fs); | 1166 mfc1(t8, FPURegister::from_code(fs.code() + 1)); |
1281 ceil_w_d(fd, fs); | 1167 ceil_w_d(fd, fs); |
1282 Mthc1(t8, fs); | 1168 mtc1(t8, FPURegister::from_code(fs.code() + 1)); |
1283 } else { | 1169 } else { |
1284 ceil_w_d(fd, fs); | 1170 ceil_w_d(fd, fs); |
1285 } | 1171 } |
1286 } | 1172 } |
1287 | 1173 |
1288 | 1174 |
1289 void MacroAssembler::Trunc_uw_d(FPURegister fd, | 1175 void MacroAssembler::Trunc_uw_d(FPURegister fd, |
1290 Register rs, | 1176 Register rs, |
1291 FPURegister scratch) { | 1177 FPURegister scratch) { |
1292 DCHECK(!fd.is(scratch)); | 1178 DCHECK(!fd.is(scratch)); |
1293 DCHECK(!rs.is(at)); | 1179 DCHECK(!rs.is(at)); |
1294 | 1180 |
1295 // Load 2^31 into scratch as its float representation. | 1181 // Load 2^31 into scratch as its float representation. |
1296 li(at, 0x41E00000); | 1182 li(at, 0x41E00000); |
| 1183 mtc1(at, FPURegister::from_code(scratch.code() + 1)); |
1297 mtc1(zero_reg, scratch); | 1184 mtc1(zero_reg, scratch); |
1298 Mthc1(at, scratch); | |
1299 // Test if scratch > fd. | 1185 // Test if scratch > fd. |
1300 // If fd < 2^31 we can convert it normally. | 1186 // If fd < 2^31 we can convert it normally. |
1301 Label simple_convert; | 1187 Label simple_convert; |
1302 BranchF(&simple_convert, NULL, lt, fd, scratch); | 1188 BranchF(&simple_convert, NULL, lt, fd, scratch); |
1303 | 1189 |
1304 // First we subtract 2^31 from fd, then trunc it to rs | 1190 // First we subtract 2^31 from fd, then trunc it to rs |
1305 // and add 2^31 to rs. | 1191 // and add 2^31 to rs. |
1306 sub_d(scratch, fd, scratch); | 1192 sub_d(scratch, fd, scratch); |
1307 trunc_w_d(scratch, scratch); | 1193 trunc_w_d(scratch, scratch); |
1308 mfc1(rs, scratch); | 1194 mfc1(rs, scratch); |
1309 Or(rs, rs, 1 << 31); | 1195 Or(rs, rs, 1 << 31); |
1310 | 1196 |
1311 Label done; | 1197 Label done; |
1312 Branch(&done); | 1198 Branch(&done); |
1313 // Simple conversion. | 1199 // Simple conversion. |
1314 bind(&simple_convert); | 1200 bind(&simple_convert); |
1315 trunc_w_d(scratch, fd); | 1201 trunc_w_d(scratch, fd); |
1316 mfc1(rs, scratch); | 1202 mfc1(rs, scratch); |
1317 | 1203 |
1318 bind(&done); | 1204 bind(&done); |
1319 } | 1205 } |
1320 | 1206 |
1321 | 1207 |
1322 void MacroAssembler::Mthc1(Register rt, FPURegister fs) { | |
1323 if (IsFp64Mode()) { | |
1324 mthc1(rt, fs); | |
1325 } else { | |
1326 mtc1(rt, fs.high()); | |
1327 } | |
1328 } | |
1329 | |
1330 | |
1331 void MacroAssembler::Mfhc1(Register rt, FPURegister fs) { | |
1332 if (IsFp64Mode()) { | |
1333 mfhc1(rt, fs); | |
1334 } else { | |
1335 mfc1(rt, fs.high()); | |
1336 } | |
1337 } | |
1338 | |
1339 | |
1340 void MacroAssembler::BranchF(Label* target, | 1208 void MacroAssembler::BranchF(Label* target, |
1341 Label* nan, | 1209 Label* nan, |
1342 Condition cc, | 1210 Condition cc, |
1343 FPURegister cmp1, | 1211 FPURegister cmp1, |
1344 FPURegister cmp2, | 1212 FPURegister cmp2, |
1345 BranchDelaySlot bd) { | 1213 BranchDelaySlot bd) { |
1346 BlockTrampolinePoolScope block_trampoline_pool(this); | 1214 BlockTrampolinePoolScope block_trampoline_pool(this); |
1347 if (cc == al) { | 1215 if (cc == al) { |
1348 Branch(bd, target); | 1216 Branch(bd, target); |
1349 return; | 1217 return; |
1350 } | 1218 } |
1351 | 1219 |
1352 DCHECK(nan || target); | 1220 DCHECK(nan || target); |
1353 // Check for unordered (NaN) cases. | 1221 // Check for unordered (NaN) cases. |
1354 if (nan) { | 1222 if (nan) { |
1355 if (!IsMipsArchVariant(kMips32r6)) { | 1223 c(UN, D, cmp1, cmp2); |
1356 c(UN, D, cmp1, cmp2); | 1224 bc1t(nan); |
1357 bc1t(nan); | 1225 } |
1358 } else { | 1226 |
1359 // Use kDoubleCompareReg for comparison result. It has to be unavailable | 1227 if (target) { |
1360 // to lithium register allocator. | 1228 // Here NaN cases were either handled by this function or are assumed to |
1361 DCHECK(!cmp1.is(kDoubleCompareReg) && !cmp2.is(kDoubleCompareReg)); | 1229 // have been handled by the caller. |
1362 cmp(UN, L, kDoubleCompareReg, cmp1, cmp2); | 1230 // Unsigned conditions are treated as their signed counterpart. |
1363 bc1nez(nan, kDoubleCompareReg); | 1231 switch (cc) { |
| 1232 case lt: |
| 1233 c(OLT, D, cmp1, cmp2); |
| 1234 bc1t(target); |
| 1235 break; |
| 1236 case gt: |
| 1237 c(ULE, D, cmp1, cmp2); |
| 1238 bc1f(target); |
| 1239 break; |
| 1240 case ge: |
| 1241 c(ULT, D, cmp1, cmp2); |
| 1242 bc1f(target); |
| 1243 break; |
| 1244 case le: |
| 1245 c(OLE, D, cmp1, cmp2); |
| 1246 bc1t(target); |
| 1247 break; |
| 1248 case eq: |
| 1249 c(EQ, D, cmp1, cmp2); |
| 1250 bc1t(target); |
| 1251 break; |
| 1252 case ueq: |
| 1253 c(UEQ, D, cmp1, cmp2); |
| 1254 bc1t(target); |
| 1255 break; |
| 1256 case ne: |
| 1257 c(EQ, D, cmp1, cmp2); |
| 1258 bc1f(target); |
| 1259 break; |
| 1260 case nue: |
| 1261 c(UEQ, D, cmp1, cmp2); |
| 1262 bc1f(target); |
| 1263 break; |
| 1264 default: |
| 1265 CHECK(0); |
1364 } | 1266 } |
1365 } | 1267 } |
1366 | 1268 |
1367 if (!IsMipsArchVariant(kMips32r6)) { | |
1368 if (target) { | |
1369 // Here NaN cases were either handled by this function or are assumed to | |
1370 // have been handled by the caller. | |
1371 switch (cc) { | |
1372 case lt: | |
1373 c(OLT, D, cmp1, cmp2); | |
1374 bc1t(target); | |
1375 break; | |
1376 case gt: | |
1377 c(ULE, D, cmp1, cmp2); | |
1378 bc1f(target); | |
1379 break; | |
1380 case ge: | |
1381 c(ULT, D, cmp1, cmp2); | |
1382 bc1f(target); | |
1383 break; | |
1384 case le: | |
1385 c(OLE, D, cmp1, cmp2); | |
1386 bc1t(target); | |
1387 break; | |
1388 case eq: | |
1389 c(EQ, D, cmp1, cmp2); | |
1390 bc1t(target); | |
1391 break; | |
1392 case ueq: | |
1393 c(UEQ, D, cmp1, cmp2); | |
1394 bc1t(target); | |
1395 break; | |
1396 case ne: | |
1397 c(EQ, D, cmp1, cmp2); | |
1398 bc1f(target); | |
1399 break; | |
1400 case nue: | |
1401 c(UEQ, D, cmp1, cmp2); | |
1402 bc1f(target); | |
1403 break; | |
1404 default: | |
1405 CHECK(0); | |
1406 } | |
1407 } | |
1408 } else { | |
1409 if (target) { | |
1410 // Here NaN cases were either handled by this function or are assumed to | |
1411 // have been handled by the caller. | |
1412 // Unsigned conditions are treated as their signed counterpart. | |
1413 // Use kDoubleCompareReg for comparison result, it is | |
1414 // valid in fp64 (FR = 1) mode which is implied for mips32r6. | |
1415 DCHECK(!cmp1.is(kDoubleCompareReg) && !cmp2.is(kDoubleCompareReg)); | |
1416 switch (cc) { | |
1417 case lt: | |
1418 cmp(OLT, L, kDoubleCompareReg, cmp1, cmp2); | |
1419 bc1nez(target, kDoubleCompareReg); | |
1420 break; | |
1421 case gt: | |
1422 cmp(ULE, L, kDoubleCompareReg, cmp1, cmp2); | |
1423 bc1eqz(target, kDoubleCompareReg); | |
1424 break; | |
1425 case ge: | |
1426 cmp(ULT, L, kDoubleCompareReg, cmp1, cmp2); | |
1427 bc1eqz(target, kDoubleCompareReg); | |
1428 break; | |
1429 case le: | |
1430 cmp(OLE, L, kDoubleCompareReg, cmp1, cmp2); | |
1431 bc1nez(target, kDoubleCompareReg); | |
1432 break; | |
1433 case eq: | |
1434 cmp(EQ, L, kDoubleCompareReg, cmp1, cmp2); | |
1435 bc1nez(target, kDoubleCompareReg); | |
1436 break; | |
1437 case ueq: | |
1438 cmp(UEQ, L, kDoubleCompareReg, cmp1, cmp2); | |
1439 bc1nez(target, kDoubleCompareReg); | |
1440 break; | |
1441 case ne: | |
1442 cmp(EQ, L, kDoubleCompareReg, cmp1, cmp2); | |
1443 bc1eqz(target, kDoubleCompareReg); | |
1444 break; | |
1445 case nue: | |
1446 cmp(UEQ, L, kDoubleCompareReg, cmp1, cmp2); | |
1447 bc1eqz(target, kDoubleCompareReg); | |
1448 break; | |
1449 default: | |
1450 CHECK(0); | |
1451 } | |
1452 } | |
1453 } | |
1454 | |
1455 if (bd == PROTECT) { | 1269 if (bd == PROTECT) { |
1456 nop(); | 1270 nop(); |
1457 } | 1271 } |
1458 } | 1272 } |
1459 | 1273 |
1460 | 1274 |
1461 void MacroAssembler::Move(FPURegister dst, double imm) { | 1275 void MacroAssembler::Move(FPURegister dst, double imm) { |
1462 static const DoubleRepresentation minus_zero(-0.0); | 1276 static const DoubleRepresentation minus_zero(-0.0); |
1463 static const DoubleRepresentation zero(0.0); | 1277 static const DoubleRepresentation zero(0.0); |
1464 DoubleRepresentation value_rep(imm); | 1278 DoubleRepresentation value_rep(imm); |
(...skipping 11 matching lines...) Expand all Loading... |
1476 if (lo != 0) { | 1290 if (lo != 0) { |
1477 li(at, Operand(lo)); | 1291 li(at, Operand(lo)); |
1478 mtc1(at, dst); | 1292 mtc1(at, dst); |
1479 } else { | 1293 } else { |
1480 mtc1(zero_reg, dst); | 1294 mtc1(zero_reg, dst); |
1481 } | 1295 } |
1482 // Move the high part of the double into the higher of the corresponding FPU | 1296 // Move the high part of the double into the higher of the corresponding FPU |
1483 // register of FPU register pair. | 1297 // register of FPU register pair. |
1484 if (hi != 0) { | 1298 if (hi != 0) { |
1485 li(at, Operand(hi)); | 1299 li(at, Operand(hi)); |
1486 Mthc1(at, dst); | 1300 mtc1(at, dst.high()); |
1487 } else { | 1301 } else { |
1488 Mthc1(zero_reg, dst); | 1302 mtc1(zero_reg, dst.high()); |
1489 } | 1303 } |
1490 } | 1304 } |
1491 } | 1305 } |
1492 | 1306 |
1493 | 1307 |
1494 void MacroAssembler::Movz(Register rd, Register rs, Register rt) { | 1308 void MacroAssembler::Movz(Register rd, Register rs, Register rt) { |
1495 if (IsMipsArchVariant(kLoongson) || IsMipsArchVariant(kMips32r6)) { | 1309 if (kArchVariant == kLoongson) { |
1496 Label done; | 1310 Label done; |
1497 Branch(&done, ne, rt, Operand(zero_reg)); | 1311 Branch(&done, ne, rt, Operand(zero_reg)); |
1498 mov(rd, rs); | 1312 mov(rd, rs); |
1499 bind(&done); | 1313 bind(&done); |
1500 } else { | 1314 } else { |
1501 movz(rd, rs, rt); | 1315 movz(rd, rs, rt); |
1502 } | 1316 } |
1503 } | 1317 } |
1504 | 1318 |
1505 | 1319 |
1506 void MacroAssembler::Movn(Register rd, Register rs, Register rt) { | 1320 void MacroAssembler::Movn(Register rd, Register rs, Register rt) { |
1507 if (IsMipsArchVariant(kLoongson) || IsMipsArchVariant(kMips32r6)) { | 1321 if (kArchVariant == kLoongson) { |
1508 Label done; | 1322 Label done; |
1509 Branch(&done, eq, rt, Operand(zero_reg)); | 1323 Branch(&done, eq, rt, Operand(zero_reg)); |
1510 mov(rd, rs); | 1324 mov(rd, rs); |
1511 bind(&done); | 1325 bind(&done); |
1512 } else { | 1326 } else { |
1513 movn(rd, rs, rt); | 1327 movn(rd, rs, rt); |
1514 } | 1328 } |
1515 } | 1329 } |
1516 | 1330 |
1517 | 1331 |
1518 void MacroAssembler::Movt(Register rd, Register rs, uint16_t cc) { | 1332 void MacroAssembler::Movt(Register rd, Register rs, uint16_t cc) { |
1519 if (IsMipsArchVariant(kLoongson)) { | 1333 if (kArchVariant == kLoongson) { |
1520 // Tests an FP condition code and then conditionally move rs to rd. | 1334 // Tests an FP condition code and then conditionally move rs to rd. |
1521 // We do not currently use any FPU cc bit other than bit 0. | 1335 // We do not currently use any FPU cc bit other than bit 0. |
1522 DCHECK(cc == 0); | 1336 DCHECK(cc == 0); |
1523 DCHECK(!(rs.is(t8) || rd.is(t8))); | 1337 DCHECK(!(rs.is(t8) || rd.is(t8))); |
1524 Label done; | 1338 Label done; |
1525 Register scratch = t8; | 1339 Register scratch = t8; |
1526 // For testing purposes we need to fetch content of the FCSR register and | 1340 // For testing purposes we need to fetch content of the FCSR register and |
1527 // than test its cc (floating point condition code) bit (for cc = 0, it is | 1341 // than test its cc (floating point condition code) bit (for cc = 0, it is |
1528 // 24. bit of the FCSR). | 1342 // 24. bit of the FCSR). |
1529 cfc1(scratch, FCSR); | 1343 cfc1(scratch, FCSR); |
1530 // For the MIPS I, II and III architectures, the contents of scratch is | 1344 // For the MIPS I, II and III architectures, the contents of scratch is |
1531 // UNPREDICTABLE for the instruction immediately following CFC1. | 1345 // UNPREDICTABLE for the instruction immediately following CFC1. |
1532 nop(); | 1346 nop(); |
1533 srl(scratch, scratch, 16); | 1347 srl(scratch, scratch, 16); |
1534 andi(scratch, scratch, 0x0080); | 1348 andi(scratch, scratch, 0x0080); |
1535 Branch(&done, eq, scratch, Operand(zero_reg)); | 1349 Branch(&done, eq, scratch, Operand(zero_reg)); |
1536 mov(rd, rs); | 1350 mov(rd, rs); |
1537 bind(&done); | 1351 bind(&done); |
1538 } else { | 1352 } else { |
1539 movt(rd, rs, cc); | 1353 movt(rd, rs, cc); |
1540 } | 1354 } |
1541 } | 1355 } |
1542 | 1356 |
1543 | 1357 |
1544 void MacroAssembler::Movf(Register rd, Register rs, uint16_t cc) { | 1358 void MacroAssembler::Movf(Register rd, Register rs, uint16_t cc) { |
1545 if (IsMipsArchVariant(kLoongson)) { | 1359 if (kArchVariant == kLoongson) { |
1546 // Tests an FP condition code and then conditionally move rs to rd. | 1360 // Tests an FP condition code and then conditionally move rs to rd. |
1547 // We do not currently use any FPU cc bit other than bit 0. | 1361 // We do not currently use any FPU cc bit other than bit 0. |
1548 DCHECK(cc == 0); | 1362 DCHECK(cc == 0); |
1549 DCHECK(!(rs.is(t8) || rd.is(t8))); | 1363 DCHECK(!(rs.is(t8) || rd.is(t8))); |
1550 Label done; | 1364 Label done; |
1551 Register scratch = t8; | 1365 Register scratch = t8; |
1552 // For testing purposes we need to fetch content of the FCSR register and | 1366 // For testing purposes we need to fetch content of the FCSR register and |
1553 // than test its cc (floating point condition code) bit (for cc = 0, it is | 1367 // than test its cc (floating point condition code) bit (for cc = 0, it is |
1554 // 24. bit of the FCSR). | 1368 // 24. bit of the FCSR). |
1555 cfc1(scratch, FCSR); | 1369 cfc1(scratch, FCSR); |
1556 // For the MIPS I, II and III architectures, the contents of scratch is | 1370 // For the MIPS I, II and III architectures, the contents of scratch is |
1557 // UNPREDICTABLE for the instruction immediately following CFC1. | 1371 // UNPREDICTABLE for the instruction immediately following CFC1. |
1558 nop(); | 1372 nop(); |
1559 srl(scratch, scratch, 16); | 1373 srl(scratch, scratch, 16); |
1560 andi(scratch, scratch, 0x0080); | 1374 andi(scratch, scratch, 0x0080); |
1561 Branch(&done, ne, scratch, Operand(zero_reg)); | 1375 Branch(&done, ne, scratch, Operand(zero_reg)); |
1562 mov(rd, rs); | 1376 mov(rd, rs); |
1563 bind(&done); | 1377 bind(&done); |
1564 } else { | 1378 } else { |
1565 movf(rd, rs, cc); | 1379 movf(rd, rs, cc); |
1566 } | 1380 } |
1567 } | 1381 } |
1568 | 1382 |
1569 | 1383 |
1570 void MacroAssembler::Clz(Register rd, Register rs) { | 1384 void MacroAssembler::Clz(Register rd, Register rs) { |
1571 if (IsMipsArchVariant(kLoongson)) { | 1385 if (kArchVariant == kLoongson) { |
1572 DCHECK(!(rd.is(t8) || rd.is(t9)) && !(rs.is(t8) || rs.is(t9))); | 1386 DCHECK(!(rd.is(t8) || rd.is(t9)) && !(rs.is(t8) || rs.is(t9))); |
1573 Register mask = t8; | 1387 Register mask = t8; |
1574 Register scratch = t9; | 1388 Register scratch = t9; |
1575 Label loop, end; | 1389 Label loop, end; |
1576 mov(at, rs); | 1390 mov(at, rs); |
1577 mov(rd, zero_reg); | 1391 mov(rd, zero_reg); |
1578 lui(mask, 0x8000); | 1392 lui(mask, 0x8000); |
1579 bind(&loop); | 1393 bind(&loop); |
1580 and_(scratch, at, mask); | 1394 and_(scratch, at, mask); |
1581 Branch(&end, ne, scratch, Operand(zero_reg)); | 1395 Branch(&end, ne, scratch, Operand(zero_reg)); |
(...skipping 841 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2423 Register r2 = no_reg; | 2237 Register r2 = no_reg; |
2424 Register scratch = at; | 2238 Register scratch = at; |
2425 | 2239 |
2426 if (rt.is_reg()) { | 2240 if (rt.is_reg()) { |
2427 r2 = rt.rm_; | 2241 r2 = rt.rm_; |
2428 } else if (cond != cc_always) { | 2242 } else if (cond != cc_always) { |
2429 r2 = scratch; | 2243 r2 = scratch; |
2430 li(r2, rt); | 2244 li(r2, rt); |
2431 } | 2245 } |
2432 | 2246 |
2433 if (!IsMipsArchVariant(kMips32r6)) { | 2247 { |
2434 BlockTrampolinePoolScope block_trampoline_pool(this); | 2248 BlockTrampolinePoolScope block_trampoline_pool(this); |
2435 switch (cond) { | 2249 switch (cond) { |
2436 case cc_always: | 2250 case cc_always: |
2437 bal(offset); | 2251 bal(offset); |
2438 break; | 2252 break; |
2439 case eq: | 2253 case eq: |
2440 bne(rs, r2, 2); | 2254 bne(rs, r2, 2); |
2441 nop(); | 2255 nop(); |
2442 bal(offset); | 2256 bal(offset); |
2443 break; | 2257 break; |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2487 break; | 2301 break; |
2488 case Uless_equal: | 2302 case Uless_equal: |
2489 sltu(scratch, r2, rs); | 2303 sltu(scratch, r2, rs); |
2490 addiu(scratch, scratch, -1); | 2304 addiu(scratch, scratch, -1); |
2491 bltzal(scratch, offset); | 2305 bltzal(scratch, offset); |
2492 break; | 2306 break; |
2493 | 2307 |
2494 default: | 2308 default: |
2495 UNREACHABLE(); | 2309 UNREACHABLE(); |
2496 } | 2310 } |
2497 } else { | |
2498 BlockTrampolinePoolScope block_trampoline_pool(this); | |
2499 switch (cond) { | |
2500 case cc_always: | |
2501 bal(offset); | |
2502 break; | |
2503 case eq: | |
2504 bne(rs, r2, 2); | |
2505 nop(); | |
2506 bal(offset); | |
2507 break; | |
2508 case ne: | |
2509 beq(rs, r2, 2); | |
2510 nop(); | |
2511 bal(offset); | |
2512 break; | |
2513 | |
2514 // Signed comparison. | |
2515 case greater: | |
2516 // rs > rt | |
2517 slt(scratch, r2, rs); | |
2518 beq(scratch, zero_reg, 2); | |
2519 nop(); | |
2520 bal(offset); | |
2521 break; | |
2522 case greater_equal: | |
2523 // rs >= rt | |
2524 slt(scratch, rs, r2); | |
2525 bne(scratch, zero_reg, 2); | |
2526 nop(); | |
2527 bal(offset); | |
2528 break; | |
2529 case less: | |
2530 // rs < r2 | |
2531 slt(scratch, rs, r2); | |
2532 bne(scratch, zero_reg, 2); | |
2533 nop(); | |
2534 bal(offset); | |
2535 break; | |
2536 case less_equal: | |
2537 // rs <= r2 | |
2538 slt(scratch, r2, rs); | |
2539 bne(scratch, zero_reg, 2); | |
2540 nop(); | |
2541 bal(offset); | |
2542 break; | |
2543 | |
2544 | |
2545 // Unsigned comparison. | |
2546 case Ugreater: | |
2547 // rs > rt | |
2548 sltu(scratch, r2, rs); | |
2549 beq(scratch, zero_reg, 2); | |
2550 nop(); | |
2551 bal(offset); | |
2552 break; | |
2553 case Ugreater_equal: | |
2554 // rs >= rt | |
2555 sltu(scratch, rs, r2); | |
2556 bne(scratch, zero_reg, 2); | |
2557 nop(); | |
2558 bal(offset); | |
2559 break; | |
2560 case Uless: | |
2561 // rs < r2 | |
2562 sltu(scratch, rs, r2); | |
2563 bne(scratch, zero_reg, 2); | |
2564 nop(); | |
2565 bal(offset); | |
2566 break; | |
2567 case Uless_equal: | |
2568 // rs <= r2 | |
2569 sltu(scratch, r2, rs); | |
2570 bne(scratch, zero_reg, 2); | |
2571 nop(); | |
2572 bal(offset); | |
2573 break; | |
2574 default: | |
2575 UNREACHABLE(); | |
2576 } | |
2577 } | 2311 } |
2578 | |
2579 // Emit a nop in the branch delay slot if required. | 2312 // Emit a nop in the branch delay slot if required. |
2580 if (bdslot == PROTECT) | 2313 if (bdslot == PROTECT) |
2581 nop(); | 2314 nop(); |
2582 } | 2315 } |
2583 | 2316 |
2584 | 2317 |
2585 void MacroAssembler::BranchAndLinkShort(Label* L, BranchDelaySlot bdslot) { | 2318 void MacroAssembler::BranchAndLinkShort(Label* L, BranchDelaySlot bdslot) { |
2586 bal(shifted_branch_offset(L, false)); | 2319 bal(shifted_branch_offset(L, false)); |
2587 | 2320 |
2588 // Emit a nop in the branch delay slot if required. | 2321 // Emit a nop in the branch delay slot if required. |
(...skipping 10 matching lines...) Expand all Loading... |
2599 int32_t offset = 0; | 2332 int32_t offset = 0; |
2600 Register r2 = no_reg; | 2333 Register r2 = no_reg; |
2601 Register scratch = at; | 2334 Register scratch = at; |
2602 if (rt.is_reg()) { | 2335 if (rt.is_reg()) { |
2603 r2 = rt.rm_; | 2336 r2 = rt.rm_; |
2604 } else if (cond != cc_always) { | 2337 } else if (cond != cc_always) { |
2605 r2 = scratch; | 2338 r2 = scratch; |
2606 li(r2, rt); | 2339 li(r2, rt); |
2607 } | 2340 } |
2608 | 2341 |
2609 if (!IsMipsArchVariant(kMips32r6)) { | 2342 { |
2610 BlockTrampolinePoolScope block_trampoline_pool(this); | 2343 BlockTrampolinePoolScope block_trampoline_pool(this); |
2611 switch (cond) { | 2344 switch (cond) { |
2612 case cc_always: | 2345 case cc_always: |
2613 offset = shifted_branch_offset(L, false); | 2346 offset = shifted_branch_offset(L, false); |
2614 bal(offset); | 2347 bal(offset); |
2615 break; | 2348 break; |
2616 case eq: | 2349 case eq: |
2617 bne(rs, r2, 2); | 2350 bne(rs, r2, 2); |
2618 nop(); | 2351 nop(); |
2619 offset = shifted_branch_offset(L, false); | 2352 offset = shifted_branch_offset(L, false); |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2674 case Uless_equal: | 2407 case Uless_equal: |
2675 sltu(scratch, r2, rs); | 2408 sltu(scratch, r2, rs); |
2676 addiu(scratch, scratch, -1); | 2409 addiu(scratch, scratch, -1); |
2677 offset = shifted_branch_offset(L, false); | 2410 offset = shifted_branch_offset(L, false); |
2678 bltzal(scratch, offset); | 2411 bltzal(scratch, offset); |
2679 break; | 2412 break; |
2680 | 2413 |
2681 default: | 2414 default: |
2682 UNREACHABLE(); | 2415 UNREACHABLE(); |
2683 } | 2416 } |
2684 } else { | |
2685 BlockTrampolinePoolScope block_trampoline_pool(this); | |
2686 switch (cond) { | |
2687 case cc_always: | |
2688 offset = shifted_branch_offset(L, false); | |
2689 bal(offset); | |
2690 break; | |
2691 case eq: | |
2692 bne(rs, r2, 2); | |
2693 nop(); | |
2694 offset = shifted_branch_offset(L, false); | |
2695 bal(offset); | |
2696 break; | |
2697 case ne: | |
2698 beq(rs, r2, 2); | |
2699 nop(); | |
2700 offset = shifted_branch_offset(L, false); | |
2701 bal(offset); | |
2702 break; | |
2703 | |
2704 // Signed comparison. | |
2705 case greater: | |
2706 // rs > rt | |
2707 slt(scratch, r2, rs); | |
2708 beq(scratch, zero_reg, 2); | |
2709 nop(); | |
2710 offset = shifted_branch_offset(L, false); | |
2711 bal(offset); | |
2712 break; | |
2713 case greater_equal: | |
2714 // rs >= rt | |
2715 slt(scratch, rs, r2); | |
2716 bne(scratch, zero_reg, 2); | |
2717 nop(); | |
2718 offset = shifted_branch_offset(L, false); | |
2719 bal(offset); | |
2720 break; | |
2721 case less: | |
2722 // rs < r2 | |
2723 slt(scratch, rs, r2); | |
2724 bne(scratch, zero_reg, 2); | |
2725 nop(); | |
2726 offset = shifted_branch_offset(L, false); | |
2727 bal(offset); | |
2728 break; | |
2729 case less_equal: | |
2730 // rs <= r2 | |
2731 slt(scratch, r2, rs); | |
2732 bne(scratch, zero_reg, 2); | |
2733 nop(); | |
2734 offset = shifted_branch_offset(L, false); | |
2735 bal(offset); | |
2736 break; | |
2737 | |
2738 | |
2739 // Unsigned comparison. | |
2740 case Ugreater: | |
2741 // rs > rt | |
2742 sltu(scratch, r2, rs); | |
2743 beq(scratch, zero_reg, 2); | |
2744 nop(); | |
2745 offset = shifted_branch_offset(L, false); | |
2746 bal(offset); | |
2747 break; | |
2748 case Ugreater_equal: | |
2749 // rs >= rt | |
2750 sltu(scratch, rs, r2); | |
2751 bne(scratch, zero_reg, 2); | |
2752 nop(); | |
2753 offset = shifted_branch_offset(L, false); | |
2754 bal(offset); | |
2755 break; | |
2756 case Uless: | |
2757 // rs < r2 | |
2758 sltu(scratch, rs, r2); | |
2759 bne(scratch, zero_reg, 2); | |
2760 nop(); | |
2761 offset = shifted_branch_offset(L, false); | |
2762 bal(offset); | |
2763 break; | |
2764 case Uless_equal: | |
2765 // rs <= r2 | |
2766 sltu(scratch, r2, rs); | |
2767 bne(scratch, zero_reg, 2); | |
2768 nop(); | |
2769 offset = shifted_branch_offset(L, false); | |
2770 bal(offset); | |
2771 break; | |
2772 | |
2773 default: | |
2774 UNREACHABLE(); | |
2775 } | |
2776 } | 2417 } |
2777 | |
2778 // Check that offset could actually hold on an int16_t. | 2418 // Check that offset could actually hold on an int16_t. |
2779 DCHECK(is_int16(offset)); | 2419 DCHECK(is_int16(offset)); |
2780 | 2420 |
2781 // Emit a nop in the branch delay slot if required. | 2421 // Emit a nop in the branch delay slot if required. |
2782 if (bdslot == PROTECT) | 2422 if (bdslot == PROTECT) |
2783 nop(); | 2423 nop(); |
2784 } | 2424 } |
2785 | 2425 |
2786 | 2426 |
2787 void MacroAssembler::Jump(Register target, | 2427 void MacroAssembler::Jump(Register target, |
(...skipping 3313 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6101 | 5741 |
6102 | 5742 |
6103 void MacroAssembler::TruncatingDiv(Register result, | 5743 void MacroAssembler::TruncatingDiv(Register result, |
6104 Register dividend, | 5744 Register dividend, |
6105 int32_t divisor) { | 5745 int32_t divisor) { |
6106 DCHECK(!dividend.is(result)); | 5746 DCHECK(!dividend.is(result)); |
6107 DCHECK(!dividend.is(at)); | 5747 DCHECK(!dividend.is(at)); |
6108 DCHECK(!result.is(at)); | 5748 DCHECK(!result.is(at)); |
6109 MultiplierAndShift ms(divisor); | 5749 MultiplierAndShift ms(divisor); |
6110 li(at, Operand(ms.multiplier())); | 5750 li(at, Operand(ms.multiplier())); |
6111 Mulh(result, dividend, Operand(at)); | 5751 Mult(dividend, Operand(at)); |
| 5752 mfhi(result); |
6112 if (divisor > 0 && ms.multiplier() < 0) { | 5753 if (divisor > 0 && ms.multiplier() < 0) { |
6113 Addu(result, result, Operand(dividend)); | 5754 Addu(result, result, Operand(dividend)); |
6114 } | 5755 } |
6115 if (divisor < 0 && ms.multiplier() > 0) { | 5756 if (divisor < 0 && ms.multiplier() > 0) { |
6116 Subu(result, result, Operand(dividend)); | 5757 Subu(result, result, Operand(dividend)); |
6117 } | 5758 } |
6118 if (ms.shift() > 0) sra(result, result, ms.shift()); | 5759 if (ms.shift() > 0) sra(result, result, ms.shift()); |
6119 srl(at, dividend, 31); | 5760 srl(at, dividend, 31); |
6120 Addu(result, result, Operand(at)); | 5761 Addu(result, result, Operand(at)); |
6121 } | 5762 } |
6122 | 5763 |
6123 | 5764 |
6124 } } // namespace v8::internal | 5765 } } // namespace v8::internal |
6125 | 5766 |
6126 #endif // V8_TARGET_ARCH_MIPS | 5767 #endif // V8_TARGET_ARCH_MIPS |
OLD | NEW |