
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).
52 строки
1,2 КиБ
ArmAsm
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
|