[llvm-commits] [llvm] r78581 - in /llvm/trunk: include/llvm/Target/Target.td lib/Target/X86/X86Instr64bit.td lib/Target/X86/X86InstrInfo.td lib/Target/X86/X86InstrSSE.td utils/TableGen/AsmMatcherEmitter.cpp

Daniel Dunbar daniel at zuster.org
Mon Aug 10 11:41:10 PDT 2009


Author: ddunbar
Date: Mon Aug 10 13:41:10 2009
New Revision: 78581

URL: http://llvm.org/viewvc/llvm-project?rev=78581&view=rev
Log:
llvm-mc/AsmMatcher: Change assembler parser match classes to their own record
structure.

Modified:
    llvm/trunk/include/llvm/Target/Target.td
    llvm/trunk/lib/Target/X86/X86Instr64bit.td
    llvm/trunk/lib/Target/X86/X86InstrInfo.td
    llvm/trunk/lib/Target/X86/X86InstrSSE.td
    llvm/trunk/utils/TableGen/AsmMatcherEmitter.cpp

Modified: llvm/trunk/include/llvm/Target/Target.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/Target.td?rev=78581&r1=78580&r2=78581&view=diff

==============================================================================
--- llvm/trunk/include/llvm/Target/Target.td (original)
+++ llvm/trunk/include/llvm/Target/Target.td Mon Aug 10 13:41:10 2009
@@ -278,6 +278,32 @@
 /// it to be resolved by inference in the context it is used.
 def unknown;
 
+/// AsmOperandClass - Representation for the kinds of operands which the target
+/// specific parser can create and the assembly matcher may need to distinguish.
+///
+/// Operand classes are used to define the order in which instructions are
+/// matched, to ensure that the instruction which gets matched for any
+/// particular list of operands is deterministic.
+///
+/// The target specific parser must be able to classify a parsed operand into a
+/// unique class which does not partially overlap with any other classes. It can
+/// match a subset of some other class, in which case the super class field
+/// should be defined.
+class AsmOperandClass {
+  /// The name to use for this class, this should be usable as an enum value,
+  /// and will be used to generated the names for the methods to test whether a
+  /// particular target specific operand matches this class, and the method to
+  /// convert an operand of this class into an MCInst operand.
+  string Name = ?;
+
+  /// The super class of this operand.
+  AsmOperandClass SuperClass = ?;
+}
+
+def ImmAsmOperand : AsmOperandClass {
+  let Name = "Imm";
+}
+   
 /// Operand Types - These provide the built-in operand types that may be used
 /// by a target.  Targets can optionally provide their own operand types as
 /// needed, though this should not be needed for RISC targets.
@@ -295,13 +321,7 @@
   // into a unique class, which does not partially overlap with any other 
   // classes. It can match a subset of some other class, in which case 
   // ParserMatchSuperClass should be set to the name of that class.
-  string ParserMatchClass = "Imm";
-
-  // ParserMatchSuperClass - The enclosing super class for this operand (if
-  // any). This operand *must* be a subset of the valid operands for the super
-  // class; i.e., the match predicate for this super class must return true
-  // for all instances of this class.
-  string ParserMatchSuperClass = ?;
+  AsmOperandClass ParserMatchClass = ImmAsmOperand;
 }
 
 def i1imm  : Operand<i1>;

Modified: llvm/trunk/lib/Target/X86/X86Instr64bit.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86Instr64bit.td?rev=78581&r1=78580&r2=78581&view=diff

==============================================================================
--- llvm/trunk/lib/Target/X86/X86Instr64bit.td (original)
+++ llvm/trunk/lib/Target/X86/X86Instr64bit.td Mon Aug 10 13:41:10 2009
@@ -33,14 +33,14 @@
 def lea64mem : Operand<i64> {
   let PrintMethod = "printlea64mem";
   let MIOperandInfo = (ops GR64, i8imm, GR64_NOSP, i32imm);
-  let ParserMatchClass = "Mem";
+  let ParserMatchClass = X86MemAsmOperand;
 }
 
 def lea64_32mem : Operand<i32> {
   let PrintMethod = "printlea64_32mem";
   let AsmOperandLowerMethod = "lower_lea64_32mem";
   let MIOperandInfo = (ops GR32, i8imm, GR32_NOSP, i32imm);
-  let ParserMatchClass = "Mem";
+  let ParserMatchClass = X86MemAsmOperand;
 }
 
 //===----------------------------------------------------------------------===//

Modified: llvm/trunk/lib/Target/X86/X86InstrInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrInfo.td?rev=78581&r1=78580&r2=78581&view=diff

==============================================================================
--- llvm/trunk/lib/Target/X86/X86InstrInfo.td (original)
+++ llvm/trunk/lib/Target/X86/X86InstrInfo.td Mon Aug 10 13:41:10 2009
@@ -170,10 +170,14 @@
 
 // *mem - Operand definitions for the funky X86 addressing mode operands.
 //
+def X86MemAsmOperand : AsmOperandClass {
+  let Name = "Mem";
+  let SuperClass = ImmAsmOperand;
+}
 class X86MemOperand<string printMethod> : Operand<iPTR> {
   let PrintMethod = printMethod;
   let MIOperandInfo = (ops ptr_rc, i8imm, ptr_rc_nosp, i32imm, i8imm);
-  let ParserMatchClass = "Mem";
+  let ParserMatchClass = X86MemAsmOperand;
 }
 
 def i8mem   : X86MemOperand<"printi8mem">;
@@ -193,13 +197,13 @@
 def i8mem_NOREX : Operand<i64> {
   let PrintMethod = "printi8mem";
   let MIOperandInfo = (ops GR64_NOREX, i8imm, GR64_NOREX_NOSP, i32imm, i8imm);
-  let ParserMatchClass = "Mem";
+  let ParserMatchClass = X86MemAsmOperand;
 }
 
 def lea32mem : Operand<i32> {
   let PrintMethod = "printlea32mem";
   let MIOperandInfo = (ops GR32, i8imm, GR32_NOSP, i32imm);
-  let ParserMatchClass = "Mem";
+  let ParserMatchClass = X86MemAsmOperand;
 }
 
 def SSECC : Operand<i8> {
@@ -210,16 +214,19 @@
   let PrintMethod = "printPICLabel";
 }
 
+def ImmSExt8AsmOperand : AsmOperandClass {
+  let Name = "ImmSExt8";
+  let SuperClass = ImmAsmOperand;
+}
+
 // A couple of more descriptive operand definitions.
 // 16-bits but only 8 bits are significant.
 def i16i8imm  : Operand<i16> {
-  let ParserMatchClass = "ImmSExt8";
-  let ParserMatchSuperClass = "Imm";
+  let ParserMatchClass = ImmSExt8AsmOperand;
 }
 // 32-bits but only 8 bits are significant.
 def i32i8imm  : Operand<i32> {
-  let ParserMatchClass = "ImmSExt8";
-  let ParserMatchSuperClass = "Imm";
+  let ParserMatchClass = ImmSExt8AsmOperand;
 }
 
 // Branch targets have OtherVT type and print as pc-relative values.

Modified: llvm/trunk/lib/Target/X86/X86InstrSSE.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86InstrSSE.td?rev=78581&r1=78580&r2=78581&view=diff

==============================================================================
--- llvm/trunk/lib/Target/X86/X86InstrSSE.td (original)
+++ llvm/trunk/lib/Target/X86/X86InstrSSE.td Mon Aug 10 13:41:10 2009
@@ -87,12 +87,12 @@
 def ssmem : Operand<v4f32> {
   let PrintMethod = "printf32mem";
   let MIOperandInfo = (ops ptr_rc, i8imm, ptr_rc_nosp, i32imm, i8imm);
-  let ParserMatchClass = "Mem";
+  let ParserMatchClass = X86MemAsmOperand;
 }
 def sdmem : Operand<v2f64> {
   let PrintMethod = "printf64mem";
   let MIOperandInfo = (ops ptr_rc, i8imm, ptr_rc_nosp, i32imm, i8imm);
-  let ParserMatchClass = "Mem";
+  let ParserMatchClass = X86MemAsmOperand;
 }
 
 //===----------------------------------------------------------------------===//

Modified: llvm/trunk/utils/TableGen/AsmMatcherEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/AsmMatcherEmitter.cpp?rev=78581&r1=78580&r2=78581&view=diff

==============================================================================
--- llvm/trunk/utils/TableGen/AsmMatcherEmitter.cpp (original)
+++ llvm/trunk/utils/TableGen/AsmMatcherEmitter.cpp Mon Aug 10 13:41:10 2009
@@ -87,11 +87,9 @@
 #include <set>
 using namespace llvm;
 
-namespace {
 static cl::opt<std::string>
 MatchPrefix("match-prefix", cl::init(""),
             cl::desc("Only match instructions with the given prefix"));
-}
 
 /// FlattenVariants - Flatten an .td file assembly string by selecting the
 /// variant at index \arg N.
@@ -455,21 +453,16 @@
   /// Map of token to class information which has already been constructed.
   std::map<std::string, ClassInfo*> TokenClasses;
 
-  /// Map of operand name to class information which has already been
-  /// constructed.
-  std::map<std::string, ClassInfo*> OperandClasses;
+  /// The ClassInfo instance for registers.
+  ClassInfo *TheRegisterClass;
 
-  /// Map of user class names to kind value.
-  std::map<std::string, unsigned> UserClasses;
+  /// Map of AsmOperandClass records to their class information.
+  std::map<Record*, ClassInfo*> AsmOperandClasses;
 
 private:
   /// getTokenClass - Lookup or create the class for the given token.
   ClassInfo *getTokenClass(const StringRef &Token);
 
-  /// getUserClassKind - Lookup or create the kind value for the given class
-  /// name.
-  unsigned getUserClassKind(const StringRef &Name);
-
   /// getOperandClass - Lookup or create the class for the given operand.
   ClassInfo *getOperandClass(const StringRef &Token,
                              const CodeGenInstruction::OperandInfo &OI);
@@ -543,66 +536,68 @@
   return Entry;
 }
 
-unsigned AsmMatcherInfo::getUserClassKind(const StringRef &Name) {
-  unsigned &Entry = UserClasses[Name];
-  
-  if (!Entry)
-    Entry = ClassInfo::UserClass0 + UserClasses.size() - 1;
-
-  return Entry;
-}
-
 ClassInfo *
 AsmMatcherInfo::getOperandClass(const StringRef &Token,
                                 const CodeGenInstruction::OperandInfo &OI) {
-  unsigned SuperClass = ClassInfo::Invalid;
-  std::string ClassName;
-  if (OI.Rec->isSubClassOf("RegisterClass")) {
-    ClassName = "Reg";
-  } else {
-    try {
-      ClassName = OI.Rec->getValueAsString("ParserMatchClass");
-      assert(ClassName != "Reg" && "'Reg' class name is reserved!");
-    } catch(...) {
-      PrintError(OI.Rec->getLoc(), "operand has no match class!");
-      ClassName = "Invalid";
-    }
-
-    // Determine the super class.
-    try {
-      std::string SuperClassName =
-        OI.Rec->getValueAsString("ParserMatchSuperClass");
-      SuperClass = getUserClassKind(SuperClassName);
-    } catch(...) { }
+  if (OI.Rec->isSubClassOf("RegisterClass"))
+    return TheRegisterClass;
+
+  assert(OI.Rec->isSubClassOf("Operand") && "Unexpected operand!");
+  Record *MatchClass = OI.Rec->getValueAsDef("ParserMatchClass");
+  ClassInfo *CI = AsmOperandClasses[MatchClass];
+
+  if (!CI) {
+    PrintError(OI.Rec->getLoc(), "operand has no match class!");
+    throw std::string("ERROR: Missing match class!");
   }
 
-  ClassInfo *&Entry = OperandClasses[ClassName];
-  
-  if (!Entry) {
-    Entry = new ClassInfo();
-    if (ClassName == "Reg") {
-      Entry->Kind = ClassInfo::Register;
-      Entry->SuperClassKind = SuperClass;
+  return CI;
+}
+
+void AsmMatcherInfo::BuildInfo(CodeGenTarget &Target) {
+  // Build the assembly match class information.
+
+  // Construct the "Reg" class.
+  //
+  // FIXME: This needs to dice up the RegisterClass instances.
+  ClassInfo *RegClass = TheRegisterClass = new ClassInfo();
+  RegClass->Kind = ClassInfo::Register;
+  RegClass->SuperClassKind = ClassInfo::Invalid;
+  RegClass->ClassName = "Reg";
+  RegClass->Name = "MCK_Reg";
+  RegClass->ValueName = "<register class>";
+  RegClass->PredicateMethod = "isReg";
+  RegClass->RenderMethod = "addRegOperands";
+  Classes.push_back(RegClass);
+
+  // Build info for the user defined assembly operand classes.
+  std::vector<Record*> AsmOperands;
+  AsmOperands = Records.getAllDerivedDefinitions("AsmOperandClass");
+  unsigned Index = 0;
+  for (std::vector<Record*>::iterator it = AsmOperands.begin(), 
+         ie = AsmOperands.end(); it != ie; ++it, ++Index) {
+    ClassInfo *CI = new ClassInfo();
+    CI->Kind = ClassInfo::UserClass0 + Index;
+
+    Init *Super = (*it)->getValueInit("SuperClass");
+    if (DefInit *DI = dynamic_cast<DefInit*>(Super)) {
+      CI->SuperClass = AsmOperandClasses[DI->getDef()];
+      if (!CI->SuperClass)
+        PrintError((*it)->getLoc(), "Invalid super class reference!");
     } else {
-      Entry->Kind = getUserClassKind(ClassName);
-      Entry->SuperClassKind = SuperClass;
+      assert(dynamic_cast<UnsetInit*>(Super) && "Unexpected SuperClass field!");
+      CI->SuperClass = 0;
     }
-    Entry->ClassName = ClassName;
-    Entry->Name = "MCK_" + ClassName;
-    Entry->ValueName = OI.Rec->getName();
-    Entry->PredicateMethod = "is" + ClassName;
-    Entry->RenderMethod = "add" + ClassName + "Operands";
-    Classes.push_back(Entry);
-  } else {
-    // Verify the super class matches.
-    assert(SuperClass == Entry->SuperClassKind &&
-           "Cannot redefine super class kind!");
+    CI->ClassName = (*it)->getValueAsString("Name");
+    CI->Name = "MCK_" + CI->ClassName;
+    CI->ValueName = (*it)->getName();
+    CI->PredicateMethod = "is" + CI->ClassName;
+    CI->RenderMethod = "add" + CI->ClassName + "Operands";
+    AsmOperandClasses[*it] = CI;
+    Classes.push_back(CI);
   }
-  
-  return Entry;
-}
 
-void AsmMatcherInfo::BuildInfo(CodeGenTarget &Target) {
+  // Build the instruction information.
   for (std::map<std::string, CodeGenInstruction>::const_iterator 
          it = Target.getInstructions().begin(), 
          ie = Target.getInstructions().end(); 





More information about the llvm-commits mailing list