diff --git a/src/greenlet/platform/switch_sh_gcc.h b/src/greenlet/platform/switch_sh_gcc.h new file mode 100644 index 00000000..5ecc3b39 --- /dev/null +++ b/src/greenlet/platform/switch_sh_gcc.h @@ -0,0 +1,36 @@ +#define STACK_REFPLUS 1 + +#ifdef SLP_EVAL +#define STACK_MAGIC 0 +#define REGS_TO_SAVE "r8", "r9", "r10", "r11", "r13", \ + "fr12", "fr13", "fr14", "fr15" + +// r12 Global context pointer, GP +// r14 Frame pointer, FP +// r15 Stack pointer, SP + +static int +slp_switch(void) +{ + int err; + void* fp; + int *stackref, stsizediff; + __asm__ volatile("" : : : REGS_TO_SAVE); + __asm__ volatile("mov.l r14, %0" : "=m"(fp) : :); + __asm__("mov r15, %0" : "=r"(stackref)); + { + SLP_SAVE_STATE(stackref, stsizediff); + __asm__ volatile( + "add %0, r15\n" + "add %0, r14\n" + : /* no outputs */ + : "r"(stsizediff)); + SLP_RESTORE_STATE(); + __asm__ volatile("mov r0, %0" : "=r"(err) : :); + } + __asm__ volatile("mov.l %0, r14" : : "m"(fp) :); + __asm__ volatile("" : : : REGS_TO_SAVE); + return err; +} + +#endif diff --git a/src/greenlet/slp_platformselect.h b/src/greenlet/slp_platformselect.h index c959f0f8..6096cb57 100644 --- a/src/greenlet/slp_platformselect.h +++ b/src/greenlet/slp_platformselect.h @@ -64,6 +64,8 @@ extern "C" { # include "platform/switch_aarch64_gcc.h" /* LLVM Aarch64 ABI for Windows */ #elif defined(__GNUC__) && defined(__loongarch64) && defined(__linux__) # include "platform/switch_loongarch64_linux.h" /* LoongArch64 */ +#elif defined(__GNUC__) && defined(__sh__) +# include "platform/switch_sh_gcc.h" /* SH */ #endif #ifdef __cplusplus