From b9bd3393f735eb1e897bce946b765e9dc8fdf68e Mon Sep 17 00:00:00 2001 From: Quim Muntal Date: Thu, 16 Oct 2025 14:26:58 +0000 Subject: [PATCH 1/4] preserve callee-saved registers in threadentry --- internal/fakecgo/trampolines_amd64.s | 13 ++++++++++++- internal/fakecgo/trampolines_arm64.s | 17 ++++++++++++++++- internal/fakecgo/trampolines_loong64.s | 20 ++++++++++++++++++-- 3 files changed, 46 insertions(+), 4 deletions(-) diff --git a/internal/fakecgo/trampolines_amd64.s b/internal/fakecgo/trampolines_amd64.s index c9a3cc09..c0cd711e 100644 --- a/internal/fakecgo/trampolines_amd64.s +++ b/internal/fakecgo/trampolines_amd64.s @@ -25,6 +25,7 @@ return value will be in AX */ #include "textflag.h" #include "go_asm.h" +#include "abi_amd64.h" // these trampolines map the gcc ABI to Go ABI and then calls into the Go equivalent functions. @@ -73,11 +74,21 @@ TEXT ·setg_trampoline(SB), NOSPLIT, $0-16 CALL BX RET -TEXT threadentry_trampoline(SB), NOSPLIT, $16 +TEXT threadentry_trampoline(SB), NOSPLIT, $0 + // See crosscall2. + PUSH_REGS_HOST_TO_ABI0() + + // X15 is designated by Go as a fixed zero register. + // We are calling directly into ABIInternal, + // so we need to ensure it's zero. + PXOR X15, X15 + MOVQ DI, AX MOVQ ·threadentry_call(SB), DX MOVQ (DX), CX CALL CX + + POP_REGS_HOST_TO_ABI0() RET TEXT ·call5(SB), NOSPLIT, $0-56 diff --git a/internal/fakecgo/trampolines_arm64.s b/internal/fakecgo/trampolines_arm64.s index 9dbdbc01..ccee9a4a 100644 --- a/internal/fakecgo/trampolines_arm64.s +++ b/internal/fakecgo/trampolines_arm64.s @@ -5,6 +5,7 @@ #include "textflag.h" #include "go_asm.h" +#include "abi_arm64.h" // these trampolines map the gcc ABI to Go ABI and then calls into the Go equivalent functions. @@ -53,11 +54,25 @@ TEXT ·setg_trampoline(SB), NOSPLIT, $0-16 RET TEXT threadentry_trampoline(SB), NOSPLIT, $0-0 - MOVD R0, 8(RSP) + // See crosscall2. + SUB $(8*24), RSP + STP (R0, R1), (8*1)(RSP) + MOVD R3, (8*3)(RSP) + + SAVE_R19_TO_R28(8*4) + SAVE_F8_TO_F15(8*14) + STP (R29, R30), (8*22)(RSP) + MOVD ·threadentry_call(SB), R26 MOVD (R26), R2 CALL (R2) MOVD $0, R0 // TODO: get the return value from threadentry + + RESTORE_R19_TO_R28(8*4) + RESTORE_F8_TO_F15(8*14) + LDP (8*22)(RSP), (R29, R30) + + ADD $(8*24), RSP RET TEXT ·call5(SB), NOSPLIT, $0-0 diff --git a/internal/fakecgo/trampolines_loong64.s b/internal/fakecgo/trampolines_loong64.s index 15b33543..62ba409d 100644 --- a/internal/fakecgo/trampolines_loong64.s +++ b/internal/fakecgo/trampolines_loong64.s @@ -5,6 +5,7 @@ #include "textflag.h" #include "go_asm.h" +#include "abi_loong64.h" // these trampolines map the gcc ABI to Go ABI and then calls into the Go equivalent functions. @@ -52,11 +53,26 @@ TEXT ·setg_trampoline(SB), NOSPLIT, $0 CALL (R5) RET -TEXT threadentry_trampoline(SB), NOSPLIT, $16 - MOVV R4, 8(R3) +TEXT threadentry_trampoline(SB), NOSPLIT, $0 + // See crosscall2. + ADDV $(-23*8), R3 + MOVV R4, (1*8)(R3) // fn unsafe.Pointer + MOVV R5, (2*8)(R3) // a unsafe.Pointer + MOVV R7, (3*8)(R3) // ctxt uintptr + + SAVE_R22_TO_R31((4*8)) + SAVE_F24_TO_F31((14*8)) + MOVV R1, (22*8)(R3) + MOVV ·threadentry_call(SB), R5 MOVV (R5), R6 CALL (R6) + + RESTORE_R22_TO_R31((4*8)) + RESTORE_F24_TO_F31((14*8)) + MOVV (22*8)(R3), R1 + + ADDV $(23*8), R3 RET TEXT ·call5(SB), NOSPLIT, $0-0 From 7f48e193d5ad87f046b84e6a4ef49ee83e264849 Mon Sep 17 00:00:00 2001 From: Quim Muntal Date: Thu, 16 Oct 2025 18:47:41 +0000 Subject: [PATCH 2/4] code review comments --- internal/fakecgo/trampolines_amd64.s | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/fakecgo/trampolines_amd64.s b/internal/fakecgo/trampolines_amd64.s index c0cd711e..68fc02de 100644 --- a/internal/fakecgo/trampolines_amd64.s +++ b/internal/fakecgo/trampolines_amd64.s @@ -80,8 +80,8 @@ TEXT threadentry_trampoline(SB), NOSPLIT, $0 // X15 is designated by Go as a fixed zero register. // We are calling directly into ABIInternal, - // so we need to ensure it's zero. - PXOR X15, X15 + // so ensure it is zero. + PXOR X15, X15 MOVQ DI, AX MOVQ ·threadentry_call(SB), DX From 4e344033e4653256c234e90d0d4f188245e157b3 Mon Sep 17 00:00:00 2001 From: Quim Muntal Date: Thu, 16 Oct 2025 18:54:50 +0000 Subject: [PATCH 3/4] use spaces --- internal/fakecgo/trampolines_loong64.s | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/internal/fakecgo/trampolines_loong64.s b/internal/fakecgo/trampolines_loong64.s index 62ba409d..a6faf687 100644 --- a/internal/fakecgo/trampolines_loong64.s +++ b/internal/fakecgo/trampolines_loong64.s @@ -55,14 +55,14 @@ TEXT ·setg_trampoline(SB), NOSPLIT, $0 TEXT threadentry_trampoline(SB), NOSPLIT, $0 // See crosscall2. - ADDV $(-23*8), R3 - MOVV R4, (1*8)(R3) // fn unsafe.Pointer - MOVV R5, (2*8)(R3) // a unsafe.Pointer - MOVV R7, (3*8)(R3) // ctxt uintptr + ADDV $(-23*8), R3 + MOVV R4, (1*8)(R3) // fn unsafe.Pointer + MOVV R5, (2*8)(R3) // a unsafe.Pointer + MOVV R7, (3*8)(R3) // ctxt uintptr SAVE_R22_TO_R31((4*8)) SAVE_F24_TO_F31((14*8)) - MOVV R1, (22*8)(R3) + MOVV R1, (22*8)(R3) MOVV ·threadentry_call(SB), R5 MOVV (R5), R6 @@ -70,9 +70,9 @@ TEXT threadentry_trampoline(SB), NOSPLIT, $0 RESTORE_R22_TO_R31((4*8)) RESTORE_F24_TO_F31((14*8)) - MOVV (22*8)(R3), R1 + MOVV (22*8)(R3), R1 - ADDV $(23*8), R3 + ADDV $(23*8), R3 RET TEXT ·call5(SB), NOSPLIT, $0-0 From 776cd3c7c863a0bb6f0258475dc21c5bddf0c6a0 Mon Sep 17 00:00:00 2001 From: Quim Muntal Date: Thu, 16 Oct 2025 21:21:26 +0200 Subject: [PATCH 4/4] Refine comment for X15 zero register usage Clarified comment regarding calling ABIInternal and zero register. --- internal/fakecgo/trampolines_amd64.s | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/internal/fakecgo/trampolines_amd64.s b/internal/fakecgo/trampolines_amd64.s index 68fc02de..6deb374b 100644 --- a/internal/fakecgo/trampolines_amd64.s +++ b/internal/fakecgo/trampolines_amd64.s @@ -79,8 +79,7 @@ TEXT threadentry_trampoline(SB), NOSPLIT, $0 PUSH_REGS_HOST_TO_ABI0() // X15 is designated by Go as a fixed zero register. - // We are calling directly into ABIInternal, - // so ensure it is zero. + // Calling directly into ABIInternal, ensure it is zero. PXOR X15, X15 MOVQ DI, AX