diff --git a/llvm/include/llvm/Target/Target.td b/llvm/include/llvm/Target/Target.td index ee9e83f5d1c2..607dac7bd420 100644 --- a/llvm/include/llvm/Target/Target.td +++ b/llvm/include/llvm/Target/Target.td @@ -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 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 { // 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; } diff --git a/llvm/lib/Target/X86/X86InstrInfo.td b/llvm/lib/Target/X86/X86InstrInfo.td index 803ca2fe566d..5a5535a2db35 100644 --- a/llvm/lib/Target/X86/X86InstrInfo.td +++ b/llvm/lib/Target/X86/X86InstrInfo.td @@ -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 : Operand { let PrintMethod = printMethod; @@ -272,12 +272,12 @@ def SSECC : Operand { 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. diff --git a/llvm/utils/TableGen/AsmMatcherEmitter.cpp b/llvm/utils/TableGen/AsmMatcherEmitter.cpp index 1947824cbf88..783c6b5aae94 100644 --- a/llvm/utils/TableGen/AsmMatcherEmitter.cpp +++ b/llvm/utils/TableGen/AsmMatcherEmitter.cpp @@ -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(Super)) { + ListInit *Supers = (*it)->getValueAsListInit("SuperClasses"); + for (unsigned i = 0, e = Supers->getSize(); i != e; ++i) { + DefInit *DI = dynamic_cast(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(Super) && "Unexpected SuperClass field!"); } CI->ClassName = (*it)->getValueAsString("Name"); CI->Name = "MCK_" + CI->ClassName;