diff --git a/Zend/asm/jump_sparc64_sysv_elf_gas.S b/Zend/asm/jump_sparc64_sysv_elf_gas.S new file mode 100644 index 0000000000000..727687aad804a --- /dev/null +++ b/Zend/asm/jump_sparc64_sysv_elf_gas.S @@ -0,0 +1,49 @@ +/* + 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 struct { + * void *handle; + * zend_fiber_transfer *transfer; + * } boost_context_data; + * + * boost_context_data jump_fcontext(void *to, zend_fiber_transfer *transfer); + */ +#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 diff --git a/Zend/asm/make_sparc64_sysv_elf_gas.S b/Zend/asm/make_sparc64_sysv_elf_gas.S new file mode 100644 index 0000000000000..52ff70b996b66 --- /dev/null +++ b/Zend/asm/make_sparc64_sysv_elf_gas.S @@ -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) +*/ + +/* + * void *make_fcontext(void *sp, size_t size, void (*fn)(boost_context_data)); + */ +#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 boost_context_data, 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 diff --git a/configure.ac b/configure.ac index 70334bf55ee06..455417c3b5acb 100644 --- a/configure.ac +++ b/configure.ac @@ -1268,6 +1268,7 @@ AS_CASE([$host_cpu], [ppc64*|powerpc64*], [fiber_cpu="ppc64"], [ppc*|powerpc*], [fiber_cpu="ppc32"], [riscv64*], [fiber_cpu="riscv64"], + [sparc64], [fiber_cpu="sparc64"], [s390x*], [fiber_cpu="s390x"], [mips64*], [fiber_cpu="mips64"], [mips*], [fiber_cpu="mips32"], @@ -1289,6 +1290,7 @@ AS_CASE([$fiber_cpu], [ppc64], [fiber_asm_file_prefix="ppc64_sysv"], [ppc32], [fiber_asm_file_prefix="ppc32_sysv"], [riscv64], [fiber_asm_file_prefix="riscv64_sysv"], + [sparc64], [fiber_asm_file_prefix="sparc64_sysv"], [s390x], [fiber_asm_file_prefix="s390x_sysv"], [mips64], [fiber_asm_file_prefix="mips64_n64"], [mips32], [fiber_asm_file_prefix="mips32_o32"],