OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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> | 5 #include <limits.h> |
6 #include <stdarg.h> | 6 #include <stdarg.h> |
7 #include <stdlib.h> | 7 #include <stdlib.h> |
8 #include <cmath> | 8 #include <cmath> |
9 | 9 |
10 #if V8_TARGET_ARCH_MIPS | 10 #if V8_TARGET_ARCH_MIPS |
(...skipping 889 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
900 break_count_ = 0; | 900 break_count_ = 0; |
901 break_pc_ = NULL; | 901 break_pc_ = NULL; |
902 break_instr_ = 0; | 902 break_instr_ = 0; |
903 | 903 |
904 // Set up architecture state. | 904 // Set up architecture state. |
905 // All registers are initialized to zero to start with. | 905 // All registers are initialized to zero to start with. |
906 for (int i = 0; i < kNumSimuRegisters; i++) { | 906 for (int i = 0; i < kNumSimuRegisters; i++) { |
907 registers_[i] = 0; | 907 registers_[i] = 0; |
908 } | 908 } |
909 for (int i = 0; i < kNumFPURegisters; i++) { | 909 for (int i = 0; i < kNumFPURegisters; i++) { |
910 FPUregisters_[i] = 0; | 910 FPUregisters_[2 * i] = 0; |
| 911 FPUregisters_[2 * i + 1] = 0; // upper part for MSA ASE |
911 } | 912 } |
912 if (IsMipsArchVariant(kMips32r6)) { | 913 if (IsMipsArchVariant(kMips32r6)) { |
913 FCSR_ = kFCSRNaN2008FlagMask; | 914 FCSR_ = kFCSRNaN2008FlagMask; |
914 } else { | 915 } else { |
915 DCHECK(IsMipsArchVariant(kMips32r1) || IsMipsArchVariant(kMips32r2)); | 916 DCHECK(IsMipsArchVariant(kMips32r1) || IsMipsArchVariant(kMips32r2)); |
916 FCSR_ = 0; | 917 FCSR_ = 0; |
917 } | 918 } |
918 | 919 |
919 // The sp is initialized to point to the bottom (high address) of the | 920 // The sp is initialized to point to the bottom (high address) of the |
920 // allocated stack area. To be safe in potential stack underflows we leave | 921 // allocated stack area. To be safe in potential stack underflows we leave |
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1056 void Simulator::set_dw_register(int reg, const int* dbl) { | 1057 void Simulator::set_dw_register(int reg, const int* dbl) { |
1057 DCHECK((reg >= 0) && (reg < kNumSimuRegisters)); | 1058 DCHECK((reg >= 0) && (reg < kNumSimuRegisters)); |
1058 registers_[reg] = dbl[0]; | 1059 registers_[reg] = dbl[0]; |
1059 registers_[reg + 1] = dbl[1]; | 1060 registers_[reg + 1] = dbl[1]; |
1060 } | 1061 } |
1061 | 1062 |
1062 | 1063 |
1063 void Simulator::set_fpu_register(int fpureg, int64_t value) { | 1064 void Simulator::set_fpu_register(int fpureg, int64_t value) { |
1064 DCHECK(IsFp64Mode()); | 1065 DCHECK(IsFp64Mode()); |
1065 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters)); | 1066 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters)); |
1066 FPUregisters_[fpureg] = value; | 1067 FPUregisters_[fpureg * 2] = value; |
1067 } | 1068 } |
1068 | 1069 |
1069 | 1070 |
1070 void Simulator::set_fpu_register_word(int fpureg, int32_t value) { | 1071 void Simulator::set_fpu_register_word(int fpureg, int32_t value) { |
1071 // Set ONLY lower 32-bits, leaving upper bits untouched. | 1072 // Set ONLY lower 32-bits, leaving upper bits untouched. |
1072 // TODO(plind): big endian issue. | 1073 // TODO(plind): big endian issue. |
1073 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters)); | 1074 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters)); |
1074 int32_t *pword = reinterpret_cast<int32_t*>(&FPUregisters_[fpureg]); | 1075 int32_t* pword = reinterpret_cast<int32_t*>(&FPUregisters_[fpureg * 2]); |
1075 *pword = value; | 1076 *pword = value; |
1076 } | 1077 } |
1077 | 1078 |
1078 | 1079 |
1079 void Simulator::set_fpu_register_hi_word(int fpureg, int32_t value) { | 1080 void Simulator::set_fpu_register_hi_word(int fpureg, int32_t value) { |
1080 // Set ONLY upper 32-bits, leaving lower bits untouched. | 1081 // Set ONLY upper 32-bits, leaving lower bits untouched. |
1081 // TODO(plind): big endian issue. | 1082 // TODO(plind): big endian issue. |
1082 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters)); | 1083 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters)); |
1083 int32_t *phiword = (reinterpret_cast<int32_t*>(&FPUregisters_[fpureg])) + 1; | 1084 int32_t* phiword = |
| 1085 (reinterpret_cast<int32_t*>(&FPUregisters_[fpureg * 2])) + 1; |
1084 *phiword = value; | 1086 *phiword = value; |
1085 } | 1087 } |
1086 | 1088 |
1087 | 1089 |
1088 void Simulator::set_fpu_register_float(int fpureg, float value) { | 1090 void Simulator::set_fpu_register_float(int fpureg, float value) { |
1089 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters)); | 1091 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters)); |
1090 *bit_cast<float*>(&FPUregisters_[fpureg]) = value; | 1092 *bit_cast<float*>(&FPUregisters_[fpureg * 2]) = value; |
1091 } | 1093 } |
1092 | 1094 |
1093 | 1095 |
1094 void Simulator::set_fpu_register_double(int fpureg, double value) { | 1096 void Simulator::set_fpu_register_double(int fpureg, double value) { |
1095 if (IsFp64Mode()) { | 1097 if (IsFp64Mode()) { |
1096 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters)); | 1098 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters)); |
1097 *bit_cast<double*>(&FPUregisters_[fpureg]) = value; | 1099 *bit_cast<double*>(&FPUregisters_[fpureg * 2]) = value; |
1098 } else { | 1100 } else { |
1099 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters) && ((fpureg % 2) == 0)); | 1101 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters) && ((fpureg % 2) == 0)); |
1100 int64_t i64 = bit_cast<int64_t>(value); | 1102 int64_t i64 = bit_cast<int64_t>(value); |
1101 set_fpu_register_word(fpureg, i64 & 0xffffffff); | 1103 set_fpu_register_word(fpureg, i64 & 0xffffffff); |
1102 set_fpu_register_word(fpureg + 1, i64 >> 32); | 1104 set_fpu_register_word(fpureg + 1, i64 >> 32); |
1103 } | 1105 } |
1104 } | 1106 } |
1105 | 1107 |
1106 | 1108 |
1107 // Get the register from the architecture state. This function does handle | 1109 // Get the register from the architecture state. This function does handle |
(...skipping 17 matching lines...) Expand all Loading... |
1125 char buffer[2 * sizeof(registers_[0])]; | 1127 char buffer[2 * sizeof(registers_[0])]; |
1126 memcpy(buffer, ®isters_[reg], 2 * sizeof(registers_[0])); | 1128 memcpy(buffer, ®isters_[reg], 2 * sizeof(registers_[0])); |
1127 memcpy(&dm_val, buffer, 2 * sizeof(registers_[0])); | 1129 memcpy(&dm_val, buffer, 2 * sizeof(registers_[0])); |
1128 return(dm_val); | 1130 return(dm_val); |
1129 } | 1131 } |
1130 | 1132 |
1131 | 1133 |
1132 int64_t Simulator::get_fpu_register(int fpureg) const { | 1134 int64_t Simulator::get_fpu_register(int fpureg) const { |
1133 if (IsFp64Mode()) { | 1135 if (IsFp64Mode()) { |
1134 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters)); | 1136 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters)); |
1135 return FPUregisters_[fpureg]; | 1137 return FPUregisters_[fpureg * 2]; |
1136 } else { | 1138 } else { |
1137 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters) && ((fpureg % 2) == 0)); | 1139 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters) && ((fpureg % 2) == 0)); |
1138 uint64_t i64; | 1140 uint64_t i64; |
1139 i64 = static_cast<uint32_t>(get_fpu_register_word(fpureg)); | 1141 i64 = static_cast<uint32_t>(get_fpu_register_word(fpureg)); |
1140 i64 |= static_cast<uint64_t>(get_fpu_register_word(fpureg + 1)) << 32; | 1142 i64 |= static_cast<uint64_t>(get_fpu_register_word(fpureg + 1)) << 32; |
1141 return static_cast<int64_t>(i64); | 1143 return static_cast<int64_t>(i64); |
1142 } | 1144 } |
1143 } | 1145 } |
1144 | 1146 |
1145 | 1147 |
1146 int32_t Simulator::get_fpu_register_word(int fpureg) const { | 1148 int32_t Simulator::get_fpu_register_word(int fpureg) const { |
1147 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters)); | 1149 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters)); |
1148 return static_cast<int32_t>(FPUregisters_[fpureg] & 0xffffffff); | 1150 return static_cast<int32_t>(FPUregisters_[fpureg * 2] & 0xffffffff); |
1149 } | 1151 } |
1150 | 1152 |
1151 | 1153 |
1152 int32_t Simulator::get_fpu_register_signed_word(int fpureg) const { | 1154 int32_t Simulator::get_fpu_register_signed_word(int fpureg) const { |
1153 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters)); | 1155 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters)); |
1154 return static_cast<int32_t>(FPUregisters_[fpureg] & 0xffffffff); | 1156 return static_cast<int32_t>(FPUregisters_[fpureg * 2] & 0xffffffff); |
1155 } | 1157 } |
1156 | 1158 |
1157 | 1159 |
1158 int32_t Simulator::get_fpu_register_hi_word(int fpureg) const { | 1160 int32_t Simulator::get_fpu_register_hi_word(int fpureg) const { |
1159 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters)); | 1161 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters)); |
1160 return static_cast<int32_t>((FPUregisters_[fpureg] >> 32) & 0xffffffff); | 1162 return static_cast<int32_t>((FPUregisters_[fpureg * 2] >> 32) & 0xffffffff); |
1161 } | 1163 } |
1162 | 1164 |
1163 | 1165 |
1164 float Simulator::get_fpu_register_float(int fpureg) const { | 1166 float Simulator::get_fpu_register_float(int fpureg) const { |
1165 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters)); | 1167 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters)); |
1166 return *bit_cast<float*>(const_cast<int64_t*>(&FPUregisters_[fpureg])); | 1168 return *bit_cast<float*>(const_cast<int64_t*>(&FPUregisters_[fpureg * 2])); |
1167 } | 1169 } |
1168 | 1170 |
1169 | 1171 |
1170 double Simulator::get_fpu_register_double(int fpureg) const { | 1172 double Simulator::get_fpu_register_double(int fpureg) const { |
1171 if (IsFp64Mode()) { | 1173 if (IsFp64Mode()) { |
1172 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters)); | 1174 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters)); |
1173 return *bit_cast<double*>(&FPUregisters_[fpureg]); | 1175 return *bit_cast<double*>(&FPUregisters_[fpureg * 2]); |
1174 } else { | 1176 } else { |
1175 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters) && ((fpureg % 2) == 0)); | 1177 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters) && ((fpureg % 2) == 0)); |
1176 int64_t i64; | 1178 int64_t i64; |
1177 i64 = static_cast<uint32_t>(get_fpu_register_word(fpureg)); | 1179 i64 = static_cast<uint32_t>(get_fpu_register_word(fpureg)); |
1178 i64 |= static_cast<uint64_t>(get_fpu_register_word(fpureg + 1)) << 32; | 1180 i64 |= static_cast<uint64_t>(get_fpu_register_word(fpureg + 1)) << 32; |
1179 return bit_cast<double>(i64); | 1181 return bit_cast<double>(i64); |
1180 } | 1182 } |
1181 } | 1183 } |
1182 | 1184 |
| 1185 template <typename T> |
| 1186 void Simulator::get_msa_register(int wreg, T* value) { |
| 1187 DCHECK((wreg >= 0) && (wreg < kNumMSARegisters)); |
| 1188 memcpy(value, FPUregisters_ + wreg * 2, kSimd128Size); |
| 1189 } |
| 1190 |
| 1191 template <typename T> |
| 1192 void Simulator::set_msa_register(int wreg, const T* value) { |
| 1193 DCHECK((wreg >= 0) && (wreg < kNumMSARegisters)); |
| 1194 memcpy(FPUregisters_ + wreg * 2, value, kSimd128Size); |
| 1195 } |
1183 | 1196 |
1184 // Runtime FP routines take up to two double arguments and zero | 1197 // Runtime FP routines take up to two double arguments and zero |
1185 // or one integer arguments. All are constructed here, | 1198 // or one integer arguments. All are constructed here, |
1186 // from a0-a3 or f12 and f14. | 1199 // from a0-a3 or f12 and f14. |
1187 void Simulator::GetFpArgs(double* x, double* y, int32_t* z) { | 1200 void Simulator::GetFpArgs(double* x, double* y, int32_t* z) { |
1188 if (!IsMipsSoftFloatABI) { | 1201 if (!IsMipsSoftFloatABI) { |
1189 *x = get_fpu_register_double(12); | 1202 *x = get_fpu_register_double(12); |
1190 *y = get_fpu_register_double(14); | 1203 *y = get_fpu_register_double(14); |
1191 *z = get_register(a2); | 1204 *z = get_register(a2); |
1192 } else { | 1205 } else { |
(...skipping 544 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1737 case DOUBLE: | 1750 case DOUBLE: |
1738 SNPrintF(trace_buf_, "%016" PRIx64 " (%" PRIu64 ") dbl:%e", | 1751 SNPrintF(trace_buf_, "%016" PRIx64 " (%" PRIu64 ") dbl:%e", |
1739 v.fmt_int64, icount_, v.fmt_double); | 1752 v.fmt_int64, icount_, v.fmt_double); |
1740 break; | 1753 break; |
1741 default: | 1754 default: |
1742 UNREACHABLE(); | 1755 UNREACHABLE(); |
1743 } | 1756 } |
1744 } | 1757 } |
1745 } | 1758 } |
1746 | 1759 |
| 1760 template <typename T> |
| 1761 void Simulator::TraceMSARegWr(T* value, TraceType t) { |
| 1762 if (::v8::internal::FLAG_trace_sim) { |
| 1763 union { |
| 1764 uint8_t b[16]; |
| 1765 uint16_t h[8]; |
| 1766 uint32_t w[4]; |
| 1767 uint64_t d[2]; |
| 1768 float f[4]; |
| 1769 double df[2]; |
| 1770 } v; |
| 1771 memcpy(v.b, value, kSimd128Size); |
| 1772 switch (t) { |
| 1773 case BYTE: |
| 1774 SNPrintF(trace_buf_, |
| 1775 "LO: %016" PRIx64 " HI: %016" PRIx64 " (%" PRIu64 ")", |
| 1776 v.d[0], v.d[1], icount_); |
| 1777 break; |
| 1778 case HALF: |
| 1779 SNPrintF(trace_buf_, |
| 1780 "LO: %016" PRIx64 " HI: %016" PRIx64 " (%" PRIu64 ")", |
| 1781 v.d[0], v.d[1], icount_); |
| 1782 break; |
| 1783 case WORD: |
| 1784 SNPrintF(trace_buf_, |
| 1785 "LO: %016" PRIx64 " HI: %016" PRIx64 " (%" PRIu64 |
| 1786 ") int32[0..3]:%" PRId32 " %" PRId32 " %" PRId32 |
| 1787 " %" PRId32, |
| 1788 v.d[0], v.d[1], icount_, v.w[0], v.w[1], v.w[2], v.w[3]); |
| 1789 break; |
| 1790 case DWORD: |
| 1791 SNPrintF(trace_buf_, |
| 1792 "LO: %016" PRIx64 " HI: %016" PRIx64 " (%" PRIu64 ")", |
| 1793 v.d[0], v.d[1], icount_); |
| 1794 break; |
| 1795 case FLOAT: |
| 1796 SNPrintF(trace_buf_, |
| 1797 "LO: %016" PRIx64 " HI: %016" PRIx64 " (%" PRIu64 |
| 1798 ") flt[0..3]:%e %e %e %e", |
| 1799 v.d[0], v.d[1], icount_, v.f[0], v.f[1], v.f[2], v.f[3]); |
| 1800 break; |
| 1801 case DOUBLE: |
| 1802 SNPrintF(trace_buf_, |
| 1803 "LO: %016" PRIx64 " HI: %016" PRIx64 " (%" PRIu64 |
| 1804 ") dbl[0..1]:%e %e", |
| 1805 v.d[0], v.d[1], icount_, v.df[0], v.df[1]); |
| 1806 break; |
| 1807 default: |
| 1808 UNREACHABLE(); |
| 1809 } |
| 1810 } |
| 1811 } |
| 1812 |
1747 // TODO(plind): consider making icount_ printing a flag option. | 1813 // TODO(plind): consider making icount_ printing a flag option. |
1748 void Simulator::TraceMemRd(int32_t addr, int32_t value, TraceType t) { | 1814 void Simulator::TraceMemRd(int32_t addr, int32_t value, TraceType t) { |
1749 if (::v8::internal::FLAG_trace_sim) { | 1815 if (::v8::internal::FLAG_trace_sim) { |
1750 union { | 1816 union { |
1751 int32_t fmt_int32; | 1817 int32_t fmt_int32; |
1752 float fmt_float; | 1818 float fmt_float; |
1753 } v; | 1819 } v; |
1754 v.fmt_int32 = value; | 1820 v.fmt_int32 = value; |
1755 | 1821 |
1756 switch (t) { | 1822 switch (t) { |
(...skipping 2352 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4109 } | 4175 } |
4110 } | 4176 } |
4111 SetResult(rd_reg(), alu_out); | 4177 SetResult(rd_reg(), alu_out); |
4112 break; | 4178 break; |
4113 } | 4179 } |
4114 default: | 4180 default: |
4115 UNREACHABLE(); | 4181 UNREACHABLE(); |
4116 } | 4182 } |
4117 } | 4183 } |
4118 | 4184 |
| 4185 int Simulator::DecodeMsaDataFormat() { |
| 4186 int df = -1; |
| 4187 if (instr_.IsMSABranchInstr()) { |
| 4188 switch (instr_.RsFieldRaw()) { |
| 4189 case BZ_V: |
| 4190 case BNZ_V: |
| 4191 df = MSA_VECT; |
| 4192 break; |
| 4193 case BZ_B: |
| 4194 case BNZ_B: |
| 4195 df = MSA_BYTE; |
| 4196 break; |
| 4197 case BZ_H: |
| 4198 case BNZ_H: |
| 4199 df = MSA_HALF; |
| 4200 break; |
| 4201 case BZ_W: |
| 4202 case BNZ_W: |
| 4203 df = MSA_WORD; |
| 4204 break; |
| 4205 case BZ_D: |
| 4206 case BNZ_D: |
| 4207 df = MSA_DWORD; |
| 4208 break; |
| 4209 default: |
| 4210 UNREACHABLE(); |
| 4211 break; |
| 4212 } |
| 4213 } else { |
| 4214 int DF[] = {MSA_BYTE, MSA_HALF, MSA_WORD, MSA_DWORD}; |
| 4215 switch (instr_.MSAMinorOpcodeField()) { |
| 4216 case kMsaMinorI5: |
| 4217 case kMsaMinorI10: |
| 4218 case kMsaMinor3R: |
| 4219 df = DF[instr_.Bits(22, 21)]; |
| 4220 break; |
| 4221 case kMsaMinorMI10: |
| 4222 df = DF[instr_.Bits(1, 0)]; |
| 4223 break; |
| 4224 case kMsaMinorBIT: |
| 4225 df = DF[instr_.MsaBitDf()]; |
| 4226 break; |
| 4227 case kMsaMinorELM: |
| 4228 df = DF[instr_.MsaElmDf()]; |
| 4229 break; |
| 4230 case kMsaMinor3RF: { |
| 4231 uint32_t opcode = instr_.InstructionBits() & kMsa3RFMask; |
| 4232 switch (opcode) { |
| 4233 case FEXDO: |
| 4234 case FTQ: |
| 4235 case MUL_Q: |
| 4236 case MADD_Q: |
| 4237 case MSUB_Q: |
| 4238 case MULR_Q: |
| 4239 case MADDR_Q: |
| 4240 case MSUBR_Q: |
| 4241 df = DF[1 + instr_.Bit(21)]; |
| 4242 break; |
| 4243 default: |
| 4244 df = DF[2 + instr_.Bit(21)]; |
| 4245 break; |
| 4246 } |
| 4247 } break; |
| 4248 case kMsaMinor2R: |
| 4249 df = DF[instr_.Bits(17, 16)]; |
| 4250 break; |
| 4251 case kMsaMinor2RF: |
| 4252 df = DF[2 + instr_.Bit(16)]; |
| 4253 break; |
| 4254 default: |
| 4255 UNREACHABLE(); |
| 4256 break; |
| 4257 } |
| 4258 } |
| 4259 return df; |
| 4260 } |
| 4261 |
| 4262 void Simulator::DecodeTypeMsaI8() { |
| 4263 DCHECK(IsMipsArchVariant(kMips32r6)); |
| 4264 DCHECK(CpuFeatures::IsSupported(MIPS_SIMD)); |
| 4265 uint32_t opcode = instr_.InstructionBits() & kMsaI8Mask; |
| 4266 |
| 4267 switch (opcode) { |
| 4268 case ANDI_B: |
| 4269 case ORI_B: |
| 4270 case NORI_B: |
| 4271 case XORI_B: |
| 4272 case BMNZI_B: |
| 4273 case BMZI_B: |
| 4274 case BSELI_B: |
| 4275 case SHF_B: |
| 4276 case SHF_H: |
| 4277 case SHF_W: |
| 4278 UNIMPLEMENTED(); |
| 4279 break; |
| 4280 default: |
| 4281 UNREACHABLE(); |
| 4282 } |
| 4283 } |
| 4284 |
| 4285 void Simulator::DecodeTypeMsaI5() { |
| 4286 DCHECK(IsMipsArchVariant(kMips32r6)); |
| 4287 DCHECK(CpuFeatures::IsSupported(MIPS_SIMD)); |
| 4288 uint32_t opcode = instr_.InstructionBits() & kMsaI5Mask; |
| 4289 |
| 4290 switch (opcode) { |
| 4291 case ADDVI: |
| 4292 case SUBVI: |
| 4293 case MAXI_S: |
| 4294 case MAXI_U: |
| 4295 case MINI_S: |
| 4296 case MINI_U: |
| 4297 case CEQI: |
| 4298 case CLTI_S: |
| 4299 case CLTI_U: |
| 4300 case CLEI_S: |
| 4301 case CLEI_U: |
| 4302 UNIMPLEMENTED(); |
| 4303 break; |
| 4304 default: |
| 4305 UNREACHABLE(); |
| 4306 } |
| 4307 } |
| 4308 |
| 4309 void Simulator::DecodeTypeMsaI10() { |
| 4310 DCHECK(IsMipsArchVariant(kMips32r6)); |
| 4311 DCHECK(CpuFeatures::IsSupported(MIPS_SIMD)); |
| 4312 uint32_t opcode = instr_.InstructionBits() & kMsaI5Mask; |
| 4313 if (opcode == LDI) { |
| 4314 UNIMPLEMENTED(); |
| 4315 } else { |
| 4316 UNREACHABLE(); |
| 4317 } |
| 4318 } |
| 4319 |
| 4320 void Simulator::DecodeTypeMsaELM() { |
| 4321 DCHECK(IsMipsArchVariant(kMips32r6)); |
| 4322 DCHECK(CpuFeatures::IsSupported(MIPS_SIMD)); |
| 4323 uint32_t opcode = instr_.InstructionBits() & kMsaELMMask; |
| 4324 int32_t n = instr_.MsaElmNValue(); |
| 4325 int32_t alu_out; |
| 4326 switch (opcode) { |
| 4327 case COPY_S: |
| 4328 case COPY_U: |
| 4329 switch (DecodeMsaDataFormat()) { |
| 4330 case MSA_BYTE: { |
| 4331 DCHECK(n < 16); |
| 4332 int8_t ws[16]; |
| 4333 get_msa_register(instr_.WsValue(), ws); |
| 4334 alu_out = static_cast<int32_t>(ws[n]); |
| 4335 SetResult(wd_reg(), (opcode == COPY_U) ? alu_out & 0xFFu : alu_out); |
| 4336 break; |
| 4337 } |
| 4338 case MSA_HALF: { |
| 4339 DCHECK(n < 8); |
| 4340 int16_t ws[8]; |
| 4341 get_msa_register(instr_.WsValue(), ws); |
| 4342 alu_out = static_cast<int32_t>(ws[n]); |
| 4343 SetResult(wd_reg(), (opcode == COPY_U) ? alu_out & 0xFFFFu : alu_out); |
| 4344 break; |
| 4345 } |
| 4346 case MSA_WORD: { |
| 4347 DCHECK(n < 4); |
| 4348 int32_t ws[4]; |
| 4349 get_msa_register(instr_.WsValue(), ws); |
| 4350 alu_out = static_cast<int32_t>(ws[n]); |
| 4351 SetResult(wd_reg(), alu_out); |
| 4352 break; |
| 4353 } |
| 4354 default: |
| 4355 UNREACHABLE(); |
| 4356 } |
| 4357 break; |
| 4358 case SLDI: |
| 4359 case SPLATI: |
| 4360 case INSERT: |
| 4361 case INSVE: |
| 4362 UNIMPLEMENTED(); |
| 4363 break; |
| 4364 default: |
| 4365 UNREACHABLE(); |
| 4366 } |
| 4367 } |
| 4368 |
| 4369 void Simulator::DecodeTypeMsaBIT() { |
| 4370 DCHECK(IsMipsArchVariant(kMips32r6)); |
| 4371 DCHECK(CpuFeatures::IsSupported(MIPS_SIMD)); |
| 4372 uint32_t opcode = instr_.InstructionBits() & kMsaBITMask; |
| 4373 |
| 4374 switch (opcode) { |
| 4375 case SLLI: |
| 4376 case SRAI: |
| 4377 case SRLI: |
| 4378 case BCLRI: |
| 4379 case BSETI: |
| 4380 case BNEGI: |
| 4381 case BINSLI: |
| 4382 case BINSRI: |
| 4383 case SAT_S: |
| 4384 case SAT_U: |
| 4385 case SRARI: |
| 4386 case SRLRI: |
| 4387 UNIMPLEMENTED(); |
| 4388 break; |
| 4389 default: |
| 4390 UNREACHABLE(); |
| 4391 } |
| 4392 } |
| 4393 |
| 4394 void Simulator::DecodeTypeMsaMI10() { |
| 4395 DCHECK(IsMipsArchVariant(kMips32r6)); |
| 4396 DCHECK(CpuFeatures::IsSupported(MIPS_SIMD)); |
| 4397 uint32_t opcode = instr_.InstructionBits() & kMsaMI10Mask; |
| 4398 if (opcode == MSA_LD) { |
| 4399 UNIMPLEMENTED(); |
| 4400 } else if (opcode == MSA_ST) { |
| 4401 UNIMPLEMENTED(); |
| 4402 } else { |
| 4403 UNREACHABLE(); |
| 4404 } |
| 4405 } |
| 4406 |
| 4407 void Simulator::DecodeTypeMsa3R() { |
| 4408 DCHECK(IsMipsArchVariant(kMips32r6)); |
| 4409 DCHECK(CpuFeatures::IsSupported(MIPS_SIMD)); |
| 4410 uint32_t opcode = instr_.InstructionBits() & kMsa3RMask; |
| 4411 switch (opcode) { |
| 4412 case SLL_MSA: |
| 4413 case SRA_MSA: |
| 4414 case SRL_MSA: |
| 4415 case BCLR: |
| 4416 case BSET: |
| 4417 case BNEG: |
| 4418 case BINSL: |
| 4419 case BINSR: |
| 4420 case ADDV: |
| 4421 case SUBV: |
| 4422 case MAX_S: |
| 4423 case MAX_U: |
| 4424 case MIN_S: |
| 4425 case MIN_U: |
| 4426 case MAX_A: |
| 4427 case MIN_A: |
| 4428 case CEQ: |
| 4429 case CLT_S: |
| 4430 case CLT_U: |
| 4431 case CLE_S: |
| 4432 case CLE_U: |
| 4433 case ADD_A: |
| 4434 case ADDS_A: |
| 4435 case ADDS_S: |
| 4436 case ADDS_U: |
| 4437 case AVE_S: |
| 4438 case AVE_U: |
| 4439 case AVER_S: |
| 4440 case AVER_U: |
| 4441 case SUBS_S: |
| 4442 case SUBS_U: |
| 4443 case SUBSUS_U: |
| 4444 case SUBSUU_S: |
| 4445 case ASUB_S: |
| 4446 case ASUB_U: |
| 4447 case MULV: |
| 4448 case MADDV: |
| 4449 case MSUBV: |
| 4450 case DIV_S_MSA: |
| 4451 case DIV_U: |
| 4452 case MOD_S: |
| 4453 case MOD_U: |
| 4454 case DOTP_S: |
| 4455 case DOTP_U: |
| 4456 case DPADD_S: |
| 4457 case DPADD_U: |
| 4458 case DPSUB_S: |
| 4459 case DPSUB_U: |
| 4460 case SLD: |
| 4461 case SPLAT: |
| 4462 case PCKEV: |
| 4463 case PCKOD: |
| 4464 case ILVL: |
| 4465 case ILVR: |
| 4466 case ILVEV: |
| 4467 case ILVOD: |
| 4468 case VSHF: |
| 4469 case SRAR: |
| 4470 case SRLR: |
| 4471 case HADD_S: |
| 4472 case HADD_U: |
| 4473 case HSUB_S: |
| 4474 case HSUB_U: |
| 4475 UNIMPLEMENTED(); |
| 4476 break; |
| 4477 default: |
| 4478 UNREACHABLE(); |
| 4479 } |
| 4480 } |
| 4481 |
| 4482 void Simulator::DecodeTypeMsa3RF() { |
| 4483 DCHECK(IsMipsArchVariant(kMips32r6)); |
| 4484 DCHECK(CpuFeatures::IsSupported(MIPS_SIMD)); |
| 4485 uint32_t opcode = instr_.InstructionBits() & kMsa3RFMask; |
| 4486 switch (opcode) { |
| 4487 case FCAF: |
| 4488 case FCUN: |
| 4489 case FCEQ: |
| 4490 case FCUEQ: |
| 4491 case FCLT: |
| 4492 case FCULT: |
| 4493 case FCLE: |
| 4494 case FCULE: |
| 4495 case FSAF: |
| 4496 case FSUN: |
| 4497 case FSEQ: |
| 4498 case FSUEQ: |
| 4499 case FSLT: |
| 4500 case FSULT: |
| 4501 case FSLE: |
| 4502 case FSULE: |
| 4503 case FADD: |
| 4504 case FSUB: |
| 4505 case FMUL: |
| 4506 case FDIV: |
| 4507 case FMADD: |
| 4508 case FMSUB: |
| 4509 case FEXP2: |
| 4510 case FEXDO: |
| 4511 case FTQ: |
| 4512 case FMIN: |
| 4513 case FMIN_A: |
| 4514 case FMAX: |
| 4515 case FMAX_A: |
| 4516 case FCOR: |
| 4517 case FCUNE: |
| 4518 case FCNE: |
| 4519 case MUL_Q: |
| 4520 case MADD_Q: |
| 4521 case MSUB_Q: |
| 4522 case FSOR: |
| 4523 case FSUNE: |
| 4524 case FSNE: |
| 4525 case MULR_Q: |
| 4526 case MADDR_Q: |
| 4527 case MSUBR_Q: |
| 4528 UNIMPLEMENTED(); |
| 4529 break; |
| 4530 default: |
| 4531 UNREACHABLE(); |
| 4532 } |
| 4533 } |
| 4534 |
| 4535 void Simulator::DecodeTypeMsaVec() { |
| 4536 DCHECK(IsMipsArchVariant(kMips32r6)); |
| 4537 DCHECK(CpuFeatures::IsSupported(MIPS_SIMD)); |
| 4538 uint32_t opcode = instr_.InstructionBits() & kMsaVECMask; |
| 4539 switch (opcode) { |
| 4540 case AND_V: |
| 4541 case OR_V: |
| 4542 case NOR_V: |
| 4543 case XOR_V: |
| 4544 case BMNZ_V: |
| 4545 case BMZ_V: |
| 4546 case BSEL_V: |
| 4547 UNIMPLEMENTED(); |
| 4548 break; |
| 4549 default: |
| 4550 UNREACHABLE(); |
| 4551 } |
| 4552 } |
| 4553 |
| 4554 void Simulator::DecodeTypeMsa2R() { |
| 4555 DCHECK(IsMipsArchVariant(kMips32r6)); |
| 4556 DCHECK(CpuFeatures::IsSupported(MIPS_SIMD)); |
| 4557 uint32_t opcode = instr_.InstructionBits() & kMsa2RMask; |
| 4558 switch (opcode) { |
| 4559 case FILL: |
| 4560 switch (DecodeMsaDataFormat()) { |
| 4561 case MSA_BYTE: { |
| 4562 int8_t wd[16]; |
| 4563 int32_t rs = get_register(instr_.WsValue()); |
| 4564 for (int i = 0; i < 16; i++) { |
| 4565 wd[i] = rs & 0xFFu; |
| 4566 } |
| 4567 set_msa_register(instr_.WdValue(), wd); |
| 4568 TraceMSARegWr(wd, BYTE); |
| 4569 break; |
| 4570 } |
| 4571 case MSA_HALF: { |
| 4572 int16_t wd[8]; |
| 4573 int32_t rs = get_register(instr_.WsValue()); |
| 4574 for (int i = 0; i < 8; i++) { |
| 4575 wd[i] = rs & 0xFFFFu; |
| 4576 } |
| 4577 set_msa_register(instr_.WdValue(), wd); |
| 4578 TraceMSARegWr(wd, HALF); |
| 4579 break; |
| 4580 } |
| 4581 case MSA_WORD: { |
| 4582 int32_t wd[4]; |
| 4583 int32_t rs = get_register(instr_.WsValue()); |
| 4584 for (int i = 0; i < 4; i++) { |
| 4585 wd[i] = rs; |
| 4586 } |
| 4587 set_msa_register(instr_.WdValue(), wd); |
| 4588 TraceMSARegWr(wd, WORD); |
| 4589 break; |
| 4590 } |
| 4591 default: |
| 4592 UNREACHABLE(); |
| 4593 } |
| 4594 break; |
| 4595 case PCNT: |
| 4596 case NLOC: |
| 4597 case NLZC: |
| 4598 UNIMPLEMENTED(); |
| 4599 break; |
| 4600 default: |
| 4601 UNREACHABLE(); |
| 4602 } |
| 4603 } |
| 4604 |
| 4605 void Simulator::DecodeTypeMsa2RF() { |
| 4606 DCHECK(IsMipsArchVariant(kMips32r6)); |
| 4607 DCHECK(CpuFeatures::IsSupported(MIPS_SIMD)); |
| 4608 uint32_t opcode = instr_.InstructionBits() & kMsa2RFMask; |
| 4609 switch (opcode) { |
| 4610 case FCLASS: |
| 4611 case FTRUNC_S: |
| 4612 case FTRUNC_U: |
| 4613 case FSQRT: |
| 4614 case FRSQRT: |
| 4615 case FRCP: |
| 4616 case FRINT: |
| 4617 case FLOG2: |
| 4618 case FEXUPL: |
| 4619 case FEXUPR: |
| 4620 case FFQL: |
| 4621 case FFQR: |
| 4622 case FTINT_S: |
| 4623 case FTINT_U: |
| 4624 case FFINT_S: |
| 4625 case FFINT_U: |
| 4626 UNIMPLEMENTED(); |
| 4627 break; |
| 4628 default: |
| 4629 UNREACHABLE(); |
| 4630 } |
| 4631 } |
| 4632 |
4119 void Simulator::DecodeTypeRegister() { | 4633 void Simulator::DecodeTypeRegister() { |
4120 // ---------- Execution. | 4634 // ---------- Execution. |
4121 switch (instr_.OpcodeFieldRaw()) { | 4635 switch (instr_.OpcodeFieldRaw()) { |
4122 case COP1: | 4636 case COP1: |
4123 DecodeTypeRegisterCOP1(); | 4637 DecodeTypeRegisterCOP1(); |
4124 break; | 4638 break; |
4125 case COP1X: | 4639 case COP1X: |
4126 DecodeTypeRegisterCOP1X(); | 4640 DecodeTypeRegisterCOP1X(); |
4127 break; | 4641 break; |
4128 case SPECIAL: | 4642 case SPECIAL: |
4129 DecodeTypeRegisterSPECIAL(); | 4643 DecodeTypeRegisterSPECIAL(); |
4130 break; | 4644 break; |
4131 case SPECIAL2: | 4645 case SPECIAL2: |
4132 DecodeTypeRegisterSPECIAL2(); | 4646 DecodeTypeRegisterSPECIAL2(); |
4133 break; | 4647 break; |
4134 case SPECIAL3: | 4648 case SPECIAL3: |
4135 DecodeTypeRegisterSPECIAL3(); | 4649 DecodeTypeRegisterSPECIAL3(); |
4136 break; | 4650 break; |
| 4651 case MSA: |
| 4652 switch (instr_.MSAMinorOpcodeField()) { |
| 4653 case kMsaMinor3R: |
| 4654 DecodeTypeMsa3R(); |
| 4655 break; |
| 4656 case kMsaMinor3RF: |
| 4657 DecodeTypeMsa3RF(); |
| 4658 break; |
| 4659 case kMsaMinorVEC: |
| 4660 DecodeTypeMsaVec(); |
| 4661 break; |
| 4662 case kMsaMinor2R: |
| 4663 DecodeTypeMsa2R(); |
| 4664 break; |
| 4665 case kMsaMinor2RF: |
| 4666 DecodeTypeMsa2RF(); |
| 4667 break; |
| 4668 default: |
| 4669 UNREACHABLE(); |
| 4670 } |
| 4671 break; |
4137 default: | 4672 default: |
4138 UNREACHABLE(); | 4673 UNREACHABLE(); |
4139 } | 4674 } |
4140 } | 4675 } |
4141 | 4676 |
4142 | 4677 |
4143 // Type 2: instructions using a 16, 21 or 26 bits immediate. (e.g. beq, beqc). | 4678 // Type 2: instructions using a 16, 21 or 26 bits immediate. (e.g. beq, beqc). |
4144 void Simulator::DecodeTypeImmediate() { | 4679 void Simulator::DecodeTypeImmediate() { |
4145 // Instruction fields. | 4680 // Instruction fields. |
4146 Opcode op = instr_.OpcodeFieldRaw(); | 4681 Opcode op = instr_.OpcodeFieldRaw(); |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4231 bool do_branch = (instr_.FBtrueValue()) ? cc_value : !cc_value; | 4766 bool do_branch = (instr_.FBtrueValue()) ? cc_value : !cc_value; |
4232 BranchHelper(do_branch); | 4767 BranchHelper(do_branch); |
4233 break; | 4768 break; |
4234 } | 4769 } |
4235 case BC1EQZ: | 4770 case BC1EQZ: |
4236 BranchHelper(!(get_fpu_register(ft_reg) & 0x1)); | 4771 BranchHelper(!(get_fpu_register(ft_reg) & 0x1)); |
4237 break; | 4772 break; |
4238 case BC1NEZ: | 4773 case BC1NEZ: |
4239 BranchHelper(get_fpu_register(ft_reg) & 0x1); | 4774 BranchHelper(get_fpu_register(ft_reg) & 0x1); |
4240 break; | 4775 break; |
| 4776 case BZ_V: |
| 4777 case BZ_B: |
| 4778 case BZ_H: |
| 4779 case BZ_W: |
| 4780 case BZ_D: |
| 4781 case BNZ_V: |
| 4782 case BNZ_B: |
| 4783 case BNZ_H: |
| 4784 case BNZ_W: |
| 4785 case BNZ_D: |
| 4786 UNIMPLEMENTED(); |
| 4787 break; |
4241 default: | 4788 default: |
4242 UNREACHABLE(); | 4789 UNREACHABLE(); |
4243 } | 4790 } |
4244 break; | 4791 break; |
4245 // ------------- REGIMM class. | 4792 // ------------- REGIMM class. |
4246 case REGIMM: | 4793 case REGIMM: |
4247 switch (instr_.RtFieldRaw()) { | 4794 switch (instr_.RtFieldRaw()) { |
4248 case BLTZ: | 4795 case BLTZ: |
4249 BranchHelper(rs < 0); | 4796 BranchHelper(rs < 0); |
4250 break; | 4797 break; |
(...skipping 322 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4573 } | 5120 } |
4574 default: | 5121 default: |
4575 UNREACHABLE(); | 5122 UNREACHABLE(); |
4576 break; | 5123 break; |
4577 } | 5124 } |
4578 } | 5125 } |
4579 } | 5126 } |
4580 SetResult(rs_reg, alu_out); | 5127 SetResult(rs_reg, alu_out); |
4581 break; | 5128 break; |
4582 } | 5129 } |
| 5130 case MSA: |
| 5131 switch (instr_.MSAMinorOpcodeField()) { |
| 5132 case kMsaMinorI8: |
| 5133 DecodeTypeMsaI8(); |
| 5134 break; |
| 5135 case kMsaMinorI5: |
| 5136 DecodeTypeMsaI5(); |
| 5137 break; |
| 5138 case kMsaMinorI10: |
| 5139 DecodeTypeMsaI10(); |
| 5140 break; |
| 5141 case kMsaMinorELM: |
| 5142 DecodeTypeMsaELM(); |
| 5143 break; |
| 5144 case kMsaMinorBIT: |
| 5145 DecodeTypeMsaBIT(); |
| 5146 break; |
| 5147 case kMsaMinorMI10: |
| 5148 DecodeTypeMsaMI10(); |
| 5149 break; |
| 5150 default: |
| 5151 UNREACHABLE(); |
| 5152 break; |
| 5153 } |
| 5154 break; |
4583 default: | 5155 default: |
4584 UNREACHABLE(); | 5156 UNREACHABLE(); |
4585 } | 5157 } |
4586 | 5158 |
4587 if (execute_branch_delay_instruction) { | 5159 if (execute_branch_delay_instruction) { |
4588 // Execute branch delay slot | 5160 // Execute branch delay slot |
4589 // We don't check for end_sim_pc. First it should not be met as the current | 5161 // We don't check for end_sim_pc. First it should not be met as the current |
4590 // pc is valid. Secondly a jump should always execute its branch delay slot. | 5162 // pc is valid. Secondly a jump should always execute its branch delay slot. |
4591 Instruction* branch_delay_instr = | 5163 Instruction* branch_delay_instr = |
4592 reinterpret_cast<Instruction*>(get_pc() + Instruction::kInstrSize); | 5164 reinterpret_cast<Instruction*>(get_pc() + Instruction::kInstrSize); |
(...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4849 | 5421 |
4850 | 5422 |
4851 #undef UNSUPPORTED | 5423 #undef UNSUPPORTED |
4852 | 5424 |
4853 } // namespace internal | 5425 } // namespace internal |
4854 } // namespace v8 | 5426 } // namespace v8 |
4855 | 5427 |
4856 #endif // USE_SIMULATOR | 5428 #endif // USE_SIMULATOR |
4857 | 5429 |
4858 #endif // V8_TARGET_ARCH_MIPS | 5430 #endif // V8_TARGET_ARCH_MIPS |
OLD | NEW |