gohostos string
goos string
goarm string
+ goarm64 string
go386 string
goamd64 string
gomips string
}
goarm = b
+ b = os.Getenv("GOARM64")
+ if b == "" {
+ b = "v8.0"
+ }
+ goarm64 = b
+
b = os.Getenv("GO386")
if b == "" {
b = "sse2"
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)
if goarch == "arm" {
xprintf(format, "GOARM", goarm)
}
+ if goarch == "arm64" {
+ xprintf(format, "GOARM64", goarm64)
+ }
if goarch == "386" {
xprintf(format, "GO386", go386)
}
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)
// 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.
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.
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
GO386 = envOr("GO386", defaultGO386)
GOAMD64 = goamd64()
GOARM = goarm()
+ GOARM64 = goarm64()
GOMIPS = gomips()
GOMIPS64 = gomips64()
GOPPC64 = goppc64()
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":
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":
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":
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
}
GOAMD64
GOARCH
GOARM
+ GOARM64
GOBIN
GOCACHE
GOCACHEPROG