summaryrefslogtreecommitdiff
path: root/vendor/github.com/tetratelabs/wazero/internal/platform/cpuid_arm64.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/tetratelabs/wazero/internal/platform/cpuid_arm64.go')
-rw-r--r--vendor/github.com/tetratelabs/wazero/internal/platform/cpuid_arm64.go71
1 files changed, 71 insertions, 0 deletions
diff --git a/vendor/github.com/tetratelabs/wazero/internal/platform/cpuid_arm64.go b/vendor/github.com/tetratelabs/wazero/internal/platform/cpuid_arm64.go
new file mode 100644
index 000000000..5430353fd
--- /dev/null
+++ b/vendor/github.com/tetratelabs/wazero/internal/platform/cpuid_arm64.go
@@ -0,0 +1,71 @@
+//go:build gc
+
+package platform
+
+import "runtime"
+
+// CpuFeatures exposes the capabilities for this CPU, queried via the Has, HasExtra methods.
+var CpuFeatures = loadCpuFeatureFlags()
+
+// cpuFeatureFlags implements CpuFeatureFlags interface.
+type cpuFeatureFlags struct {
+ isar0 uint64
+ isar1 uint64
+}
+
+// implemented in cpuid_arm64.s
+func getisar0() uint64
+
+// implemented in cpuid_arm64.s
+func getisar1() uint64
+
+func loadCpuFeatureFlags() CpuFeatureFlags {
+ switch runtime.GOOS {
+ case "darwin", "windows":
+ // These OSes do not allow userland to read the instruction set attribute registers,
+ // but basically require atomic instructions:
+ // - "darwin" is the desktop version (mobile version is "ios"),
+ // and the M1 is a ARMv8.4.
+ // - "windows" requires them from Windows 11, see page 12
+ // https://download.microsoft.com/download/7/8/8/788bf5ab-0751-4928-a22c-dffdc23c27f2/Minimum%20Hardware%20Requirements%20for%20Windows%2011.pdf
+ return &cpuFeatureFlags{
+ isar0: uint64(CpuFeatureArm64Atomic),
+ isar1: 0,
+ }
+ case "linux", "freebsd":
+ // These OSes allow userland to read the instruction set attribute registers,
+ // which is otherwise restricted to EL0:
+ // https://kernel.org/doc/Documentation/arm64/cpu-feature-registers.txt
+ // See these for contents of the registers:
+ // https://developer.arm.com/documentation/ddi0601/latest/AArch64-Registers/ID-AA64ISAR0-EL1--AArch64-Instruction-Set-Attribute-Register-0
+ // https://developer.arm.com/documentation/ddi0601/latest/AArch64-Registers/ID-AA64ISAR1-EL1--AArch64-Instruction-Set-Attribute-Register-1
+ return &cpuFeatureFlags{
+ isar0: getisar0(),
+ isar1: getisar1(),
+ }
+ default:
+ return &cpuFeatureFlags{}
+ }
+}
+
+// Has implements the same method on the CpuFeatureFlags interface.
+func (f *cpuFeatureFlags) Has(cpuFeature CpuFeature) bool {
+ return (f.isar0 & uint64(cpuFeature)) != 0
+}
+
+// HasExtra implements the same method on the CpuFeatureFlags interface.
+func (f *cpuFeatureFlags) HasExtra(cpuFeature CpuFeature) bool {
+ return (f.isar1 & uint64(cpuFeature)) != 0
+}
+
+// Raw implements the same method on the CpuFeatureFlags interface.
+func (f *cpuFeatureFlags) Raw() uint64 {
+ // Below, we only set bits for the features we care about,
+ // instead of setting all the unnecessary bits obtained from the
+ // instruction set attribute registers.
+ var ret uint64
+ if f.Has(CpuFeatureArm64Atomic) {
+ ret = 1 << 0
+ }
+ return ret
+}