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

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: Rebase Created 3 years, 7 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
« no previous file with comments | « src/mips/simulator-mips.h ('k') | src/mips64/constants-mips64.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
1125 char buffer[2 * sizeof(registers_[0])]; 1127 char buffer[2 * sizeof(registers_[0])];
1126 memcpy(buffer, &registers_[reg], 2 * sizeof(registers_[0])); 1128 memcpy(buffer, &registers_[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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/mips/simulator-mips.h ('k') | src/mips64/constants-mips64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698