Search code examples
assemblyprogram-counterposition-independent-codextensa

Move the PC into another register with xtensa (lx6) cores


I'm trying to get the current PC value into an assembly routine written for xtensa (lx6) cores. After digging into the instruction set doc, I cannot see really how to achieve this. It looks as if the PC is not mapped into the 16 AR, and I cannot see it listed into the registers I can access through the RSR instruction, or even the RER instruction.

Any advice ?


Solution

  • The following macro is a portable (between xtensa core configurations) way to load full 32-bit runtime address of the label label into the register ar:

    .macro  get_runtime_addr label, ar, at
            .ifgt 0x\ar - 0xa0
            mov     \at, a0
            .endif
            .begin  no-transform
            _call0  1f
    \label:
            .end    no-transform
            .align  4
    1:
            .ifgt 0x\ar - 0xa0
            mov     \ar, a0
            mov     a0, \at
            .endif
    .endm
    

    The no-transform block around the call and the following label ensures that no literal pool or jump trampoline is inserted between them.

    When the macro is used with ar other than a0 it preserves the current a0 value in the temporary register at. When ar is a0 the argument at is not used and may be omitted.