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