aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJoel Sing <joel@sing.id.au>2023-08-27 19:35:33 +1000
committerJoel Sing <joel@sing.id.au>2025-11-17 23:33:36 -0800
commitb9ef0633f6117c74fabcd7247a76b4feb86df086 (patch)
treee72455efe805092171cecbae5349b0b066a0e1e8 /src
parenta087dea8692eee879e8226b70eb691dea7758b0b (diff)
downloadgo-b9ef0633f6117c74fabcd7247a76b4feb86df086.tar.xz
cmd/internal/sys,internal/goarch,runtime: enable the use of compressed instructions on riscv64
Enable the use of compressed instructions on riscv64 by reducing the PC quantum to two bytes and reducing the minimum instruction length to two bytes. Change gostartcall on riscv64 to land at two times the PC quantum into goexit, so that we retain four byte alignment and revise the NOP instructions in goexit to ensure that they are never compressed. Additionally, adjust PCALIGN so that it correctly handles two byte offsets. Fixes #47560 Updates #71105 Cq-Include-Trybots: luci.golang.try:gotip-linux-riscv64 Change-Id: I4329a8fbfcb4de636aadaeadabb826bc22698640 Reviewed-on: https://go-review.googlesource.com/c/go/+/523477 Reviewed-by: Junyang Shao <shaojunyang@google.com> Reviewed-by: Mark Freeman <markfreeman@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Mark Ryan <markdryan@rivosinc.com>
Diffstat (limited to 'src')
-rw-r--r--src/cmd/internal/obj/riscv/obj.go11
-rw-r--r--src/cmd/internal/sys/arch.go2
-rw-r--r--src/internal/goarch/goarch_riscv64.go2
-rw-r--r--src/runtime/asm_riscv64.s10
-rw-r--r--src/runtime/sys_riscv64.go11
5 files changed, 25 insertions, 11 deletions
diff --git a/src/cmd/internal/obj/riscv/obj.go b/src/cmd/internal/obj/riscv/obj.go
index 3deab34d31..8b9be5d78b 100644
--- a/src/cmd/internal/obj/riscv/obj.go
+++ b/src/cmd/internal/obj/riscv/obj.go
@@ -4799,10 +4799,17 @@ func assemble(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
v := pcAlignPadLength(p.Pc, alignedValue)
offset := p.Pc
for ; v >= 4; v -= 4 {
- // NOP
- cursym.WriteBytes(ctxt, offset, []byte{0x13, 0, 0, 0})
+ // NOP (ADDI $0, X0, X0)
+ cursym.WriteBytes(ctxt, offset, []byte{0x13, 0x00, 0x00, 0x00})
offset += 4
}
+ if v == 2 {
+ // CNOP
+ cursym.WriteBytes(ctxt, offset, []byte{0x01, 0x00})
+ offset += 2
+ } else if v != 0 {
+ ctxt.Diag("bad PCALIGN pad length")
+ }
continue
}
diff --git a/src/cmd/internal/sys/arch.go b/src/cmd/internal/sys/arch.go
index 3c92a6bbf2..14b1cde22b 100644
--- a/src/cmd/internal/sys/arch.go
+++ b/src/cmd/internal/sys/arch.go
@@ -236,7 +236,7 @@ var ArchRISCV64 = &Arch{
ByteOrder: binary.LittleEndian,
PtrSize: 8,
RegSize: 8,
- MinLC: 4,
+ MinLC: 2,
Alignment: 8, // riscv unaligned loads work, but are really slow (trap + simulated by OS)
CanMergeLoads: false,
HasLR: true,
diff --git a/src/internal/goarch/goarch_riscv64.go b/src/internal/goarch/goarch_riscv64.go
index 3b6da1e02f..468f9a6374 100644
--- a/src/internal/goarch/goarch_riscv64.go
+++ b/src/internal/goarch/goarch_riscv64.go
@@ -7,7 +7,7 @@ package goarch
const (
_ArchFamily = RISCV64
_DefaultPhysPageSize = 4096
- _PCQuantum = 4
+ _PCQuantum = 2
_MinFrameSize = 8
_StackAlign = PtrSize
)
diff --git a/src/runtime/asm_riscv64.s b/src/runtime/asm_riscv64.s
index 5bd16181ee..428701a503 100644
--- a/src/runtime/asm_riscv64.s
+++ b/src/runtime/asm_riscv64.s
@@ -623,14 +623,14 @@ TEXT _cgo_topofstack(SB),NOSPLIT,$8
RET
// func goexit(neverCallThisFunction)
-// The top-most function running on a goroutine
-// returns to goexit+PCQuantum.
+// The top-most function running on a goroutine, returns to goexit+PCQuantum*2.
+// Note that the NOPs are written in a manner that will not be compressed,
+// since the offset must be known by the runtime.
TEXT runtime·goexit(SB),NOSPLIT|NOFRAME|TOPFRAME,$0-0
- MOV ZERO, ZERO // NOP
+ WORD $0x00000013 // NOP
JMP runtime·goexit1(SB) // does not return
// traceback from goexit1 must hit code range of goexit
- MOV ZERO, ZERO // NOP
-
+ WORD $0x00000013 // NOP
// This is called from .init_array and follows the platform, not the Go ABI.
TEXT runtime·addmoduledata(SB),NOSPLIT,$0-0
diff --git a/src/runtime/sys_riscv64.go b/src/runtime/sys_riscv64.go
index e710840819..65dc684c33 100644
--- a/src/runtime/sys_riscv64.go
+++ b/src/runtime/sys_riscv64.go
@@ -4,7 +4,12 @@
package runtime
-import "unsafe"
+import (
+ "unsafe"
+
+ "internal/abi"
+ "internal/runtime/sys"
+)
// adjust Gobuf as if it executed a call to fn with context ctxt
// and then did an immediate Gosave.
@@ -12,7 +17,9 @@ func gostartcall(buf *gobuf, fn, ctxt unsafe.Pointer) {
if buf.lr != 0 {
throw("invalid use of gostartcall")
}
- buf.lr = buf.pc
+ // Use double the PC quantum on riscv64, so that we retain
+ // four byte alignment and use non-compressed instructions.
+ buf.lr = abi.FuncPCABI0(goexit) + sys.PCQuantum*2
buf.pc = uintptr(fn)
buf.ctxt = ctxt
}