Переместите ПК в другой регистр с ядрами xtensa (lx6)
Я пытаюсь получить текущее значение ПК в процедуре сборки, написанной для ядер xtensa (lx6). Покопавшись в документации по набору инструкций, я не могу понять, как этого добиться. Похоже, что ПК не отображается в 16 AR, и я не вижу его в списке регистров, к которым я могу получить доступ с помощью инструкции RSR или даже инструкции RER.
Любой совет ?
2 ответа
Следующий макрос является переносимым (между конфигурациями ядра xtensa) способом загрузки полного 32-битного адреса времени выполнения метки.label
в реестр:
.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
блок вокруг вызова, а следующая метка гарантирует, что между ними не будет вставлен буквальный пул или батут для прыжков.
Когда макрос используется с другими параметрами, он сохраняет текущее значение во временном регистре. Когдаar
являетсяa0
Аргументat
не используется и может быть опущен.
Вот как это сделать:
.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