]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/dist,internal: add GOARM64 environment variable
authorAndrey Bokhanko <andreybokhanko@gmail.com>
Tue, 30 Jan 2024 16:18:24 +0000 (19:18 +0300)
committerM Zhuo <mengzhuo1203@gmail.com>
Wed, 6 Mar 2024 01:33:19 +0000 (01:33 +0000)
Adds GOARM64 environment variable with accepted range of values "v8.{0-9}",
"v9.{0-5}" and optional ",lse" and ",crypto" suffixes.

Right now it doesn't affect anything, but can be used in the future to
selectively target specific versions of different ARM64 hardware.

For #60905

Change-Id: I6d530041b6931aa884e34f719f8ec41b1cb03ece
Reviewed-on: https://go-review.googlesource.com/c/go/+/559555
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Mauri de Souza Meneguzzo <mauri870@gmail.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
Reviewed-by: Shu-Chun Weng <scw@google.com>
Reviewed-by: Fannie Zhang <Fannie.Zhang@arm.com>
src/cmd/dist/build.go
src/cmd/dist/buildruntime.go
src/cmd/go/alldocs.go
src/cmd/go/internal/help/helpdoc.go
src/internal/buildcfg/cfg.go
src/internal/buildcfg/cfg_test.go
src/internal/cfg/cfg.go

index d4d1bd8f0b512cb85f4d7bd9368762db0a56f6a1..64f8f530543d788fd4134851edcae5ef7d878f91 100644 (file)
@@ -33,6 +33,7 @@ var (
        gohostos         string
        goos             string
        goarm            string
+       goarm64          string
        go386            string
        goamd64          string
        gomips           string
@@ -141,6 +142,12 @@ func xinit() {
        }
        goarm = b
 
+       b = os.Getenv("GOARM64")
+       if b == "" {
+               b = "v8.0"
+       }
+       goarm64 = b
+
        b = os.Getenv("GO386")
        if b == "" {
                b = "sse2"
@@ -230,6 +237,7 @@ func xinit() {
        os.Setenv("GOAMD64", goamd64)
        os.Setenv("GOARCH", goarch)
        os.Setenv("GOARM", goarm)
+       os.Setenv("GOARM64", goarm64)
        os.Setenv("GOHOSTARCH", gohostarch)
        os.Setenv("GOHOSTOS", gohostos)
        os.Setenv("GOOS", goos)
@@ -1239,6 +1247,9 @@ func cmdenv() {
        if goarch == "arm" {
                xprintf(format, "GOARM", goarm)
        }
+       if goarch == "arm64" {
+               xprintf(format, "GOARM64", goarm64)
+       }
        if goarch == "386" {
                xprintf(format, "GO386", go386)
        }
index b041183bdf58d4b897844e01d6a8a20fe219a5b2..7095f43772628426a90c3413fdb88715774a5cd8 100644 (file)
@@ -54,6 +54,7 @@ func mkbuildcfg(file string) {
        fmt.Fprintf(&buf, "const defaultGO386 = `%s`\n", go386)
        fmt.Fprintf(&buf, "const defaultGOAMD64 = `%s`\n", goamd64)
        fmt.Fprintf(&buf, "const defaultGOARM = `%s`\n", goarm)
+       fmt.Fprintf(&buf, "const defaultGOARM64 = `%s`\n", goarm64)
        fmt.Fprintf(&buf, "const defaultGOMIPS = `%s`\n", gomips)
        fmt.Fprintf(&buf, "const defaultGOMIPS64 = `%s`\n", gomips64)
        fmt.Fprintf(&buf, "const defaultGOPPC64 = `%s`\n", goppc64)
index 153128e715151b3f709c006b60848e8e497e49df..dde47ac1b86bb3c66bbd1accd250577e44f4195f 100644 (file)
 //     correspond to the amd64.v1, amd64.v2, and amd64.v3 feature build tags.
 //   - For GOARCH=arm, GOARM=5, 6, and 7
 //     correspond to the arm.5, arm.6, and arm.7 feature build tags.
+//   - For GOARCH=arm64, GOARM64=v8.{0-9} and v9.{0-5}
+//     correspond to the arm64.v8.{0-9} and arm64.v9.{0-5} feature build tags.
 //   - For GOARCH=mips or mipsle,
 //     GOMIPS=hardfloat and softfloat
 //     correspond to the mips.hardfloat and mips.softfloat
 //             Valid values are 5, 6, 7.
 //             The value can be followed by an option specifying how to implement floating point instructions.
 //             Valid options are ,softfloat (default for 5) and ,hardfloat (default for 6 and 7).
+//     GOARM64
+//             For GOARCH=arm64, the ARM64 architecture for which to compile.
+//             Valid values are v8.0 (default), v8.{1-9}, v9.{0-5}.
+//             The value can be followed by an option specifying extensions implemented by target hardware.
+//             Valid options are ,lse and ,crypto.
+//             Note that some extensions are enabled by default starting from a certain GOARM64 version;
+//             for example, lse is enabled by default starting from v8.1.
 //     GO386
 //             For GOARCH=386, how to implement floating point instructions.
 //             Valid values are sse2 (default), softfloat.
index ddaca3807af7afd46badd9327bb3c99ebcaea944..e1d719be4f1cf0dcea189d6fccb05f50183f5c63 100644 (file)
@@ -603,6 +603,13 @@ Architecture-specific environment variables:
                Valid values are 5, 6, 7.
                The value can be followed by an option specifying how to implement floating point instructions.
                Valid options are ,softfloat (default for 5) and ,hardfloat (default for 6 and 7).
+       GOARM64
+               For GOARCH=arm64, the ARM64 architecture for which to compile.
+               Valid values are v8.0 (default), v8.{1-9}, v9.{0-5}.
+               The value can be followed by an option specifying extensions implemented by target hardware.
+               Valid options are ,lse and ,crypto.
+               Note that some extensions are enabled by default starting from a certain GOARM64 version;
+               for example, lse is enabled by default starting from v8.1.
        GO386
                For GOARCH=386, how to implement floating point instructions.
                Valid values are sse2 (default), softfloat.
@@ -893,6 +900,8 @@ The defined architecture feature build tags are:
          correspond to the amd64.v1, amd64.v2, and amd64.v3 feature build tags.
        - For GOARCH=arm, GOARM=5, 6, and 7
          correspond to the arm.5, arm.6, and arm.7 feature build tags.
+       - For GOARCH=arm64, GOARM64=v8.{0-9} and v9.{0-5}
+         correspond to the arm64.v8.{0-9} and arm64.v9.{0-5} feature build tags.
        - For GOARCH=mips or mipsle,
          GOMIPS=hardfloat and softfloat
          correspond to the mips.hardfloat and mips.softfloat
index 61810f1348258ea3b2c6742eee20e5684037af7f..b074a36b941f7f6b7f80dba27dba3100d5fa0a22 100644 (file)
@@ -26,6 +26,7 @@ var (
        GO386     = envOr("GO386", defaultGO386)
        GOAMD64   = goamd64()
        GOARM     = goarm()
+       GOARM64   = goarm64()
        GOMIPS    = gomips()
        GOMIPS64  = gomips64()
        GOPPC64   = goppc64()
@@ -126,6 +127,106 @@ func goarm() (g goarmFeatures) {
        return
 }
 
+type goarm64Features struct {
+       Version string
+       // Large Systems Extension
+       LSE bool
+       // ARM v8.0 Cryptographic Extension. It includes the following features:
+       // * FEAT_AES, which includes the AESD and AESE instructions.
+       // * FEAT_PMULL, which includes the PMULL, PMULL2 instructions.
+       // * FEAT_SHA1, which includes the SHA1* instructions.
+       // * FEAT_SHA256, which includes the SHA256* instructions.
+       Crypto bool
+}
+
+func (g goarm64Features) String() string {
+       arm64Str := g.Version
+       if g.LSE {
+               arm64Str += ",lse"
+       }
+       if g.Crypto {
+               arm64Str += ",crypto"
+       }
+       return arm64Str
+}
+
+func parseGoarm64(v string) (g goarm64Features) {
+       const (
+               lseOpt    = ",lse"
+               cryptoOpt = ",crypto"
+       )
+
+       g.LSE = false
+       g.Crypto = false
+       // We allow any combination of suffixes, in any order
+       for {
+               if strings.HasSuffix(v, lseOpt) {
+                       g.LSE = true
+                       v = v[:len(v)-len(lseOpt)]
+                       continue
+               }
+
+               if strings.HasSuffix(v, cryptoOpt) {
+                       g.Crypto = true
+                       v = v[:len(v)-len(cryptoOpt)]
+                       continue
+               }
+
+               break
+       }
+
+       switch v {
+       case "v8.0":
+               g.Version = v
+       case "v8.1", "v8.2", "v8.3", "v8.4", "v8.5", "v8.6", "v8.7", "v8.8", "v8.9",
+               "v9.0", "v9.1", "v9.2", "v9.3", "v9.4", "v9.5":
+               g.Version = v
+               // LSE extension is mandatory starting from 8.1
+               g.LSE = true
+       default:
+               Error = fmt.Errorf("invalid GOARM64: must start with v8.{0-9} or v9.{0-5} and may optionally end in %q and/or %q",
+                       lseOpt, cryptoOpt)
+               g.Version = defaultGOARM64
+       }
+
+       return
+}
+
+func goarm64() goarm64Features {
+       return parseGoarm64(envOr("GOARM64", defaultGOARM64))
+}
+
+// Returns true if g supports giving ARM64 ISA
+// Note that this function doesn't accept / test suffixes (like ",lse" or ",crypto")
+func (g goarm64Features) Supports(s string) bool {
+       // We only accept "v{8-9}.{0-9}. Everything else is malformed.
+       if len(s) != 4 {
+               return false
+       }
+
+       major := s[1]
+       minor := s[3]
+
+       // We only accept "v{8-9}.{0-9}. Everything else is malformed.
+       if major < '8' || major > '9' ||
+               minor < '0' || minor > '9' ||
+               s[0] != 'v' || s[2] != '.' {
+               return false
+       }
+
+       g_major := g.Version[1]
+       g_minor := g.Version[3]
+
+       if major == g_major {
+               return minor <= g_minor
+       } else if g_major == '9' {
+               // v9.0 diverged from v8.5. This means we should compare with g_minor increased by five.
+               return minor <= g_minor+5
+       } else {
+               return false
+       }
+}
+
 func gomips() string {
        switch v := envOr("GOMIPS", defaultGOMIPS); v {
        case "hardfloat", "softfloat":
@@ -238,6 +339,8 @@ func GOGOARCH() (name, value string) {
                return "GOAMD64", fmt.Sprintf("v%d", GOAMD64)
        case "arm":
                return "GOARM", GOARM.String()
+       case "arm64":
+               return "GOARM64", GOARM64.String()
        case "mips", "mipsle":
                return "GOMIPS", GOMIPS
        case "mips64", "mips64le":
@@ -266,6 +369,20 @@ func gogoarchTags() []string {
                        list = append(list, fmt.Sprintf("%s.%d", GOARCH, i))
                }
                return list
+       case "arm64":
+               var list []string
+               major := int(GOARM64.Version[1] - '0')
+               minor := int(GOARM64.Version[3] - '0')
+               for i := 0; i <= minor; i++ {
+                       list = append(list, fmt.Sprintf("%s.v%d.%d", GOARCH, major, i))
+               }
+               // ARM64 v9.x also includes support of v8.x+5 (i.e. v9.1 includes v8.(1+5) = v8.6).
+               if major == 9 {
+                       for i := 0; i <= minor+5 && i <= 9; i++ {
+                               list = append(list, fmt.Sprintf("%s.v%d.%d", GOARCH, 8, i))
+                       }
+               }
+               return list
        case "mips", "mipsle":
                return []string{GOARCH + "." + GOMIPS}
        case "mips64", "mips64le":
index 69eeef24221523b41706dfc0c0751ce3763773f1..33a9c5e1b8c434f57b099381148a596db689aeb0 100644 (file)
@@ -37,4 +37,89 @@ func TestConfigFlags(t *testing.T) {
        if _ = goriscv64(); Error == nil {
                t.Errorf("Wrong parsing of RISCV64=rva22")
        }
+       Error = nil
+       os.Setenv("GOARM64", "v7.0")
+       if _ = goarm64(); Error == nil {
+               t.Errorf("Wrong parsing of GOARM64=7.0")
+       }
+       Error = nil
+       os.Setenv("GOARM64", "8.0")
+       if _ = goarm64(); Error == nil {
+               t.Errorf("Wrong parsing of GOARM64=8.0")
+       }
+       Error = nil
+       os.Setenv("GOARM64", "v8.0,lsb")
+       if _ = goarm64(); Error == nil {
+               t.Errorf("Wrong parsing of GOARM64=v8.0,lsb")
+       }
+       os.Setenv("GOARM64", "v8.0,lse")
+       if goarm64().Version != "v8.0" || goarm64().LSE != true || goarm64().Crypto != false {
+               t.Errorf("Wrong parsing of GOARM64=v8.0,lse")
+       }
+       os.Setenv("GOARM64", "v8.0,crypto")
+       if goarm64().Version != "v8.0" || goarm64().LSE != false || goarm64().Crypto != true {
+               t.Errorf("Wrong parsing of GOARM64=v8.0,crypto")
+       }
+       os.Setenv("GOARM64", "v8.0,crypto,lse")
+       if goarm64().Version != "v8.0" || goarm64().LSE != true || goarm64().Crypto != true {
+               t.Errorf("Wrong parsing of GOARM64=v8.0,crypto,lse")
+       }
+       os.Setenv("GOARM64", "v8.0,lse,crypto")
+       if goarm64().Version != "v8.0" || goarm64().LSE != true || goarm64().Crypto != true {
+               t.Errorf("Wrong parsing of GOARM64=v8.0,lse,crypto")
+       }
+       os.Setenv("GOARM64", "v9.0")
+       if goarm64().Version != "v9.0" || goarm64().LSE != true || goarm64().Crypto != false {
+               t.Errorf("Wrong parsing of GOARM64=v9.0")
+       }
+}
+
+func TestGoarm64FeaturesSupports(t *testing.T) {
+       g := parseGoarm64("v9.3")
+
+       if !g.Supports("v9.3") {
+               t.Errorf("Wrong goarm64Features.Supports for v9.3, v9.3")
+       }
+
+       if g.Supports("v9.4") {
+               t.Errorf("Wrong goarm64Features.Supports for v9.3, v9.4")
+       }
+
+       if !g.Supports("v8.8") {
+               t.Errorf("Wrong goarm64Features.Supports for v9.3, v8.8")
+       }
+
+       if g.Supports("v8.9") {
+               t.Errorf("Wrong goarm64Features.Supports for v9.3, v8.9")
+       }
+
+       if g.Supports(",lse") {
+               t.Errorf("Wrong goarm64Features.Supports for v9.3, ,lse")
+       }
+}
+
+func TestGogoarchTags(t *testing.T) {
+       old_goarch := GOARCH
+       old_goarm64 := GOARM64
+
+       GOARCH = "arm64"
+
+       os.Setenv("GOARM64", "v9.5")
+       GOARM64 = goarm64()
+       tags := gogoarchTags()
+       want := []string{"arm64.v9.0", "arm64.v9.1", "arm64.v9.2", "arm64.v9.3", "arm64.v9.4", "arm64.v9.5",
+               "arm64.v8.0", "arm64.v8.1", "arm64.v8.2", "arm64.v8.3", "arm64.v8.4", "arm64.v8.5", "arm64.v8.6", "arm64.v8.7", "arm64.v8.8", "arm64.v8.9"}
+       if len(tags) != len(want) {
+               t.Errorf("Wrong number of tags for GOARM64=v9.5")
+       } else {
+               for i, v := range tags {
+                       if v != want[i] {
+                               t.Error("Wrong tags for GOARM64=v9.5")
+                               break
+                       }
+               }
+       }
+
+       GOARCH = old_goarch
+       GOARM64 = old_goarm64
 }
index a9c99c4b966de1f465ecc7d5150d2e2b95920a4b..08d210b797385b26ef4a652ec8b17bdf99768b3e 100644 (file)
@@ -36,6 +36,7 @@ const KnownEnv = `
        GOAMD64
        GOARCH
        GOARM
+       GOARM64
        GOBIN
        GOCACHE
        GOCACHEPROG