Subzero, MIPS32: Implement logical instructions ashr, lshr, shl
This patch adds support for logical operations ashr, lshr and shl.
R=stichnot@chromium.org
Review URL: https://codereview.chromium.org/1975283002 .
Patch from Srdjan Obucina <Srdjan.Obucina@imgtec.com>.
diff --git a/src/IceInstMIPS32.cpp b/src/IceInstMIPS32.cpp
index 30d48e3..043c2ca 100644
--- a/src/IceInstMIPS32.cpp
+++ b/src/IceInstMIPS32.cpp
@@ -67,11 +67,15 @@
template <> const char *InstMIPS32Or::Opcode = "or";
template <> const char *InstMIPS32Ori::Opcode = "ori";
template <> const char *InstMIPS32Sll::Opcode = "sll";
+template <> const char *InstMIPS32Sllv::Opcode = "sllv";
template <> const char *InstMIPS32Slt::Opcode = "slt";
template <> const char *InstMIPS32Slti::Opcode = "slti";
template <> const char *InstMIPS32Sltiu::Opcode = "sltiu";
template <> const char *InstMIPS32Sltu::Opcode = "sltu";
template <> const char *InstMIPS32Sra::Opcode = "sra";
+template <> const char *InstMIPS32Srav::Opcode = "srav";
+template <> const char *InstMIPS32Srl::Opcode = "srl";
+template <> const char *InstMIPS32Srlv::Opcode = "srlv";
template <> const char *InstMIPS32Sub::Opcode = "sub";
template <> const char *InstMIPS32Subu::Opcode = "subu";
template <> const char *InstMIPS32Xor::Opcode = "xor";
diff --git a/src/IceInstMIPS32.h b/src/IceInstMIPS32.h
index 4247e7e..85f268e 100644
--- a/src/IceInstMIPS32.h
+++ b/src/IceInstMIPS32.h
@@ -139,11 +139,15 @@
Ori,
Ret,
Sll,
+ Sllv,
Slt,
Slti,
Sltiu,
Sltu,
Sra,
+ Srav,
+ Srl,
+ Srlv,
Sub,
Subu,
Xor,
@@ -478,11 +482,15 @@
using InstMIPS32Or = InstMIPS32ThreeAddrGPR<InstMIPS32::Or>;
using InstMIPS32Ori = InstMIPS32Imm16<InstMIPS32::Ori>;
using InstMIPS32Sll = InstMIPS32Imm16<InstMIPS32::Sll>;
+using InstMIPS32Sllv = InstMIPS32ThreeAddrGPR<InstMIPS32::Sllv>;
using InstMIPS32Slt = InstMIPS32ThreeAddrGPR<InstMIPS32::Slt>;
using InstMIPS32Slti = InstMIPS32Imm16<InstMIPS32::Slti>;
using InstMIPS32Sltiu = InstMIPS32Imm16<InstMIPS32::Sltiu>;
using InstMIPS32Sltu = InstMIPS32ThreeAddrGPR<InstMIPS32::Sltu>;
using InstMIPS32Sra = InstMIPS32Imm16<InstMIPS32::Sra>;
+using InstMIPS32Srav = InstMIPS32ThreeAddrGPR<InstMIPS32::Srav>;
+using InstMIPS32Srl = InstMIPS32Imm16<InstMIPS32::Srl>;
+using InstMIPS32Srlv = InstMIPS32ThreeAddrGPR<InstMIPS32::Srlv>;
using InstMIPS32Sub = InstMIPS32ThreeAddrGPR<InstMIPS32::Sub>;
using InstMIPS32Subu = InstMIPS32ThreeAddrGPR<InstMIPS32::Subu>;
using InstMIPS32Ori = InstMIPS32Imm16<InstMIPS32::Ori>;
diff --git a/src/IceTargetLoweringMIPS32.cpp b/src/IceTargetLoweringMIPS32.cpp
index 79f02fb..a2e82b2 100644
--- a/src/IceTargetLoweringMIPS32.cpp
+++ b/src/IceTargetLoweringMIPS32.cpp
@@ -692,9 +692,6 @@
switch (Instr->getOp()) {
default:
break;
- case InstArithmetic::Shl:
- case InstArithmetic::Lshr:
- case InstArithmetic::Ashr:
case InstArithmetic::Udiv:
case InstArithmetic::Sdiv:
case InstArithmetic::Urem:
@@ -742,12 +739,21 @@
_mov(Dest, T);
return;
}
- case InstArithmetic::Shl:
- break;
- case InstArithmetic::Lshr:
- break;
- case InstArithmetic::Ashr:
- break;
+ case InstArithmetic::Shl: {
+ _sllv(T, Src0R, Src1R);
+ _mov(Dest, T);
+ return;
+ }
+ case InstArithmetic::Lshr: {
+ _srlv(T, Src0R, Src1R);
+ _mov(Dest, T);
+ return;
+ }
+ case InstArithmetic::Ashr: {
+ _srav(T, Src0R, Src1R);
+ _mov(Dest, T);
+ return;
+ }
case InstArithmetic::Udiv:
break;
case InstArithmetic::Sdiv:
diff --git a/src/IceTargetLoweringMIPS32.h b/src/IceTargetLoweringMIPS32.h
index 0454f30..a90311a 100644
--- a/src/IceTargetLoweringMIPS32.h
+++ b/src/IceTargetLoweringMIPS32.h
@@ -224,6 +224,10 @@
Context.insert<InstMIPS32Sll>(Dest, Src, Imm);
}
+ void _sllv(Variable *Dest, Variable *Src0, Variable *Src1) {
+ Context.insert<InstMIPS32Sllv>(Dest, Src0, Src1);
+ }
+
void _slt(Variable *Dest, Variable *Src0, Variable *Src1) {
Context.insert<InstMIPS32Slt>(Dest, Src0, Src1);
}
@@ -244,6 +248,18 @@
Context.insert<InstMIPS32Sra>(Dest, Src, Imm);
}
+ void _srav(Variable *Dest, Variable *Src0, Variable *Src1) {
+ Context.insert<InstMIPS32Srav>(Dest, Src0, Src1);
+ }
+
+ void _srl(Variable *Dest, Variable *Src, uint32_t Imm) {
+ Context.insert<InstMIPS32Srl>(Dest, Src, Imm);
+ }
+
+ void _srlv(Variable *Dest, Variable *Src0, Variable *Src1) {
+ Context.insert<InstMIPS32Srlv>(Dest, Src0, Src1);
+ }
+
void _sub(Variable *Dest, Variable *Src0, Variable *Src1) {
Context.insert<InstMIPS32Sub>(Dest, Src0, Src1);
}
diff --git a/tests_lit/llvm2ice_tests/shift.ll b/tests_lit/llvm2ice_tests/shift.ll
index 020b1c9..2478544 100644
--- a/tests_lit/llvm2ice_tests/shift.ll
+++ b/tests_lit/llvm2ice_tests/shift.ll
@@ -24,6 +24,17 @@
; RUN: | %if --need=target_ARM32 --need=allow_dump \
; RUN: --command FileCheck --check-prefix ARM32 %s
+; RUN: %if --need=target_MIPS32 --need=allow_dump \
+; RUN: --command %p2i --filetype=asm --assemble \
+; RUN: --disassemble --target mips32 -i %s --args -O2 --skip-unimplemented \
+; RUN: | %if --need=target_MIPS32 --need=allow_dump \
+; RUN: --command FileCheck --check-prefix MIPS32 %s
+
+; RUN: %if --need=target_MIPS32 --need=allow_dump \
+; RUN: --command %p2i --filetype=asm --assemble \
+; RUN: --disassemble --target mips32 -i %s --args -Om1 --skip-unimplemented \
+; RUN: | %if --need=target_MIPS32 --need=allow_dump \
+; RUN: --command FileCheck --check-prefix MIPS32 %s
@i1 = internal global [4 x i8] zeroinitializer, align 4
@i2 = internal global [4 x i8] zeroinitializer, align 4
@@ -73,6 +84,9 @@
; CHECK-LABEL: shlImmLarge
; CHECK: shl {{.*}},0x1
+; MIPS32-LABEL: shlImmLarge
+; MIPS32: sllv
+
define internal i32 @shlImmNeg(i32 %val) {
entry:
%result = shl i32 %val, -1
@@ -81,6 +95,9 @@
; CHECK-LABEL: shlImmNeg
; CHECK: shl {{.*}},0xff
+; MIPS32-LABEL: shlImmNeg
+; MIPS32: sllv
+
define internal i32 @lshrImmLarge(i32 %val) {
entry:
%result = lshr i32 %val, 257
@@ -89,6 +106,9 @@
; CHECK-LABEL: lshrImmLarge
; CHECK: shr {{.*}},0x1
+; MIPS32-LABEL: lshrImmLarge
+; MIPS32: srlv
+
define internal i32 @lshrImmNeg(i32 %val) {
entry:
%result = lshr i32 %val, -1
@@ -97,6 +117,9 @@
; CHECK-LABEL: lshrImmNeg
; CHECK: shr {{.*}},0xff
+; MIPS32-LABEL: lshrImmNeg
+; MIPS32: srlv
+
define internal i32 @ashrImmLarge(i32 %val) {
entry:
%result = ashr i32 %val, 257
@@ -105,6 +128,9 @@
; CHECK-LABEL: ashrImmLarge
; CHECK: sar {{.*}},0x1
+; MIPS32-LABEL: ashrImmLarge
+; MIPS32: srav
+
define internal i32 @ashrImmNeg(i32 %val) {
entry:
%result = ashr i32 %val, -1
@@ -113,6 +139,9 @@
; CHECK-LABEL: ashrImmNeg
; CHECK: sar {{.*}},0xff
+; MIPS32-LABEL: ashrImmNeg
+; MIPS32: srav
+
define internal i64 @shlImm64One(i64 %val) {
entry:
%result = shl i64 %val, 1