summaryrefslogtreecommitdiffstats
path: root/lib/Target/ARM/ARMISelDAGToDAG.cpp
diff options
context:
space:
mode:
authored <ed@FreeBSD.org>2009-06-22 08:08:12 +0000
committered <ed@FreeBSD.org>2009-06-22 08:08:12 +0000
commita4c19d68f13cf0a83bc0da53bd6d547fcaf635fe (patch)
tree86c1bc482baa6c81fc70b8d715153bfa93377186 /lib/Target/ARM/ARMISelDAGToDAG.cpp
parentdb89e312d968c258aba3c79c1c398f5fb19267a3 (diff)
downloadFreeBSD-src-a4c19d68f13cf0a83bc0da53bd6d547fcaf635fe.zip
FreeBSD-src-a4c19d68f13cf0a83bc0da53bd6d547fcaf635fe.tar.gz
Update LLVM sources to r73879.
Diffstat (limited to 'lib/Target/ARM/ARMISelDAGToDAG.cpp')
-rw-r--r--lib/Target/ARM/ARMISelDAGToDAG.cpp40
1 files changed, 37 insertions, 3 deletions
diff --git a/lib/Target/ARM/ARMISelDAGToDAG.cpp b/lib/Target/ARM/ARMISelDAGToDAG.cpp
index ca3a9cb..1ed9e80 100644
--- a/lib/Target/ARM/ARMISelDAGToDAG.cpp
+++ b/lib/Target/ARM/ARMISelDAGToDAG.cpp
@@ -52,8 +52,13 @@ public:
virtual const char *getPassName() const {
return "ARM Instruction Selection";
- }
-
+ }
+
+ /// getI32Imm - Return a target constant with the specified value, of type i32.
+ inline SDValue getI32Imm(unsigned Imm) {
+ return CurDAG->getTargetConstant(Imm, MVT::i32);
+ }
+
SDNode *Select(SDValue Op);
virtual void InstructionSelect();
bool SelectAddrMode2(SDValue Op, SDValue N, SDValue &Base,
@@ -84,6 +89,9 @@ public:
bool SelectThumbAddrModeSP(SDValue Op, SDValue N, SDValue &Base,
SDValue &OffImm);
+ bool SelectShifterOperand(SDValue Op, SDValue N,
+ SDValue &BaseReg, SDValue &Opc);
+
bool SelectShifterOperandReg(SDValue Op, SDValue N, SDValue &A,
SDValue &B, SDValue &C);
@@ -509,8 +517,30 @@ bool ARMDAGToDAGISel::SelectThumbAddrModeSP(SDValue Op, SDValue N,
return false;
}
+bool ARMDAGToDAGISel::SelectShifterOperand(SDValue Op,
+ SDValue N,
+ SDValue &BaseReg,
+ SDValue &Opc) {
+ ARM_AM::ShiftOpc ShOpcVal = ARM_AM::getShiftOpcForNode(N);
+
+ // Don't match base register only case. That is matched to a separate
+ // lower complexity pattern with explicit register operand.
+ if (ShOpcVal == ARM_AM::no_shift) return false;
+
+ BaseReg = N.getOperand(0);
+ unsigned ShImmVal = 0;
+ if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1)))
+ ShImmVal = RHS->getZExtValue() & 31;
+ else
+ return false;
+
+ Opc = getI32Imm(ARM_AM::getSORegOpc(ShOpcVal, ShImmVal));
+
+ return true;
+}
+
bool ARMDAGToDAGISel::SelectShifterOperandReg(SDValue Op,
- SDValue N,
+ SDValue N,
SDValue &BaseReg,
SDValue &ShReg,
SDValue &Opc) {
@@ -549,6 +579,10 @@ SDNode *ARMDAGToDAGISel::Select(SDValue Op) {
switch (N->getOpcode()) {
default: break;
case ISD::Constant: {
+ // ARMv6T2 and later should materialize imms via MOV / MOVT pair.
+ if (Subtarget->hasV6T2Ops() || Subtarget->hasThumb2())
+ break;
+
unsigned Val = cast<ConstantSDNode>(N)->getZExtValue();
bool UseCP = true;
if (Subtarget->isThumb())
OpenPOWER on IntegriCloud