/*
Copyright Claudio Jeker 2024
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
*/
/*
* transfer_t ontop_fcontext(fcontext_t const to, void *vp, transfer_t (*fn)(transfer_t));
*/
#define CC64FSZ 176
#define BIAS 2047
#define SP 128
#define I7 136
.file "ontop_sparc64_sysv_elf_gas.S"
.text
.align 4
.global ontop_fcontext
.type ontop_fcontext, %function
ontop_fcontext:
# prepare stack
save %sp, -CC64FSZ, %sp
# store framepointer and return address in slots reserved
# for arguments
stx %fp, [%sp + BIAS + SP]
stx %i7, [%sp + BIAS + I7]
mov %sp, %o0
# force flush register windows to stack and with that save context
flushw
# get SP (pointing to new context-data) from %i0 param
mov %i0, %sp
# load framepointer and return address from context
ldx [%sp + BIAS + SP], %fp
ldx [%sp + BIAS + I7], %i7
# ontop_fcontext requires to directly call a function on top of the
# current frame so restore register window before doing the jump
# to the context function which then is in %o2. Do not clobber
# %o7 in the jump so that (*fn)() returns to that address.
restore %o0, %g0, %o0
# restore old %sp (pointing to old context-data) in %o0
# *data stored in %o1 was not modified
jmpl %o2, %g0
nop
.size ontop_fcontext,.-ontop_fcontext
# Mark that we don't need executable stack.
.section .note.GNU-stack,"",%progbits