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 ?
CodePudding user response:
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
CodePudding user response:
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 ar, at, label
mov \at, a0
.begin no_transform
_call0 1f
\label:
.end no_transform
.align 4
1:
mov \ar, a0
mov a0, \at
.endm
The no-transform
block around the call and the following label ensures that no literal pool or jump trampoline is inserted between them.