1
0
mirror of https://github.com/golang/go synced 2024-11-17 12:54:47 -07:00

cmd/go: add GORISCV64 environment variable

The variable represents the RISC-V user-mode application profile for
which to compile.  Valid values are rva20u64 (the default) and
rva22u64.

Setting GORISCV64=rva20u64 defines the riscv64.rva20u64 build tag,
sets the internal variable buildcfg.GORISCV64 to 20 and defines the
macro GORISCV64_rva20u64 for use in assembly language code.

Setting GORISCV64=rva22u64 defines the riscv64.rva20u64 and
riscv64.rva22u64 build tags, sets the internal variable
buildcfg.GORISCV64 to 22 and defines the macro GORISCV64_rva22u64
for use in assembly language code.

This patch only provides a mechanism for the compiler and hand-coded
assembly language functions to take advantage of the RISC-V
extensions mandated by the application profiles.  Further patches
will be required to get the compiler/assembler and assembly language
functions to actually generate and use these extensions.

Fixes #61476

Change-Id: I9195ae6ee71703cd2112160e89157ab63b8391af
Reviewed-on: https://go-review.googlesource.com/c/go/+/541135
Reviewed-by: M Zhuo <mengzhuo1203@gmail.com>
Reviewed-by: Joel Sing <joel@sing.id.au>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Wang Yaduo <wangyaduo@linux.alibaba.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
Reviewed-by: Bryan Mills <bcmills@google.com>
Run-TryBot: M Zhuo <mengzhuo1203@gmail.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
This commit is contained in:
Mark Ryan 2023-11-07 10:09:49 +01:00 committed by Joel Sing
parent b3acaa8230
commit b4e7d630bc
11 changed files with 119 additions and 23 deletions

15
src/cmd/dist/build.go vendored
View File

@ -38,6 +38,7 @@ var (
gomips string gomips string
gomips64 string gomips64 string
goppc64 string goppc64 string
goriscv64 string
goroot string goroot string
goroot_final string goroot_final string
goextlinkenabled string goextlinkenabled string
@ -177,6 +178,12 @@ func xinit() {
} }
goppc64 = b goppc64 = b
b = os.Getenv("GORISCV64")
if b == "" {
b = "rva20u64"
}
goriscv64 = b
if p := pathf("%s/src/all.bash", goroot); !isfile(p) { if p := pathf("%s/src/all.bash", goroot); !isfile(p) {
fatalf("$GOROOT is not set correctly or not exported\n"+ fatalf("$GOROOT is not set correctly or not exported\n"+
"\tGOROOT=%s\n"+ "\tGOROOT=%s\n"+
@ -236,6 +243,7 @@ func xinit() {
os.Setenv("GOMIPS", gomips) os.Setenv("GOMIPS", gomips)
os.Setenv("GOMIPS64", gomips64) os.Setenv("GOMIPS64", gomips64)
os.Setenv("GOPPC64", goppc64) os.Setenv("GOPPC64", goppc64)
os.Setenv("GORISCV64", goriscv64)
os.Setenv("GOROOT", goroot) os.Setenv("GOROOT", goroot)
os.Setenv("GOROOT_FINAL", goroot_final) os.Setenv("GOROOT_FINAL", goroot_final)
@ -891,6 +899,10 @@ func runInstall(pkg string, ch chan struct{}) {
asmArgs = append(asmArgs, "-D", "GOPPC64_power8") asmArgs = append(asmArgs, "-D", "GOPPC64_power8")
} }
} }
if goarch == "riscv64" {
// Define GORISCV64_value from goriscv64
asmArgs = append(asmArgs, "-D", "GORISCV64_"+goriscv64)
}
goasmh := pathf("%s/go_asm.h", workdir) goasmh := pathf("%s/go_asm.h", workdir)
// Collect symabis from assembly code. // Collect symabis from assembly code.
@ -1236,6 +1248,9 @@ func cmdenv() {
if goarch == "ppc64" || goarch == "ppc64le" { if goarch == "ppc64" || goarch == "ppc64le" {
xprintf(format, "GOPPC64", goppc64) xprintf(format, "GOPPC64", goppc64)
} }
if goarch == "riscv64" {
xprintf(format, "GORISCV64", goriscv64)
}
xprintf(format, "GOWORK", "off") xprintf(format, "GOWORK", "off")
if *path { if *path {

View File

@ -57,6 +57,7 @@ func mkbuildcfg(file string) {
fmt.Fprintf(&buf, "const defaultGOMIPS = `%s`\n", gomips) fmt.Fprintf(&buf, "const defaultGOMIPS = `%s`\n", gomips)
fmt.Fprintf(&buf, "const defaultGOMIPS64 = `%s`\n", gomips64) fmt.Fprintf(&buf, "const defaultGOMIPS64 = `%s`\n", gomips64)
fmt.Fprintf(&buf, "const defaultGOPPC64 = `%s`\n", goppc64) fmt.Fprintf(&buf, "const defaultGOPPC64 = `%s`\n", goppc64)
fmt.Fprintf(&buf, "const defaultGORISCV64 = `%s`\n", goriscv64)
fmt.Fprintf(&buf, "const defaultGOEXPERIMENT = `%s`\n", goexperiment) fmt.Fprintf(&buf, "const defaultGOEXPERIMENT = `%s`\n", goexperiment)
fmt.Fprintf(&buf, "const defaultGO_EXTLINK_ENABLED = `%s`\n", goextlinkenabled) fmt.Fprintf(&buf, "const defaultGO_EXTLINK_ENABLED = `%s`\n", goextlinkenabled)
fmt.Fprintf(&buf, "const defaultGO_LDSO = `%s`\n", defaultldso) fmt.Fprintf(&buf, "const defaultGO_LDSO = `%s`\n", defaultldso)

View File

@ -2001,10 +2001,13 @@
// ppc64.power8, ppc64.power9, and ppc64.power10 // ppc64.power8, ppc64.power9, and ppc64.power10
// (or ppc64le.power8, ppc64le.power9, and ppc64le.power10) // (or ppc64le.power8, ppc64le.power9, and ppc64le.power10)
// feature build tags. // feature build tags.
// - For GOARCH=riscv64,
// GORISCV64=rva20u64 and rva22u64 correspond to the riscv64.rva20u64
// and riscv64.rva22u64 build tags.
// - For GOARCH=wasm, GOWASM=satconv and signext // - For GOARCH=wasm, GOWASM=satconv and signext
// correspond to the wasm.satconv and wasm.signext feature build tags. // correspond to the wasm.satconv and wasm.signext feature build tags.
// //
// For GOARCH=amd64, arm, ppc64, and ppc64le, a particular feature level // For GOARCH=amd64, arm, ppc64, ppc64le, and riscv64, a particular feature level
// sets the feature build tags for all previous levels as well. // sets the feature build tags for all previous levels as well.
// For example, GOAMD64=v2 sets the amd64.v1 and amd64.v2 feature flags. // For example, GOAMD64=v2 sets the amd64.v1 and amd64.v2 feature flags.
// This ensures that code making use of v2 features continues to compile // This ensures that code making use of v2 features continues to compile
@ -2300,6 +2303,10 @@
// GOPPC64 // GOPPC64
// For GOARCH=ppc64{,le}, the target ISA (Instruction Set Architecture). // For GOARCH=ppc64{,le}, the target ISA (Instruction Set Architecture).
// Valid values are power8 (default), power9, power10. // Valid values are power8 (default), power9, power10.
// GORISCV64
// For GOARCH=riscv64, the RISC-V user-mode application profile for which
// to compile. Valid values are rva20u64 (default), rva22u64.
// See https://github.com/riscv/riscv-profiles/blob/main/profiles.adoc
// GOWASM // GOWASM
// For GOARCH=wasm, comma-separated list of experimental WebAssembly features to use. // For GOARCH=wasm, comma-separated list of experimental WebAssembly features to use.
// Valid values are satconv, signext. // Valid values are satconv, signext.

View File

@ -408,13 +408,14 @@ var (
GOMODCACHE = envOr("GOMODCACHE", gopathDir("pkg/mod")) GOMODCACHE = envOr("GOMODCACHE", gopathDir("pkg/mod"))
// Used in envcmd.MkEnv and build ID computations. // Used in envcmd.MkEnv and build ID computations.
GOARM = envOr("GOARM", fmt.Sprint(buildcfg.GOARM)) GOARM = envOr("GOARM", fmt.Sprint(buildcfg.GOARM))
GO386 = envOr("GO386", buildcfg.GO386) GO386 = envOr("GO386", buildcfg.GO386)
GOAMD64 = envOr("GOAMD64", fmt.Sprintf("%s%d", "v", buildcfg.GOAMD64)) GOAMD64 = envOr("GOAMD64", fmt.Sprintf("%s%d", "v", buildcfg.GOAMD64))
GOMIPS = envOr("GOMIPS", buildcfg.GOMIPS) GOMIPS = envOr("GOMIPS", buildcfg.GOMIPS)
GOMIPS64 = envOr("GOMIPS64", buildcfg.GOMIPS64) GOMIPS64 = envOr("GOMIPS64", buildcfg.GOMIPS64)
GOPPC64 = envOr("GOPPC64", fmt.Sprintf("%s%d", "power", buildcfg.GOPPC64)) GOPPC64 = envOr("GOPPC64", fmt.Sprintf("%s%d", "power", buildcfg.GOPPC64))
GOWASM = envOr("GOWASM", fmt.Sprint(buildcfg.GOWASM)) GORISCV64 = envOr("GORISCV64", fmt.Sprintf("rva%du64", buildcfg.GORISCV64))
GOWASM = envOr("GOWASM", fmt.Sprint(buildcfg.GOWASM))
GOPROXY = envOr("GOPROXY", "") GOPROXY = envOr("GOPROXY", "")
GOSUMDB = envOr("GOSUMDB", "") GOSUMDB = envOr("GOSUMDB", "")
@ -445,6 +446,8 @@ func GetArchEnv() (key, val string) {
return "GOMIPS64", GOMIPS64 return "GOMIPS64", GOMIPS64
case "ppc64", "ppc64le": case "ppc64", "ppc64le":
return "GOPPC64", GOPPC64 return "GOPPC64", GOPPC64
case "riscv64":
return "GORISCV64", GORISCV64
case "wasm": case "wasm":
return "GOWASM", GOWASM return "GOWASM", GOWASM
} }

View File

@ -619,6 +619,10 @@ Architecture-specific environment variables:
GOPPC64 GOPPC64
For GOARCH=ppc64{,le}, the target ISA (Instruction Set Architecture). For GOARCH=ppc64{,le}, the target ISA (Instruction Set Architecture).
Valid values are power8 (default), power9, power10. Valid values are power8 (default), power9, power10.
GORISCV64
For GOARCH=riscv64, the RISC-V user-mode application profile for which
to compile. Valid values are rva20u64 (default), rva22u64.
See https://github.com/riscv/riscv-profiles/blob/main/profiles.adoc
GOWASM GOWASM
For GOARCH=wasm, comma-separated list of experimental WebAssembly features to use. For GOARCH=wasm, comma-separated list of experimental WebAssembly features to use.
Valid values are satconv, signext. Valid values are satconv, signext.
@ -907,10 +911,13 @@ The defined architecture feature build tags are:
ppc64.power8, ppc64.power9, and ppc64.power10 ppc64.power8, ppc64.power9, and ppc64.power10
(or ppc64le.power8, ppc64le.power9, and ppc64le.power10) (or ppc64le.power8, ppc64le.power9, and ppc64le.power10)
feature build tags. feature build tags.
- For GOARCH=riscv64,
GORISCV64=rva20u64 and rva22u64 correspond to the riscv64.rva20u64
and riscv64.rva22u64 build tags.
- For GOARCH=wasm, GOWASM=satconv and signext - For GOARCH=wasm, GOWASM=satconv and signext
correspond to the wasm.satconv and wasm.signext feature build tags. correspond to the wasm.satconv and wasm.signext feature build tags.
For GOARCH=amd64, arm, ppc64, and ppc64le, a particular feature level For GOARCH=amd64, arm, ppc64, ppc64le, and riscv64, a particular feature level
sets the feature build tags for all previous levels as well. sets the feature build tags for all previous levels as well.
For example, GOAMD64=v2 sets the amd64.v1 and amd64.v2 feature flags. For example, GOAMD64=v2 sets the amd64.v1 and amd64.v2 feature flags.
This ensures that code making use of v2 features continues to compile This ensures that code making use of v2 features continues to compile

View File

@ -361,6 +361,11 @@ func asmArgs(a *Action, p *load.Package) []any {
} }
} }
if cfg.Goarch == "riscv64" {
// Define GORISCV64_value from cfg.GORISCV64.
args = append(args, "-D", "GORISCV64_"+cfg.GORISCV64)
}
if cfg.Goarch == "arm" { if cfg.Goarch == "arm" {
// Define GOARM_value from cfg.GOARM. // Define GOARM_value from cfg.GOARM.
switch cfg.GOARM { switch cfg.GOARM {

View File

@ -40,6 +40,26 @@ env GOPPC64=power10
go list -f '{{context.ToolTags}}' go list -f '{{context.ToolTags}}'
stdout 'ppc64le.power8 ppc64le.power9 ppc64le.power10' stdout 'ppc64le.power8 ppc64le.power9 ppc64le.power10'
env GOARCH=riscv64
env GORISCV64=rva20u64
go list -f '{{context.ToolTags}}'
stdout 'riscv64.rva20u64'
env GOARCH=riscv64
env GORISCV64=rva22u64
go list -f '{{context.ToolTags}}'
stdout 'riscv64.rva20u64 riscv64.rva22u64'
env GOARCH=riscv64
env GORISCV64=rva22
! go list -f '{{context.ToolTags}}'
stderr 'go: invalid GORISCV64: must be rva20u64, rva22u64'
env GOARCH=riscv64
env GORISCV64=
go list -f '{{context.ToolTags}}'
stdout 'riscv64.rva20u64'
env GOARCH=386 env GOARCH=386
env GO386=sse2 env GO386=sse2
go list -f '{{context.ToolTags}}' go list -f '{{context.ToolTags}}'

View File

@ -1468,7 +1468,7 @@ var (
"ppc64x": {}, // A pseudo-arch representing both ppc64 and ppc64le "ppc64x": {}, // A pseudo-arch representing both ppc64 and ppc64le
"s390x": {}, "s390x": {},
"wasm": {}, "wasm": {},
"riscv64": {}, "riscv64": {"GORISCV64", "rva20u64", "rva22u64"},
} }
) )

View File

@ -21,19 +21,20 @@ import (
) )
var ( var (
GOROOT = runtime.GOROOT() // cached for efficiency GOROOT = runtime.GOROOT() // cached for efficiency
GOARCH = envOr("GOARCH", defaultGOARCH) GOARCH = envOr("GOARCH", defaultGOARCH)
GOOS = envOr("GOOS", defaultGOOS) GOOS = envOr("GOOS", defaultGOOS)
GO386 = envOr("GO386", defaultGO386) GO386 = envOr("GO386", defaultGO386)
GOAMD64 = goamd64() GOAMD64 = goamd64()
GOARM = goarm() GOARM = goarm()
GOMIPS = gomips() GOMIPS = gomips()
GOMIPS64 = gomips64() GOMIPS64 = gomips64()
GOPPC64 = goppc64() GOPPC64 = goppc64()
GOWASM = gowasm() GORISCV64 = goriscv64()
ToolTags = toolTags() GOWASM = gowasm()
GO_LDSO = defaultGO_LDSO ToolTags = toolTags()
Version = version GO_LDSO = defaultGO_LDSO
Version = version
) )
// Error is one of the errors found (if any) in the build configuration. // Error is one of the errors found (if any) in the build configuration.
@ -157,6 +158,22 @@ func goppc64() int {
return int(defaultGOPPC64[len("power")] - '0') return int(defaultGOPPC64[len("power")] - '0')
} }
func goriscv64() int {
switch v := envOr("GORISCV64", defaultGORISCV64); v {
case "rva20u64":
return 20
case "rva22u64":
return 22
}
Error = fmt.Errorf("invalid GORISCV64: must be rva20u64, rva22u64")
v := defaultGORISCV64[len("rva"):]
i := strings.IndexFunc(v, func(r rune) bool {
return r < '0' || r > '9'
})
year, _ := strconv.Atoi(v[:i])
return year
}
type gowasmFeatures struct { type gowasmFeatures struct {
SatConv bool SatConv bool
SignExt bool SignExt bool
@ -260,6 +277,12 @@ func gogoarchTags() []string {
list = append(list, fmt.Sprintf("%s.power%d", GOARCH, i)) list = append(list, fmt.Sprintf("%s.power%d", GOARCH, i))
} }
return list return list
case "riscv64":
list := []string{GOARCH + "." + "rva20u64"}
if GORISCV64 >= 22 {
list = append(list, GOARCH+"."+"rva22u64")
}
return list
case "wasm": case "wasm":
var list []string var list []string
if GOWASM.SatConv { if GOWASM.SatConv {

View File

@ -23,4 +23,18 @@ func TestConfigFlags(t *testing.T) {
if goamd64(); Error == nil { if goamd64(); Error == nil {
t.Errorf("Wrong parsing of GOAMD64=1") t.Errorf("Wrong parsing of GOAMD64=1")
} }
os.Setenv("GORISCV64", "rva20u64")
if goriscv64() != 20 {
t.Errorf("Wrong parsing of RISCV64=rva20u64")
}
os.Setenv("GORISCV64", "rva22u64")
if goriscv64() != 22 {
t.Errorf("Wrong parsing of RISCV64=rva22u64")
}
Error = nil
os.Setenv("GORISCV64", "rva22")
if _ = goriscv64(); Error == nil {
t.Errorf("Wrong parsing of RISCV64=rva22")
}
} }

View File

@ -57,6 +57,7 @@ const KnownEnv = `
GOPPC64 GOPPC64
GOPRIVATE GOPRIVATE
GOPROXY GOPROXY
GORISCV64
GOROOT GOROOT
GOSUMDB GOSUMDB
GOTMPDIR GOTMPDIR