diff options
author | Sergey Fedorov <[email protected]> | 2022-10-19 18:49:45 +0800 |
---|---|---|
committer | GitHub <[email protected]> | 2022-10-19 23:49:45 +1300 |
commit | 567725ed303b6738493c80efaf93dc4c1e65a9c9 (patch) | |
tree | 75f141047050eee63c05d613491595a7a9380afa /coroutine/ppc | |
parent | fc3137ef54562c3c3290245c0f62e0bb193c3145 (diff) |
Fix and improve coroutines for Darwin (macOS) ppc/ppc64. (#5975)
Notes
Notes:
Merged-By: ioquatix <[email protected]>
Diffstat (limited to 'coroutine/ppc')
-rw-r--r-- | coroutine/ppc/Context.S | 117 | ||||
-rw-r--r-- | coroutine/ppc/Context.h | 1 |
2 files changed, 68 insertions, 50 deletions
diff --git a/coroutine/ppc/Context.S b/coroutine/ppc/Context.S index fe28390df0..cdda93e179 100644 --- a/coroutine/ppc/Context.S +++ b/coroutine/ppc/Context.S @@ -1,73 +1,90 @@ +; Based on the code by Samuel Williams. Created by Sergey Fedorov on 04/06/2022. +; Credits to Samuel Williams, Rei Odaira and Iain Sandoe. Errors, if any, are mine. +; Some relevant examples: https://github.com/gcc-mirror/gcc/blob/master/libphobos/libdruntime/config/powerpc/switchcontext.S +; https://github.com/gcc-mirror/gcc/blob/master/libgcc/config/rs6000/darwin-gpsave.S +; https://www.ibm.com/docs/en/aix/7.2?topic=epilogs-saving-gprs-only +; ppc32 version may be re-written compactly with stmw/lwm, but the code wonʼt be faster, see: https://github.com/ruby/ruby/pull/5927#issuecomment-1139730541 + +; Notice that this code is only for Darwin (macOS). Darwin ABI differs from AIX and ELF. +; To add support for AIX, *BSD or *Linux, please make separate implementations. + #define TOKEN_PASTE(x,y) x##y #define PREFIXED_SYMBOL(prefix,name) TOKEN_PASTE(prefix,name) +.machine ppc7400 ; = G4, Rosetta .text -.align 2 .globl PREFIXED_SYMBOL(SYMBOL_PREFIX,coroutine_transfer) +.align 2 + PREFIXED_SYMBOL(SYMBOL_PREFIX,coroutine_transfer): - # Make space on the stack for caller registers - addi r1,r1,-80 + ; Make space on the stack for caller registers + ; (Should we rather use red zone? See libphobos example.) + subi r1,r1,80 + + ; Get LR + mflr r0 - # Save caller registers - stw r13,0(r1) - stw r14,4(r1) - stw r15,8(r1) - stw r16,12(r1) - stw r17,16(r1) - stw r18,20(r1) - stw r19,24(r1) - stw r20,28(r1) - stw r21,32(r1) + ; Save caller registers + stw r31,0(r1) + stw r30,4(r1) + stw r29,8(r1) + stw r28,12(r1) + stw r27,16(r1) + stw r26,20(r1) + stw r25,24(r1) + stw r24,28(r1) + stw r23,32(r1) stw r22,36(r1) - stw r23,40(r1) - stw r24,44(r1) - stw r25,48(r1) - stw r26,52(r1) - stw r27,56(r1) - stw r28,60(r1) - stw r29,64(r1) - stw r30,68(r1) - stw r31,72(r1) + stw r21,40(r1) + stw r20,44(r1) + stw r19,48(r1) + stw r18,52(r1) + stw r17,56(r1) + stw r16,60(r1) + stw r15,64(r1) + stw r14,68(r1) + stw r13,72(r1) - # Save return address - mflr r0 + ; Save return address + ; Possibly should rather be saved into linkage area, see libphobos and IBM docs stw r0,76(r1) - # Save stack pointer to first argument + ; Save stack pointer to first argument stw r1,0(r3) - # Load stack pointer from second argument + ; Load stack pointer from second argument lwz r1,0(r4) - # Restore caller registers - lwz r13,0(r1) - lwz r14,4(r1) - lwz r15,8(r1) - lwz r16,12(r1) - lwz r17,16(r1) - lwz r18,20(r1) - lwz r19,24(r1) - lwz r20,28(r1) - lwz r21,32(r1) + ; Load return address + lwz r0,76(r1) + + ; Restore caller registers + lwz r13,72(r1) + lwz r14,68(r1) + lwz r15,64(r1) + lwz r16,60(r1) + lwz r17,56(r1) + lwz r18,52(r1) + lwz r19,48(r1) + lwz r20,44(r1) + lwz r21,40(r1) lwz r22,36(r1) - lwz r23,40(r1) - lwz r24,44(r1) - lwz r25,48(r1) - lwz r26,52(r1) - lwz r27,56(r1) - lwz r28,60(r1) - lwz r29,64(r1) - lwz r30,68(r1) - lwz r31,72(r1) + lwz r23,32(r1) + lwz r24,28(r1) + lwz r25,24(r1) + lwz r26,20(r1) + lwz r27,16(r1) + lwz r28,12(r1) + lwz r29,8(r1) + lwz r30,4(r1) + lwz r31,0(r1) - # Load return address - lwz r0,76(r1) + ; Set LR mtlr r0 - # Pop stack frame + ; Pop stack frame addi r1,r1,80 - # Jump to return address + ; Jump to return address blr - diff --git a/coroutine/ppc/Context.h b/coroutine/ppc/Context.h index 9f69390388..1fce112579 100644 --- a/coroutine/ppc/Context.h +++ b/coroutine/ppc/Context.h @@ -9,6 +9,7 @@ #include <string.h> #define COROUTINE __attribute__((noreturn)) void +#define COROUTINE_LIMITED_ADDRESS_SPACE enum { COROUTINE_REGISTERS = |