From 54e8f884788d2cd89d2f6ed966dc52b6887a0d38 Mon Sep 17 00:00:00 2001 From: Sergey Fedorov Date: Fri, 28 Mar 2025 20:43:09 +0800 Subject: [PATCH] ppc/ppc64 coroutines: save/restore CR as well Corresponding change for ppc64le: https://github.com/ruby/ruby/commit/d8a21592b462aba0a66324f7444a2f6e61116d3a --- coroutine/ppc/Context.S | 15 ++++++++++++--- coroutine/ppc64/Context.S | 15 ++++++++++++--- 2 files changed, 24 insertions(+), 6 deletions(-) diff --git coroutine/ppc/Context.S coroutine/ppc/Context.S index f44b2419b4..a77ecdcbaf 100644 --- coroutine/ppc/Context.S +++ coroutine/ppc/Context.S @@ -19,7 +19,7 @@ PREFIXED_SYMBOL(coroutine_transfer): ; Make space on the stack for caller registers ; (Should we rather use red zone? See libphobos example.) - subi r1,r1,80 + subi r1,r1,84 ; Get LR mflr r0 @@ -46,9 +46,12 @@ PREFIXED_SYMBOL(coroutine_transfer): 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 caller CR register + mfcr r0 + stw r0,80(r1) + ; Save stack pointer to first argument stw r1,0(r3) @@ -82,8 +85,14 @@ PREFIXED_SYMBOL(coroutine_transfer): ; Set LR mtlr r0 + ; Load CR register + lwz r0,80(r1) + ; While it is feasible to deal with select fields of CR, + ; it is easier and potentially faster to use the whole of it. + mtcr r0 + ; Pop stack frame - addi r1,r1,80 + addi r1,r1,84 ; Jump to return address blr diff --git coroutine/ppc64/Context.S coroutine/ppc64/Context.S index 20a47c61c6..0082428629 100644 --- coroutine/ppc64/Context.S +++ coroutine/ppc64/Context.S @@ -18,7 +18,7 @@ PREFIXED_SYMBOL(coroutine_transfer): ; Make space on the stack for caller registers ; (Should we rather use red zone? See libphobos example.) - subi r1,r1,160 + subi r1,r1,168 ; Get LR mflr r0 @@ -45,9 +45,12 @@ PREFIXED_SYMBOL(coroutine_transfer): 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 caller CR register + mfcr r0 + std r0,160(r1) + ; Save stack pointer to first argument std r1,0(r3) @@ -81,8 +84,14 @@ PREFIXED_SYMBOL(coroutine_transfer): ; Set LR mtlr r0 + ; Load CR register + ld r0,160(r1) + ; While it is feasible to deal with select fields of CR, + ; it is easier and potentially faster to use the whole of it. + mtcr r0 + ; Pop stack frame - addi r1,r1,160 + addi r1,r1,168 ; Jump to return address blr --- coroutine/ppc/Context.h 2026-07-14 08:22:10.000000000 +0800 +++ coroutine/ppc/Context.h 2026-07-18 00:29:45.000000000 +0800 @@ -13,7 +13,7 @@ enum { COROUTINE_REGISTERS = - 20 /* 19 general purpose registers (r13-r31) and 1 return address */ + 21 /* 19 general purpose registers (r13-r31), 1 special register (cr) and 1 return address */ + 4 /* space for fiber_entry() to store the link register */ }; --- coroutine/ppc64/Context.h 2026-07-14 08:22:10.000000000 +0800 +++ coroutine/ppc64/Context.h 2026-07-18 00:29:19.000000000 +0800 @@ -12,7 +12,7 @@ enum { COROUTINE_REGISTERS = - 20 /* 19 general purpose registers (r13-r31) and 1 return address */ + 21 /* 19 general purpose registers (r13-r31), 1 special register (cr) and 1 return address */ + 4 /* space for fiber_entry() to store the link register */ };