runtime/cgo: add abi_riscv64.h for callee-saved register macros

Add abi_riscv64.h with SAVE_GPR/SAVE_FPR macros for saving and
restoring the RISC-V callee-saved registers, following the pattern
established by the other abi_*.h headers.

Refactor asm_riscv64.s (cgo crosscall2), asm_riscv64.s (runtime
_rt0_riscv64_lib), and race_riscv64.s (racecallbackthunk) to use
the new macros, replacing inline register save/restore sequences.

Change-Id: I83cef17a35c57fc8b5e045e7181460283ae5b423
Reviewed-on: https://go-review.googlesource.com/c/go/+/749900
Reviewed-by: David Chase <drchase@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Quim Muntal <quimmuntal@gmail.com>
Reviewed-by: Russ Cox <rsc@golang.org>
This commit is contained in:
George Adams
2026-02-27 15:45:55 +00:00
committed by Quim Muntal
parent ff023a3341
commit ad168c5131
4 changed files with 89 additions and 144 deletions

View File

@@ -5,6 +5,7 @@
#include "go_asm.h"
#include "funcdata.h"
#include "textflag.h"
#include "cgo/abi_riscv64.h"
// When building with -buildmode=c-shared, this symbol is called when the shared
@@ -12,30 +13,8 @@
TEXT _rt0_riscv64_lib(SB),NOSPLIT,$224
// Preserve callee-save registers, along with X1 (LR).
MOV X1, (8*3)(X2)
MOV X8, (8*4)(X2)
MOV X9, (8*5)(X2)
MOV X18, (8*6)(X2)
MOV X19, (8*7)(X2)
MOV X20, (8*8)(X2)
MOV X21, (8*9)(X2)
MOV X22, (8*10)(X2)
MOV X23, (8*11)(X2)
MOV X24, (8*12)(X2)
MOV X25, (8*13)(X2)
MOV X26, (8*14)(X2)
MOV g, (8*15)(X2)
MOVD F8, (8*16)(X2)
MOVD F9, (8*17)(X2)
MOVD F18, (8*18)(X2)
MOVD F19, (8*19)(X2)
MOVD F20, (8*20)(X2)
MOVD F21, (8*21)(X2)
MOVD F22, (8*22)(X2)
MOVD F23, (8*23)(X2)
MOVD F24, (8*24)(X2)
MOVD F25, (8*25)(X2)
MOVD F26, (8*26)(X2)
MOVD F27, (8*27)(X2)
SAVE_GPR((8*4))
SAVE_FPR((8*16))
// Initialize g as nil in case of using g later e.g. sigaction in cgo_sigaction.go
MOV X0, g
@@ -66,30 +45,8 @@ nocgo:
restore:
// Restore callee-save registers, along with X1 (LR).
MOV (8*3)(X2), X1
MOV (8*4)(X2), X8
MOV (8*5)(X2), X9
MOV (8*6)(X2), X18
MOV (8*7)(X2), X19
MOV (8*8)(X2), X20
MOV (8*9)(X2), X21
MOV (8*10)(X2), X22
MOV (8*11)(X2), X23
MOV (8*12)(X2), X24
MOV (8*13)(X2), X25
MOV (8*14)(X2), X26
MOV (8*15)(X2), g
MOVD (8*16)(X2), F8
MOVD (8*17)(X2), F9
MOVD (8*18)(X2), F18
MOVD (8*19)(X2), F19
MOVD (8*20)(X2), F20
MOVD (8*21)(X2), F21
MOVD (8*22)(X2), F22
MOVD (8*23)(X2), F23
MOVD (8*24)(X2), F24
MOVD (8*25)(X2), F25
MOVD (8*26)(X2), F26
MOVD (8*27)(X2), F27
RESTORE_GPR((8*4))
RESTORE_FPR((8*16))
RET

View File

@@ -0,0 +1,72 @@
// Copyright 2026 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_GPR(offset) saves X8, X9, X18-X27 to the stack space
// of ((offset)+0*8)(X2) ~ ((offset)+11*8)(X2).
//
// SAVE_FPR(offset) saves F8, F9, F18-F27 to the stack space
// of ((offset)+0*8)(X2) ~ ((offset)+11*8)(X2).
//
// Note: g is X27
#define SAVE_GPR(offset) \
MOV X8, ((offset)+0*8)(X2) \
MOV X9, ((offset)+1*8)(X2) \
MOV X18, ((offset)+2*8)(X2) \
MOV X19, ((offset)+3*8)(X2) \
MOV X20, ((offset)+4*8)(X2) \
MOV X21, ((offset)+5*8)(X2) \
MOV X22, ((offset)+6*8)(X2) \
MOV X23, ((offset)+7*8)(X2) \
MOV X24, ((offset)+8*8)(X2) \
MOV X25, ((offset)+9*8)(X2) \
MOV X26, ((offset)+10*8)(X2) \
MOV g, ((offset)+11*8)(X2)
#define RESTORE_GPR(offset) \
MOV ((offset)+0*8)(X2), X8 \
MOV ((offset)+1*8)(X2), X9 \
MOV ((offset)+2*8)(X2), X18 \
MOV ((offset)+3*8)(X2), X19 \
MOV ((offset)+4*8)(X2), X20 \
MOV ((offset)+5*8)(X2), X21 \
MOV ((offset)+6*8)(X2), X22 \
MOV ((offset)+7*8)(X2), X23 \
MOV ((offset)+8*8)(X2), X24 \
MOV ((offset)+9*8)(X2), X25 \
MOV ((offset)+10*8)(X2), X26 \
MOV ((offset)+11*8)(X2), g
#define SAVE_FPR(offset) \
MOVD F8, ((offset)+0*8)(X2) \
MOVD F9, ((offset)+1*8)(X2) \
MOVD F18, ((offset)+2*8)(X2) \
MOVD F19, ((offset)+3*8)(X2) \
MOVD F20, ((offset)+4*8)(X2) \
MOVD F21, ((offset)+5*8)(X2) \
MOVD F22, ((offset)+6*8)(X2) \
MOVD F23, ((offset)+7*8)(X2) \
MOVD F24, ((offset)+8*8)(X2) \
MOVD F25, ((offset)+9*8)(X2) \
MOVD F26, ((offset)+10*8)(X2) \
MOVD F27, ((offset)+11*8)(X2)
#define RESTORE_FPR(offset) \
MOVD ((offset)+0*8)(X2), F8 \
MOVD ((offset)+1*8)(X2), F9 \
MOVD ((offset)+2*8)(X2), F18 \
MOVD ((offset)+3*8)(X2), F19 \
MOVD ((offset)+4*8)(X2), F20 \
MOVD ((offset)+5*8)(X2), F21 \
MOVD ((offset)+6*8)(X2), F22 \
MOVD ((offset)+7*8)(X2), F23 \
MOVD ((offset)+8*8)(X2), F24 \
MOVD ((offset)+9*8)(X2), F25 \
MOVD ((offset)+10*8)(X2), F26 \
MOVD ((offset)+11*8)(X2), F27

View File

@@ -3,6 +3,7 @@
// license that can be found in the LICENSE file.
#include "textflag.h"
#include "abi_riscv64.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
@@ -31,61 +32,19 @@ TEXT crosscall2(SB),NOSPLIT|NOFRAME,$0
MOV X10, (8*1)(X2) // fn unsafe.Pointer
MOV X11, (8*2)(X2) // a unsafe.Pointer
MOV X13, (8*3)(X2) // ctxt uintptr
MOV X8, (8*4)(X2)
MOV X9, (8*5)(X2)
MOV X18, (8*6)(X2)
MOV X19, (8*7)(X2)
MOV X20, (8*8)(X2)
MOV X21, (8*9)(X2)
MOV X22, (8*10)(X2)
MOV X23, (8*11)(X2)
MOV X24, (8*12)(X2)
MOV X25, (8*13)(X2)
MOV X26, (8*14)(X2)
MOV g, (8*15)(X2)
SAVE_GPR((8*4))
MOV X1, (8*16)(X2)
MOVD F8, (8*17)(X2)
MOVD F9, (8*18)(X2)
MOVD F18, (8*19)(X2)
MOVD F19, (8*20)(X2)
MOVD F20, (8*21)(X2)
MOVD F21, (8*22)(X2)
MOVD F22, (8*23)(X2)
MOVD F23, (8*24)(X2)
MOVD F24, (8*25)(X2)
MOVD F25, (8*26)(X2)
MOVD F26, (8*27)(X2)
MOVD F27, (8*28)(X2)
SAVE_FPR((8*17))
// Initialize Go ABI environment
CALL runtime·load_g(SB)
CALL runtime·cgocallback(SB)
MOV (8*4)(X2), X8
MOV (8*5)(X2), X9
MOV (8*6)(X2), X18
MOV (8*7)(X2), X19
MOV (8*8)(X2), X20
MOV (8*9)(X2), X21
MOV (8*10)(X2), X22
MOV (8*11)(X2), X23
MOV (8*12)(X2), X24
MOV (8*13)(X2), X25
MOV (8*14)(X2), X26
MOV (8*15)(X2), g
RESTORE_GPR((8*4))
MOV (8*16)(X2), X1
MOVD (8*17)(X2), F8
MOVD (8*18)(X2), F9
MOVD (8*19)(X2), F18
MOVD (8*20)(X2), F19
MOVD (8*21)(X2), F20
MOVD (8*22)(X2), F21
MOVD (8*23)(X2), F22
MOVD (8*24)(X2), F23
MOVD (8*25)(X2), F24
MOVD (8*26)(X2), F25
MOVD (8*27)(X2), F26
MOVD (8*28)(X2), F27
RESTORE_FPR((8*17))
ADD $(8*29), X2
RET

View File

@@ -7,6 +7,7 @@
#include "go_asm.h"
#include "funcdata.h"
#include "textflag.h"
#include "cgo/abi_riscv64.h"
// The following thunks allow calling the gcc-compiled race runtime directly
// from Go code without going all the way through cgo.
@@ -473,30 +474,8 @@ rest:
// 8(X2) and 16(X2) are for args passed to racecallback
SUB $(27*8), X2
MOV X1, (0*8)(X2)
MOV X8, (3*8)(X2)
MOV X9, (4*8)(X2)
MOV X18, (5*8)(X2)
MOV X19, (6*8)(X2)
MOV X20, (7*8)(X2)
MOV X21, (8*8)(X2)
MOV X22, (9*8)(X2)
MOV X23, (10*8)(X2)
MOV X24, (11*8)(X2)
MOV X25, (12*8)(X2)
MOV X26, (13*8)(X2)
MOV g, (14*8)(X2)
MOVD F8, (15*8)(X2)
MOVD F9, (16*8)(X2)
MOVD F18, (17*8)(X2)
MOVD F19, (18*8)(X2)
MOVD F20, (19*8)(X2)
MOVD F21, (20*8)(X2)
MOVD F22, (21*8)(X2)
MOVD F23, (22*8)(X2)
MOVD F24, (23*8)(X2)
MOVD F25, (24*8)(X2)
MOVD F26, (25*8)(X2)
MOVD F27, (26*8)(X2)
SAVE_GPR((3*8))
SAVE_FPR((15*8))
// Set g = g0.
CALL runtime·load_g(SB)
@@ -515,30 +494,8 @@ rest:
ret:
// Restore callee-save registers.
MOV (0*8)(X2), X1
MOV (3*8)(X2), X8
MOV (4*8)(X2), X9
MOV (5*8)(X2), X18
MOV (6*8)(X2), X19
MOV (7*8)(X2), X20
MOV (8*8)(X2), X21
MOV (9*8)(X2), X22
MOV (10*8)(X2), X23
MOV (11*8)(X2), X24
MOV (12*8)(X2), X25
MOV (13*8)(X2), X26
MOV (14*8)(X2), g
MOVD (15*8)(X2), F8
MOVD (16*8)(X2), F9
MOVD (17*8)(X2), F18
MOVD (18*8)(X2), F19
MOVD (19*8)(X2), F20
MOVD (20*8)(X2), F21
MOVD (21*8)(X2), F22
MOVD (22*8)(X2), F23
MOVD (23*8)(X2), F24
MOVD (24*8)(X2), F25
MOVD (25*8)(X2), F26
MOVD (26*8)(X2), F27
RESTORE_GPR((3*8))
RESTORE_FPR((15*8))
ADD $(27*8), X2
JMP (X1)