MIPS: InstructionCodeGeneratorMIPS*::DivRemByPowerOfTwo()
Replace [d]sll+[d]srl with [d]ins on R2+.
Change-Id: I7587e46c47c8ce413d81a5c6c29d91e32a14d855
diff --git a/compiler/utils/mips64/assembler_mips64.cc b/compiler/utils/mips64/assembler_mips64.cc
index bf56877..e1b0e75 100644
--- a/compiler/utils/mips64/assembler_mips64.cc
+++ b/compiler/utils/mips64/assembler_mips64.cc
@@ -430,6 +430,20 @@
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 @@
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;