cpu: add Int8 matrix multiplication instructions CPU feature flag for ARM64

References:
https://github.com/torvalds/linux/blob/5bbd9b249880dba032bffa002dd9cd12cd5af09c/arch/arm64/include/uapi/asm/hwcap.h#L75C9-L75C31

https://developer.arm.com/documentation/ddi0601/2024-03/AArch64-Registers/ID-AA64ISAR1-EL1--AArch64-Instruction-Set-Attribute-Register-1

Change-Id: Ic4e1cf2c23097c7e8695453b6d0b335756d474bc
Reviewed-on: https://go-review.googlesource.com/c/sys/+/595678
Reviewed-by: Ian Lance Taylor <iant@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Auto-Submit: Ian Lance Taylor <iant@golang.org>
Reviewed-by: Cherry Mui <cherryyz@google.com>
diff --git a/cpu/cpu.go b/cpu/cpu.go
index 11a0abc..ec07aab 100644
--- a/cpu/cpu.go
+++ b/cpu/cpu.go
@@ -106,6 +106,7 @@
 	HasSVE2     bool // Scalable Vector Extensions 2
 	HasASIMDFHM bool // Advanced SIMD multiplication FP16 to FP32
 	HasDIT      bool // Data Independent Timing support
+	HasI8MM     bool // Advanced SIMD Int8 matrix multiplication instructions
 	_           CacheLinePad
 }
 
diff --git a/cpu/cpu_arm64.go b/cpu/cpu_arm64.go
index 8bde6f1..af2aa99 100644
--- a/cpu/cpu_arm64.go
+++ b/cpu/cpu_arm64.go
@@ -39,6 +39,7 @@
 		{Name: "asimddp", Feature: &ARM64.HasASIMDDP},
 		{Name: "asimdfhm", Feature: &ARM64.HasASIMDFHM},
 		{Name: "dit", Feature: &ARM64.HasDIT},
+		{Name: "i8mm", Feature: &ARM64.HasI8MM},
 	}
 }
 
@@ -146,6 +147,11 @@
 		ARM64.HasLRCPC = true
 	}
 
+	switch extractBits(isar1, 52, 55) {
+	case 1:
+		ARM64.HasI8MM = true
+	}
+
 	// ID_AA64PFR0_EL1
 	switch extractBits(pfr0, 16, 19) {
 	case 0:
diff --git a/cpu/cpu_linux_arm64.go b/cpu/cpu_linux_arm64.go
index bc61b19..08f35ea 100644
--- a/cpu/cpu_linux_arm64.go
+++ b/cpu/cpu_linux_arm64.go
@@ -38,6 +38,7 @@
 	hwcap_DIT      = 1 << 24
 
 	hwcap2_SVE2 = 1 << 1
+	hwcap2_I8MM = 1 << 13
 )
 
 // linuxKernelCanEmulateCPUID reports whether we're running
@@ -112,6 +113,7 @@
 
 	// HWCAP2 feature bits
 	ARM64.HasSVE2 = isSet(hwCap2, hwcap2_SVE2)
+	ARM64.HasI8MM = isSet(hwCap2, hwcap2_I8MM)
 }
 
 func isSet(hwc uint, value uint) bool {