Add some additional capabilities to the neon emitter
authorNate Begeman <natebegeman@mac.com>
Thu, 3 Jun 2010 21:35:22 +0000 (21:35 +0000)
committerNate Begeman <natebegeman@mac.com>
Thu, 3 Jun 2010 21:35:22 +0000 (21:35 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@105416 91177308-0d34-0410-b5e6-96231b3b80d8

utils/TableGen/NeonEmitter.cpp

index cc828a5ccae4ef28fa247a88268e89842677d418..90df782f871ade419c04cc7146bd84d11a172103 100644 (file)
@@ -41,7 +41,8 @@ enum OpKind {
   OpOr,
   OpXor,
   OpAndNot,
-  OpOrNot
+  OpOrNot,
+  OpCast
 };
 
 static void ParseTypes(Record *r, std::string &s,
@@ -85,6 +86,19 @@ static char Widen(const char t) {
   return '\0';
 }
 
+static char Narrow(const char t) {
+  switch (t) {
+    case 's':
+      return 'c';
+    case 'i':
+      return 's';
+    case 'l':
+      return 'i';
+    default: throw "unhandled type in widen!";
+  }
+  return '\0';
+}
+
 static char ClassifyType(StringRef ty, bool &quad, bool &poly, bool &usgn) {
   unsigned off = 0;
   
@@ -167,6 +181,13 @@ static std::string TypeString(const char mod, StringRef typestr) {
       pntr = true;
       scal = true;
       break;
+    case 'h':
+      type = Narrow(type);
+      break;
+    case 'e':
+      type = Narrow(type);
+      usgn = true;
+      break;
     default:
       break;
   }
@@ -308,9 +329,11 @@ static std::string GenOpString(OpKind op, const std::string &proto,
   if (structTypes)
     s += "(" + ts + "){";
   
-  std::string a = structTypes ? "a.val" : "a";
-  std::string b = structTypes ? "b.val" : "b";
-  std::string c = structTypes ? "c.val" : "c";
+  std::string a, b, c;
+  if (proto.size() > 1)
+    a = (structTypes && proto[1] != 'l') ? "a.val" : "a";
+  b = structTypes ? "b.val" : "b";
+  c = structTypes ? "c.val" : "c";
   
   switch(op) {
   case OpAdd:
@@ -364,6 +387,9 @@ static std::string GenOpString(OpKind op, const std::string &proto,
   case OpOrNot:
     s += a + " | ~" + b;
     break;
+  case OpCast:
+    s += "(__neon_" + ts + ")" + a;
+    break;
   default:
     throw "unknown OpKind!";
     break;
@@ -489,6 +515,7 @@ void NeonEmitter::run(raw_ostream &OS) {
   OpMap["OP_XOR"]  = OpXor;
   OpMap["OP_ANDN"] = OpAndNot;
   OpMap["OP_ORN"]  = OpOrNot;
+  OpMap["OP_CAST"] = OpCast;
   
   // Unique the return+pattern types, and assign them.
   for (unsigned i = 0, e = RV.size(); i != e; ++i) {