Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

No Support for Apple M1 Pro in 0.0.4 #13

Closed
aaronmassicotte opened this issue Nov 28, 2022 · 5 comments
Closed

No Support for Apple M1 Pro in 0.0.4 #13

aaronmassicotte opened this issue Nov 28, 2022 · 5 comments

Comments

@aaronmassicotte
Copy link

cpu-features.js

const features = require('cpu-features')();
console.log(features)

node cpu-features.js
{ arch: 'unknown', flags: {} }

sysctl -n machdep.cpu.brand_string
Apple M1 Pro

@aaronmassicotte aaronmassicotte changed the title No Support for Apple M1 Pro No Support for Apple M1 Pro in 0.0.4 Nov 28, 2022
@mscdex
Copy link
Owner

mscdex commented Nov 28, 2022

That's expected, cpu_features does not support it yet. This PR looks like the best bet as far as adding support goes, so you might keep tabs on that and/or voice your support there.

@Brooooooklyn
Copy link

@mscdex
Copy link
Owner

mscdex commented Aug 16, 2023

@aaronmassicotte Since I don't have access to Apple Silicon hardware, if you're up to it, could you try applying this patch and let me know if it works for you?:

Patch
diff --git a/deps/cpu_features/CMakeLists.txt b/deps/cpu_features/CMakeLists.txt
index bcc9bb0..7a4f641 100644
--- a/deps/cpu_features/CMakeLists.txt
+++ b/deps/cpu_features/CMakeLists.txt
@@ -1,4 +1,4 @@
-cmake_minimum_required(VERSION 3.0)
+cmake_minimum_required(VERSION 3.19.2)
 
 # option() honors normal variables.
 # see: https://cmake.org/cmake/help/git-stage/policy/CMP0077.html
@@ -147,7 +147,7 @@ target_link_libraries(cpu_features PUBLIC ${CMAKE_DL_LIBS})
 target_include_directories(cpu_features
   PUBLIC $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/cpu_features>
 )
-if(PROCESSOR_IS_X86)
+if(PROCESSOR_IS_X86 OR PROCESSOR_IS_AARCH64)
   if(APPLE)
     target_compile_definitions(cpu_features PRIVATE HAVE_SYSCTLBYNAME)
   endif()
diff --git a/deps/cpu_features/cpu_features.gyp b/deps/cpu_features/cpu_features.gyp
index cd0b011..2846738 100644
--- a/deps/cpu_features/cpu_features.gyp
+++ b/deps/cpu_features/cpu_features.gyp
@@ -16,6 +16,7 @@
 
         # platform-specific cpu checking implementations
         'src/impl_aarch64_linux_or_android.c',
+        'src/impl_aarch64_macos_or_iphone.c',
         'src/impl_arm_linux_or_android.c',
         'src/impl_mips_linux_or_android.c',
         'src/impl_ppc_linux.c',
@@ -73,7 +74,7 @@
           ],
         }],
 
-        ['OS=="mac" and target_arch in "ia32 x32 x64"', {
+        ['OS=="mac" and target_arch in "ia32 x32 x64 arm64"', {
           'defines': [
             'HAVE_SYSCTLBYNAME=1',
           ],
diff --git a/deps/cpu_features/include/cpu_features_macros.h b/deps/cpu_features/include/cpu_features_macros.h
index 215b567..652335d 100644
--- a/deps/cpu_features/include/cpu_features_macros.h
+++ b/deps/cpu_features/include/cpu_features_macros.h
@@ -39,7 +39,7 @@
 #define CPU_FEATURES_ARCH_ARM
 #endif
 
-#if (defined(__aarch64__) || defined(_M_ARM64))
+#if (defined(__aarch64__)  || defined(__arm64__) || defined(_M_ARM64))
 #define CPU_FEATURES_ARCH_AARCH64
 #endif
 
diff --git a/deps/cpu_features/src/impl_aarch64__base_implementation.inl b/deps/cpu_features/src/impl_aarch64__base_implementation.inl
new file mode 100644
index 0000000..9677a6f
--- /dev/null
+++ b/deps/cpu_features/src/impl_aarch64__base_implementation.inl
@@ -0,0 +1,88 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include <stdbool.h>
+
+#include "cpuinfo_aarch64.h"
+#include "internal/bit_utils.h"
+#include "internal/filesystem.h"
+#include "internal/stack_line_reader.h"
+#include "internal/string_view.h"
+
+#if !defined(CPU_FEATURES_ARCH_AARCH64)
+#error "Cannot compile aarch64_base on a non aarch64 platform."
+#endif
+
+////////////////////////////////////////////////////////////////////////////////
+// Definitions for introspection.
+////////////////////////////////////////////////////////////////////////////////
+#define INTROSPECTION_TABLE                                                \
+  LINE(AARCH64_FP, fp, "fp", AARCH64_HWCAP_FP, 0)                          \
+  LINE(AARCH64_ASIMD, asimd, "asimd", AARCH64_HWCAP_ASIMD, 0)              \
+  LINE(AARCH64_EVTSTRM, evtstrm, "evtstrm", AARCH64_HWCAP_EVTSTRM, 0)      \
+  LINE(AARCH64_AES, aes, "aes", AARCH64_HWCAP_AES, 0)                      \
+  LINE(AARCH64_PMULL, pmull, "pmull", AARCH64_HWCAP_PMULL, 0)              \
+  LINE(AARCH64_SHA1, sha1, "sha1", AARCH64_HWCAP_SHA1, 0)                  \
+  LINE(AARCH64_SHA2, sha2, "sha2", AARCH64_HWCAP_SHA2, 0)                  \
+  LINE(AARCH64_CRC32, crc32, "crc32", AARCH64_HWCAP_CRC32, 0)              \
+  LINE(AARCH64_ATOMICS, atomics, "atomics", AARCH64_HWCAP_ATOMICS, 0)      \
+  LINE(AARCH64_FPHP, fphp, "fphp", AARCH64_HWCAP_FPHP, 0)                  \
+  LINE(AARCH64_ASIMDHP, asimdhp, "asimdhp", AARCH64_HWCAP_ASIMDHP, 0)      \
+  LINE(AARCH64_CPUID, cpuid, "cpuid", AARCH64_HWCAP_CPUID, 0)              \
+  LINE(AARCH64_ASIMDRDM, asimdrdm, "asimdrdm", AARCH64_HWCAP_ASIMDRDM, 0)  \
+  LINE(AARCH64_JSCVT, jscvt, "jscvt", AARCH64_HWCAP_JSCVT, 0)              \
+  LINE(AARCH64_FCMA, fcma, "fcma", AARCH64_HWCAP_FCMA, 0)                  \
+  LINE(AARCH64_LRCPC, lrcpc, "lrcpc", AARCH64_HWCAP_LRCPC, 0)              \
+  LINE(AARCH64_DCPOP, dcpop, "dcpop", AARCH64_HWCAP_DCPOP, 0)              \
+  LINE(AARCH64_SHA3, sha3, "sha3", AARCH64_HWCAP_SHA3, 0)                  \
+  LINE(AARCH64_SM3, sm3, "sm3", AARCH64_HWCAP_SM3, 0)                      \
+  LINE(AARCH64_SM4, sm4, "sm4", AARCH64_HWCAP_SM4, 0)                      \
+  LINE(AARCH64_ASIMDDP, asimddp, "asimddp", AARCH64_HWCAP_ASIMDDP, 0)      \
+  LINE(AARCH64_SHA512, sha512, "sha512", AARCH64_HWCAP_SHA512, 0)          \
+  LINE(AARCH64_SVE, sve, "sve", AARCH64_HWCAP_SVE, 0)                      \
+  LINE(AARCH64_ASIMDFHM, asimdfhm, "asimdfhm", AARCH64_HWCAP_ASIMDFHM, 0)  \
+  LINE(AARCH64_DIT, dit, "dit", AARCH64_HWCAP_DIT, 0)                      \
+  LINE(AARCH64_USCAT, uscat, "uscat", AARCH64_HWCAP_USCAT, 0)              \
+  LINE(AARCH64_ILRCPC, ilrcpc, "ilrcpc", AARCH64_HWCAP_ILRCPC, 0)          \
+  LINE(AARCH64_FLAGM, flagm, "flagm", AARCH64_HWCAP_FLAGM, 0)              \
+  LINE(AARCH64_SSBS, ssbs, "ssbs", AARCH64_HWCAP_SSBS, 0)                  \
+  LINE(AARCH64_SB, sb, "sb", AARCH64_HWCAP_SB, 0)                          \
+  LINE(AARCH64_PACA, paca, "paca", AARCH64_HWCAP_PACA, 0)                  \
+  LINE(AARCH64_PACG, pacg, "pacg", AARCH64_HWCAP_PACG, 0)                  \
+  LINE(AARCH64_DCPODP, dcpodp, "dcpodp", 0, AARCH64_HWCAP2_DCPODP)         \
+  LINE(AARCH64_SVE2, sve2, "sve2", 0, AARCH64_HWCAP2_SVE2)                 \
+  LINE(AARCH64_SVEAES, sveaes, "sveaes", 0, AARCH64_HWCAP2_SVEAES)         \
+  LINE(AARCH64_SVEPMULL, svepmull, "svepmull", 0, AARCH64_HWCAP2_SVEPMULL) \
+  LINE(AARCH64_SVEBITPERM, svebitperm, "svebitperm", 0,                    \
+       AARCH64_HWCAP2_SVEBITPERM)                                          \
+  LINE(AARCH64_SVESHA3, svesha3, "svesha3", 0, AARCH64_HWCAP2_SVESHA3)     \
+  LINE(AARCH64_SVESM4, svesm4, "svesm4", 0, AARCH64_HWCAP2_SVESM4)         \
+  LINE(AARCH64_FLAGM2, flagm2, "flagm2", 0, AARCH64_HWCAP2_FLAGM2)         \
+  LINE(AARCH64_FRINT, frint, "frint", 0, AARCH64_HWCAP2_FRINT)             \
+  LINE(AARCH64_SVEI8MM, svei8mm, "svei8mm", 0, AARCH64_HWCAP2_SVEI8MM)     \
+  LINE(AARCH64_SVEF32MM, svef32mm, "svef32mm", 0, AARCH64_HWCAP2_SVEF32MM) \
+  LINE(AARCH64_SVEF64MM, svef64mm, "svef64mm", 0, AARCH64_HWCAP2_SVEF64MM) \
+  LINE(AARCH64_SVEBF16, svebf16, "svebf16", 0, AARCH64_HWCAP2_SVEBF16)     \
+  LINE(AARCH64_I8MM, i8mm, "i8mm", 0, AARCH64_HWCAP2_I8MM)                 \
+  LINE(AARCH64_BF16, bf16, "bf16", 0, AARCH64_HWCAP2_BF16)                 \
+  LINE(AARCH64_DGH, dgh, "dgh", 0, AARCH64_HWCAP2_DGH)                     \
+  LINE(AARCH64_RNG, rng, "rng", 0, AARCH64_HWCAP2_RNG)                     \
+  LINE(AARCH64_BTI, bti, "bti", 0, AARCH64_HWCAP2_BTI)                     \
+  LINE(AARCH64_MTE, mte, "mte", 0, AARCH64_HWCAP2_MTE)                     \
+  LINE(AARCH64_ECV, ecv, "ecv", 0, AARCH64_HWCAP2_ECV)                     \
+  LINE(AARCH64_AFP, afp, "afp", 0, AARCH64_HWCAP2_AFP)                     \
+  LINE(AARCH64_RPRES, rpres, "rpres", 0, AARCH64_HWCAP2_RPRES)
+#define INTROSPECTION_PREFIX Aarch64
+#define INTROSPECTION_ENUM_PREFIX AARCH64
+#include "define_introspection_and_hwcaps.inl"
diff --git a/deps/cpu_features/src/impl_aarch64_linux_or_android.c b/deps/cpu_features/src/impl_aarch64_linux_or_android.c
index ef923d9..c0a764c 100644
--- a/deps/cpu_features/src/impl_aarch64_linux_or_android.c
+++ b/deps/cpu_features/src/impl_aarch64_linux_or_android.c
@@ -17,81 +17,7 @@
 #ifdef CPU_FEATURES_ARCH_AARCH64
 #if defined(CPU_FEATURES_OS_LINUX) || defined(CPU_FEATURES_OS_ANDROID)
 
-#include "cpuinfo_aarch64.h"
-
-////////////////////////////////////////////////////////////////////////////////
-// Definitions for introspection.
-////////////////////////////////////////////////////////////////////////////////
-#define INTROSPECTION_TABLE                                                \
-  LINE(AARCH64_FP, fp, "fp", AARCH64_HWCAP_FP, 0)                          \
-  LINE(AARCH64_ASIMD, asimd, "asimd", AARCH64_HWCAP_ASIMD, 0)              \
-  LINE(AARCH64_EVTSTRM, evtstrm, "evtstrm", AARCH64_HWCAP_EVTSTRM, 0)      \
-  LINE(AARCH64_AES, aes, "aes", AARCH64_HWCAP_AES, 0)                      \
-  LINE(AARCH64_PMULL, pmull, "pmull", AARCH64_HWCAP_PMULL, 0)              \
-  LINE(AARCH64_SHA1, sha1, "sha1", AARCH64_HWCAP_SHA1, 0)                  \
-  LINE(AARCH64_SHA2, sha2, "sha2", AARCH64_HWCAP_SHA2, 0)                  \
-  LINE(AARCH64_CRC32, crc32, "crc32", AARCH64_HWCAP_CRC32, 0)              \
-  LINE(AARCH64_ATOMICS, atomics, "atomics", AARCH64_HWCAP_ATOMICS, 0)      \
-  LINE(AARCH64_FPHP, fphp, "fphp", AARCH64_HWCAP_FPHP, 0)                  \
-  LINE(AARCH64_ASIMDHP, asimdhp, "asimdhp", AARCH64_HWCAP_ASIMDHP, 0)      \
-  LINE(AARCH64_CPUID, cpuid, "cpuid", AARCH64_HWCAP_CPUID, 0)              \
-  LINE(AARCH64_ASIMDRDM, asimdrdm, "asimdrdm", AARCH64_HWCAP_ASIMDRDM, 0)  \
-  LINE(AARCH64_JSCVT, jscvt, "jscvt", AARCH64_HWCAP_JSCVT, 0)              \
-  LINE(AARCH64_FCMA, fcma, "fcma", AARCH64_HWCAP_FCMA, 0)                  \
-  LINE(AARCH64_LRCPC, lrcpc, "lrcpc", AARCH64_HWCAP_LRCPC, 0)              \
-  LINE(AARCH64_DCPOP, dcpop, "dcpop", AARCH64_HWCAP_DCPOP, 0)              \
-  LINE(AARCH64_SHA3, sha3, "sha3", AARCH64_HWCAP_SHA3, 0)                  \
-  LINE(AARCH64_SM3, sm3, "sm3", AARCH64_HWCAP_SM3, 0)                      \
-  LINE(AARCH64_SM4, sm4, "sm4", AARCH64_HWCAP_SM4, 0)                      \
-  LINE(AARCH64_ASIMDDP, asimddp, "asimddp", AARCH64_HWCAP_ASIMDDP, 0)      \
-  LINE(AARCH64_SHA512, sha512, "sha512", AARCH64_HWCAP_SHA512, 0)          \
-  LINE(AARCH64_SVE, sve, "sve", AARCH64_HWCAP_SVE, 0)                      \
-  LINE(AARCH64_ASIMDFHM, asimdfhm, "asimdfhm", AARCH64_HWCAP_ASIMDFHM, 0)  \
-  LINE(AARCH64_DIT, dit, "dit", AARCH64_HWCAP_DIT, 0)                      \
-  LINE(AARCH64_USCAT, uscat, "uscat", AARCH64_HWCAP_USCAT, 0)              \
-  LINE(AARCH64_ILRCPC, ilrcpc, "ilrcpc", AARCH64_HWCAP_ILRCPC, 0)          \
-  LINE(AARCH64_FLAGM, flagm, "flagm", AARCH64_HWCAP_FLAGM, 0)              \
-  LINE(AARCH64_SSBS, ssbs, "ssbs", AARCH64_HWCAP_SSBS, 0)                  \
-  LINE(AARCH64_SB, sb, "sb", AARCH64_HWCAP_SB, 0)                          \
-  LINE(AARCH64_PACA, paca, "paca", AARCH64_HWCAP_PACA, 0)                  \
-  LINE(AARCH64_PACG, pacg, "pacg", AARCH64_HWCAP_PACG, 0)                  \
-  LINE(AARCH64_DCPODP, dcpodp, "dcpodp", 0, AARCH64_HWCAP2_DCPODP)         \
-  LINE(AARCH64_SVE2, sve2, "sve2", 0, AARCH64_HWCAP2_SVE2)                 \
-  LINE(AARCH64_SVEAES, sveaes, "sveaes", 0, AARCH64_HWCAP2_SVEAES)         \
-  LINE(AARCH64_SVEPMULL, svepmull, "svepmull", 0, AARCH64_HWCAP2_SVEPMULL) \
-  LINE(AARCH64_SVEBITPERM, svebitperm, "svebitperm", 0,                    \
-       AARCH64_HWCAP2_SVEBITPERM)                                          \
-  LINE(AARCH64_SVESHA3, svesha3, "svesha3", 0, AARCH64_HWCAP2_SVESHA3)     \
-  LINE(AARCH64_SVESM4, svesm4, "svesm4", 0, AARCH64_HWCAP2_SVESM4)         \
-  LINE(AARCH64_FLAGM2, flagm2, "flagm2", 0, AARCH64_HWCAP2_FLAGM2)         \
-  LINE(AARCH64_FRINT, frint, "frint", 0, AARCH64_HWCAP2_FRINT)             \
-  LINE(AARCH64_SVEI8MM, svei8mm, "svei8mm", 0, AARCH64_HWCAP2_SVEI8MM)     \
-  LINE(AARCH64_SVEF32MM, svef32mm, "svef32mm", 0, AARCH64_HWCAP2_SVEF32MM) \
-  LINE(AARCH64_SVEF64MM, svef64mm, "svef64mm", 0, AARCH64_HWCAP2_SVEF64MM) \
-  LINE(AARCH64_SVEBF16, svebf16, "svebf16", 0, AARCH64_HWCAP2_SVEBF16)     \
-  LINE(AARCH64_I8MM, i8mm, "i8mm", 0, AARCH64_HWCAP2_I8MM)                 \
-  LINE(AARCH64_BF16, bf16, "bf16", 0, AARCH64_HWCAP2_BF16)                 \
-  LINE(AARCH64_DGH, dgh, "dgh", 0, AARCH64_HWCAP2_DGH)                     \
-  LINE(AARCH64_RNG, rng, "rng", 0, AARCH64_HWCAP2_RNG)                     \
-  LINE(AARCH64_BTI, bti, "bti", 0, AARCH64_HWCAP2_BTI)                     \
-  LINE(AARCH64_MTE, mte, "mte", 0, AARCH64_HWCAP2_MTE)                     \
-  LINE(AARCH64_ECV, ecv, "ecv", 0, AARCH64_HWCAP2_ECV)                     \
-  LINE(AARCH64_AFP, afp, "afp", 0, AARCH64_HWCAP2_AFP)                     \
-  LINE(AARCH64_RPRES, rpres, "rpres", 0, AARCH64_HWCAP2_RPRES)
-#define INTROSPECTION_PREFIX Aarch64
-#define INTROSPECTION_ENUM_PREFIX AARCH64
-#include "define_introspection_and_hwcaps.inl"
-
-////////////////////////////////////////////////////////////////////////////////
-// Implementation.
-////////////////////////////////////////////////////////////////////////////////
-
-#include <stdbool.h>
-
-#include "internal/bit_utils.h"
-#include "internal/filesystem.h"
-#include "internal/stack_line_reader.h"
-#include "internal/string_view.h"
+#include "impl_aarch64__base_implementation.inl"
 
 static bool HandleAarch64Line(const LineResult result,
                               Aarch64Info* const info) {
diff --git a/deps/cpu_features/src/impl_aarch64_macos_or_iphone.c b/deps/cpu_features/src/impl_aarch64_macos_or_iphone.c
new file mode 100644
index 0000000..3ca4f3c
--- /dev/null
+++ b/deps/cpu_features/src/impl_aarch64_macos_or_iphone.c
@@ -0,0 +1,81 @@
+// Copyright 2021 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//    http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "cpu_features_macros.h"
+
+#ifdef CPU_FEATURES_ARCH_AARCH64
+#if defined(CPU_FEATURES_OS_MACOS) || defined(CPU_FEATURES_OS_IPHONE)
+
+#include "impl_aarch64__base_implementation.inl"
+
+#if !defined(HAVE_SYSCTLBYNAME)
+#error "Darwin needs support for sysctlbyname"
+#endif
+#include <sys/sysctl.h>
+
+#if defined(CPU_FEATURES_MOCK_SYSCTL_AARCH64)
+extern bool GetDarwinSysCtlByName(const char*);
+extern int GetDarwinSysCtlByNameValue(const char* name);
+#else
+static int GetDarwinSysCtlByNameValue(const char* name) {
+  int enabled;
+  size_t enabled_len = sizeof(enabled);
+  const int failure = sysctlbyname(name, &enabled, &enabled_len, NULL, 0);
+  return failure ? 0 : enabled;
+}
+
+static bool GetDarwinSysCtlByName(const char* name) {
+  return GetDarwinSysCtlByNameValue(name) != 0;
+}
+#endif
+
+static const Aarch64Info kEmptyAarch64Info;
+
+Aarch64Info GetAarch64Info(void) {
+  Aarch64Info info = kEmptyAarch64Info;
+
+  // Handling Darwin platform through sysctlbyname.
+  info.implementer = GetDarwinSysCtlByNameValue("hw.cputype");
+  info.variant = GetDarwinSysCtlByNameValue("hw.cpusubtype");
+  info.part = GetDarwinSysCtlByNameValue("hw.cpufamily");
+  info.revision = GetDarwinSysCtlByNameValue("hw.cpusubfamily");
+
+  info.features.fp = GetDarwinSysCtlByName("hw.optional.floatingpoint");
+  info.features.asimd = GetDarwinSysCtlByName("hw.optional.AdvSIMD");
+  info.features.aes = GetDarwinSysCtlByName("hw.optional.arm.FEAT_AES");
+  info.features.pmull = GetDarwinSysCtlByName("hw.optional.arm.FEAT_PMULL");
+  info.features.sha1 = GetDarwinSysCtlByName("hw.optional.arm.FEAT_SHA1");
+  info.features.sha2 = GetDarwinSysCtlByName("hw.optional.arm.FEAT_SHA2");
+  info.features.crc32 = GetDarwinSysCtlByName("hw.optional.armv8_crc32");
+  info.features.atomics = GetDarwinSysCtlByName("hw.optional.armv8_1_atomics");
+  info.features.fphp = GetDarwinSysCtlByName("hw.optional.neon_hpfp");
+  info.features.jscvt = GetDarwinSysCtlByName("hw.optional.arm.FEAT_JSCVT");
+  info.features.fcma = GetDarwinSysCtlByName("hw.optional.arm.FEAT_FCMA");
+  info.features.lrcpc = GetDarwinSysCtlByName("hw.optional.arm.FEAT_LRCPC");
+  info.features.sha3 = GetDarwinSysCtlByName("hw.optional.armv8_2_sha3");
+  info.features.sha512 = GetDarwinSysCtlByName("hw.optional.armv8_2_sha512");
+  info.features.asimdfhm = GetDarwinSysCtlByName("hw.optional.armv8_2_fhm");
+  info.features.flagm = GetDarwinSysCtlByName("hw.optional.arm.FEAT_FLAGM");
+  info.features.flagm2 = GetDarwinSysCtlByName("hw.optional.arm.FEAT_FLAGM2");
+  info.features.ssbs = GetDarwinSysCtlByName("hw.optional.arm.FEAT_SSBS");
+  info.features.sb = GetDarwinSysCtlByName("hw.optional.arm.FEAT_SB");
+  info.features.i8mm = GetDarwinSysCtlByName("hw.optional.arm.FEAT_I8MM");
+  info.features.bf16 = GetDarwinSysCtlByName("hw.optional.arm.FEAT_BF16");
+  info.features.bti = GetDarwinSysCtlByName("hw.optional.arm.FEAT_BTI");
+
+  return info;
+}
+
+#endif  // defined(CPU_FEATURES_OS_MACOS) || defined(CPU_FEATURES_OS_IPHONE)
+#endif  // CPU_FEATURES_ARCH_AARCH64
diff --git a/deps/cpu_features/test/CMakeLists.txt b/deps/cpu_features/test/CMakeLists.txt
index f627d74..80a0466 100644
--- a/deps/cpu_features/test/CMakeLists.txt
+++ b/deps/cpu_features/test/CMakeLists.txt
@@ -74,7 +74,12 @@ if(PROCESSOR_IS_AARCH64)
   add_executable(cpuinfo_aarch64_test
     cpuinfo_aarch64_test.cc
     ../src/impl_aarch64_linux_or_android.c
+    ../src/impl_aarch64_macos_or_iphone.c
     ../src/impl_aarch64_windows.c)
+  if(APPLE)
+    target_compile_definitions(cpuinfo_aarch64_test PUBLIC CPU_FEATURES_MOCK_SYSCTL_AARCH64)
+    target_compile_definitions(cpuinfo_aarch64_test PRIVATE HAVE_SYSCTLBYNAME)
+  endif()
   target_compile_definitions(cpuinfo_aarch64_test PUBLIC CPU_FEATURES_MOCK_CPUID_AARCH64)
   target_link_libraries(cpuinfo_aarch64_test all_libraries)
   add_test(NAME cpuinfo_aarch64_test COMMAND cpuinfo_aarch64_test)
diff --git a/deps/cpu_features/test/cpuinfo_aarch64_test.cc b/deps/cpu_features/test/cpuinfo_aarch64_test.cc
index ef9abae..b43d1aa 100644
--- a/deps/cpu_features/test/cpuinfo_aarch64_test.cc
+++ b/deps/cpu_features/test/cpuinfo_aarch64_test.cc
@@ -96,6 +96,125 @@ TEST(CpuinfoAarch64Test, Aarch64FeaturesEnum) {
 #if defined(CPU_FEATURES_OS_LINUX)
 void DisableHardwareCapabilities() { SetHardwareCapabilities(0, 0); }
 
+#if defined(CPU_FEATURES_OS_MACOS)
+
+class FakeCpu {
+ public:
+  bool GetDarwinSysCtlByName(std::string name) const {
+    return darwin_sysctlbyname_.count(name);
+  }
+
+  int GetDarwinSysCtlByNameValue(std::string name) const {
+    std::map<std::string, int>::const_iterator iter = darwin_sysctlbynamevalue_.find(name);
+    if (iter != std::end(darwin_sysctlbynamevalue_)) {
+      return iter->second;
+    }
+
+    return 0;
+  }
+
+  void SetDarwinSysCtlByName(std::string name) {
+    darwin_sysctlbyname_.insert(name);
+  }
+
+  void SetDarwinSysCtlByNameValue(std::string name, int value) {
+    darwin_sysctlbynamevalue_[name] = value;
+  }
+ private:
+  std::set<std::string> darwin_sysctlbyname_;
+  std::map<std::string, int> darwin_sysctlbynamevalue_;
+};
+
+static FakeCpu* g_fake_cpu_instance = nullptr;
+
+static FakeCpu& cpu() {
+  assert(g_fake_cpu_instance != nullptr);
+  return *g_fake_cpu_instance;
+}
+
+extern "C" bool GetDarwinSysCtlByName(const char* name) {
+  return cpu().GetDarwinSysCtlByName(name);
+}
+
+extern "C" int GetDarwinSysCtlByNameValue(const char *name) {
+  return cpu().GetDarwinSysCtlByNameValue(name);
+}
+
+class CpuinfoAarch64Test : public ::testing::Test {
+ protected:
+  void SetUp() override {
+    assert(g_fake_cpu_instance == nullptr);
+    g_fake_cpu_instance = new FakeCpu();
+  }
+  void TearDown() override {
+    delete g_fake_cpu_instance;
+    g_fake_cpu_instance = nullptr;
+  }
+};
+
+TEST_F(CpuinfoAarch64Test, FromDarwinSysctlFromName) {
+  cpu().SetDarwinSysCtlByName("hw.optional.floatingpoint");
+  cpu().SetDarwinSysCtlByName("hw.optional.neon");
+  cpu().SetDarwinSysCtlByName("hw.optional.neon_hpfp");
+  cpu().SetDarwinSysCtlByName("hw.optional.neon_fp16");
+  cpu().SetDarwinSysCtlByName("hw.optional.armv8_1_atomics");
+  cpu().SetDarwinSysCtlByName("hw.optional.armv8_crc32");
+  cpu().SetDarwinSysCtlByName("hw.optional.armv8_2_fhm");
+  cpu().SetDarwinSysCtlByName("hw.optional.armv8_2_sha512");
+  cpu().SetDarwinSysCtlByName("hw.optional.armv8_2_sha3");
+  cpu().SetDarwinSysCtlByName("hw.optional.amx_version");
+  cpu().SetDarwinSysCtlByName("hw.optional.ucnormal_mem");
+  cpu().SetDarwinSysCtlByName("hw.optional.arm64");
+
+  cpu().SetDarwinSysCtlByNameValue("hw.cputype", 16777228);
+  cpu().SetDarwinSysCtlByNameValue("hw.cpusubtype", 2);
+  cpu().SetDarwinSysCtlByNameValue("hw.cpu64bit", 1);
+  cpu().SetDarwinSysCtlByNameValue("hw.cpufamily", 458787763);
+  cpu().SetDarwinSysCtlByNameValue("hw.cpusubfamily", 2);
+
+  const auto info = GetAarch64Info();
+
+  EXPECT_EQ(info.implementer, 0x100000C);
+  EXPECT_EQ(info.variant, 2);
+  EXPECT_EQ(info.part, 0x1B588BB3);
+  EXPECT_EQ(info.revision, 2);
+
+  EXPECT_TRUE(info.features.fp);
+  EXPECT_FALSE(info.features.asimd);
+  EXPECT_FALSE(info.features.evtstrm);
+  EXPECT_FALSE(info.features.aes);
+  EXPECT_FALSE(info.features.pmull);
+  EXPECT_FALSE(info.features.sha1);
+  EXPECT_FALSE(info.features.sha2);
+  EXPECT_TRUE(info.features.crc32);
+  EXPECT_TRUE(info.features.atomics);
+  EXPECT_TRUE(info.features.fphp);
+  EXPECT_FALSE(info.features.asimdhp);
+  EXPECT_FALSE(info.features.cpuid);
+  EXPECT_FALSE(info.features.asimdrdm);
+  EXPECT_FALSE(info.features.jscvt);
+  EXPECT_FALSE(info.features.fcma);
+  EXPECT_FALSE(info.features.lrcpc);
+  EXPECT_FALSE(info.features.dcpop);
+  EXPECT_TRUE(info.features.sha3);
+  EXPECT_FALSE(info.features.sm3);
+  EXPECT_FALSE(info.features.sm4);
+  EXPECT_FALSE(info.features.asimddp);
+  EXPECT_TRUE(info.features.sha512);
+  EXPECT_FALSE(info.features.sve);
+  EXPECT_TRUE(info.features.asimdfhm);
+  EXPECT_FALSE(info.features.dit);
+  EXPECT_FALSE(info.features.uscat);
+  EXPECT_FALSE(info.features.ilrcpc);
+  EXPECT_FALSE(info.features.flagm);
+  EXPECT_FALSE(info.features.ssbs);
+  EXPECT_FALSE(info.features.sb);
+  EXPECT_FALSE(info.features.paca);
+  EXPECT_FALSE(info.features.pacg);
+}
+
+#else
+
 TEST(CpuinfoAarch64Test, FromHardwareCap) {
   ResetHwcaps();
   SetHardwareCapabilities(AARCH64_HWCAP_FP | AARCH64_HWCAP_AES, 0);
@@ -163,6 +282,7 @@ TEST(CpuinfoAarch64Test, FromHardwareCap2) {
   EXPECT_FALSE(info.features.dgh);
   EXPECT_FALSE(info.features.rng);
 }
+#endif  // CPU_FEATURES_OS_MACOS
 
 TEST(CpuinfoAarch64Test, ARMCortexA53) {
   ResetHwcaps();
diff --git a/src/binding.cc b/src/binding.cc
index 4d7bdbf..7905239 100644
--- a/src/binding.cc
+++ b/src/binding.cc
@@ -113,8 +113,7 @@ NAN_METHOD(GetCPUInfo) {
   SET_NUM("part", details.part);
   SET_NUM("revision", details.revision);
   SET_VAL("flags", GenerateFlags(&details.features));
-// M1 mac support is currently missing in cpu_features
-#elif defined(CPU_FEATURES_ARCH_AARCH64) && !defined(CPU_FEATURES_OS_MACOS)
+#elif defined(CPU_FEATURES_ARCH_AARCH64)
   const Aarch64Info details = GetAarch64Info();
   SET_STR("arch", "aarch64");
   SET_NUM("implementer", details.implementer);

@aaronmassicotte
Copy link
Author

I've applied the patch and this is the output:

{
  arch: 'aarch64',
  implementer: 16777228,
  variant: 2,
  part: 458787763,
  revision: 4,
  flags: {
    fp: true,
    asimd: true,
    aes: true,
    pmull: true,
    sha1: true,
    crc32: true,
    atomics: true,
    fphp: true,
    jscvt: true,
    fcma: true,
    lrcpc: true,
    sha3: true,
    sha512: true,
    asimdfhm: true,
    ssbs: true,
    sb: true
  }
}

I am used to seeing arm64 as the name, but otherwise LGTM

@mscdex
Copy link
Owner

mscdex commented Aug 17, 2023

Thanks for the feedback, I've added and applied the unofficial patch for now. I'm still hoping upstream will merge it at some point, but until then ...

@mscdex mscdex closed this as completed Aug 17, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants