Index: include/llvm/Target/Target.td =================================================================== --- include/llvm/Target/Target.td +++ include/llvm/Target/Target.td @@ -488,6 +488,12 @@ /// constraint. For example, "$Rn = $Rd". string TwoOperandAliasConstraint = ""; + /// Assembler variant name to use for this instruction. If specified then + /// instruction will be presented only in MatchTable for this variant. If + /// not specified then assembler variants will be determined based on + /// AsmString + string AsmVariantName = ""; + ///@} /// UseNamedOperandTable - If set, the operand indices of this instruction @@ -1126,6 +1132,10 @@ // defined AsmMatchConverter and instead use the function generated by the // dag Result. bit UseInstAsmMatchConverter = 1; + + // Assembler variant name to use for this alias. If not specified then + // assembler variants will be determined based on AsmString + string AsmVariantName = ""; } //===----------------------------------------------------------------------===// Index: test/TableGen/AsmVariant.td =================================================================== --- /dev/null +++ test/TableGen/AsmVariant.td @@ -0,0 +1,46 @@ +// RUN: llvm-tblgen -gen-asm-matcher -I %p/../../include %s | FileCheck %s + +// Check that cpecifying AsmVariant works correctly + +include "llvm/Target/Target.td" + +def ArchInstrInfo : InstrInfo { } + +def FooAsmParserVariant : AsmParserVariant { + let Variant = 0; + let Name = "Foo"; +} + +def BarAsmParserVariant : AsmParserVariant { + let Variant = 1; + let Name = "Bar"; +} + +def Arch : Target { + let InstructionSet = ArchInstrInfo; + let AssemblyParserVariants = [FooAsmParserVariant, BarAsmParserVariant]; +} + +def Reg : Register<"reg">; + +def RegClass : RegisterClass<"foo", [i32], 0, (add Reg)>; + +def foo : Instruction { + let Size = 2; + let OutOperandList = (outs); + let InOperandList = (ins); + let AsmString = "foo"; + let AsmVariantName = "Foo"; +} + +def BarAlias : InstAlias<"bar", (foo)> { + string AsmVariantName = "Bar"; +} + +// CHECK: static const MatchEntry MatchTable0[] = { +// CHECK-NEXT: /* foo */, Arch::foo +// CHECK-NEXT: }; + +// CHECK: static const MatchEntry MatchTable1[] = { +// CHECK-NEXT: /* bar */, Arch::foo +// CHECK-NEXT: }; Index: utils/TableGen/AsmMatcherEmitter.cpp =================================================================== --- utils/TableGen/AsmMatcherEmitter.cpp +++ utils/TableGen/AsmMatcherEmitter.cpp @@ -353,6 +353,7 @@ std::string TokenizingCharacters; std::string SeparatorCharacters; std::string BreakCharacters; + std::string Name; int AsmVariantNo; }; @@ -1468,6 +1469,7 @@ AsmVariant->getValueAsString("SeparatorCharacters"); Variant.BreakCharacters = AsmVariant->getValueAsString("BreakCharacters"); + Variant.Name = AsmVariant->getValueAsString("Name"); Variant.AsmVariantNo = AsmVariant->getValueAsInt("Variant"); for (const CodeGenInstruction *CGI : Target.getInstructionsByEnumValue()) { @@ -1481,6 +1483,11 @@ if (CGI->TheDef->getValueAsBit("isCodeGenOnly")) continue; + // Ignore instructions for different instructions + const std::string V = CGI->TheDef->getValueAsString("AsmVariantName"); + if (!V.empty() && V != Variant.Name) + continue; + auto II = llvm::make_unique(*CGI); II->initialize(*this, SingletonRegisters, Variant, HasMnemonicFirst); @@ -1509,6 +1516,10 @@ .startswith( MatchPrefix)) continue; + const std::string V = Alias->TheDef->getValueAsString("AsmVariantName"); + if (!V.empty() && V != Variant.Name) + continue; + auto II = llvm::make_unique(std::move(Alias)); II->initialize(*this, SingletonRegisters, Variant, HasMnemonicFirst);