[llvm-commits] [llvm] r69822 - in /llvm/trunk: docs/TableGenFundamentals.html test/TableGen/nameconcat.td utils/TableGen/CodeGenInstruction.cpp utils/TableGen/Record.cpp utils/TableGen/Record.h utils/TableGen/TGLexer.cpp utils/TableGen/TGLexer.h utils/TableGen/TGParser.cpp

David Greene greened at obbligato.org
Wed Apr 22 13:18:10 PDT 2009


Author: greened
Date: Wed Apr 22 15:18:10 2009
New Revision: 69822

URL: http://llvm.org/viewvc/llvm-project?rev=69822&view=rev
Log:

Implement !nameconcat to concatenate strings and look up the resulting
name in the symbol table, returning an object.

Added:
    llvm/trunk/test/TableGen/nameconcat.td
Modified:
    llvm/trunk/docs/TableGenFundamentals.html
    llvm/trunk/utils/TableGen/CodeGenInstruction.cpp
    llvm/trunk/utils/TableGen/Record.cpp
    llvm/trunk/utils/TableGen/Record.h
    llvm/trunk/utils/TableGen/TGLexer.cpp
    llvm/trunk/utils/TableGen/TGLexer.h
    llvm/trunk/utils/TableGen/TGParser.cpp

Modified: llvm/trunk/docs/TableGenFundamentals.html
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/TableGenFundamentals.html?rev=69822&r1=69821&r2=69822&view=diff

==============================================================================
--- llvm/trunk/docs/TableGenFundamentals.html (original)
+++ llvm/trunk/docs/TableGenFundamentals.html Wed Apr 22 15:18:10 2009
@@ -398,6 +398,11 @@
 <dt><tt>!strconcat(a, b)</tt></dt>
   <dd>A string value that is the result of concatenating the 'a' and 'b'
   strings.</dd>
+<dt><tt>!nameconcat(a, b)</tt></dt>
+  <dd>A value that is the result of concatenating the 'a' and 'b'
+  strings and looking up the resulting name in the symbol table.  The symbol type 
+  determines the type of the resulting value.  If the symbol is not found, 
+  TableGen emits an error and aborts.</dd>
 </dl>
 
 <p>Note that all of the values have rules specifying how they convert to values
@@ -627,8 +632,9 @@
 
 <p>The name of the resultant definitions has the multidef fragment names
    appended to them, so this defines <tt>ADD_rr</tt>, <tt>ADD_ri</tt>,
-   <tt>SUB_rr</tt>, etc.  Using a multiclass this way is exactly equivalent to
-   instantiating the classes multiple times yourself, e.g. by writing:</p>
+   <tt>SUB_rr</tt>, etc.  Using a multiclass this way is exactly
+   equivalent to instantiating the classes multiple times yourself,
+   e.g. by writing:</p>
 
 <div class="doc_code">
 <pre>

Added: llvm/trunk/test/TableGen/nameconcat.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/TableGen/nameconcat.td?rev=69822&view=auto

==============================================================================
--- llvm/trunk/test/TableGen/nameconcat.td (added)
+++ llvm/trunk/test/TableGen/nameconcat.td Wed Apr 22 15:18:10 2009
@@ -0,0 +1,76 @@
+// RUN: tblgen %s | grep {add_ps} | count 2
+
+class ValueType<int size, int value> {
+  int Size = size;
+  int Value = value;
+}
+
+def v2i64  : ValueType<128, 22>;   //  2 x i64 vector value
+def v2f64  : ValueType<128, 28>;   //  2 x f64 vector value
+
+class Intrinsic<string name> {
+  string Name = name;
+}
+
+class Inst<bits<8> opcode, dag oopnds, dag iopnds, string asmstr, 
+           list<dag> pattern> {
+  bits<8> Opcode = opcode;
+  dag OutOperands = oopnds;
+  dag InOperands = iopnds;
+  string AssemblyString = asmstr;
+  list<dag> Pattern = pattern;
+}
+
+def ops;
+def outs;
+def ins;
+
+def set;
+
+// Define registers
+class Register<string n> {
+  string Name = n;
+}
+
+class RegisterClass<list<ValueType> regTypes, list<Register> regList> {
+  list<ValueType> RegTypes = regTypes;
+  list<Register> MemberList = regList;
+}
+
+def XMM0: Register<"xmm0">;
+def XMM1: Register<"xmm1">;
+def XMM2: Register<"xmm2">;
+def XMM3: Register<"xmm3">;
+def XMM4: Register<"xmm4">;
+def XMM5: Register<"xmm5">;
+def XMM6: Register<"xmm6">;
+def XMM7: Register<"xmm7">;
+def XMM8:  Register<"xmm8">;
+def XMM9:  Register<"xmm9">;
+def XMM10: Register<"xmm10">;
+def XMM11: Register<"xmm11">;
+def XMM12: Register<"xmm12">;
+def XMM13: Register<"xmm13">;
+def XMM14: Register<"xmm14">;
+def XMM15: Register<"xmm15">;
+
+def VR128 : RegisterClass<[v2i64, v2f64],
+                          [XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7,
+                           XMM8, XMM9, XMM10, XMM11,
+                           XMM12, XMM13, XMM14, XMM15]>;
+
+// Define intrinsics
+def int_x86_sse2_add_ps : Intrinsic<"addps">;
+def int_x86_sse2_add_pd : Intrinsic<"addpd">;
+
+multiclass arith<bits<8> opcode, string asmstr, string Intr> {
+  def PS : Inst<opcode, (outs VR128:$dst), (ins VR128:$src1, VR128:$src2),
+                 !strconcat(asmstr, "\t$dst, $src1, $src2"),
+                 [(set VR128:$dst, (!nameconcat(Intr, "_ps") VR128:$src1, VR128:$src2))]>;
+
+  def PD : Inst<opcode, (outs VR128:$dst), (ins VR128:$src1, VR128:$src2),
+                 !strconcat(asmstr, "\t$dst, $src1, $src2"),
+                 [(set VR128:$dst, (!nameconcat(Intr, "_pd") VR128:$src1, VR128:$src2))]>;
+}
+
+defm ADD : arith<0x58, "add", "int_x86_sse2_add">;

Modified: llvm/trunk/utils/TableGen/CodeGenInstruction.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CodeGenInstruction.cpp?rev=69822&r1=69821&r2=69822&view=diff

==============================================================================
--- llvm/trunk/utils/TableGen/CodeGenInstruction.cpp (original)
+++ llvm/trunk/utils/TableGen/CodeGenInstruction.cpp Wed Apr 22 15:18:10 2009
@@ -127,7 +127,7 @@
     OperandList.clear();
     return;
   }
-  DI = (DagInit*)(new BinOpInit(BinOpInit::CONCAT, DI, IDI))->Fold();
+  DI = (DagInit*)(new BinOpInit(BinOpInit::CONCAT, DI, IDI))->Fold(R, 0);
 
   unsigned MIOperandNo = 0;
   std::set<std::string> OperandNames;

Modified: llvm/trunk/utils/TableGen/Record.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/Record.cpp?rev=69822&r1=69821&r2=69822&view=diff

==============================================================================
--- llvm/trunk/utils/TableGen/Record.cpp (original)
+++ llvm/trunk/utils/TableGen/Record.cpp Wed Apr 22 15:18:10 2009
@@ -395,7 +395,7 @@
   return Result + "]";
 }
 
-Init *BinOpInit::Fold() {
+Init *BinOpInit::Fold(Record *CurRec, MultiClass *CurMultiClass) {
   switch (getOpcode()) {
   default: assert(0 && "Unknown binop");
   case CONCAT: {
@@ -437,6 +437,43 @@
       return new StringInit(LHSs->getValue() + RHSs->getValue());
     break;
   }
+  case NAMECONCAT: {
+    StringInit *LHSs = dynamic_cast<StringInit*>(LHS);
+    StringInit *RHSs = dynamic_cast<StringInit*>(RHS);
+    if (LHSs && RHSs) {
+      std::string Name(LHSs->getValue() + RHSs->getValue());
+
+      // From TGParser::ParseIDValue
+      if (CurRec) {
+        if (const RecordVal *RV = CurRec->getValue(Name))
+          return new VarInit(Name, RV->getType());
+
+        std::string TemplateArgName = CurRec->getName()+":"+Name;
+        if (CurRec->isTemplateArg(TemplateArgName)) {
+          const RecordVal *RV = CurRec->getValue(TemplateArgName);
+          assert(RV && "Template arg doesn't exist??");
+          return new VarInit(TemplateArgName, RV->getType());
+        }
+      }
+
+      if (CurMultiClass) {
+        std::string MCName = CurMultiClass->Rec.getName()+"::"+Name;
+        if (CurMultiClass->Rec.isTemplateArg(MCName)) {
+          const RecordVal *RV = CurMultiClass->Rec.getValue(MCName);
+          assert(RV && "Template arg doesn't exist??");
+          return new VarInit(MCName, RV->getType());
+        }
+      }
+
+      if (Record *D = Records.getDef(Name))
+        return new DefInit(D);
+
+      cerr << "Variable not defined: '" + Name + "'\n";
+      assert(0 && "Variable not found");
+      return 0;
+    }
+    break;
+  }
   case SHL:
   case SRA:
   case SRL: {
@@ -464,8 +501,8 @@
   Init *rhs = RHS->resolveReferences(R, RV);
   
   if (LHS != lhs || RHS != rhs)
-    return (new BinOpInit(getOpcode(), lhs, rhs))->Fold();
-  return Fold();
+    return (new BinOpInit(getOpcode(), lhs, rhs))->Fold(&R, 0);
+  return Fold(&R, 0);
 }
 
 std::string BinOpInit::getAsString() const {
@@ -476,6 +513,7 @@
   case SRA: Result = "!sra"; break;
   case SRL: Result = "!srl"; break;
   case STRCONCAT: Result = "!strconcat"; break;
+  case NAMECONCAT: Result = "!nameconcat"; break;
   }
   return Result + "(" + LHS->getAsString() + ", " + RHS->getAsString() + ")";
 }

Modified: llvm/trunk/utils/TableGen/Record.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/Record.h?rev=69822&r1=69821&r2=69822&view=diff

==============================================================================
--- llvm/trunk/utils/TableGen/Record.h (original)
+++ llvm/trunk/utils/TableGen/Record.h Wed Apr 22 15:18:10 2009
@@ -53,6 +53,7 @@
 // Other classes.
 class Record;
 class RecordVal;
+class MultiClass;
 
 //===----------------------------------------------------------------------===//
 //  Type Classes
@@ -659,7 +660,7 @@
 ///
 class BinOpInit : public Init {
 public:
-  enum BinaryOp { SHL, SRA, SRL, STRCONCAT, CONCAT };
+  enum BinaryOp { SHL, SRA, SRL, STRCONCAT, CONCAT, NAMECONCAT };
 private:
   BinaryOp Opc;
   Init *LHS, *RHS;
@@ -673,7 +674,7 @@
 
   // Fold - If possible, fold this to a simpler init.  Return this if not
   // possible to fold.
-  Init *Fold();
+  Init *Fold(Record *CurRec, MultiClass *CurMultiClass);
 
   virtual Init *convertInitializerTo(RecTy *Ty) {
     return Ty->convertValue(this);
@@ -1124,6 +1125,14 @@
 
 std::ostream &operator<<(std::ostream &OS, const Record &R);
 
+struct MultiClass {
+  Record Rec;  // Placeholder for template args and Name.
+  typedef std::vector<Record*> RecordVector;
+  RecordVector DefPrototypes;
+    
+  MultiClass(const std::string &Name, TGLoc Loc) : Rec(Name, Loc) {}
+};
+
 class RecordKeeper {
   std::map<std::string, Record*> Classes, Defs;
 public:

Modified: llvm/trunk/utils/TableGen/TGLexer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/TGLexer.cpp?rev=69822&r1=69821&r2=69822&view=diff

==============================================================================
--- llvm/trunk/utils/TableGen/TGLexer.cpp (original)
+++ llvm/trunk/utils/TableGen/TGLexer.cpp Wed Apr 22 15:18:10 2009
@@ -429,11 +429,12 @@
   // Check to see which operator this is.
   unsigned Len = CurPtr-Start;
   
-  if (Len == 3 && !memcmp(Start, "con", 3)) return tgtok::XConcat;
-  if (Len == 3 && !memcmp(Start, "sra", 3)) return tgtok::XSRA;
-  if (Len == 3 && !memcmp(Start, "srl", 3)) return tgtok::XSRL;
-  if (Len == 3 && !memcmp(Start, "shl", 3)) return tgtok::XSHL;
-  if (Len == 9 && !memcmp(Start, "strconcat", 9)) return tgtok::XStrConcat;
+  if (Len == 3  && !memcmp(Start, "con", 3)) return tgtok::XConcat;
+  if (Len == 3  && !memcmp(Start, "sra", 3)) return tgtok::XSRA;
+  if (Len == 3  && !memcmp(Start, "srl", 3)) return tgtok::XSRL;
+  if (Len == 3  && !memcmp(Start, "shl", 3)) return tgtok::XSHL;
+  if (Len == 9  && !memcmp(Start, "strconcat", 9))   return tgtok::XStrConcat;
+  if (Len == 10 && !memcmp(Start, "nameconcat", 10)) return tgtok::XNameConcat;
   
   return ReturnError(Start-1, "Unknown operator");
 }

Modified: llvm/trunk/utils/TableGen/TGLexer.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/TGLexer.h?rev=69822&r1=69821&r2=69822&view=diff

==============================================================================
--- llvm/trunk/utils/TableGen/TGLexer.h (original)
+++ llvm/trunk/utils/TableGen/TGLexer.h Wed Apr 22 15:18:10 2009
@@ -45,8 +45,8 @@
     MultiClass, String,
     
     // !keywords.
-    XConcat, XSRA, XSRL, XSHL, XStrConcat,
-    
+    XConcat, XSRA, XSRL, XSHL, XStrConcat, XNameConcat,
+
     // Integer value.
     IntVal,
     

Modified: llvm/trunk/utils/TableGen/TGParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/TGParser.cpp?rev=69822&r1=69821&r2=69822&view=diff

==============================================================================
--- llvm/trunk/utils/TableGen/TGParser.cpp (original)
+++ llvm/trunk/utils/TableGen/TGParser.cpp Wed Apr 22 15:18:10 2009
@@ -23,14 +23,6 @@
 //===----------------------------------------------------------------------===//
 
 namespace llvm {
-struct MultiClass {
-  Record Rec;  // Placeholder for template args and Name.
-  typedef std::vector<Record*> RecordVector;
-  RecordVector DefPrototypes;
-    
-  MultiClass(const std::string &Name, TGLoc Loc) : Rec(Name, Loc) {}
-};
-  
 struct SubClassReference {
   TGLoc RefLoc;
   Record *Rec;
@@ -777,14 +769,47 @@
   }
   case tgtok::l_paren: {         // Value ::= '(' IDValue DagArgList ')'
     Lex.Lex();   // eat the '('
-    if (Lex.getCode() != tgtok::Id) {
+    if (Lex.getCode() != tgtok::Id
+        && Lex.getCode() != tgtok::XNameConcat) {
       TokError("expected identifier in dag init");
       return 0;
     }
     
-    Init *Operator = ParseIDValue(CurRec);
-    if (Operator == 0) return 0;
-    
+    Init *Operator = 0;
+    if (Lex.getCode() == tgtok::Id) {
+      Operator = ParseIDValue(CurRec);
+      if (Operator == 0) return 0;
+    }
+    else {
+      BinOpInit::BinaryOp Code = BinOpInit::NAMECONCAT;
+ 
+      Lex.Lex();  // eat the operation
+      if (Lex.getCode() != tgtok::l_paren) {
+        TokError("expected '(' after binary operator");
+        return 0;
+      }
+      Lex.Lex();  // eat the '('
+
+      Init *LHS = ParseValue(CurRec);
+      if (LHS == 0) return 0;
+
+      if (Lex.getCode() != tgtok::comma) {
+        TokError("expected ',' in binary operator");
+        return 0;
+      }
+      Lex.Lex();  // eat the ','
+
+      Init *RHS = ParseValue(CurRec);
+       if (RHS == 0) return 0;
+
+       if (Lex.getCode() != tgtok::r_paren) {
+         TokError("expected ')' in binary operator");
+         return 0;
+       }
+       Lex.Lex();  // eat the ')'
+       Operator = (new BinOpInit(Code, LHS, RHS))->Fold(CurRec, CurMultiClass);
+    }
+
     // If the operator name is present, parse it.
     std::string OperatorName;
     if (Lex.getCode() == tgtok::colon) {
@@ -796,7 +821,6 @@
       Lex.Lex();  // eat the VarName.
     }
     
-    
     std::vector<std::pair<llvm::Init*, std::string> > DagArgs;
     if (Lex.getCode() != tgtok::r_paren) {
       DagArgs = ParseDagArgList(CurRec);
@@ -815,15 +839,17 @@
   case tgtok::XSRA: 
   case tgtok::XSRL:
   case tgtok::XSHL:
-  case tgtok::XStrConcat: {  // Value ::= !binop '(' Value ',' Value ')'
+  case tgtok::XStrConcat:
+  case tgtok::XNameConcat: {  // Value ::= !binop '(' Value ',' Value ')'
     BinOpInit::BinaryOp Code;
     switch (Lex.getCode()) {
     default: assert(0 && "Unhandled code!");
-    case tgtok::XConcat:    Code = BinOpInit::CONCAT; break;
-    case tgtok::XSRA:       Code = BinOpInit::SRA; break;
-    case tgtok::XSRL:       Code = BinOpInit::SRL; break;
-    case tgtok::XSHL:       Code = BinOpInit::SHL; break;
-    case tgtok::XStrConcat: Code = BinOpInit::STRCONCAT; break;
+    case tgtok::XConcat:     Code = BinOpInit::CONCAT; break;
+    case tgtok::XSRA:        Code = BinOpInit::SRA; break;
+    case tgtok::XSRL:        Code = BinOpInit::SRL; break;
+    case tgtok::XSHL:        Code = BinOpInit::SHL; break;
+    case tgtok::XStrConcat:  Code = BinOpInit::STRCONCAT; break;
+    case tgtok::XNameConcat: Code = BinOpInit::NAMECONCAT; break;
     }
     Lex.Lex();  // eat the operation
     if (Lex.getCode() != tgtok::l_paren) {
@@ -831,7 +857,7 @@
       return 0;
     }
     Lex.Lex();  // eat the '('
-    
+
     Init *LHS = ParseValue(CurRec);
     if (LHS == 0) return 0;
 
@@ -849,7 +875,7 @@
       return 0;
     }
     Lex.Lex();  // eat the ')'
-    return (new BinOpInit(Code, LHS, RHS))->Fold();
+    return (new BinOpInit(Code, LHS, RHS))->Fold(CurRec, CurMultiClass);
   }
   }
   





More information about the llvm-commits mailing list