cmd/asm,cmd/compile,cmd/internal/obj/riscv: use compressed instructions on riscv64

Make use of compressed instructions on riscv64 - add a compress
pass to the end of the assembler, which replaces non-compressed
instructions with compressed alternatives if possible.

Provide a `compressinstructions` compiler and assembler debug
flag, such that the compression pass can be disabled via
`-asmflags=all=-d=compressinstructions=0` and
`-gcflags=all=-d=compressinstructions=0`. Note that this does
not prevent the explicit use of compressed instructions via
assembly.

Note that this does not make use of compressed control transfer
instructions - this will be implemented in later changes.

Reduces the text size of a hello world binary by ~121KB
and reduces the text size of the go binary on riscv64 by ~1.21MB
(between 8-10% in both cases).

Updates #71105

Cq-Include-Trybots: luci.golang.try:gotip-linux-riscv64
Change-Id: I24258353688554042c2a836deed4830cc673e985
Reviewed-on: https://go-review.googlesource.com/c/go/+/523478
Reviewed-by: Mark Ryan <markdryan@rivosinc.com>
Reviewed-by: Mark Freeman <markfreeman@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
This commit is contained in:
Joel Sing 2025-09-26 05:05:49 +10:00
parent b9ef0633f6
commit 9859b43643
9 changed files with 225 additions and 48 deletions

View file

@ -11,8 +11,8 @@ import (
"os"
"os/exec"
"path/filepath"
"regexp"
"runtime"
"strings"
"testing"
)
@ -48,10 +48,10 @@ func genLargeBranch(buf *bytes.Buffer) {
fmt.Fprintln(buf, "TEXT f(SB),0,$0-0")
fmt.Fprintln(buf, "BEQ X0, X0, label")
for i := 0; i < 1<<19; i++ {
fmt.Fprintln(buf, "ADD $0, X0, X0")
fmt.Fprintln(buf, "ADD $0, X5, X0")
}
fmt.Fprintln(buf, "label:")
fmt.Fprintln(buf, "ADD $0, X0, X0")
fmt.Fprintln(buf, "ADD $0, X5, X0")
}
// TestLargeCall generates a large function (>1MB of text) with a call to
@ -112,11 +112,11 @@ func genLargeCall(buf *bytes.Buffer) {
fmt.Fprintln(buf, "TEXT ·x(SB),0,$0-0")
fmt.Fprintln(buf, "CALL ·y(SB)")
for i := 0; i < 1<<19; i++ {
fmt.Fprintln(buf, "ADD $0, X0, X0")
fmt.Fprintln(buf, "ADD $0, X5, X0")
}
fmt.Fprintln(buf, "RET")
fmt.Fprintln(buf, "TEXT ·y(SB),0,$0-0")
fmt.Fprintln(buf, "ADD $0, X0, X0")
fmt.Fprintln(buf, "ADD $0, X5, X0")
fmt.Fprintln(buf, "RET")
}
@ -301,9 +301,9 @@ TEXT _stub(SB),$0-0
// FENCE
// NOP
// FENCE
// RET
want := "0f 00 f0 0f 13 00 00 00 0f 00 f0 0f 67 80 00 00"
if !strings.Contains(string(out), want) {
// RET (CJALR or JALR)
want := regexp.MustCompile("0x0000 0f 00 f0 0f 13 00 00 00 0f 00 f0 0f (82 80|67 80 00 00) ")
if !want.Match(out) {
t.Errorf("PCALIGN test failed - got %s\nwant %s", out, want)
}
}