Subzero, MIPS32: SRAV instruction encoding
Implements SRAV instruction encoding
R=stichnot@chromium.org
Review URL: https://codereview.chromium.org/2375923002 .
Patch from Srdjan Obucina <Srdjan.Obucina@imgtec.com>.
diff --git a/src/IceAssemblerMIPS32.cpp b/src/IceAssemblerMIPS32.cpp
index 00ef9fe..ce69042 100644
--- a/src/IceAssemblerMIPS32.cpp
+++ b/src/IceAssemblerMIPS32.cpp
@@ -845,6 +845,12 @@
emitRdRtSa(Opcode, OpRd, OpRt, Sa, "srl");
}
+void AssemblerMIPS32::srav(const Operand *OpRd, const Operand *OpRt,
+ const Operand *OpRs) {
+ static constexpr IValueT Opcode = 0x00000007;
+ emitRdRsRt(Opcode, OpRd, OpRs, OpRt, "srav");
+}
+
void AssemblerMIPS32::srlv(const Operand *OpRd, const Operand *OpRt,
const Operand *OpRs) {
static constexpr IValueT Opcode = 0x00000006;
diff --git a/src/IceAssemblerMIPS32.h b/src/IceAssemblerMIPS32.h
index c9f097a..74d7820 100644
--- a/src/IceAssemblerMIPS32.h
+++ b/src/IceAssemblerMIPS32.h
@@ -237,6 +237,8 @@
void sra(const Operand *OpRd, const Operand *OpRt, const uint32_t Sa);
+ void srav(const Operand *OpRd, const Operand *OpRt, const Operand *OpRs);
+
void srl(const Operand *OpRd, const Operand *OpRt, const uint32_t Sa);
void srlv(const Operand *OpRd, const Operand *OpRt, const Operand *OpRs);
diff --git a/src/IceInstMIPS32.cpp b/src/IceInstMIPS32.cpp
index 25282ea..adccf43 100644
--- a/src/IceInstMIPS32.cpp
+++ b/src/IceInstMIPS32.cpp
@@ -1139,6 +1139,11 @@
Asm->sra(getDest(), getSrc(0), Imm);
}
+template <> void InstMIPS32Srav::emitIAS(const Cfg *Func) const {
+ auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>();
+ Asm->srav(getDest(), getSrc(0), getSrc(1));
+}
+
template <> void InstMIPS32Srl::emitIAS(const Cfg *Func) const {
auto *Asm = Func->getAssembler<MIPS32::AssemblerMIPS32>();
Asm->srl(getDest(), getSrc(0), Imm);
diff --git a/src/IceInstMIPS32.h b/src/IceInstMIPS32.h
index 6e7eb83..abd2302 100644
--- a/src/IceInstMIPS32.h
+++ b/src/IceInstMIPS32.h
@@ -1314,6 +1314,7 @@
template <> void InstMIPS32Sqrt_s::emitIAS(const Cfg *Func) const;
template <> void InstMIPS32Sw::emitIAS(const Cfg *Func) const;
template <> void InstMIPS32Sra::emitIAS(const Cfg *Func) const;
+template <> void InstMIPS32Srav::emitIAS(const Cfg *Func) const;
template <> void InstMIPS32Srl::emitIAS(const Cfg *Func) const;
template <> void InstMIPS32Srlv::emitIAS(const Cfg *Func) const;
template <> void InstMIPS32Sub_d::emitIAS(const Cfg *Func) const;
diff --git a/tests_lit/assembler/mips32/encoding_test_arith.ll b/tests_lit/assembler/mips32/encoding_test_arith.ll
index 7df1d49..417d714 100644
--- a/tests_lit/assembler/mips32/encoding_test_arith.ll
+++ b/tests_lit/assembler/mips32/encoding_test_arith.ll
@@ -162,3 +162,35 @@
; IASM-NEXT: .byte 0x0
; IASM-NEXT: .byte 0x0
; IASM-NEXT: .byte 0x0
+
+define internal i32 @ashrImm(i32 %val, i32 %shift) {
+entry:
+ %result = ashr i32 %val, %shift
+ ret i32 %result
+}
+
+; ASM-LABEL: ashrImm:
+; ASM-NEXT: .LashrImm$entry:
+; ASM-NEXT: srav $a0, $a0, $a1
+; ASM-NEXT: move $v0, $a0
+; ASM-NEXT: jr $ra
+
+; DIS-LABEL: <ashrImm>:
+; DIS-NEXT: 00a42007 srav a0,a0,a1
+; DIS-NEXT: 00801021 move v0,a0
+; DIS-NEXT: 03e00008 jr ra
+
+; IASM-LABEL: ashrImm:
+; IASM-NEXT: .LashrImm$entry:
+; IASM-NEXT: .byte 0x7
+; IASM-NEXT: .byte 0x20
+; IASM-NEXT: .byte 0xa4
+; IASM-NEXT: .byte 0x0
+; IASM-NEXT: .byte 0x21
+; IASM-NEXT: .byte 0x10
+; IASM-NEXT: .byte 0x80
+; IASM-NEXT: .byte 0x0
+; IASM-NEXT: .byte 0x8
+; IASM-NEXT: .byte 0x0
+; IASM-NEXT: .byte 0xe0
+; IASM-NEXT: .byte 0x3