mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-04-06 09:44:39 +00:00
Hexagon: Remove assembler mapped instruction definitions.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@180133 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
fa799112dd
commit
47089c91ae
@ -541,12 +541,6 @@ CountValue *HexagonHardwareLoops::getLoopTripCount(MachineLoop *L,
|
||||
case Hexagon::CMPEQrr:
|
||||
Cmp = !Negated ? Comparison::EQ : Comparison::NE;
|
||||
break;
|
||||
case Hexagon::CMPLTrr:
|
||||
Cmp = !Negated ? Comparison::LTs : Comparison::GEs;
|
||||
break;
|
||||
case Hexagon::CMPLTUrr:
|
||||
Cmp = !Negated ? Comparison::LTu : Comparison::GEu;
|
||||
break;
|
||||
case Hexagon::CMPGTUri:
|
||||
case Hexagon::CMPGTUrr:
|
||||
Cmp = !Negated ? Comparison::GTu : Comparison::LEu;
|
||||
|
@ -160,6 +160,17 @@ inline SDValue XformU7ToU7M1Imm(signed Imm) {
|
||||
return CurDAG->getTargetConstant(Imm - 1, MVT::i8);
|
||||
}
|
||||
|
||||
// XformS8ToS8M1Imm - Return a target constant decremented by 1.
|
||||
inline SDValue XformSToSM1Imm(signed Imm) {
|
||||
return CurDAG->getTargetConstant(Imm - 1, MVT::i32);
|
||||
}
|
||||
|
||||
// XformU8ToU8M1Imm - Return a target constant decremented by 1.
|
||||
inline SDValue XformUToUM1Imm(unsigned Imm) {
|
||||
assert((Imm >= 1) && "Cannot decrement unsigned int less than 1");
|
||||
return CurDAG->getTargetConstant(Imm - 1, MVT::i32);
|
||||
}
|
||||
|
||||
// Include the pieces autogenerated from the target description.
|
||||
#include "HexagonGenDAGISel.inc"
|
||||
};
|
||||
|
@ -325,8 +325,6 @@ bool HexagonInstrInfo::analyzeCompare(const MachineInstr *MI,
|
||||
case Hexagon::CMPGTUrr:
|
||||
case Hexagon::CMPGTri:
|
||||
case Hexagon::CMPGTrr:
|
||||
case Hexagon::CMPLTUrr:
|
||||
case Hexagon::CMPLTrr:
|
||||
SrcReg = MI->getOperand(1).getReg();
|
||||
Mask = ~0;
|
||||
break;
|
||||
@ -366,8 +364,6 @@ bool HexagonInstrInfo::analyzeCompare(const MachineInstr *MI,
|
||||
case Hexagon::CMPhEQrr_xor_V4:
|
||||
case Hexagon::CMPhGTUrr_V4:
|
||||
case Hexagon::CMPhGTrr_shl_V4:
|
||||
case Hexagon::CMPLTUrr:
|
||||
case Hexagon::CMPLTrr:
|
||||
SrcReg2 = MI->getOperand(2).getReg();
|
||||
return true;
|
||||
|
||||
@ -2114,14 +2110,10 @@ bool HexagonInstrInfo::isNewValueJumpCandidate(const MachineInstr *MI) const {
|
||||
default: return false;
|
||||
case Hexagon::CMPEQrr:
|
||||
case Hexagon::CMPEQri:
|
||||
case Hexagon::CMPLTrr:
|
||||
case Hexagon::CMPGTrr:
|
||||
case Hexagon::CMPGTri:
|
||||
case Hexagon::CMPLTUrr:
|
||||
case Hexagon::CMPGTUrr:
|
||||
case Hexagon::CMPGTUri:
|
||||
case Hexagon::CMPGEri:
|
||||
case Hexagon::CMPGEUri:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -14,6 +14,8 @@
|
||||
include "HexagonInstrFormats.td"
|
||||
include "HexagonOperands.td"
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// Multi-class for logical operators.
|
||||
multiclass ALU32_rr_ri<string OpcStr, SDNode OpNode> {
|
||||
def rr : ALU32_rr<(outs IntRegs:$dst), (ins IntRegs:$b, IntRegs:$c),
|
||||
@ -34,12 +36,6 @@ multiclass CMP64_rr<string OpcStr, PatFrag OpNode> {
|
||||
[(set (i1 PredRegs:$dst),
|
||||
(OpNode (i64 DoubleRegs:$b), (i64 DoubleRegs:$c)))]>;
|
||||
}
|
||||
multiclass CMP32_rr<string OpcStr, PatFrag OpNode> {
|
||||
def rr : ALU32_rr<(outs PredRegs:$dst), (ins IntRegs:$b, IntRegs:$c),
|
||||
!strconcat("$dst = ", !strconcat(OpcStr, "($b, $c)")),
|
||||
[(set (i1 PredRegs:$dst),
|
||||
(OpNode (i32 IntRegs:$b), (i32 IntRegs:$c)))]>;
|
||||
}
|
||||
|
||||
multiclass CMP32_rr_ri_s10<string OpcStr, string CextOp, PatFrag OpNode> {
|
||||
let CextOpcode = CextOp in {
|
||||
@ -75,14 +71,6 @@ multiclass CMP32_rr_ri_u9<string OpcStr, string CextOp, PatFrag OpNode> {
|
||||
}
|
||||
}
|
||||
|
||||
multiclass CMP32_ri_u8<string OpcStr, PatFrag OpNode> {
|
||||
let isExtendable = 1, opExtendable = 2, isExtentSigned = 0, opExtentBits = 8 in
|
||||
def ri : ALU32_ri<(outs PredRegs:$dst), (ins IntRegs:$b, u8Ext:$c),
|
||||
!strconcat("$dst = ", !strconcat(OpcStr, "($b, #$c)")),
|
||||
[(set (i1 PredRegs:$dst), (OpNode (i32 IntRegs:$b),
|
||||
u8ExtPred:$c))]>;
|
||||
}
|
||||
|
||||
multiclass CMP32_ri_s8<string OpcStr, PatFrag OpNode> {
|
||||
let isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 8 in
|
||||
def ri : ALU32_ri<(outs PredRegs:$dst), (ins IntRegs:$b, s8Ext:$c),
|
||||
@ -188,11 +176,6 @@ def OR_ri : ALU32_ri<(outs IntRegs:$dst),
|
||||
[(set (i32 IntRegs:$dst), (or (i32 IntRegs:$src1),
|
||||
s10ExtPred:$src2))]>, ImmRegRel;
|
||||
|
||||
def NOT_rr : ALU32_rr<(outs IntRegs:$dst),
|
||||
(ins IntRegs:$src1),
|
||||
"$dst = not($src1)",
|
||||
[(set (i32 IntRegs:$dst), (not (i32 IntRegs:$src1)))]>;
|
||||
|
||||
let isExtendable = 1, opExtendable = 2, isExtentSigned = 1, opExtentBits = 10,
|
||||
InputType = "imm", CextOpcode = "AND" in
|
||||
def AND_ri : ALU32_ri<(outs IntRegs:$dst),
|
||||
@ -200,10 +183,7 @@ def AND_ri : ALU32_ri<(outs IntRegs:$dst),
|
||||
"$dst = and($src1, #$src2)",
|
||||
[(set (i32 IntRegs:$dst), (and (i32 IntRegs:$src1),
|
||||
s10ExtPred:$src2))]>, ImmRegRel;
|
||||
// Negate.
|
||||
def NEG : ALU32_rr<(outs IntRegs:$dst), (ins IntRegs:$src1),
|
||||
"$dst = neg($src1)",
|
||||
[(set (i32 IntRegs:$dst), (ineg (i32 IntRegs:$src1)))]>;
|
||||
|
||||
// Nop.
|
||||
let neverHasSideEffects = 1 in
|
||||
def NOP : ALU32_rr<(outs), (ins),
|
||||
@ -219,6 +199,12 @@ def SUB_ri : ALU32_ri<(outs IntRegs:$dst),
|
||||
[(set IntRegs:$dst, (sub s10ExtPred:$src1, IntRegs:$src2))]>,
|
||||
ImmRegRel;
|
||||
|
||||
// Rd = not(Rs) gets mapped to Rd=sub(#-1, Rs).
|
||||
def : Pat<(not (i32 IntRegs:$src1)),
|
||||
(SUB_ri -1, (i32 IntRegs:$src1))>;
|
||||
|
||||
// Rd = neg(Rs) gets mapped to Rd=sub(#0, Rs).
|
||||
// Pattern definition for 'neg' was not necessary.
|
||||
|
||||
multiclass TFR_Pred<bit PredNot> {
|
||||
let isPredicatedFalse = PredNot in {
|
||||
@ -535,11 +521,21 @@ def COMBINE_rr_cdnNotPt : ALU32_rr<(outs DoubleRegs:$dst),
|
||||
// Compare.
|
||||
defm CMPGTU : CMP32_rr_ri_u9<"cmp.gtu", "CMPGTU", setugt>, ImmRegRel;
|
||||
defm CMPGT : CMP32_rr_ri_s10<"cmp.gt", "CMPGT", setgt>, ImmRegRel;
|
||||
defm CMPLT : CMP32_rr<"cmp.lt", setlt>;
|
||||
defm CMPLTU : CMP32_rr<"cmp.ltu", setult>;
|
||||
defm CMPEQ : CMP32_rr_ri_s10<"cmp.eq", "CMPEQ", seteq>, ImmRegRel;
|
||||
defm CMPGE : CMP32_ri_s8<"cmp.ge", setge>;
|
||||
defm CMPGEU : CMP32_ri_u8<"cmp.geu", setuge>;
|
||||
|
||||
// SDNode for converting immediate C to C-1.
|
||||
def DEC_CONST_SIGNED : SDNodeXForm<imm, [{
|
||||
// Return the byte immediate const-1 as an SDNode.
|
||||
int32_t imm = N->getSExtValue();
|
||||
return XformSToSM1Imm(imm);
|
||||
}]>;
|
||||
|
||||
// SDNode for converting immediate C to C-1.
|
||||
def DEC_CONST_UNSIGNED : SDNodeXForm<imm, [{
|
||||
// Return the byte immediate const-1 as an SDNode.
|
||||
uint32_t imm = N->getZExtValue();
|
||||
return XformUToUM1Imm(imm);
|
||||
}]>;
|
||||
|
||||
def CTLZ_rr : SInst<(outs IntRegs:$dst), (ins IntRegs:$src1),
|
||||
"$dst = cl0($src1)",
|
||||
@ -2132,10 +2128,11 @@ def : Pat <(add (i1 PredRegs:$src1), -1),
|
||||
|
||||
// Map from p0 = setlt(r0, r1) r2 = mux(p0, r3, r4) =>
|
||||
// p0 = cmp.lt(r0, r1), r0 = mux(p0, r2, r1).
|
||||
// cmp.lt(r0, r1) -> cmp.gt(r1, r0)
|
||||
def : Pat <(select (i1 (setlt (i32 IntRegs:$src1), (i32 IntRegs:$src2))),
|
||||
(i32 IntRegs:$src3),
|
||||
(i32 IntRegs:$src4)),
|
||||
(i32 (TFR_condset_rr (CMPLTrr (i32 IntRegs:$src1), (i32 IntRegs:$src2)),
|
||||
(i32 (TFR_condset_rr (CMPGTrr (i32 IntRegs:$src2), (i32 IntRegs:$src1)),
|
||||
(i32 IntRegs:$src4), (i32 IntRegs:$src3)))>,
|
||||
Requires<[HasV2TOnly]>;
|
||||
|
||||
@ -2153,16 +2150,16 @@ def : Pat <(select (not (i1 PredRegs:$src1)), s12ImmPred:$src2,
|
||||
|
||||
// Map from p0 = pnot(p0); r0 = mux(p0, r1, #i)
|
||||
// => r0 = TFR_condset_ir(p0, #i, r1)
|
||||
def : Pat <(select (not PredRegs:$src1), IntRegs:$src2, s12ImmPred:$src3),
|
||||
def : Pat <(select (not (i1 PredRegs:$src1)), IntRegs:$src2, s12ImmPred:$src3),
|
||||
(i32 (TFR_condset_ir (i1 PredRegs:$src1), s12ImmPred:$src3,
|
||||
(i32 IntRegs:$src2)))>;
|
||||
|
||||
// Map from p0 = pnot(p0); if (p0) jump => if (!p0) jump.
|
||||
def : Pat <(brcond (not PredRegs:$src1), bb:$offset),
|
||||
def : Pat <(brcond (not (i1 PredRegs:$src1)), bb:$offset),
|
||||
(JMP_cNot (i1 PredRegs:$src1), bb:$offset)>;
|
||||
|
||||
// Map from p2 = pnot(p2); p1 = and(p0, p2) => p1 = and(p0, !p2).
|
||||
def : Pat <(and PredRegs:$src1, (not PredRegs:$src2)),
|
||||
def : Pat <(and (i1 PredRegs:$src1), (not (i1 PredRegs:$src2))),
|
||||
(i1 (AND_pnotp (i1 PredRegs:$src1), (i1 PredRegs:$src2)))>;
|
||||
|
||||
// Map from i1 loads to 32 bits. This assumes that the i1* is byte aligned.
|
||||
@ -2201,13 +2198,16 @@ def : Pat <(brcond (i1 (setne (i1 PredRegs:$src1), (i1 -1))), bb:$offset),
|
||||
def : Pat <(brcond (i1 (setne (i1 PredRegs:$src1), (i1 0))), bb:$offset),
|
||||
(JMP_c (i1 PredRegs:$src1), bb:$offset)>;
|
||||
|
||||
// cmp.lt(Rs, Imm) -> !cmp.ge(Rs, Imm) -> !cmp.gt(Rs, Imm-1)
|
||||
def : Pat <(brcond (i1 (setlt (i32 IntRegs:$src1), s8ImmPred:$src2)),
|
||||
bb:$offset),
|
||||
(JMP_cNot (CMPGEri (i32 IntRegs:$src1), s8ImmPred:$src2), bb:$offset)>;
|
||||
(JMP_cNot (CMPGTri (i32 IntRegs:$src1),
|
||||
(DEC_CONST_SIGNED s8ImmPred:$src2)), bb:$offset)>;
|
||||
|
||||
// cmp.lt(r0, r1) -> cmp.gt(r1, r0)
|
||||
def : Pat <(brcond (i1 (setlt (i32 IntRegs:$src1), (i32 IntRegs:$src2))),
|
||||
bb:$offset),
|
||||
(JMP_c (CMPLTrr (i32 IntRegs:$src1), (i32 IntRegs:$src2)), bb:$offset)>;
|
||||
(JMP_c (CMPGTrr (i32 IntRegs:$src2), (i32 IntRegs:$src1)), bb:$offset)>;
|
||||
|
||||
def : Pat <(brcond (i1 (setuge (i64 DoubleRegs:$src1), (i64 DoubleRegs:$src2))),
|
||||
bb:$offset),
|
||||
@ -2299,8 +2299,8 @@ def : Pat<(i64 (anyext (i32 IntRegs:$src1))),
|
||||
|
||||
// Map cmple -> cmpgt.
|
||||
// rs <= rt -> !(rs > rt).
|
||||
def : Pat<(i1 (setle (i32 IntRegs:$src1), s10ImmPred:$src2)),
|
||||
(i1 (NOT_p (CMPGTri (i32 IntRegs:$src1), s10ImmPred:$src2)))>;
|
||||
def : Pat<(i1 (setle (i32 IntRegs:$src1), s10ExtPred:$src2)),
|
||||
(i1 (NOT_p (CMPGTri (i32 IntRegs:$src1), s10ExtPred:$src2)))>;
|
||||
|
||||
// rs <= rt -> !(rs > rt).
|
||||
def : Pat<(i1 (setle (i32 IntRegs:$src1), (i32 IntRegs:$src2))),
|
||||
@ -2313,8 +2313,8 @@ def : Pat<(i1 (setle (i64 DoubleRegs:$src1), (i64 DoubleRegs:$src2))),
|
||||
// Map cmpne -> cmpeq.
|
||||
// Hexagon_TODO: We should improve on this.
|
||||
// rs != rt -> !(rs == rt).
|
||||
def : Pat <(i1 (setne (i32 IntRegs:$src1), s10ImmPred:$src2)),
|
||||
(i1 (NOT_p(i1 (CMPEQri (i32 IntRegs:$src1), s10ImmPred:$src2))))>;
|
||||
def : Pat <(i1 (setne (i32 IntRegs:$src1), s10ExtPred:$src2)),
|
||||
(i1 (NOT_p(i1 (CMPEQri (i32 IntRegs:$src1), s10ExtPred:$src2))))>;
|
||||
|
||||
// Map cmpne(Rs) -> !cmpeqe(Rs).
|
||||
// rs != rt -> !(rs == rt).
|
||||
@ -2336,8 +2336,9 @@ def : Pat <(i1 (setne (i64 DoubleRegs:$src1), (i64 DoubleRegs:$src2))),
|
||||
def : Pat <(i1 (setge (i32 IntRegs:$src1), (i32 IntRegs:$src2))),
|
||||
(i1 (NOT_p (i1 (CMPGTrr (i32 IntRegs:$src2), (i32 IntRegs:$src1)))))>;
|
||||
|
||||
def : Pat <(i1 (setge (i32 IntRegs:$src1), s8ImmPred:$src2)),
|
||||
(i1 (CMPGEri (i32 IntRegs:$src1), s8ImmPred:$src2))>;
|
||||
// cmpge(Rs, Imm) -> cmpgt(Rs, Imm-1)
|
||||
def : Pat <(i1 (setge (i32 IntRegs:$src1), s8ExtPred:$src2)),
|
||||
(i1 (CMPGTri (i32 IntRegs:$src1), (DEC_CONST_SIGNED s8ExtPred:$src2)))>;
|
||||
|
||||
// Map cmpge(Rss, Rtt) -> !cmpgt(Rtt, Rss).
|
||||
// rss >= rtt -> !(rtt > rss).
|
||||
@ -2346,9 +2347,10 @@ def : Pat <(i1 (setge (i64 DoubleRegs:$src1), (i64 DoubleRegs:$src2))),
|
||||
(i64 DoubleRegs:$src1)))))>;
|
||||
|
||||
// Map cmplt(Rs, Imm) -> !cmpge(Rs, Imm).
|
||||
// !cmpge(Rs, Imm) -> !cmpgt(Rs, Imm-1).
|
||||
// rs < rt -> !(rs >= rt).
|
||||
def : Pat <(i1 (setlt (i32 IntRegs:$src1), s8ImmPred:$src2)),
|
||||
(i1 (NOT_p (CMPGEri (i32 IntRegs:$src1), s8ImmPred:$src2)))>;
|
||||
def : Pat <(i1 (setlt (i32 IntRegs:$src1), s8ExtPred:$src2)),
|
||||
(i1 (NOT_p (CMPGTri (i32 IntRegs:$src1), (DEC_CONST_SIGNED s8ExtPred:$src2))))>;
|
||||
|
||||
// Map cmplt(Rs, Rt) -> cmpgt(Rt, Rs).
|
||||
// rs < rt -> rt > rs.
|
||||
@ -2372,13 +2374,17 @@ def : Pat <(i1 (setult (i32 IntRegs:$src1), (i32 IntRegs:$src2))),
|
||||
def : Pat <(i1 (setult (i64 DoubleRegs:$src1), (i64 DoubleRegs:$src2))),
|
||||
(i1 (CMPGTU64rr (i64 DoubleRegs:$src2), (i64 DoubleRegs:$src1)))>;
|
||||
|
||||
// Generate cmpgeu(Rs, #u8)
|
||||
def : Pat <(i1 (setuge (i32 IntRegs:$src1), u8ImmPred:$src2)),
|
||||
(i1 (CMPGEUri (i32 IntRegs:$src1), u8ImmPred:$src2))>;
|
||||
// Generate cmpgeu(Rs, #0) -> cmpeq(Rs, Rs)
|
||||
def : Pat <(i1 (setuge (i32 IntRegs:$src1), 0)),
|
||||
(i1 (CMPEQrr (i32 IntRegs:$src1), (i32 IntRegs:$src1)))>;
|
||||
|
||||
// Generate cmpgeu(Rs, #u8) -> cmpgtu(Rs, #u8 -1)
|
||||
def : Pat <(i1 (setuge (i32 IntRegs:$src1), u8ExtPred:$src2)),
|
||||
(i1 (CMPGTUri (i32 IntRegs:$src1), (DEC_CONST_UNSIGNED u8ExtPred:$src2)))>;
|
||||
|
||||
// Generate cmpgtu(Rs, #u9)
|
||||
def : Pat <(i1 (setugt (i32 IntRegs:$src1), u9ImmPred:$src2)),
|
||||
(i1 (CMPGTUri (i32 IntRegs:$src1), u9ImmPred:$src2))>;
|
||||
def : Pat <(i1 (setugt (i32 IntRegs:$src1), u9ExtPred:$src2)),
|
||||
(i1 (CMPGTUri (i32 IntRegs:$src1), u9ExtPred:$src2))>;
|
||||
|
||||
// Map from Rs >= Rt -> !(Rt > Rs).
|
||||
// rs >= rt -> !(rt > rs).
|
||||
@ -2390,7 +2396,7 @@ def : Pat <(i1 (setuge (i32 IntRegs:$src1), (i32 IntRegs:$src2))),
|
||||
def : Pat <(i1 (setuge (i64 DoubleRegs:$src1), (i64 DoubleRegs:$src2))),
|
||||
(i1 (NOT_p (CMPGTU64rr (i64 DoubleRegs:$src2), (i64 DoubleRegs:$src1))))>;
|
||||
|
||||
// Map from cmpleu(Rs, Rs) -> !cmpgtu(Rs, Rs).
|
||||
// Map from cmpleu(Rs, Rt) -> !cmpgtu(Rs, Rt).
|
||||
// Map from (Rs <= Rt) -> !(Rs > Rt).
|
||||
def : Pat <(i1 (setule (i32 IntRegs:$src1), (i32 IntRegs:$src2))),
|
||||
(i1 (NOT_p (CMPGTUrr (i32 IntRegs:$src1), (i32 IntRegs:$src2))))>;
|
||||
|
@ -208,14 +208,10 @@ static bool canCompareBeNewValueJump(const HexagonInstrInfo *QII,
|
||||
// range specified by the arch.
|
||||
if (!secondReg) {
|
||||
int64_t v = MI->getOperand(2).getImm();
|
||||
if (MI->getOpcode() == Hexagon::CMPGEri ||
|
||||
(MI->getOpcode() == Hexagon::CMPGEUri && v > 0))
|
||||
--v;
|
||||
|
||||
if (!(isUInt<5>(v) ||
|
||||
((MI->getOpcode() == Hexagon::CMPEQri ||
|
||||
MI->getOpcode() == Hexagon::CMPGTri ||
|
||||
MI->getOpcode() == Hexagon::CMPGEri) &&
|
||||
MI->getOpcode() == Hexagon::CMPGTri) &&
|
||||
(v == -1))))
|
||||
return false;
|
||||
}
|
||||
@ -284,7 +280,6 @@ static unsigned getNewValueJumpOpcode(const MachineInstr *MI, int reg,
|
||||
return Hexagon::JMP_EQriPtneg_nv_V4;
|
||||
}
|
||||
|
||||
case Hexagon::CMPLTrr:
|
||||
case Hexagon::CMPGTrr: {
|
||||
if (secondRegNewified)
|
||||
return Hexagon::JMP_GTrrdnPt_nv_V4;
|
||||
@ -292,13 +287,6 @@ static unsigned getNewValueJumpOpcode(const MachineInstr *MI, int reg,
|
||||
return Hexagon::JMP_GTrrPt_nv_V4;
|
||||
}
|
||||
|
||||
case Hexagon::CMPGEri: {
|
||||
if (reg >= 1)
|
||||
return Hexagon::JMP_GTriPt_nv_V4;
|
||||
else
|
||||
return Hexagon::JMP_GTriPtneg_nv_V4;
|
||||
}
|
||||
|
||||
case Hexagon::CMPGTri: {
|
||||
if (reg >= 0)
|
||||
return Hexagon::JMP_GTriPt_nv_V4;
|
||||
@ -306,7 +294,6 @@ static unsigned getNewValueJumpOpcode(const MachineInstr *MI, int reg,
|
||||
return Hexagon::JMP_GTriPtneg_nv_V4;
|
||||
}
|
||||
|
||||
case Hexagon::CMPLTUrr:
|
||||
case Hexagon::CMPGTUrr: {
|
||||
if (secondRegNewified)
|
||||
return Hexagon::JMP_GTUrrdnPt_nv_V4;
|
||||
@ -317,13 +304,6 @@ static unsigned getNewValueJumpOpcode(const MachineInstr *MI, int reg,
|
||||
case Hexagon::CMPGTUri:
|
||||
return Hexagon::JMP_GTUriPt_nv_V4;
|
||||
|
||||
case Hexagon::CMPGEUri: {
|
||||
if (reg == 0)
|
||||
return Hexagon::JMP_EQrrPt_nv_V4;
|
||||
else
|
||||
return Hexagon::JMP_GTUriPt_nv_V4;
|
||||
}
|
||||
|
||||
default:
|
||||
llvm_unreachable("Could not find matching New Value Jump instruction.");
|
||||
}
|
||||
@ -525,10 +505,8 @@ bool HexagonNewValueJump::runOnMachineFunction(MachineFunction &MF) {
|
||||
if (isSecondOpReg) {
|
||||
// In case of CMPLT, or CMPLTU, or EQ with the second register
|
||||
// to newify, swap the operands.
|
||||
if (cmpInstr->getOpcode() == Hexagon::CMPLTrr ||
|
||||
cmpInstr->getOpcode() == Hexagon::CMPLTUrr ||
|
||||
(cmpInstr->getOpcode() == Hexagon::CMPEQrr &&
|
||||
feederReg == (unsigned) cmpOp2)) {
|
||||
if (cmpInstr->getOpcode() == Hexagon::CMPEQrr &&
|
||||
feederReg == (unsigned) cmpOp2) {
|
||||
unsigned tmp = cmpReg1;
|
||||
bool tmpIsKill = MO1IsKill;
|
||||
cmpReg1 = cmpOp2;
|
||||
@ -586,38 +564,29 @@ bool HexagonNewValueJump::runOnMachineFunction(MachineFunction &MF) {
|
||||
if (invertPredicate)
|
||||
opc = QII->getInvertedPredicatedOpcode(opc);
|
||||
|
||||
// Manage the conversions from CMPGEUri to either CMPEQrr
|
||||
// or CMPGTUri properly. See Arch spec for CMPGEUri instructions.
|
||||
// This has to be after the getNewValueJumpOpcode function call as
|
||||
// second operand of the compare could be modified in this logic.
|
||||
if (cmpInstr->getOpcode() == Hexagon::CMPGEUri) {
|
||||
if (cmpOp2 == 0) {
|
||||
cmpOp2 = cmpReg1;
|
||||
MO2IsKill = MO1IsKill;
|
||||
isSecondOpReg = true;
|
||||
} else
|
||||
--cmpOp2;
|
||||
}
|
||||
|
||||
// Manage the conversions from CMPGEri to CMPGTUri properly.
|
||||
// See Arch spec for CMPGEri instructions.
|
||||
if (cmpInstr->getOpcode() == Hexagon::CMPGEri)
|
||||
--cmpOp2;
|
||||
|
||||
if (isSecondOpReg) {
|
||||
if (isSecondOpReg)
|
||||
NewMI = BuildMI(*MBB, jmpPos, dl,
|
||||
QII->get(opc))
|
||||
.addReg(cmpReg1, getKillRegState(MO1IsKill))
|
||||
.addReg(cmpOp2, getKillRegState(MO2IsKill))
|
||||
.addMBB(jmpTarget);
|
||||
}
|
||||
else {
|
||||
|
||||
else if ((cmpInstr->getOpcode() == Hexagon::CMPEQri ||
|
||||
cmpInstr->getOpcode() == Hexagon::CMPGTri) &&
|
||||
cmpOp2 == -1 )
|
||||
// Corresponding new-value compare jump instructions don't have the
|
||||
// operand for -1 immediate value.
|
||||
NewMI = BuildMI(*MBB, jmpPos, dl,
|
||||
QII->get(opc))
|
||||
.addReg(cmpReg1, getKillRegState(MO1IsKill))
|
||||
.addMBB(jmpTarget);
|
||||
|
||||
else
|
||||
NewMI = BuildMI(*MBB, jmpPos, dl,
|
||||
QII->get(opc))
|
||||
.addReg(cmpReg1, getKillRegState(MO1IsKill))
|
||||
.addImm(cmpOp2)
|
||||
.addMBB(jmpTarget);
|
||||
}
|
||||
|
||||
assert(NewMI && "New Value Jump Instruction Not created!");
|
||||
if (cmpInstr->getOperand(0).isReg() &&
|
||||
|
87
test/CodeGen/Hexagon/cmp_pred2.ll
Normal file
87
test/CodeGen/Hexagon/cmp_pred2.ll
Normal file
@ -0,0 +1,87 @@
|
||||
; RUN: llc -march=hexagon -mcpu=hexagonv5 < %s | FileCheck %s
|
||||
; Make sure that the assembler mapped compare instructions are correctly generated.
|
||||
|
||||
@c = common global i32 0, align 4
|
||||
|
||||
define i32 @test1(i32 %a, i32 %b) nounwind {
|
||||
; CHECK-NOT: cmp.ge
|
||||
; CHECK: cmp.gt
|
||||
entry:
|
||||
%cmp = icmp slt i32 %a, 100
|
||||
br i1 %cmp, label %if.then, label %entry.if.end_crit_edge
|
||||
|
||||
entry.if.end_crit_edge:
|
||||
%.pre = load i32* @c, align 4
|
||||
br label %if.end
|
||||
|
||||
if.then:
|
||||
%sub = add nsw i32 %a, -10
|
||||
store i32 %sub, i32* @c, align 4
|
||||
br label %if.end
|
||||
|
||||
if.end:
|
||||
%0 = phi i32 [ %.pre, %entry.if.end_crit_edge ], [ %sub, %if.then ]
|
||||
ret i32 %0
|
||||
}
|
||||
|
||||
define i32 @test2(i32 %a, i32 %b) nounwind {
|
||||
; CHECK-NOT: cmp.lt
|
||||
; CHECK: cmp.gt
|
||||
entry:
|
||||
%cmp = icmp sge i32 %a, %b
|
||||
br i1 %cmp, label %entry.if.end_crit_edge, label %if.then
|
||||
|
||||
entry.if.end_crit_edge:
|
||||
%.pre = load i32* @c, align 4
|
||||
br label %if.end
|
||||
|
||||
if.then:
|
||||
%sub = add nsw i32 %a, -10
|
||||
store i32 %sub, i32* @c, align 4
|
||||
br label %if.end
|
||||
|
||||
if.end:
|
||||
%0 = phi i32 [ %.pre, %entry.if.end_crit_edge ], [ %sub, %if.then ]
|
||||
ret i32 %0
|
||||
}
|
||||
|
||||
define i32 @test4(i32 %a, i32 %b) nounwind {
|
||||
; CHECK-NOT: cmp.ltu
|
||||
; CHECK: cmp.gtu
|
||||
entry:
|
||||
%cmp = icmp uge i32 %a, %b
|
||||
br i1 %cmp, label %entry.if.end_crit_edge, label %if.then
|
||||
|
||||
entry.if.end_crit_edge:
|
||||
%.pre = load i32* @c, align 4
|
||||
br label %if.end
|
||||
|
||||
if.then:
|
||||
%sub = add i32 %a, -10
|
||||
store i32 %sub, i32* @c, align 4
|
||||
br label %if.end
|
||||
|
||||
if.end:
|
||||
%0 = phi i32 [ %.pre, %entry.if.end_crit_edge ], [ %sub, %if.then ]
|
||||
ret i32 %0
|
||||
}
|
||||
|
||||
define i32 @test5(i32 %a, i32 %b) nounwind {
|
||||
; CHECK: cmp.gtu
|
||||
entry:
|
||||
%cmp = icmp uge i32 %a, 29999
|
||||
br i1 %cmp, label %if.then, label %entry.if.end_crit_edge
|
||||
|
||||
entry.if.end_crit_edge:
|
||||
%.pre = load i32* @c, align 4
|
||||
br label %if.end
|
||||
|
||||
if.then:
|
||||
%sub = add i32 %a, -10
|
||||
store i32 %sub, i32* @c, align 4
|
||||
br label %if.end
|
||||
|
||||
if.end:
|
||||
%0 = phi i32 [ %.pre, %entry.if.end_crit_edge ], [ %sub, %if.then ]
|
||||
ret i32 %0
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user