[llvm-commits] [llvm] r105769 - in /llvm/trunk/utils/TableGen: NeonEmitter.cpp NeonEmitter.h

Nate Begeman natebegeman at mac.com
Wed Jun 9 17:16:56 PDT 2010


Author: sampo
Date: Wed Jun  9 19:16:56 2010
New Revision: 105769

URL: http://llvm.org/viewvc/llvm-project?rev=105769&view=rev
Log:
NEON support for _lane ops, and multiplies by scalar.

Modified:
    llvm/trunk/utils/TableGen/NeonEmitter.cpp
    llvm/trunk/utils/TableGen/NeonEmitter.h

Modified: llvm/trunk/utils/TableGen/NeonEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/NeonEmitter.cpp?rev=105769&r1=105768&r2=105769&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/NeonEmitter.cpp (original)
+++ llvm/trunk/utils/TableGen/NeonEmitter.cpp Wed Jun  9 19:16:56 2010
@@ -137,6 +137,7 @@
       usgn = true;
       break;
     case 's':
+    case 'a':
       scal = true;
       break;
     case 'k':
@@ -442,14 +443,7 @@
   return s;
 }
 
-// Generate the definition for this intrinsic, e.g. "a + b" for OpAdd.
-// If structTypes is true, the NEON types are structs of vector types rather
-// than vector types, and the call becomes "a.val + b.val"
-static std::string GenOpString(OpKind op, const std::string &proto,
-                               StringRef typestr, bool structTypes = true) {
-  std::string ts = TypeString(proto[0], typestr);
-  std::string s = ts + " r; r";
-
+static std::string Duplicate(StringRef typestr, const std::string &a) {
   bool dummy, quad = false;
   char type = ClassifyType(typestr, quad, dummy, dummy);
   unsigned nElts = 0;
@@ -462,6 +456,27 @@
     case 'f': nElts = 2; break;
   }
   nElts <<= quad;
+
+  std::string s;
+  
+  s = "(__neon_" + TypeString('d', typestr) + "){ ";
+  for (unsigned i = 0; i != nElts; ++i) {
+    s += a;
+    if ((i + 1) < nElts)
+      s += ", ";
+  }
+  s += " }";
+  
+  return s;
+}
+
+// Generate the definition for this intrinsic, e.g. "a + b" for OpAdd.
+// If structTypes is true, the NEON types are structs of vector types rather
+// than vector types, and the call becomes "a.val + b.val"
+static std::string GenOpString(OpKind op, const std::string &proto,
+                               StringRef typestr, bool structTypes = true) {
+  std::string ts = TypeString(proto[0], typestr);
+  std::string s = ts + " r; r";
   
   if (structTypes)
     s += ".val";
@@ -481,12 +496,18 @@
   case OpSub:
     s += a + " - " + b;
     break;
+  case OpMulN:
+    b = Duplicate(typestr, "b");
   case OpMul:
     s += a + " * " + b;
     break;
+  case OpMlaN:
+    c = Duplicate(typestr, "c");
   case OpMla:
     s += a + " + ( " + b + " * " + c + " )";
     break;
+  case OpMlsN:
+    c = Duplicate(typestr, "c");
   case OpMls:
     s += a + " - ( " + b + " * " + c + " )";
     break;
@@ -540,13 +561,7 @@
     s += "(__neon_int64x1_t)(((__neon_int64x2_t)" + a + ")[0])";
     break;
   case OpDup:
-    s += "(__neon_" + ts + "){ ";
-    for (unsigned i = 0; i != nElts; ++i) {
-      s += a;
-      if ((i + 1) < nElts)
-        s += ", ";
-    }
-    s += " }";
+    s += Duplicate(typestr, a);
     break;
   default:
     throw "unknown OpKind!";
@@ -647,10 +662,17 @@
       
       s += " = ";
     }
-  }    
+  }
+  
+  bool splat = proto.find('a') != std::string::npos;
   
   s += "__builtin_neon_";
-  s += MangleName(name, typestr, ck);
+  if (splat) {
+    std::string vname(name, 0, name.size()-2);
+    s += MangleName(vname, typestr, ck);
+  } else {
+    s += MangleName(name, typestr, ck);
+  }
   s += "(";
   
   for (unsigned i = 1, e = proto.size(); i != e; ++i, ++arg) {
@@ -672,12 +694,18 @@
     // Parenthesize the args from the macro.
     if (define)
       s.push_back('(');
-    s.push_back(arg);
+    
+    if (splat && (i + 1) == e) 
+      s += Duplicate(typestr, std::string(&arg, 1));
+    else
+      s.push_back(arg);
+
+    // Parenthesize the args from the macro.
     if (define)
       s.push_back(')');
     
     if (structTypes && proto[i] != 's' && proto[i] != 'i' && proto[i] != 'l' &&
-        proto[i] != 'p' && proto[i] != 'c') {
+        proto[i] != 'p' && proto[i] != 'c' && proto[i] != 'a') {
       s += ".val";
     }
     if ((i + 1) < e)
@@ -748,7 +776,6 @@
 
   // Emit NEON-specific scalar typedefs.
   // FIXME: probably need to do something better for polynomial types.
-  // FIXME: is this the correct thing to do for float16?
   OS << "typedef float float32_t;\n";
   OS << "typedef uint8_t poly8_t;\n";
   OS << "typedef uint16_t poly16_t;\n";
@@ -869,6 +896,9 @@
     std::string Proto = R->getValueAsString("Prototype");
     std::string Types = R->getValueAsString("Types");
 
+    if (Proto.find('a') != std::string::npos)
+      continue;
+      
     SmallVector<StringRef, 16> TypeVec;
     ParseTypes(R, Types, TypeVec);
 

Modified: llvm/trunk/utils/TableGen/NeonEmitter.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/NeonEmitter.h?rev=105769&r1=105768&r2=105769&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/NeonEmitter.h (original)
+++ llvm/trunk/utils/TableGen/NeonEmitter.h Wed Jun  9 19:16:56 2010
@@ -28,6 +28,9 @@
   OpMul,
   OpMla,
   OpMls,
+  OpMulN,
+  OpMlaN,
+  OpMlsN,
   OpEq,
   OpGe,
   OpLe,
@@ -64,38 +67,39 @@
     
   public:
     NeonEmitter(RecordKeeper &R) : Records(R) {
-      OpMap["OP_NONE"] = OpNone;
-      OpMap["OP_ADD"]  = OpAdd;
-      OpMap["OP_SUB"]  = OpSub;
-      OpMap["OP_MUL"]  = OpMul;
-      OpMap["OP_MLA"]  = OpMla;
-      OpMap["OP_MLS"]  = OpMls;
-      OpMap["OP_EQ"]   = OpEq;
-      OpMap["OP_GE"]   = OpGe;
-      OpMap["OP_LE"]   = OpLe;
-      OpMap["OP_GT"]   = OpGt;
-      OpMap["OP_LT"]   = OpLt;
-      OpMap["OP_NEG"]  = OpNeg;
-      OpMap["OP_NOT"]  = OpNot;
-      OpMap["OP_AND"]  = OpAnd;
-      OpMap["OP_OR"]   = OpOr;
-      OpMap["OP_XOR"]  = OpXor;
-      OpMap["OP_ANDN"] = OpAndNot;
-      OpMap["OP_ORN"]  = OpOrNot;
-      OpMap["OP_CAST"] = OpCast;
-      OpMap["OP_CONC"] = OpConcat;
-      OpMap["OP_HI"]   = OpHi;
-      OpMap["OP_LO"]   = OpLo;
-      OpMap["OP_DUP"]  = OpDup;
+      OpMap["OP_NONE"]  = OpNone;
+      OpMap["OP_ADD"]   = OpAdd;
+      OpMap["OP_SUB"]   = OpSub;
+      OpMap["OP_MUL"]   = OpMul;
+      OpMap["OP_MLA"]   = OpMla;
+      OpMap["OP_MLS"]   = OpMls;
+      OpMap["OP_MUL_N"] = OpMulN;
+      OpMap["OP_MLA_N"] = OpMlaN;
+      OpMap["OP_MLS_N"] = OpMlsN;
+      OpMap["OP_EQ"]    = OpEq;
+      OpMap["OP_GE"]    = OpGe;
+      OpMap["OP_LE"]    = OpLe;
+      OpMap["OP_GT"]    = OpGt;
+      OpMap["OP_LT"]    = OpLt;
+      OpMap["OP_NEG"]   = OpNeg;
+      OpMap["OP_NOT"]   = OpNot;
+      OpMap["OP_AND"]   = OpAnd;
+      OpMap["OP_OR"]    = OpOr;
+      OpMap["OP_XOR"]   = OpXor;
+      OpMap["OP_ANDN"]  = OpAndNot;
+      OpMap["OP_ORN"]   = OpOrNot;
+      OpMap["OP_CAST"]  = OpCast;
+      OpMap["OP_CONC"]  = OpConcat;
+      OpMap["OP_HI"]    = OpHi;
+      OpMap["OP_LO"]    = OpLo;
+      OpMap["OP_DUP"]   = OpDup;
 
       Record *SI = R.getClass("SInst");
       Record *II = R.getClass("IInst");
       Record *WI = R.getClass("WInst");
-      Record *BI = R.getClass("BInst");
       ClassMap[SI] = ClassS;
       ClassMap[II] = ClassI;
       ClassMap[WI] = ClassW;
-      ClassMap[BI] = ClassB;
     }
     
     // run - Emit arm_neon.h.inc





More information about the llvm-commits mailing list