diff options
-rw-r--r-- | compiler/optimizing/code_generator_mips.cc | 8 | ||||
-rw-r--r-- | compiler/optimizing/code_generator_mips64.cc | 19 | ||||
-rw-r--r-- | compiler/utils/mips64/assembler_mips64.cc | 31 | ||||
-rw-r--r-- | compiler/utils/mips64/assembler_mips64.h | 4 | ||||
-rw-r--r-- | compiler/utils/mips64/assembler_mips64_test.cc | 31 | ||||
-rw-r--r-- | disassembler/disassembler_mips.cc | 5 |
6 files changed, 73 insertions, 25 deletions
diff --git a/compiler/optimizing/code_generator_mips.cc b/compiler/optimizing/code_generator_mips.cc index 9f4c2349e7..c4772ad79f 100644 --- a/compiler/optimizing/code_generator_mips.cc +++ b/compiler/optimizing/code_generator_mips.cc @@ -3774,8 +3774,12 @@ void InstructionCodeGeneratorMIPS::DivRemByPowerOfTwo(HBinaryOperation* instruct if (IsUint<16>(abs_imm - 1)) { __ Andi(out, out, abs_imm - 1); } else { - __ Sll(out, out, 32 - ctz_imm); - __ Srl(out, out, 32 - ctz_imm); + if (codegen_->GetInstructionSetFeatures().IsMipsIsaRevGreaterThanEqual2()) { + __ Ins(out, ZERO, ctz_imm, 32 - ctz_imm); + } else { + __ Sll(out, out, 32 - ctz_imm); + __ Srl(out, out, 32 - ctz_imm); + } } __ Subu(out, out, TMP); } diff --git a/compiler/optimizing/code_generator_mips64.cc b/compiler/optimizing/code_generator_mips64.cc index eb64f1be23..c8891eddfc 100644 --- a/compiler/optimizing/code_generator_mips64.cc +++ b/compiler/optimizing/code_generator_mips64.cc @@ -3311,12 +3311,7 @@ void InstructionCodeGeneratorMIPS64::DivRemByPowerOfTwo(HBinaryOperation* instru __ Sra(TMP, dividend, 31); __ Srl(TMP, TMP, 32 - ctz_imm); __ Addu(out, dividend, TMP); - if (IsUint<16>(abs_imm - 1)) { - __ Andi(out, out, abs_imm - 1); - } else { - __ Sll(out, out, 32 - ctz_imm); - __ Srl(out, out, 32 - ctz_imm); - } + __ Ins(out, ZERO, ctz_imm, 32 - ctz_imm); __ Subu(out, out, TMP); } } else { @@ -3335,17 +3330,7 @@ void InstructionCodeGeneratorMIPS64::DivRemByPowerOfTwo(HBinaryOperation* instru __ Dsrl32(TMP, TMP, 32 - ctz_imm); } __ Daddu(out, dividend, TMP); - if (IsUint<16>(abs_imm - 1)) { - __ Andi(out, out, abs_imm - 1); - } else { - if (ctz_imm > 32) { - __ Dsll(out, out, 64 - ctz_imm); - __ Dsrl(out, out, 64 - ctz_imm); - } else { - __ Dsll32(out, out, 32 - ctz_imm); - __ Dsrl32(out, out, 32 - ctz_imm); - } - } + __ DblIns(out, ZERO, ctz_imm, 64 - ctz_imm); __ Dsubu(out, out, TMP); } } diff --git a/compiler/utils/mips64/assembler_mips64.cc b/compiler/utils/mips64/assembler_mips64.cc index bf56877499..e1b0e75108 100644 --- a/compiler/utils/mips64/assembler_mips64.cc +++ b/compiler/utils/mips64/assembler_mips64.cc @@ -430,6 +430,20 @@ void Mips64Assembler::Dext(GpuRegister rt, GpuRegister rs, int pos, int size) { EmitR(0x1f, rs, rt, static_cast<GpuRegister>(size - 1), pos, 0x3); } +void Mips64Assembler::Ins(GpuRegister rd, GpuRegister rt, int pos, int size) { + CHECK(IsUint<5>(pos)) << pos; + CHECK(IsUint<5>(size - 1)) << size; + CHECK(IsUint<5>(pos + size - 1)) << pos << " + " << size; + EmitR(0x1f, rt, rd, static_cast<GpuRegister>(pos + size - 1), pos, 0x04); +} + +void Mips64Assembler::Dinsm(GpuRegister rt, GpuRegister rs, int pos, int size) { + CHECK(IsUint<5>(pos)) << pos; + CHECK(2 <= size && size <= 64) << size; + CHECK(IsUint<5>(pos + size - 33)) << pos << " + " << size; + EmitR(0x1f, rs, rt, static_cast<GpuRegister>(pos + size - 33), pos, 0x5); +} + void Mips64Assembler::Dinsu(GpuRegister rt, GpuRegister rs, int pos, int size) { CHECK(IsUint<5>(pos - 32)) << pos; CHECK(IsUint<5>(size - 1)) << size; @@ -437,6 +451,23 @@ void Mips64Assembler::Dinsu(GpuRegister rt, GpuRegister rs, int pos, int size) { EmitR(0x1f, rs, rt, static_cast<GpuRegister>(pos + size - 33), pos - 32, 0x6); } +void Mips64Assembler::Dins(GpuRegister rt, GpuRegister rs, int pos, int size) { + CHECK(IsUint<5>(pos)) << pos; + CHECK(IsUint<5>(size - 1)) << size; + CHECK(IsUint<5>(pos + size - 1)) << pos << " + " << size; + EmitR(0x1f, rs, rt, static_cast<GpuRegister>(pos + size - 1), pos, 0x7); +} + +void Mips64Assembler::DblIns(GpuRegister rt, GpuRegister rs, int pos, int size) { + if (pos >= 32) { + Dinsu(rt, rs, pos, size); + } else if ((static_cast<int64_t>(pos) + size - 1) >= 32) { + Dinsm(rt, rs, pos, size); + } else { + Dins(rt, rs, pos, size); + } +} + void Mips64Assembler::Lsa(GpuRegister rd, GpuRegister rs, GpuRegister rt, int saPlusOne) { CHECK(1 <= saPlusOne && saPlusOne <= 4) << saPlusOne; int sa = saPlusOne - 1; diff --git a/compiler/utils/mips64/assembler_mips64.h b/compiler/utils/mips64/assembler_mips64.h index 9f5e6aaa88..7a61f39e64 100644 --- a/compiler/utils/mips64/assembler_mips64.h +++ b/compiler/utils/mips64/assembler_mips64.h @@ -478,7 +478,11 @@ class Mips64Assembler FINAL : public Assembler, public JNIMacroAssembler<Pointer void Dsbh(GpuRegister rd, GpuRegister rt); // MIPS64 void Dshd(GpuRegister rd, GpuRegister rt); // MIPS64 void Dext(GpuRegister rs, GpuRegister rt, int pos, int size); // MIPS64 + void Ins(GpuRegister rt, GpuRegister rs, int pos, int size); + void Dins(GpuRegister rt, GpuRegister rs, int pos, int size); // MIPS64 + void Dinsm(GpuRegister rt, GpuRegister rs, int pos, int size); // MIPS64 void Dinsu(GpuRegister rt, GpuRegister rs, int pos, int size); // MIPS64 + void DblIns(GpuRegister rt, GpuRegister rs, int pos, int size); // MIPS64 void Lsa(GpuRegister rd, GpuRegister rs, GpuRegister rt, int saPlusOne); void Dlsa(GpuRegister rd, GpuRegister rs, GpuRegister rt, int saPlusOne); // MIPS64 void Wsbh(GpuRegister rd, GpuRegister rt); diff --git a/compiler/utils/mips64/assembler_mips64_test.cc b/compiler/utils/mips64/assembler_mips64_test.cc index d89ca3d6ea..b0e1d91c3f 100644 --- a/compiler/utils/mips64/assembler_mips64_test.cc +++ b/compiler/utils/mips64/assembler_mips64_test.cc @@ -1353,23 +1353,42 @@ TEST_F(AssemblerMIPS64Test, Dext) { DriverStr(expected.str(), "Dext"); } -TEST_F(AssemblerMIPS64Test, Dinsu) { +TEST_F(AssemblerMIPS64Test, Ins) { + std::vector<mips64::GpuRegister*> regs = GetRegisters(); + WarnOnCombinations(regs.size() * regs.size() * 33 * 16); + std::string expected; + for (mips64::GpuRegister* reg1 : regs) { + for (mips64::GpuRegister* reg2 : regs) { + for (int32_t pos = 0; pos < 32; pos++) { + for (int32_t size = 1; pos + size <= 32; size++) { + __ Ins(*reg1, *reg2, pos, size); + std::ostringstream instr; + instr << "ins $" << *reg1 << ", $" << *reg2 << ", " << pos << ", " << size << "\n"; + expected += instr.str(); + } + } + } + } + DriverStr(expected, "Ins"); +} + +TEST_F(AssemblerMIPS64Test, DblIns) { std::vector<mips64::GpuRegister*> reg1_registers = GetRegisters(); std::vector<mips64::GpuRegister*> reg2_registers = GetRegisters(); - WarnOnCombinations(reg1_registers.size() * reg2_registers.size() * 33 * 16); + WarnOnCombinations(reg1_registers.size() * reg2_registers.size() * 65 * 32); std::ostringstream expected; for (mips64::GpuRegister* reg1 : reg1_registers) { for (mips64::GpuRegister* reg2 : reg2_registers) { - for (int32_t pos = 32; pos < 64; pos++) { + for (int32_t pos = 0; pos < 64; pos++) { for (int32_t size = 1; pos + size <= 64; size++) { - __ Dinsu(*reg1, *reg2, pos, size); - expected << "dinsu $" << *reg1 << ", $" << *reg2 << ", " << pos << ", " << size << "\n"; + __ DblIns(*reg1, *reg2, pos, size); + expected << "dins $" << *reg1 << ", $" << *reg2 << ", " << pos << ", " << size << "\n"; } } } } - DriverStr(expected.str(), "Dinsu"); + DriverStr(expected.str(), "DblIns"); } TEST_F(AssemblerMIPS64Test, Lsa) { diff --git a/disassembler/disassembler_mips.cc b/disassembler/disassembler_mips.cc index 2c800e7af3..b5f5d6ff10 100644 --- a/disassembler/disassembler_mips.cc +++ b/disassembler/disassembler_mips.cc @@ -177,7 +177,9 @@ static const MipsInstruction gMipsInstructions[] = { { kSpecial3Mask | 0x3f, (31 << kOpcodeShift), "ext", "TSAZ", }, { kSpecial3Mask | 0x3f, (31 << kOpcodeShift) | 3, "dext", "TSAZ", }, { kSpecial3Mask | 0x3f, (31 << kOpcodeShift) | 4, "ins", "TSAz", }, + { kSpecial3Mask | 0x3f, (31 << kOpcodeShift) | 5, "dinsm", "TSAJ", }, { kSpecial3Mask | 0x3f, (31 << kOpcodeShift) | 6, "dinsu", "TSFz", }, + { kSpecial3Mask | 0x3f, (31 << kOpcodeShift) | 7, "dins", "TSAz", }, { kSpecial3Mask | (0x1f << 21) | (0x1f << 6) | 0x3f, (31 << kOpcodeShift) | (16 << 6) | 32, "seb", @@ -584,6 +586,9 @@ size_t DisassemblerMips::Dump(std::ostream& os, const uint8_t* instr_ptr) { case 'i': // Sign-extended lower 16-bit immediate. args << static_cast<int16_t>(instruction & 0xffff); break; + case 'J': // sz (dinsm size). + args << (rd - sa + 33); + break; case 'j': // sa value for lsa/dlsa. args << (sa + 1); break; |