Add conditional mvn instructions.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@118935 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Target/ARM/ARMISelDAGToDAG.cpp b/lib/Target/ARM/ARMISelDAGToDAG.cpp
index ee3ffef..965ec6e 100644
--- a/lib/Target/ARM/ARMISelDAGToDAG.cpp
+++ b/lib/Target/ARM/ARMISelDAGToDAG.cpp
@@ -142,14 +142,30 @@
bool SelectT2AddrModeSoReg(SDValue N, SDValue &Base,
SDValue &OffReg, SDValue &ShImm);
+ inline bool is_so_imm(unsigned Imm) const {
+ return ARM_AM::getSOImmVal(Imm) != -1;
+ }
+
+ inline bool is_so_imm_not(unsigned Imm) const {
+ return ARM_AM::getSOImmVal(~Imm) != -1;
+ }
+
+ inline bool is_t2_so_imm(unsigned Imm) const {
+ return ARM_AM::getT2SOImmVal(Imm) != -1;
+ }
+
+ inline bool is_t2_so_imm_not(unsigned Imm) const {
+ return ARM_AM::getT2SOImmVal(~Imm) != -1;
+ }
+
inline bool Pred_so_imm(SDNode *inN) const {
ConstantSDNode *N = cast<ConstantSDNode>(inN);
- return ARM_AM::getSOImmVal(N->getZExtValue()) != -1;
+ return is_so_imm(N->getZExtValue());
}
inline bool Pred_t2_so_imm(SDNode *inN) const {
ConstantSDNode *N = cast<ConstantSDNode>(inN);
- return ARM_AM::getT2SOImmVal(N->getZExtValue()) != -1;
+ return is_t2_so_imm(N->getZExtValue());
}
// Include the pieces autogenerated from the target description.
@@ -1767,13 +1783,18 @@
return 0;
unsigned TrueImm = T->getZExtValue();
- bool isSoImm = Pred_t2_so_imm(TrueVal.getNode());
+ bool isSoImm = is_t2_so_imm(TrueImm);
if (isSoImm || TrueImm <= 0xffff) {
- SDValue True = CurDAG->getTargetConstant(T->getZExtValue(), MVT::i32);
+ SDValue True = CurDAG->getTargetConstant(TrueImm, MVT::i32);
SDValue CC = CurDAG->getTargetConstant(CCVal, MVT::i32);
SDValue Ops[] = { FalseVal, True, CC, CCR, InFlag };
return CurDAG->SelectNodeTo(N, (isSoImm ? ARM::t2MOVCCi : ARM::t2MOVCCi16),
MVT::i32, Ops, 5);
+ } else if (is_t2_so_imm_not(TrueImm)) {
+ SDValue True = CurDAG->getTargetConstant(TrueImm, MVT::i32);
+ SDValue CC = CurDAG->getTargetConstant(CCVal, MVT::i32);
+ SDValue Ops[] = { FalseVal, True, CC, CCR, InFlag };
+ return CurDAG->SelectNodeTo(N, ARM::t2MVNCCi, MVT::i32, Ops, 5);
}
return 0;
}
@@ -1786,13 +1807,18 @@
return 0;
unsigned TrueImm = T->getZExtValue();
- bool isSoImm = Pred_so_imm(TrueVal.getNode());
+ bool isSoImm = is_so_imm(TrueImm);
if (isSoImm || (Subtarget->hasV6T2Ops() && TrueImm <= 0xffff)) {
SDValue True = CurDAG->getTargetConstant(TrueImm, MVT::i32);
SDValue CC = CurDAG->getTargetConstant(CCVal, MVT::i32);
SDValue Ops[] = { FalseVal, True, CC, CCR, InFlag };
return CurDAG->SelectNodeTo(N, (isSoImm ? ARM::MOVCCi : ARM::MOVCCi16),
MVT::i32, Ops, 5);
+ } else if (is_so_imm_not(TrueImm)) {
+ SDValue True = CurDAG->getTargetConstant(~TrueImm, MVT::i32);
+ SDValue CC = CurDAG->getTargetConstant(CCVal, MVT::i32);
+ SDValue Ops[] = { FalseVal, True, CC, CCR, InFlag };
+ return CurDAG->SelectNodeTo(N, ARM::MVNCCi, MVT::i32, Ops, 5);
}
return 0;
}
diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td
index 6926bf0..849bda8 100644
--- a/lib/Target/ARM/ARMInstrInfo.td
+++ b/lib/Target/ARM/ARMInstrInfo.td
@@ -212,12 +212,12 @@
def so_imm_neg :
PatLeaf<(imm), [{
- return ARM_AM::getSOImmVal(-(int)N->getZExtValue()) != -1;
+ return ARM_AM::getSOImmVal(-(uint32_t)N->getZExtValue()) != -1;
}], so_imm_neg_XFORM>;
def so_imm_not :
PatLeaf<(imm), [{
- return ARM_AM::getSOImmVal(~(int)N->getZExtValue()) != -1;
+ return ARM_AM::getSOImmVal(~(uint32_t)N->getZExtValue()) != -1;
}], so_imm_not_XFORM>;
// sext_16_node predicate - True if the SDNode is sign-extended 16 or more bits.
@@ -2875,6 +2875,7 @@
// the normal MOV instructions. That would fix the dependency on
// special casing them in tblgen.
let neverHasSideEffects = 1 in {
+let isAsCheapAsAMove = 1 in
def MOVCCr : AI1<0b1101, (outs GPR:$Rd), (ins GPR:$false, GPR:$Rm), DPFrm,
IIC_iCMOVr, "mov", "\t$Rd, $Rm",
[/*(set GPR:$Rd, (ARMcmov GPR:$false, GPR:$Rm, imm:$cc, CCR:$ccr))*/]>,
@@ -2903,6 +2904,7 @@
let Inst{11-0} = shift;
}
+let isAsCheapAsAMove = 1 in
def MOVCCi16 : AI1<0b1000, (outs GPR:$Rd), (ins GPR:$false, i32imm:$imm),
DPFrm, IIC_iMOVi,
"movw", "\t$Rd, $imm",
@@ -2918,6 +2920,7 @@
let Inst{11-0} = imm{11-0};
}
+let isAsCheapAsAMove = 1 in
def MOVCCi : AI1<0b1101, (outs GPR:$Rd),
(ins GPR:$false, so_imm:$imm), DPFrm, IIC_iCMOVi,
"mov", "\t$Rd, $imm",
@@ -2931,6 +2934,21 @@
let Inst{15-12} = Rd;
let Inst{11-0} = imm;
}
+
+let isAsCheapAsAMove = 1 in
+def MVNCCi : AI1<0b1111, (outs GPR:$Rd),
+ (ins GPR:$false, so_imm:$imm), DPFrm, IIC_iCMOVi,
+ "mvn", "\t$Rd, $imm",
+ [/*(set GPR:$Rd, (ARMcmov GPR:$false, so_imm_not:$imm, imm:$cc, CCR:$ccr))*/]>,
+ RegConstraint<"$false = $Rd">, UnaryDP {
+ bits<4> Rd;
+ bits<12> imm;
+ let Inst{25} = 1;
+ let Inst{20} = 0;
+ let Inst{19-16} = 0b0000;
+ let Inst{15-12} = Rd;
+ let Inst{11-0} = imm;
+}
} // neverHasSideEffects
//===----------------------------------------------------------------------===//
diff --git a/lib/Target/ARM/ARMInstrThumb2.td b/lib/Target/ARM/ARMInstrThumb2.td
index 3854b68..66f2259 100644
--- a/lib/Target/ARM/ARMInstrThumb2.td
+++ b/lib/Target/ARM/ARMInstrThumb2.td
@@ -66,7 +66,7 @@
// t2_so_imm_neg - Match an immediate that is a negation of a t2_so_imm.
def t2_so_imm_neg : Operand<i32>,
PatLeaf<(imm), [{
- return ARM_AM::getT2SOImmVal(-((int)N->getZExtValue())) != -1;
+ return ARM_AM::getT2SOImmVal(-((uint32_t)N->getZExtValue())) != -1;
}], t2_so_imm_neg_XFORM>;
// Break t2_so_imm's up into two pieces. This handles immediates with up to 16
@@ -2243,7 +2243,7 @@
// Conditional moves
// FIXME: should be able to write a pattern for ARMcmov, but can't use
// a two-value operand where a dag node expects two operands. :(
-let neverHasSideEffects = 1 in {
+let neverHasSideEffects = 1, isAsCheapAsAMove = 1 in {
def t2MOVCCr : T2I<(outs rGPR:$dst), (ins rGPR:$false, rGPR:$true), IIC_iCMOVr,
"mov", ".w\t$dst, $true",
[/*(set rGPR:$dst, (ARMcmov rGPR:$false, rGPR:$true, imm:$cc, CCR:$ccr))*/]>,
@@ -2270,7 +2270,7 @@
}
def t2MOVCCi16 : T2I<(outs rGPR:$dst), (ins rGPR:$false, i32imm:$src),
- IIC_iMOVi,
+ IIC_iCMOVi,
"movw", "\t$dst, $src", []>,
RegConstraint<"$false = $dst"> {
let Inst{31-27} = 0b11110;
@@ -2280,6 +2280,19 @@
let Inst{15} = 0;
}
+def t2MVNCCi : T2I<(outs rGPR:$dst), (ins rGPR:$false, t2_so_imm:$true),
+ IIC_iCMOVi, "mvn", ".w\t$dst, $true",
+[/*(set rGPR:$dst,(ARMcmov rGPR:$false,t2_so_imm_not:$true,
+ imm:$cc, CCR:$ccr))*/]>,
+ RegConstraint<"$false = $dst"> {
+ let Inst{31-27} = 0b11110;
+ let Inst{25} = 0;
+ let Inst{24-21} = 0b0011;
+ let Inst{20} = 0; // The S bit.
+ let Inst{19-16} = 0b1111; // Rn
+ let Inst{15} = 0;
+}
+
class T2I_movcc_sh<bits<2> opcod, dag oops, dag iops, InstrItinClass itin,
string opc, string asm, list<dag> pattern>
: T2I<oops, iops, itin, opc, asm, pattern> {