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