1FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )
2
3	.text
4	.code64
5
6	/* Must match jmp_buf structure layout */
7	.struct	0
8env_retaddr:	.quad	0
9env_stack:	.quad	0
10env_rbx:	.quad	0
11env_rbp:	.quad	0
12env_r12:	.quad	0
13env_r13:	.quad	0
14env_r14:	.quad	0
15env_r15:	.quad	0
16	.previous
17
18/*
19 * Save stack context for non-local goto
20 */
21	.globl	setjmp
22setjmp:
23	/* Save return address */
24	movq	0(%rsp), %rax
25	movq	%rax, env_retaddr(%rdi)
26	/* Save stack pointer */
27	movq	%rsp, env_stack(%rdi)
28	/* Save other registers */
29	movq	%rbx, env_rbx(%rdi)
30	movq	%rbp, env_rbp(%rdi)
31	movq	%r12, env_r12(%rdi)
32	movq	%r13, env_r13(%rdi)
33	movq	%r14, env_r14(%rdi)
34	movq	%r15, env_r15(%rdi)
35	/* Return 0 when returning as setjmp() */
36	xorq	%rax, %rax
37	ret
38	.size	setjmp, . - setjmp
39
40/*
41 * Non-local jump to a saved stack context
42 */
43	.globl	longjmp
44longjmp:
45	/* Get result in %rax */
46	movq	%rsi, %rax
47	/* Force result to non-zero */
48	testq	%rax, %rax
49	jnz	1f
50	incq	%rax
511:	/* Restore stack pointer */
52	movq	env_stack(%rdi), %rsp
53	/* Restore other registers */
54	movq	env_rbx(%rdi), %rbx
55	movq	env_rbp(%rdi), %rbp
56	movq	env_r12(%rdi), %r12
57	movq	env_r13(%rdi), %r13
58	movq	env_r14(%rdi), %r14
59	movq	env_r15(%rdi), %r15
60	/* Replace return address on the new stack */
61	popq	%rcx	/* discard */
62	pushq	env_retaddr(%rdi)
63	/* Return to setjmp() caller */
64	ret
65	.size	longjmp, . - longjmp
66