mirror of
https://github.com/golang/go
synced 2024-11-24 13:10:11 -07:00
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>
This commit is contained in:
parent
9e3b1d53a0
commit
e8b5bc63be
11
src/cmd/dist/build.go
vendored
11
src/cmd/dist/build.go
vendored
@ -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)
|
||||
}
|
||||
|
1
src/cmd/dist/buildruntime.go
vendored
1
src/cmd/dist/buildruntime.go
vendored
@ -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)
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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":
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -36,6 +36,7 @@ const KnownEnv = `
|
||||
GOAMD64
|
||||
GOARCH
|
||||
GOARM
|
||||
GOARM64
|
||||
GOBIN
|
||||
GOCACHE
|
||||
GOCACHEPROG
|
||||
|
Loading…
Reference in New Issue
Block a user