[LLVMdev] (MC) Register parsing for AsmParser (standalone assembler)
jcarter at mips.com
Thu Feb 2 17:33:13 PST 2012
Thank you, thank you , thank you
Knowing what the problem is a great help. I can start towards the solution now.
From: Jim Grosbach [grosbach at apple.com]
Sent: Thursday, February 02, 2012 4:43 PM
To: Carter, Jack
Subject: Re: [LLVMdev] (MC) Register parsing for AsmParser (standalone assembler)
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.
On Jan 31, 2012, at 1:26 PM, "Carter, Jack" <jcarter at mips.com<mailto:jcarter at mips.com>> wrote:
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<char>, std::allocator<char> >, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >*, std::allocator<const std::pair<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >*> >&, unsigned int, unsigned int) const: Assertion `Matches.size() == 1 && "Had duplicate keys to match on"' failed.
Background for Mips register sets:
The Mips architecture has register names that are context sensitive.
For instance, the 32 general purpose registers for both Mips32 and Mips64 have the same name, but each of the Mips32 registers are just a subregister in their Mips64 instance.
def AT : MipsGPRReg< 1, "AT">, DwarfRegNum<>;
def AT_64 : Mips64GPRReg< 1, "AT", [AT]>;
It gets more interesting with floating point where we have 3 different configurations, single precision, double precision aliased with single precision pair and straight double point precision. All of which share the same register name.
/// Mips Single point precision FPU Registers
def F0 : FPR< 0, "F0">, DwarfRegNum<>;
/// Mips Double point precision FPU Registers (aliased
/// with the single precision to hold 64 bit values)
def D0 : AFPR< 0, "F0", [F0, F1]>;
/// Mips Double point precision FPU Registers in MFP64 mode.
def D0_64 : AFPR64<0, "F0", [F0]>;
Notice that we currently need the symbolic name to be different (F0/D0/D0_64) for use in the codegen.
The examples here are from lib/Target/Mips/MipsRegisterInfo.td.
Do I just need to use/write another register parser? Or is there a clever way of defining the context sensitive Mips register set?
LLVM Developers mailing list
LLVMdev at cs.uiuc.edu<mailto:LLVMdev at cs.uiuc.edu> http://llvm.cs.uiuc.edu
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the llvm-dev