2022-10-19 13:49:45 +03:00
; 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.
2022-05-22 06:02:03 +03:00
# define T O K E N _ P A S T E ( x ,y ) x ## y
# define P R E F I X E D _ S Y M B O L ( p r e f i x ,n a m e ) T O K E N _ P A S T E ( p r e f i x ,n a m e )
2022-10-19 13:49:45 +03:00
.machine ppc7400 ; = G4, Rosetta
2022-05-22 06:02:03 +03:00
.text
.globl PREFIXED_ S Y M B O L ( S Y M B O L _ P R E F I X ,c o r o u t i n e _ t r a n s f e r )
2022-10-19 13:49:45 +03:00
.align 2
2022-05-22 06:02:03 +03:00
PREFIXED_ S Y M B O L ( S Y M B O L _ P R E F I X ,c o r o u t i n e _ t r a n s f e r ) :
2022-10-19 13:49:45 +03:00
; Make space on the stack for caller registers
; (Should we rather use red zone? See libphobos example.)
subi r1 ,r1 ,8 0
; Get LR
mflr r0
2022-05-22 06:02:03 +03:00
2022-10-19 13:49:45 +03:00
; Save caller registers
stw r31 ,0 ( r1 )
stw r30 ,4 ( r1 )
stw r29 ,8 ( r1 )
stw r28 ,1 2 ( r1 )
stw r27 ,1 6 ( r1 )
stw r26 ,2 0 ( r1 )
stw r25 ,2 4 ( r1 )
stw r24 ,2 8 ( r1 )
stw r23 ,3 2 ( r1 )
2022-05-22 06:02:03 +03:00
stw r22 ,3 6 ( r1 )
2022-10-19 13:49:45 +03:00
stw r21 ,4 0 ( r1 )
stw r20 ,4 4 ( r1 )
stw r19 ,4 8 ( r1 )
stw r18 ,5 2 ( r1 )
stw r17 ,5 6 ( r1 )
stw r16 ,6 0 ( r1 )
stw r15 ,6 4 ( r1 )
stw r14 ,6 8 ( r1 )
stw r13 ,7 2 ( r1 )
2022-05-22 06:02:03 +03:00
2022-10-19 13:49:45 +03:00
; Save return address
; Possibly should rather be saved into linkage area, see libphobos and IBM docs
2022-05-22 06:02:03 +03:00
stw r0 ,7 6 ( r1 )
2022-10-19 13:49:45 +03:00
; Save stack pointer to first argument
2022-05-22 06:02:03 +03:00
stw r1 ,0 ( r3 )
2022-10-19 13:49:45 +03:00
; Load stack pointer from second argument
2022-05-22 06:02:03 +03:00
lwz r1 ,0 ( r4 )
2022-10-19 13:49:45 +03:00
; Load return address
lwz r0 ,7 6 ( r1 )
; Restore caller registers
lwz r13 ,7 2 ( r1 )
lwz r14 ,6 8 ( r1 )
lwz r15 ,6 4 ( r1 )
lwz r16 ,6 0 ( r1 )
lwz r17 ,5 6 ( r1 )
lwz r18 ,5 2 ( r1 )
lwz r19 ,4 8 ( r1 )
lwz r20 ,4 4 ( r1 )
lwz r21 ,4 0 ( r1 )
2022-05-22 06:02:03 +03:00
lwz r22 ,3 6 ( r1 )
2022-10-19 13:49:45 +03:00
lwz r23 ,3 2 ( r1 )
lwz r24 ,2 8 ( r1 )
lwz r25 ,2 4 ( r1 )
lwz r26 ,2 0 ( r1 )
lwz r27 ,1 6 ( r1 )
lwz r28 ,1 2 ( r1 )
lwz r29 ,8 ( r1 )
lwz r30 ,4 ( r1 )
lwz r31 ,0 ( r1 )
2022-05-22 06:02:03 +03:00
2022-10-19 13:49:45 +03:00
; Set LR
2022-05-22 06:02:03 +03:00
mtlr r0
2022-10-19 13:49:45 +03:00
; Pop stack frame
2022-05-22 06:02:03 +03:00
addi r1 ,r1 ,8 0
2022-10-19 13:49:45 +03:00
; Jump to return address
2022-05-22 06:02:03 +03:00
blr