|
26 | 26 | GO386 = envOr("GO386", defaultGO386)
|
27 | 27 | GOAMD64 = goamd64()
|
28 | 28 | GOARM = goarm()
|
| 29 | + GOARM64 = goarm64() |
29 | 30 | GOMIPS = gomips()
|
30 | 31 | GOMIPS64 = gomips64()
|
31 | 32 | GOPPC64 = goppc64()
|
@@ -126,6 +127,106 @@ func goarm() (g goarmFeatures) {
|
126 | 127 | return
|
127 | 128 | }
|
128 | 129 |
|
| 130 | +type goarm64Features struct { |
| 131 | + Version string |
| 132 | + // Large Systems Extension |
| 133 | + LSE bool |
| 134 | + // ARM v8.0 Cryptographic Extension. It includes the following features: |
| 135 | + // * FEAT_AES, which includes the AESD and AESE instructions. |
| 136 | + // * FEAT_PMULL, which includes the PMULL, PMULL2 instructions. |
| 137 | + // * FEAT_SHA1, which includes the SHA1* instructions. |
| 138 | + // * FEAT_SHA256, which includes the SHA256* instructions. |
| 139 | + Crypto bool |
| 140 | +} |
| 141 | + |
| 142 | +func (g goarm64Features) String() string { |
| 143 | + arm64Str := g.Version |
| 144 | + if g.LSE { |
| 145 | + arm64Str += ",lse" |
| 146 | + } |
| 147 | + if g.Crypto { |
| 148 | + arm64Str += ",crypto" |
| 149 | + } |
| 150 | + return arm64Str |
| 151 | +} |
| 152 | + |
| 153 | +func parseGoarm64(v string) (g goarm64Features) { |
| 154 | + const ( |
| 155 | + lseOpt = ",lse" |
| 156 | + cryptoOpt = ",crypto" |
| 157 | + ) |
| 158 | + |
| 159 | + g.LSE = false |
| 160 | + g.Crypto = false |
| 161 | + // We allow any combination of suffixes, in any order |
| 162 | + for { |
| 163 | + if strings.HasSuffix(v, lseOpt) { |
| 164 | + g.LSE = true |
| 165 | + v = v[:len(v)-len(lseOpt)] |
| 166 | + continue |
| 167 | + } |
| 168 | + |
| 169 | + if strings.HasSuffix(v, cryptoOpt) { |
| 170 | + g.Crypto = true |
| 171 | + v = v[:len(v)-len(cryptoOpt)] |
| 172 | + continue |
| 173 | + } |
| 174 | + |
| 175 | + break |
| 176 | + } |
| 177 | + |
| 178 | + switch v { |
| 179 | + case "v8.0": |
| 180 | + g.Version = v |
| 181 | + case "v8.1", "v8.2", "v8.3", "v8.4", "v8.5", "v8.6", "v8.7", "v8.8", "v8.9", |
| 182 | + "v9.0", "v9.1", "v9.2", "v9.3", "v9.4", "v9.5": |
| 183 | + g.Version = v |
| 184 | + // LSE extension is mandatory starting from 8.1 |
| 185 | + g.LSE = true |
| 186 | + default: |
| 187 | + Error = fmt.Errorf("invalid GOARM64: must start with v8.{0-9} or v9.{0-5} and may optionally end in %q and/or %q", |
| 188 | + lseOpt, cryptoOpt) |
| 189 | + g.Version = defaultGOARM64 |
| 190 | + } |
| 191 | + |
| 192 | + return |
| 193 | +} |
| 194 | + |
| 195 | +func goarm64() goarm64Features { |
| 196 | + return parseGoarm64(envOr("GOARM64", defaultGOARM64)) |
| 197 | +} |
| 198 | + |
| 199 | +// Returns true if g supports giving ARM64 ISA |
| 200 | +// Note that this function doesn't accept / test suffixes (like ",lse" or ",crypto") |
| 201 | +func (g goarm64Features) Supports(s string) bool { |
| 202 | + // We only accept "v{8-9}.{0-9}. Everything else is malformed. |
| 203 | + if len(s) != 4 { |
| 204 | + return false |
| 205 | + } |
| 206 | + |
| 207 | + major := s[1] |
| 208 | + minor := s[3] |
| 209 | + |
| 210 | + // We only accept "v{8-9}.{0-9}. Everything else is malformed. |
| 211 | + if major < '8' || major > '9' || |
| 212 | + minor < '0' || minor > '9' || |
| 213 | + s[0] != 'v' || s[2] != '.' { |
| 214 | + return false |
| 215 | + } |
| 216 | + |
| 217 | + g_major := g.Version[1] |
| 218 | + g_minor := g.Version[3] |
| 219 | + |
| 220 | + if major == g_major { |
| 221 | + return minor <= g_minor |
| 222 | + } else if g_major == '9' { |
| 223 | + // v9.0 diverged from v8.5. This means we should compare with g_minor increased by five. |
| 224 | + return minor <= g_minor+5 |
| 225 | + } else { |
| 226 | + return false |
| 227 | + } |
| 228 | +} |
| 229 | + |
129 | 230 | func gomips() string {
|
130 | 231 | switch v := envOr("GOMIPS", defaultGOMIPS); v {
|
131 | 232 | case "hardfloat", "softfloat":
|
@@ -238,6 +339,8 @@ func GOGOARCH() (name, value string) {
|
238 | 339 | return "GOAMD64", fmt.Sprintf("v%d", GOAMD64)
|
239 | 340 | case "arm":
|
240 | 341 | return "GOARM", GOARM.String()
|
| 342 | + case "arm64": |
| 343 | + return "GOARM64", GOARM64.String() |
241 | 344 | case "mips", "mipsle":
|
242 | 345 | return "GOMIPS", GOMIPS
|
243 | 346 | case "mips64", "mips64le":
|
@@ -266,6 +369,20 @@ func gogoarchTags() []string {
|
266 | 369 | list = append(list, fmt.Sprintf("%s.%d", GOARCH, i))
|
267 | 370 | }
|
268 | 371 | return list
|
| 372 | + case "arm64": |
| 373 | + var list []string |
| 374 | + major := int(GOARM64.Version[1] - '0') |
| 375 | + minor := int(GOARM64.Version[3] - '0') |
| 376 | + for i := 0; i <= minor; i++ { |
| 377 | + list = append(list, fmt.Sprintf("%s.v%d.%d", GOARCH, major, i)) |
| 378 | + } |
| 379 | + // ARM64 v9.x also includes support of v8.x+5 (i.e. v9.1 includes v8.(1+5) = v8.6). |
| 380 | + if major == 9 { |
| 381 | + for i := 0; i <= minor+5 && i <= 9; i++ { |
| 382 | + list = append(list, fmt.Sprintf("%s.v%d.%d", GOARCH, 8, i)) |
| 383 | + } |
| 384 | + } |
| 385 | + return list |
269 | 386 | case "mips", "mipsle":
|
270 | 387 | return []string{GOARCH + "." + GOMIPS}
|
271 | 388 | case "mips64", "mips64le":
|
|
0 commit comments