[LLVMdev] Instantiating Target-Specifc ASM Parser

Stefan Hepp stefan at stefant.org
Wed Jul 17 05:28:20 PDT 2013


We are using the AsmParser to analyse inline asm instructions in our 
backend, i.e. to get the actual size in bytes of an instruction or to 
find all calls,.. I assume this might be similar to what you want to do.
I let AsmPrinter do all the hard work of parsing inline asm and 
instantiating everything. This might be a bit of an overkill though if 
you do not need inline-asm parsing (it replaces placeholders with proper 
register names, ...). For your case it might be sufficient to have a 
look at the code in AsmParser::EmitInlineAsm(StringRef Str, ..). You 
will need to have a proper context and MCStreamer object though..

Here is what I did to make this happen:

1) Extract a header for the MCNullStreamer class to include/llvm/MC to 
be able to make subclasses. I will attach the modified files for your 

2) Make the EmitInlineAsm functions in AsmPrinter public. Move 
construction and deletion of the Mangler in AsmPrinter.cpp into the 
constructor/destructor of AsmPrinter. In AsmPrinter::EmitInlineAsm 
(AsmPrinterInlineAsm.cpp:93), add an 'if (MMI) { .. }' to skip the 
DiagnosticHandler stuff if MMI is not set.

3) Create a subclass of MCNullStreamer to visit all parsed instructions 
in the inline asm code, like so:

class InstrAnalyzer : public MCNullStreamer {
   const MCInstrInfo &MII;
   unsigned size;
   InstrAnalyzer(MCContext &ctx)
     : MCNullStreamer(ctx), MII(ctx.getInstrInfo()), size(0)
     { }
   virtual void EmitInstruction(const MCInst &Inst) {
     const MCInstrDesc &MID = MII.get(Inst.getOpcode());
     size += MID.getSize();

4) Create a new AsmPrinter and use it to parse and emit asm, e.g. like 
so (our backend is called Patmos, so do not wonder about this..):

unsigned int PatmosInstrInfo::getInstrSize(const MachineInstr *MI) const {
   if (MI->isInlineAsm()) {
     // PTM is the TargetMachine
     // TODO is there a way to get the current context?
     MCContext Ctx(*PTM.getMCAsmInfo(),
                   *PTM.getRegisterInfo(), *PTM.getInstrInfo(), 0);

     // PIA is deleted by AsmPrinter
     PatmosInstrAnalyzer *PIA = new InstrAnalyzer(Ctx);

     // PTM.getTargetLowering()->getObjFileLowering() might not yet be
     // initialized, so we create a new section object for this temp context
     const MCSection* TS = Ctx.getELFSection(".text",
                                             ELF::SHT_PROGBITS, 0,

     PatmosAsmPrinter PAP(PTM, *PIA);

     return PIA->getSize();
   else if (MI->isBundle()) {
     // handle bundles..
     unsigned size = ...;
     return size;
   else {
     // trust the desc..
     return MI->getDesc().getSize();

I tested this with LLVM 3.2, and it should work with LLVM 3.3 (though I 
am not finished testing it..).

  Stefan Hepp

On 07/16/2013 02:27 PM, Dunn, Kyle wrote:
> Hello,
> I am working on backend development and would like to utilize my
> target's MCAsmParser inside of an MCInst-level class implementation. I
> noticed that the AsmParser is registered with the target registry
> however I am having no luck grepping for a "template" of how to
> instantiate it and have yet to find specific documentation on how it is
> done. Any ideas or help is greatly appreciated!
> Cheers,
> Kyle Dunn
> _______________________________________________
> LLVM Developers mailing list
> LLVMdev at cs.uiuc.edu         http://llvm.cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
-------------- next part --------------
A non-text attachment was scrubbed...
Name: MCNullStreamer.h
Type: text/x-chdr
Size: 4579 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20130717/9246b522/attachment.h>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: MCNullStreamer.cpp
Type: text/x-c++src
Size: 877 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20130717/9246b522/attachment.cpp>

More information about the llvm-dev mailing list