Add support for code generation of the one register with immediate form of vorr.
We could be more aggressive about making this work for a larger range of constants,
but this seems like a good start.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@118201 91177308-0d34-0410-b5e6-96231b3b80d8
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 @@
     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 @@
   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 @@
   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 @@
   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();
 }