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

Bob Wilson bob.wilson at apple.com
Mon Dec 6 17:12:23 PST 2010


Author: bwilson
Date: Mon Dec  6 19:12:23 2010
New Revision: 121087

URL: http://llvm.org/viewvc/llvm-project?rev=121087&view=rev
Log:
Add an OpReinterpret operation to TableGen's NeonEmitter.
An OpReinterpret entry is handled by translating it to OpCast intrinsics for
all combinations of source and destination types with the same total size.
This will be used to generate all the vreinterpret intrinsics.

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=121087&r1=121086&r2=121087&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/NeonEmitter.cpp (original)
+++ llvm/trunk/utils/TableGen/NeonEmitter.cpp Mon Dec  6 19:12:23 2010
@@ -897,6 +897,55 @@
   return s;
 }
 
+static std::string GenIntrinsic(const std::string &name,
+                                const std::string &proto,
+                                StringRef outTypeStr, StringRef inTypeStr,
+                                OpKind kind, ClassKind classKind) {
+  assert(!proto.empty() && "");
+  bool define = proto.find('i') != std::string::npos;
+  std::string s;
+
+  // static always inline + return type
+  if (define)
+    s += "#define ";
+  else
+    s += "__ai " + TypeString(proto[0], outTypeStr) + " ";
+
+  // Function name with type suffix
+  std::string mangledName = MangleName(name, outTypeStr, ClassS);
+  if (outTypeStr != inTypeStr) {
+    // If the input type is different (e.g., for vreinterpret), append a suffix
+    // for the input type.  String off a "Q" (quad) prefix so that MangleName
+    // does not insert another "q" in the name.
+    unsigned typeStrOff = (inTypeStr[0] == 'Q' ? 1 : 0);
+    StringRef inTypeNoQuad = inTypeStr.substr(typeStrOff);
+    mangledName = MangleName(mangledName, inTypeNoQuad, ClassS);
+  }
+  s += mangledName;
+
+  // Function arguments
+  s += GenArgs(proto, inTypeStr);
+
+  // Definition.
+  if (define) {
+    s += " __extension__ ({ \\\n  ";
+    s += GenMacroLocals(proto, inTypeStr);
+  } else {
+    s += " { \\\n  ";
+  }
+
+  if (kind != OpNone)
+    s += GenOpString(kind, proto, outTypeStr);
+  else
+    s += GenBuiltin(name, proto, outTypeStr, classKind);
+  if (define)
+    s += " })";
+  else
+    s += " }";
+  s += "\n";
+  return s;
+}
+
 /// run - Read the records in arm_neon.td and output arm_neon.h.  arm_neon.h
 /// is comprised of type definitions and function declarations.
 void NeonEmitter::run(raw_ostream &OS) {
@@ -975,50 +1024,32 @@
     SmallVector<StringRef, 16> TypeVec;
     ParseTypes(R, Types, TypeVec);
 
-    OpKind k = OpMap[R->getValueAsDef("Operand")->getName()];
+    OpKind kind = OpMap[R->getValueAsDef("Operand")->getName()];
 
-    bool define = Proto.find('i') != std::string::npos;
+    ClassKind classKind = ClassNone;
+    if (R->getSuperClasses().size() >= 2)
+      classKind = ClassMap[R->getSuperClasses()[1]];
+    if (classKind == ClassNone && kind == OpNone)
+      throw TGError(R->getLoc(), "Builtin has no class kind");
 
     for (unsigned ti = 0, te = TypeVec.size(); ti != te; ++ti) {
-      assert(!Proto.empty() && "");
-
-      // static always inline + return type
-      if (define)
-        OS << "#define";
-      else
-        OS << "__ai " << TypeString(Proto[0], TypeVec[ti]);
-
-      // Function name with type suffix
-      OS << " " << MangleName(name, TypeVec[ti], ClassS);
-
-      // Function arguments
-      OS << GenArgs(Proto, TypeVec[ti]);
-
-      // Definition.
-      if (define) {
-        OS << " __extension__ ({ \\\n  ";
-        OS << GenMacroLocals(Proto, TypeVec[ti]);
-      } else {
-        OS << " { \\\n  ";
-      }
-
-      if (k != OpNone) {
-        OS << GenOpString(k, Proto, TypeVec[ti]);
+      if (kind == OpReinterpret) {
+        bool outQuad = false;
+        bool dummy = false;
+        (void)ClassifyType(TypeVec[ti], outQuad, dummy, dummy);
+        for (unsigned srcti = 0, srcte = TypeVec.size();
+             srcti != srcte; ++srcti) {
+          bool inQuad = false;
+          (void)ClassifyType(TypeVec[srcti], inQuad, dummy, dummy);
+          if (srcti == ti || inQuad != outQuad)
+            continue;
+          OS << GenIntrinsic(name, Proto, TypeVec[ti], TypeVec[srcti],
+                             OpCast, ClassS);
+        }
       } else {
-        if (R->getSuperClasses().size() < 2)
-          throw TGError(R->getLoc(), "Builtin has no class kind");
-
-        ClassKind ck = ClassMap[R->getSuperClasses()[1]];
-
-        if (ck == ClassNone)
-          throw TGError(R->getLoc(), "Builtin has no class kind");
-        OS << GenBuiltin(name, Proto, TypeVec[ti], ck);
+        OS << GenIntrinsic(name, Proto, TypeVec[ti], TypeVec[ti],
+                           kind, classKind);
       }
-      if (define)
-        OS << " })";
-      else
-        OS << " }";
-      OS << "\n";
     }
     OS << "\n";
   }

Modified: llvm/trunk/utils/TableGen/NeonEmitter.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/NeonEmitter.h?rev=121087&r1=121086&r2=121087&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/NeonEmitter.h (original)
+++ llvm/trunk/utils/TableGen/NeonEmitter.h Mon Dec  6 19:12:23 2010
@@ -54,7 +54,8 @@
   OpSelect,
   OpRev16,
   OpRev32,
-  OpRev64
+  OpRev64,
+  OpReinterpret
 };
 
 enum ClassKind {
@@ -107,6 +108,7 @@
       OpMap["OP_REV16"] = OpRev16;
       OpMap["OP_REV32"] = OpRev32;
       OpMap["OP_REV64"] = OpRev64;
+      OpMap["OP_REINT"] = OpReinterpret;
 
       Record *SI = R.getClass("SInst");
       Record *II = R.getClass("IInst");





More information about the llvm-commits mailing list