OSDN Git Service

Add support for "_lane" variants of VMUL, VMLA, and VMLS Neon intrinsics.
authorBob Wilson <bob.wilson@apple.com>
Fri, 3 Dec 2010 00:34:12 +0000 (00:34 +0000)
committerBob Wilson <bob.wilson@apple.com>
Fri, 3 Dec 2010 00:34:12 +0000 (00:34 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@120764 91177308-0d34-0410-b5e6-96231b3b80d8

utils/TableGen/NeonEmitter.cpp
utils/TableGen/NeonEmitter.h

index 6aa3d9c..dc6b353 100644 (file)
@@ -523,6 +523,15 @@ static std::string Duplicate(unsigned nElts, StringRef typestr,
   return s;
 }
 
+static std::string SplatLane(unsigned nElts, const std::string &vec,
+                             const std::string &lane) {
+  std::string s = "__builtin_shufflevector(" + vec + ", " + vec;
+  for (unsigned i = 0; i < nElts; ++i)
+    s += ", " + lane;
+  s += ")";
+  return s;
+}
+
 static unsigned GetNumElements(StringRef typestr, bool &quad) {
   quad = false;
   bool dummy = false;
@@ -572,18 +581,27 @@ static std::string GenOpString(OpKind op, const std::string &proto,
   case OpMulN:
     s += "__a * " + Duplicate(nElts, typestr, "__b") + ";";
     break;
+  case OpMulLane:
+    s += "__a * " + SplatLane(nElts, "__b", "__c") + ";";
+    break;
   case OpMul:
     s += "__a * __b;";
     break;
   case OpMlaN:
     s += "__a + (__b * " + Duplicate(nElts, typestr, "__c") + ");";
     break;
+  case OpMlaLane:
+    s += "__a + (__b * " + SplatLane(nElts, "__c", "__d") + ");";
+    break;
   case OpMla:
     s += "__a + (__b * __c);";
     break;
   case OpMlsN:
     s += "__a - (__b * " + Duplicate(nElts, typestr, "__c") + ");";
     break;
+  case OpMlsLane:
+    s += "__a - (__b * " + SplatLane(nElts, "__c", "__d") + ");";
+    break;
   case OpMls:
     s += "__a - (__b * __c);";
     break;
index 4dcb96a..ffea644 100644 (file)
@@ -31,6 +31,9 @@ enum OpKind {
   OpMulN,
   OpMlaN,
   OpMlsN,
+  OpMulLane,
+  OpMlaLane,
+  OpMlsLane,
   OpEq,
   OpGe,
   OpLe,
@@ -80,6 +83,9 @@ namespace llvm {
       OpMap["OP_MUL_N"] = OpMulN;
       OpMap["OP_MLA_N"] = OpMlaN;
       OpMap["OP_MLS_N"] = OpMlsN;
+      OpMap["OP_MUL_LN"]= OpMulLane;
+      OpMap["OP_MLA_LN"]= OpMlaLane;
+      OpMap["OP_MLS_LN"]= OpMlsLane;
       OpMap["OP_EQ"]    = OpEq;
       OpMap["OP_GE"]    = OpGe;
       OpMap["OP_LE"]    = OpLe;