(MC) Register parsing for AsmParser (standalone assembler)

I’m trying to build a standalone assembler for Mips using AsmParser.

Following the lead of X86, ARM and MBlaze I have run tblgen -gen-asm-matcher on Mips.td to produce tables and methods to aid the parser (MipsAsmParser.cpp) which is a stripped down ARM implementation.

I am getting an assertion for what I believe are multiple register definitions with the same name.

llvm-tblgen: /home/jcarter/workarea/asm/llvm/utils/TableGen/StringMatcher.cpp:52: bool llvm::StringMatcher::EmitStringMatcherForChar(const std::vector<const std::pair<std::basic_string<char, std::char_traits, std::allocator >, std::basic_string<char, std::char_traits, std::allocator > >, std::allocator<const std::pair<std::basic_string<char, std::char_traits, std::allocator >, std::basic_string<char, std::char_traits, std::allocator > >> >&, unsigned int, unsigned int) const: Assertion `Matches.size() == 1 && “Had duplicate keys to match on”’ failed.

I’m trying to build a standalone assembler for Mips using AsmParser.

Following the lead of X86, ARM and MBlaze I have run tblgen -gen-asm-matcher on Mips.td to produce tables and methods to aid the parser (MipsAsmParser.cpp) which is a stripped down ARM implementation.

I am getting an assertion for what I believe are multiple register definitions with the same name.

llvm-tblgen: /home/jcarter/workarea/asm/llvm/utils/TableGen/StringMatcher.cpp:52: bool llvm::StringMatcher::EmitStringMatcherForChar(const std::vector<const std::pair<std::basic_string<char, std::char_traits, std::allocator >, std::basic_string<char, std::char_traits, std::allocator > >, std::allocator<const std::pair<std::basic_string<char, std::char_traits, std::allocator >, std::basic_string<char, std::char_traits, std::allocator > >> >&, unsigned int, unsigned int) const: Assertion `Matches.size() == 1 && “Had duplicate keys to match on”’ failed.

I don’t know the actual answer for your question, but it would be really great if you could add code to tblgen to have it produce an error for this case, instead of aborting.

-Chris

I agree that a clear error message is necessary to save the developer a lot of time.

I am also chronicling my steps and travails of getting the llvm-mc assembler to work for Mips so the next target has it easier.

But, it would be really nice to have insight from current AsmParser developers in the philosophy and assumptions for the current tblgen -gen-asm-matcher use.

Is it ok to not use it (MipsGenAsmMatcher.inc) and go our own way? I’d rather not, because it goes against the reuse philosophy.

Can the target.td definition be changed to allow register predicates if it doesn’t already have that? If so, I could change the register name comparison to be a register name plus predicate comparison with no predicate being a type to preserve current use.

Cheers,

Jack

Hi Jack,

You’re running into a fundamental problem with the current table generated asmmatcher. Specifically, wants to believe that assembly parsing is context insensitive, or at least close enough that operands can be parsed w/o knowing the context of the instruction. Its idea is to use the operand types to disambiguate which instruction should be selected. It sounds like MIPS 64vs.32 does things the other way around and uses the mnemonic to disambiguate what the operands mean.

You may be able to work around this a bit w/ some tblgen hacking. First, you’ll need to disable the TableGen emission of MatchRegisterName(), which is almost certainly where this is running into trouble. That’s currently unconditionally generated, and will need parameterized. Second, you’ll need to have your register name matcher explicitly check for all the valid reg names complete w/ context to disambiguate. The ARM backend does some trivial additional (not context sensitive) handling there to match register name aliases.

-Jim

Thank you, thank you , thank you

Knowing what the problem is a great help. I can start towards the solution now.

Jack