Commit a393fd40 by Sagar Thakur Committed by Jim Stichnoth

[Subzero][MIPS32] Implement icmp operation for i8, i16 operands

BUG=none R=jpp@chromium.org Review URL: https://codereview.chromium.org/2022063003 . Patch from Sagar Thakur <sagar.thakur@imgtec.com>.
parent 7dbe8022
...@@ -1174,11 +1174,24 @@ void TargetMIPS32::lowerIcmp(const InstIcmp *Instr) { ...@@ -1174,11 +1174,24 @@ void TargetMIPS32::lowerIcmp(const InstIcmp *Instr) {
InstIcmp::ICond Cond = Instr->getCondition(); InstIcmp::ICond Cond = Instr->getCondition();
auto *Src0R = legalizeToReg(Src0); auto *Src0R = legalizeToReg(Src0);
auto *Src1R = legalizeToReg(Src1); auto *Src1R = legalizeToReg(Src1);
const Type Src0Ty = Src0R->getType();
const uint32_t ShAmt = INT32_BITS - getScalarIntBitWidth(Src0->getType());
Variable *Src0RT = I32Reg();
Variable *Src1RT = I32Reg();
if (Src0Ty != IceType_i32) {
_sll(Src0RT, Src0R, ShAmt);
_sll(Src1RT, Src1R, ShAmt);
} else {
_mov(Src0RT, Src0R);
_mov(Src1RT, Src1R);
}
switch (Cond) { switch (Cond) {
case InstIcmp::Eq: { case InstIcmp::Eq: {
auto *DestT = I32Reg(); auto *DestT = I32Reg();
auto *T = I32Reg(); auto *T = I32Reg();
_xor(T, Src0R, Src1R); _xor(T, Src0RT, Src1RT);
_sltiu(DestT, T, 1); _sltiu(DestT, T, 1);
_mov(Dest, DestT); _mov(Dest, DestT);
return; return;
...@@ -1187,63 +1200,63 @@ void TargetMIPS32::lowerIcmp(const InstIcmp *Instr) { ...@@ -1187,63 +1200,63 @@ void TargetMIPS32::lowerIcmp(const InstIcmp *Instr) {
auto *DestT = I32Reg(); auto *DestT = I32Reg();
auto *T = I32Reg(); auto *T = I32Reg();
auto *Zero = getZero(); auto *Zero = getZero();
_xor(T, Src0R, Src1R); _xor(T, Src0RT, Src1RT);
_sltu(DestT, Zero, T); _sltu(DestT, Zero, T);
_mov(Dest, DestT); _mov(Dest, DestT);
return; return;
} }
case InstIcmp::Ugt: { case InstIcmp::Ugt: {
auto *DestT = I32Reg(); auto *DestT = I32Reg();
_sltu(DestT, Src1R, Src0R); _sltu(DestT, Src1RT, Src0RT);
_mov(Dest, DestT); _mov(Dest, DestT);
return; return;
} }
case InstIcmp::Uge: { case InstIcmp::Uge: {
auto *DestT = I32Reg(); auto *DestT = I32Reg();
auto *T = I32Reg(); auto *T = I32Reg();
_sltu(T, Src0R, Src1R); _sltu(T, Src0RT, Src1RT);
_xori(DestT, T, 1); _xori(DestT, T, 1);
_mov(Dest, DestT); _mov(Dest, DestT);
return; return;
} }
case InstIcmp::Ult: { case InstIcmp::Ult: {
auto *DestT = I32Reg(); auto *DestT = I32Reg();
_sltu(DestT, Src0R, Src1R); _sltu(DestT, Src0RT, Src1RT);
_mov(Dest, DestT); _mov(Dest, DestT);
return; return;
} }
case InstIcmp::Ule: { case InstIcmp::Ule: {
auto *DestT = I32Reg(); auto *DestT = I32Reg();
auto *T = I32Reg(); auto *T = I32Reg();
_sltu(T, Src1R, Src0R); _sltu(T, Src1RT, Src0RT);
_xori(DestT, T, 1); _xori(DestT, T, 1);
_mov(Dest, DestT); _mov(Dest, DestT);
return; return;
} }
case InstIcmp::Sgt: { case InstIcmp::Sgt: {
auto *DestT = I32Reg(); auto *DestT = I32Reg();
_slt(DestT, Src1R, Src0R); _slt(DestT, Src1RT, Src0RT);
_mov(Dest, DestT); _mov(Dest, DestT);
return; return;
} }
case InstIcmp::Sge: { case InstIcmp::Sge: {
auto *DestT = I32Reg(); auto *DestT = I32Reg();
auto *T = I32Reg(); auto *T = I32Reg();
_slt(T, Src0R, Src1R); _slt(T, Src0RT, Src1RT);
_xori(DestT, T, 1); _xori(DestT, T, 1);
_mov(Dest, DestT); _mov(Dest, DestT);
return; return;
} }
case InstIcmp::Slt: { case InstIcmp::Slt: {
auto *DestT = I32Reg(); auto *DestT = I32Reg();
_slt(DestT, Src0R, Src1R); _slt(DestT, Src0RT, Src1RT);
_mov(Dest, DestT); _mov(Dest, DestT);
return; return;
} }
case InstIcmp::Sle: { case InstIcmp::Sle: {
auto *DestT = I32Reg(); auto *DestT = I32Reg();
auto *T = I32Reg(); auto *T = I32Reg();
_slt(T, Src1R, Src0R); _slt(T, Src1RT, Src0RT);
_xori(DestT, T, 1); _xori(DestT, T, 1);
_mov(Dest, DestT); _mov(Dest, DestT);
return; return;
......
; Simple tests for icmp with i8, i16, i32 operands.
; RUN: %if --need=allow_dump --need=target_MIPS32 --command %p2i \
; RUN: --filetype=asm --target mips32 -i %s --args -O2 --skip-unimplemented \
; RUN: -allow-externally-defined-symbols \
; RUN: | %if --need=allow_dump --need=target_MIPS32 --command FileCheck %s \
; RUN: --check-prefix=COMMON --check-prefix=MIPS32
; RUN: %if --need=allow_dump --need=target_MIPS32 --command %p2i \
; RUN: --filetype=asm --target mips32 -i %s --args -Om1 --skip-unimplemented \
; RUN: -allow-externally-defined-symbols \
; RUN: | %if --need=allow_dump --need=target_MIPS32 --command FileCheck %s \
; RUN: --check-prefix=COMMON --check-prefix=MIPS32
define internal i32 @icmpEq32(i32 %a, i32 %b) {
entry:
%cmp = icmp eq i32 %a, %b
%cmp.ret_ext = zext i1 %cmp to i32
ret i32 %cmp.ret_ext
}
; MIPS32-LABEL: icmpEq32
; MIPS32: xor
; MIPS32: sltiu {{.*}}, {{.*}}, 1
define internal i32 @icmpNe32(i32 %a, i32 %b) {
entry:
%cmp = icmp ne i32 %a, %b
%cmp.ret_ext = zext i1 %cmp to i32
ret i32 %cmp.ret_ext
}
; MIPS32-LABEL: icmpNe32
; MIPS32: xor
; MIPS32: sltu {{.*}}, $zero, {{.*}}
define internal i32 @icmpSgt32(i32 %a, i32 %b) {
entry:
%cmp = icmp sgt i32 %a, %b
%cmp.ret_ext = zext i1 %cmp to i32
ret i32 %cmp.ret_ext
}
; MIPS32-LABEL: icmpSgt32
; MIPS32: slt
define internal i32 @icmpUgt32(i32 %a, i32 %b) {
entry:
%cmp = icmp ugt i32 %a, %b
%cmp.ret_ext = zext i1 %cmp to i32
ret i32 %cmp.ret_ext
}
; MIPS32-LABEL: icmpUgt32
; MIPS32: sltu
define internal i32 @icmpSge32(i32 %a, i32 %b) {
entry:
%cmp = icmp sge i32 %a, %b
%cmp.ret_ext = zext i1 %cmp to i32
ret i32 %cmp.ret_ext
}
; MIPS32-LABEL: icmpSge32
; MIPS32: slt
; MIPS32: xori {{.*}}, {{.*}}, 1
define internal i32 @icmpUge32(i32 %a, i32 %b) {
entry:
%cmp = icmp uge i32 %a, %b
%cmp.ret_ext = zext i1 %cmp to i32
ret i32 %cmp.ret_ext
}
; MIPS32-LABEL: icmpUge32
; MIPS32: sltu
; MIPS32: xori {{.*}}, {{.*}}, 1
define internal i32 @icmpSlt32(i32 %a, i32 %b) {
entry:
%cmp = icmp slt i32 %a, %b
%cmp.ret_ext = zext i1 %cmp to i32
ret i32 %cmp.ret_ext
}
; MIPS32-LABEL: icmpSlt32
; MIPS32: slt
define internal i32 @icmpUlt32(i32 %a, i32 %b) {
entry:
%cmp = icmp ult i32 %a, %b
%cmp.ret_ext = zext i1 %cmp to i32
ret i32 %cmp.ret_ext
}
; MIPS32-LABEL: icmpUlt32
; MIPS32: sltu
define internal i32 @icmpSle32(i32 %a, i32 %b) {
entry:
%cmp = icmp sle i32 %a, %b
%cmp.ret_ext = zext i1 %cmp to i32
ret i32 %cmp.ret_ext
}
; MIPS32-LABEL: icmpSle32
; MIPS32: slt
; MIPS32: xori {{.*}}, {{.*}}, 1
define internal i32 @icmpUle32(i32 %a, i32 %b) {
entry:
%cmp = icmp ule i32 %a, %b
%cmp.ret_ext = zext i1 %cmp to i32
ret i32 %cmp.ret_ext
}
; MIPS32-LABEL: icmpUle32
; MIPS32: sltu
; MIPS32: xori {{.*}}, {{.*}}, 1
define internal i32 @icmpEq8(i32 %a, i32 %b) {
entry:
%a_8 = trunc i32 %a to i8
%b_8 = trunc i32 %b to i8
%icmp = icmp eq i8 %b_8, %a_8
%ret = zext i1 %icmp to i32
ret i32 %ret
}
; MIPS32-LABEL: icmpEq8
; MIPS32: sll {{.*}}, {{.*}}, 24
; MIPS32: sll {{.*}}, {{.*}}, 24
; MIPS32: xor
; MIPS32: sltiu {{.*}}, {{.*}}, 1
define internal i32 @icmpSgt8(i32 %a, i32 %b) {
entry:
%a_8 = trunc i32 %a to i8
%b_8 = trunc i32 %b to i8
%icmp = icmp sgt i8 %b_8, %a_8
%ret = zext i1 %icmp to i32
ret i32 %ret
}
; MIPS32-LABEL: icmpSgt8
; MIPS32: sll {{.*}}, {{.*}}, 24
; MIPS32: sll {{.*}}, {{.*}}, 24
; MIPS32: slt
define internal i32 @icmpUgt8(i32 %a, i32 %b) {
entry:
%a_8 = trunc i32 %a to i8
%b_8 = trunc i32 %b to i8
%icmp = icmp ugt i8 %b_8, %a_8
%ret = zext i1 %icmp to i32
ret i32 %ret
}
; MIPS32-LABEL: icmpUgt8
; MIPS32: sll {{.*}}, {{.*}}, 24
; MIPS32: sll {{.*}}, {{.*}}, 24
; MIPS32: sltu
define internal i32 @icmpSgt16(i32 %a, i32 %b) {
entry:
%a_16 = trunc i32 %a to i16
%b_16 = trunc i32 %b to i16
%icmp = icmp sgt i16 %b_16, %a_16
%ret = zext i1 %icmp to i32
ret i32 %ret
}
; MIPS32-LABEL: icmpSgt16
; MIPS32: sll {{.*}}, {{.*}}, 16
; MIPS32: sll {{.*}}, {{.*}}, 16
; MIPS32: slt
define internal i32 @icmpUgt16(i32 %a, i32 %b) {
entry:
%a_16 = trunc i32 %a to i16
%b_16 = trunc i32 %b to i16
%icmp = icmp ugt i16 %b_16, %a_16
%ret = zext i1 %icmp to i32
ret i32 %ret
}
; MIPS32-LABEL: icmpUgt16
; MIPS32: sll {{.*}}, {{.*}}, 16
; MIPS32: sll {{.*}}, {{.*}}, 16
; MIPS32: sltu
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment