diff --git a/src/cmd/dist/build.go b/src/cmd/dist/build.go index 32e59b446a..96199bcbfa 100644 --- a/src/cmd/dist/build.go +++ b/src/cmd/dist/build.go @@ -38,6 +38,7 @@ var ( gomips string gomips64 string goppc64 string + goriscv64 string goroot string goroot_final string goextlinkenabled string @@ -177,6 +178,12 @@ func xinit() { } goppc64 = b + b = os.Getenv("GORISCV64") + if b == "" { + b = "rva20u64" + } + goriscv64 = b + if p := pathf("%s/src/all.bash", goroot); !isfile(p) { fatalf("$GOROOT is not set correctly or not exported\n"+ "\tGOROOT=%s\n"+ @@ -236,6 +243,7 @@ func xinit() { os.Setenv("GOMIPS", gomips) os.Setenv("GOMIPS64", gomips64) os.Setenv("GOPPC64", goppc64) + os.Setenv("GORISCV64", goriscv64) os.Setenv("GOROOT", goroot) os.Setenv("GOROOT_FINAL", goroot_final) @@ -891,6 +899,10 @@ func runInstall(pkg string, ch chan struct{}) { 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) // Collect symabis from assembly code. @@ -1236,6 +1248,9 @@ func cmdenv() { if goarch == "ppc64" || goarch == "ppc64le" { xprintf(format, "GOPPC64", goppc64) } + if goarch == "riscv64" { + xprintf(format, "GORISCV64", goriscv64) + } xprintf(format, "GOWORK", "off") if *path { diff --git a/src/cmd/dist/buildruntime.go b/src/cmd/dist/buildruntime.go index 1de78f0fdb..b041183bdf 100644 --- a/src/cmd/dist/buildruntime.go +++ b/src/cmd/dist/buildruntime.go @@ -57,6 +57,7 @@ func mkbuildcfg(file string) { fmt.Fprintf(&buf, "const defaultGOMIPS = `%s`\n", gomips) fmt.Fprintf(&buf, "const defaultGOMIPS64 = `%s`\n", gomips64) 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 defaultGO_EXTLINK_ENABLED = `%s`\n", goextlinkenabled) fmt.Fprintf(&buf, "const defaultGO_LDSO = `%s`\n", defaultldso) diff --git a/src/cmd/go/alldocs.go b/src/cmd/go/alldocs.go index e61e865c84..05e42a6d31 100644 --- a/src/cmd/go/alldocs.go +++ b/src/cmd/go/alldocs.go @@ -2001,10 +2001,13 @@ // ppc64.power8, ppc64.power9, and ppc64.power10 // (or ppc64le.power8, ppc64le.power9, and ppc64le.power10) // 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 // 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. // 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 @@ -2300,6 +2303,10 @@ // GOPPC64 // For GOARCH=ppc64{,le}, the target ISA (Instruction Set Architecture). // 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 // For GOARCH=wasm, comma-separated list of experimental WebAssembly features to use. // Valid values are satconv, signext. diff --git a/src/cmd/go/internal/cfg/cfg.go b/src/cmd/go/internal/cfg/cfg.go index a8daa2dfc3..948bceab32 100644 --- a/src/cmd/go/internal/cfg/cfg.go +++ b/src/cmd/go/internal/cfg/cfg.go @@ -408,13 +408,14 @@ var ( GOMODCACHE = envOr("GOMODCACHE", gopathDir("pkg/mod")) // Used in envcmd.MkEnv and build ID computations. - GOARM = envOr("GOARM", fmt.Sprint(buildcfg.GOARM)) - GO386 = envOr("GO386", buildcfg.GO386) - GOAMD64 = envOr("GOAMD64", fmt.Sprintf("%s%d", "v", buildcfg.GOAMD64)) - GOMIPS = envOr("GOMIPS", buildcfg.GOMIPS) - GOMIPS64 = envOr("GOMIPS64", buildcfg.GOMIPS64) - GOPPC64 = envOr("GOPPC64", fmt.Sprintf("%s%d", "power", buildcfg.GOPPC64)) - GOWASM = envOr("GOWASM", fmt.Sprint(buildcfg.GOWASM)) + GOARM = envOr("GOARM", fmt.Sprint(buildcfg.GOARM)) + GO386 = envOr("GO386", buildcfg.GO386) + GOAMD64 = envOr("GOAMD64", fmt.Sprintf("%s%d", "v", buildcfg.GOAMD64)) + GOMIPS = envOr("GOMIPS", buildcfg.GOMIPS) + GOMIPS64 = envOr("GOMIPS64", buildcfg.GOMIPS64) + GOPPC64 = envOr("GOPPC64", fmt.Sprintf("%s%d", "power", buildcfg.GOPPC64)) + GORISCV64 = envOr("GORISCV64", fmt.Sprintf("rva%du64", buildcfg.GORISCV64)) + GOWASM = envOr("GOWASM", fmt.Sprint(buildcfg.GOWASM)) GOPROXY = envOr("GOPROXY", "") GOSUMDB = envOr("GOSUMDB", "") @@ -445,6 +446,8 @@ func GetArchEnv() (key, val string) { return "GOMIPS64", GOMIPS64 case "ppc64", "ppc64le": return "GOPPC64", GOPPC64 + case "riscv64": + return "GORISCV64", GORISCV64 case "wasm": return "GOWASM", GOWASM } diff --git a/src/cmd/go/internal/help/helpdoc.go b/src/cmd/go/internal/help/helpdoc.go index c5d1e2af16..a53e078d79 100644 --- a/src/cmd/go/internal/help/helpdoc.go +++ b/src/cmd/go/internal/help/helpdoc.go @@ -619,6 +619,10 @@ Architecture-specific environment variables: GOPPC64 For GOARCH=ppc64{,le}, the target ISA (Instruction Set Architecture). 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 For GOARCH=wasm, comma-separated list of experimental WebAssembly features to use. Valid values are satconv, signext. @@ -907,10 +911,13 @@ The defined architecture feature build tags are: ppc64.power8, ppc64.power9, and ppc64.power10 (or ppc64le.power8, ppc64le.power9, and ppc64le.power10) 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 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. 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 diff --git a/src/cmd/go/internal/work/gc.go b/src/cmd/go/internal/work/gc.go index e2a5456bde..09ea8259e0 100644 --- a/src/cmd/go/internal/work/gc.go +++ b/src/cmd/go/internal/work/gc.go @@ -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" { // Define GOARM_value from cfg.GOARM. switch cfg.GOARM { diff --git a/src/cmd/go/testdata/script/tooltags.txt b/src/cmd/go/testdata/script/tooltags.txt index 27068eebae..1f6f54563c 100644 --- a/src/cmd/go/testdata/script/tooltags.txt +++ b/src/cmd/go/testdata/script/tooltags.txt @@ -40,6 +40,26 @@ env GOPPC64=power10 go list -f '{{context.ToolTags}}' 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 GO386=sse2 go list -f '{{context.ToolTags}}' diff --git a/src/cmd/internal/testdir/testdir_test.go b/src/cmd/internal/testdir/testdir_test.go index 0fb56e6c78..a26733d856 100644 --- a/src/cmd/internal/testdir/testdir_test.go +++ b/src/cmd/internal/testdir/testdir_test.go @@ -1468,7 +1468,7 @@ var ( "ppc64x": {}, // A pseudo-arch representing both ppc64 and ppc64le "s390x": {}, "wasm": {}, - "riscv64": {}, + "riscv64": {"GORISCV64", "rva20u64", "rva22u64"}, } ) diff --git a/src/internal/buildcfg/cfg.go b/src/internal/buildcfg/cfg.go index 8b97a653d7..0bf5b8f75c 100644 --- a/src/internal/buildcfg/cfg.go +++ b/src/internal/buildcfg/cfg.go @@ -21,19 +21,20 @@ import ( ) var ( - GOROOT = runtime.GOROOT() // cached for efficiency - GOARCH = envOr("GOARCH", defaultGOARCH) - GOOS = envOr("GOOS", defaultGOOS) - GO386 = envOr("GO386", defaultGO386) - GOAMD64 = goamd64() - GOARM = goarm() - GOMIPS = gomips() - GOMIPS64 = gomips64() - GOPPC64 = goppc64() - GOWASM = gowasm() - ToolTags = toolTags() - GO_LDSO = defaultGO_LDSO - Version = version + GOROOT = runtime.GOROOT() // cached for efficiency + GOARCH = envOr("GOARCH", defaultGOARCH) + GOOS = envOr("GOOS", defaultGOOS) + GO386 = envOr("GO386", defaultGO386) + GOAMD64 = goamd64() + GOARM = goarm() + GOMIPS = gomips() + GOMIPS64 = gomips64() + GOPPC64 = goppc64() + GORISCV64 = goriscv64() + GOWASM = gowasm() + ToolTags = toolTags() + GO_LDSO = defaultGO_LDSO + Version = version ) // 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') } +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 { SatConv bool SignExt bool @@ -260,6 +277,12 @@ func gogoarchTags() []string { list = append(list, fmt.Sprintf("%s.power%d", GOARCH, i)) } return list + case "riscv64": + list := []string{GOARCH + "." + "rva20u64"} + if GORISCV64 >= 22 { + list = append(list, GOARCH+"."+"rva22u64") + } + return list case "wasm": var list []string if GOWASM.SatConv { diff --git a/src/internal/buildcfg/cfg_test.go b/src/internal/buildcfg/cfg_test.go index 0123593317..69eeef2422 100644 --- a/src/internal/buildcfg/cfg_test.go +++ b/src/internal/buildcfg/cfg_test.go @@ -23,4 +23,18 @@ func TestConfigFlags(t *testing.T) { if goamd64(); Error == nil { 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") + } } diff --git a/src/internal/cfg/cfg.go b/src/internal/cfg/cfg.go index 2af0ec7078..a9c99c4b96 100644 --- a/src/internal/cfg/cfg.go +++ b/src/internal/cfg/cfg.go @@ -57,6 +57,7 @@ const KnownEnv = ` GOPPC64 GOPRIVATE GOPROXY + GORISCV64 GOROOT GOSUMDB GOTMPDIR