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

337 Views Asked by At

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 ?

2

There are 2 best solutions below

4
jcmvbkbc On BEST ANSWER

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.

0
Vincent Dupaquis On

Here is a way to do this :

    .file   "getpc.S"
    .text
.Ltext0:
    .section    .text.get_pc,"ax",@progbits
    .align  4
    .global called_routine
    .type   called_routine, @function

// All this mess to get the PC (roughly) !

// This routine is called just to get the caller return address
// it is stored into the a0 register
called_routine:    
    entry   a1, 32
    mov     a2,a0
    retw.n


// This routine obtains something which contains 30 bits of the PC
// Please refer the xtensa instruction set manual (CALL8) for more information
// on how to rebuild the topmost 2 bits of it
    .align  4
    .global get_pc
    .global get_pc_return_address
    .type   get_pc, @function
get_pc:
    entry   a1, 32

    call8   called_routine
get_pc_return_address:
    mov.n   a2, a10
    retw.n