Reputation: 27626
In an LLVM backend, I'd like to emit a pseudo-instruction as the relaxation of a real (non-pseudo-)instruction. The problem is, I am unable to find a way to add my pseudo-instruction expander pass in my TargetPassConfig
such that it will be applied to the output of my AsmBackend::relaxInstruction
.
Looking at MCAssembler::relaxInstruction
, which seems to be the driver for relaxation, it passes the relaxation's result directly to the instruction encoder:
bool MCAssembler::relaxInstruction(MCAsmLayout &Layout,
MCRelaxableFragment &F) {
if (!fragmentNeedsRelaxation(&F, Layout))
return false;
++stats::RelaxedInstructions;
// FIXME-PERF: We could immediately lower out instructions if we can tell
// they are fully resolved, to avoid retesting on later passes.
// Relax the fragment.
MCInst Relaxed;
getBackend().relaxInstruction(F.getInst(), F.getSubtargetInfo(), Relaxed);
// Encode the new instruction.
//
// FIXME-PERF: If it matters, we could let the target do this. It can
// probably do so more efficiently in many cases.
SmallVector<MCFixup, 4> Fixups;
SmallString<256> Code;
raw_svector_ostream VecOS(Code);
getEmitter().encodeInstruction(Relaxed, VecOS, Fixups, F.getSubtargetInfo());
// Update the fragment.
F.setInst(Relaxed);
F.getContents() = Code;
F.getFixups() = Fixups;
return true;
}
To me, this implies that I'm "on my own" in ensuring that my backend's relaxInstruction
doesn't emit any pseudo-instructions. So how do I hook my pseudo-instruction expander pass into my relaxInstruction
?
Upvotes: 0
Views: 312
Reputation: 618
Inside your target's CodeEmitter::encodeInstruction
it usually ends up with a call to getBinaryCodeForInstr
. Before this call can you expand your pseudo instruction in to the two real ones?
Upvotes: 1