1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-21 03:53:04 +02:00

[Hexagon] Adding compare byte/halfword reg-reg/reg-imm forms. Adding compare to general register reg-imm form.

llvm-svn: 224991
This commit is contained in:
Colin LeMahieu 2014-12-30 17:39:24 +00:00
parent 300c89d245
commit c9924ffc90
3 changed files with 146 additions and 52 deletions

View File

@ -128,63 +128,129 @@ def C4_cmplte : T_ALU32_3op_cmp<"!cmp.gt", 0b10, 1, 0>;
def C4_cmplteu : T_ALU32_3op_cmp<"!cmp.gtu", 0b11, 1, 0>; def C4_cmplteu : T_ALU32_3op_cmp<"!cmp.gtu", 0b11, 1, 0>;
} }
// Generate frame index addresses. // Pats for instruction selection.
let hasSideEffects = 0, isReMaterializable = 1,
isExtended = 1, opExtendable = 2, validSubTargets = HasV4SubT in
def TFR_FI_immext_V4 : ALU32_ri<(outs IntRegs:$dst),
(ins IntRegs:$src1, s32Imm:$offset),
"$dst = add($src1, ##$offset)",
[]>,
Requires<[HasV4T]>;
// Rd=cmp.eq(Rs,#s8) // A class to embed the usual comparison patfrags within a zext to i32.
let validSubTargets = HasV4SubT, isExtendable = 1, opExtendable = 2, // The seteq/setne frags use "lhs" and "rhs" as operands, so use the same
isExtentSigned = 1, opExtentBits = 8 in // names, or else the frag's "body" won't match the operands.
def V4_A4_rcmpeqi : ALU32_ri<(outs IntRegs:$Rd), class CmpInReg<PatFrag Op>
(ins IntRegs:$Rs, s8Ext:$s8), : PatFrag<(ops node:$lhs, node:$rhs),(i32 (zext (i1 Op.Fragment)))>;
"$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: T_cmp32_rr_pat<A4_rcmpeq, CmpInReg<seteq>, i32>;
def: T_cmp32_rr_pat<A4_rcmpneq, CmpInReg<setne>, i32>;
class T_CMP_rrbh<string mnemonic, bits<3> MinOp, bit IsComm>
: SInst<(outs PredRegs:$Pd), (ins IntRegs:$Rs, IntRegs:$Rt),
"$Pd = "#mnemonic#"($Rs, $Rt)", [], "", S_3op_tc_2early_SLOT23>,
ImmRegRel {
let validSubTargets = HasV4SubT;
let InputType = "reg";
let CextOpcode = mnemonic;
let isCompare = 1;
let isCommutable = IsComm;
let hasSideEffects = 0;
bits<2> Pd;
bits<5> Rs;
bits<5> Rt;
let IClass = 0b1100;
let Inst{27-21} = 0b0111110;
let Inst{20-16} = Rs;
let Inst{12-8} = Rt;
let Inst{7-5} = MinOp;
let Inst{1-0} = Pd;
}
let isCodeGenOnly = 0 in {
def A4_cmpbeq : T_CMP_rrbh<"cmpb.eq", 0b110, 1>;
def A4_cmpbgt : T_CMP_rrbh<"cmpb.gt", 0b010, 0>;
def A4_cmpbgtu : T_CMP_rrbh<"cmpb.gtu", 0b111, 0>;
def A4_cmpheq : T_CMP_rrbh<"cmph.eq", 0b011, 1>;
def A4_cmphgt : T_CMP_rrbh<"cmph.gt", 0b100, 0>;
def A4_cmphgtu : T_CMP_rrbh<"cmph.gtu", 0b101, 0>;
}
class T_CMP_ribh<string mnemonic, bits<2> MajOp, bit IsHalf, bit IsComm,
Operand ImmType, bit IsImmExt, bit IsImmSigned, int ImmBits>
: ALU64Inst<(outs PredRegs:$Pd), (ins IntRegs:$Rs, ImmType:$Imm),
"$Pd = "#mnemonic#"($Rs, #$Imm)", [], "", ALU64_tc_2early_SLOT23>,
ImmRegRel {
let validSubTargets = HasV4SubT;
let InputType = "imm";
let CextOpcode = mnemonic;
let isCompare = 1;
let isCommutable = IsComm;
let hasSideEffects = 0;
let isExtendable = IsImmExt;
let opExtendable = !if (IsImmExt, 2, 0);
let isExtentSigned = IsImmSigned;
let opExtentBits = ImmBits;
bits<2> Pd;
bits<5> Rs;
bits<8> Imm;
let IClass = 0b1101;
let Inst{27-24} = 0b1101;
let Inst{22-21} = MajOp;
let Inst{20-16} = Rs;
let Inst{12-5} = Imm;
let Inst{4} = 0b0;
let Inst{3} = IsHalf;
let Inst{1-0} = Pd;
}
let isCodeGenOnly = 0 in {
def A4_cmpbeqi : T_CMP_ribh<"cmpb.eq", 0b00, 0, 1, u8Imm, 0, 0, 8>;
def A4_cmpbgti : T_CMP_ribh<"cmpb.gt", 0b01, 0, 0, s8Imm, 0, 1, 8>;
def A4_cmpbgtui : T_CMP_ribh<"cmpb.gtu", 0b10, 0, 0, u7Ext, 1, 0, 7>;
def A4_cmpheqi : T_CMP_ribh<"cmph.eq", 0b00, 1, 1, s8Ext, 1, 1, 8>;
def A4_cmphgti : T_CMP_ribh<"cmph.gt", 0b01, 1, 0, s8Ext, 1, 1, 8>;
def A4_cmphgtui : T_CMP_ribh<"cmph.gtu", 0b10, 1, 0, u7Ext, 1, 0, 7>;
}
class T_RCMP_EQ_ri<string mnemonic, bit IsNeg>
: ALU32_ri<(outs IntRegs:$Rd), (ins IntRegs:$Rs, s8Ext:$s8),
"$Rd = "#mnemonic#"($Rs, #$s8)", [], "", ALU32_2op_tc_1_SLOT0123>,
ImmRegRel {
let validSubTargets = HasV4SubT;
let InputType = "imm";
let CextOpcode = !if (IsNeg, "!rcmp.eq", "rcmp.eq");
let isExtendable = 1;
let opExtendable = 2;
let isExtentSigned = 1;
let opExtentBits = 8;
let hasNewValue = 1;
bits<5> Rd;
bits<5> Rs;
bits<8> s8;
let IClass = 0b0111;
let Inst{27-24} = 0b0011;
let Inst{22} = 0b1;
let Inst{21} = IsNeg;
let Inst{20-16} = Rs;
let Inst{13} = 0b1;
let Inst{12-5} = s8;
let Inst{4-0} = Rd;
}
let isCodeGenOnly = 0 in {
def A4_rcmpeqi : T_RCMP_EQ_ri<"cmp.eq", 0>;
def A4_rcmpneqi : T_RCMP_EQ_ri<"!cmp.eq", 1>;
}
def: Pat<(i32 (zext (i1 (seteq (i32 IntRegs:$Rs), s8ExtPred:$s8)))),
(A4_rcmpeqi IntRegs:$Rs, s8ExtPred:$s8)>;
def: Pat<(i32 (zext (i1 (setne (i32 IntRegs:$Rs), s8ExtPred:$s8)))),
(A4_rcmpneqi IntRegs:$Rs, s8ExtPred:$s8)>;
// Preserve the S2_tstbit_r generation
def: Pat<(i32 (zext (i1 (setne (i32 (and (i32 (shl 1, (i32 IntRegs:$src2))), def: Pat<(i32 (zext (i1 (setne (i32 (and (i32 (shl 1, (i32 IntRegs:$src2))),
(i32 IntRegs:$src1))), 0)))), (i32 IntRegs:$src1))), 0)))),
(i32 (C2_muxii (i1 (S2_tstbit_r (i32 IntRegs:$src1), (i32 IntRegs:$src2))), (C2_muxii (S2_tstbit_r IntRegs:$src1, IntRegs:$src2), 1, 0)>;
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 - // ALU32 -

View File

@ -60,6 +60,10 @@
# CHECK: p3 = cmp.gtu(r21, r31) # CHECK: p3 = cmp.gtu(r21, r31)
0x13 0xdf 0x75 0xf2 0x13 0xdf 0x75 0xf2
# CHECK: p3 = !cmp.gtu(r21, r31) # CHECK: p3 = !cmp.gtu(r21, r31)
0xf1 0xe3 0x55 0x73
# CHECK: r17 = cmp.eq(r21, #31)
0xf1 0xe3 0x75 0x73
# CHECK: r17 = !cmp.eq(r21, #31)
0x11 0xdf 0x55 0xf3 0x11 0xdf 0x55 0xf3
# CHECK: r17 = cmp.eq(r21, r31) # CHECK: r17 = cmp.eq(r21, r31)
0x11 0xdf 0x75 0xf3 0x11 0xdf 0x75 0xf3

View File

@ -1,5 +1,29 @@
# RUN: llvm-mc --triple hexagon -disassemble < %s | FileCheck %s # RUN: llvm-mc --triple hexagon -disassemble < %s | FileCheck %s
0x43 0xd5 0xd1 0xc7
# CHECK: p3 = cmpb.gt(r17, r21)
0xc3 0xd5 0xd1 0xc7
# CHECK: p3 = cmpb.eq(r17, r21)
0xe3 0xd5 0xd1 0xc7
# CHECK: p3 = cmpb.gtu(r17, r21)
0xa3 0xc2 0x11 0xdd
# CHECK: p3 = cmpb.eq(r17, #21)
0xa3 0xc2 0x31 0xdd
# CHECK: p3 = cmpb.gt(r17, #21)
0xa3 0xc2 0x51 0xdd
# CHECK: p3 = cmpb.gtu(r17, #21)
0x63 0xd5 0xd1 0xc7
# CHECK: p3 = cmph.eq(r17, r21)
0x83 0xd5 0xd1 0xc7
# CHECK: p3 = cmph.gt(r17, r21)
0xa3 0xd5 0xd1 0xc7
# CHECK: p3 = cmph.gtu(r17, r21)
0xab 0xc2 0x11 0xdd
# CHECK: p3 = cmph.eq(r17, #21)
0xab 0xc2 0x31 0xdd
# CHECK: p3 = cmph.gt(r17, #21)
0xab 0xc2 0x51 0xdd
# CHECK: p3 = cmph.gtu(r17, #21)
0x03 0xde 0x94 0xd2 0x03 0xde 0x94 0xd2
# CHECK: p3 = cmp.eq(r21:20, r31:30) # CHECK: p3 = cmp.eq(r21:20, r31:30)
0x43 0xde 0x94 0xd2 0x43 0xde 0x94 0xd2