Add the last of the SemaChecking-gen code.
authorNate Begeman <natebegeman@mac.com>
Mon, 14 Jun 2010 05:17:23 +0000 (05:17 +0000)
committerNate Begeman <natebegeman@mac.com>
Mon, 14 Jun 2010 05:17:23 +0000 (05:17 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@105929 91177308-0d34-0410-b5e6-96231b3b80d8

utils/TableGen/NeonEmitter.cpp

index bf5c1753356c6553a33299502e9d0ab4270adacb..bdcfbc5a8696f78ec43f1d48c8cd34e272f77d79 100644 (file)
@@ -946,6 +946,28 @@ void NeonEmitter::run(raw_ostream &OS) {
   OS << "#endif /* __ARM_NEON_H */\n";
 }
 
+static unsigned RangeFromType(StringRef typestr) {
+  // base type to get the type string for.
+  bool quad = false, dummy = false;
+  char type = ClassifyType(typestr, quad, dummy, dummy);
+  
+  switch (type) {
+    case 'c':
+      return (8 << quad) - 1;
+    case 'h':
+    case 's':
+      return (4 << quad) - 1;
+    case 'f':
+    case 'i':
+      return (2 << quad) - 1;
+    case 'l':
+      return (1 << quad) - 1;
+    default:
+      throw "unhandled type!";
+      break;
+  }
+}
+
 /// runHeader - generate one of three different tables which are used by clang
 /// to support ARM NEON codegen.  By default, this will produce the contents of
 /// BuiltinsARM.def's NEON section.  You may also enable the genSemaTypes or
@@ -1020,11 +1042,32 @@ void NeonEmitter::runHeader(raw_ostream &OS) {
       }
       
       if (genSemaRange) {
-        if (Proto.find('s') == std::string::npos)
+        std::string namestr, shiftstr, rangestr;
+        
+        // Builtins which are overloaded by type will need to have their upper
+        // bound computed at Sema time based on the type constant.
+        if (Proto.find('s') == std::string::npos) {
           ck = ClassB;
+          if (R->getValueAsBit("isShift")) {
+            shiftstr = ", true";
+            
+            // Right shifts have an 'r' in the name, left shifts do not.
+            if (name.find('r') != std::string::npos)
+              rangestr = "l = 1; ";
+          }
+          rangestr += "u = RFT(TV" + shiftstr + ")";
+        } else {
+          rangestr = "u = " + utostr(RangeFromType(TypeVec[ti]));
+        }
+        // Make sure cases appear only once.
+        namestr = MangleName(name, TypeVec[ti], ck);
+        if (EmittedMap.count(namestr))
+          continue;
+        EmittedMap[namestr] = OpNone;
         
         OS << "case ARM::BI__builtin_neon_" 
-           << MangleName(name, TypeVec[ti], ck) << "\n";
+           << MangleName(name, TypeVec[ti], ck) << ": i = " << Proto.find('i')-1 
+           << "; " << rangestr << "; break;\n";
         continue;
       }