Hexagon: Add V4 compare instructions. Enable relationship mapping

for the existing instructions.

llvm-svn: 174389
This commit is contained in:
Jyotsna Verma 2013-02-05 16:42:24 +00:00
parent b81c922947
commit 6f635b5488
3 changed files with 220 additions and 16 deletions

View File

@ -251,6 +251,54 @@ def TFR_FI_immext_V4 : ALU32_ri<(outs IntRegs:$dst),
[]>,
Requires<[HasV4T]>;
// Rd=cmp.eq(Rs,#s8)
let validSubTargets = HasV4SubT, isExtendable = 1, opExtendable = 2,
isExtentSigned = 1, opExtentBits = 8 in
def V4_A4_rcmpeqi : ALU32_ri<(outs IntRegs:$Rd),
(ins IntRegs:$Rs, s8Ext:$s8),
"$Rd = cmp.eq($Rs, #$s8)",
[(set (i32 IntRegs:$Rd),
(i32 (zext (i1 (seteq (i32 IntRegs:$Rs),
s8ExtPred:$s8)))))]>,
Requires<[HasV4T]>;
// Preserve the TSTBIT generation
def : Pat <(i32 (zext (i1 (setne (i32 (and (i32 (shl 1, (i32 IntRegs:$src2))),
(i32 IntRegs:$src1))), 0)))),
(i32 (MUX_ii (i1 (TSTBIT_rr (i32 IntRegs:$src1), (i32 IntRegs:$src2))),
1, 0))>;
// Interfered with tstbit generation, above pattern preserves, see : tstbit.ll
// Rd=cmp.ne(Rs,#s8)
let validSubTargets = HasV4SubT, isExtendable = 1, opExtendable = 2,
isExtentSigned = 1, opExtentBits = 8 in
def V4_A4_rcmpneqi : ALU32_ri<(outs IntRegs:$Rd),
(ins IntRegs:$Rs, s8Ext:$s8),
"$Rd = !cmp.eq($Rs, #$s8)",
[(set (i32 IntRegs:$Rd),
(i32 (zext (i1 (setne (i32 IntRegs:$Rs),
s8ExtPred:$s8)))))]>,
Requires<[HasV4T]>;
// Rd=cmp.eq(Rs,Rt)
let validSubTargets = HasV4SubT in
def V4_A4_rcmpeq : ALU32_ri<(outs IntRegs:$Rd),
(ins IntRegs:$Rs, IntRegs:$Rt),
"$Rd = cmp.eq($Rs, $Rt)",
[(set (i32 IntRegs:$Rd),
(i32 (zext (i1 (seteq (i32 IntRegs:$Rs),
IntRegs:$Rt)))))]>,
Requires<[HasV4T]>;
// Rd=cmp.ne(Rs,Rt)
let validSubTargets = HasV4SubT in
def V4_A4_rcmpneq : ALU32_ri<(outs IntRegs:$Rd),
(ins IntRegs:$Rs, IntRegs:$Rt),
"$Rd = !cmp.eq($Rs, $Rt)",
[(set (i32 IntRegs:$Rd),
(i32 (zext (i1 (setne (i32 IntRegs:$Rs),
IntRegs:$Rt)))))]>,
Requires<[HasV4T]>;
//===----------------------------------------------------------------------===//
// ALU32 -
@ -3656,7 +3704,61 @@ def MEMb_ORr_MEM_V4 : MEMInst_V4<(outs),
// incorrect code for negative numbers.
// Pd=cmpb.eq(Rs,#u8)
let isCompare = 1 in
// p=!cmp.eq(r1,r2)
let isCompare = 1, validSubTargets = HasV4SubT in
def CMPnotEQ_rr : ALU32_rr<(outs PredRegs:$dst),
(ins IntRegs:$src1, IntRegs:$src2),
"$dst = !cmp.eq($src1, $src2)",
[(set (i1 PredRegs:$dst),
(setne (i32 IntRegs:$src1), (i32 IntRegs:$src2)))]>,
Requires<[HasV4T]>;
// p=!cmp.eq(r1,#s10)
let isCompare = 1, validSubTargets = HasV4SubT in
def CMPnotEQ_ri : ALU32_ri<(outs PredRegs:$dst),
(ins IntRegs:$src1, s10Ext:$src2),
"$dst = !cmp.eq($src1, #$src2)",
[(set (i1 PredRegs:$dst),
(setne (i32 IntRegs:$src1), s10ImmPred:$src2))]>,
Requires<[HasV4T]>;
// p=!cmp.gt(r1,r2)
let isCompare = 1, validSubTargets = HasV4SubT in
def CMPnotGT_rr : ALU32_rr<(outs PredRegs:$dst),
(ins IntRegs:$src1, IntRegs:$src2),
"$dst = !cmp.gt($src1, $src2)",
[(set (i1 PredRegs:$dst),
(not (setgt (i32 IntRegs:$src1), (i32 IntRegs:$src2))))]>,
Requires<[HasV4T]>;
// p=!cmp.gt(r1,#s10)
let isCompare = 1, validSubTargets = HasV4SubT in
def CMPnotGT_ri : ALU32_ri<(outs PredRegs:$dst),
(ins IntRegs:$src1, s10Ext:$src2),
"$dst = !cmp.gt($src1, #$src2)",
[(set (i1 PredRegs:$dst),
(not (setgt (i32 IntRegs:$src1), s10ImmPred:$src2)))]>,
Requires<[HasV4T]>;
// p=!cmp.gtu(r1,r2)
let isCompare = 1, validSubTargets = HasV4SubT in
def CMPnotGTU_rr : ALU32_rr<(outs PredRegs:$dst),
(ins IntRegs:$src1, IntRegs:$src2),
"$dst = !cmp.gtu($src1, $src2)",
[(set (i1 PredRegs:$dst),
(not (setugt (i32 IntRegs:$src1), (i32 IntRegs:$src2))))]>,
Requires<[HasV4T]>;
// p=!cmp.gtu(r1,#u9)
let isCompare = 1, validSubTargets = HasV4SubT in
def CMPnotGTU_ri : ALU32_ri<(outs PredRegs:$dst),
(ins IntRegs:$src1, u9Ext:$src2),
"$dst = !cmp.gtu($src1, #$src2)",
[(set (i1 PredRegs:$dst),
(not (setugt (i32 IntRegs:$src1), u9ImmPred:$src2)))]>,
Requires<[HasV4T]>;
let isCompare = 1, validSubTargets = HasV4SubT in
def CMPbEQri_V4 : MInst<(outs PredRegs:$dst),
(ins IntRegs:$src1, u8Imm:$src2),
"$dst = cmpb.eq($src1, #$src2)",
@ -3664,6 +3766,12 @@ def CMPbEQri_V4 : MInst<(outs PredRegs:$dst),
(seteq (and (i32 IntRegs:$src1), 255), u8ImmPred:$src2))]>,
Requires<[HasV4T]>;
def : Pat <(brcond (i1 (setne (and (i32 IntRegs:$src1), 255), u8ImmPred:$src2)),
bb:$offset),
(JMP_cNot (CMPbEQri_V4 (i32 IntRegs:$src1), u8ImmPred:$src2),
bb:$offset)>,
Requires<[HasV4T]>;
// Pd=cmpb.eq(Rs,Rt)
let isCompare = 1, validSubTargets = HasV4SubT in
def CMPbEQrr_ubub_V4 : MInst<(outs PredRegs:$dst),
@ -3705,20 +3813,21 @@ def CMPbGTUri_V4 : MInst<(outs PredRegs:$dst),
Requires<[HasV4T]>, ImmRegRel;
// Pd=cmpb.gtu(Rs,Rt)
let isCompare = 1 in
let isCompare = 1, validSubTargets = HasV4SubT, CextOpcode = "CMPbGTU",
InputType = "reg" in
def CMPbGTUrr_V4 : MInst<(outs PredRegs:$dst),
(ins IntRegs:$src1, IntRegs:$src2),
"$dst = cmpb.gtu($src1, $src2)",
[(set (i1 PredRegs:$dst), (setugt (and (i32 IntRegs:$src1), 255),
(and (i32 IntRegs:$src2), 255)))]>,
Requires<[HasV4T]>;
Requires<[HasV4T]>, ImmRegRel;
// Following instruction is not being extended as it results into the incorrect
// code for negative numbers.
// Signed half compare(.eq) ri.
// Pd=cmph.eq(Rs,#s8)
let isCompare = 1 in
let isCompare = 1, validSubTargets = HasV4SubT in
def CMPhEQri_V4 : MInst<(outs PredRegs:$dst),
(ins IntRegs:$src1, s8Imm:$src2),
"$dst = cmph.eq($src1, #$src2)",
@ -3732,7 +3841,7 @@ def CMPhEQri_V4 : MInst<(outs PredRegs:$dst),
// r0=and(r0,#0xffff)
// p0=cmp.eq(r0,#0)
// Pd=cmph.eq(Rs,Rt)
let isCompare = 1 in
let isCompare = 1, validSubTargets = HasV4SubT in
def CMPhEQrr_xor_V4 : MInst<(outs PredRegs:$dst),
(ins IntRegs:$src1, IntRegs:$src2),
"$dst = cmph.eq($src1, $src2)",
@ -3747,7 +3856,7 @@ def CMPhEQrr_xor_V4 : MInst<(outs PredRegs:$dst),
// r1=asl(r1,16)
// p0=cmp.eq(r0,r1)
// Pd=cmph.eq(Rs,Rt)
let isCompare = 1 in
let isCompare = 1, validSubTargets = HasV4SubT in
def CMPhEQrr_shl_V4 : MInst<(outs PredRegs:$dst),
(ins IntRegs:$src1, IntRegs:$src2),
"$dst = cmph.eq($src1, $src2)",
@ -3761,19 +3870,20 @@ used in the cmph.gt instruction.
// Signed half compare(.gt) ri.
// Pd=cmph.gt(Rs,#s8)
let isCompare = 1 in
let isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 8,
isCompare = 1, validSubTargets = HasV4SubT in
def CMPhGTri_V4 : MInst<(outs PredRegs:$dst),
(ins IntRegs:$src1, s8Imm:$src2),
(ins IntRegs:$src1, s8Ext:$src2),
"$dst = cmph.gt($src1, #$src2)",
[(set (i1 PredRegs:$dst),
(setgt (shl (i32 IntRegs:$src1), (i32 16)),
s8ImmPred:$src2))]>,
s8ExtPred:$src2))]>,
Requires<[HasV4T]>;
*/
// Signed half compare(.gt) rr.
// Pd=cmph.gt(Rs,Rt)
let isCompare = 1 in
let isCompare = 1, validSubTargets = HasV4SubT in
def CMPhGTrr_shl_V4 : MInst<(outs PredRegs:$dst),
(ins IntRegs:$src1, IntRegs:$src2),
"$dst = cmph.gt($src1, $src2)",
@ -3784,24 +3894,41 @@ def CMPhGTrr_shl_V4 : MInst<(outs PredRegs:$dst),
// Unsigned half compare rr (.gtu).
// Pd=cmph.gtu(Rs,Rt)
let isCompare = 1 in
let isCompare = 1, validSubTargets = HasV4SubT, CextOpcode = "CMPhGTU",
InputType = "reg" in
def CMPhGTUrr_V4 : MInst<(outs PredRegs:$dst),
(ins IntRegs:$src1, IntRegs:$src2),
"$dst = cmph.gtu($src1, $src2)",
[(set (i1 PredRegs:$dst),
(setugt (and (i32 IntRegs:$src1), 65535),
(and (i32 IntRegs:$src2), 65535)))]>,
Requires<[HasV4T]>;
Requires<[HasV4T]>, ImmRegRel;
// Unsigned half compare ri (.gtu).
// Pd=cmph.gtu(Rs,#u7)
let isCompare = 1 in
let isExtendable = 1, opExtendable = 2, isExtentSigned = 0, opExtentBits = 7,
isCompare = 1, validSubTargets = HasV4SubT, CextOpcode = "CMPhGTU",
InputType = "imm" in
def CMPhGTUri_V4 : MInst<(outs PredRegs:$dst),
(ins IntRegs:$src1, u7Imm:$src2),
(ins IntRegs:$src1, u7Ext:$src2),
"$dst = cmph.gtu($src1, #$src2)",
[(set (i1 PredRegs:$dst), (setugt (and (i32 IntRegs:$src1), 65535),
u7ImmPred:$src2))]>,
Requires<[HasV4T]>;
u7ExtPred:$src2))]>,
Requires<[HasV4T]>, ImmRegRel;
let validSubTargets = HasV4SubT in
def NTSTBIT_rr : SInst<(outs PredRegs:$dst), (ins IntRegs:$src1, IntRegs:$src2),
"$dst = !tstbit($src1, $src2)",
[(set (i1 PredRegs:$dst),
(seteq (and (shl 1, (i32 IntRegs:$src2)), (i32 IntRegs:$src1)), 0))]>,
Requires<[HasV4T]>;
let validSubTargets = HasV4SubT in
def NTSTBIT_ri : SInst<(outs PredRegs:$dst), (ins IntRegs:$src1, u5Imm:$src2),
"$dst = !tstbit($src1, $src2)",
[(set (i1 PredRegs:$dst),
(seteq (and (shl 1, u5ImmPred:$src2), (i32 IntRegs:$src1)), 0))]>,
Requires<[HasV4T]>;
//===----------------------------------------------------------------------===//
// XTYPE/PRED -

View File

@ -0,0 +1,34 @@
; RUN: llc -march=hexagon -mcpu=hexagonv4 < %s | FileCheck %s
; Check that we generate compare to general register.
define i32 @compare1(i32 %a) nounwind {
; CHECK: r{{[0-9]+}}{{ *}}={{ *}}cmp.eq(r{{[0-9]+}},{{ *}}#120)
entry:
%cmp = icmp eq i32 %a, 120
%conv = zext i1 %cmp to i32
ret i32 %conv
}
define i32 @compare2(i32 %a) nounwind readnone {
; CHECK: r{{[0-9]+}}{{ *}}={{ *}}!cmp.eq(r{{[0-9]+}},{{ *}}#120)
entry:
%cmp = icmp ne i32 %a, 120
%conv = zext i1 %cmp to i32
ret i32 %conv
}
define i32 @compare3(i32 %a, i32 %b) nounwind readnone {
; CHECK: r{{[0-9]+}}{{ *}}={{ *}}cmp.eq(r{{[0-9]+}},{{ *}}r{{[0-9]+}})
entry:
%cmp = icmp eq i32 %a, %b
%conv = zext i1 %cmp to i32
ret i32 %conv
}
define i32 @compare4(i32 %a, i32 %b) nounwind readnone {
; CHECK: r{{[0-9]+}}{{ *}}={{ *}}!cmp.eq(r{{[0-9]+}},{{ *}}r{{[0-9]+}})
entry:
%cmp = icmp ne i32 %a, %b
%conv = zext i1 %cmp to i32
ret i32 %conv
}

View File

@ -0,0 +1,43 @@
; RUN: llc -march=hexagon -mcpu=hexagonv4 < %s | FileCheck %s
; Check that we generate compare to predicate register.
define i32 @compare1(i32 %a, i32 %b) nounwind {
; CHECK: p{{[0-3]}}{{ *}}={{ *}}!cmp.eq(r{{[0-9]+}},{{ *}}r{{[0-9]+}})
entry:
%cmp = icmp ne i32 %a, %b
%add = add nsw i32 %a, %b
%sub = sub nsw i32 %a, %b
%add.sub = select i1 %cmp, i32 %add, i32 %sub
ret i32 %add.sub
}
define i32 @compare2(i32 %a) nounwind {
; CHECK: p{{[0-3]}}{{ *}}={{ *}}!cmp.eq(r{{[0-9]+}},{{ *}}#10)
entry:
%cmp = icmp ne i32 %a, 10
%add = add nsw i32 %a, 10
%sub = sub nsw i32 %a, 10
%add.sub = select i1 %cmp, i32 %add, i32 %sub
ret i32 %add.sub
}
define i32 @compare3(i32 %a, i32 %b) nounwind {
; CHECK: p{{[0-3]}}{{ *}}={{ *}}cmp.gt(r{{[0-9]+}},{{ *}}r{{[0-9]+}})
entry:
%cmp = icmp sgt i32 %a, %b
%sub = sub nsw i32 %a, %b
%add = add nsw i32 %a, %b
%sub.add = select i1 %cmp, i32 %sub, i32 %add
ret i32 %sub.add
}
define i32 @compare4(i32 %a) nounwind {
; CHECK: p{{[0-3]}}{{ *}}={{ *}}cmp.gt(r{{[0-9]+}},{{ *}}#10)
entry:
%cmp = icmp sgt i32 %a, 10
%sub = sub nsw i32 %a, 10
%add = add nsw i32 %a, 10
%sub.add = select i1 %cmp, i32 %sub, i32 %add
ret i32 %sub.add
}