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>