Commit 70b6ed47 by Sagar Thakur Committed by Jim Stichnoth

[Subzero][MIPS] Implement 64-bit integer compare operations

R=stichnot@chromium.org Review URL: https://codereview.chromium.org/2369323002 . Patch from Sagar Thakur <sagar.thakur@imgtec.com>.
parent b0f09fc8
...@@ -1153,7 +1153,7 @@ using InstMIPS32Movn = InstMIPS32MovConditional<InstMIPS32::Movn>; ...@@ -1153,7 +1153,7 @@ using InstMIPS32Movn = InstMIPS32MovConditional<InstMIPS32::Movn>;
using InstMIPS32Movn_d = InstMIPS32ThreeAddrGPR<InstMIPS32::Movn_d>; using InstMIPS32Movn_d = InstMIPS32ThreeAddrGPR<InstMIPS32::Movn_d>;
using InstMIPS32Movn_s = InstMIPS32ThreeAddrGPR<InstMIPS32::Movn_s>; using InstMIPS32Movn_s = InstMIPS32ThreeAddrGPR<InstMIPS32::Movn_s>;
using InstMIPS32Movt = InstMIPS32MovConditional<InstMIPS32::Movt>; using InstMIPS32Movt = InstMIPS32MovConditional<InstMIPS32::Movt>;
using InstMIPS32Movz = InstMIPS32ThreeAddrGPR<InstMIPS32::Movz>; using InstMIPS32Movz = InstMIPS32MovConditional<InstMIPS32::Movz>;
using InstMIPS32Movz_d = InstMIPS32ThreeAddrGPR<InstMIPS32::Movz_d>; using InstMIPS32Movz_d = InstMIPS32ThreeAddrGPR<InstMIPS32::Movz_d>;
using InstMIPS32Movz_s = InstMIPS32ThreeAddrGPR<InstMIPS32::Movz_s>; using InstMIPS32Movz_s = InstMIPS32ThreeAddrGPR<InstMIPS32::Movz_s>;
using InstMIPS32Mtc1 = InstMIPS32TwoAddrGPR<InstMIPS32::Mtc1>; using InstMIPS32Mtc1 = InstMIPS32TwoAddrGPR<InstMIPS32::Mtc1>;
......
...@@ -2900,8 +2900,149 @@ void TargetMIPS32::lowerFcmp(const InstFcmp *Instr) { ...@@ -2900,8 +2900,149 @@ void TargetMIPS32::lowerFcmp(const InstFcmp *Instr) {
} }
void TargetMIPS32::lower64Icmp(const InstIcmp *Instr) { void TargetMIPS32::lower64Icmp(const InstIcmp *Instr) {
UnimplementedLoweringError(this, Instr); Operand *Src0 = legalize(Instr->getSrc(0));
return; Operand *Src1 = legalize(Instr->getSrc(1));
Variable *Dest = Instr->getDest();
InstIcmp::ICond Condition = Instr->getCondition();
Variable *Src0LoR = legalizeToReg(loOperand(Src0));
Variable *Src0HiR = legalizeToReg(hiOperand(Src0));
Variable *Src1LoR = legalizeToReg(loOperand(Src1));
Variable *Src1HiR = legalizeToReg(hiOperand(Src1));
switch (Condition) {
default:
llvm_unreachable("unexpected condition");
break;
case InstIcmp::Eq: {
auto *T1 = I32Reg();
auto *T2 = I32Reg();
auto *T3 = I32Reg();
auto *T4 = I32Reg();
_xor(T1, Src0HiR, Src1HiR);
_xor(T2, Src0LoR, Src1LoR);
_or(T3, T1, T2);
_sltiu(T4, T3, 1);
_mov(Dest, T4);
return;
}
case InstIcmp::Ne: {
auto *T1 = I32Reg();
auto *T2 = I32Reg();
auto *T3 = I32Reg();
auto *T4 = I32Reg();
_xor(T1, Src0HiR, Src1HiR);
_xor(T2, Src0LoR, Src1LoR);
_or(T3, T1, T2);
_sltu(T4, getZero(), T3);
_mov(Dest, T4);
return;
}
case InstIcmp::Sgt: {
auto *T1 = I32Reg();
auto *T2 = I32Reg();
auto *T3 = I32Reg();
_xor(T1, Src0HiR, Src1HiR);
_slt(T2, Src1HiR, Src0HiR);
_sltu(T3, Src1LoR, Src0LoR);
_movz(T2, T3, T1);
_mov(Dest, T2);
return;
}
case InstIcmp::Ugt: {
auto *T1 = I32Reg();
auto *T2 = I32Reg();
auto *T3 = I32Reg();
_xor(T1, Src0HiR, Src1HiR);
_sltu(T2, Src1HiR, Src0HiR);
_sltu(T3, Src1LoR, Src0LoR);
_movz(T2, T3, T1);
_mov(Dest, T2);
return;
}
case InstIcmp::Sge: {
auto *T1 = I32Reg();
auto *T2 = I32Reg();
auto *T3 = I32Reg();
auto *T4 = I32Reg();
auto *T5 = I32Reg();
_xor(T1, Src0HiR, Src1HiR);
_slt(T2, Src0HiR, Src1HiR);
_xori(T3, T2, 1);
_sltu(T4, Src0LoR, Src1LoR);
_xori(T5, T4, 1);
_movz(T3, T5, T1);
_mov(Dest, T3);
return;
}
case InstIcmp::Uge: {
auto *T1 = I32Reg();
auto *T2 = I32Reg();
auto *T3 = I32Reg();
auto *T4 = I32Reg();
auto *T5 = I32Reg();
_xor(T1, Src0HiR, Src1HiR);
_sltu(T2, Src0HiR, Src1HiR);
_xori(T3, T2, 1);
_sltu(T4, Src0LoR, Src1LoR);
_xori(T5, T4, 1);
_movz(T3, T5, T1);
_mov(Dest, T3);
return;
}
case InstIcmp::Slt: {
auto *T1 = I32Reg();
auto *T2 = I32Reg();
auto *T3 = I32Reg();
_xor(T1, Src0HiR, Src1HiR);
_slt(T2, Src0HiR, Src1HiR);
_sltu(T3, Src0LoR, Src1LoR);
_movz(T2, T3, T1);
_mov(Dest, T2);
return;
}
case InstIcmp::Ult: {
auto *T1 = I32Reg();
auto *T2 = I32Reg();
auto *T3 = I32Reg();
_xor(T1, Src0HiR, Src1HiR);
_sltu(T2, Src0HiR, Src1HiR);
_sltu(T3, Src0LoR, Src1LoR);
_movz(T2, T3, T1);
_mov(Dest, T2);
return;
}
case InstIcmp::Sle: {
auto *T1 = I32Reg();
auto *T2 = I32Reg();
auto *T3 = I32Reg();
auto *T4 = I32Reg();
auto *T5 = I32Reg();
_xor(T1, Src0HiR, Src1HiR);
_slt(T2, Src1HiR, Src0HiR);
_xori(T3, T2, 1);
_sltu(T4, Src1LoR, Src0LoR);
_xori(T5, T4, 1);
_movz(T3, T5, T1);
_mov(Dest, T3);
return;
}
case InstIcmp::Ule: {
auto *T1 = I32Reg();
auto *T2 = I32Reg();
auto *T3 = I32Reg();
auto *T4 = I32Reg();
auto *T5 = I32Reg();
_xor(T1, Src0HiR, Src1HiR);
_sltu(T2, Src1HiR, Src0HiR);
_xori(T3, T2, 1);
_sltu(T4, Src1LoR, Src0LoR);
_xori(T5, T4, 1);
_movz(T3, T5, T1);
_mov(Dest, T3);
return;
}
}
} }
void TargetMIPS32::lowerIcmp(const InstIcmp *Instr) { void TargetMIPS32::lowerIcmp(const InstIcmp *Instr) {
......
...@@ -34,7 +34,7 @@ ...@@ -34,7 +34,7 @@
; RUN: --disassemble --target mips32 -i %s --args -O2 --skip-unimplemented \ ; RUN: --disassemble --target mips32 -i %s --args -O2 --skip-unimplemented \
; RUN: -allow-externally-defined-symbols \ ; RUN: -allow-externally-defined-symbols \
; RUN: | %if --need=target_MIPS32 --need=allow_dump \ ; RUN: | %if --need=target_MIPS32 --need=allow_dump \
; RUN: --command FileCheck --check-prefix MIPS32 %s ; RUN: --command FileCheck --check-prefix MIPS32 --check-prefix MIPS32-O2 %s
@__init_array_start = internal constant [0 x i8] zeroinitializer, align 4 @__init_array_start = internal constant [0 x i8] zeroinitializer, align 4
@__fini_array_start = internal constant [0 x i8] zeroinitializer, align 4 @__fini_array_start = internal constant [0 x i8] zeroinitializer, align 4
...@@ -1604,6 +1604,12 @@ entry: ...@@ -1604,6 +1604,12 @@ entry:
; ARM32: mov ; ARM32: mov
; ARM32: moveq ; ARM32: moveq
; MIPS32-LABEL: icmpEq64Bool
; MIPS32: xor [[T1:.*]],{{.*}},{{.*}}
; MIPS32: xor [[T2:.*]],{{.*}},{{.*}}
; MIPS32: or [[T3:.*]],[[T1]],[[T2]]
; MIPS32: sltiu {{.*}},[[T3]],1
define internal i32 @icmpNe64Bool(i64 %a, i64 %b) { define internal i32 @icmpNe64Bool(i64 %a, i64 %b) {
entry: entry:
%cmp = icmp ne i64 %a, %b %cmp = icmp ne i64 %a, %b
...@@ -1622,6 +1628,12 @@ entry: ...@@ -1622,6 +1628,12 @@ entry:
; ARM32: mov ; ARM32: mov
; ARM32: movne ; ARM32: movne
; MIPS32-LABEL: icmpNe64Bool
; MIPS32: xor [[T1:.*]],{{.*}},{{.*}}
; MIPS32: xor [[T2:.*]],{{.*}},{{.*}}
; MIPS32: or [[T3:.*]],[[T1]],[[T2]]
; MIPS32: sltu {{.*}},zero,[[T3]]
define internal i32 @icmpSgt64Bool(i64 %a, i64 %b) { define internal i32 @icmpSgt64Bool(i64 %a, i64 %b) {
entry: entry:
%cmp = icmp sgt i64 %a, %b %cmp = icmp sgt i64 %a, %b
...@@ -1648,6 +1660,15 @@ entry: ...@@ -1648,6 +1660,15 @@ entry:
; ARM32: sbcs ; ARM32: sbcs
; ARM32: movlt ; ARM32: movlt
; MIPS32-LABEL: icmpSgt64Bool
; MIPS32: xor [[T1:.*]],[[A_HI:.*]],[[B_HI:.*]]
; MIPS32: slt [[T2:.*]],{{.*}},{{.*}}
; MIPS32: sltu [[T3:.*]],{{.*}},{{.*}}
; MIPS32: movz [[T2]],[[T3]],[[T1]]
; MIPS32-O2: move {{.*}},[[T2]]
; MIPS32-OM1: sw [[T2]],[[MEM:.*]]
; MIPS32-OM1: lb {{.*}},[[MEM]]
define internal i32 @icmpUgt64Bool(i64 %a, i64 %b) { define internal i32 @icmpUgt64Bool(i64 %a, i64 %b) {
entry: entry:
%cmp = icmp ugt i64 %a, %b %cmp = icmp ugt i64 %a, %b
...@@ -1674,6 +1695,15 @@ entry: ...@@ -1674,6 +1695,15 @@ entry:
; ARM32: cmpeq ; ARM32: cmpeq
; ARM32: movhi ; ARM32: movhi
; MIPS32-LABEL: icmpUgt64Bool
; MIPS32: xor [[T1:.*]],[[A_HI:.*]],[[B_HI:.*]]
; MIPS32: sltu [[T2:.*]],[[B_HI]],[[A_HI]]
; MIPS32: sltu [[T3:.*]],{{.*}},{{.*}}
; MIPS32: movz [[T2]],[[T3]],[[T1]]
; MIPS32-O2: move {{.*}},[[T2]]
; MIPS32-OM1: sw [[T2]],[[MEM:.*]]
; MIPS32-OM1: lb {{.*}},[[MEM]]
define internal i32 @icmpSge64Bool(i64 %a, i64 %b) { define internal i32 @icmpSge64Bool(i64 %a, i64 %b) {
entry: entry:
%cmp = icmp sge i64 %a, %b %cmp = icmp sge i64 %a, %b
...@@ -1700,6 +1730,17 @@ entry: ...@@ -1700,6 +1730,17 @@ entry:
; ARM32: sbcs ; ARM32: sbcs
; ARM32: movge ; ARM32: movge
; MIPS32-LABEL: icmpSge64Bool
; MIPS32: xor [[T1:.*]],[[A_HI:.*]],[[B_HI:.*]]
; MIPS32: slt [[T2:.*]],[[A_HI]],[[B_HI]]
; MIPS32: xori [[T3:.*]],[[T2]],0x1
; MIPS32: sltu [[T4:.*]],{{.*}},{{.*}}
; MIPS32: xori [[T5:.*]],[[T4]],0x1
; MIPS32: movz [[T6:.*]],[[T5]],[[T1]]
; MIPS32-O2: move {{.*}},[[T3]]
; MIPS32-OM1: sw [[T3]],[[MEM:.*]]
; MIPS32-OM1: lb {{.*}},[[MEM]]
define internal i32 @icmpUge64Bool(i64 %a, i64 %b) { define internal i32 @icmpUge64Bool(i64 %a, i64 %b) {
entry: entry:
%cmp = icmp uge i64 %a, %b %cmp = icmp uge i64 %a, %b
...@@ -1726,6 +1767,17 @@ entry: ...@@ -1726,6 +1767,17 @@ entry:
; ARM32: cmpeq ; ARM32: cmpeq
; ARM32: movcs ; ARM32: movcs
; MIPS32-LABEL: icmpUge64Bool
; MIPS32: xor [[T1:.*]],[[A_HI:.*]],[[B_HI:.*]]
; MIPS32: sltu [[T2:.*]],[[A_HI]],[[B_HI]]
; MIPS32: xori [[T3:.*]],[[T2]],0x1
; MIPS32: sltu [[T4:.*]],{{.*}},{{.*}}
; MIPS32: xori [[T5:.*]],[[T4]],0x1
; MIPS32: movz [[T6:.*]],[[T5]],[[T1]]
; MIPS32-O2: move {{.*}},[[T3]]
; MIPS32-OM1: sw [[T3]],[[MEM:.*]]
; MIPS32-OM1: lb {{.*}},[[MEM]]
define internal i32 @icmpSlt64Bool(i64 %a, i64 %b) { define internal i32 @icmpSlt64Bool(i64 %a, i64 %b) {
entry: entry:
%cmp = icmp slt i64 %a, %b %cmp = icmp slt i64 %a, %b
...@@ -1752,6 +1804,15 @@ entry: ...@@ -1752,6 +1804,15 @@ entry:
; ARM32: sbcs ; ARM32: sbcs
; ARM32: movlt ; ARM32: movlt
; MIPS32-LABEL: icmpSlt64Bool
; MIPS32: xor [[T1:.*]],[[A_HI:.*]],[[B_HI:.*]]
; MIPS32: slt [[T2:.*]],[[A_HI]],[[B_HI]]
; MIPS32: sltu [[T3:.*]],{{.*}},{{.*}}
; MIPS32: movz [[T2:.*]],[[T3]],[[T1]]
; MIPS32-O2: move {{.*}},[[T2]]
; MIPS32-OM1: sw [[T2]],[[MEM:.*]]
; MIPS32-OM1: lb {{.*}},[[MEM]]
define internal i32 @icmpUlt64Bool(i64 %a, i64 %b) { define internal i32 @icmpUlt64Bool(i64 %a, i64 %b) {
entry: entry:
%cmp = icmp ult i64 %a, %b %cmp = icmp ult i64 %a, %b
...@@ -1778,6 +1839,15 @@ entry: ...@@ -1778,6 +1839,15 @@ entry:
; ARM32: cmpeq ; ARM32: cmpeq
; ARM32: movcc ; ARM32: movcc
; MIPS32-LABEL: icmpUlt64Bool
; MIPS32: xor [[T1:.*]],[[A_HI:.*]],[[B_HI:.*]]
; MIPS32: sltu [[T2:.*]],[[A_HI]],[[B_HI]]
; MIPS32: sltu [[T3:.*]],{{.*}},{{.*}}
; MIPS32: movz [[T2:.*]],[[T3]],[[T1]]
; MIPS32-O2: move {{.*}},[[T2]]
; MIPS32-OM1: sw [[T2]],[[MEM:.*]]
; MIPS32-OM1: lb {{.*}},[[MEM]]
define internal i32 @icmpSle64Bool(i64 %a, i64 %b) { define internal i32 @icmpSle64Bool(i64 %a, i64 %b) {
entry: entry:
%cmp = icmp sle i64 %a, %b %cmp = icmp sle i64 %a, %b
...@@ -1804,6 +1874,17 @@ entry: ...@@ -1804,6 +1874,17 @@ entry:
; ARM32: sbcs ; ARM32: sbcs
; ARM32: movge ; ARM32: movge
; MIPS32-LABEL: icmpSle64Bool
; MIPS32: xor [[T1:.*]],[[A_HI:.*]],[[B_HI:.*]]
; MIPS32: slt [[T2:.*]],[[B_HI]],[[A_HI]]
; MIPS32: xori [[T3:.*]],[[T2]],0x1
; MIPS32: sltu [[T4:.*]],{{.*}},{{.*}}
; MIPS32: xori [[T5:.*]],[[T4]],0x1
; MIPS32: movz [[T6:.*]],[[T5]],[[T1]]
; MIPS32-O2: move {{.*}},[[T3]]
; MIPS32-OM1: sw [[T3]],[[MEM:.*]]
; MIPS32-OM1: lb {{.*}},[[MEM]]
define internal i32 @icmpUle64Bool(i64 %a, i64 %b) { define internal i32 @icmpUle64Bool(i64 %a, i64 %b) {
entry: entry:
%cmp = icmp ule i64 %a, %b %cmp = icmp ule i64 %a, %b
...@@ -1830,6 +1911,17 @@ entry: ...@@ -1830,6 +1911,17 @@ entry:
; ARM32: cmpeq ; ARM32: cmpeq
; ARM32: movls ; ARM32: movls
; MIPS32-LABEL: icmpUle64Bool
; MIPS32: xor [[T1:.*]],[[A_HI:.*]],[[B_HI:.*]]
; MIPS32: sltu [[T2:.*]],[[B_HI]],[[A_HI]]
; MIPS32: xori [[T3:.*]],[[T2]],0x1
; MIPS32: sltu [[T4:.*]],{{.*}},{{.*}}
; MIPS32: xori [[T5:.*]],[[T4]],0x1
; MIPS32: movz [[T6:.*]],[[T5]],[[T1]]
; MIPS32-O2: move {{.*}},[[T3]]
; MIPS32-OM1: sw [[T3]],[[MEM:.*]]
; MIPS32-OM1: lb {{.*}},[[MEM]]
define internal i64 @load64(i32 %a) { define internal i64 @load64(i32 %a) {
entry: entry:
%__1 = inttoptr i32 %a to i64* %__1 = inttoptr i32 %a to i64*
......
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