diff options
Diffstat (limited to 'lib/Target/ARM/ARMISelLowering.cpp')
-rw-r--r-- | lib/Target/ARM/ARMISelLowering.cpp | 29 |
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(); } |