diff options
author | Jim Grosbach <grosbach@apple.com> | 2010-10-07 00:42:42 +0000 |
---|---|---|
committer | Jim Grosbach <grosbach@apple.com> | 2010-10-07 00:42:42 +0000 |
commit | 742adc328a52a7b342cbeb2a3ce75480734bf888 (patch) | |
tree | 480e59e410c2cf09064a51697d999c01f7e4947c /llvm/lib | |
parent | 894d2e61467a09581d8bd3fb600df5b3dee78aed (diff) | |
download | bcm5719-llvm-742adc328a52a7b342cbeb2a3ce75480734bf888.tar.gz bcm5719-llvm-742adc328a52a7b342cbeb2a3ce75480734bf888.zip |
Allow use of the 16-bit literal move instruction in CMOVs for ARM mode.
llvm-svn: 115884
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp | 18 | ||||
-rw-r--r-- | llvm/lib/Target/ARM/ARMInstrInfo.td | 13 |
2 files changed, 23 insertions, 8 deletions
diff --git a/llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp b/llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp index d619564a4f2..a7edf1724ac 100644 --- a/llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp +++ b/llvm/lib/Target/ARM/ARMISelDAGToDAG.cpp @@ -193,7 +193,7 @@ private: SDNode *SelectT2CMOVSoImmOp(SDNode *N, SDValue FalseVal, SDValue TrueVal, ARMCC::CondCodes CCVal, SDValue CCR, SDValue InFlag); - SDNode *SelectARMCMOVSoImmOp(SDNode *N, SDValue FalseVal, SDValue TrueVal, + SDNode *SelectARMCMOVImmOp(SDNode *N, SDValue FalseVal, SDValue TrueVal, ARMCC::CondCodes CCVal, SDValue CCR, SDValue InFlag); @@ -1521,18 +1521,20 @@ SelectT2CMOVSoImmOp(SDNode *N, SDValue FalseVal, SDValue TrueVal, } SDNode *ARMDAGToDAGISel:: -SelectARMCMOVSoImmOp(SDNode *N, SDValue FalseVal, SDValue TrueVal, +SelectARMCMOVImmOp(SDNode *N, SDValue FalseVal, SDValue TrueVal, ARMCC::CondCodes CCVal, SDValue CCR, SDValue InFlag) { ConstantSDNode *T = dyn_cast<ConstantSDNode>(TrueVal); if (!T) return 0; - if (Pred_so_imm(TrueVal.getNode())) { - SDValue True = CurDAG->getTargetConstant(T->getZExtValue(), MVT::i32); + unsigned TrueImm = T->getZExtValue(); + bool isSoImm = Pred_so_imm(TrueVal.getNode()); + 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, - ARM::MOVCCi, MVT::i32, Ops, 5); + return CurDAG->SelectNodeTo(N, (isSoImm ? ARM::MOVCCi : ARM::MOVCCi16), + MVT::i32, Ops, 5); } return 0; } @@ -1589,10 +1591,10 @@ SDNode *ARMDAGToDAGISel::SelectCMOVOp(SDNode *N) { if (Res) return Res; } else { - SDNode *Res = SelectARMCMOVSoImmOp(N, FalseVal, TrueVal, + SDNode *Res = SelectARMCMOVImmOp(N, FalseVal, TrueVal, CCVal, CCR, InFlag); if (!Res) - Res = SelectARMCMOVSoImmOp(N, TrueVal, FalseVal, + Res = SelectARMCMOVImmOp(N, TrueVal, FalseVal, ARMCC::getOppositeCondition(CCVal), CCR, InFlag); if (Res) return Res; diff --git a/llvm/lib/Target/ARM/ARMInstrInfo.td b/llvm/lib/Target/ARM/ARMInstrInfo.td index 893284ad1c3..95bc1d90254 100644 --- a/llvm/lib/Target/ARM/ARMInstrInfo.td +++ b/llvm/lib/Target/ARM/ARMInstrInfo.td @@ -2416,6 +2416,9 @@ def BCCZi64 : PseudoInst<(outs), // 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. :( +// FIXME: These should all be pseudo-instructions that get expanded to +// the normal MOV instructions. That would fix the dependency on +// special casing them in tblgen. let neverHasSideEffects = 1 in { def MOVCCr : AI1<0b1101, (outs GPR:$dst), (ins GPR:$false, GPR:$true), DPFrm, IIC_iCMOVr, "mov", "\t$dst, $true", @@ -2433,6 +2436,16 @@ def MOVCCs : AI1<0b1101, (outs GPR:$dst), let Inst{25} = 0; } +def MOVCCi16 : AI1<0b1000, (outs GPR:$dst), (ins GPR:$false, i32imm:$src), + DPFrm, IIC_iMOVi, + "movw", "\t$dst, $src", + []>, + RegConstraint<"$false = $dst">, Requires<[IsARM, HasV6T2]>, + UnaryDP { + let Inst{20} = 0; + let Inst{25} = 1; +} + def MOVCCi : AI1<0b1101, (outs GPR:$dst), (ins GPR:$false, so_imm:$true), DPFrm, IIC_iCMOVi, "mov", "\t$dst, $true", |