aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrey Bokhanko <andreybokhanko@gmail.com>2024-01-30 19:18:24 +0300
committerM Zhuo <mengzhuo1203@gmail.com>2024-03-06 01:33:19 +0000
commite8b5bc63be22e2bebffabcfccaf54d4c19822fe6 (patch)
treec065761b361bc9edfd074f93edee2c5f61cc70a2
parent9e3b1d53a012e98cfd02de2de8b1bd53522464d4 (diff)
downloadgo-e8b5bc63be22e2bebffabcfccaf54d4c19822fe6.tar.gz
go-e8b5bc63be22e2bebffabcfccaf54d4c19822fe6.zip
cmd/dist,internal: add GOARM64 environment variable
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>
-rw-r--r--src/cmd/dist/build.go11
-rw-r--r--src/cmd/dist/buildruntime.go1
-rw-r--r--src/cmd/go/alldocs.go9
-rw-r--r--src/cmd/go/internal/help/helpdoc.go9
-rw-r--r--src/internal/buildcfg/cfg.go117
-rw-r--r--src/internal/buildcfg/cfg_test.go85
-rw-r--r--src/internal/cfg/cfg.go1
7 files changed, 233 insertions, 0 deletions
diff --git a/src/cmd/dist/build.go b/src/cmd/dist/build.go
index d4d1bd8f0b..64f8f53054 100644
--- a/src/cmd/dist/build.go
+++ b/src/cmd/dist/build.go
@@ -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)
}
diff --git a/src/cmd/dist/buildruntime.go b/src/cmd/dist/buildruntime.go
index b041183bdf..7095f43772 100644
--- a/src/cmd/dist/buildruntime.go
+++ b/src/cmd/dist/buildruntime.go
@@ -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)
diff --git a/src/cmd/go/alldocs.go b/src/cmd/go/alldocs.go
index 153128e715..dde47ac1b8 100644
--- a/src/cmd/go/alldocs.go
+++ b/src/cmd/go/alldocs.go
@@ -1990,6 +1990,8 @@
// 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
@@ -2289,6 +2291,13 @@
// 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.
diff --git a/src/cmd/go/internal/help/helpdoc.go b/src/cmd/go/internal/help/helpdoc.go
index ddaca3807a..e1d719be4f 100644
--- a/src/cmd/go/internal/help/helpdoc.go
+++ b/src/cmd/go/internal/help/helpdoc.go
@@ -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
diff --git a/src/internal/buildcfg/cfg.go b/src/internal/buildcfg/cfg.go
index 61810f1348..b074a36b94 100644
--- a/src/internal/buildcfg/cfg.go
+++ b/src/internal/buildcfg/cfg.go
@@ -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":
diff --git a/src/internal/buildcfg/cfg_test.go b/src/internal/buildcfg/cfg_test.go
index 69eeef2422..33a9c5e1b8 100644
--- a/src/internal/buildcfg/cfg_test.go
+++ b/src/internal/buildcfg/cfg_test.go
@@ -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
}
diff --git a/src/internal/cfg/cfg.go b/src/internal/cfg/cfg.go
index a9c99c4b96..08d210b797 100644
--- a/src/internal/cfg/cfg.go
+++ b/src/internal/cfg/cfg.go
@@ -36,6 +36,7 @@ const KnownEnv = `
GOAMD64
GOARCH
GOARM
+ GOARM64
GOBIN
GOCACHE
GOCACHEPROG