[LLVMdev] Instantiating Target-Specifc ASM Parser
Stefan Hepp
stefan at stefant.org
Wed Jul 17 05:28:20 PDT 2013
Hi,
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
convenience.
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;
public:
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,
SectionKind::getText());
PIA->SwitchSection(TS);
PatmosAsmPrinter PAP(PTM, *PIA);
PAP.EmitInlineAsm(MI);
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..).
Cheers,
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