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 | 3bbdcea49abddea69d124e7ef055c9fdaa8d12f6 (patch) | |
tree | b4af7a4a7a077d1b1fb1d448c2468fd23226b39b /lib | |
parent | 1bb9adae4ca5c3da92e5733aa8b105645a0f7fea (diff) |
Allow use of the 16-bit literal move instruction in CMOVs for ARM mode.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@115884 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Target/ARM/ARMISelDAGToDAG.cpp | 18 | ||||
-rw-r--r-- | lib/Target/ARM/ARMInstrInfo.td | 13 |
2 files changed, 23 insertions, 8 deletions
diff --git a/lib/Target/ARM/ARMISelDAGToDAG.cpp b/lib/Target/ARM/ARMISelDAGToDAG.cpp index d619564a4f2..a7edf1724ac 100644 --- a/lib/Target/ARM/ARMISelDAGToDAG.cpp +++ b/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/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td index 893284ad1c3..95bc1d90254 100644 --- a/lib/Target/ARM/ARMInstrInfo.td +++ b/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", |