/* Copyright 2011-2012 Nicholas J. Kain, licensed under standard MIT license */
// 2025-02-24: some tweaks from djb

.global ___longjmp
.global __longjmp
.global _longjmp
.global longjmp
.type ___longjmp,@function
.type __longjmp,@function
.type _longjmp,@function
.type longjmp,@function
___longjmp:
__longjmp:
_longjmp:
longjmp:
	mov %rsi,%rax           /* val will be longjmp return */
	test %rax,%rax
	jnz 1f
	inc %rax                /* if val==0, val=1 per longjmp semantics */
1:
	movq (%rdi),%rbx         /* rdi is the jmp_buf, restore regs from it */
	movq 8(%rdi),%rbp
	movq 16(%rdi),%r12
	movq 24(%rdi),%r13
	movq 32(%rdi),%r14
	movq 40(%rdi),%r15
	movq 48(%rdi),%rdx       /* this ends up being the stack pointer */
	movq %rdx,%rsp
	movq 56(%rdi),%rdx       /* this is the instruction pointer */
	jmp *%rdx               /* goto saved address without altering rsp */

.global ___setjmp
.global __setjmp
.global _setjmp
.global setjmp
.type ___setjmp,@function
.type __setjmp,@function
.type _setjmp,@function
.type setjmp,@function
___setjmp:
__setjmp:
_setjmp:
setjmp:
	movq %rbx,(%rdi)         /* rdi is jmp_buf, move registers onto it */
	movq %rbp,8(%rdi)
	movq %r12,16(%rdi)
	movq %r13,24(%rdi)
	movq %r14,32(%rdi)
	movq %r15,40(%rdi)
	leaq 8(%rsp),%rdx        /* this is our rsp WITHOUT current ret addr */
	movq %rdx,48(%rdi)
	movq (%rsp),%rdx         /* save return addr ptr for new rip */
	movq %rdx,56(%rdi)
	xorq %rax,%rax           /* always return 0 */
	ret

.global ___sigsetjmp
.global __sigsetjmp
.global _sigsetjmp
.global sigsetjmp
.type ___sigsetjmp,@function
.type __sigsetjmp,@function
.type _sigsetjmp,@function
.type sigsetjmp,@function
___sigsetjmp:
__sigsetjmp:
_sigsetjmp:
sigsetjmp:
	test %rsi,%rsi
	movq %rsi,64(%rdi)
	jz 1f
	pushq %rdi
	leaq 72(%rdi),%rdx
	xorq %rsi,%rsi
	movq $2,%rdi
	call sigprocmask
	popq %rdi
1:	jmp setjmp

.global ___siglongjmp
.global __siglongjmp
.global _siglongjmp
.global siglongjmp
.type ___siglongjmp,@function
.type __siglongjmp,@function
.type _siglongjmp,@function
.type siglongjmp,@function
___siglongjmp:
__siglongjmp:
_siglongjmp:
siglongjmp:
	movq 64(%rdi),%rdx
	test %rdx,%rdx
	jz 1f
	pushq %rdi
	leaq 72(%rdi),%rsi
	xorq %rdx,%rdx
	movq $2,%rdi
	call sigprocmask
	popq %rdi
1:	jmp longjmp

.section	.note.GNU-stack,"",@progbits