aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Target/ARM/ARMISelLowering.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Target/ARM/ARMISelLowering.cpp')
-rw-r--r--lib/Target/ARM/ARMISelLowering.cpp29
1 files changed, 29 insertions, 0 deletions
diff --git a/lib/Target/ARM/ARMISelLowering.cpp b/lib/Target/ARM/ARMISelLowering.cpp
index 2e4fa32..7a3a747 100644
--- a/lib/Target/ARM/ARMISelLowering.cpp
+++ b/lib/Target/ARM/ARMISelLowering.cpp
@@ -101,6 +101,7 @@ void ARMTargetLowering::addTypeForNEON(EVT VT, EVT PromotedLdStVT,
setOperationAction(ISD::SHL, VT.getSimpleVT(), Custom);
setOperationAction(ISD::SRA, VT.getSimpleVT(), Custom);
setOperationAction(ISD::SRL, VT.getSimpleVT(), Custom);
+ setOperationAction(ISD::OR, VT.getSimpleVT(), Custom);
setLoadExtAction(ISD::SEXTLOAD, VT.getSimpleVT(), Expand);
setLoadExtAction(ISD::ZEXTLOAD, VT.getSimpleVT(), Expand);
for (unsigned InnerVT = (unsigned)MVT::FIRST_VECTOR_VALUETYPE;
@@ -820,6 +821,7 @@ const char *ARMTargetLowering::getTargetNodeName(unsigned Opcode) const {
case ARMISD::FMAX: return "ARMISD::FMAX";
case ARMISD::FMIN: return "ARMISD::FMIN";
case ARMISD::BFI: return "ARMISD::BFI";
+ case ARMISD::VORRIMM: return "ARMISD::VORRIMM";
}
}
@@ -3431,6 +3433,32 @@ static SDValue IsSingleInstrConstant(SDValue N, SelectionDAG &DAG,
return SDValue();
}
+static SDValue LowerOR(SDValue Op, SelectionDAG &DAG) {
+ SDValue Op1 = Op.getOperand(1);
+ while (Op1.getOpcode() == ISD::BIT_CONVERT && Op1.getOperand(0) != Op1)
+ Op1 = Op1.getOperand(0);
+ if (Op1.getOpcode() != ARMISD::VMOVIMM) return Op;
+
+ ConstantSDNode* TargetConstant = cast<ConstantSDNode>(Op1.getOperand(0));
+ uint32_t ConstVal = TargetConstant->getZExtValue();
+
+ // FIXME: VORRIMM only supports immediate encodings of 16 and 32 bit size.
+ // In theory for VMOVIMMs whose value is already encoded as with an
+ // 8 bit encoding, we could re-encode it as a 16 or 32 bit immediate.
+ EVT VorrVT = Op1.getValueType();
+ EVT EltVT = VorrVT.getVectorElementType();
+ if (EltVT != MVT::i16 && EltVT != MVT::i32) return Op;
+
+ ConstVal |= 0x0100;
+ SDValue OrConst = DAG.getTargetConstant(ConstVal, MVT::i32);
+
+ DebugLoc dl = Op.getDebugLoc();
+ EVT VT = Op.getValueType();
+ SDValue toTy = DAG.getNode(ISD::BIT_CONVERT, dl, VorrVT, Op.getOperand(0));
+ SDValue Vorr = DAG.getNode(ARMISD::VORRIMM, dl, VorrVT, toTy, OrConst);
+ return DAG.getNode(ISD::BIT_CONVERT, dl, VT, Vorr);
+}
+
// If this is a case we can't handle, return null and let the default
// expansion code take care of it.
static SDValue LowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG,
@@ -3899,6 +3927,7 @@ SDValue ARMTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
case ISD::CONCAT_VECTORS: return LowerCONCAT_VECTORS(Op, DAG);
case ISD::FLT_ROUNDS_: return LowerFLT_ROUNDS_(Op, DAG);
case ISD::MUL: return LowerMUL(Op, DAG);
+ case ISD::OR: return LowerOR(Op, DAG);
}
return SDValue();
}