Cactus
Cactus

Reputation: 27626

Emitting a pseudo-instruction during relaxation

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

Answers (1)

Colin LeMahieu
Colin LeMahieu

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

Related Questions