| 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 |