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 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
989 void Simulator::set_dw_register(int reg, const int* dbl) { | 990 void Simulator::set_dw_register(int reg, const int* dbl) { |
990 DCHECK((reg >= 0) && (reg < kNumSimuRegisters)); | 991 DCHECK((reg >= 0) && (reg < kNumSimuRegisters)); |
991 registers_[reg] = dbl[1]; | 992 registers_[reg] = dbl[1]; |
992 registers_[reg] = registers_[reg] << 32; | 993 registers_[reg] = registers_[reg] << 32; |
993 registers_[reg] += dbl[0]; | 994 registers_[reg] += dbl[0]; |
994 } | 995 } |
995 | 996 |
996 | 997 |
997 void Simulator::set_fpu_register(int fpureg, int64_t value) { | 998 void Simulator::set_fpu_register(int fpureg, int64_t value) { |
998 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters)); | 999 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters)); |
999 FPUregisters_[fpureg] = value; | 1000 FPUregisters_[fpureg * 2] = value; |
1000 } | 1001 } |
1001 | 1002 |
1002 | 1003 |
1003 void Simulator::set_fpu_register_word(int fpureg, int32_t value) { | 1004 void Simulator::set_fpu_register_word(int fpureg, int32_t value) { |
1004 // Set ONLY lower 32-bits, leaving upper bits untouched. | 1005 // Set ONLY lower 32-bits, leaving upper bits untouched. |
1005 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters)); | 1006 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters)); |
1006 int32_t* pword; | 1007 int32_t* pword; |
1007 if (kArchEndian == kLittle) { | 1008 if (kArchEndian == kLittle) { |
1008 pword = reinterpret_cast<int32_t*>(&FPUregisters_[fpureg]); | 1009 pword = reinterpret_cast<int32_t*>(&FPUregisters_[fpureg * 2]); |
1009 } else { | 1010 } else { |
1010 pword = reinterpret_cast<int32_t*>(&FPUregisters_[fpureg]) + 1; | 1011 pword = reinterpret_cast<int32_t*>(&FPUregisters_[fpureg * 2]) + 1; |
1011 } | 1012 } |
1012 *pword = value; | 1013 *pword = value; |
1013 } | 1014 } |
1014 | 1015 |
1015 | 1016 |
1016 void Simulator::set_fpu_register_hi_word(int fpureg, int32_t value) { | 1017 void Simulator::set_fpu_register_hi_word(int fpureg, int32_t value) { |
1017 // Set ONLY upper 32-bits, leaving lower bits untouched. | 1018 // Set ONLY upper 32-bits, leaving lower bits untouched. |
1018 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters)); | 1019 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters)); |
1019 int32_t* phiword; | 1020 int32_t* phiword; |
1020 if (kArchEndian == kLittle) { | 1021 if (kArchEndian == kLittle) { |
1021 phiword = (reinterpret_cast<int32_t*>(&FPUregisters_[fpureg])) + 1; | 1022 phiword = (reinterpret_cast<int32_t*>(&FPUregisters_[fpureg * 2])) + 1; |
1022 } else { | 1023 } else { |
1023 phiword = reinterpret_cast<int32_t*>(&FPUregisters_[fpureg]); | 1024 phiword = reinterpret_cast<int32_t*>(&FPUregisters_[fpureg * 2]); |
1024 } | 1025 } |
1025 *phiword = value; | 1026 *phiword = value; |
1026 } | 1027 } |
1027 | 1028 |
1028 | 1029 |
1029 void Simulator::set_fpu_register_float(int fpureg, float value) { | 1030 void Simulator::set_fpu_register_float(int fpureg, float value) { |
1030 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters)); | 1031 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters)); |
1031 *bit_cast<float*>(&FPUregisters_[fpureg]) = value; | 1032 *bit_cast<float*>(&FPUregisters_[fpureg * 2]) = value; |
1032 } | 1033 } |
1033 | 1034 |
1034 | 1035 |
1035 void Simulator::set_fpu_register_double(int fpureg, double value) { | 1036 void Simulator::set_fpu_register_double(int fpureg, double value) { |
1036 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters)); | 1037 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters)); |
1037 *bit_cast<double*>(&FPUregisters_[fpureg]) = value; | 1038 *bit_cast<double*>(&FPUregisters_[fpureg * 2]) = value; |
1038 } | 1039 } |
1039 | 1040 |
1040 | 1041 |
1041 // Get the register from the architecture state. This function does handle | 1042 // Get the register from the architecture state. This function does handle |
1042 // the special case of accessing the PC register. | 1043 // the special case of accessing the PC register. |
1043 int64_t Simulator::get_register(int reg) const { | 1044 int64_t Simulator::get_register(int reg) const { |
1044 DCHECK((reg >= 0) && (reg < kNumSimuRegisters)); | 1045 DCHECK((reg >= 0) && (reg < kNumSimuRegisters)); |
1045 if (reg == 0) | 1046 if (reg == 0) |
1046 return 0; | 1047 return 0; |
1047 else | 1048 else |
(...skipping 10 matching lines...) Expand all Loading... |
1058 // into the double precision floating point value and return it. | 1059 // into the double precision floating point value and return it. |
1059 char buffer[sizeof(registers_[0])]; | 1060 char buffer[sizeof(registers_[0])]; |
1060 memcpy(buffer, ®isters_[reg], sizeof(registers_[0])); | 1061 memcpy(buffer, ®isters_[reg], sizeof(registers_[0])); |
1061 memcpy(&dm_val, buffer, sizeof(registers_[0])); | 1062 memcpy(&dm_val, buffer, sizeof(registers_[0])); |
1062 return(dm_val); | 1063 return(dm_val); |
1063 } | 1064 } |
1064 | 1065 |
1065 | 1066 |
1066 int64_t Simulator::get_fpu_register(int fpureg) const { | 1067 int64_t Simulator::get_fpu_register(int fpureg) const { |
1067 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters)); | 1068 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters)); |
1068 return FPUregisters_[fpureg]; | 1069 return FPUregisters_[fpureg * 2]; |
1069 } | 1070 } |
1070 | 1071 |
1071 | 1072 |
1072 int32_t Simulator::get_fpu_register_word(int fpureg) const { | 1073 int32_t Simulator::get_fpu_register_word(int fpureg) const { |
1073 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters)); | 1074 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters)); |
1074 return static_cast<int32_t>(FPUregisters_[fpureg] & 0xffffffff); | 1075 return static_cast<int32_t>(FPUregisters_[fpureg * 2] & 0xffffffff); |
1075 } | 1076 } |
1076 | 1077 |
1077 | 1078 |
1078 int32_t Simulator::get_fpu_register_signed_word(int fpureg) const { | 1079 int32_t Simulator::get_fpu_register_signed_word(int fpureg) const { |
1079 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters)); | 1080 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters)); |
1080 return static_cast<int32_t>(FPUregisters_[fpureg] & 0xffffffff); | 1081 return static_cast<int32_t>(FPUregisters_[fpureg * 2] & 0xffffffff); |
1081 } | 1082 } |
1082 | 1083 |
1083 | 1084 |
1084 int32_t Simulator::get_fpu_register_hi_word(int fpureg) const { | 1085 int32_t Simulator::get_fpu_register_hi_word(int fpureg) const { |
1085 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters)); | 1086 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters)); |
1086 return static_cast<int32_t>((FPUregisters_[fpureg] >> 32) & 0xffffffff); | 1087 return static_cast<int32_t>((FPUregisters_[fpureg * 2] >> 32) & 0xffffffff); |
1087 } | 1088 } |
1088 | 1089 |
1089 | 1090 |
1090 float Simulator::get_fpu_register_float(int fpureg) const { | 1091 float Simulator::get_fpu_register_float(int fpureg) const { |
1091 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters)); | 1092 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters)); |
1092 return *bit_cast<float*>(const_cast<int64_t*>(&FPUregisters_[fpureg])); | 1093 return *bit_cast<float*>(const_cast<int64_t*>(&FPUregisters_[fpureg * 2])); |
1093 } | 1094 } |
1094 | 1095 |
1095 | 1096 |
1096 double Simulator::get_fpu_register_double(int fpureg) const { | 1097 double Simulator::get_fpu_register_double(int fpureg) const { |
1097 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters)); | 1098 DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters)); |
1098 return *bit_cast<double*>(&FPUregisters_[fpureg]); | 1099 return *bit_cast<double*>(&FPUregisters_[fpureg * 2]); |
1099 } | 1100 } |
1100 | 1101 |
| 1102 template <typename T> |
| 1103 void Simulator::get_msa_register(int wreg, T* value) { |
| 1104 DCHECK((wreg >= 0) && (wreg < kNumMSARegisters)); |
| 1105 memcpy(value, FPUregisters_ + wreg * 2, kSimd128Size); |
| 1106 } |
| 1107 |
| 1108 template <typename T> |
| 1109 void Simulator::set_msa_register(int wreg, const T* value) { |
| 1110 DCHECK((wreg >= 0) && (wreg < kNumMSARegisters)); |
| 1111 memcpy(FPUregisters_ + wreg * 2, value, kSimd128Size); |
| 1112 } |
1101 | 1113 |
1102 // Runtime FP routines take up to two double arguments and zero | 1114 // Runtime FP routines take up to two double arguments and zero |
1103 // or one integer arguments. All are constructed here, | 1115 // or one integer arguments. All are constructed here, |
1104 // from a0-a3 or f12 and f13 (n64), or f14 (O32). | 1116 // from a0-a3 or f12 and f13 (n64), or f14 (O32). |
1105 void Simulator::GetFpArgs(double* x, double* y, int32_t* z) { | 1117 void Simulator::GetFpArgs(double* x, double* y, int32_t* z) { |
1106 if (!IsMipsSoftFloatABI) { | 1118 if (!IsMipsSoftFloatABI) { |
1107 const int fparg2 = 13; | 1119 const int fparg2 = 13; |
1108 *x = get_fpu_register_double(12); | 1120 *x = get_fpu_register_double(12); |
1109 *y = get_fpu_register_double(fparg2); | 1121 *y = get_fpu_register_double(fparg2); |
1110 *z = static_cast<int32_t>(get_register(a2)); | 1122 *z = static_cast<int32_t>(get_register(a2)); |
(...skipping 554 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1665 " uint32:%" PRIu32 " int64:%" PRId64 " uint64:%" PRIu64, | 1677 " uint32:%" PRIu32 " int64:%" PRId64 " uint64:%" PRIu64, |
1666 v.fmt_int64, icount_, v.fmt_int32[0], v.fmt_int32[0], | 1678 v.fmt_int64, icount_, v.fmt_int32[0], v.fmt_int32[0], |
1667 v.fmt_int64, v.fmt_int64); | 1679 v.fmt_int64, v.fmt_int64); |
1668 break; | 1680 break; |
1669 default: | 1681 default: |
1670 UNREACHABLE(); | 1682 UNREACHABLE(); |
1671 } | 1683 } |
1672 } | 1684 } |
1673 } | 1685 } |
1674 | 1686 |
| 1687 template <typename T> |
| 1688 void Simulator::TraceMSARegWr(T* value, TraceType t) { |
| 1689 if (::v8::internal::FLAG_trace_sim) { |
| 1690 union { |
| 1691 uint8_t b[16]; |
| 1692 uint16_t h[8]; |
| 1693 uint32_t w[4]; |
| 1694 uint64_t d[2]; |
| 1695 float f[4]; |
| 1696 double df[2]; |
| 1697 } v; |
| 1698 memcpy(v.b, value, kSimd128Size); |
| 1699 switch (t) { |
| 1700 case BYTE: |
| 1701 SNPrintF(trace_buf_, |
| 1702 "LO: %016" PRIx64 " HI: %016" PRIx64 " (%" PRIu64 ")", |
| 1703 v.d[0], v.d[1], icount_); |
| 1704 break; |
| 1705 case HALF: |
| 1706 SNPrintF(trace_buf_, |
| 1707 "LO: %016" PRIx64 " HI: %016" PRIx64 " (%" PRIu64 ")", |
| 1708 v.d[0], v.d[1], icount_); |
| 1709 break; |
| 1710 case WORD: |
| 1711 SNPrintF(trace_buf_, |
| 1712 "LO: %016" PRIx64 " HI: %016" PRIx64 " (%" PRIu64 |
| 1713 ") int32[0..3]:%" PRId32 " %" PRId32 " %" PRId32 |
| 1714 " %" PRId32, |
| 1715 v.d[0], v.d[1], icount_, v.w[0], v.w[1], v.w[2], v.w[3]); |
| 1716 break; |
| 1717 case DWORD: |
| 1718 SNPrintF(trace_buf_, |
| 1719 "LO: %016" PRIx64 " HI: %016" PRIx64 " (%" PRIu64 ")", |
| 1720 v.d[0], v.d[1], icount_); |
| 1721 break; |
| 1722 case FLOAT: |
| 1723 SNPrintF(trace_buf_, |
| 1724 "LO: %016" PRIx64 " HI: %016" PRIx64 " (%" PRIu64 |
| 1725 ") flt[0..3]:%e %e %e %e", |
| 1726 v.d[0], v.d[1], icount_, v.f[0], v.f[1], v.f[2], v.f[3]); |
| 1727 break; |
| 1728 case DOUBLE: |
| 1729 SNPrintF(trace_buf_, |
| 1730 "LO: %016" PRIx64 " HI: %016" PRIx64 " (%" PRIu64 |
| 1731 ") dbl[0..1]:%e %e", |
| 1732 v.d[0], v.d[1], icount_, v.df[0], v.df[1]); |
| 1733 break; |
| 1734 default: |
| 1735 UNREACHABLE(); |
| 1736 } |
| 1737 } |
| 1738 } |
| 1739 |
1675 // TODO(plind): consider making icount_ printing a flag option. | 1740 // TODO(plind): consider making icount_ printing a flag option. |
1676 void Simulator::TraceMemRd(int64_t addr, int64_t value, TraceType t) { | 1741 void Simulator::TraceMemRd(int64_t addr, int64_t value, TraceType t) { |
1677 if (::v8::internal::FLAG_trace_sim) { | 1742 if (::v8::internal::FLAG_trace_sim) { |
1678 union { | 1743 union { |
1679 int64_t fmt_int64; | 1744 int64_t fmt_int64; |
1680 int32_t fmt_int32[2]; | 1745 int32_t fmt_int32[2]; |
1681 float fmt_float[2]; | 1746 float fmt_float[2]; |
1682 double fmt_double; | 1747 double fmt_double; |
1683 } v; | 1748 } v; |
1684 v.fmt_int64 = value; | 1749 v.fmt_int64 = value; |
(...skipping 2647 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4332 } | 4397 } |
4333 } | 4398 } |
4334 SetResult(rd_reg(), alu_out); | 4399 SetResult(rd_reg(), alu_out); |
4335 break; | 4400 break; |
4336 } | 4401 } |
4337 default: | 4402 default: |
4338 UNREACHABLE(); | 4403 UNREACHABLE(); |
4339 } | 4404 } |
4340 } | 4405 } |
4341 | 4406 |
| 4407 int Simulator::DecodeMsaDataFormat() { |
| 4408 int df = -1; |
| 4409 if (instr_.IsMSABranchInstr()) { |
| 4410 switch (instr_.RsFieldRaw()) { |
| 4411 case BZ_V: |
| 4412 case BNZ_V: |
| 4413 df = MSA_VECT; |
| 4414 break; |
| 4415 case BZ_B: |
| 4416 case BNZ_B: |
| 4417 df = MSA_BYTE; |
| 4418 break; |
| 4419 case BZ_H: |
| 4420 case BNZ_H: |
| 4421 df = MSA_HALF; |
| 4422 break; |
| 4423 case BZ_W: |
| 4424 case BNZ_W: |
| 4425 df = MSA_WORD; |
| 4426 break; |
| 4427 case BZ_D: |
| 4428 case BNZ_D: |
| 4429 df = MSA_DWORD; |
| 4430 break; |
| 4431 default: |
| 4432 UNREACHABLE(); |
| 4433 break; |
| 4434 } |
| 4435 } else { |
| 4436 int DF[] = {MSA_BYTE, MSA_HALF, MSA_WORD, MSA_DWORD}; |
| 4437 switch (instr_.MSAMinorOpcodeField()) { |
| 4438 case kMsaMinorI5: |
| 4439 case kMsaMinorI10: |
| 4440 case kMsaMinor3R: |
| 4441 df = DF[instr_.Bits(22, 21)]; |
| 4442 break; |
| 4443 case kMsaMinorMI10: |
| 4444 df = DF[instr_.Bits(1, 0)]; |
| 4445 break; |
| 4446 case kMsaMinorBIT: |
| 4447 df = DF[instr_.MsaBitDf()]; |
| 4448 break; |
| 4449 case kMsaMinorELM: |
| 4450 df = DF[instr_.MsaElmDf()]; |
| 4451 break; |
| 4452 case kMsaMinor3RF: { |
| 4453 uint32_t opcode = instr_.InstructionBits() & kMsa3RFMask; |
| 4454 switch (opcode) { |
| 4455 case FEXDO: |
| 4456 case FTQ: |
| 4457 case MUL_Q: |
| 4458 case MADD_Q: |
| 4459 case MSUB_Q: |
| 4460 case MULR_Q: |
| 4461 case MADDR_Q: |
| 4462 case MSUBR_Q: |
| 4463 df = DF[1 + instr_.Bit(21)]; |
| 4464 break; |
| 4465 default: |
| 4466 df = DF[2 + instr_.Bit(21)]; |
| 4467 break; |
| 4468 } |
| 4469 } break; |
| 4470 case kMsaMinor2R: |
| 4471 df = DF[instr_.Bits(17, 16)]; |
| 4472 break; |
| 4473 case kMsaMinor2RF: |
| 4474 df = DF[2 + instr_.Bit(16)]; |
| 4475 break; |
| 4476 default: |
| 4477 UNREACHABLE(); |
| 4478 break; |
| 4479 } |
| 4480 } |
| 4481 return df; |
| 4482 } |
| 4483 |
| 4484 void Simulator::DecodeTypeMsaI8() { |
| 4485 DCHECK(kArchVariant == kMips64r6); |
| 4486 DCHECK(CpuFeatures::IsSupported(MIPS_SIMD)); |
| 4487 uint32_t opcode = instr_.InstructionBits() & kMsaI8Mask; |
| 4488 |
| 4489 switch (opcode) { |
| 4490 case ANDI_B: |
| 4491 case ORI_B: |
| 4492 case NORI_B: |
| 4493 case XORI_B: |
| 4494 case BMNZI_B: |
| 4495 case BMZI_B: |
| 4496 case BSELI_B: |
| 4497 case SHF_B: |
| 4498 case SHF_H: |
| 4499 case SHF_W: |
| 4500 UNIMPLEMENTED(); |
| 4501 break; |
| 4502 default: |
| 4503 UNREACHABLE(); |
| 4504 } |
| 4505 } |
| 4506 |
| 4507 void Simulator::DecodeTypeMsaI5() { |
| 4508 DCHECK(kArchVariant == kMips64r6); |
| 4509 DCHECK(CpuFeatures::IsSupported(MIPS_SIMD)); |
| 4510 uint32_t opcode = instr_.InstructionBits() & kMsaI5Mask; |
| 4511 |
| 4512 switch (opcode) { |
| 4513 case ADDVI: |
| 4514 case SUBVI: |
| 4515 case MAXI_S: |
| 4516 case MAXI_U: |
| 4517 case MINI_S: |
| 4518 case MINI_U: |
| 4519 case CEQI: |
| 4520 case CLTI_S: |
| 4521 case CLTI_U: |
| 4522 case CLEI_S: |
| 4523 case CLEI_U: |
| 4524 UNIMPLEMENTED(); |
| 4525 break; |
| 4526 default: |
| 4527 UNREACHABLE(); |
| 4528 } |
| 4529 } |
| 4530 |
| 4531 void Simulator::DecodeTypeMsaI10() { |
| 4532 DCHECK(kArchVariant == kMips64r6); |
| 4533 DCHECK(CpuFeatures::IsSupported(MIPS_SIMD)); |
| 4534 uint32_t opcode = instr_.InstructionBits() & kMsaI5Mask; |
| 4535 if (opcode == LDI) { |
| 4536 UNIMPLEMENTED(); |
| 4537 } else { |
| 4538 UNREACHABLE(); |
| 4539 } |
| 4540 } |
| 4541 |
| 4542 void Simulator::DecodeTypeMsaELM() { |
| 4543 DCHECK(kArchVariant == kMips64r6); |
| 4544 DCHECK(CpuFeatures::IsSupported(MIPS_SIMD)); |
| 4545 uint32_t opcode = instr_.InstructionBits() & kMsaELMMask; |
| 4546 int32_t n = instr_.MsaElmNValue(); |
| 4547 int64_t alu_out; |
| 4548 switch (opcode) { |
| 4549 case COPY_S: |
| 4550 case COPY_U: |
| 4551 switch (DecodeMsaDataFormat()) { |
| 4552 case MSA_BYTE: { |
| 4553 DCHECK(n < 16); |
| 4554 int8_t ws[16]; |
| 4555 get_msa_register(instr_.WsValue(), ws); |
| 4556 alu_out = static_cast<int32_t>(ws[n]); |
| 4557 SetResult(wd_reg(), (opcode == COPY_U) ? alu_out & 0xFFu : alu_out); |
| 4558 break; |
| 4559 } |
| 4560 case MSA_HALF: { |
| 4561 DCHECK(n < 8); |
| 4562 int16_t ws[8]; |
| 4563 get_msa_register(instr_.WsValue(), ws); |
| 4564 alu_out = static_cast<int32_t>(ws[n]); |
| 4565 SetResult(wd_reg(), (opcode == COPY_U) ? alu_out & 0xFFFFu : alu_out); |
| 4566 break; |
| 4567 } |
| 4568 case MSA_WORD: { |
| 4569 DCHECK(n < 4); |
| 4570 int32_t ws[4]; |
| 4571 get_msa_register(instr_.WsValue(), ws); |
| 4572 alu_out = static_cast<int32_t>(ws[n]); |
| 4573 SetResult(wd_reg(), |
| 4574 (opcode == COPY_U) ? alu_out & 0xFFFFFFFFu : alu_out); |
| 4575 break; |
| 4576 } |
| 4577 case MSA_DWORD: { |
| 4578 DCHECK(n < 2); |
| 4579 int64_t ws[2]; |
| 4580 get_msa_register(instr_.WsValue(), ws); |
| 4581 alu_out = static_cast<int64_t>(ws[n]); |
| 4582 SetResult(wd_reg(), alu_out); |
| 4583 break; |
| 4584 } |
| 4585 default: |
| 4586 UNREACHABLE(); |
| 4587 } |
| 4588 break; |
| 4589 case SLDI: |
| 4590 case SPLATI: |
| 4591 case INSERT: |
| 4592 case INSVE: |
| 4593 UNIMPLEMENTED(); |
| 4594 break; |
| 4595 default: |
| 4596 UNREACHABLE(); |
| 4597 } |
| 4598 } |
| 4599 |
| 4600 void Simulator::DecodeTypeMsaBIT() { |
| 4601 DCHECK(kArchVariant == kMips64r6); |
| 4602 DCHECK(CpuFeatures::IsSupported(MIPS_SIMD)); |
| 4603 uint32_t opcode = instr_.InstructionBits() & kMsaBITMask; |
| 4604 |
| 4605 switch (opcode) { |
| 4606 case SLLI: |
| 4607 case SRAI: |
| 4608 case SRLI: |
| 4609 case BCLRI: |
| 4610 case BSETI: |
| 4611 case BNEGI: |
| 4612 case BINSLI: |
| 4613 case BINSRI: |
| 4614 case SAT_S: |
| 4615 case SAT_U: |
| 4616 case SRARI: |
| 4617 case SRLRI: |
| 4618 UNIMPLEMENTED(); |
| 4619 break; |
| 4620 default: |
| 4621 UNREACHABLE(); |
| 4622 } |
| 4623 } |
| 4624 |
| 4625 void Simulator::DecodeTypeMsaMI10() { |
| 4626 DCHECK(kArchVariant == kMips64r6); |
| 4627 DCHECK(CpuFeatures::IsSupported(MIPS_SIMD)); |
| 4628 uint32_t opcode = instr_.InstructionBits() & kMsaMI10Mask; |
| 4629 if (opcode == MSA_LD) { |
| 4630 UNIMPLEMENTED(); |
| 4631 } else if (opcode == MSA_ST) { |
| 4632 UNIMPLEMENTED(); |
| 4633 } else { |
| 4634 UNREACHABLE(); |
| 4635 } |
| 4636 } |
| 4637 |
| 4638 void Simulator::DecodeTypeMsa3R() { |
| 4639 DCHECK(kArchVariant == kMips64r6); |
| 4640 DCHECK(CpuFeatures::IsSupported(MIPS_SIMD)); |
| 4641 uint32_t opcode = instr_.InstructionBits() & kMsa3RMask; |
| 4642 switch (opcode) { |
| 4643 case SLL_MSA: |
| 4644 case SRA_MSA: |
| 4645 case SRL_MSA: |
| 4646 case BCLR: |
| 4647 case BSET: |
| 4648 case BNEG: |
| 4649 case BINSL: |
| 4650 case BINSR: |
| 4651 case ADDV: |
| 4652 case SUBV: |
| 4653 case MAX_S: |
| 4654 case MAX_U: |
| 4655 case MIN_S: |
| 4656 case MIN_U: |
| 4657 case MAX_A: |
| 4658 case MIN_A: |
| 4659 case CEQ: |
| 4660 case CLT_S: |
| 4661 case CLT_U: |
| 4662 case CLE_S: |
| 4663 case CLE_U: |
| 4664 case ADD_A: |
| 4665 case ADDS_A: |
| 4666 case ADDS_S: |
| 4667 case ADDS_U: |
| 4668 case AVE_S: |
| 4669 case AVE_U: |
| 4670 case AVER_S: |
| 4671 case AVER_U: |
| 4672 case SUBS_S: |
| 4673 case SUBS_U: |
| 4674 case SUBSUS_U: |
| 4675 case SUBSUU_S: |
| 4676 case ASUB_S: |
| 4677 case ASUB_U: |
| 4678 case MULV: |
| 4679 case MADDV: |
| 4680 case MSUBV: |
| 4681 case DIV_S_MSA: |
| 4682 case DIV_U: |
| 4683 case MOD_S: |
| 4684 case MOD_U: |
| 4685 case DOTP_S: |
| 4686 case DOTP_U: |
| 4687 case DPADD_S: |
| 4688 case DPADD_U: |
| 4689 case DPSUB_S: |
| 4690 case DPSUB_U: |
| 4691 case SLD: |
| 4692 case SPLAT: |
| 4693 case PCKEV: |
| 4694 case PCKOD: |
| 4695 case ILVL: |
| 4696 case ILVR: |
| 4697 case ILVEV: |
| 4698 case ILVOD: |
| 4699 case VSHF: |
| 4700 case SRAR: |
| 4701 case SRLR: |
| 4702 case HADD_S: |
| 4703 case HADD_U: |
| 4704 case HSUB_S: |
| 4705 case HSUB_U: |
| 4706 UNIMPLEMENTED(); |
| 4707 break; |
| 4708 default: |
| 4709 UNREACHABLE(); |
| 4710 } |
| 4711 } |
| 4712 |
| 4713 void Simulator::DecodeTypeMsa3RF() { |
| 4714 DCHECK(kArchVariant == kMips64r6); |
| 4715 DCHECK(CpuFeatures::IsSupported(MIPS_SIMD)); |
| 4716 uint32_t opcode = instr_.InstructionBits() & kMsa3RFMask; |
| 4717 switch (opcode) { |
| 4718 case FCAF: |
| 4719 case FCUN: |
| 4720 case FCEQ: |
| 4721 case FCUEQ: |
| 4722 case FCLT: |
| 4723 case FCULT: |
| 4724 case FCLE: |
| 4725 case FCULE: |
| 4726 case FSAF: |
| 4727 case FSUN: |
| 4728 case FSEQ: |
| 4729 case FSUEQ: |
| 4730 case FSLT: |
| 4731 case FSULT: |
| 4732 case FSLE: |
| 4733 case FSULE: |
| 4734 case FADD: |
| 4735 case FSUB: |
| 4736 case FMUL: |
| 4737 case FDIV: |
| 4738 case FMADD: |
| 4739 case FMSUB: |
| 4740 case FEXP2: |
| 4741 case FEXDO: |
| 4742 case FTQ: |
| 4743 case FMIN: |
| 4744 case FMIN_A: |
| 4745 case FMAX: |
| 4746 case FMAX_A: |
| 4747 case FCOR: |
| 4748 case FCUNE: |
| 4749 case FCNE: |
| 4750 case MUL_Q: |
| 4751 case MADD_Q: |
| 4752 case MSUB_Q: |
| 4753 case FSOR: |
| 4754 case FSUNE: |
| 4755 case FSNE: |
| 4756 case MULR_Q: |
| 4757 case MADDR_Q: |
| 4758 case MSUBR_Q: |
| 4759 UNIMPLEMENTED(); |
| 4760 break; |
| 4761 default: |
| 4762 UNREACHABLE(); |
| 4763 } |
| 4764 } |
| 4765 |
| 4766 void Simulator::DecodeTypeMsaVec() { |
| 4767 DCHECK(kArchVariant == kMips64r6); |
| 4768 DCHECK(CpuFeatures::IsSupported(MIPS_SIMD)); |
| 4769 uint32_t opcode = instr_.InstructionBits() & kMsaVECMask; |
| 4770 switch (opcode) { |
| 4771 case AND_V: |
| 4772 case OR_V: |
| 4773 case NOR_V: |
| 4774 case XOR_V: |
| 4775 case BMNZ_V: |
| 4776 case BMZ_V: |
| 4777 case BSEL_V: |
| 4778 UNIMPLEMENTED(); |
| 4779 break; |
| 4780 default: |
| 4781 UNREACHABLE(); |
| 4782 } |
| 4783 } |
| 4784 |
| 4785 void Simulator::DecodeTypeMsa2R() { |
| 4786 DCHECK(kArchVariant == kMips64r6); |
| 4787 DCHECK(CpuFeatures::IsSupported(MIPS_SIMD)); |
| 4788 uint32_t opcode = instr_.InstructionBits() & kMsa2RMask; |
| 4789 switch (opcode) { |
| 4790 case FILL: |
| 4791 switch (DecodeMsaDataFormat()) { |
| 4792 case MSA_BYTE: { |
| 4793 int8_t wd[16]; |
| 4794 int64_t rs = get_register(instr_.WsValue()); |
| 4795 for (int i = 0; i < 16; i++) { |
| 4796 wd[i] = rs & 0xFFu; |
| 4797 } |
| 4798 set_msa_register(instr_.WdValue(), wd); |
| 4799 TraceMSARegWr(wd, BYTE); |
| 4800 break; |
| 4801 } |
| 4802 case MSA_HALF: { |
| 4803 int16_t wd[8]; |
| 4804 int64_t rs = get_register(instr_.WsValue()); |
| 4805 for (int i = 0; i < 8; i++) { |
| 4806 wd[i] = rs & 0xFFFFu; |
| 4807 } |
| 4808 set_msa_register(instr_.WdValue(), wd); |
| 4809 TraceMSARegWr(wd, HALF); |
| 4810 break; |
| 4811 } |
| 4812 case MSA_WORD: { |
| 4813 int32_t wd[4]; |
| 4814 int64_t rs = get_register(instr_.WsValue()); |
| 4815 for (int i = 0; i < 4; i++) { |
| 4816 wd[i] = rs & 0xFFFFFFFFu; |
| 4817 } |
| 4818 set_msa_register(instr_.WdValue(), wd); |
| 4819 TraceMSARegWr(wd, WORD); |
| 4820 break; |
| 4821 } |
| 4822 case MSA_DWORD: { |
| 4823 int64_t wd[2]; |
| 4824 int64_t rs = get_register(instr_.WsValue()); |
| 4825 wd[0] = wd[1] = rs; |
| 4826 set_msa_register(instr_.WdValue(), wd); |
| 4827 TraceMSARegWr(wd, DWORD); |
| 4828 break; |
| 4829 } |
| 4830 default: |
| 4831 UNREACHABLE(); |
| 4832 } |
| 4833 break; |
| 4834 case PCNT: |
| 4835 case NLOC: |
| 4836 case NLZC: |
| 4837 UNIMPLEMENTED(); |
| 4838 break; |
| 4839 default: |
| 4840 UNREACHABLE(); |
| 4841 } |
| 4842 } |
| 4843 |
| 4844 void Simulator::DecodeTypeMsa2RF() { |
| 4845 DCHECK(kArchVariant == kMips64r6); |
| 4846 DCHECK(CpuFeatures::IsSupported(MIPS_SIMD)); |
| 4847 uint32_t opcode = instr_.InstructionBits() & kMsa2RFMask; |
| 4848 switch (opcode) { |
| 4849 case FCLASS: |
| 4850 case FTRUNC_S: |
| 4851 case FTRUNC_U: |
| 4852 case FSQRT: |
| 4853 case FRSQRT: |
| 4854 case FRCP: |
| 4855 case FRINT: |
| 4856 case FLOG2: |
| 4857 case FEXUPL: |
| 4858 case FEXUPR: |
| 4859 case FFQL: |
| 4860 case FFQR: |
| 4861 case FTINT_S: |
| 4862 case FTINT_U: |
| 4863 case FFINT_S: |
| 4864 case FFINT_U: |
| 4865 UNIMPLEMENTED(); |
| 4866 break; |
| 4867 default: |
| 4868 UNREACHABLE(); |
| 4869 } |
| 4870 } |
| 4871 |
4342 void Simulator::DecodeTypeRegister() { | 4872 void Simulator::DecodeTypeRegister() { |
4343 // ---------- Execution. | 4873 // ---------- Execution. |
4344 switch (instr_.OpcodeFieldRaw()) { | 4874 switch (instr_.OpcodeFieldRaw()) { |
4345 case COP1: | 4875 case COP1: |
4346 DecodeTypeRegisterCOP1(); | 4876 DecodeTypeRegisterCOP1(); |
4347 break; | 4877 break; |
4348 case COP1X: | 4878 case COP1X: |
4349 DecodeTypeRegisterCOP1X(); | 4879 DecodeTypeRegisterCOP1X(); |
4350 break; | 4880 break; |
4351 case SPECIAL: | 4881 case SPECIAL: |
4352 DecodeTypeRegisterSPECIAL(); | 4882 DecodeTypeRegisterSPECIAL(); |
4353 break; | 4883 break; |
4354 case SPECIAL2: | 4884 case SPECIAL2: |
4355 DecodeTypeRegisterSPECIAL2(); | 4885 DecodeTypeRegisterSPECIAL2(); |
4356 break; | 4886 break; |
4357 case SPECIAL3: | 4887 case SPECIAL3: |
4358 DecodeTypeRegisterSPECIAL3(); | 4888 DecodeTypeRegisterSPECIAL3(); |
4359 break; | 4889 break; |
| 4890 case MSA: |
| 4891 switch (instr_.MSAMinorOpcodeField()) { |
| 4892 case kMsaMinor3R: |
| 4893 DecodeTypeMsa3R(); |
| 4894 break; |
| 4895 case kMsaMinor3RF: |
| 4896 DecodeTypeMsa3RF(); |
| 4897 break; |
| 4898 case kMsaMinorVEC: |
| 4899 DecodeTypeMsaVec(); |
| 4900 break; |
| 4901 case kMsaMinor2R: |
| 4902 DecodeTypeMsa2R(); |
| 4903 break; |
| 4904 case kMsaMinor2RF: |
| 4905 DecodeTypeMsa2RF(); |
| 4906 break; |
| 4907 default: |
| 4908 UNREACHABLE(); |
| 4909 } |
| 4910 break; |
4360 // Unimplemented opcodes raised an error in the configuration step before, | 4911 // Unimplemented opcodes raised an error in the configuration step before, |
4361 // so we can use the default here to set the destination register in common | 4912 // so we can use the default here to set the destination register in common |
4362 // cases. | 4913 // cases. |
4363 default: | 4914 default: |
4364 UNREACHABLE(); | 4915 UNREACHABLE(); |
4365 } | 4916 } |
4366 } | 4917 } |
4367 | 4918 |
4368 | 4919 |
4369 // Type 2: instructions using a 16, 21 or 26 bits immediate. (e.g. beq, beqc). | 4920 // 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... |
4462 bool do_branch = (instr_.FBtrueValue()) ? cc_value : !cc_value; | 5013 bool do_branch = (instr_.FBtrueValue()) ? cc_value : !cc_value; |
4463 BranchHelper(do_branch); | 5014 BranchHelper(do_branch); |
4464 break; | 5015 break; |
4465 } | 5016 } |
4466 case BC1EQZ: | 5017 case BC1EQZ: |
4467 BranchHelper(!(get_fpu_register(ft_reg) & 0x1)); | 5018 BranchHelper(!(get_fpu_register(ft_reg) & 0x1)); |
4468 break; | 5019 break; |
4469 case BC1NEZ: | 5020 case BC1NEZ: |
4470 BranchHelper(get_fpu_register(ft_reg) & 0x1); | 5021 BranchHelper(get_fpu_register(ft_reg) & 0x1); |
4471 break; | 5022 break; |
| 5023 case BZ_V: |
| 5024 case BZ_B: |
| 5025 case BZ_H: |
| 5026 case BZ_W: |
| 5027 case BZ_D: |
| 5028 case BNZ_V: |
| 5029 case BNZ_B: |
| 5030 case BNZ_H: |
| 5031 case BNZ_W: |
| 5032 case BNZ_D: |
| 5033 UNIMPLEMENTED(); |
| 5034 break; |
4472 default: | 5035 default: |
4473 UNREACHABLE(); | 5036 UNREACHABLE(); |
4474 } | 5037 } |
4475 break; | 5038 break; |
4476 // ------------- REGIMM class. | 5039 // ------------- REGIMM class. |
4477 case REGIMM: | 5040 case REGIMM: |
4478 switch (instr_.RtFieldRaw()) { | 5041 switch (instr_.RtFieldRaw()) { |
4479 case BLTZ: | 5042 case BLTZ: |
4480 BranchHelper(rs < 0); | 5043 BranchHelper(rs < 0); |
4481 break; | 5044 break; |
(...skipping 402 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4884 } | 5447 } |
4885 break; | 5448 break; |
4886 } | 5449 } |
4887 } | 5450 } |
4888 break; | 5451 break; |
4889 } | 5452 } |
4890 } | 5453 } |
4891 SetResult(rs_reg, alu_out); | 5454 SetResult(rs_reg, alu_out); |
4892 break; | 5455 break; |
4893 } | 5456 } |
| 5457 case MSA: |
| 5458 switch (instr_.MSAMinorOpcodeField()) { |
| 5459 case kMsaMinorI8: |
| 5460 DecodeTypeMsaI8(); |
| 5461 break; |
| 5462 case kMsaMinorI5: |
| 5463 DecodeTypeMsaI5(); |
| 5464 break; |
| 5465 case kMsaMinorI10: |
| 5466 DecodeTypeMsaI10(); |
| 5467 break; |
| 5468 case kMsaMinorELM: |
| 5469 DecodeTypeMsaELM(); |
| 5470 break; |
| 5471 case kMsaMinorBIT: |
| 5472 DecodeTypeMsaBIT(); |
| 5473 break; |
| 5474 case kMsaMinorMI10: |
| 5475 DecodeTypeMsaMI10(); |
| 5476 break; |
| 5477 default: |
| 5478 UNREACHABLE(); |
| 5479 break; |
| 5480 } |
| 5481 break; |
4894 default: | 5482 default: |
4895 UNREACHABLE(); | 5483 UNREACHABLE(); |
4896 } | 5484 } |
4897 | 5485 |
4898 if (execute_branch_delay_instruction) { | 5486 if (execute_branch_delay_instruction) { |
4899 // Execute branch delay slot | 5487 // Execute branch delay slot |
4900 // We don't check for end_sim_pc. First it should not be met as the current | 5488 // We don't check for end_sim_pc. First it should not be met as the current |
4901 // pc is valid. Secondly a jump should always execute its branch delay slot. | 5489 // pc is valid. Secondly a jump should always execute its branch delay slot. |
4902 Instruction* branch_delay_instr = | 5490 Instruction* branch_delay_instr = |
4903 reinterpret_cast<Instruction*>(get_pc() + Instruction::kInstrSize); | 5491 reinterpret_cast<Instruction*>(get_pc() + Instruction::kInstrSize); |
(...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5176 } | 5764 } |
5177 | 5765 |
5178 | 5766 |
5179 #undef UNSUPPORTED | 5767 #undef UNSUPPORTED |
5180 } // namespace internal | 5768 } // namespace internal |
5181 } // namespace v8 | 5769 } // namespace v8 |
5182 | 5770 |
5183 #endif // USE_SIMULATOR | 5771 #endif // USE_SIMULATOR |
5184 | 5772 |
5185 #endif // V8_TARGET_ARCH_MIPS64 | 5773 #endif // V8_TARGET_ARCH_MIPS64 |
OLD | NEW |