diff --git a/src/runtime/cgo/abi_loong64.h b/src/runtime/cgo/abi_loong64.h new file mode 100644 index 00000000000..b10d83732f1 --- /dev/null +++ b/src/runtime/cgo/abi_loong64.h @@ -0,0 +1,60 @@ +// Copyright 2022 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Macros for transitioning from the host ABI to Go ABI0. +// +// These macros save and restore the callee-saved registers +// from the stack, but they don't adjust stack pointer, so +// the user should prepare stack space in advance. +// SAVE_R22_TO_R31(offset) saves R22 ~ R31 to the stack space +// of ((offset)+0*8)(R3) ~ ((offset)+9*8)(R3). +// +// SAVE_F24_TO_F31(offset) saves F24 ~ F31 to the stack space +// of ((offset)+0*8)(R3) ~ ((offset)+7*8)(R3). +// +// Note: g is R22 + +#define SAVE_R22_TO_R31(offset) \ + MOVV g, ((offset)+(0*8))(R3) \ + MOVV R23, ((offset)+(1*8))(R3) \ + MOVV R24, ((offset)+(2*8))(R3) \ + MOVV R25, ((offset)+(3*8))(R3) \ + MOVV R26, ((offset)+(4*8))(R3) \ + MOVV R27, ((offset)+(5*8))(R3) \ + MOVV R28, ((offset)+(6*8))(R3) \ + MOVV R29, ((offset)+(7*8))(R3) \ + MOVV R30, ((offset)+(8*8))(R3) \ + MOVV R31, ((offset)+(9*8))(R3) + +#define SAVE_F24_TO_F31(offset) \ + MOVD F24, ((offset)+(0*8))(R3) \ + MOVD F25, ((offset)+(1*8))(R3) \ + MOVD F26, ((offset)+(2*8))(R3) \ + MOVD F27, ((offset)+(3*8))(R3) \ + MOVD F28, ((offset)+(4*8))(R3) \ + MOVD F29, ((offset)+(5*8))(R3) \ + MOVD F30, ((offset)+(6*8))(R3) \ + MOVD F31, ((offset)+(7*8))(R3) + +#define RESTORE_R22_TO_R31(offset) \ + MOVV ((offset)+(0*8))(R3), g \ + MOVV ((offset)+(1*8))(R3), R23 \ + MOVV ((offset)+(2*8))(R3), R24 \ + MOVV ((offset)+(3*8))(R3), R25 \ + MOVV ((offset)+(4*8))(R3), R26 \ + MOVV ((offset)+(5*8))(R3), R27 \ + MOVV ((offset)+(6*8))(R3), R28 \ + MOVV ((offset)+(7*8))(R3), R29 \ + MOVV ((offset)+(8*8))(R3), R30 \ + MOVV ((offset)+(9*8))(R3), R31 + +#define RESTORE_F24_TO_F31(offset) \ + MOVD ((offset)+(0*8))(R3), F24 \ + MOVD ((offset)+(1*8))(R3), F25 \ + MOVD ((offset)+(2*8))(R3), F26 \ + MOVD ((offset)+(3*8))(R3), F27 \ + MOVD ((offset)+(4*8))(R3), F28 \ + MOVD ((offset)+(5*8))(R3), F29 \ + MOVD ((offset)+(6*8))(R3), F30 \ + MOVD ((offset)+(7*8))(R3), F31 diff --git a/src/runtime/cgo/asm_loong64.s b/src/runtime/cgo/asm_loong64.s index 1eb5b3ea37c..3b514ffc4a1 100644 --- a/src/runtime/cgo/asm_loong64.s +++ b/src/runtime/cgo/asm_loong64.s @@ -3,6 +3,7 @@ // license that can be found in the LICENSE file. #include "textflag.h" +#include "abi_loong64.h" // Set the x_crosscall2_ptr C function pointer variable point to crosscall2. // It's such a pointer chain: _crosscall2_ptr -> x_crosscall2_ptr -> crosscall2 @@ -24,52 +25,24 @@ TEXT crosscall2(SB),NOSPLIT|NOFRAME,$0 * first arg. */ - ADDV $(-8*22), R3 - MOVV R4, (8*1)(R3) // fn unsafe.Pointer - MOVV R5, (8*2)(R3) // a unsafe.Pointer - MOVV R7, (8*3)(R3) // ctxt uintptr - MOVV R23, (8*4)(R3) - MOVV R24, (8*5)(R3) - MOVV R25, (8*6)(R3) - MOVV R26, (8*7)(R3) - MOVV R27, (8*8)(R3) - MOVV R28, (8*9)(R3) - MOVV R29, (8*10)(R3) - MOVV R30, (8*11)(R3) - MOVV g, (8*12)(R3) - MOVV R1, (8*13)(R3) - MOVD F24, (8*14)(R3) - MOVD F25, (8*15)(R3) - MOVD F26, (8*16)(R3) - MOVD F27, (8*17)(R3) - MOVD F28, (8*18)(R3) - MOVD F29, (8*19)(R3) - MOVD F30, (8*20)(R3) - MOVD F31, (8*21)(R3) + 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) // Initialize Go ABI environment JAL runtime·load_g(SB) JAL runtime·cgocallback(SB) - MOVV (8*4)(R3), R23 - MOVV (8*5)(R3), R24 - MOVV (8*6)(R3), R25 - MOVV (8*7)(R3), R26 - MOVV (8*8)(R3), R27 - MOVV (8*9)(R3), R28 - MOVV (8*10)(R3), R29 - MOVV (8*11)(R3), R30 - MOVV (8*12)(R3), g - MOVV (8*13)(R3), R1 - MOVD (8*14)(R3), F24 - MOVD (8*15)(R3), F25 - MOVD (8*16)(R3), F26 - MOVD (8*17)(R3), F27 - MOVD (8*18)(R3), F28 - MOVD (8*19)(R3), F29 - MOVD (8*20)(R3), F30 - MOVD (8*21)(R3), F31 - ADDV $(8*22), R3 + RESTORE_R22_TO_R31((4*8)) + RESTORE_F24_TO_F31((14*8)) + MOVV (22*8)(R3), R1 + + ADDV $(23*8), R3 RET diff --git a/src/runtime/sys_linux_loong64.s b/src/runtime/sys_linux_loong64.s index 9ce5e722565..f1dcef42338 100644 --- a/src/runtime/sys_linux_loong64.s +++ b/src/runtime/sys_linux_loong64.s @@ -9,6 +9,7 @@ #include "go_asm.h" #include "go_tls.h" #include "textflag.h" +#include "cgo/abi_loong64.h" #define AT_FDCWD -100 @@ -374,18 +375,29 @@ TEXT runtime·sigfwd(SB),NOSPLIT,$0-32 JAL (R20) RET -TEXT runtime·sigtramp(SB),NOSPLIT|TOPFRAME,$64 +TEXT runtime·sigtramp(SB),NOSPLIT|TOPFRAME,$168 + MOVW R4, (1*8)(R3) + MOVV R5, (2*8)(R3) + MOVV R6, (3*8)(R3) + + // Save callee-save registers in the case of signal forwarding. + // Please refer to https://golang.org/issue/31827 . + SAVE_R22_TO_R31((4*8)) + SAVE_F24_TO_F31((14*8)) + // this might be called in external code context, // where g is not set. - MOVB runtime·iscgo(SB), R19 - BEQ R19, 2(PC) + MOVB runtime·iscgo(SB), R4 + BEQ R4, 2(PC) JAL runtime·load_g(SB) - MOVW R4, 8(R3) - MOVV R5, 16(R3) - MOVV R6, 24(R3) - MOVV $runtime·sigtrampgo(SB), R19 - JAL (R19) + MOVV $runtime·sigtrampgo(SB), R4 + JAL (R4) + + // Restore callee-save registers. + RESTORE_R22_TO_R31((4*8)) + RESTORE_F24_TO_F31((14*8)) + RET TEXT runtime·cgoSigtramp(SB),NOSPLIT,$0