tinygo/src/runtime/asm_riscv.S
Ayke van Laethem 49e22fe678 runtime: load sp and pc inside tinygo_longjmp
This is a small change to make it easier to support architectures that
need to restore more than just the sp and pc registers. In particular,
it is needed for the AVR architecture that needs to restore the frame
pointer (Y register).
2022-06-19 11:51:12 +02:00

52 строки
1,2 КиБ
ArmAsm

#if __riscv_xlen==64
#define REGSIZE 8
#define SREG sd
#define LREG ld
#else
#define REGSIZE 4
#define SREG sw
#define LREG lw
#endif
.section .text.tinygo_scanCurrentStack
.global tinygo_scanCurrentStack
.type tinygo_scanCurrentStack, %function
tinygo_scanCurrentStack:
// Push callee-saved registers onto the stack.
addi sp, sp, -13*REGSIZE
SREG ra, 0*REGSIZE(sp)
SREG s11, 1*REGSIZE(sp)
SREG s10, 2*REGSIZE(sp)
SREG s9, 3*REGSIZE(sp)
SREG s8, 4*REGSIZE(sp)
SREG s7, 5*REGSIZE(sp)
SREG s6, 6*REGSIZE(sp)
SREG s5, 7*REGSIZE(sp)
SREG s4, 8*REGSIZE(sp)
SREG s3, 9*REGSIZE(sp)
SREG s2, 10*REGSIZE(sp)
SREG s1, 11*REGSIZE(sp)
SREG s0, 12*REGSIZE(sp)
// Scan the stack.
mv a0, sp
call tinygo_scanstack
// Restore return address.
LREG ra, 0(sp)
// Restore stack state.
addi sp, sp, 13*REGSIZE
// Return to the caller.
ret
.section .text.tinygo_longjmp
.global tinygo_longjmp
tinygo_longjmp:
// Note: the code we jump to assumes a0 is non-zero, which is already the
// case because that's the defer frame pointer.
lw sp, 0(a0) // jumpSP
lw a1, REGSIZE(a0) // jumpPC
jr a1