-
Notifications
You must be signed in to change notification settings - Fork 37
Makefile: Add compile-time compiler+host platform feature detection #1146
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
Merged
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,29 +1,113 @@ | ||
# SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT | ||
# | ||
# Automatically detect system architecture and set preprocessor etc accordingly | ||
# Automatically detect system architecture and set preprocessor flags accordingly | ||
# This file detects host CPU capabilities and combines them with compiler support | ||
# to enable optimal compilation flags. | ||
|
||
# Native compilation | ||
ifeq ($(CROSS_PREFIX),) | ||
ifndef _AUTO_MK | ||
_AUTO_MK := | ||
|
||
# Helper function to check if host CPU supports a feature | ||
# Usage: $(call check_host_feature,feature_pattern,source_command) | ||
define check_host_feature | ||
$(shell $(2) 2>/dev/null | grep -q "$(1)" && echo 1 || echo 0) | ||
endef | ||
|
||
# x86_64 architecture detection | ||
ifeq ($(ARCH),x86_64) | ||
|
||
# Host CPU feature detection for x86_64 | ||
ifeq ($(HOST_PLATFORM),Linux-x86_64) | ||
CFLAGS += -mavx2 -mbmi2 -mpopcnt -maes | ||
CFLAGS += -DMLK_FORCE_X86_64 | ||
else ifeq ($(HOST_PLATFORM),Linux-aarch64) | ||
CFLAGS += -DMLK_FORCE_AARCH64 | ||
# Linux: Use /proc/cpuinfo | ||
MK_HOST_SUPPORTS_AVX2 := $(call check_host_feature,avx2,cat /proc/cpuinfo) | ||
MK_HOST_SUPPORTS_SSE2 := $(call check_host_feature,sse2,cat /proc/cpuinfo) | ||
MK_HOST_SUPPORTS_BMI2 := $(call check_host_feature,bmi2,cat /proc/cpuinfo) | ||
else ifeq ($(HOST_PLATFORM),Darwin-x86_64) | ||
# macOS: Use sysctl | ||
MK_HOST_SUPPORTS_AVX2 := $(call check_host_feature,AVX2,sysctl -n machdep.cpu.leaf7_features) | ||
MK_HOST_SUPPORTS_SSE2 := $(call check_host_feature,SSE2,sysctl -n machdep.cpu.features) | ||
MK_HOST_SUPPORTS_BMI2 := $(call check_host_feature,BMI2,sysctl -n machdep.cpu.leaf7_features) | ||
else ifneq ($(CROSS_PREFIX),) | ||
# Cross-compilation: assume all features are supported | ||
MK_HOST_SUPPORTS_AVX2 := 1 | ||
MK_HOST_SUPPORTS_SSE2 := 1 | ||
MK_HOST_SUPPORTS_BMI2 := 1 | ||
else | ||
# Other platforms: assume no support | ||
MK_HOST_SUPPORTS_AVX2 := 0 | ||
MK_HOST_SUPPORTS_SSE2 := 0 | ||
MK_HOST_SUPPORTS_BMI2 := 0 | ||
endif # HOST_PLATFORM x86_64 | ||
|
||
endif # x86_64 | ||
|
||
# AArch64 architecture detection | ||
ifeq ($(ARCH),aarch64) | ||
|
||
# Host CPU feature detection for AArch64 | ||
ifeq ($(HOST_PLATFORM),Linux-aarch64) | ||
# Linux: Use /proc/cpuinfo (look for sha3 in Features line) | ||
MK_HOST_SUPPORTS_SHA3 := $(call check_host_feature,sha3,cat /proc/cpuinfo) | ||
else ifeq ($(HOST_PLATFORM),Darwin-arm64) | ||
CFLAGS += -DMLK_FORCE_AARCH64 | ||
# macOS: Use sysctl to check for SHA3 support | ||
MK_HOST_SUPPORTS_SHA3 := $(call check_host_feature,1,sysctl -n hw.optional.armv8_2_sha3) | ||
else ifneq ($(CROSS_PREFIX),) | ||
# Cross-compilation: assume all features are supported | ||
MK_HOST_SUPPORTS_SHA3 := 1 | ||
else | ||
# Other platforms: assume no support | ||
MK_HOST_SUPPORTS_SHA3 := 0 | ||
endif # HOST_PLATFORM aarch64 | ||
|
||
endif # aarch64 | ||
|
||
# Only apply CFLAGS modifications if AUTO=1 | ||
ifeq ($(AUTO),1) | ||
|
||
# x86_64 CFLAGS configuration | ||
ifeq ($(ARCH),x86_64) | ||
CFLAGS += -DMLK_FORCE_X86_64 | ||
|
||
# Add flags only if both compiler and host support the feature | ||
ifeq ($(MK_COMPILER_SUPPORTS_AVX2)$(MK_HOST_SUPPORTS_AVX2),11) | ||
CFLAGS += -mavx2 | ||
endif | ||
# Cross compilation | ||
else ifneq ($(findstring x86_64, $(CROSS_PREFIX)),) | ||
CFLAGS += -mavx2 -mbmi2 -mpopcnt -maes | ||
CFLAGS += -DMLK_FORCE_X86_64 | ||
else ifneq ($(findstring aarch64_be, $(CROSS_PREFIX)),) | ||
CFLAGS += -DMLK_FORCE_AARCH64_EB | ||
else ifneq ($(findstring aarch64, $(CROSS_PREFIX)),) | ||
CFLAGS += -DMLK_FORCE_AARCH64 | ||
else ifneq ($(findstring riscv64, $(CROSS_PREFIX)),) | ||
CFLAGS += -DMLK_FORCE_RISCV64 | ||
else ifneq ($(findstring riscv32, $(CROSS_PREFIX)),) | ||
CFLAGS += -DMLK_FORCE_RISCV32 | ||
else ifneq ($(findstring powerpc64le, $(CROSS_PREFIX)),) | ||
CFLAGS += -DMLK_FORCE_PPC64LE | ||
|
||
ifeq ($(MK_COMPILER_SUPPORTS_BMI2)$(MK_HOST_SUPPORTS_BMI2),11) | ||
CFLAGS += -mbmi2 | ||
endif | ||
endif # x86_64 | ||
|
||
# AArch64 CFLAGS configuration | ||
ifeq ($(ARCH),aarch64) | ||
CFLAGS += -DMLK_FORCE_AARCH64 | ||
|
||
# Add SHA3 flags only if both compiler and host support it | ||
ifeq ($(MK_COMPILER_SUPPORTS_SHA3)$(MK_HOST_SUPPORTS_SHA3),11) | ||
CFLAGS += -march=armv8.4-a+sha3 | ||
mkannwischer marked this conversation as resolved.
Show resolved
Hide resolved
|
||
endif | ||
endif # aarch64 | ||
|
||
# AArch64 Big Endian CFLAGS configuration | ||
ifeq ($(ARCH),aarch64_be) | ||
CFLAGS += -DMLK_FORCE_AARCH64_EB | ||
endif # aarch64_be | ||
|
||
# RISC-V 64-bit CFLAGS configuration | ||
ifeq ($(ARCH),riscv64) | ||
CFLAGS += -DMLK_FORCE_RISCV64 | ||
endif # riscv64 | ||
|
||
# RISC-V 32-bit CFLAGS configuration | ||
ifeq ($(ARCH),riscv32) | ||
CFLAGS += -DMLK_FORCE_RISCV32 | ||
endif # riscv32 | ||
|
||
# PowerPC 64-bit Little Endian CFLAGS configuration | ||
ifeq ($(ARCH),powerpc64le) | ||
CFLAGS += -DMLK_FORCE_PPC64LE | ||
endif # powerpc64le | ||
|
||
endif # AUTO=1 | ||
|
||
endif # _AUTO_MK |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
# SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT | ||
# | ||
# Compiler feature detection for mlkem-native | ||
# This file detects whether the compiler supports various architectural features | ||
# used by mlkem-native through compile-time tests with C code containing inline assembly. | ||
# | ||
# Feature detection can be overridden by setting the corresponding variable on the command line: | ||
# make MK_COMPILER_SUPPORTS_SHA3=0 # Disable SHA3 detection | ||
# make MK_COMPILER_SUPPORTS_AVX2=0 # Disable AVX2 detection | ||
# make MK_COMPILER_SUPPORTS_BMI2=0 # Disable BMI2 detection | ||
# make MK_COMPILER_SUPPORTS_SSE2=0 # Disable SSE2 detection | ||
mkannwischer marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
ifndef _COMPILER_MK | ||
_COMPILER_MK := | ||
|
||
# Normalize architecture names | ||
ARCH := $(shell uname -m) | ||
ifeq ($(ARCH),arm64) | ||
ARCH := aarch64 | ||
endif | ||
|
||
# Override ARCH for cross-compilation based on CROSS_PREFIX | ||
ifneq ($(CROSS_PREFIX),) | ||
ifneq ($(findstring x86_64, $(CROSS_PREFIX)),) | ||
ARCH := x86_64 | ||
else ifneq ($(findstring aarch64_be, $(CROSS_PREFIX)),) | ||
ARCH := aarch64_be | ||
else ifneq ($(findstring aarch64, $(CROSS_PREFIX)),) | ||
ARCH := aarch64 | ||
else ifneq ($(findstring riscv64, $(CROSS_PREFIX)),) | ||
ARCH := riscv64 | ||
else ifneq ($(findstring riscv32, $(CROSS_PREFIX)),) | ||
ARCH := riscv32 | ||
else ifneq ($(findstring powerpc64le, $(CROSS_PREFIX)),) | ||
ARCH := powerpc64le | ||
endif | ||
endif # CROSS_PREFIX | ||
|
||
# x86_64 feature detection | ||
ifeq ($(ARCH),x86_64) | ||
|
||
# Test AVX2 support using C with inline assembly | ||
# Can be overridden by setting MK_COMPILER_SUPPORTS_AVX2=0/1 on command line | ||
MK_COMPILER_SUPPORTS_AVX2 ?= $(shell echo 'int main() { __asm__("vpxor %%ymm0, %%ymm1, %%ymm2" ::: "ymm0", "ymm1", "ymm2"); return 0; }' | $(CC) -mavx2 -x c - -c -o /dev/null 2>/dev/null && echo 1 || echo 0) | ||
|
||
# Test SSE2 support using C with inline assembly | ||
# Can be overridden by setting MK_COMPILER_SUPPORTS_SSE2=0/1 on command line | ||
MK_COMPILER_SUPPORTS_SSE2 ?= $(shell echo 'int main() { __asm__("pxor %%xmm0, %%xmm1" ::: "xmm0", "xmm1"); return 0; }' | $(CC) -msse2 -x c - -c -o /dev/null 2>/dev/null && echo 1 || echo 0) | ||
|
||
# Test BMI2 support using C with inline assembly | ||
# Can be overridden by setting MK_COMPILER_SUPPORTS_BMI2=0/1 on command line | ||
MK_COMPILER_SUPPORTS_BMI2 ?= $(shell echo 'int main() { __asm__("pdep %%eax, %%ebx, %%ecx" ::: "eax", "ebx", "ecx"); return 0; }' | $(CC) -mbmi2 -x c - -c -o /dev/null 2>/dev/null && echo 1 || echo 0) | ||
|
||
endif # x86_64 | ||
|
||
# AArch64 feature detection | ||
ifeq ($(ARCH),aarch64) | ||
|
||
# Test SHA3 support (Armv8.4-a+SHA3) using C with inline assembly | ||
# Can be overridden by setting MK_COMPILER_SUPPORTS_SHA3=0/1 on command line | ||
MK_COMPILER_SUPPORTS_SHA3 ?= $(shell echo 'int main() { __asm__("eor3 v0.16b, v1.16b, v2.16b, v3.16b" ::: "v0", "v1", "v2", "v3"); return 0; }' | $(CC) -march=armv8.4-a+sha3 -x c - -c -o /dev/null 2>/dev/null && echo 1 || echo 0) | ||
|
||
endif # aarch64 | ||
|
||
endif # _COMPILER_MK |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.