summaryrefslogtreecommitdiff
path: root/cmake/utils
diff options
context:
space:
mode:
authorDimitri Staessens <dimitri@ouroboros.rocks>2026-04-25 22:21:49 +0200
committerSander Vrijders <sander@ouroboros.rocks>2026-05-06 09:04:22 +0200
commit77fdc9f1d162b2307d7752d56930710858f702b4 (patch)
treede70a08d6da1c0d5f14a4693c0872843b4625717 /cmake/utils
parentdd978895f5bbf6b595813d1288d90f825fd402ec (diff)
downloadouroboros-77fdc9f1d162b2307d7752d56930710858f702b4.tar.gz
ouroboros-77fdc9f1d162b2307d7752d56930710858f702b4.zip
cmake: Add CPU feature detection helper
Add cmake/utils/CPUUtils.cmake providing detect_cpu_feature() plus detect_pclmul() and detect_pmull() that compile-test for x86 PCLMULQDQ+SSE4.1 and aarch64 FEAT_PMULL respectively. This will be useful for hardware accelerated CRC64/NVMe integrity checks. Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks> Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
Diffstat (limited to 'cmake/utils')
-rw-r--r--cmake/utils/CPUUtils.cmake54
1 files changed, 54 insertions, 0 deletions
diff --git a/cmake/utils/CPUUtils.cmake b/cmake/utils/CPUUtils.cmake
new file mode 100644
index 00000000..e158792a
--- /dev/null
+++ b/cmake/utils/CPUUtils.cmake
@@ -0,0 +1,54 @@
+include(CheckCSourceCompiles)
+
+# Detect a CPU feature by attempting to compile a small program with
+# the matching compiler flag.
+function(detect_cpu_feature _result_var _flags _source)
+ set(_save_flags "${CMAKE_REQUIRED_FLAGS}")
+ set(_save_quiet "${CMAKE_REQUIRED_QUIET}")
+ set(CMAKE_REQUIRED_FLAGS "${_save_flags} ${_flags}")
+ set(CMAKE_REQUIRED_QUIET TRUE)
+ check_c_source_compiles("${_source}" ${_result_var})
+ set(CMAKE_REQUIRED_FLAGS "${_save_flags}")
+ set(CMAKE_REQUIRED_QUIET "${_save_quiet}")
+endfunction()
+
+# x86 PCLMULQDQ (carry-less multiply) + SSE4.1. Sets HAVE_PCLMUL only
+# when both intrinsic groups compile.
+function(detect_pclmul)
+ detect_cpu_feature(_HAVE_PCLMUL "-mpclmul"
+"#include <wmmintrin.h>
+int main(void) {
+ __m128i a = _mm_setzero_si128();
+ __m128i b = _mm_clmulepi64_si128(a, a, 0);
+ return (int) _mm_cvtsi128_si32(b);
+}")
+ detect_cpu_feature(_HAVE_SSE41 "-msse4.1"
+"#include <smmintrin.h>
+int main(void) {
+ __m128i a = _mm_setzero_si128();
+ return _mm_extract_epi32(a, 0);
+}")
+ if(_HAVE_PCLMUL AND _HAVE_SSE41)
+ set(HAVE_PCLMUL TRUE CACHE INTERNAL
+ "x86 PCLMUL + SSE4.1 intrinsics available")
+ else()
+ unset(HAVE_PCLMUL CACHE)
+ endif()
+endfunction()
+
+# aarch64 FEAT_PMULL (vmull_p64 / vmull_high_p64) carry-less multiply.
+function(detect_pmull)
+ detect_cpu_feature(_HAVE_PMULL "-march=armv8-a+crypto"
+"#include <arm_neon.h>
+int main(void) {
+ poly64_t a = (poly64_t) 0;
+ poly128_t c = vmull_p64(a, a);
+ return (int) vgetq_lane_u64((uint64x2_t) c, 0);
+}")
+ if(_HAVE_PMULL)
+ set(HAVE_PMULL TRUE CACHE INTERNAL
+ "aarch64 PMULL intrinsics available")
+ else()
+ unset(HAVE_PMULL CACHE)
+ endif()
+endfunction()