summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorJim Grosbach <grosbach@apple.com>2010-10-07 00:53:56 +0000
committerJim Grosbach <grosbach@apple.com>2010-10-07 00:53:56 +0000
commita4257162be84d9d606a42e9db5ce2163426949e3 (patch)
tree4046cd4dff00fd59ceb392ebcf1a95d6769bbf5a /lib
parent511c686f766ba977b667dd04638b68cf241373d5 (diff)
downloadllvm-a4257162be84d9d606a42e9db5ce2163426949e3.tar.gz
llvm-a4257162be84d9d606a42e9db5ce2163426949e3.tar.bz2
llvm-a4257162be84d9d606a42e9db5ce2163426949e3.tar.xz
Allow use of the 16-bit literal move instruction in CMOVs for Thumb2 mode.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@115890 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/Target/ARM/ARMISelDAGToDAG.cpp16
-rw-r--r--lib/Target/ARM/ARMInstrThumb2.td11
2 files changed, 20 insertions, 7 deletions
diff --git a/lib/Target/ARM/ARMISelDAGToDAG.cpp b/lib/Target/ARM/ARMISelDAGToDAG.cpp
index a7edf1724a..4485da42ce 100644
--- a/lib/Target/ARM/ARMISelDAGToDAG.cpp
+++ b/lib/Target/ARM/ARMISelDAGToDAG.cpp
@@ -190,7 +190,7 @@ private:
SDNode *SelectARMCMOVShiftOp(SDNode *N, SDValue FalseVal, SDValue TrueVal,
ARMCC::CondCodes CCVal, SDValue CCR,
SDValue InFlag);
- SDNode *SelectT2CMOVSoImmOp(SDNode *N, SDValue FalseVal, SDValue TrueVal,
+ SDNode *SelectT2CMOVImmOp(SDNode *N, SDValue FalseVal, SDValue TrueVal,
ARMCC::CondCodes CCVal, SDValue CCR,
SDValue InFlag);
SDNode *SelectARMCMOVImmOp(SDNode *N, SDValue FalseVal, SDValue TrueVal,
@@ -1504,18 +1504,20 @@ SelectARMCMOVShiftOp(SDNode *N, SDValue FalseVal, SDValue TrueVal,
}
SDNode *ARMDAGToDAGISel::
-SelectT2CMOVSoImmOp(SDNode *N, SDValue FalseVal, SDValue TrueVal,
+SelectT2CMOVImmOp(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_t2_so_imm(TrueVal.getNode())) {
+ unsigned TrueImm = T->getZExtValue();
+ bool isSoImm = Pred_t2_so_imm(TrueVal.getNode());
+ if (isSoImm || TrueImm <= 0xffff) {
SDValue True = CurDAG->getTargetConstant(T->getZExtValue(), MVT::i32);
SDValue CC = CurDAG->getTargetConstant(CCVal, MVT::i32);
SDValue Ops[] = { FalseVal, True, CC, CCR, InFlag };
- return CurDAG->SelectNodeTo(N,
- ARM::t2MOVCCi, MVT::i32, Ops, 5);
+ return CurDAG->SelectNodeTo(N, (isSoImm ? ARM::t2MOVCCi : ARM::t2MOVCCi16),
+ MVT::i32, Ops, 5);
}
return 0;
}
@@ -1583,10 +1585,10 @@ SDNode *ARMDAGToDAGISel::SelectCMOVOp(SDNode *N) {
// (so_imm:i32 (imm:i32):$true), (imm:i32):$cc)
// Pattern complexity = 10 cost = 1 size = 0
if (Subtarget->isThumb()) {
- SDNode *Res = SelectT2CMOVSoImmOp(N, FalseVal, TrueVal,
+ SDNode *Res = SelectT2CMOVImmOp(N, FalseVal, TrueVal,
CCVal, CCR, InFlag);
if (!Res)
- Res = SelectT2CMOVSoImmOp(N, TrueVal, FalseVal,
+ Res = SelectT2CMOVImmOp(N, TrueVal, FalseVal,
ARMCC::getOppositeCondition(CCVal), CCR, InFlag);
if (Res)
return Res;
diff --git a/lib/Target/ARM/ARMInstrThumb2.td b/lib/Target/ARM/ARMInstrThumb2.td
index f6544e37df..b0acd12564 100644
--- a/lib/Target/ARM/ARMInstrThumb2.td
+++ b/lib/Target/ARM/ARMInstrThumb2.td
@@ -2227,6 +2227,17 @@ def t2MOVCCi : T2I<(outs rGPR:$dst), (ins rGPR:$false, t2_so_imm:$true),
let Inst{15} = 0;
}
+def t2MOVCCi16 : T2I<(outs rGPR:$dst), (ins rGPR:$false, i32imm:$src),
+ IIC_iMOVi,
+ "movw", "\t$dst, $src", []>,
+ RegConstraint<"$false = $dst"> {
+ let Inst{31-27} = 0b11110;
+ let Inst{25} = 1;
+ let Inst{24-21} = 0b0010;
+ let Inst{20} = 0; // The S bit.
+ 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> {