Implement Neon VTRN instructions.  For now, anyway, these are selected
directly from the intrinsics produced by the frontend.  If it is more
convenient to have a custom DAG node for using these to implement shuffles,
we can add that later.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@78459 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Target/ARM/ARMISelDAGToDAG.cpp b/lib/Target/ARM/ARMISelDAGToDAG.cpp
index 04f4dd3..bfaf678 100644
--- a/lib/Target/ARM/ARMISelDAGToDAG.cpp
+++ b/lib/Target/ARM/ARMISelDAGToDAG.cpp
@@ -1448,6 +1448,33 @@
                             N->getOperand(4), N->getOperand(5) };
     return CurDAG->getTargetNode(Opc, dl, MVT::Other, Ops, 7);
   }
+
+  case ISD::INTRINSIC_WO_CHAIN: {
+    unsigned IntNo = cast<ConstantSDNode>(N->getOperand(0))->getZExtValue();
+    MVT VT = N->getValueType(0);
+    unsigned Opc = 0;
+
+    // Match intrinsics that return multiple values.
+    switch (IntNo) {
+    default: break;
+
+    case Intrinsic::arm_neon_vtrni:
+      switch (VT.getSimpleVT()) {
+      default: return NULL;
+      case MVT::v8i8:  Opc = ARM::VTRNd8; break;
+      case MVT::v4i16: Opc = ARM::VTRNd16; break;
+      case MVT::v2f32:
+      case MVT::v2i32: Opc = ARM::VTRNd32; break;
+      case MVT::v16i8: Opc = ARM::VTRNq8; break;
+      case MVT::v8i16: Opc = ARM::VTRNq16; break;
+      case MVT::v4f32:
+      case MVT::v4i32: Opc = ARM::VTRNq32; break;
+      }
+      return CurDAG->getTargetNode(Opc, dl, VT, VT, N->getOperand(1),
+                                   N->getOperand(2));
+    }
+    break;
+  }
   }
 
   return SelectCode(Op);