]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/go: add GORISCV64 environment variable
authorMark Ryan <markdryan@rivosinc.com>
Tue, 7 Nov 2023 09:09:49 +0000 (10:09 +0100)
committerJoel Sing <joel@sing.id.au>
Wed, 24 Jan 2024 07:25:25 +0000 (07:25 +0000)
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>

src/cmd/dist/build.go
src/cmd/dist/buildruntime.go
src/cmd/go/alldocs.go
src/cmd/go/internal/cfg/cfg.go
src/cmd/go/internal/help/helpdoc.go
src/cmd/go/internal/work/gc.go
src/cmd/go/testdata/script/tooltags.txt
src/cmd/internal/testdir/testdir_test.go
src/internal/buildcfg/cfg.go
src/internal/buildcfg/cfg_test.go
src/internal/cfg/cfg.go

index 32e59b446a5d9be5be970271cb3e9b7a0c59304f..96199bcbfa827d77688fb8c1fee73c3cbc929729 100644 (file)
@@ -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 {
index 1de78f0fdb2eb10f5384a49081de95d9021c565d..b041183bdf58d4b897844e01d6a8a20fe219a5b2 100644 (file)
@@ -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)
index e61e865c84a8f77b06196c584f29f5f8bda3640b..05e42a6d3111448d5ef9406ec8e0ba217644700f 100644 (file)
 //     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
 //     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.
index a8daa2dfc369ea45a6a47a05ad4157bb2f7ee9bb..948bceab32fdc3b2a4d8bd71db7abb3c5487ee6d 100644 (file)
@@ -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
        }
index c5d1e2af16e2286ed0f8be3164a605d8926a16c3..a53e078d7955bdf546b97615a905c3e6e345dbca 100644 (file)
@@ -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
index e2a5456bdec808f12da303235b94f3759f8e9196..09ea8259e054e548868196ed629eb109cf1bb0e2 100644 (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" {
                // Define GOARM_value from cfg.GOARM.
                switch cfg.GOARM {
index 27068eebaeb9590f91cd32dc667301085ef89b36..1f6f54563ca97a52b4aade3d5a713007eb9dff03 100644 (file)
@@ -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}}'
index 0fb56e6c785a71f3326f4dd0baf821d5adcd2160..a26733d856b0c799ac4d260852a8bca2d6ca6363 100644 (file)
@@ -1468,7 +1468,7 @@ var (
                "ppc64x":  {}, // A pseudo-arch representing both ppc64 and ppc64le
                "s390x":   {},
                "wasm":    {},
-               "riscv64": {},
+               "riscv64": {"GORISCV64", "rva20u64", "rva22u64"},
        }
 )
 
index 8b97a653d77394fb80d782db7fd22d5662111f76..0bf5b8f75c2e9a76e9185e30bee4fe956976a5bd 100644 (file)
@@ -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 {
index 0123593317d4319bf94ee3c12d7a910a5c35c13d..69eeef24221523b41706dfc0c0751ce3763773f1 100644 (file)
@@ -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")
+       }
 }
index 2af0ec707868947bda6c966a3156625241db12c7..a9c99c4b966de1f465ecc7d5150d2e2b95920a4b 100644 (file)
@@ -57,6 +57,7 @@ const KnownEnv = `
        GOPPC64
        GOPRIVATE
        GOPROXY
+       GORISCV64
        GOROOT
        GOSUMDB
        GOTMPDIR