From 0dd1ce3920076f78cf4c93939dd83d433b1a8620 Mon Sep 17 00:00:00 2001
From: Tim Kosse <tim.kosse@filezilla-project.org>
Date: Tue, 5 Dec 2023 21:19:16 +0100
Subject: [PATCH] CPU feature detection for Apple M1 devices.

---
 ChangeLog   |  5 +++++
 fat-arm64.c | 18 ++++++++++++++++++
 2 files changed, 23 insertions(+)

diff --git a/ChangeLog b/ChangeLog
index eb9e7006..c2cbf32e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,10 @@
 2023-12-05  Niels Möller  <nisse@lysator.liu.se>
 
+	From Tim Kosse:
+	* fat-arm64.c (check_sysctlbyname) [__APPLE__]: New function.
+	(get_arm64_features) [__APPLE__]: Fix feature detection for Apple
+	M1 devices.
+
 	* configure.ac: In openssl tests, check for the headers actually
 	used by the benchmarking code, and for a subset of the relevant
 	functions.
diff --git a/fat-arm64.c b/fat-arm64.c
index aec99f66..240302a6 100644
--- a/fat-arm64.c
+++ b/fat-arm64.c
@@ -50,6 +50,8 @@
 # include <sys/sysctl.h>
 # include <machine/cpu.h>
 # include <machine/armreg.h>
+#elif defined(__APPLE__)
+# include <sys/sysctl.h>
 #endif
 
 #include "nettle-types.h"
@@ -86,6 +88,16 @@ struct arm64_features
 #define MATCH(s, slen, literal, llen) \
   ((slen) == (llen) && memcmp ((s), (literal), llen) == 0)
 
+#if defined(__APPLE__)
+static int
+check_sysctlbyname(const char* name)
+{
+  int val;
+  size_t s = sizeof(val);
+  return sysctlbyname(name, &val, &s, NULL, 0) ? 0 : val;
+}
+#endif
+
 static void
 get_arm64_features (struct arm64_features *features)
 {
@@ -141,6 +153,12 @@ get_arm64_features (struct arm64_features *features)
         = (ID_AA64ISAR0_SHA1(isar0) >= ID_AA64ISAR0_SHA1_BASE);
       features->have_sha2
         = (ID_AA64ISAR0_SHA2(isar0) >= ID_AA64ISAR0_SHA2_BASE);
+#elif defined(__APPLE__)
+      /* See https://developer.apple.com/documentation/kernel/1387446-sysctlbyname/determining_instruction_set_characteristics */
+      features->have_aes = check_sysctlbyname("hw.optional.arm.FEAT_AES");
+      features->have_pmull = check_sysctlbyname("hw.optional.arm.FEAT_PMULL");
+      features->have_sha1 = check_sysctlbyname("hw.optional.arm.FEAT_SHA1");
+      features->have_sha2 = check_sysctlbyname("hw.optional.arm.FEAT_SHA256");
 #endif
     }
 }
-- 
GitLab