blob: e43200d7b6cfb757e25db1b908d2a620d61565f7 [file] [log] [blame]
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )
.text
.code64
/* Must match jmp_buf structure layout */
.struct 0
env_retaddr: .quad 0
env_stack: .quad 0
env_rbx: .quad 0
env_rbp: .quad 0
env_r12: .quad 0
env_r13: .quad 0
env_r14: .quad 0
env_r15: .quad 0
.previous
/*
* Save stack context for non-local goto
*/
.globl setjmp
setjmp:
/* Save return address */
movq 0(%rsp), %rax
movq %rax, env_retaddr(%rdi)
/* Save stack pointer */
movq %rsp, env_stack(%rdi)
/* Save other registers */
movq %rbx, env_rbx(%rdi)
movq %rbp, env_rbp(%rdi)
movq %r12, env_r12(%rdi)
movq %r13, env_r13(%rdi)
movq %r14, env_r14(%rdi)
movq %r15, env_r15(%rdi)
/* Return 0 when returning as setjmp() */
xorq %rax, %rax
ret
.size setjmp, . - setjmp
/*
* Non-local jump to a saved stack context
*/
.globl longjmp
longjmp:
/* Get result in %rax */
movq %rsi, %rax
/* Force result to non-zero */
testq %rax, %rax
jnz 1f
incq %rax
1: /* Restore stack pointer */
movq env_stack(%rdi), %rsp
/* Restore other registers */
movq env_rbx(%rdi), %rbx
movq env_rbp(%rdi), %rbp
movq env_r12(%rdi), %r12
movq env_r13(%rdi), %r13
movq env_r14(%rdi), %r14
movq env_r15(%rdi), %r15
/* Replace return address on the new stack */
popq %rcx /* discard */
pushq env_retaddr(%rdi)
/* Return to setjmp() caller */
ret
.size longjmp, . - longjmp