diff options
Diffstat (limited to 'lib/Target/ARM/ARMISelDAGToDAG.cpp')
-rw-r--r-- | lib/Target/ARM/ARMISelDAGToDAG.cpp | 36 |
1 files changed, 31 insertions, 5 deletions
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 @@ public: 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 @@ SelectT2CMOVImmOp(SDNode *N, SDValue FalseVal, SDValue TrueVal, 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 @@ SelectARMCMOVImmOp(SDNode *N, SDValue FalseVal, SDValue TrueVal, 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; } |