aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/Target/ARM/ARMExpandPseudoInsts.cpp10
-rw-r--r--lib/Target/ARM/ARMISelDAGToDAG.cpp40
-rw-r--r--lib/Target/ARM/ARMInstrInfo.td5
-rw-r--r--lib/Target/ARM/ARMInstrThumb2.td10
4 files changed, 47 insertions, 18 deletions
diff --git a/lib/Target/ARM/ARMExpandPseudoInsts.cpp b/lib/Target/ARM/ARMExpandPseudoInsts.cpp
index b252fd2..f38c452 100644
--- a/lib/Target/ARM/ARMExpandPseudoInsts.cpp
+++ b/lib/Target/ARM/ARMExpandPseudoInsts.cpp
@@ -691,15 +691,19 @@ bool ARMExpandPseudo::ExpandMBB(MachineBasicBlock &MBB) {
}
case ARM::MOVi32imm:
- case ARM::t2MOVi32imm: {
+ case ARM::MOVCCi32imm:
+ case ARM::t2MOVi32imm:
+ case ARM::t2MOVCCi32imm: {
unsigned PredReg = 0;
ARMCC::CondCodes Pred = llvm::getInstrPredicate(&MI, PredReg);
unsigned DstReg = MI.getOperand(0).getReg();
bool DstIsDead = MI.getOperand(0).isDead();
- const MachineOperand &MO = MI.getOperand(1);
+ bool isCC = Opcode == ARM::MOVCCi32imm || Opcode == ARM::t2MOVCCi32imm;
+ const MachineOperand &MO = MI.getOperand(isCC ? 2 : 1);
MachineInstrBuilder LO16, HI16;
- if (Opcode == ARM::MOVi32imm && !STI->hasV6T2Ops()) {
+ if (!STI->hasV6T2Ops() &&
+ (Opcode == ARM::MOVi32imm || Opcode == ARM::MOVCCi32imm)) {
// Expand into a movi + orr.
LO16 = BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM::MOVi), DstReg);
HI16 = BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM::ORRri))
diff --git a/lib/Target/ARM/ARMISelDAGToDAG.cpp b/lib/Target/ARM/ARMISelDAGToDAG.cpp
index f30fd94..b5ef7b1 100644
--- a/lib/Target/ARM/ARMISelDAGToDAG.cpp
+++ b/lib/Target/ARM/ARMISelDAGToDAG.cpp
@@ -1782,20 +1782,26 @@ SelectT2CMOVImmOp(SDNode *N, SDValue FalseVal, SDValue TrueVal,
if (!T)
return 0;
+ unsigned Opc = 0;
unsigned TrueImm = T->getZExtValue();
bool isSoImm = is_t2_so_imm(TrueImm);
if (isSoImm || 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::t2MOVCCi : ARM::t2MOVCCi16),
- MVT::i32, Ops, 5);
+ Opc = isSoImm ? ARM::t2MOVCCi : ARM::t2MOVCCi16;
} else if (is_t2_so_imm_not(TrueImm)) {
- SDValue True = CurDAG->getTargetConstant(~TrueImm, MVT::i32);
+ TrueImm = ~TrueImm;
+ Opc = ARM::t2MVNCCi;
+ } else if (Subtarget->hasV6T2Ops()) {
+ // Large immediate.
+ Opc = ARM::t2MOVCCi32imm;
+ }
+
+ if (Opc) {
+ 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 CurDAG->SelectNodeTo(N, Opc, MVT::i32, Ops, 5);
}
+
return 0;
}
@@ -1806,20 +1812,26 @@ SelectARMCMOVImmOp(SDNode *N, SDValue FalseVal, SDValue TrueVal,
if (!T)
return 0;
+ unsigned Opc = 0;
unsigned TrueImm = T->getZExtValue();
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);
+ Opc = isSoImm ? ARM::MOVCCi : ARM::MOVCCi16;
} else if (is_so_imm_not(TrueImm)) {
- SDValue True = CurDAG->getTargetConstant(~TrueImm, MVT::i32);
+ TrueImm = ~TrueImm;
+ Opc = ARM::MVNCCi;
+ } else if (Subtarget->hasV6T2Ops() || ARM_AM::isSOImmTwoPartVal(TrueImm)) {
+ // Large immediate.
+ Opc = ARM::MOVCCi32imm;
+ }
+
+ if (Opc) {
+ 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 CurDAG->SelectNodeTo(N, Opc, MVT::i32, Ops, 5);
}
+
return 0;
}
diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td
index a0c7c9c..1e48108 100644
--- a/lib/Target/ARM/ARMInstrInfo.td
+++ b/lib/Target/ARM/ARMInstrInfo.td
@@ -2942,6 +2942,11 @@ def MOVCCi : AI1<0b1101, (outs GPR:$Rd),
let Inst{11-0} = imm;
}
+// Two instruction predicate mov immediate.
+def MOVCCi32imm : PseudoInst<(outs GPR:$Rd),
+ (ins GPR:$false, i32imm:$src, pred:$p),
+ IIC_iMOVix2, "", []>, RegConstraint<"$false = $Rd">;
+
let isAsCheapAsAMove = 1 in
def MVNCCi : AI1<0b1111, (outs GPR:$Rd),
(ins GPR:$false, so_imm:$imm), DPFrm, IIC_iCMOVi,
diff --git a/lib/Target/ARM/ARMInstrThumb2.td b/lib/Target/ARM/ARMInstrThumb2.td
index 66f2259..6fd814a 100644
--- a/lib/Target/ARM/ARMInstrThumb2.td
+++ b/lib/Target/ARM/ARMInstrThumb2.td
@@ -2243,7 +2243,8 @@ defm t2TEQ : T2I_cmp_irs<0b0100, "teq",
// 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, isAsCheapAsAMove = 1 in {
+let neverHasSideEffects = 1 in {
+let 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))*/]>,
@@ -2257,6 +2258,7 @@ def t2MOVCCr : T2I<(outs rGPR:$dst), (ins rGPR:$false, rGPR:$true), IIC_iCMOVr,
let Inst{7-4} = 0b0000;
}
+let isAsCheapAsAMove = 1 in
def t2MOVCCi : T2I<(outs rGPR:$dst), (ins rGPR:$false, t2_so_imm:$true),
IIC_iCMOVi, "mov", ".w\t$dst, $true",
[/*(set rGPR:$dst,(ARMcmov rGPR:$false,t2_so_imm:$true, imm:$cc, CCR:$ccr))*/]>,
@@ -2269,6 +2271,7 @@ def t2MOVCCi : T2I<(outs rGPR:$dst), (ins rGPR:$false, t2_so_imm:$true),
let Inst{15} = 0;
}
+let isAsCheapAsAMove = 1 in
def t2MOVCCi16 : T2I<(outs rGPR:$dst), (ins rGPR:$false, i32imm:$src),
IIC_iCMOVi,
"movw", "\t$dst, $src", []>,
@@ -2280,6 +2283,11 @@ def t2MOVCCi16 : T2I<(outs rGPR:$dst), (ins rGPR:$false, i32imm:$src),
let Inst{15} = 0;
}
+def t2MOVCCi32imm : PseudoInst<(outs rGPR:$dst),
+ (ins rGPR:$false, i32imm:$src, pred:$p),
+ IIC_iMOVix2, "", []>, RegConstraint<"$false = $dst">;
+
+let isAsCheapAsAMove = 1 in
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,