Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(66)

Side by Side Diff: src/mips/simulator-mips.cc

Issue 2799923002: MIPS[64]: Implement fill.df, copy_u.df, copy_s.df instructions in simulator (Closed)
Patch Set: Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
1123 char buffer[2 * sizeof(registers_[0])]; 1125 char buffer[2 * sizeof(registers_[0])];
1124 memcpy(buffer, &registers_[reg], 2 * sizeof(registers_[0])); 1126 memcpy(buffer, &registers_[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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698