diff options
author | 2017-10-13 14:34:32 +0200 | |
---|---|---|
committer | 2017-10-19 11:24:55 +0200 | |
commit | 3309c01e55821f693e3b9cec0ef24969edf2528f (patch) | |
tree | cacb4a3775166297b1c9bb9e6236ab901ad725d4 | |
parent | 24276374dcaf95bfc52be2b8193eb4e337de62e4 (diff) |
MIPS: Introduce a few MSA instructions
These instructions are needed for SIMD reduction.
Also added assembler tests for each instruction.
Test: mma test-art-host-gtest
Change-Id: I0f02618a14b4cbcc3b81ce51dd2586fa4cdbfd18
-rw-r--r-- | compiler/utils/assembler_test.h | 18 | ||||
-rw-r--r-- | compiler/utils/mips/assembler_mips.cc | 212 | ||||
-rw-r--r-- | compiler/utils/mips/assembler_mips.h | 27 | ||||
-rw-r--r-- | compiler/utils/mips/assembler_mips32r6_test.cc | 126 | ||||
-rw-r--r-- | compiler/utils/mips64/assembler_mips64.cc | 156 | ||||
-rw-r--r-- | compiler/utils/mips64/assembler_mips64.h | 30 | ||||
-rw-r--r-- | compiler/utils/mips64/assembler_mips64_test.cc | 145 | ||||
-rw-r--r-- | disassembler/disassembler_mips.cc | 33 |
8 files changed, 747 insertions, 0 deletions
diff --git a/compiler/utils/assembler_test.h b/compiler/utils/assembler_test.h index ae7636b106..ad84412ef5 100644 --- a/compiler/utils/assembler_test.h +++ b/compiler/utils/assembler_test.h @@ -650,6 +650,24 @@ class AssemblerTest : public testing::Test { } template <typename ImmType> + std::string RepeatRVIb(void (Ass::*f)(Reg, VecReg, ImmType), + int imm_bits, + const std::string& fmt, + int bias = 0, + int multiplier = 1) { + return RepeatTemplatedRegistersImmBits<Reg, VecReg, ImmType>( + f, + imm_bits, + GetRegisters(), + GetVectorRegisters(), + &AssemblerTest::GetRegName<RegisterView::kUsePrimaryName>, + &AssemblerTest::GetVecRegName, + fmt, + bias, + multiplier); + } + + template <typename ImmType> std::string RepeatVVIb(void (Ass::*f)(VecReg, VecReg, ImmType), int imm_bits, const std::string& fmt, diff --git a/compiler/utils/mips/assembler_mips.cc b/compiler/utils/mips/assembler_mips.cc index e85645b446..cbb2c0ea47 100644 --- a/compiler/utils/mips/assembler_mips.cc +++ b/compiler/utils/mips/assembler_mips.cc @@ -2800,6 +2800,74 @@ void MipsAssembler::SplatiD(VectorRegister wd, VectorRegister ws, int n1) { static_cast<FRegister>(ws)); } +void MipsAssembler::Copy_sB(Register rd, VectorRegister ws, int n4) { + CHECK(HasMsa()); + CHECK(IsUint<4>(n4)) << n4; + DsFsmInstrRf(EmitMsaELM(0x2, n4 | kMsaDfNByteMask, ws, static_cast<VectorRegister>(rd), 0x19), + rd, + static_cast<FRegister>(ws)); +} + +void MipsAssembler::Copy_sH(Register rd, VectorRegister ws, int n3) { + CHECK(HasMsa()); + CHECK(IsUint<3>(n3)) << n3; + DsFsmInstrRf(EmitMsaELM(0x2, n3 | kMsaDfNHalfwordMask, ws, static_cast<VectorRegister>(rd), 0x19), + rd, + static_cast<FRegister>(ws)); +} + +void MipsAssembler::Copy_sW(Register rd, VectorRegister ws, int n2) { + CHECK(HasMsa()); + CHECK(IsUint<2>(n2)) << n2; + DsFsmInstrRf(EmitMsaELM(0x2, n2 | kMsaDfNWordMask, ws, static_cast<VectorRegister>(rd), 0x19), + rd, + static_cast<FRegister>(ws)); +} + +void MipsAssembler::Copy_uB(Register rd, VectorRegister ws, int n4) { + CHECK(HasMsa()); + CHECK(IsUint<4>(n4)) << n4; + DsFsmInstrRf(EmitMsaELM(0x3, n4 | kMsaDfNByteMask, ws, static_cast<VectorRegister>(rd), 0x19), + rd, + static_cast<FRegister>(ws)); +} + +void MipsAssembler::Copy_uH(Register rd, VectorRegister ws, int n3) { + CHECK(HasMsa()); + CHECK(IsUint<3>(n3)) << n3; + DsFsmInstrRf(EmitMsaELM(0x3, n3 | kMsaDfNHalfwordMask, ws, static_cast<VectorRegister>(rd), 0x19), + rd, + static_cast<FRegister>(ws)); +} + +void MipsAssembler::InsertB(VectorRegister wd, Register rs, int n4) { + CHECK(HasMsa()); + CHECK(IsUint<4>(n4)) << n4; + DsFsmInstrFffr(EmitMsaELM(0x4, n4 | kMsaDfNByteMask, static_cast<VectorRegister>(rs), wd, 0x19), + static_cast<FRegister>(wd), + static_cast<FRegister>(wd), + rs); +} + +void MipsAssembler::InsertH(VectorRegister wd, Register rs, int n3) { + CHECK(HasMsa()); + CHECK(IsUint<3>(n3)) << n3; + DsFsmInstrFffr( + EmitMsaELM(0x4, n3 | kMsaDfNHalfwordMask, static_cast<VectorRegister>(rs), wd, 0x19), + static_cast<FRegister>(wd), + static_cast<FRegister>(wd), + rs); +} + +void MipsAssembler::InsertW(VectorRegister wd, Register rs, int n2) { + CHECK(HasMsa()); + CHECK(IsUint<2>(n2)) << n2; + DsFsmInstrFffr(EmitMsaELM(0x4, n2 | kMsaDfNWordMask, static_cast<VectorRegister>(rs), wd, 0x19), + static_cast<FRegister>(wd), + static_cast<FRegister>(wd), + rs); +} + void MipsAssembler::FillB(VectorRegister wd, Register rs) { CHECK(HasMsa()); DsFsmInstrFr(EmitMsa2R(0xc0, 0x0, static_cast<VectorRegister>(rs), wd, 0x1e), @@ -2921,6 +2989,38 @@ void MipsAssembler::StD(VectorRegister wd, Register rs, int offset) { rs); } +void MipsAssembler::IlvlB(VectorRegister wd, VectorRegister ws, VectorRegister wt) { + CHECK(HasMsa()); + DsFsmInstrFff(EmitMsa3R(0x4, 0x0, wt, ws, wd, 0x14), + static_cast<FRegister>(wd), + static_cast<FRegister>(ws), + static_cast<FRegister>(wt)); +} + +void MipsAssembler::IlvlH(VectorRegister wd, VectorRegister ws, VectorRegister wt) { + CHECK(HasMsa()); + DsFsmInstrFff(EmitMsa3R(0x4, 0x1, wt, ws, wd, 0x14), + static_cast<FRegister>(wd), + static_cast<FRegister>(ws), + static_cast<FRegister>(wt)); +} + +void MipsAssembler::IlvlW(VectorRegister wd, VectorRegister ws, VectorRegister wt) { + CHECK(HasMsa()); + DsFsmInstrFff(EmitMsa3R(0x4, 0x2, wt, ws, wd, 0x14), + static_cast<FRegister>(wd), + static_cast<FRegister>(ws), + static_cast<FRegister>(wt)); +} + +void MipsAssembler::IlvlD(VectorRegister wd, VectorRegister ws, VectorRegister wt) { + CHECK(HasMsa()); + DsFsmInstrFff(EmitMsa3R(0x4, 0x3, wt, ws, wd, 0x14), + static_cast<FRegister>(wd), + static_cast<FRegister>(ws), + static_cast<FRegister>(wt)); +} + void MipsAssembler::IlvrB(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); DsFsmInstrFff(EmitMsa3R(0x5, 0x0, wt, ws, wd, 0x14), @@ -2953,6 +3053,70 @@ void MipsAssembler::IlvrD(VectorRegister wd, VectorRegister ws, VectorRegister w static_cast<FRegister>(wt)); } +void MipsAssembler::IlvevB(VectorRegister wd, VectorRegister ws, VectorRegister wt) { + CHECK(HasMsa()); + DsFsmInstrFff(EmitMsa3R(0x6, 0x0, wt, ws, wd, 0x14), + static_cast<FRegister>(wd), + static_cast<FRegister>(ws), + static_cast<FRegister>(wt)); +} + +void MipsAssembler::IlvevH(VectorRegister wd, VectorRegister ws, VectorRegister wt) { + CHECK(HasMsa()); + DsFsmInstrFff(EmitMsa3R(0x6, 0x1, wt, ws, wd, 0x14), + static_cast<FRegister>(wd), + static_cast<FRegister>(ws), + static_cast<FRegister>(wt)); +} + +void MipsAssembler::IlvevW(VectorRegister wd, VectorRegister ws, VectorRegister wt) { + CHECK(HasMsa()); + DsFsmInstrFff(EmitMsa3R(0x6, 0x2, wt, ws, wd, 0x14), + static_cast<FRegister>(wd), + static_cast<FRegister>(ws), + static_cast<FRegister>(wt)); +} + +void MipsAssembler::IlvevD(VectorRegister wd, VectorRegister ws, VectorRegister wt) { + CHECK(HasMsa()); + DsFsmInstrFff(EmitMsa3R(0x6, 0x3, wt, ws, wd, 0x14), + static_cast<FRegister>(wd), + static_cast<FRegister>(ws), + static_cast<FRegister>(wt)); +} + +void MipsAssembler::IlvodB(VectorRegister wd, VectorRegister ws, VectorRegister wt) { + CHECK(HasMsa()); + DsFsmInstrFff(EmitMsa3R(0x7, 0x0, wt, ws, wd, 0x14), + static_cast<FRegister>(wd), + static_cast<FRegister>(ws), + static_cast<FRegister>(wt)); +} + +void MipsAssembler::IlvodH(VectorRegister wd, VectorRegister ws, VectorRegister wt) { + CHECK(HasMsa()); + DsFsmInstrFff(EmitMsa3R(0x7, 0x1, wt, ws, wd, 0x14), + static_cast<FRegister>(wd), + static_cast<FRegister>(ws), + static_cast<FRegister>(wt)); +} + +void MipsAssembler::IlvodW(VectorRegister wd, VectorRegister ws, VectorRegister wt) { + CHECK(HasMsa()); + DsFsmInstrFff(EmitMsa3R(0x7, 0x2, wt, ws, wd, 0x14), + static_cast<FRegister>(wd), + static_cast<FRegister>(ws), + static_cast<FRegister>(wt)); +} + +void MipsAssembler::IlvodD(VectorRegister wd, VectorRegister ws, VectorRegister wt) { + CHECK(HasMsa()); + DsFsmInstrFff(EmitMsa3R(0x7, 0x3, wt, ws, wd, 0x14), + static_cast<FRegister>(wd), + static_cast<FRegister>(ws), + static_cast<FRegister>(wt)); +} + void MipsAssembler::MaddvB(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); DsFsmInstrFff(EmitMsa3R(0x1, 0x0, wt, ws, wd, 0x12), @@ -3049,6 +3213,54 @@ void MipsAssembler::FmsubD(VectorRegister wd, VectorRegister ws, VectorRegister static_cast<FRegister>(wt)); } +void MipsAssembler::Hadd_sH(VectorRegister wd, VectorRegister ws, VectorRegister wt) { + CHECK(HasMsa()); + DsFsmInstrFff(EmitMsa3R(0x4, 0x1, wt, ws, wd, 0x15), + static_cast<FRegister>(wd), + static_cast<FRegister>(ws), + static_cast<FRegister>(wt)); +} + +void MipsAssembler::Hadd_sW(VectorRegister wd, VectorRegister ws, VectorRegister wt) { + CHECK(HasMsa()); + DsFsmInstrFff(EmitMsa3R(0x4, 0x2, wt, ws, wd, 0x15), + static_cast<FRegister>(wd), + static_cast<FRegister>(ws), + static_cast<FRegister>(wt)); +} + +void MipsAssembler::Hadd_sD(VectorRegister wd, VectorRegister ws, VectorRegister wt) { + CHECK(HasMsa()); + DsFsmInstrFff(EmitMsa3R(0x4, 0x3, wt, ws, wd, 0x15), + static_cast<FRegister>(wd), + static_cast<FRegister>(ws), + static_cast<FRegister>(wt)); +} + +void MipsAssembler::Hadd_uH(VectorRegister wd, VectorRegister ws, VectorRegister wt) { + CHECK(HasMsa()); + DsFsmInstrFff(EmitMsa3R(0x5, 0x1, wt, ws, wd, 0x15), + static_cast<FRegister>(wd), + static_cast<FRegister>(ws), + static_cast<FRegister>(wt)); +} + +void MipsAssembler::Hadd_uW(VectorRegister wd, VectorRegister ws, VectorRegister wt) { + CHECK(HasMsa()); + DsFsmInstrFff(EmitMsa3R(0x5, 0x2, wt, ws, wd, 0x15), + static_cast<FRegister>(wd), + static_cast<FRegister>(ws), + static_cast<FRegister>(wt)); +} + +void MipsAssembler::Hadd_uD(VectorRegister wd, VectorRegister ws, VectorRegister wt) { + CHECK(HasMsa()); + DsFsmInstrFff(EmitMsa3R(0x5, 0x3, wt, ws, wd, 0x15), + static_cast<FRegister>(wd), + static_cast<FRegister>(ws), + static_cast<FRegister>(wt)); +} + void MipsAssembler::ReplicateFPToVectorRegister(VectorRegister dst, FRegister src, bool is_double) { diff --git a/compiler/utils/mips/assembler_mips.h b/compiler/utils/mips/assembler_mips.h index 1c5b442557..c0ea29fbd7 100644 --- a/compiler/utils/mips/assembler_mips.h +++ b/compiler/utils/mips/assembler_mips.h @@ -601,6 +601,14 @@ class MipsAssembler FINAL : public Assembler, public JNIMacroAssembler<PointerSi void SplatiH(VectorRegister wd, VectorRegister ws, int n3); void SplatiW(VectorRegister wd, VectorRegister ws, int n2); void SplatiD(VectorRegister wd, VectorRegister ws, int n1); + void Copy_sB(Register rd, VectorRegister ws, int n4); + void Copy_sH(Register rd, VectorRegister ws, int n3); + void Copy_sW(Register rd, VectorRegister ws, int n2); + void Copy_uB(Register rd, VectorRegister ws, int n4); + void Copy_uH(Register rd, VectorRegister ws, int n3); + void InsertB(VectorRegister wd, Register rs, int n4); + void InsertH(VectorRegister wd, Register rs, int n3); + void InsertW(VectorRegister wd, Register rs, int n2); void FillB(VectorRegister wd, Register rs); void FillH(VectorRegister wd, Register rs); void FillW(VectorRegister wd, Register rs); @@ -618,10 +626,22 @@ class MipsAssembler FINAL : public Assembler, public JNIMacroAssembler<PointerSi void StW(VectorRegister wd, Register rs, int offset); void StD(VectorRegister wd, Register rs, int offset); + void IlvlB(VectorRegister wd, VectorRegister ws, VectorRegister wt); + void IlvlH(VectorRegister wd, VectorRegister ws, VectorRegister wt); + void IlvlW(VectorRegister wd, VectorRegister ws, VectorRegister wt); + void IlvlD(VectorRegister wd, VectorRegister ws, VectorRegister wt); void IlvrB(VectorRegister wd, VectorRegister ws, VectorRegister wt); void IlvrH(VectorRegister wd, VectorRegister ws, VectorRegister wt); void IlvrW(VectorRegister wd, VectorRegister ws, VectorRegister wt); void IlvrD(VectorRegister wd, VectorRegister ws, VectorRegister wt); + void IlvevB(VectorRegister wd, VectorRegister ws, VectorRegister wt); + void IlvevH(VectorRegister wd, VectorRegister ws, VectorRegister wt); + void IlvevW(VectorRegister wd, VectorRegister ws, VectorRegister wt); + void IlvevD(VectorRegister wd, VectorRegister ws, VectorRegister wt); + void IlvodB(VectorRegister wd, VectorRegister ws, VectorRegister wt); + void IlvodH(VectorRegister wd, VectorRegister ws, VectorRegister wt); + void IlvodW(VectorRegister wd, VectorRegister ws, VectorRegister wt); + void IlvodD(VectorRegister wd, VectorRegister ws, VectorRegister wt); void MaddvB(VectorRegister wd, VectorRegister ws, VectorRegister wt); void MaddvH(VectorRegister wd, VectorRegister ws, VectorRegister wt); @@ -636,6 +656,13 @@ class MipsAssembler FINAL : public Assembler, public JNIMacroAssembler<PointerSi void FmsubW(VectorRegister wd, VectorRegister ws, VectorRegister wt); void FmsubD(VectorRegister wd, VectorRegister ws, VectorRegister wt); + void Hadd_sH(VectorRegister wd, VectorRegister ws, VectorRegister wt); + void Hadd_sW(VectorRegister wd, VectorRegister ws, VectorRegister wt); + void Hadd_sD(VectorRegister wd, VectorRegister ws, VectorRegister wt); + void Hadd_uH(VectorRegister wd, VectorRegister ws, VectorRegister wt); + void Hadd_uW(VectorRegister wd, VectorRegister ws, VectorRegister wt); + void Hadd_uD(VectorRegister wd, VectorRegister ws, VectorRegister wt); + // Helper for replicating floating point value in all destination elements. void ReplicateFPToVectorRegister(VectorRegister dst, FRegister src, bool is_double); diff --git a/compiler/utils/mips/assembler_mips32r6_test.cc b/compiler/utils/mips/assembler_mips32r6_test.cc index b12b6b651c..c76a568ddd 100644 --- a/compiler/utils/mips/assembler_mips32r6_test.cc +++ b/compiler/utils/mips/assembler_mips32r6_test.cc @@ -2185,6 +2185,46 @@ TEST_F(AssemblerMIPS32r6Test, SplatiD) { "splati.d"); } +TEST_F(AssemblerMIPS32r6Test, Copy_sB) { + DriverStr(RepeatRVIb(&mips::MipsAssembler::Copy_sB, 4, "copy_s.b ${reg1}, ${reg2}[{imm}]"), + "copy_s.b"); +} + +TEST_F(AssemblerMIPS32r6Test, Copy_sH) { + DriverStr(RepeatRVIb(&mips::MipsAssembler::Copy_sH, 3, "copy_s.h ${reg1}, ${reg2}[{imm}]"), + "copy_s.h"); +} + +TEST_F(AssemblerMIPS32r6Test, Copy_sW) { + DriverStr(RepeatRVIb(&mips::MipsAssembler::Copy_sW, 2, "copy_s.w ${reg1}, ${reg2}[{imm}]"), + "copy_s.w"); +} + +TEST_F(AssemblerMIPS32r6Test, Copy_uB) { + DriverStr(RepeatRVIb(&mips::MipsAssembler::Copy_uB, 4, "copy_u.b ${reg1}, ${reg2}[{imm}]"), + "copy_u.b"); +} + +TEST_F(AssemblerMIPS32r6Test, Copy_uH) { + DriverStr(RepeatRVIb(&mips::MipsAssembler::Copy_uH, 3, "copy_u.h ${reg1}, ${reg2}[{imm}]"), + "copy_u.h"); +} + +TEST_F(AssemblerMIPS32r6Test, InsertB) { + DriverStr(RepeatVRIb(&mips::MipsAssembler::InsertB, 4, "insert.b ${reg1}[{imm}], ${reg2}"), + "insert.b"); +} + +TEST_F(AssemblerMIPS32r6Test, InsertH) { + DriverStr(RepeatVRIb(&mips::MipsAssembler::InsertH, 3, "insert.h ${reg1}[{imm}], ${reg2}"), + "insert.h"); +} + +TEST_F(AssemblerMIPS32r6Test, InsertW) { + DriverStr(RepeatVRIb(&mips::MipsAssembler::InsertW, 2, "insert.w ${reg1}[{imm}], ${reg2}"), + "insert.w"); +} + TEST_F(AssemblerMIPS32r6Test, FillB) { DriverStr(RepeatVR(&mips::MipsAssembler::FillB, "fill.b ${reg1}, ${reg2}"), "fill.b"); } @@ -2251,6 +2291,22 @@ TEST_F(AssemblerMIPS32r6Test, StD) { "st.d"); } +TEST_F(AssemblerMIPS32r6Test, IlvlB) { + DriverStr(RepeatVVV(&mips::MipsAssembler::IlvlB, "ilvl.b ${reg1}, ${reg2}, ${reg3}"), "ilvl.b"); +} + +TEST_F(AssemblerMIPS32r6Test, IlvlH) { + DriverStr(RepeatVVV(&mips::MipsAssembler::IlvlH, "ilvl.h ${reg1}, ${reg2}, ${reg3}"), "ilvl.h"); +} + +TEST_F(AssemblerMIPS32r6Test, IlvlW) { + DriverStr(RepeatVVV(&mips::MipsAssembler::IlvlW, "ilvl.w ${reg1}, ${reg2}, ${reg3}"), "ilvl.w"); +} + +TEST_F(AssemblerMIPS32r6Test, IlvlD) { + DriverStr(RepeatVVV(&mips::MipsAssembler::IlvlD, "ilvl.d ${reg1}, ${reg2}, ${reg3}"), "ilvl.d"); +} + TEST_F(AssemblerMIPS32r6Test, IlvrB) { DriverStr(RepeatVVV(&mips::MipsAssembler::IlvrB, "ilvr.b ${reg1}, ${reg2}, ${reg3}"), "ilvr.b"); } @@ -2267,6 +2323,46 @@ TEST_F(AssemblerMIPS32r6Test, IlvrD) { DriverStr(RepeatVVV(&mips::MipsAssembler::IlvrD, "ilvr.d ${reg1}, ${reg2}, ${reg3}"), "ilvr.d"); } +TEST_F(AssemblerMIPS32r6Test, IlvevB) { + DriverStr(RepeatVVV(&mips::MipsAssembler::IlvevB, "ilvev.b ${reg1}, ${reg2}, ${reg3}"), + "ilvev.b"); +} + +TEST_F(AssemblerMIPS32r6Test, IlvevH) { + DriverStr(RepeatVVV(&mips::MipsAssembler::IlvevH, "ilvev.h ${reg1}, ${reg2}, ${reg3}"), + "ilvev.h"); +} + +TEST_F(AssemblerMIPS32r6Test, IlvevW) { + DriverStr(RepeatVVV(&mips::MipsAssembler::IlvevW, "ilvev.w ${reg1}, ${reg2}, ${reg3}"), + "ilvev.w"); +} + +TEST_F(AssemblerMIPS32r6Test, IlvevD) { + DriverStr(RepeatVVV(&mips::MipsAssembler::IlvevD, "ilvev.d ${reg1}, ${reg2}, ${reg3}"), + "ilvev.d"); +} + +TEST_F(AssemblerMIPS32r6Test, IlvodB) { + DriverStr(RepeatVVV(&mips::MipsAssembler::IlvodB, "ilvod.b ${reg1}, ${reg2}, ${reg3}"), + "ilvod.b"); +} + +TEST_F(AssemblerMIPS32r6Test, IlvodH) { + DriverStr(RepeatVVV(&mips::MipsAssembler::IlvodH, "ilvod.h ${reg1}, ${reg2}, ${reg3}"), + "ilvod.h"); +} + +TEST_F(AssemblerMIPS32r6Test, IlvodW) { + DriverStr(RepeatVVV(&mips::MipsAssembler::IlvodW, "ilvod.w ${reg1}, ${reg2}, ${reg3}"), + "ilvod.w"); +} + +TEST_F(AssemblerMIPS32r6Test, IlvodD) { + DriverStr(RepeatVVV(&mips::MipsAssembler::IlvodD, "ilvod.d ${reg1}, ${reg2}, ${reg3}"), + "ilvod.d"); +} + TEST_F(AssemblerMIPS32r6Test, MaddvB) { DriverStr(RepeatVVV(&mips::MipsAssembler::MaddvB, "maddv.b ${reg1}, ${reg2}, ${reg3}"), "maddv.b"); @@ -2287,6 +2383,36 @@ TEST_F(AssemblerMIPS32r6Test, MaddvD) { "maddv.d"); } +TEST_F(AssemblerMIPS32r6Test, Hadd_sH) { + DriverStr(RepeatVVV(&mips::MipsAssembler::Hadd_sH, "hadd_s.h ${reg1}, ${reg2}, ${reg3}"), + "hadd_s.h"); +} + +TEST_F(AssemblerMIPS32r6Test, Hadd_sW) { + DriverStr(RepeatVVV(&mips::MipsAssembler::Hadd_sW, "hadd_s.w ${reg1}, ${reg2}, ${reg3}"), + "hadd_s.w"); +} + +TEST_F(AssemblerMIPS32r6Test, Hadd_sD) { + DriverStr(RepeatVVV(&mips::MipsAssembler::Hadd_sD, "hadd_s.d ${reg1}, ${reg2}, ${reg3}"), + "hadd_s.d"); +} + +TEST_F(AssemblerMIPS32r6Test, Hadd_uH) { + DriverStr(RepeatVVV(&mips::MipsAssembler::Hadd_uH, "hadd_u.h ${reg1}, ${reg2}, ${reg3}"), + "hadd_u.h"); +} + +TEST_F(AssemblerMIPS32r6Test, Hadd_uW) { + DriverStr(RepeatVVV(&mips::MipsAssembler::Hadd_uW, "hadd_u.w ${reg1}, ${reg2}, ${reg3}"), + "hadd_u.w"); +} + +TEST_F(AssemblerMIPS32r6Test, Hadd_uD) { + DriverStr(RepeatVVV(&mips::MipsAssembler::Hadd_uD, "hadd_u.d ${reg1}, ${reg2}, ${reg3}"), + "hadd_u.d"); +} + TEST_F(AssemblerMIPS32r6Test, MsubvB) { DriverStr(RepeatVVV(&mips::MipsAssembler::MsubvB, "msubv.b ${reg1}, ${reg2}, ${reg3}"), "msubv.b"); diff --git a/compiler/utils/mips64/assembler_mips64.cc b/compiler/utils/mips64/assembler_mips64.cc index 606d4c39d0..d8a4531ac2 100644 --- a/compiler/utils/mips64/assembler_mips64.cc +++ b/compiler/utils/mips64/assembler_mips64.cc @@ -1874,6 +1874,72 @@ void Mips64Assembler::SplatiD(VectorRegister wd, VectorRegister ws, int n1) { EmitMsaELM(0x1, n1 | kMsaDfNDoublewordMask, ws, wd, 0x19); } +void Mips64Assembler::Copy_sB(GpuRegister rd, VectorRegister ws, int n4) { + CHECK(HasMsa()); + CHECK(IsUint<4>(n4)) << n4; + EmitMsaELM(0x2, n4 | kMsaDfNByteMask, ws, static_cast<VectorRegister>(rd), 0x19); +} + +void Mips64Assembler::Copy_sH(GpuRegister rd, VectorRegister ws, int n3) { + CHECK(HasMsa()); + CHECK(IsUint<3>(n3)) << n3; + EmitMsaELM(0x2, n3 | kMsaDfNHalfwordMask, ws, static_cast<VectorRegister>(rd), 0x19); +} + +void Mips64Assembler::Copy_sW(GpuRegister rd, VectorRegister ws, int n2) { + CHECK(HasMsa()); + CHECK(IsUint<2>(n2)) << n2; + EmitMsaELM(0x2, n2 | kMsaDfNWordMask, ws, static_cast<VectorRegister>(rd), 0x19); +} + +void Mips64Assembler::Copy_sD(GpuRegister rd, VectorRegister ws, int n1) { + CHECK(HasMsa()); + CHECK(IsUint<1>(n1)) << n1; + EmitMsaELM(0x2, n1 | kMsaDfNDoublewordMask, ws, static_cast<VectorRegister>(rd), 0x19); +} + +void Mips64Assembler::Copy_uB(GpuRegister rd, VectorRegister ws, int n4) { + CHECK(HasMsa()); + CHECK(IsUint<4>(n4)) << n4; + EmitMsaELM(0x3, n4 | kMsaDfNByteMask, ws, static_cast<VectorRegister>(rd), 0x19); +} + +void Mips64Assembler::Copy_uH(GpuRegister rd, VectorRegister ws, int n3) { + CHECK(HasMsa()); + CHECK(IsUint<3>(n3)) << n3; + EmitMsaELM(0x3, n3 | kMsaDfNHalfwordMask, ws, static_cast<VectorRegister>(rd), 0x19); +} + +void Mips64Assembler::Copy_uW(GpuRegister rd, VectorRegister ws, int n2) { + CHECK(HasMsa()); + CHECK(IsUint<2>(n2)) << n2; + EmitMsaELM(0x3, n2 | kMsaDfNWordMask, ws, static_cast<VectorRegister>(rd), 0x19); +} + +void Mips64Assembler::InsertB(VectorRegister wd, GpuRegister rs, int n4) { + CHECK(HasMsa()); + CHECK(IsUint<4>(n4)) << n4; + EmitMsaELM(0x4, n4 | kMsaDfNByteMask, static_cast<VectorRegister>(rs), wd, 0x19); +} + +void Mips64Assembler::InsertH(VectorRegister wd, GpuRegister rs, int n3) { + CHECK(HasMsa()); + CHECK(IsUint<3>(n3)) << n3; + EmitMsaELM(0x4, n3 | kMsaDfNHalfwordMask, static_cast<VectorRegister>(rs), wd, 0x19); +} + +void Mips64Assembler::InsertW(VectorRegister wd, GpuRegister rs, int n2) { + CHECK(HasMsa()); + CHECK(IsUint<2>(n2)) << n2; + EmitMsaELM(0x4, n2 | kMsaDfNWordMask, static_cast<VectorRegister>(rs), wd, 0x19); +} + +void Mips64Assembler::InsertD(VectorRegister wd, GpuRegister rs, int n1) { + CHECK(HasMsa()); + CHECK(IsUint<1>(n1)) << n1; + EmitMsaELM(0x4, n1 | kMsaDfNDoublewordMask, static_cast<VectorRegister>(rs), wd, 0x19); +} + void Mips64Assembler::FillB(VectorRegister wd, GpuRegister rs) { CHECK(HasMsa()); EmitMsa2R(0xc0, 0x0, static_cast<VectorRegister>(rs), wd, 0x1e); @@ -1972,6 +2038,26 @@ void Mips64Assembler::StD(VectorRegister wd, GpuRegister rs, int offset) { EmitMsaMI10((offset >> TIMES_8) & kMsaS10Mask, rs, wd, 0x9, 0x3); } +void Mips64Assembler::IlvlB(VectorRegister wd, VectorRegister ws, VectorRegister wt) { + CHECK(HasMsa()); + EmitMsa3R(0x4, 0x0, wt, ws, wd, 0x14); +} + +void Mips64Assembler::IlvlH(VectorRegister wd, VectorRegister ws, VectorRegister wt) { + CHECK(HasMsa()); + EmitMsa3R(0x4, 0x1, wt, ws, wd, 0x14); +} + +void Mips64Assembler::IlvlW(VectorRegister wd, VectorRegister ws, VectorRegister wt) { + CHECK(HasMsa()); + EmitMsa3R(0x4, 0x2, wt, ws, wd, 0x14); +} + +void Mips64Assembler::IlvlD(VectorRegister wd, VectorRegister ws, VectorRegister wt) { + CHECK(HasMsa()); + EmitMsa3R(0x4, 0x3, wt, ws, wd, 0x14); +} + void Mips64Assembler::IlvrB(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); EmitMsa3R(0x5, 0x0, wt, ws, wd, 0x14); @@ -1992,6 +2078,46 @@ void Mips64Assembler::IlvrD(VectorRegister wd, VectorRegister ws, VectorRegister EmitMsa3R(0x5, 0x3, wt, ws, wd, 0x14); } +void Mips64Assembler::IlvevB(VectorRegister wd, VectorRegister ws, VectorRegister wt) { + CHECK(HasMsa()); + EmitMsa3R(0x6, 0x0, wt, ws, wd, 0x14); +} + +void Mips64Assembler::IlvevH(VectorRegister wd, VectorRegister ws, VectorRegister wt) { + CHECK(HasMsa()); + EmitMsa3R(0x6, 0x1, wt, ws, wd, 0x14); +} + +void Mips64Assembler::IlvevW(VectorRegister wd, VectorRegister ws, VectorRegister wt) { + CHECK(HasMsa()); + EmitMsa3R(0x6, 0x2, wt, ws, wd, 0x14); +} + +void Mips64Assembler::IlvevD(VectorRegister wd, VectorRegister ws, VectorRegister wt) { + CHECK(HasMsa()); + EmitMsa3R(0x6, 0x3, wt, ws, wd, 0x14); +} + +void Mips64Assembler::IlvodB(VectorRegister wd, VectorRegister ws, VectorRegister wt) { + CHECK(HasMsa()); + EmitMsa3R(0x7, 0x0, wt, ws, wd, 0x14); +} + +void Mips64Assembler::IlvodH(VectorRegister wd, VectorRegister ws, VectorRegister wt) { + CHECK(HasMsa()); + EmitMsa3R(0x7, 0x1, wt, ws, wd, 0x14); +} + +void Mips64Assembler::IlvodW(VectorRegister wd, VectorRegister ws, VectorRegister wt) { + CHECK(HasMsa()); + EmitMsa3R(0x7, 0x2, wt, ws, wd, 0x14); +} + +void Mips64Assembler::IlvodD(VectorRegister wd, VectorRegister ws, VectorRegister wt) { + CHECK(HasMsa()); + EmitMsa3R(0x7, 0x3, wt, ws, wd, 0x14); +} + void Mips64Assembler::MaddvB(VectorRegister wd, VectorRegister ws, VectorRegister wt) { CHECK(HasMsa()); EmitMsa3R(0x1, 0x0, wt, ws, wd, 0x12); @@ -2052,6 +2178,36 @@ void Mips64Assembler::FmsubD(VectorRegister wd, VectorRegister ws, VectorRegiste EmitMsa3R(0x2, 0x3, wt, ws, wd, 0x1b); } +void Mips64Assembler::Hadd_sH(VectorRegister wd, VectorRegister ws, VectorRegister wt) { + CHECK(HasMsa()); + EmitMsa3R(0x4, 0x1, wt, ws, wd, 0x15); +} + +void Mips64Assembler::Hadd_sW(VectorRegister wd, VectorRegister ws, VectorRegister wt) { + CHECK(HasMsa()); + EmitMsa3R(0x4, 0x2, wt, ws, wd, 0x15); +} + +void Mips64Assembler::Hadd_sD(VectorRegister wd, VectorRegister ws, VectorRegister wt) { + CHECK(HasMsa()); + EmitMsa3R(0x4, 0x3, wt, ws, wd, 0x15); +} + +void Mips64Assembler::Hadd_uH(VectorRegister wd, VectorRegister ws, VectorRegister wt) { + CHECK(HasMsa()); + EmitMsa3R(0x5, 0x1, wt, ws, wd, 0x15); +} + +void Mips64Assembler::Hadd_uW(VectorRegister wd, VectorRegister ws, VectorRegister wt) { + CHECK(HasMsa()); + EmitMsa3R(0x5, 0x2, wt, ws, wd, 0x15); +} + +void Mips64Assembler::Hadd_uD(VectorRegister wd, VectorRegister ws, VectorRegister wt) { + CHECK(HasMsa()); + EmitMsa3R(0x5, 0x3, wt, ws, wd, 0x15); +} + void Mips64Assembler::ReplicateFPToVectorRegister(VectorRegister dst, FpuRegister src, bool is_double) { diff --git a/compiler/utils/mips64/assembler_mips64.h b/compiler/utils/mips64/assembler_mips64.h index a3787ac6ae..d67fb0054d 100644 --- a/compiler/utils/mips64/assembler_mips64.h +++ b/compiler/utils/mips64/assembler_mips64.h @@ -785,6 +785,17 @@ class Mips64Assembler FINAL : public Assembler, public JNIMacroAssembler<Pointer void SplatiH(VectorRegister wd, VectorRegister ws, int n3); void SplatiW(VectorRegister wd, VectorRegister ws, int n2); void SplatiD(VectorRegister wd, VectorRegister ws, int n1); + void Copy_sB(GpuRegister rd, VectorRegister ws, int n4); + void Copy_sH(GpuRegister rd, VectorRegister ws, int n3); + void Copy_sW(GpuRegister rd, VectorRegister ws, int n2); + void Copy_sD(GpuRegister rd, VectorRegister ws, int n1); + void Copy_uB(GpuRegister rd, VectorRegister ws, int n4); + void Copy_uH(GpuRegister rd, VectorRegister ws, int n3); + void Copy_uW(GpuRegister rd, VectorRegister ws, int n2); + void InsertB(VectorRegister wd, GpuRegister rs, int n4); + void InsertH(VectorRegister wd, GpuRegister rs, int n3); + void InsertW(VectorRegister wd, GpuRegister rs, int n2); + void InsertD(VectorRegister wd, GpuRegister rs, int n1); void FillB(VectorRegister wd, GpuRegister rs); void FillH(VectorRegister wd, GpuRegister rs); void FillW(VectorRegister wd, GpuRegister rs); @@ -803,10 +814,22 @@ class Mips64Assembler FINAL : public Assembler, public JNIMacroAssembler<Pointer void StW(VectorRegister wd, GpuRegister rs, int offset); void StD(VectorRegister wd, GpuRegister rs, int offset); + void IlvlB(VectorRegister wd, VectorRegister ws, VectorRegister wt); + void IlvlH(VectorRegister wd, VectorRegister ws, VectorRegister wt); + void IlvlW(VectorRegister wd, VectorRegister ws, VectorRegister wt); + void IlvlD(VectorRegister wd, VectorRegister ws, VectorRegister wt); void IlvrB(VectorRegister wd, VectorRegister ws, VectorRegister wt); void IlvrH(VectorRegister wd, VectorRegister ws, VectorRegister wt); void IlvrW(VectorRegister wd, VectorRegister ws, VectorRegister wt); void IlvrD(VectorRegister wd, VectorRegister ws, VectorRegister wt); + void IlvevB(VectorRegister wd, VectorRegister ws, VectorRegister wt); + void IlvevH(VectorRegister wd, VectorRegister ws, VectorRegister wt); + void IlvevW(VectorRegister wd, VectorRegister ws, VectorRegister wt); + void IlvevD(VectorRegister wd, VectorRegister ws, VectorRegister wt); + void IlvodB(VectorRegister wd, VectorRegister ws, VectorRegister wt); + void IlvodH(VectorRegister wd, VectorRegister ws, VectorRegister wt); + void IlvodW(VectorRegister wd, VectorRegister ws, VectorRegister wt); + void IlvodD(VectorRegister wd, VectorRegister ws, VectorRegister wt); void MaddvB(VectorRegister wd, VectorRegister ws, VectorRegister wt); void MaddvH(VectorRegister wd, VectorRegister ws, VectorRegister wt); @@ -821,6 +844,13 @@ class Mips64Assembler FINAL : public Assembler, public JNIMacroAssembler<Pointer void FmsubW(VectorRegister wd, VectorRegister ws, VectorRegister wt); void FmsubD(VectorRegister wd, VectorRegister ws, VectorRegister wt); + void Hadd_sH(VectorRegister wd, VectorRegister ws, VectorRegister wt); + void Hadd_sW(VectorRegister wd, VectorRegister ws, VectorRegister wt); + void Hadd_sD(VectorRegister wd, VectorRegister ws, VectorRegister wt); + void Hadd_uH(VectorRegister wd, VectorRegister ws, VectorRegister wt); + void Hadd_uW(VectorRegister wd, VectorRegister ws, VectorRegister wt); + void Hadd_uD(VectorRegister wd, VectorRegister ws, VectorRegister wt); + // Helper for replicating floating point value in all destination elements. void ReplicateFPToVectorRegister(VectorRegister dst, FpuRegister src, bool is_double); diff --git a/compiler/utils/mips64/assembler_mips64_test.cc b/compiler/utils/mips64/assembler_mips64_test.cc index bf0326de87..164af7891c 100644 --- a/compiler/utils/mips64/assembler_mips64_test.cc +++ b/compiler/utils/mips64/assembler_mips64_test.cc @@ -3399,6 +3399,61 @@ TEST_F(AssemblerMIPS64Test, SplatiD) { "splati.d"); } +TEST_F(AssemblerMIPS64Test, Copy_sB) { + DriverStr(RepeatRVIb(&mips64::Mips64Assembler::Copy_sB, 4, "copy_s.b ${reg1}, ${reg2}[{imm}]"), + "copy_s.b"); +} + +TEST_F(AssemblerMIPS64Test, Copy_sH) { + DriverStr(RepeatRVIb(&mips64::Mips64Assembler::Copy_sH, 3, "copy_s.h ${reg1}, ${reg2}[{imm}]"), + "copy_s.h"); +} + +TEST_F(AssemblerMIPS64Test, Copy_sW) { + DriverStr(RepeatRVIb(&mips64::Mips64Assembler::Copy_sW, 2, "copy_s.w ${reg1}, ${reg2}[{imm}]"), + "copy_s.w"); +} + +TEST_F(AssemblerMIPS64Test, Copy_sD) { + DriverStr(RepeatRVIb(&mips64::Mips64Assembler::Copy_sD, 1, "copy_s.d ${reg1}, ${reg2}[{imm}]"), + "copy_s.d"); +} + +TEST_F(AssemblerMIPS64Test, Copy_uB) { + DriverStr(RepeatRVIb(&mips64::Mips64Assembler::Copy_uB, 4, "copy_u.b ${reg1}, ${reg2}[{imm}]"), + "copy_u.b"); +} + +TEST_F(AssemblerMIPS64Test, Copy_uH) { + DriverStr(RepeatRVIb(&mips64::Mips64Assembler::Copy_uH, 3, "copy_u.h ${reg1}, ${reg2}[{imm}]"), + "copy_u.h"); +} + +TEST_F(AssemblerMIPS64Test, Copy_uW) { + DriverStr(RepeatRVIb(&mips64::Mips64Assembler::Copy_uW, 2, "copy_u.w ${reg1}, ${reg2}[{imm}]"), + "copy_u.w"); +} + +TEST_F(AssemblerMIPS64Test, InsertB) { + DriverStr(RepeatVRIb(&mips64::Mips64Assembler::InsertB, 4, "insert.b ${reg1}[{imm}], ${reg2}"), + "insert.b"); +} + +TEST_F(AssemblerMIPS64Test, InsertH) { + DriverStr(RepeatVRIb(&mips64::Mips64Assembler::InsertH, 3, "insert.h ${reg1}[{imm}], ${reg2}"), + "insert.h"); +} + +TEST_F(AssemblerMIPS64Test, InsertW) { + DriverStr(RepeatVRIb(&mips64::Mips64Assembler::InsertW, 2, "insert.w ${reg1}[{imm}], ${reg2}"), + "insert.w"); +} + +TEST_F(AssemblerMIPS64Test, InsertD) { + DriverStr(RepeatVRIb(&mips64::Mips64Assembler::InsertD, 1, "insert.d ${reg1}[{imm}], ${reg2}"), + "insert.d"); +} + TEST_F(AssemblerMIPS64Test, FillB) { DriverStr(RepeatVR(&mips64::Mips64Assembler::FillB, "fill.b ${reg1}, ${reg2}"), "fill.b"); } @@ -3469,6 +3524,26 @@ TEST_F(AssemblerMIPS64Test, StD) { "st.d"); } +TEST_F(AssemblerMIPS64Test, IlvlB) { + DriverStr(RepeatVVV(&mips64::Mips64Assembler::IlvlB, "ilvl.b ${reg1}, ${reg2}, ${reg3}"), + "ilvl.b"); +} + +TEST_F(AssemblerMIPS64Test, IlvlH) { + DriverStr(RepeatVVV(&mips64::Mips64Assembler::IlvlH, "ilvl.h ${reg1}, ${reg2}, ${reg3}"), + "ilvl.h"); +} + +TEST_F(AssemblerMIPS64Test, IlvlW) { + DriverStr(RepeatVVV(&mips64::Mips64Assembler::IlvlW, "ilvl.w ${reg1}, ${reg2}, ${reg3}"), + "ilvl.w"); +} + +TEST_F(AssemblerMIPS64Test, IlvlD) { + DriverStr(RepeatVVV(&mips64::Mips64Assembler::IlvlD, "ilvl.d ${reg1}, ${reg2}, ${reg3}"), + "ilvl.d"); +} + TEST_F(AssemblerMIPS64Test, IlvrB) { DriverStr(RepeatVVV(&mips64::Mips64Assembler::IlvrB, "ilvr.b ${reg1}, ${reg2}, ${reg3}"), "ilvr.b"); @@ -3489,6 +3564,46 @@ TEST_F(AssemblerMIPS64Test, IlvrD) { "ilvr.d"); } +TEST_F(AssemblerMIPS64Test, IlvevB) { + DriverStr(RepeatVVV(&mips64::Mips64Assembler::IlvevB, "ilvev.b ${reg1}, ${reg2}, ${reg3}"), + "ilvev.b"); +} + +TEST_F(AssemblerMIPS64Test, IlvevH) { + DriverStr(RepeatVVV(&mips64::Mips64Assembler::IlvevH, "ilvev.h ${reg1}, ${reg2}, ${reg3}"), + "ilvev.h"); +} + +TEST_F(AssemblerMIPS64Test, IlvevW) { + DriverStr(RepeatVVV(&mips64::Mips64Assembler::IlvevW, "ilvev.w ${reg1}, ${reg2}, ${reg3}"), + "ilvev.w"); +} + +TEST_F(AssemblerMIPS64Test, IlvevD) { + DriverStr(RepeatVVV(&mips64::Mips64Assembler::IlvevD, "ilvev.d ${reg1}, ${reg2}, ${reg3}"), + "ilvev.d"); +} + +TEST_F(AssemblerMIPS64Test, IlvodB) { + DriverStr(RepeatVVV(&mips64::Mips64Assembler::IlvodB, "ilvod.b ${reg1}, ${reg2}, ${reg3}"), + "ilvod.b"); +} + +TEST_F(AssemblerMIPS64Test, IlvodH) { + DriverStr(RepeatVVV(&mips64::Mips64Assembler::IlvodH, "ilvod.h ${reg1}, ${reg2}, ${reg3}"), + "ilvod.h"); +} + +TEST_F(AssemblerMIPS64Test, IlvodW) { + DriverStr(RepeatVVV(&mips64::Mips64Assembler::IlvodW, "ilvod.w ${reg1}, ${reg2}, ${reg3}"), + "ilvod.w"); +} + +TEST_F(AssemblerMIPS64Test, IlvodD) { + DriverStr(RepeatVVV(&mips64::Mips64Assembler::IlvodD, "ilvod.d ${reg1}, ${reg2}, ${reg3}"), + "ilvod.d"); +} + TEST_F(AssemblerMIPS64Test, MaddvB) { DriverStr(RepeatVVV(&mips64::Mips64Assembler::MaddvB, "maddv.b ${reg1}, ${reg2}, ${reg3}"), "maddv.b"); @@ -3509,6 +3624,36 @@ TEST_F(AssemblerMIPS64Test, MaddvD) { "maddv.d"); } +TEST_F(AssemblerMIPS64Test, Hadd_sH) { + DriverStr(RepeatVVV(&mips64::Mips64Assembler::Hadd_sH, "hadd_s.h ${reg1}, ${reg2}, ${reg3}"), + "hadd_s.h"); +} + +TEST_F(AssemblerMIPS64Test, Hadd_sW) { + DriverStr(RepeatVVV(&mips64::Mips64Assembler::Hadd_sW, "hadd_s.w ${reg1}, ${reg2}, ${reg3}"), + "hadd_s.w"); +} + +TEST_F(AssemblerMIPS64Test, Hadd_sD) { + DriverStr(RepeatVVV(&mips64::Mips64Assembler::Hadd_sD, "hadd_s.d ${reg1}, ${reg2}, ${reg3}"), + "hadd_s.d"); +} + +TEST_F(AssemblerMIPS64Test, Hadd_uH) { + DriverStr(RepeatVVV(&mips64::Mips64Assembler::Hadd_uH, "hadd_u.h ${reg1}, ${reg2}, ${reg3}"), + "hadd_u.h"); +} + +TEST_F(AssemblerMIPS64Test, Hadd_uW) { + DriverStr(RepeatVVV(&mips64::Mips64Assembler::Hadd_uW, "hadd_u.w ${reg1}, ${reg2}, ${reg3}"), + "hadd_u.w"); +} + +TEST_F(AssemblerMIPS64Test, Hadd_uD) { + DriverStr(RepeatVVV(&mips64::Mips64Assembler::Hadd_uD, "hadd_u.d ${reg1}, ${reg2}, ${reg3}"), + "hadd_u.d"); +} + TEST_F(AssemblerMIPS64Test, MsubvB) { DriverStr(RepeatVVV(&mips64::Mips64Assembler::MsubvB, "msubv.b ${reg1}, ${reg2}, ${reg3}"), "msubv.b"); diff --git a/disassembler/disassembler_mips.cc b/disassembler/disassembler_mips.cc index 938ea5dc2f..7c6a3251f7 100644 --- a/disassembler/disassembler_mips.cc +++ b/disassembler/disassembler_mips.cc @@ -479,15 +479,23 @@ static const MipsInstruction gMipsInstructions[] = { { kMsaMask | (0x7 << 23), kMsa | (0x2 << 23) | 0x9, "srli", "kmW" }, { kMsaMask | (0x3ff << 16), kMsa | (0xbe << 16) | 0x19, "move.v", "km" }, { kMsaMask | (0xf << 22), kMsa | (0x1 << 22) | 0x19, "splati", "kX" }, + { kMsaMask | (0xf << 22), kMsa | (0x2 << 22) | 0x19, "copy_s", "yX" }, + { kMsaMask | (0xf << 22), kMsa | (0x3 << 22) | 0x19, "copy_u", "yX" }, + { kMsaMask | (0xf << 22), kMsa | (0x4 << 22) | 0x19, "insert", "YD" }, { kMsaMask | (0xff << 18), kMsa | (0xc0 << 18) | 0x1e, "fill", "vkD" }, { kMsaMask | (0x7 << 23), kMsa | (0x6 << 23) | 0x7, "ldi", "kx" }, { kMsaSpecialMask | (0xf << 2), kMsa | (0x8 << 2), "ld", "kw" }, { kMsaSpecialMask | (0xf << 2), kMsa | (0x9 << 2), "st", "kw" }, + { kMsaMask | (0x7 << 23), kMsa | (0x4 << 23) | 0x14, "ilvl", "Vkmn" }, { kMsaMask | (0x7 << 23), kMsa | (0x5 << 23) | 0x14, "ilvr", "Vkmn" }, + { kMsaMask | (0x7 << 23), kMsa | (0x6 << 23) | 0x14, "ilvev", "Vkmn" }, + { kMsaMask | (0x7 << 23), kMsa | (0x7 << 23) | 0x14, "ilvod", "Vkmn" }, { kMsaMask | (0x7 << 23), kMsa | (0x1 << 23) | 0x12, "maddv", "Vkmn" }, { kMsaMask | (0x7 << 23), kMsa | (0x2 << 23) | 0x12, "msubv", "Vkmn" }, { kMsaMask | (0xf << 22), kMsa | (0x4 << 22) | 0x1b, "fmadd", "Ukmn" }, { kMsaMask | (0xf << 22), kMsa | (0x5 << 22) | 0x1b, "fmsub", "Ukmn" }, + { kMsaMask | (0x7 << 23), kMsa | (0x4 << 23) | 0x15, "hadd_s", "Vkmn" }, + { kMsaMask | (0x7 << 23), kMsa | (0x5 << 23) | 0x15, "hadd_u", "Vkmn" }, }; static uint32_t ReadU32(const uint8_t* ptr) { @@ -760,6 +768,31 @@ size_t DisassemblerMips::Dump(std::ostream& os, const uint8_t* instr_ptr) { args << i10; break; } + case 'Y': // MSA df/n - wd[x]. + { + int32_t df_n = (instruction >> 16) & 0x3f; + if ((df_n & (0x3 << 4)) == 0) { + opcode += ".b"; + args << 'w' << sa << '[' << (df_n & 0xf) << ']'; + break; + } + if ((df_n & (0x3 << 3)) == 0) { + opcode += ".h"; + args << 'w' << sa << '[' << (df_n & 0x7) << ']'; + break; + } + if ((df_n & (0x3 << 2)) == 0) { + opcode += ".w"; + args << 'w' << sa << '[' << (df_n & 0x3) << ']'; + break; + } + if ((df_n & (0x3 << 1)) == 0) { + opcode += ".d"; + args << 'w' << sa << '[' << (df_n & 0x1) << ']'; + } + break; + } + case 'y': args << RegName(sa); break; } if (*(args_fmt + 1)) { args << ", "; |