1
0
mirror of https://github.com/golang/go synced 2024-09-29 07:14:29 -06: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:
Andrey Bokhanko 2024-01-30 19:18:24 +03:00 committed by M Zhuo
parent 9e3b1d53a0
commit e8b5bc63be
7 changed files with 233 additions and 0 deletions

11
src/cmd/dist/build.go vendored
View 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)
}

View 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)

View File

@ -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.

View 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

View 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":

View 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
}

View File

@ -36,6 +36,7 @@ const KnownEnv = `
GOAMD64
GOARCH
GOARM
GOARM64
GOBIN
GOCACHE
GOCACHEPROG