Max Muster via llvm-dev
2020-Sep-16 12:01 UTC
[llvm-dev] Aarch64: Build MachineInstruction for "ADR Xd, ."
Hi, In AArch64, the PC is not a general purpose register. However, there are other methods to read the current value of the PC to a register. According to [1], you can read the PC value via the ADR instruction: ADR Xd, . Here, the dot (".") means "here". So a label at the current location. The question is now, how to build an LLVM MachineInstruction with that? Something like this: Register PcReg = MRI.createVirtualRegister(&AArch64::GPR64RegClass); BuildMI(bb, bb.instr_begin(), DebugLoc(), TII.get(AArch64::ADR)) .addReg(PcReg) .addLabel("."); However, I am struggling in adding a label for the current location as the second operand. Best, Max [1] developer.arm.com/architectures/learn-the-architecture/armv8-a-instruction-set-architecture/registers-in-aarch64-other-registers -------------- next part -------------- An HTML attachment was scrubbed... URL: <lists.llvm.org/pipermail/llvm-dev/attachments/20200916/1a7ef8af/attachment.html>
Tim Northover via llvm-dev
2020-Sep-16 14:38 UTC
[llvm-dev] Aarch64: Build MachineInstruction for "ADR Xd, ."
Hi Max, On Wed, 16 Sep 2020 at 13:02, Max Muster via llvm-dev <llvm-dev at lists.llvm.org> wrote:> Register PcReg = MRI.createVirtualRegister(&AArch64::GPR64RegClass); > BuildMI(bb, bb.instr_begin(), > DebugLoc(), TII.get(AArch64::ADR)) > .addReg(PcReg) > .addLabel("."); > > However, I am struggling in adding a label for the current location as the second operand.If you literally just want the current address then ".addImm(0)" will do it. You need a label if some other part of the program needs to refer back to that location. In that case I think you'll need a pseudo that gets converted to a label and an ADR by AArch64AsmPrinter.cpp. Something like case AArch64::ADRAnchor: { MCSymbol *Label = MF->getContext().createTempSymbol(); MCExpr *LabelE = MCSymbolRefExpr::create(Label, MF->getContext()); OutStreamer->emitLabel(Label); EmitToStreamer(OutStreamer, MCInstBuilder(AArch64::ADR) .addReg(DestReg) .addExpr(LabelE))); } And then of course you have to work out how to tell the other code about this temporary label you created. Cheers. Tim.