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_MIPS64 | 10 #if V8_TARGET_ARCH_MIPS64 |
(...skipping 821 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
832 break_count_ = 0; | 832 break_count_ = 0; |
833 break_pc_ = NULL; | 833 break_pc_ = NULL; |
834 break_instr_ = 0; | 834 break_instr_ = 0; |
835 | 835 |
836 // Set up architecture state. | 836 // Set up architecture state. |
837 // All registers are initialized to zero to start with. | 837 // All registers are initialized to zero to start with. |
838 for (int i = 0; i < kNumSimuRegisters; i++) { | 838 for (int i = 0; i < kNumSimuRegisters; i++) { |
839 registers_[i] = 0; | 839 registers_[i] = 0; |
840 } | 840 } |
841 for (int i = 0; i < kNumFPURegisters; i++) { | 841 for (int i = 0; i < kNumFPURegisters; i++) { |
842 FPUregisters_[i] = 0; | 842 FPUregisters_[2 * i] = 0; |
| 843 FPUregisters_[2 * i + 1] = 0; // upper part for MSA ASE |
843 } | 844 } |
844 | 845 |
845 if (kArchVariant == kMips64r6) { | 846 if (kArchVariant == kMips64r6) { |
846 FCSR_ = kFCSRNaN2008FlagMask; | 847 FCSR_ = kFCSRNaN2008FlagMask; |
847 } else { | 848 } else { |
848 FCSR_ = 0; | 849 FCSR_ = 0; |
849 } | 850 } |
850 | 851 |
851 // The sp is initialized to point to the bottom (high address) of the | 852 // The sp is initialized to point to the bottom (high address) of the |
852 // allocated stack area. To be safe in potential stack underflows we leave | 853 // allocated stack area. To be safe in potential stack underflows we leave |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
987 void Simulator::set_dw_register(int reg, const int* dbl) { | 988 void Simulator::set_dw_register(int reg, const int* dbl) { |
988 DCHECK((reg >= 0) && (reg < kNumSimuRegisters)); | 989 DCHECK((reg >= 0) && (reg < kNumSimuRegisters)); |
989 registers_[reg] = dbl[1]; | 990 registers_[reg] = dbl[1]; |
990 registers_[reg] = registers_[reg] << 32; | 991 registers_[reg] = registers_[reg] << 32; |
991 registers_[reg] += dbl[0]; | 992 registers_[reg] += dbl[0]; |
992 } | 993 } |
993 | 994 |
994 | 995 |
995 void Simulator::set_fpu_register(int fpureg, int64_t value) { | 996 void Simulator::set_fpu_register(int fpureg, int64_t value) { |
996 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters)); | 997 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters)); |
997 FPUregisters_[fpureg] = value; | 998 FPUregisters_[fpureg * 2] = value; |
998 } | 999 } |
999 | 1000 |
1000 | 1001 |
1001 void Simulator::set_fpu_register_word(int fpureg, int32_t value) { | 1002 void Simulator::set_fpu_register_word(int fpureg, int32_t value) { |
1002 // Set ONLY lower 32-bits, leaving upper bits untouched. | 1003 // Set ONLY lower 32-bits, leaving upper bits untouched. |
1003 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters)); | 1004 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters)); |
1004 int32_t* pword; | 1005 int32_t* pword; |
1005 if (kArchEndian == kLittle) { | 1006 if (kArchEndian == kLittle) { |
1006 pword = reinterpret_cast<int32_t*>(&FPUregisters_[fpureg]); | 1007 pword = reinterpret_cast<int32_t*>(&FPUregisters_[fpureg * 2]); |
1007 } else { | 1008 } else { |
1008 pword = reinterpret_cast<int32_t*>(&FPUregisters_[fpureg]) + 1; | 1009 pword = reinterpret_cast<int32_t*>(&FPUregisters_[fpureg * 2]) + 1; |
1009 } | 1010 } |
1010 *pword = value; | 1011 *pword = value; |
1011 } | 1012 } |
1012 | 1013 |
1013 | 1014 |
1014 void Simulator::set_fpu_register_hi_word(int fpureg, int32_t value) { | 1015 void Simulator::set_fpu_register_hi_word(int fpureg, int32_t value) { |
1015 // Set ONLY upper 32-bits, leaving lower bits untouched. | 1016 // Set ONLY upper 32-bits, leaving lower bits untouched. |
1016 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters)); | 1017 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters)); |
1017 int32_t* phiword; | 1018 int32_t* phiword; |
1018 if (kArchEndian == kLittle) { | 1019 if (kArchEndian == kLittle) { |
1019 phiword = (reinterpret_cast<int32_t*>(&FPUregisters_[fpureg])) + 1; | 1020 phiword = (reinterpret_cast<int32_t*>(&FPUregisters_[fpureg * 2])) + 1; |
1020 } else { | 1021 } else { |
1021 phiword = reinterpret_cast<int32_t*>(&FPUregisters_[fpureg]); | 1022 phiword = reinterpret_cast<int32_t*>(&FPUregisters_[fpureg * 2]); |
1022 } | 1023 } |
1023 *phiword = value; | 1024 *phiword = value; |
1024 } | 1025 } |
1025 | 1026 |
1026 | 1027 |
1027 void Simulator::set_fpu_register_float(int fpureg, float value) { | 1028 void Simulator::set_fpu_register_float(int fpureg, float value) { |
1028 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters)); | 1029 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters)); |
1029 *bit_cast<float*>(&FPUregisters_[fpureg]) = value; | 1030 *bit_cast<float*>(&FPUregisters_[fpureg * 2]) = value; |
1030 } | 1031 } |
1031 | 1032 |
1032 | 1033 |
1033 void Simulator::set_fpu_register_double(int fpureg, double value) { | 1034 void Simulator::set_fpu_register_double(int fpureg, double value) { |
1034 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters)); | 1035 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters)); |
1035 *bit_cast<double*>(&FPUregisters_[fpureg]) = value; | 1036 *bit_cast<double*>(&FPUregisters_[fpureg * 2]) = value; |
1036 } | 1037 } |
1037 | 1038 |
1038 | 1039 |
1039 // Get the register from the architecture state. This function does handle | 1040 // Get the register from the architecture state. This function does handle |
1040 // the special case of accessing the PC register. | 1041 // the special case of accessing the PC register. |
1041 int64_t Simulator::get_register(int reg) const { | 1042 int64_t Simulator::get_register(int reg) const { |
1042 DCHECK((reg >= 0) && (reg < kNumSimuRegisters)); | 1043 DCHECK((reg >= 0) && (reg < kNumSimuRegisters)); |
1043 if (reg == 0) | 1044 if (reg == 0) |
1044 return 0; | 1045 return 0; |
1045 else | 1046 else |
(...skipping 10 matching lines...) Expand all Loading... |
1056 // into the double precision floating point value and return it. | 1057 // into the double precision floating point value and return it. |
1057 char buffer[sizeof(registers_[0])]; | 1058 char buffer[sizeof(registers_[0])]; |
1058 memcpy(buffer, ®isters_[reg], sizeof(registers_[0])); | 1059 memcpy(buffer, ®isters_[reg], sizeof(registers_[0])); |
1059 memcpy(&dm_val, buffer, sizeof(registers_[0])); | 1060 memcpy(&dm_val, buffer, sizeof(registers_[0])); |
1060 return(dm_val); | 1061 return(dm_val); |
1061 } | 1062 } |
1062 | 1063 |
1063 | 1064 |
1064 int64_t Simulator::get_fpu_register(int fpureg) const { | 1065 int64_t Simulator::get_fpu_register(int fpureg) const { |
1065 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters)); | 1066 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters)); |
1066 return FPUregisters_[fpureg]; | 1067 return FPUregisters_[fpureg * 2]; |
1067 } | 1068 } |
1068 | 1069 |
1069 | 1070 |
1070 int32_t Simulator::get_fpu_register_word(int fpureg) const { | 1071 int32_t Simulator::get_fpu_register_word(int fpureg) const { |
1071 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters)); | 1072 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters)); |
1072 return static_cast<int32_t>(FPUregisters_[fpureg] & 0xffffffff); | 1073 return static_cast<int32_t>(FPUregisters_[fpureg * 2] & 0xffffffff); |
1073 } | 1074 } |
1074 | 1075 |
1075 | 1076 |
1076 int32_t Simulator::get_fpu_register_signed_word(int fpureg) const { | 1077 int32_t Simulator::get_fpu_register_signed_word(int fpureg) const { |
1077 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters)); | 1078 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters)); |
1078 return static_cast<int32_t>(FPUregisters_[fpureg] & 0xffffffff); | 1079 return static_cast<int32_t>(FPUregisters_[fpureg * 2] & 0xffffffff); |
1079 } | 1080 } |
1080 | 1081 |
1081 | 1082 |
1082 int32_t Simulator::get_fpu_register_hi_word(int fpureg) const { | 1083 int32_t Simulator::get_fpu_register_hi_word(int fpureg) const { |
1083 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters)); | 1084 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters)); |
1084 return static_cast<int32_t>((FPUregisters_[fpureg] >> 32) & 0xffffffff); | 1085 return static_cast<int32_t>((FPUregisters_[fpureg * 2] >> 32) & 0xffffffff); |
1085 } | 1086 } |
1086 | 1087 |
1087 | 1088 |
1088 float Simulator::get_fpu_register_float(int fpureg) const { | 1089 float Simulator::get_fpu_register_float(int fpureg) const { |
1089 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters)); | 1090 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters)); |
1090 return *bit_cast<float*>(const_cast<int64_t*>(&FPUregisters_[fpureg])); | 1091 return *bit_cast<float*>(const_cast<int64_t*>(&FPUregisters_[fpureg * 2])); |
1091 } | 1092 } |
1092 | 1093 |
1093 | 1094 |
1094 double Simulator::get_fpu_register_double(int fpureg) const { | 1095 double Simulator::get_fpu_register_double(int fpureg) const { |
1095 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters)); | 1096 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters)); |
1096 return *bit_cast<double*>(&FPUregisters_[fpureg]); | 1097 return *bit_cast<double*>(&FPUregisters_[fpureg * 2]); |
1097 } | 1098 } |
1098 | 1099 |
| 1100 template <typename T> |
| 1101 void Simulator::get_msa_register(int wreg, T* value) { |
| 1102 DCHECK((wreg >= 0) && (wreg < kNumMSARegisters)); |
| 1103 memcpy(value, FPUregisters_ + wreg * 2, kSimd128Size); |
| 1104 } |
| 1105 |
| 1106 template <typename T> |
| 1107 void Simulator::set_msa_register(int wreg, const T* value) { |
| 1108 DCHECK((wreg >= 0) && (wreg < kNumMSARegisters)); |
| 1109 memcpy(FPUregisters_ + wreg * 2, value, kSimd128Size); |
| 1110 } |
1099 | 1111 |
1100 // Runtime FP routines take up to two double arguments and zero | 1112 // Runtime FP routines take up to two double arguments and zero |
1101 // or one integer arguments. All are constructed here, | 1113 // or one integer arguments. All are constructed here, |
1102 // from a0-a3 or f12 and f13 (n64), or f14 (O32). | 1114 // from a0-a3 or f12 and f13 (n64), or f14 (O32). |
1103 void Simulator::GetFpArgs(double* x, double* y, int32_t* z) { | 1115 void Simulator::GetFpArgs(double* x, double* y, int32_t* z) { |
1104 if (!IsMipsSoftFloatABI) { | 1116 if (!IsMipsSoftFloatABI) { |
1105 const int fparg2 = 13; | 1117 const int fparg2 = 13; |
1106 *x = get_fpu_register_double(12); | 1118 *x = get_fpu_register_double(12); |
1107 *y = get_fpu_register_double(fparg2); | 1119 *y = get_fpu_register_double(fparg2); |
1108 *z = static_cast<int32_t>(get_register(a2)); | 1120 *z = static_cast<int32_t>(get_register(a2)); |
(...skipping 554 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1663 " uint32:%" PRIu32 " int64:%" PRId64 " uint64:%" PRIu64, | 1675 " uint32:%" PRIu32 " int64:%" PRId64 " uint64:%" PRIu64, |
1664 v.fmt_int64, icount_, v.fmt_int32[0], v.fmt_int32[0], | 1676 v.fmt_int64, icount_, v.fmt_int32[0], v.fmt_int32[0], |
1665 v.fmt_int64, v.fmt_int64); | 1677 v.fmt_int64, v.fmt_int64); |
1666 break; | 1678 break; |
1667 default: | 1679 default: |
1668 UNREACHABLE(); | 1680 UNREACHABLE(); |
1669 } | 1681 } |
1670 } | 1682 } |
1671 } | 1683 } |
1672 | 1684 |
| 1685 template <typename T> |
| 1686 void Simulator::TraceMSARegWr(T* value, TraceType t) { |
| 1687 if (::v8::internal::FLAG_trace_sim) { |
| 1688 union { |
| 1689 uint8_t b[16]; |
| 1690 uint16_t h[8]; |
| 1691 uint32_t w[4]; |
| 1692 uint64_t d[2]; |
| 1693 float f[4]; |
| 1694 double df[2]; |
| 1695 } v; |
| 1696 memcpy(v.b, value, kSimd128Size); |
| 1697 switch (t) { |
| 1698 case BYTE: |
| 1699 SNPrintF(trace_buf_, |
| 1700 "LO: %016" PRIx64 " HI: %016" PRIx64 " (%" PRIu64 ")", |
| 1701 v.d[0], v.d[1], icount_); |
| 1702 break; |
| 1703 case HALF: |
| 1704 SNPrintF(trace_buf_, |
| 1705 "LO: %016" PRIx64 " HI: %016" PRIx64 " (%" PRIu64 ")", |
| 1706 v.d[0], v.d[1], icount_); |
| 1707 break; |
| 1708 case WORD: |
| 1709 SNPrintF(trace_buf_, |
| 1710 "LO: %016" PRIx64 " HI: %016" PRIx64 " (%" PRIu64 |
| 1711 ") int32[0..3]:%" PRId32 " %" PRId32 " %" PRId32 |
| 1712 " %" PRId32, |
| 1713 v.d[0], v.d[1], icount_, v.w[0], v.w[1], v.w[2], v.w[3]); |
| 1714 break; |
| 1715 case DWORD: |
| 1716 SNPrintF(trace_buf_, |
| 1717 "LO: %016" PRIx64 " HI: %016" PRIx64 " (%" PRIu64 ")", |
| 1718 v.d[0], v.d[1], icount_); |
| 1719 break; |
| 1720 case FLOAT: |
| 1721 SNPrintF(trace_buf_, |
| 1722 "LO: %016" PRIx64 " HI: %016" PRIx64 " (%" PRIu64 |
| 1723 ") flt[0..3]:%e %e %e %e", |
| 1724 v.d[0], v.d[1], icount_, v.f[0], v.f[1], v.f[2], v.f[3]); |
| 1725 break; |
| 1726 case DOUBLE: |
| 1727 SNPrintF(trace_buf_, |
| 1728 "LO: %016" PRIx64 " HI: %016" PRIx64 " (%" PRIu64 |
| 1729 ") dbl[0..1]:%e %e", |
| 1730 v.d[0], v.d[1], icount_, v.df[0], v.df[1]); |
| 1731 break; |
| 1732 default: |
| 1733 UNREACHABLE(); |
| 1734 } |
| 1735 } |
| 1736 } |
| 1737 |
1673 // TODO(plind): consider making icount_ printing a flag option. | 1738 // TODO(plind): consider making icount_ printing a flag option. |
1674 void Simulator::TraceMemRd(int64_t addr, int64_t value, TraceType t) { | 1739 void Simulator::TraceMemRd(int64_t addr, int64_t value, TraceType t) { |
1675 if (::v8::internal::FLAG_trace_sim) { | 1740 if (::v8::internal::FLAG_trace_sim) { |
1676 union { | 1741 union { |
1677 int64_t fmt_int64; | 1742 int64_t fmt_int64; |
1678 int32_t fmt_int32[2]; | 1743 int32_t fmt_int32[2]; |
1679 float fmt_float[2]; | 1744 float fmt_float[2]; |
1680 double fmt_double; | 1745 double fmt_double; |
1681 } v; | 1746 } v; |
1682 v.fmt_int64 = value; | 1747 v.fmt_int64 = value; |
(...skipping 2616 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4299 } | 4364 } |
4300 } | 4365 } |
4301 SetResult(rd_reg(), alu_out); | 4366 SetResult(rd_reg(), alu_out); |
4302 break; | 4367 break; |
4303 } | 4368 } |
4304 default: | 4369 default: |
4305 UNREACHABLE(); | 4370 UNREACHABLE(); |
4306 } | 4371 } |
4307 } | 4372 } |
4308 | 4373 |
| 4374 int Simulator::DecodeMsaDataFormat() { |
| 4375 int df = -1; |
| 4376 if (instr_.IsMSABranchInstr()) { |
| 4377 switch (instr_.RsFieldRaw()) { |
| 4378 case BZ_V: |
| 4379 case BNZ_V: |
| 4380 df = MSA_VECT; |
| 4381 break; |
| 4382 case BZ_B: |
| 4383 case BNZ_B: |
| 4384 df = MSA_BYTE; |
| 4385 break; |
| 4386 case BZ_H: |
| 4387 case BNZ_H: |
| 4388 df = MSA_HALF; |
| 4389 break; |
| 4390 case BZ_W: |
| 4391 case BNZ_W: |
| 4392 df = MSA_WORD; |
| 4393 break; |
| 4394 case BZ_D: |
| 4395 case BNZ_D: |
| 4396 df = MSA_DWORD; |
| 4397 break; |
| 4398 default: |
| 4399 UNREACHABLE(); |
| 4400 break; |
| 4401 } |
| 4402 } else { |
| 4403 int DF[] = {MSA_BYTE, MSA_HALF, MSA_WORD, MSA_DWORD}; |
| 4404 switch (instr_.MSAMinorOpcodeField()) { |
| 4405 case kMsaMinorI5: |
| 4406 case kMsaMinorI10: |
| 4407 case kMsaMinor3R: |
| 4408 df = DF[instr_.Bits(22, 21)]; |
| 4409 break; |
| 4410 case kMsaMinorMI10: |
| 4411 df = DF[instr_.Bits(1, 0)]; |
| 4412 break; |
| 4413 case kMsaMinorBIT: |
| 4414 df = DF[instr_.MsaBitDf()]; |
| 4415 break; |
| 4416 case kMsaMinorELM: |
| 4417 df = DF[instr_.MsaElmDf()]; |
| 4418 break; |
| 4419 case kMsaMinor3RF: { |
| 4420 uint32_t opcode = instr_.InstructionBits() & kMsa3RFMask; |
| 4421 switch (opcode) { |
| 4422 case FEXDO: |
| 4423 case FTQ: |
| 4424 case MUL_Q: |
| 4425 case MADD_Q: |
| 4426 case MSUB_Q: |
| 4427 case MULR_Q: |
| 4428 case MADDR_Q: |
| 4429 case MSUBR_Q: |
| 4430 df = DF[1 + instr_.Bit(21)]; |
| 4431 break; |
| 4432 default: |
| 4433 df = DF[2 + instr_.Bit(21)]; |
| 4434 break; |
| 4435 } |
| 4436 } break; |
| 4437 case kMsaMinor2R: |
| 4438 df = DF[instr_.Bits(17, 16)]; |
| 4439 break; |
| 4440 case kMsaMinor2RF: |
| 4441 df = DF[2 + instr_.Bit(16)]; |
| 4442 break; |
| 4443 default: |
| 4444 UNREACHABLE(); |
| 4445 break; |
| 4446 } |
| 4447 } |
| 4448 return df; |
| 4449 } |
| 4450 |
| 4451 void Simulator::DecodeTypeMsaI8() { |
| 4452 DCHECK(kArchVariant == kMips64r6); |
| 4453 DCHECK(CpuFeatures::IsSupported(MIPS_SIMD)); |
| 4454 uint32_t opcode = instr_.InstructionBits() & kMsaI8Mask; |
| 4455 |
| 4456 switch (opcode) { |
| 4457 case ANDI_B: |
| 4458 case ORI_B: |
| 4459 case NORI_B: |
| 4460 case XORI_B: |
| 4461 case BMNZI_B: |
| 4462 case BMZI_B: |
| 4463 case BSELI_B: |
| 4464 case SHF_B: |
| 4465 case SHF_H: |
| 4466 case SHF_W: |
| 4467 UNIMPLEMENTED(); |
| 4468 break; |
| 4469 default: |
| 4470 UNREACHABLE(); |
| 4471 } |
| 4472 } |
| 4473 |
| 4474 void Simulator::DecodeTypeMsaI5() { |
| 4475 DCHECK(kArchVariant == kMips64r6); |
| 4476 DCHECK(CpuFeatures::IsSupported(MIPS_SIMD)); |
| 4477 uint32_t opcode = instr_.InstructionBits() & kMsaI5Mask; |
| 4478 |
| 4479 switch (opcode) { |
| 4480 case ADDVI: |
| 4481 case SUBVI: |
| 4482 case MAXI_S: |
| 4483 case MAXI_U: |
| 4484 case MINI_S: |
| 4485 case MINI_U: |
| 4486 case CEQI: |
| 4487 case CLTI_S: |
| 4488 case CLTI_U: |
| 4489 case CLEI_S: |
| 4490 case CLEI_U: |
| 4491 UNIMPLEMENTED(); |
| 4492 break; |
| 4493 default: |
| 4494 UNREACHABLE(); |
| 4495 } |
| 4496 } |
| 4497 |
| 4498 void Simulator::DecodeTypeMsaI10() { |
| 4499 DCHECK(kArchVariant == kMips64r6); |
| 4500 DCHECK(CpuFeatures::IsSupported(MIPS_SIMD)); |
| 4501 uint32_t opcode = instr_.InstructionBits() & kMsaI5Mask; |
| 4502 if (opcode == LDI) { |
| 4503 UNIMPLEMENTED(); |
| 4504 } else { |
| 4505 UNREACHABLE(); |
| 4506 } |
| 4507 } |
| 4508 |
| 4509 void Simulator::DecodeTypeMsaELM() { |
| 4510 DCHECK(kArchVariant == kMips64r6); |
| 4511 DCHECK(CpuFeatures::IsSupported(MIPS_SIMD)); |
| 4512 uint32_t opcode = instr_.InstructionBits() & kMsaELMMask; |
| 4513 int32_t n = instr_.MsaElmNValue(); |
| 4514 int64_t alu_out; |
| 4515 switch (opcode) { |
| 4516 case COPY_S: |
| 4517 case COPY_U: |
| 4518 switch (DecodeMsaDataFormat()) { |
| 4519 case MSA_BYTE: { |
| 4520 DCHECK(n < 16); |
| 4521 int8_t ws[16]; |
| 4522 get_msa_register(instr_.WsValue(), ws); |
| 4523 alu_out = static_cast<int32_t>(ws[n]); |
| 4524 SetResult(wd_reg(), (opcode == COPY_U) ? alu_out & 0xFFu : alu_out); |
| 4525 break; |
| 4526 } |
| 4527 case MSA_HALF: { |
| 4528 DCHECK(n < 8); |
| 4529 int16_t ws[8]; |
| 4530 get_msa_register(instr_.WsValue(), ws); |
| 4531 alu_out = static_cast<int32_t>(ws[n]); |
| 4532 SetResult(wd_reg(), (opcode == COPY_U) ? alu_out & 0xFFFFu : alu_out); |
| 4533 break; |
| 4534 } |
| 4535 case MSA_WORD: { |
| 4536 DCHECK(n < 4); |
| 4537 int32_t ws[4]; |
| 4538 get_msa_register(instr_.WsValue(), ws); |
| 4539 alu_out = static_cast<int32_t>(ws[n]); |
| 4540 SetResult(wd_reg(), |
| 4541 (opcode == COPY_U) ? alu_out & 0xFFFFFFFFu : alu_out); |
| 4542 break; |
| 4543 } |
| 4544 case MSA_DWORD: { |
| 4545 DCHECK(n < 2); |
| 4546 int64_t ws[2]; |
| 4547 get_msa_register(instr_.WsValue(), ws); |
| 4548 alu_out = static_cast<int64_t>(ws[n]); |
| 4549 SetResult(wd_reg(), alu_out); |
| 4550 break; |
| 4551 } |
| 4552 default: |
| 4553 UNREACHABLE(); |
| 4554 } |
| 4555 break; |
| 4556 case SLDI: |
| 4557 case SPLATI: |
| 4558 case INSERT: |
| 4559 case INSVE: |
| 4560 UNIMPLEMENTED(); |
| 4561 break; |
| 4562 default: |
| 4563 UNREACHABLE(); |
| 4564 } |
| 4565 } |
| 4566 |
| 4567 void Simulator::DecodeTypeMsaBIT() { |
| 4568 DCHECK(kArchVariant == kMips64r6); |
| 4569 DCHECK(CpuFeatures::IsSupported(MIPS_SIMD)); |
| 4570 uint32_t opcode = instr_.InstructionBits() & kMsaBITMask; |
| 4571 |
| 4572 switch (opcode) { |
| 4573 case SLLI: |
| 4574 case SRAI: |
| 4575 case SRLI: |
| 4576 case BCLRI: |
| 4577 case BSETI: |
| 4578 case BNEGI: |
| 4579 case BINSLI: |
| 4580 case BINSRI: |
| 4581 case SAT_S: |
| 4582 case SAT_U: |
| 4583 case SRARI: |
| 4584 case SRLRI: |
| 4585 UNIMPLEMENTED(); |
| 4586 break; |
| 4587 default: |
| 4588 UNREACHABLE(); |
| 4589 } |
| 4590 } |
| 4591 |
| 4592 void Simulator::DecodeTypeMsaMI10() { |
| 4593 DCHECK(kArchVariant == kMips64r6); |
| 4594 DCHECK(CpuFeatures::IsSupported(MIPS_SIMD)); |
| 4595 uint32_t opcode = instr_.InstructionBits() & kMsaMI10Mask; |
| 4596 if (opcode == MSA_LD) { |
| 4597 UNIMPLEMENTED(); |
| 4598 } else if (opcode == MSA_ST) { |
| 4599 UNIMPLEMENTED(); |
| 4600 } else { |
| 4601 UNREACHABLE(); |
| 4602 } |
| 4603 } |
| 4604 |
| 4605 void Simulator::DecodeTypeMsa3R() { |
| 4606 DCHECK(kArchVariant == kMips64r6); |
| 4607 DCHECK(CpuFeatures::IsSupported(MIPS_SIMD)); |
| 4608 uint32_t opcode = instr_.InstructionBits() & kMsa3RMask; |
| 4609 switch (opcode) { |
| 4610 case SLL_MSA: |
| 4611 case SRA_MSA: |
| 4612 case SRL_MSA: |
| 4613 case BCLR: |
| 4614 case BSET: |
| 4615 case BNEG: |
| 4616 case BINSL: |
| 4617 case BINSR: |
| 4618 case ADDV: |
| 4619 case SUBV: |
| 4620 case MAX_S: |
| 4621 case MAX_U: |
| 4622 case MIN_S: |
| 4623 case MIN_U: |
| 4624 case MAX_A: |
| 4625 case MIN_A: |
| 4626 case CEQ: |
| 4627 case CLT_S: |
| 4628 case CLT_U: |
| 4629 case CLE_S: |
| 4630 case CLE_U: |
| 4631 case ADD_A: |
| 4632 case ADDS_A: |
| 4633 case ADDS_S: |
| 4634 case ADDS_U: |
| 4635 case AVE_S: |
| 4636 case AVE_U: |
| 4637 case AVER_S: |
| 4638 case AVER_U: |
| 4639 case SUBS_S: |
| 4640 case SUBS_U: |
| 4641 case SUBSUS_U: |
| 4642 case SUBSUU_S: |
| 4643 case ASUB_S: |
| 4644 case ASUB_U: |
| 4645 case MULV: |
| 4646 case MADDV: |
| 4647 case MSUBV: |
| 4648 case DIV_S_MSA: |
| 4649 case DIV_U: |
| 4650 case MOD_S: |
| 4651 case MOD_U: |
| 4652 case DOTP_S: |
| 4653 case DOTP_U: |
| 4654 case DPADD_S: |
| 4655 case DPADD_U: |
| 4656 case DPSUB_S: |
| 4657 case DPSUB_U: |
| 4658 case SLD: |
| 4659 case SPLAT: |
| 4660 case PCKEV: |
| 4661 case PCKOD: |
| 4662 case ILVL: |
| 4663 case ILVR: |
| 4664 case ILVEV: |
| 4665 case ILVOD: |
| 4666 case VSHF: |
| 4667 case SRAR: |
| 4668 case SRLR: |
| 4669 case HADD_S: |
| 4670 case HADD_U: |
| 4671 case HSUB_S: |
| 4672 case HSUB_U: |
| 4673 UNIMPLEMENTED(); |
| 4674 break; |
| 4675 default: |
| 4676 UNREACHABLE(); |
| 4677 } |
| 4678 } |
| 4679 |
| 4680 void Simulator::DecodeTypeMsa3RF() { |
| 4681 DCHECK(kArchVariant == kMips64r6); |
| 4682 DCHECK(CpuFeatures::IsSupported(MIPS_SIMD)); |
| 4683 uint32_t opcode = instr_.InstructionBits() & kMsa3RFMask; |
| 4684 switch (opcode) { |
| 4685 case FCAF: |
| 4686 case FCUN: |
| 4687 case FCEQ: |
| 4688 case FCUEQ: |
| 4689 case FCLT: |
| 4690 case FCULT: |
| 4691 case FCLE: |
| 4692 case FCULE: |
| 4693 case FSAF: |
| 4694 case FSUN: |
| 4695 case FSEQ: |
| 4696 case FSUEQ: |
| 4697 case FSLT: |
| 4698 case FSULT: |
| 4699 case FSLE: |
| 4700 case FSULE: |
| 4701 case FADD: |
| 4702 case FSUB: |
| 4703 case FMUL: |
| 4704 case FDIV: |
| 4705 case FMADD: |
| 4706 case FMSUB: |
| 4707 case FEXP2: |
| 4708 case FEXDO: |
| 4709 case FTQ: |
| 4710 case FMIN: |
| 4711 case FMIN_A: |
| 4712 case FMAX: |
| 4713 case FMAX_A: |
| 4714 case FCOR: |
| 4715 case FCUNE: |
| 4716 case FCNE: |
| 4717 case MUL_Q: |
| 4718 case MADD_Q: |
| 4719 case MSUB_Q: |
| 4720 case FSOR: |
| 4721 case FSUNE: |
| 4722 case FSNE: |
| 4723 case MULR_Q: |
| 4724 case MADDR_Q: |
| 4725 case MSUBR_Q: |
| 4726 UNIMPLEMENTED(); |
| 4727 break; |
| 4728 default: |
| 4729 UNREACHABLE(); |
| 4730 } |
| 4731 } |
| 4732 |
| 4733 void Simulator::DecodeTypeMsaVec() { |
| 4734 DCHECK(kArchVariant == kMips64r6); |
| 4735 DCHECK(CpuFeatures::IsSupported(MIPS_SIMD)); |
| 4736 uint32_t opcode = instr_.InstructionBits() & kMsaVECMask; |
| 4737 switch (opcode) { |
| 4738 case AND_V: |
| 4739 case OR_V: |
| 4740 case NOR_V: |
| 4741 case XOR_V: |
| 4742 case BMNZ_V: |
| 4743 case BMZ_V: |
| 4744 case BSEL_V: |
| 4745 UNIMPLEMENTED(); |
| 4746 break; |
| 4747 default: |
| 4748 UNREACHABLE(); |
| 4749 } |
| 4750 } |
| 4751 |
| 4752 void Simulator::DecodeTypeMsa2R() { |
| 4753 DCHECK(kArchVariant == kMips64r6); |
| 4754 DCHECK(CpuFeatures::IsSupported(MIPS_SIMD)); |
| 4755 uint32_t opcode = instr_.InstructionBits() & kMsa2RMask; |
| 4756 switch (opcode) { |
| 4757 case FILL: |
| 4758 switch (DecodeMsaDataFormat()) { |
| 4759 case MSA_BYTE: { |
| 4760 int8_t wd[16]; |
| 4761 int64_t rs = get_register(instr_.WsValue()); |
| 4762 for (int i = 0; i < 16; i++) { |
| 4763 wd[i] = rs & 0xFFu; |
| 4764 } |
| 4765 set_msa_register(instr_.WdValue(), wd); |
| 4766 TraceMSARegWr(wd, BYTE); |
| 4767 break; |
| 4768 } |
| 4769 case MSA_HALF: { |
| 4770 int16_t wd[8]; |
| 4771 int64_t rs = get_register(instr_.WsValue()); |
| 4772 for (int i = 0; i < 8; i++) { |
| 4773 wd[i] = rs & 0xFFFFu; |
| 4774 } |
| 4775 set_msa_register(instr_.WdValue(), wd); |
| 4776 TraceMSARegWr(wd, HALF); |
| 4777 break; |
| 4778 } |
| 4779 case MSA_WORD: { |
| 4780 int32_t wd[4]; |
| 4781 int64_t rs = get_register(instr_.WsValue()); |
| 4782 for (int i = 0; i < 4; i++) { |
| 4783 wd[i] = rs & 0xFFFFFFFFu; |
| 4784 } |
| 4785 set_msa_register(instr_.WdValue(), wd); |
| 4786 TraceMSARegWr(wd, WORD); |
| 4787 break; |
| 4788 } |
| 4789 case MSA_DWORD: { |
| 4790 int64_t wd[2]; |
| 4791 int64_t rs = get_register(instr_.WsValue()); |
| 4792 wd[0] = wd[1] = rs; |
| 4793 set_msa_register(instr_.WdValue(), wd); |
| 4794 TraceMSARegWr(wd, DWORD); |
| 4795 break; |
| 4796 } |
| 4797 default: |
| 4798 UNREACHABLE(); |
| 4799 } |
| 4800 break; |
| 4801 case PCNT: |
| 4802 case NLOC: |
| 4803 case NLZC: |
| 4804 UNIMPLEMENTED(); |
| 4805 break; |
| 4806 default: |
| 4807 UNREACHABLE(); |
| 4808 } |
| 4809 } |
| 4810 |
| 4811 void Simulator::DecodeTypeMsa2RF() { |
| 4812 DCHECK(kArchVariant == kMips64r6); |
| 4813 DCHECK(CpuFeatures::IsSupported(MIPS_SIMD)); |
| 4814 uint32_t opcode = instr_.InstructionBits() & kMsa2RFMask; |
| 4815 switch (opcode) { |
| 4816 case FCLASS: |
| 4817 case FTRUNC_S: |
| 4818 case FTRUNC_U: |
| 4819 case FSQRT: |
| 4820 case FRSQRT: |
| 4821 case FRCP: |
| 4822 case FRINT: |
| 4823 case FLOG2: |
| 4824 case FEXUPL: |
| 4825 case FEXUPR: |
| 4826 case FFQL: |
| 4827 case FFQR: |
| 4828 case FTINT_S: |
| 4829 case FTINT_U: |
| 4830 case FFINT_S: |
| 4831 case FFINT_U: |
| 4832 UNIMPLEMENTED(); |
| 4833 break; |
| 4834 default: |
| 4835 UNREACHABLE(); |
| 4836 } |
| 4837 } |
| 4838 |
4309 void Simulator::DecodeTypeRegister() { | 4839 void Simulator::DecodeTypeRegister() { |
4310 // ---------- Execution. | 4840 // ---------- Execution. |
4311 switch (instr_.OpcodeFieldRaw()) { | 4841 switch (instr_.OpcodeFieldRaw()) { |
4312 case COP1: | 4842 case COP1: |
4313 DecodeTypeRegisterCOP1(); | 4843 DecodeTypeRegisterCOP1(); |
4314 break; | 4844 break; |
4315 case COP1X: | 4845 case COP1X: |
4316 DecodeTypeRegisterCOP1X(); | 4846 DecodeTypeRegisterCOP1X(); |
4317 break; | 4847 break; |
4318 case SPECIAL: | 4848 case SPECIAL: |
4319 DecodeTypeRegisterSPECIAL(); | 4849 DecodeTypeRegisterSPECIAL(); |
4320 break; | 4850 break; |
4321 case SPECIAL2: | 4851 case SPECIAL2: |
4322 DecodeTypeRegisterSPECIAL2(); | 4852 DecodeTypeRegisterSPECIAL2(); |
4323 break; | 4853 break; |
4324 case SPECIAL3: | 4854 case SPECIAL3: |
4325 DecodeTypeRegisterSPECIAL3(); | 4855 DecodeTypeRegisterSPECIAL3(); |
4326 break; | 4856 break; |
| 4857 case MSA: |
| 4858 switch (instr_.MSAMinorOpcodeField()) { |
| 4859 case kMsaMinor3R: |
| 4860 DecodeTypeMsa3R(); |
| 4861 break; |
| 4862 case kMsaMinor3RF: |
| 4863 DecodeTypeMsa3RF(); |
| 4864 break; |
| 4865 case kMsaMinorVEC: |
| 4866 DecodeTypeMsaVec(); |
| 4867 break; |
| 4868 case kMsaMinor2R: |
| 4869 DecodeTypeMsa2R(); |
| 4870 break; |
| 4871 case kMsaMinor2RF: |
| 4872 DecodeTypeMsa2RF(); |
| 4873 break; |
| 4874 default: |
| 4875 UNREACHABLE(); |
| 4876 } |
| 4877 break; |
4327 // Unimplemented opcodes raised an error in the configuration step before, | 4878 // Unimplemented opcodes raised an error in the configuration step before, |
4328 // so we can use the default here to set the destination register in common | 4879 // so we can use the default here to set the destination register in common |
4329 // cases. | 4880 // cases. |
4330 default: | 4881 default: |
4331 UNREACHABLE(); | 4882 UNREACHABLE(); |
4332 } | 4883 } |
4333 } | 4884 } |
4334 | 4885 |
4335 | 4886 |
4336 // Type 2: instructions using a 16, 21 or 26 bits immediate. (e.g. beq, beqc). | 4887 // Type 2: instructions using a 16, 21 or 26 bits immediate. (e.g. beq, beqc). |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4429 bool do_branch = (instr_.FBtrueValue()) ? cc_value : !cc_value; | 4980 bool do_branch = (instr_.FBtrueValue()) ? cc_value : !cc_value; |
4430 BranchHelper(do_branch); | 4981 BranchHelper(do_branch); |
4431 break; | 4982 break; |
4432 } | 4983 } |
4433 case BC1EQZ: | 4984 case BC1EQZ: |
4434 BranchHelper(!(get_fpu_register(ft_reg) & 0x1)); | 4985 BranchHelper(!(get_fpu_register(ft_reg) & 0x1)); |
4435 break; | 4986 break; |
4436 case BC1NEZ: | 4987 case BC1NEZ: |
4437 BranchHelper(get_fpu_register(ft_reg) & 0x1); | 4988 BranchHelper(get_fpu_register(ft_reg) & 0x1); |
4438 break; | 4989 break; |
| 4990 case BZ_V: |
| 4991 case BZ_B: |
| 4992 case BZ_H: |
| 4993 case BZ_W: |
| 4994 case BZ_D: |
| 4995 case BNZ_V: |
| 4996 case BNZ_B: |
| 4997 case BNZ_H: |
| 4998 case BNZ_W: |
| 4999 case BNZ_D: |
| 5000 UNIMPLEMENTED(); |
| 5001 break; |
4439 default: | 5002 default: |
4440 UNREACHABLE(); | 5003 UNREACHABLE(); |
4441 } | 5004 } |
4442 break; | 5005 break; |
4443 // ------------- REGIMM class. | 5006 // ------------- REGIMM class. |
4444 case REGIMM: | 5007 case REGIMM: |
4445 switch (instr_.RtFieldRaw()) { | 5008 switch (instr_.RtFieldRaw()) { |
4446 case BLTZ: | 5009 case BLTZ: |
4447 BranchHelper(rs < 0); | 5010 BranchHelper(rs < 0); |
4448 break; | 5011 break; |
(...skipping 402 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4851 } | 5414 } |
4852 break; | 5415 break; |
4853 } | 5416 } |
4854 } | 5417 } |
4855 break; | 5418 break; |
4856 } | 5419 } |
4857 } | 5420 } |
4858 SetResult(rs_reg, alu_out); | 5421 SetResult(rs_reg, alu_out); |
4859 break; | 5422 break; |
4860 } | 5423 } |
| 5424 case MSA: |
| 5425 switch (instr_.MSAMinorOpcodeField()) { |
| 5426 case kMsaMinorI8: |
| 5427 DecodeTypeMsaI8(); |
| 5428 break; |
| 5429 case kMsaMinorI5: |
| 5430 DecodeTypeMsaI5(); |
| 5431 break; |
| 5432 case kMsaMinorI10: |
| 5433 DecodeTypeMsaI10(); |
| 5434 break; |
| 5435 case kMsaMinorELM: |
| 5436 DecodeTypeMsaELM(); |
| 5437 break; |
| 5438 case kMsaMinorBIT: |
| 5439 DecodeTypeMsaBIT(); |
| 5440 break; |
| 5441 case kMsaMinorMI10: |
| 5442 DecodeTypeMsaMI10(); |
| 5443 break; |
| 5444 default: |
| 5445 UNREACHABLE(); |
| 5446 break; |
| 5447 } |
| 5448 break; |
4861 default: | 5449 default: |
4862 UNREACHABLE(); | 5450 UNREACHABLE(); |
4863 } | 5451 } |
4864 | 5452 |
4865 if (execute_branch_delay_instruction) { | 5453 if (execute_branch_delay_instruction) { |
4866 // Execute branch delay slot | 5454 // Execute branch delay slot |
4867 // We don't check for end_sim_pc. First it should not be met as the current | 5455 // We don't check for end_sim_pc. First it should not be met as the current |
4868 // pc is valid. Secondly a jump should always execute its branch delay slot. | 5456 // pc is valid. Secondly a jump should always execute its branch delay slot. |
4869 Instruction* branch_delay_instr = | 5457 Instruction* branch_delay_instr = |
4870 reinterpret_cast<Instruction*>(get_pc() + Instruction::kInstrSize); | 5458 reinterpret_cast<Instruction*>(get_pc() + Instruction::kInstrSize); |
(...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5143 } | 5731 } |
5144 | 5732 |
5145 | 5733 |
5146 #undef UNSUPPORTED | 5734 #undef UNSUPPORTED |
5147 } // namespace internal | 5735 } // namespace internal |
5148 } // namespace v8 | 5736 } // namespace v8 |
5149 | 5737 |
5150 #endif // USE_SIMULATOR | 5738 #endif // USE_SIMULATOR |
5151 | 5739 |
5152 #endif // V8_TARGET_ARCH_MIPS64 | 5740 #endif // V8_TARGET_ARCH_MIPS64 |
OLD | NEW |