diff --git a/include/llvm/Target/Target.td b/include/llvm/Target/Target.td index a30d40f97d6..dcbf5f288d8 100644 --- a/include/llvm/Target/Target.td +++ b/include/llvm/Target/Target.td @@ -290,14 +290,25 @@ def unknown; /// 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. + /// 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 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 + /// default to "isFoo", where Foo is the AsmOperandClass name. The method + /// signature should be: + /// bool isFoo() const; + string PredicateMethod = ?; + + /// The name of the method on the target specific operand to call to add the + /// target specific operand to an MCInst. If not set, this will default to + /// "addFooOperands", where Foo is the AsmOperandClass name. The method + /// signature should be: + /// void addFooOperands(MCInst &Inst, unsigned N) const; + string RenderMethod = ?; } def ImmAsmOperand : AsmOperandClass { diff --git a/lib/Target/X86/AsmParser/X86AsmParser.cpp b/lib/Target/X86/AsmParser/X86AsmParser.cpp index 5a42683a494..c3e292eb7e9 100644 --- a/lib/Target/X86/AsmParser/X86AsmParser.cpp +++ b/lib/Target/X86/AsmParser/X86AsmParser.cpp @@ -154,23 +154,23 @@ struct X86Operand { bool isReg() const { return Kind == Register; } - void addRegOperands(MCInst &Inst, unsigned N) { + void addRegOperands(MCInst &Inst, unsigned N) const { assert(N == 1 && "Invalid number of operands!"); Inst.addOperand(MCOperand::CreateReg(getReg())); } - void addImmOperands(MCInst &Inst, unsigned N) { + void addImmOperands(MCInst &Inst, unsigned N) const { assert(N == 1 && "Invalid number of operands!"); Inst.addOperand(MCOperand::CreateMCValue(getImm())); } - void addImmSExt8Operands(MCInst &Inst, unsigned N) { + void addImmSExt8Operands(MCInst &Inst, unsigned N) const { // FIXME: Support user customization of the render method. assert(N == 1 && "Invalid number of operands!"); Inst.addOperand(MCOperand::CreateMCValue(getImm())); } - void addMemOperands(MCInst &Inst, unsigned N) { + void addMemOperands(MCInst &Inst, unsigned N) const { assert((N == 4 || N == 5) && "Invalid number of operands!"); Inst.addOperand(MCOperand::CreateReg(getMemBaseReg())); diff --git a/utils/TableGen/AsmMatcherEmitter.cpp b/utils/TableGen/AsmMatcherEmitter.cpp index 0f3f9ed97f6..019348bf944 100644 --- a/utils/TableGen/AsmMatcherEmitter.cpp +++ b/utils/TableGen/AsmMatcherEmitter.cpp @@ -589,8 +589,27 @@ void AsmMatcherInfo::BuildInfo(CodeGenTarget &Target) { 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"; + + // Get or construct the predicate method name. + Init *PMName = (*it)->getValueInit("PredicateMethod"); + if (StringInit *SI = dynamic_cast(PMName)) { + CI->PredicateMethod = SI->getValue(); + } else { + assert(dynamic_cast(PMName) && + "Unexpected PredicateMethod field!"); + CI->PredicateMethod = "is" + CI->ClassName; + } + + // Get or construct the render method name. + Init *RMName = (*it)->getValueInit("RenderMethod"); + if (StringInit *SI = dynamic_cast(RMName)) { + CI->RenderMethod = SI->getValue(); + } else { + assert(dynamic_cast(RMName) && + "Unexpected RenderMethod field!"); + CI->RenderMethod = "add" + CI->ClassName + "Operands"; + } + AsmOperandClasses[*it] = CI; Classes.push_back(CI); }