tblgen/AsmMatcher: Change AsmOperandClass to allow a list of superclasses instead...
authorDaniel Dunbar <daniel@zuster.org>
Sat, 22 May 2010 21:02:29 +0000 (21:02 +0000)
committerDaniel Dunbar <daniel@zuster.org>
Sat, 22 May 2010 21:02:29 +0000 (21:02 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@104452 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Target/Target.td
lib/Target/X86/X86InstrInfo.td
utils/TableGen/AsmMatcherEmitter.cpp

index ee9e83f5d1c23a0958d604ecb7d2255cf33a7644..607dac7bd420c2c470d61cb7d1332f600a4bffa5 100644 (file)
@@ -299,8 +299,8 @@ class AsmOperandClass {
   /// The name to use for this class, which should be usable as an enum value.
   string Name = ?;
 
-  /// The super class of this operand.
-  AsmOperandClass SuperClass = ?;
+  /// The super classes of this operand.
+  list<AsmOperandClass> SuperClasses = [];
 
   /// The name of the method on the target specific operand to call to test
   /// whether the operand is an instance of this class. If not set, this will
@@ -334,10 +334,10 @@ class Operand<ValueType ty> {
   // in. Match classes are used to define the order in which instructions are
   // match, to ensure that which instructions gets matched is deterministic.
   //
-  // The target specific parser must be able to classify an 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 
-  // ParserMatchSuperClass should be set to the name of that class.
+  // The target specific parser must be able to classify an 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 AsmOperandClass
+  // should declare the other operand as one of its super classes.
   AsmOperandClass ParserMatchClass = ImmAsmOperand;
 }
 
index 803ca2fe566d6c9407f042d25b9a2165c75874d1..5a5535a2db35fc1a2c6e522da5a920738bbd08d6 100644 (file)
@@ -195,15 +195,15 @@ def ptr_rc_nosp : PointerLikeRegClass<1>;
 //
 def X86MemAsmOperand : AsmOperandClass {
   let Name = "Mem";
-  let SuperClass = ?;
+  let SuperClasses = [];
 }
 def X86NoSegMemAsmOperand : AsmOperandClass {
   let Name = "NoSegMem";
-  let SuperClass = X86MemAsmOperand;
+  let SuperClasses = [X86MemAsmOperand];
 }
 def X86AbsMemAsmOperand : AsmOperandClass {
   let Name = "AbsMem";
-  let SuperClass = X86NoSegMemAsmOperand;
+  let SuperClasses = [X86NoSegMemAsmOperand];
 }
 class X86MemOperand<string printMethod> : Operand<iPTR> {
   let PrintMethod = printMethod;
@@ -272,12 +272,12 @@ def SSECC : Operand<i8> {
 
 def ImmSExt32AsmOperand : AsmOperandClass {
   let Name = "ImmSExt32";
-  let SuperClass = ImmAsmOperand;
+  let SuperClasses = [ImmAsmOperand];
 }
 
 def ImmSExt8AsmOperand : AsmOperandClass {
   let Name = "ImmSExt8";
-  let SuperClass = ImmSExt32AsmOperand;
+  let SuperClasses = [ImmSExt32AsmOperand];
 }
 
 // A couple of more descriptive operand definitions.
index 1947824cbf886170ba86f4ac9b65d370ff85127d..783c6b5aae9416e71b45763e1a9839f5c2ee658f 100644 (file)
@@ -794,15 +794,19 @@ void AsmMatcherInfo::BuildOperandClasses(CodeGenTarget &Target) {
     ClassInfo *CI = AsmOperandClasses[*it];
     CI->Kind = ClassInfo::UserClass0 + Index;
 
-    Init *Super = (*it)->getValueInit("SuperClass");
-    if (DefInit *DI = dynamic_cast<DefInit*>(Super)) {
+    ListInit *Supers = (*it)->getValueAsListInit("SuperClasses");
+    for (unsigned i = 0, e = Supers->getSize(); i != e; ++i) {
+      DefInit *DI = dynamic_cast<DefInit*>(Supers->getElement(i));
+      if (!DI) {
+        PrintError((*it)->getLoc(), "Invalid super class reference!");
+        continue;
+      }
+
       ClassInfo *SC = AsmOperandClasses[DI->getDef()];
       if (!SC)
         PrintError((*it)->getLoc(), "Invalid super class reference!");
       else
         CI->SuperClasses.push_back(SC);
-    } else {
-      assert(dynamic_cast<UnsetInit*>(Super) && "Unexpected SuperClass field!");
     }
     CI->ClassName = (*it)->getValueAsString("Name");
     CI->Name = "MCK_" + CI->ClassName;