| Index: src/mips64/simulator-mips64.cc
|
| diff --git a/src/mips64/simulator-mips64.cc b/src/mips64/simulator-mips64.cc
|
| index 7ec51b1cfed4d466c584b0c59387abdd98a7dbe8..08c4458bf9a886f5815eaa533991bdc01f8fec12 100644
|
| --- a/src/mips64/simulator-mips64.cc
|
| +++ b/src/mips64/simulator-mips64.cc
|
| @@ -839,7 +839,8 @@ Simulator::Simulator(Isolate* isolate) : isolate_(isolate) {
|
| registers_[i] = 0;
|
| }
|
| for (int i = 0; i < kNumFPURegisters; i++) {
|
| - FPUregisters_[i] = 0;
|
| + FPUregisters_[2 * i] = 0;
|
| + FPUregisters_[2 * i + 1] = 0; // upper part for MSA ASE
|
| }
|
|
|
| if (kArchVariant == kMips64r6) {
|
| @@ -994,7 +995,7 @@ void Simulator::set_dw_register(int reg, const int* dbl) {
|
|
|
| void Simulator::set_fpu_register(int fpureg, int64_t value) {
|
| DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters));
|
| - FPUregisters_[fpureg] = value;
|
| + FPUregisters_[fpureg * 2] = value;
|
| }
|
|
|
|
|
| @@ -1003,9 +1004,9 @@ void Simulator::set_fpu_register_word(int fpureg, int32_t value) {
|
| DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters));
|
| int32_t* pword;
|
| if (kArchEndian == kLittle) {
|
| - pword = reinterpret_cast<int32_t*>(&FPUregisters_[fpureg]);
|
| + pword = reinterpret_cast<int32_t*>(&FPUregisters_[fpureg * 2]);
|
| } else {
|
| - pword = reinterpret_cast<int32_t*>(&FPUregisters_[fpureg]) + 1;
|
| + pword = reinterpret_cast<int32_t*>(&FPUregisters_[fpureg * 2]) + 1;
|
| }
|
| *pword = value;
|
| }
|
| @@ -1016,9 +1017,9 @@ void Simulator::set_fpu_register_hi_word(int fpureg, int32_t value) {
|
| DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters));
|
| int32_t* phiword;
|
| if (kArchEndian == kLittle) {
|
| - phiword = (reinterpret_cast<int32_t*>(&FPUregisters_[fpureg])) + 1;
|
| + phiword = (reinterpret_cast<int32_t*>(&FPUregisters_[fpureg * 2])) + 1;
|
| } else {
|
| - phiword = reinterpret_cast<int32_t*>(&FPUregisters_[fpureg]);
|
| + phiword = reinterpret_cast<int32_t*>(&FPUregisters_[fpureg * 2]);
|
| }
|
| *phiword = value;
|
| }
|
| @@ -1026,13 +1027,13 @@ void Simulator::set_fpu_register_hi_word(int fpureg, int32_t value) {
|
|
|
| void Simulator::set_fpu_register_float(int fpureg, float value) {
|
| DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters));
|
| - *bit_cast<float*>(&FPUregisters_[fpureg]) = value;
|
| + *bit_cast<float*>(&FPUregisters_[fpureg * 2]) = value;
|
| }
|
|
|
|
|
| void Simulator::set_fpu_register_double(int fpureg, double value) {
|
| DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters));
|
| - *bit_cast<double*>(&FPUregisters_[fpureg]) = value;
|
| + *bit_cast<double*>(&FPUregisters_[fpureg * 2]) = value;
|
| }
|
|
|
|
|
| @@ -1063,39 +1064,50 @@ double Simulator::get_double_from_register_pair(int reg) {
|
|
|
| int64_t Simulator::get_fpu_register(int fpureg) const {
|
| DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters));
|
| - return FPUregisters_[fpureg];
|
| + return FPUregisters_[fpureg * 2];
|
| }
|
|
|
|
|
| int32_t Simulator::get_fpu_register_word(int fpureg) const {
|
| DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters));
|
| - return static_cast<int32_t>(FPUregisters_[fpureg] & 0xffffffff);
|
| + return static_cast<int32_t>(FPUregisters_[fpureg * 2] & 0xffffffff);
|
| }
|
|
|
|
|
| int32_t Simulator::get_fpu_register_signed_word(int fpureg) const {
|
| DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters));
|
| - return static_cast<int32_t>(FPUregisters_[fpureg] & 0xffffffff);
|
| + return static_cast<int32_t>(FPUregisters_[fpureg * 2] & 0xffffffff);
|
| }
|
|
|
|
|
| int32_t Simulator::get_fpu_register_hi_word(int fpureg) const {
|
| DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters));
|
| - return static_cast<int32_t>((FPUregisters_[fpureg] >> 32) & 0xffffffff);
|
| + return static_cast<int32_t>((FPUregisters_[fpureg * 2] >> 32) & 0xffffffff);
|
| }
|
|
|
|
|
| float Simulator::get_fpu_register_float(int fpureg) const {
|
| DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters));
|
| - return *bit_cast<float*>(const_cast<int64_t*>(&FPUregisters_[fpureg]));
|
| + return *bit_cast<float*>(const_cast<int64_t*>(&FPUregisters_[fpureg * 2]));
|
| }
|
|
|
|
|
| double Simulator::get_fpu_register_double(int fpureg) const {
|
| DCHECK((fpureg >= 0) && (fpureg < kNumFPURegisters));
|
| - return *bit_cast<double*>(&FPUregisters_[fpureg]);
|
| + return *bit_cast<double*>(&FPUregisters_[fpureg * 2]);
|
| }
|
|
|
| +template <typename T>
|
| +void Simulator::get_msa_register(int wreg, T* value) {
|
| + DCHECK((wreg >= 0) && (wreg < kNumMSARegisters));
|
| + memcpy(value, FPUregisters_ + wreg * 2, kSimd128Size);
|
| +}
|
| +
|
| +template <typename T>
|
| +void Simulator::set_msa_register(int wreg, const T* value) {
|
| + DCHECK((wreg >= 0) && (wreg < kNumMSARegisters));
|
| + memcpy(FPUregisters_ + wreg * 2, value, kSimd128Size);
|
| +}
|
|
|
| // Runtime FP routines take up to two double arguments and zero
|
| // or one integer arguments. All are constructed here,
|
| @@ -1670,6 +1682,59 @@ void Simulator::TraceRegWr(int64_t value, TraceType t) {
|
| }
|
| }
|
|
|
| +template <typename T>
|
| +void Simulator::TraceMSARegWr(T* value, TraceType t) {
|
| + if (::v8::internal::FLAG_trace_sim) {
|
| + union {
|
| + uint8_t b[16];
|
| + uint16_t h[8];
|
| + uint32_t w[4];
|
| + uint64_t d[2];
|
| + float f[4];
|
| + double df[2];
|
| + } v;
|
| + memcpy(v.b, value, kSimd128Size);
|
| + switch (t) {
|
| + case BYTE:
|
| + SNPrintF(trace_buf_,
|
| + "LO: %016" PRIx64 " HI: %016" PRIx64 " (%" PRIu64 ")",
|
| + v.d[0], v.d[1], icount_);
|
| + break;
|
| + case HALF:
|
| + SNPrintF(trace_buf_,
|
| + "LO: %016" PRIx64 " HI: %016" PRIx64 " (%" PRIu64 ")",
|
| + v.d[0], v.d[1], icount_);
|
| + break;
|
| + case WORD:
|
| + SNPrintF(trace_buf_,
|
| + "LO: %016" PRIx64 " HI: %016" PRIx64 " (%" PRIu64
|
| + ") int32[0..3]:%" PRId32 " %" PRId32 " %" PRId32
|
| + " %" PRId32,
|
| + v.d[0], v.d[1], icount_, v.w[0], v.w[1], v.w[2], v.w[3]);
|
| + break;
|
| + case DWORD:
|
| + SNPrintF(trace_buf_,
|
| + "LO: %016" PRIx64 " HI: %016" PRIx64 " (%" PRIu64 ")",
|
| + v.d[0], v.d[1], icount_);
|
| + break;
|
| + case FLOAT:
|
| + SNPrintF(trace_buf_,
|
| + "LO: %016" PRIx64 " HI: %016" PRIx64 " (%" PRIu64
|
| + ") flt[0..3]:%e %e %e %e",
|
| + v.d[0], v.d[1], icount_, v.f[0], v.f[1], v.f[2], v.f[3]);
|
| + break;
|
| + case DOUBLE:
|
| + SNPrintF(trace_buf_,
|
| + "LO: %016" PRIx64 " HI: %016" PRIx64 " (%" PRIu64
|
| + ") dbl[0..1]:%e %e",
|
| + v.d[0], v.d[1], icount_, v.df[0], v.df[1]);
|
| + break;
|
| + default:
|
| + UNREACHABLE();
|
| + }
|
| + }
|
| +}
|
| +
|
| // TODO(plind): consider making icount_ printing a flag option.
|
| void Simulator::TraceMemRd(int64_t addr, int64_t value, TraceType t) {
|
| if (::v8::internal::FLAG_trace_sim) {
|
| @@ -4306,6 +4371,471 @@ void Simulator::DecodeTypeRegisterSPECIAL3() {
|
| }
|
| }
|
|
|
| +int Simulator::DecodeMsaDataFormat() {
|
| + int df = -1;
|
| + if (instr_.IsMSABranchInstr()) {
|
| + switch (instr_.RsFieldRaw()) {
|
| + case BZ_V:
|
| + case BNZ_V:
|
| + df = MSA_VECT;
|
| + break;
|
| + case BZ_B:
|
| + case BNZ_B:
|
| + df = MSA_BYTE;
|
| + break;
|
| + case BZ_H:
|
| + case BNZ_H:
|
| + df = MSA_HALF;
|
| + break;
|
| + case BZ_W:
|
| + case BNZ_W:
|
| + df = MSA_WORD;
|
| + break;
|
| + case BZ_D:
|
| + case BNZ_D:
|
| + df = MSA_DWORD;
|
| + break;
|
| + default:
|
| + UNREACHABLE();
|
| + break;
|
| + }
|
| + } else {
|
| + int DF[] = {MSA_BYTE, MSA_HALF, MSA_WORD, MSA_DWORD};
|
| + switch (instr_.MSAMinorOpcodeField()) {
|
| + case kMsaMinorI5:
|
| + case kMsaMinorI10:
|
| + case kMsaMinor3R:
|
| + df = DF[instr_.Bits(22, 21)];
|
| + break;
|
| + case kMsaMinorMI10:
|
| + df = DF[instr_.Bits(1, 0)];
|
| + break;
|
| + case kMsaMinorBIT:
|
| + df = DF[instr_.MsaBitDf()];
|
| + break;
|
| + case kMsaMinorELM:
|
| + df = DF[instr_.MsaElmDf()];
|
| + break;
|
| + case kMsaMinor3RF: {
|
| + uint32_t opcode = instr_.InstructionBits() & kMsa3RFMask;
|
| + switch (opcode) {
|
| + case FEXDO:
|
| + case FTQ:
|
| + case MUL_Q:
|
| + case MADD_Q:
|
| + case MSUB_Q:
|
| + case MULR_Q:
|
| + case MADDR_Q:
|
| + case MSUBR_Q:
|
| + df = DF[1 + instr_.Bit(21)];
|
| + break;
|
| + default:
|
| + df = DF[2 + instr_.Bit(21)];
|
| + break;
|
| + }
|
| + } break;
|
| + case kMsaMinor2R:
|
| + df = DF[instr_.Bits(17, 16)];
|
| + break;
|
| + case kMsaMinor2RF:
|
| + df = DF[2 + instr_.Bit(16)];
|
| + break;
|
| + default:
|
| + UNREACHABLE();
|
| + break;
|
| + }
|
| + }
|
| + return df;
|
| +}
|
| +
|
| +void Simulator::DecodeTypeMsaI8() {
|
| + DCHECK(kArchVariant == kMips64r6);
|
| + DCHECK(CpuFeatures::IsSupported(MIPS_SIMD));
|
| + uint32_t opcode = instr_.InstructionBits() & kMsaI8Mask;
|
| +
|
| + switch (opcode) {
|
| + case ANDI_B:
|
| + case ORI_B:
|
| + case NORI_B:
|
| + case XORI_B:
|
| + case BMNZI_B:
|
| + case BMZI_B:
|
| + case BSELI_B:
|
| + case SHF_B:
|
| + case SHF_H:
|
| + case SHF_W:
|
| + UNIMPLEMENTED();
|
| + break;
|
| + default:
|
| + UNREACHABLE();
|
| + }
|
| +}
|
| +
|
| +void Simulator::DecodeTypeMsaI5() {
|
| + DCHECK(kArchVariant == kMips64r6);
|
| + DCHECK(CpuFeatures::IsSupported(MIPS_SIMD));
|
| + uint32_t opcode = instr_.InstructionBits() & kMsaI5Mask;
|
| +
|
| + switch (opcode) {
|
| + case ADDVI:
|
| + case SUBVI:
|
| + case MAXI_S:
|
| + case MAXI_U:
|
| + case MINI_S:
|
| + case MINI_U:
|
| + case CEQI:
|
| + case CLTI_S:
|
| + case CLTI_U:
|
| + case CLEI_S:
|
| + case CLEI_U:
|
| + UNIMPLEMENTED();
|
| + break;
|
| + default:
|
| + UNREACHABLE();
|
| + }
|
| +}
|
| +
|
| +void Simulator::DecodeTypeMsaI10() {
|
| + DCHECK(kArchVariant == kMips64r6);
|
| + DCHECK(CpuFeatures::IsSupported(MIPS_SIMD));
|
| + uint32_t opcode = instr_.InstructionBits() & kMsaI5Mask;
|
| + if (opcode == LDI) {
|
| + UNIMPLEMENTED();
|
| + } else {
|
| + UNREACHABLE();
|
| + }
|
| +}
|
| +
|
| +void Simulator::DecodeTypeMsaELM() {
|
| + DCHECK(kArchVariant == kMips64r6);
|
| + DCHECK(CpuFeatures::IsSupported(MIPS_SIMD));
|
| + uint32_t opcode = instr_.InstructionBits() & kMsaELMMask;
|
| + int32_t n = instr_.MsaElmNValue();
|
| + int64_t alu_out;
|
| + switch (opcode) {
|
| + case COPY_S:
|
| + case COPY_U:
|
| + switch (DecodeMsaDataFormat()) {
|
| + case MSA_BYTE: {
|
| + DCHECK(n < 16);
|
| + int8_t ws[16];
|
| + get_msa_register(instr_.WsValue(), ws);
|
| + alu_out = static_cast<int32_t>(ws[n]);
|
| + SetResult(wd_reg(), (opcode == COPY_U) ? alu_out & 0xFFu : alu_out);
|
| + break;
|
| + }
|
| + case MSA_HALF: {
|
| + DCHECK(n < 8);
|
| + int16_t ws[8];
|
| + get_msa_register(instr_.WsValue(), ws);
|
| + alu_out = static_cast<int32_t>(ws[n]);
|
| + SetResult(wd_reg(), (opcode == COPY_U) ? alu_out & 0xFFFFu : alu_out);
|
| + break;
|
| + }
|
| + case MSA_WORD: {
|
| + DCHECK(n < 4);
|
| + int32_t ws[4];
|
| + get_msa_register(instr_.WsValue(), ws);
|
| + alu_out = static_cast<int32_t>(ws[n]);
|
| + SetResult(wd_reg(),
|
| + (opcode == COPY_U) ? alu_out & 0xFFFFFFFFu : alu_out);
|
| + break;
|
| + }
|
| + case MSA_DWORD: {
|
| + DCHECK(n < 2);
|
| + int64_t ws[2];
|
| + get_msa_register(instr_.WsValue(), ws);
|
| + alu_out = static_cast<int64_t>(ws[n]);
|
| + SetResult(wd_reg(), alu_out);
|
| + break;
|
| + }
|
| + default:
|
| + UNREACHABLE();
|
| + }
|
| + break;
|
| + case SLDI:
|
| + case SPLATI:
|
| + case INSERT:
|
| + case INSVE:
|
| + UNIMPLEMENTED();
|
| + break;
|
| + default:
|
| + UNREACHABLE();
|
| + }
|
| +}
|
| +
|
| +void Simulator::DecodeTypeMsaBIT() {
|
| + DCHECK(kArchVariant == kMips64r6);
|
| + DCHECK(CpuFeatures::IsSupported(MIPS_SIMD));
|
| + uint32_t opcode = instr_.InstructionBits() & kMsaBITMask;
|
| +
|
| + switch (opcode) {
|
| + case SLLI:
|
| + case SRAI:
|
| + case SRLI:
|
| + case BCLRI:
|
| + case BSETI:
|
| + case BNEGI:
|
| + case BINSLI:
|
| + case BINSRI:
|
| + case SAT_S:
|
| + case SAT_U:
|
| + case SRARI:
|
| + case SRLRI:
|
| + UNIMPLEMENTED();
|
| + break;
|
| + default:
|
| + UNREACHABLE();
|
| + }
|
| +}
|
| +
|
| +void Simulator::DecodeTypeMsaMI10() {
|
| + DCHECK(kArchVariant == kMips64r6);
|
| + DCHECK(CpuFeatures::IsSupported(MIPS_SIMD));
|
| + uint32_t opcode = instr_.InstructionBits() & kMsaMI10Mask;
|
| + if (opcode == MSA_LD) {
|
| + UNIMPLEMENTED();
|
| + } else if (opcode == MSA_ST) {
|
| + UNIMPLEMENTED();
|
| + } else {
|
| + UNREACHABLE();
|
| + }
|
| +}
|
| +
|
| +void Simulator::DecodeTypeMsa3R() {
|
| + DCHECK(kArchVariant == kMips64r6);
|
| + DCHECK(CpuFeatures::IsSupported(MIPS_SIMD));
|
| + uint32_t opcode = instr_.InstructionBits() & kMsa3RMask;
|
| + switch (opcode) {
|
| + case SLL_MSA:
|
| + case SRA_MSA:
|
| + case SRL_MSA:
|
| + case BCLR:
|
| + case BSET:
|
| + case BNEG:
|
| + case BINSL:
|
| + case BINSR:
|
| + case ADDV:
|
| + case SUBV:
|
| + case MAX_S:
|
| + case MAX_U:
|
| + case MIN_S:
|
| + case MIN_U:
|
| + case MAX_A:
|
| + case MIN_A:
|
| + case CEQ:
|
| + case CLT_S:
|
| + case CLT_U:
|
| + case CLE_S:
|
| + case CLE_U:
|
| + case ADD_A:
|
| + case ADDS_A:
|
| + case ADDS_S:
|
| + case ADDS_U:
|
| + case AVE_S:
|
| + case AVE_U:
|
| + case AVER_S:
|
| + case AVER_U:
|
| + case SUBS_S:
|
| + case SUBS_U:
|
| + case SUBSUS_U:
|
| + case SUBSUU_S:
|
| + case ASUB_S:
|
| + case ASUB_U:
|
| + case MULV:
|
| + case MADDV:
|
| + case MSUBV:
|
| + case DIV_S_MSA:
|
| + case DIV_U:
|
| + case MOD_S:
|
| + case MOD_U:
|
| + case DOTP_S:
|
| + case DOTP_U:
|
| + case DPADD_S:
|
| + case DPADD_U:
|
| + case DPSUB_S:
|
| + case DPSUB_U:
|
| + case SLD:
|
| + case SPLAT:
|
| + case PCKEV:
|
| + case PCKOD:
|
| + case ILVL:
|
| + case ILVR:
|
| + case ILVEV:
|
| + case ILVOD:
|
| + case VSHF:
|
| + case SRAR:
|
| + case SRLR:
|
| + case HADD_S:
|
| + case HADD_U:
|
| + case HSUB_S:
|
| + case HSUB_U:
|
| + UNIMPLEMENTED();
|
| + break;
|
| + default:
|
| + UNREACHABLE();
|
| + }
|
| +}
|
| +
|
| +void Simulator::DecodeTypeMsa3RF() {
|
| + DCHECK(kArchVariant == kMips64r6);
|
| + DCHECK(CpuFeatures::IsSupported(MIPS_SIMD));
|
| + uint32_t opcode = instr_.InstructionBits() & kMsa3RFMask;
|
| + switch (opcode) {
|
| + case FCAF:
|
| + case FCUN:
|
| + case FCEQ:
|
| + case FCUEQ:
|
| + case FCLT:
|
| + case FCULT:
|
| + case FCLE:
|
| + case FCULE:
|
| + case FSAF:
|
| + case FSUN:
|
| + case FSEQ:
|
| + case FSUEQ:
|
| + case FSLT:
|
| + case FSULT:
|
| + case FSLE:
|
| + case FSULE:
|
| + case FADD:
|
| + case FSUB:
|
| + case FMUL:
|
| + case FDIV:
|
| + case FMADD:
|
| + case FMSUB:
|
| + case FEXP2:
|
| + case FEXDO:
|
| + case FTQ:
|
| + case FMIN:
|
| + case FMIN_A:
|
| + case FMAX:
|
| + case FMAX_A:
|
| + case FCOR:
|
| + case FCUNE:
|
| + case FCNE:
|
| + case MUL_Q:
|
| + case MADD_Q:
|
| + case MSUB_Q:
|
| + case FSOR:
|
| + case FSUNE:
|
| + case FSNE:
|
| + case MULR_Q:
|
| + case MADDR_Q:
|
| + case MSUBR_Q:
|
| + UNIMPLEMENTED();
|
| + break;
|
| + default:
|
| + UNREACHABLE();
|
| + }
|
| +}
|
| +
|
| +void Simulator::DecodeTypeMsaVec() {
|
| + DCHECK(kArchVariant == kMips64r6);
|
| + DCHECK(CpuFeatures::IsSupported(MIPS_SIMD));
|
| + uint32_t opcode = instr_.InstructionBits() & kMsaVECMask;
|
| + switch (opcode) {
|
| + case AND_V:
|
| + case OR_V:
|
| + case NOR_V:
|
| + case XOR_V:
|
| + case BMNZ_V:
|
| + case BMZ_V:
|
| + case BSEL_V:
|
| + UNIMPLEMENTED();
|
| + break;
|
| + default:
|
| + UNREACHABLE();
|
| + }
|
| +}
|
| +
|
| +void Simulator::DecodeTypeMsa2R() {
|
| + DCHECK(kArchVariant == kMips64r6);
|
| + DCHECK(CpuFeatures::IsSupported(MIPS_SIMD));
|
| + uint32_t opcode = instr_.InstructionBits() & kMsa2RMask;
|
| + switch (opcode) {
|
| + case FILL:
|
| + switch (DecodeMsaDataFormat()) {
|
| + case MSA_BYTE: {
|
| + int8_t wd[16];
|
| + int64_t rs = get_register(instr_.WsValue());
|
| + for (int i = 0; i < 16; i++) {
|
| + wd[i] = rs & 0xFFu;
|
| + }
|
| + set_msa_register(instr_.WdValue(), wd);
|
| + TraceMSARegWr(wd, BYTE);
|
| + break;
|
| + }
|
| + case MSA_HALF: {
|
| + int16_t wd[8];
|
| + int64_t rs = get_register(instr_.WsValue());
|
| + for (int i = 0; i < 8; i++) {
|
| + wd[i] = rs & 0xFFFFu;
|
| + }
|
| + set_msa_register(instr_.WdValue(), wd);
|
| + TraceMSARegWr(wd, HALF);
|
| + break;
|
| + }
|
| + case MSA_WORD: {
|
| + int32_t wd[4];
|
| + int64_t rs = get_register(instr_.WsValue());
|
| + for (int i = 0; i < 4; i++) {
|
| + wd[i] = rs & 0xFFFFFFFFu;
|
| + }
|
| + set_msa_register(instr_.WdValue(), wd);
|
| + TraceMSARegWr(wd, WORD);
|
| + break;
|
| + }
|
| + case MSA_DWORD: {
|
| + int64_t wd[2];
|
| + int64_t rs = get_register(instr_.WsValue());
|
| + wd[0] = wd[1] = rs;
|
| + set_msa_register(instr_.WdValue(), wd);
|
| + TraceMSARegWr(wd, DWORD);
|
| + break;
|
| + }
|
| + default:
|
| + UNREACHABLE();
|
| + }
|
| + break;
|
| + case PCNT:
|
| + case NLOC:
|
| + case NLZC:
|
| + UNIMPLEMENTED();
|
| + break;
|
| + default:
|
| + UNREACHABLE();
|
| + }
|
| +}
|
| +
|
| +void Simulator::DecodeTypeMsa2RF() {
|
| + DCHECK(kArchVariant == kMips64r6);
|
| + DCHECK(CpuFeatures::IsSupported(MIPS_SIMD));
|
| + uint32_t opcode = instr_.InstructionBits() & kMsa2RFMask;
|
| + switch (opcode) {
|
| + case FCLASS:
|
| + case FTRUNC_S:
|
| + case FTRUNC_U:
|
| + case FSQRT:
|
| + case FRSQRT:
|
| + case FRCP:
|
| + case FRINT:
|
| + case FLOG2:
|
| + case FEXUPL:
|
| + case FEXUPR:
|
| + case FFQL:
|
| + case FFQR:
|
| + case FTINT_S:
|
| + case FTINT_U:
|
| + case FFINT_S:
|
| + case FFINT_U:
|
| + UNIMPLEMENTED();
|
| + break;
|
| + default:
|
| + UNREACHABLE();
|
| + }
|
| +}
|
| +
|
| void Simulator::DecodeTypeRegister() {
|
| // ---------- Execution.
|
| switch (instr_.OpcodeFieldRaw()) {
|
| @@ -4324,6 +4854,27 @@ void Simulator::DecodeTypeRegister() {
|
| case SPECIAL3:
|
| DecodeTypeRegisterSPECIAL3();
|
| break;
|
| + case MSA:
|
| + switch (instr_.MSAMinorOpcodeField()) {
|
| + case kMsaMinor3R:
|
| + DecodeTypeMsa3R();
|
| + break;
|
| + case kMsaMinor3RF:
|
| + DecodeTypeMsa3RF();
|
| + break;
|
| + case kMsaMinorVEC:
|
| + DecodeTypeMsaVec();
|
| + break;
|
| + case kMsaMinor2R:
|
| + DecodeTypeMsa2R();
|
| + break;
|
| + case kMsaMinor2RF:
|
| + DecodeTypeMsa2RF();
|
| + break;
|
| + default:
|
| + UNREACHABLE();
|
| + }
|
| + break;
|
| // Unimplemented opcodes raised an error in the configuration step before,
|
| // so we can use the default here to set the destination register in common
|
| // cases.
|
| @@ -4436,6 +4987,18 @@ void Simulator::DecodeTypeImmediate() {
|
| case BC1NEZ:
|
| BranchHelper(get_fpu_register(ft_reg) & 0x1);
|
| break;
|
| + case BZ_V:
|
| + case BZ_B:
|
| + case BZ_H:
|
| + case BZ_W:
|
| + case BZ_D:
|
| + case BNZ_V:
|
| + case BNZ_B:
|
| + case BNZ_H:
|
| + case BNZ_W:
|
| + case BNZ_D:
|
| + UNIMPLEMENTED();
|
| + break;
|
| default:
|
| UNREACHABLE();
|
| }
|
| @@ -4858,6 +5421,31 @@ void Simulator::DecodeTypeImmediate() {
|
| SetResult(rs_reg, alu_out);
|
| break;
|
| }
|
| + case MSA:
|
| + switch (instr_.MSAMinorOpcodeField()) {
|
| + case kMsaMinorI8:
|
| + DecodeTypeMsaI8();
|
| + break;
|
| + case kMsaMinorI5:
|
| + DecodeTypeMsaI5();
|
| + break;
|
| + case kMsaMinorI10:
|
| + DecodeTypeMsaI10();
|
| + break;
|
| + case kMsaMinorELM:
|
| + DecodeTypeMsaELM();
|
| + break;
|
| + case kMsaMinorBIT:
|
| + DecodeTypeMsaBIT();
|
| + break;
|
| + case kMsaMinorMI10:
|
| + DecodeTypeMsaMI10();
|
| + break;
|
| + default:
|
| + UNREACHABLE();
|
| + break;
|
| + }
|
| + break;
|
| default:
|
| UNREACHABLE();
|
| }
|
|
|