mirror of
https://github.com/ruby/ruby.git
synced 2025-08-15 13:39:04 +02:00
Fix and improve coroutines for Darwin (macOS) ppc/ppc64. (#5975)
This commit is contained in:
parent
fc3137ef54
commit
567725ed30
Notes:
git
2022-10-19 10:50:05 +00:00
Merged-By: ioquatix <samuel@codeotaku.com>
17 changed files with 196 additions and 120 deletions
|
@ -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
|
||||
|
||||
# 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)
|
||||
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)
|
||||
|
||||
# Save return address
|
||||
; Get LR
|
||||
mflr r0
|
||||
|
||||
; 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 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
|
||||
; 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)
|
||||
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)
|
||||
|
||||
# Load return address
|
||||
; 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,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)
|
||||
|
||||
; Set LR
|
||||
mtlr r0
|
||||
|
||||
# Pop stack frame
|
||||
; Pop stack frame
|
||||
addi r1,r1,80
|
||||
|
||||
# Jump to return address
|
||||
; Jump to return address
|
||||
blr
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include <string.h>
|
||||
|
||||
#define COROUTINE __attribute__((noreturn)) void
|
||||
#define COROUTINE_LIMITED_ADDRESS_SPACE
|
||||
|
||||
enum {
|
||||
COROUTINE_REGISTERS =
|
||||
|
|
|
@ -1,70 +1,89 @@
|
|||
; 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
|
||||
|
||||
; 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 ppc64 ; = G5
|
||||
.text
|
||||
.align 3
|
||||
|
||||
.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,-152
|
||||
; Make space on the stack for caller registers
|
||||
; (Should we rather use red zone? See libphobos example.)
|
||||
subi r1,r1,160
|
||||
|
||||
# Save caller registers
|
||||
std r14,0(r1)
|
||||
std r15,8(r1)
|
||||
std r16,16(r1)
|
||||
std r17,24(r1)
|
||||
std r18,32(r1)
|
||||
std r19,40(r1)
|
||||
std r20,48(r1)
|
||||
std r21,56(r1)
|
||||
std r22,64(r1)
|
||||
std r23,72(r1)
|
||||
std r24,80(r1)
|
||||
std r25,88(r1)
|
||||
std r26,96(r1)
|
||||
std r27,104(r1)
|
||||
std r28,112(r1)
|
||||
std r29,120(r1)
|
||||
std r30,128(r1)
|
||||
std r31,136(r1)
|
||||
|
||||
# Save return address
|
||||
; Get LR
|
||||
mflr r0
|
||||
std r0,144(r1)
|
||||
|
||||
# Save stack pointer to first argument
|
||||
; Save caller registers
|
||||
std r31,0(r1)
|
||||
std r30,8(r1)
|
||||
std r29,16(r1)
|
||||
std r28,24(r1)
|
||||
std r27,32(r1)
|
||||
std r26,40(r1)
|
||||
std r25,48(r1)
|
||||
std r24,56(r1)
|
||||
std r23,64(r1)
|
||||
std r22,72(r1)
|
||||
std r21,80(r1)
|
||||
std r20,88(r1)
|
||||
std r19,96(r1)
|
||||
std r18,104(r1)
|
||||
std r17,112(r1)
|
||||
std r16,120(r1)
|
||||
std r15,128(r1)
|
||||
std r14,136(r1)
|
||||
std r13,144(r1)
|
||||
|
||||
; Save return address
|
||||
; Possibly should rather be saved into linkage area, see libphobos and IBM docs
|
||||
std r0,152(r1)
|
||||
|
||||
; Save stack pointer to first argument
|
||||
std r1,0(r3)
|
||||
|
||||
# Load stack pointer from second argument
|
||||
; Load stack pointer from second argument
|
||||
ld r1,0(r4)
|
||||
|
||||
# Restore caller registers
|
||||
ld r14,0(r1)
|
||||
ld r15,8(r1)
|
||||
ld r16,16(r1)
|
||||
ld r17,24(r1)
|
||||
ld r18,32(r1)
|
||||
ld r19,40(r1)
|
||||
ld r20,48(r1)
|
||||
ld r21,56(r1)
|
||||
ld r22,64(r1)
|
||||
ld r23,72(r1)
|
||||
ld r24,80(r1)
|
||||
ld r25,88(r1)
|
||||
ld r26,96(r1)
|
||||
ld r27,104(r1)
|
||||
ld r28,112(r1)
|
||||
ld r29,120(r1)
|
||||
ld r30,128(r1)
|
||||
ld r31,136(r1)
|
||||
; Load return address
|
||||
ld r0,152(r1)
|
||||
|
||||
# Load return address
|
||||
ld r0,144(r1)
|
||||
; Restore caller registers
|
||||
ld r13,144(r1)
|
||||
ld r14,136(r1)
|
||||
ld r15,128(r1)
|
||||
ld r16,120(r1)
|
||||
ld r17,112(r1)
|
||||
ld r18,104(r1)
|
||||
ld r19,96(r1)
|
||||
ld r20,88(r1)
|
||||
ld r21,80(r1)
|
||||
ld r22,72(r1)
|
||||
ld r23,64(r1)
|
||||
ld r24,56(r1)
|
||||
ld r25,48(r1)
|
||||
ld r26,40(r1)
|
||||
ld r27,32(r1)
|
||||
ld r28,24(r1)
|
||||
ld r29,16(r1)
|
||||
ld r30,8(r1)
|
||||
ld r31,0(r1)
|
||||
|
||||
; Set LR
|
||||
mtlr r0
|
||||
|
||||
# Pop stack frame
|
||||
addi r1,r1,152
|
||||
; Pop stack frame
|
||||
addi r1,r1,160
|
||||
|
||||
# Jump to return address
|
||||
; Jump to return address
|
||||
blr
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
|
||||
enum {
|
||||
COROUTINE_REGISTERS =
|
||||
19 /* 18 general purpose registers (r14–r31) and 1 return address */
|
||||
20 /* 19 general purpose registers (r13–r31) and 1 return address */
|
||||
+ 4 /* space for fiber_entry() to store the link register */
|
||||
};
|
||||
|
||||
|
@ -44,7 +44,7 @@ static inline void coroutine_initialize(
|
|||
memset(context->stack_pointer, 0, sizeof(void*) * COROUTINE_REGISTERS);
|
||||
|
||||
/* Skip a global prologue that sets the TOC register */
|
||||
context->stack_pointer[18] = ((char*)start) + 8;
|
||||
context->stack_pointer[19] = ((char*)start) + 8;
|
||||
}
|
||||
|
||||
struct coroutine_context * coroutine_transfer(struct coroutine_context * current, struct coroutine_context * target);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue