Allow multiclass def names to contain "#NAME"" where TableGen replaces
authorDavid Greene <greened@obbligato.org>
Tue, 5 May 2009 16:28:25 +0000 (16:28 +0000)
committerDavid Greene <greened@obbligato.org>
Tue, 5 May 2009 16:28:25 +0000 (16:28 +0000)
#NAME# with the name of the defm instantiating the multiclass.  This is
useful for AVX instruction naming where a "V" prefix is standard
throughout the ISA.  For example:

multiclass SSE_AVX_Inst<...> {
   def SS : Instr<...>;
   def SD : Instr<...>;
   def PS : Instr<...>;
   def PD : Instr<...>;

   def V#NAME#SS : Instr<...>;
   def V#NAME#SD : Instr<...>;
   def V#NAME#PS : Instr<...>;
   def V#NAME#PD : Instr<...>;
}

defm ADD : SSE_AVX_Inst<...>;

Results in

ADDSS
ADDSD
ADDPS
ADDPD

VADDSS
VADDSD
VADDPS
VADDPD

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@70979 91177308-0d34-0410-b5e6-96231b3b80d8

test/TableGen/MultiClassDefName.td [new file with mode: 0644]
utils/TableGen/TGLexer.cpp
utils/TableGen/TGParser.cpp

diff --git a/test/TableGen/MultiClassDefName.td b/test/TableGen/MultiClassDefName.td
new file mode 100644 (file)
index 0000000..2e71f7d
--- /dev/null
@@ -0,0 +1,12 @@
+// RUN: tblgen %s | grep WorldHelloCC | count 1
+
+class C<string n> {
+  string name = n;
+}
+
+multiclass Names<string n, string m> {
+   def CC : C<n>;
+   def World#NAME#CC : C<m>;
+}
+
+defm Hello : Names<"hello", "world">;
index f2ea7a151715186ba6bb0ed282f9f5d79f6b5d35..8eb219b66b482d1cce3b30c30bf516eb9e8cdd29 100644 (file)
@@ -98,7 +98,7 @@ tgtok::TokKind TGLexer::LexToken() {
   switch (CurChar) {
   default:
     // Handle letters: [a-zA-Z_]
-    if (isalpha(CurChar) || CurChar == '_')
+    if (isalpha(CurChar) || CurChar == '_' || CurChar == '#')
       return LexIdentifier();
       
     // Unknown character, emit an error.
@@ -220,8 +220,20 @@ tgtok::TokKind TGLexer::LexIdentifier() {
   const char *IdentStart = TokStart;
   
   // Match the rest of the identifier regex: [0-9a-zA-Z_]*
-  while (isalpha(*CurPtr) || isdigit(*CurPtr) || *CurPtr == '_')
-    ++CurPtr;
+  while (isalpha(*CurPtr) || isdigit(*CurPtr) || *CurPtr == '_'
+         || *CurPtr == '#') {
+    // If this contains a '#', make sure it's value
+    if (*CurPtr == '#') {
+      if (strncmp(CurPtr, "#NAME#", 6) != 0) {
+        return tgtok::Error;
+      }
+      CurPtr += 6;
+    }
+    else {
+      ++CurPtr;
+    }
+  }
+  
   
   // Check to see if this identifier is a keyword.
   unsigned Len = CurPtr-IdentStart;
index 2e2ec3118b00c1729d05e5876d3c4e56d5981303..ba181533c11101ea92572264773dce67219bf67d 100644 (file)
@@ -1609,9 +1609,18 @@ bool TGParser::ParseDefm() {
     for (unsigned i = 0, e = MC->DefPrototypes.size(); i != e; ++i) {
       Record *DefProto = MC->DefPrototypes[i];
 
-      // Add the suffix to the defm name to get the new name.
-      Record *CurRec = new Record(DefmPrefix + DefProto->getName(),
-                                  DefmPrefixLoc);
+      // Add in the defm name
+      std::string DefName = DefProto->getName();
+      std::string::size_type idx = DefName.find("#NAME#");
+      if (idx != std::string::npos) {
+        DefName.replace(idx, 6, DefmPrefix);
+      }
+      else {
+        // Add the suffix to the defm name to get the new name.
+        DefName = DefmPrefix + DefName;
+      }
+
+      Record *CurRec = new Record(DefName, DefmPrefixLoc);
 
       SubClassReference Ref;
       Ref.RefLoc = DefmPrefixLoc;