summaryrefslogtreecommitdiff
path: root/compiler/utils
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/utils')
-rw-r--r--compiler/utils/mips/assembler_mips.cc19
-rw-r--r--compiler/utils/mips/assembler_mips.h1
2 files changed, 20 insertions, 0 deletions
diff --git a/compiler/utils/mips/assembler_mips.cc b/compiler/utils/mips/assembler_mips.cc
index 2e2231b07d..a99d02d4d0 100644
--- a/compiler/utils/mips/assembler_mips.cc
+++ b/compiler/utils/mips/assembler_mips.cc
@@ -635,6 +635,7 @@ void MipsAssembler::Ins(Register rd, Register rt, int pos, int size) {
DsFsmInstrRrr(EmitR(0x1f, rt, rd, static_cast<Register>(pos + size - 1), pos, 0x04), rd, rd, rt);
}
+// TODO: This instruction is available in both R6 and MSA and it should be used when available.
void MipsAssembler::Lsa(Register rd, Register rs, Register rt, int saPlusOne) {
CHECK(IsR6());
CHECK(1 <= saPlusOne && saPlusOne <= 4) << saPlusOne;
@@ -642,6 +643,24 @@ void MipsAssembler::Lsa(Register rd, Register rs, Register rt, int saPlusOne) {
DsFsmInstrRrr(EmitR(0x0, rs, rt, rd, sa, 0x05), rd, rs, rt);
}
+void MipsAssembler::ShiftAndAdd(Register dst,
+ Register src_idx,
+ Register src_base,
+ int shamt,
+ Register tmp) {
+ CHECK(0 <= shamt && shamt <= 4) << shamt;
+ CHECK_NE(src_base, tmp);
+ if (shamt == TIMES_1) {
+ // Catch the special case where the shift amount is zero (0).
+ Addu(dst, src_base, src_idx);
+ } else if (IsR6()) {
+ Lsa(dst, src_idx, src_base, shamt);
+ } else {
+ Sll(tmp, src_idx, shamt);
+ Addu(dst, src_base, tmp);
+ }
+}
+
void MipsAssembler::Lb(Register rt, Register rs, uint16_t imm16) {
DsFsmInstrRrr(EmitI(0x20, rs, rt, imm16), rt, rs, rs);
}
diff --git a/compiler/utils/mips/assembler_mips.h b/compiler/utils/mips/assembler_mips.h
index 1a5a23d10b..463daeb5d7 100644
--- a/compiler/utils/mips/assembler_mips.h
+++ b/compiler/utils/mips/assembler_mips.h
@@ -263,6 +263,7 @@ class MipsAssembler FINAL : public Assembler, public JNIMacroAssembler<PointerSi
void Ext(Register rd, Register rt, int pos, int size); // R2+
void Ins(Register rd, Register rt, int pos, int size); // R2+
void Lsa(Register rd, Register rs, Register rt, int saPlusOne); // R6
+ void ShiftAndAdd(Register dst, Register src_idx, Register src_base, int shamt, Register tmp = AT);
void Lb(Register rt, Register rs, uint16_t imm16);
void Lh(Register rt, Register rs, uint16_t imm16);