Since I did most of the work for php I decided to also implement the fiber / context ASM for sparc64 in boost.
The difference is that boost has a ontop_fcontext() function which is not really documented but in the end I figured it out. I did test this against the tests in boost-context. Will do more tests tomorrow but maybe someone else wants to join the context party :) -- :wq Claudio Index: Makefile =================================================================== RCS file: /cvs/ports/devel/boost/Makefile,v diff -u -p -r1.142 Makefile --- Makefile 4 Jan 2024 08:16:16 -0000 1.142 +++ Makefile 8 Feb 2024 16:51:47 -0000 @@ -1,4 +1,4 @@ -NOT_FOR_ARCHS-md = alpha hppa sparc64 +NOT_FOR_ARCHS-md = alpha hppa DPB_PROPERTIES= parallel @@ -132,7 +132,7 @@ SUBST_VARS+= SO_VERSION # Revert back to Boost::Context 1.80.0 ASM code for i386 post-extract: - cp -f ${FILESDIR}/*_i386_sysv_elf_gas.S ${WRKSRC}/libs/context/src/asm/ + cp -f ${FILESDIR}/*_sysv_elf_gas.S ${WRKSRC}/libs/context/src/asm/ do-configure: echo "using ${TOOLSET} : : ${CXX} ;" >>${WRKSRC}/tools/build/src/user-config.jam Index: files/jump_sparc64_sysv_elf_gas.S =================================================================== RCS file: files/jump_sparc64_sysv_elf_gas.S diff -N files/jump_sparc64_sysv_elf_gas.S --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ files/jump_sparc64_sysv_elf_gas.S 8 Feb 2024 16:51:47 -0000 @@ -0,0 +1,53 @@ +/* + 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) +*/ + +/* + * typedef void* fcontext_t; + * + * struct transfer_t { + * fcontext_t fctx; + * void * data; + * }; + * + * transfer_t jump_fcontext(fcontext_t const to, void *vp); + */ +#define FRAMESIZE 176 +#define BIAS 2047 +#define SP 128 +#define I7 136 + +.file "jump_sparc64_sysv_elf_gas.S" +.text +.align 4 +.global jump_fcontext +.type jump_fcontext, %function +jump_fcontext: + # prepare stack + save %sp, -FRAMESIZE, %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 + + # store old %sp (pointing to old context-data) in %i0 as return + # *data stored in %i1 is unmodified + mov %o0, %i0 + + ret + restore +.size jump_fcontext,.-jump_fcontext +# Mark that we don't need executable stack. +.section .note.GNU-stack,"",%progbits Index: files/make_sparc64_sysv_elf_gas.S =================================================================== RCS file: files/make_sparc64_sysv_elf_gas.S diff -N files/make_sparc64_sysv_elf_gas.S --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ files/make_sparc64_sysv_elf_gas.S 8 Feb 2024 16:51:47 -0000 @@ -0,0 +1,69 @@ +/* + 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) +*/ + +/* + * fcontext_t *make_fcontext(void *sp, size_t size, void (*fn)(transfer_t)); + */ +#define FRAMESIZE 176 +#define BIAS 2047 +#define FP 112 +#define SP 128 +#define I7 136 + +.file "make_sparc64_sysv_elf_gas.S" +.text +.align 4 +.global make_fcontext +.type make_fcontext, %function +make_fcontext: + save %sp, -FRAMESIZE, %sp + + # shift address in %i0 (allocated stack) to lower 16 byte boundary + and %i0, -0xf, %i0 + + # reserve space for two frames on the stack + # the first frame is for the call the second one holds the data + # for jump_fcontext + sub %i0, 2 * FRAMESIZE, %i0 + + # third argument of make_fcontext() is the context-function to call + # store it in the first stack frame, also clear %fp there to indicate + # the end of the stack. + stx %i2, [%i0 + FRAMESIZE + I7] + stx %g0, [%i0 + FRAMESIZE + FP] + + # On OpenBSD stackghost prevents overriding the return address on + # a stack frame. So this code uses an extra trampoline to load + # to call the context-function and then do the _exit(0) dance. + # Extract the full address of the trampoline via pc relative addressing +1: + rd %pc, %l0 + add %l0, (trampoline - 1b - 8), %l0 + stx %l0, [%i0 + I7] + + # Save framepointer to first stack frame but first substract the BIAS + add %i0, FRAMESIZE - BIAS, %l0 + stx %l0, [%i0 + SP] + + # Return context-data which is also includes the BIAS + sub %i0, BIAS, %i0 + ret + restore + +trampoline: + ldx [%sp + BIAS + I7], %l0 + + # no need to setup transfer_t, already in %o0 and %o1 + jmpl %l0, %o7 + nop + + call _exit + clr %o0 + unimp +.size make_fcontext,.-make_fcontext +# Mark that we don't need executable stack. +.section .note.GNU-stack,"",%progbits Index: files/ontop_sparc64_sysv_elf_gas.S =================================================================== RCS file: files/ontop_sparc64_sysv_elf_gas.S diff -N files/ontop_sparc64_sysv_elf_gas.S --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ files/ontop_sparc64_sysv_elf_gas.S 8 Feb 2024 16:51:47 -0000 @@ -0,0 +1,52 @@ +/* + 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 FRAMESIZE 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, -FRAMESIZE, %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 + + # store old %sp (pointing to old context-data) in %i0 as return + # *data stored in %i1 is unmodified + mov %o0, %i0 + + # 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 + jmpl %o2, %g0 + nop + +.size jump_fcontext,.-jump_fcontext +# Mark that we don't need executable stack. +.section .note.GNU-stack,"",%progbits Index: patches/patch-libs_context_build_Jamfile_v2 =================================================================== RCS file: patches/patch-libs_context_build_Jamfile_v2 diff -N patches/patch-libs_context_build_Jamfile_v2 --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ patches/patch-libs_context_build_Jamfile_v2 8 Feb 2024 16:51:47 -0000 @@ -0,0 +1,34 @@ +Index: libs/context/build/Jamfile.v2 +--- libs/context/build/Jamfile.v2.orig ++++ libs/context/build/Jamfile.v2 +@@ -508,6 +508,30 @@ alias asm_sources + <toolset>gcc + ; + ++# SPARC64 ++# SPARC64/SYSV/ELF ++alias asm_sources ++ : asm/make_sparc64_sysv_elf_gas.S ++ asm/jump_sparc64_sysv_elf_gas.S ++ asm/ontop_sparc64_sysv_elf_gas.S ++ : <abi>sysv ++ <address-model>64 ++ <architecture>sparc ++ <binary-format>elf ++ <toolset>clang ++ ; ++ ++alias asm_sources ++ : asm/make_sparc64_sysv_elf_gas.S ++ asm/jump_sparc64_sysv_elf_gas.S ++ asm/ontop_sparc64_sysv_elf_gas.S ++ : <abi>sysv ++ <address-model>64 ++ <architecture>sparc ++ <binary-format>elf ++ <toolset>gcc ++ ; ++ + # S390X + # S390X/SYSV/ELF + alias asm_sources