On Tue, Feb 13, 2024 at 09:03:49AM +0100, Claudio Jeker wrote:

> On Thu, Feb 08, 2024 at 06:50:55PM +0100, Claudio Jeker wrote:
> > 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 :)
> 
> I realized that I can save an instruction by using the builtin ADD
> instruction in 'restore' to set up %o0. So a context switch on sparc64
> is now 10 instructions :)
> 
> I ran test for context, fiber, coroutine and coroutine2 in boost and all
> test pass. The powerdns_recoursor package built but I'm not sure how to
> test this properly.

If it starts and does not crash you're good. My sparc64s are currently
in storage, so I cannot test myself right now as our attic will be
under construction soon. Will test when things are back to normal.

        -Otto

> 
> IMO this is ready for commit. I will start pushing these changes upstream
> as well.
> -- 
> :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  12 Feb 2024 19:12:11 -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 12 Feb 2024 19:12:11 -0000
> @@ -0,0 +1,51 @@
> +/*
> +       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 CC64FSZ 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, -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
> +
> +     ret
> +      restore %o0, %g0, %o0
> +     # restore old %sp (pointing to old context-data) in %o0
> +     # *data stored in %o1 was not modified
> +.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 12 Feb 2024 19:12:11 -0000
> @@ -0,0 +1,68 @@
> +/*
> +       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 CC64FSZ 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, -CC64FSZ, %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 * CC64FSZ, %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 + CC64FSZ + I7]
> +     stx     %g0, [%i0 + CC64FSZ + 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, CC64FSZ - BIAS, %l0
> +     stx     %l0, [%i0 + SP]
> +
> +     # Return context-data which is also includes the BIAS
> +     ret
> +      restore %i0, -BIAS, %o0
> +
> +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        12 Feb 2024 19:12:11 -0000
> @@ -0,0 +1,50 @@
> +/*
> +       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        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       12 Feb 2024 19:12:11 
> -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
> 

Reply via email to