Skip to content

Commit 7a07d3a

Browse files
authored
Enable feature detection for arm64 (#44)
* Enable feature detection for arm64
1 parent c17dbe9 commit 7a07d3a

5 files changed

Lines changed: 437 additions & 3 deletions

File tree

cpuid.go

Lines changed: 175 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
// Package cpuid provides information about the CPU running the current program.
44
//
55
// CPU features are detected on startup, and kept for fast access through the life of the application.
6-
// Currently x86 / x64 (AMD64) is supported.
6+
// Currently x86 / x64 (AMD64) as well as arm64 is supported.
77
//
88
// You can access the CPU information by accessing the shared CPU variable of the cpuid library.
99
//
@@ -175,12 +175,69 @@ var flagNames = map[Flags]string{
175175

176176
}
177177

178+
/* all special features for arm64 should be defined here */
179+
const (
180+
/* extension instructions */
181+
CPU_ARM64_FEATURE_FP = 1 << iota
182+
CPU_ARM64_FEATURE_ASIMD
183+
CPU_ARM64_FEATURE_EVTSTRM
184+
CPU_ARM64_FEATURE_AES
185+
CPU_ARM64_FEATURE_PMULL
186+
CPU_ARM64_FEATURE_SHA1
187+
CPU_ARM64_FEATURE_SHA2
188+
CPU_ARM64_FEATURE_CRC32
189+
CPU_ARM64_FEATURE_ATOMICS
190+
CPU_ARM64_FEATURE_FPHP
191+
CPU_ARM64_FEATURE_ASIMDHP
192+
CPU_ARM64_FEATURE_CPUID
193+
CPU_ARM64_FEATURE_ASIMDRDM
194+
CPU_ARM64_FEATURE_JSCVT
195+
CPU_ARM64_FEATURE_FCMA
196+
CPU_ARM64_FEATURE_LRCPC
197+
CPU_ARM64_FEATURE_DCPOP
198+
CPU_ARM64_FEATURE_SHA3
199+
CPU_ARM64_FEATURE_SM3
200+
CPU_ARM64_FEATURE_SM4
201+
CPU_ARM64_FEATURE_ASIMDDP
202+
CPU_ARM64_FEATURE_SHA512
203+
CPU_ARM64_FEATURE_SVE
204+
CPU_ARM64_FEATURE_GPA
205+
)
206+
207+
var flagNames_Arm64 = map[Flags]string{
208+
CPU_ARM64_FEATURE_FP: "FP", // Single-precision and double-precision floating point
209+
CPU_ARM64_FEATURE_ASIMD: "ASIMD", // Advanced SIMD
210+
CPU_ARM64_FEATURE_EVTSTRM: "EVTSTRM", // Generic timer
211+
CPU_ARM64_FEATURE_AES: "AES", // AES instructions
212+
CPU_ARM64_FEATURE_PMULL: "PMULL", // Polynomial Multiply instructions (PMULL/PMULL2)
213+
CPU_ARM64_FEATURE_SHA1: "SHA1", // SHA-1 instructions (SHA1C, etc)
214+
CPU_ARM64_FEATURE_SHA2: "SHA2", // SHA-2 instructions (SHA256H, etc)
215+
CPU_ARM64_FEATURE_CRC32: "CRC32", // CRC32/CRC32C instructions
216+
CPU_ARM64_FEATURE_ATOMICS: "ATOMICS", // Large System Extensions (LSE)
217+
CPU_ARM64_FEATURE_FPHP: "FPHP", // Half-precision floating point
218+
CPU_ARM64_FEATURE_ASIMDHP: "ASIMDHP", // Advanced SIMD half-precision floating point
219+
CPU_ARM64_FEATURE_CPUID: "CPUID", // Some CPU ID registers readable at user-level
220+
CPU_ARM64_FEATURE_ASIMDRDM: "ASIMDRDM", // Rounding Double Multiply Accumulate/Subtract (SQRDMLAH/SQRDMLSH)
221+
CPU_ARM64_FEATURE_JSCVT: "JSCVT", // Javascript-style double->int convert (FJCVTZS)
222+
CPU_ARM64_FEATURE_FCMA: "FCMA", // Floatin point complex number addition and multiplication
223+
CPU_ARM64_FEATURE_LRCPC: "LRCPC", // Weaker release consistency (LDAPR, etc)
224+
CPU_ARM64_FEATURE_DCPOP: "DCPOP", // Data cache clean to Point of Persistence (DC CVAP)
225+
CPU_ARM64_FEATURE_SHA3: "SHA3", // SHA-3 instructions (EOR3, RAXI, XAR, BCAX)
226+
CPU_ARM64_FEATURE_SM3: "SM3", // SM3 instructions
227+
CPU_ARM64_FEATURE_SM4: "SM4", // SM4 instructions
228+
CPU_ARM64_FEATURE_ASIMDDP: "ASIMDDP", // SIMD Dot Product
229+
CPU_ARM64_FEATURE_SHA512: "SHA512", // SHA512 instructions
230+
CPU_ARM64_FEATURE_SVE: "SVE", // Scalable Vector Extension
231+
CPU_ARM64_FEATURE_GPA: "GPA", // Generic Pointer Authentication
232+
}
233+
178234
// CPUInfo contains information about the detected system CPU.
179235
type CPUInfo struct {
180236
BrandName string // Brand name reported by the CPU
181237
VendorID Vendor // Comparable CPU vendor ID
182238
VendorString string // Raw vendor string.
183-
Features Flags // Features of the CPU
239+
Features Flags // Features of the CPU (x64)
240+
Arm64Features Flags // Features of the CPU (arm64)
184241
PhysicalCores int // Number of physical processor cores in your CPU. Will be 0 if undetectable.
185242
ThreadsPerCore int // Number of threads per physical core. Will be 1 if undetectable.
186243
LogicalCores int // Number of physical cores times threads that can run on each core through the use of hyperthreading. Will be 0 if undetectable.
@@ -230,6 +287,7 @@ func Detect() {
230287
CPU.CacheLine = cacheLine()
231288
CPU.Family, CPU.Model = familyModel()
232289
CPU.Features = support()
290+
CPU.Arm64Features = supportArm64()
233291
CPU.SGX = hasSGX(CPU.Features&SGX != 0, CPU.Features&SGXLC != 0)
234292
CPU.ThreadsPerCore = threadsPerCore()
235293
CPU.LogicalCores = logicalCores()
@@ -1317,3 +1375,118 @@ func valAsString(values ...uint32) []byte {
13171375
}
13181376
return r
13191377
}
1378+
1379+
// Single-precision and double-precision floating point
1380+
func (c CPUInfo) Arm64_FP() bool {
1381+
return c.Arm64Features&CPU_ARM64_FEATURE_FP != 0
1382+
}
1383+
1384+
// Advanced SIMD
1385+
func (c CPUInfo) Arm64_ASIMD() bool {
1386+
return c.Arm64Features&CPU_ARM64_FEATURE_ASIMD != 0
1387+
}
1388+
1389+
// Generic timer
1390+
func (c CPUInfo) Arm64_EVTSTRM() bool {
1391+
return c.Arm64Features&CPU_ARM64_FEATURE_EVTSTRM != 0
1392+
}
1393+
1394+
// AES instructions
1395+
func (c CPUInfo) Arm64_AES() bool {
1396+
return c.Arm64Features&CPU_ARM64_FEATURE_AES != 0
1397+
}
1398+
1399+
// Polynomial Multiply instructions (PMULL/PMULL2)
1400+
func (c CPUInfo) Arm64_PMULL() bool {
1401+
return c.Arm64Features&CPU_ARM64_FEATURE_PMULL != 0
1402+
}
1403+
1404+
// SHA-1 instructions (SHA1C, etc)
1405+
func (c CPUInfo) Arm64_SHA1() bool {
1406+
return c.Arm64Features&CPU_ARM64_FEATURE_SHA1 != 0
1407+
}
1408+
1409+
// SHA-2 instructions (SHA256H, etc)
1410+
func (c CPUInfo) Arm64_SHA2() bool {
1411+
return c.Arm64Features&CPU_ARM64_FEATURE_SHA2 != 0
1412+
}
1413+
1414+
// CRC32/CRC32C instructions
1415+
func (c CPUInfo) Arm64_CRC32() bool {
1416+
return c.Arm64Features&CPU_ARM64_FEATURE_CRC32 != 0
1417+
}
1418+
1419+
// Large System Extensions (LSE)
1420+
func (c CPUInfo) Arm64_ATOMICS() bool {
1421+
return c.Arm64Features&CPU_ARM64_FEATURE_ATOMICS != 0
1422+
}
1423+
1424+
// Half-precision floating point
1425+
func (c CPUInfo) Arm64_FPHP() bool {
1426+
return c.Arm64Features&CPU_ARM64_FEATURE_FPHP != 0
1427+
}
1428+
1429+
// Advanced SIMD half-precision floating point
1430+
func (c CPUInfo) Arm64_ASIMDHP() bool {
1431+
return c.Arm64Features&CPU_ARM64_FEATURE_ASIMDHP != 0
1432+
}
1433+
1434+
// Rounding Double Multiply Accumulate/Subtract (SQRDMLAH/SQRDMLSH)
1435+
func (c CPUInfo) Arm64_ASIMDRDM() bool {
1436+
return c.Arm64Features&CPU_ARM64_FEATURE_ASIMDRDM != 0
1437+
}
1438+
1439+
// Javascript-style double->int convert (FJCVTZS)
1440+
func (c CPUInfo) Arm64_JSCVT() bool {
1441+
return c.Arm64Features&CPU_ARM64_FEATURE_JSCVT != 0
1442+
}
1443+
1444+
// Floatin point complex number addition and multiplication
1445+
func (c CPUInfo) Arm64_FCMA() bool {
1446+
return c.Arm64Features&CPU_ARM64_FEATURE_FCMA != 0
1447+
}
1448+
1449+
// Weaker release consistency (LDAPR, etc)
1450+
func (c CPUInfo) Arm64_LRCPC() bool {
1451+
return c.Arm64Features&CPU_ARM64_FEATURE_LRCPC != 0
1452+
}
1453+
1454+
// Data cache clean to Point of Persistence (DC CVAP)
1455+
func (c CPUInfo) Arm64_DCPOP() bool {
1456+
return c.Arm64Features&CPU_ARM64_FEATURE_DCPOP != 0
1457+
}
1458+
1459+
// SHA-3 instructions (EOR3, RAXI, XAR, BCAX)
1460+
func (c CPUInfo) Arm64_SHA3() bool {
1461+
return c.Arm64Features&CPU_ARM64_FEATURE_SHA3 != 0
1462+
}
1463+
1464+
// SM3 instructions
1465+
func (c CPUInfo) Arm64_SM3() bool {
1466+
return c.Arm64Features&CPU_ARM64_FEATURE_SM3 != 0
1467+
}
1468+
1469+
// SM4 instructions
1470+
func (c CPUInfo) Arm64_SM4() bool {
1471+
return c.Arm64Features&CPU_ARM64_FEATURE_SM4 != 0
1472+
}
1473+
1474+
// SIMD Dot Product
1475+
func (c CPUInfo) Arm64_ASIMDDP() bool {
1476+
return c.Arm64Features&CPU_ARM64_FEATURE_ASIMDDP != 0
1477+
}
1478+
1479+
// SHA512 instructions
1480+
func (c CPUInfo) Arm64_SHA512() bool {
1481+
return c.Arm64Features&CPU_ARM64_FEATURE_SHA512 != 0
1482+
}
1483+
1484+
// Scalable Vector Extension
1485+
func (c CPUInfo) Arm64_SVE() bool {
1486+
return c.Arm64Features&CPU_ARM64_FEATURE_SVE != 0
1487+
}
1488+
1489+
// Generic Pointer Authentication
1490+
func (c CPUInfo) Arm64_GPA() bool {
1491+
return c.Arm64Features&CPU_ARM64_FEATURE_GPA != 0
1492+
}

cpuid_arm64.s

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// Copyright (c) 2015 Klaus Post, released under MIT License. See LICENSE file.
2+
3+
//+build arm64,!gccgo
4+
5+
// See https://www.kernel.org/doc/Documentation/arm64/cpu-feature-registers.txt
6+
7+
// func getMidr
8+
TEXT ·getMidr(SB), 7, $0
9+
WORD $0xd5380000 // mrs x0, midr_el1 /* Main ID Register */
10+
MOVD R0, midr+0(FP)
11+
RET
12+
13+
// func getProcFeatures
14+
TEXT ·getProcFeatures(SB), 7, $0
15+
WORD $0xd5380400 // mrs x0, id_aa64pfr0_el1 /* Processor Feature Register 0 */
16+
MOVD R0, procFeatures+0(FP)
17+
RET
18+
19+
// func getInstAttributes
20+
TEXT ·getInstAttributes(SB), 7, $0
21+
WORD $0xd5380600 // mrs x0, id_aa64isar0_el1 /* Instruction Set Attribute Register 0 */
22+
WORD $0xd5380621 // mrs x1, id_aa64isar1_el1 /* Instruction Set Attribute Register 1 */
23+
MOVD R0, instAttrReg0+0(FP)
24+
MOVD R1, instAttrReg1+8(FP)
25+
RET
26+

0 commit comments

Comments
 (0)