1/*
2       Copyright Claudio Jeker 2024
3   Distributed under the Boost Software License, Version 1.0.
4      (See accompanying file LICENSE_1_0.txt or copy at
5          http://www.boost.org/LICENSE_1_0.txt)
6*/
7
8/*
9 * void *make_fcontext(void *sp, size_t size, void (*fn)(boost_context_data));
10 */
11#define CC64FSZ 176
12#define BIAS 2047
13#define FP 112
14#define SP 128
15#define I7 136
16
17.file "make_sparc64_sysv_elf_gas.S"
18.text
19.align  4
20.global make_fcontext
21.type   make_fcontext, %function
22make_fcontext:
23	save	%sp, -CC64FSZ, %sp
24
25	# shift address in %i0 (allocated stack) to lower 16 byte boundary
26	and	%i0, -0xf, %i0
27
28	# reserve space for two frames on the stack
29	# the first frame is for the call the second one holds the data
30	# for jump_fcontext
31	sub	%i0, 2 * CC64FSZ, %i0
32
33	# third argument of make_fcontext() is the context-function to call
34	# store it in the first stack frame, also clear %fp there to indicate
35	# the end of the stack.
36	stx	%i2, [%i0 + CC64FSZ + I7]
37	stx	%g0, [%i0 + CC64FSZ + FP]
38
39	# On OpenBSD stackghost prevents overriding the return address on
40	# a stack frame. So this code uses an extra trampoline to load
41	# to call the context-function and then do the _exit(0) dance.
42	# Extract the full address of the trampoline via pc relative addressing
431:
44	rd	%pc, %l0
45	add	%l0, (trampoline - 1b - 8), %l0
46	stx	%l0, [%i0 + I7]
47
48	# Save framepointer to first stack frame but first substract the BIAS
49	add	%i0, CC64FSZ - BIAS, %l0
50	stx	%l0, [%i0 + SP]
51
52	# Return context-data which is also includes the BIAS
53	ret
54	 restore %i0, -BIAS, %o0
55
56trampoline:
57	ldx	[%sp + BIAS + I7], %l0
58
59	# no need to setup boost_context_data, already in %o0 and %o1
60	jmpl	%l0, %o7
61	 nop
62
63	call	_exit
64	 clr	%o0
65	unimp
66.size	make_fcontext,.-make_fcontext
67# Mark that we don't need executable stack.
68.section .note.GNU-stack,"",%progbits
69