Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .github/actions/ct-test/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,5 @@ runs:
- shell: ${{ env.SHELL }}
run: |
make clean
tests func --exec-wrapper="valgrind --error-exitcode=1 --track-origins=yes ${{ inputs.valgrind_flags }}" --cflags="-DMLK_CONFIG_CT_TESTING_ENABLED -DNTESTS=50 ${{ inputs.cflags }}"
# Disable the AArch64 SHA3 extension as it's not yet supported by valgrind
MK_COMPILER_SUPPORTS_SHA3=0 tests func --exec-wrapper="valgrind --error-exitcode=1 --track-origins=yes ${{ inputs.valgrind_flags }}" --cflags="-DMLK_CONFIG_CT_TESTING_ENABLED -DNTESTS=50 ${{ inputs.cflags }}"
38 changes: 37 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@
build test all \
clean quickcheck check-defined-CYCLES \
size_512 size_768 size_1024 size \
run_size_512 run_size_768 run_size_1024 run_size
run_size_512 run_size_768 run_size_1024 run_size \
host_info

SHELL := /bin/bash
.DEFAULT_GOAL := build
Expand All @@ -26,6 +27,8 @@ all: build
W := $(EXEC_WRAPPER)

include test/mk/config.mk
include test/mk/compiler.mk
include test/mk/auto.mk
include test/mk/components.mk
include test/mk/rules.mk

Expand Down Expand Up @@ -86,6 +89,15 @@ acvp_1024: $(MLKEM1024_DIR)/bin/acvp_mlkem1024
$(Q)echo " ACVP ML-KEM-1024: $^"
acvp: acvp_512 acvp_768 acvp_1024

ifeq ($(HOST_PLATFORM),Linux-aarch64)
# valgrind does not work with the AArch64 SHA3 extension
# Use armv8-a as the target architecture, overwriting a
# potential earlier addition of armv8.4-a+sha3.
$(MLKEM512_DIR)/bin/test_stack512: CFLAGS += -march=armv8-a
$(MLKEM768_DIR)/bin/test_stack768: CFLAGS += -march=armv8-a
$(MLKEM1024_DIR)/bin/test_stack1024: CFLAGS += -march=armv8-a
endif

stack_512: $(MLKEM512_DIR)/bin/test_stack512
$(Q)echo " STACK ML-KEM-512: $^"
stack_768: $(MLKEM768_DIR)/bin/test_stack768
Expand Down Expand Up @@ -176,6 +188,30 @@ run_size: \
run_size_768 \
run_size_1024

# Display host and compiler feature detection information
# Shows which architectural features are supported by both the compiler and host CPU
# Usage: make host_info [AUTO=0|1] [CROSS_PREFIX=...]
host_info:
@echo "=== Host and Compiler Feature Detection ==="
@echo "Host Platform: $(HOST_PLATFORM)"
@echo "Target Architecture: $(ARCH)"
@echo "Compiler: $(CC)"
@echo "Cross Prefix: $(if $(CROSS_PREFIX),$(CROSS_PREFIX),<none>)"
@echo "AUTO: $(AUTO)"
@echo ""
ifeq ($(ARCH),x86_64)
@echo "=== x86_64 Feature Support ==="
@echo "AVX2: Host $(if $(filter 1,$(MK_HOST_SUPPORTS_AVX2)),✅,❌) Compiler $(if $(filter 1,$(MK_COMPILER_SUPPORTS_AVX2)),✅,❌)"
@echo "SSE2: Host $(if $(filter 1,$(MK_HOST_SUPPORTS_SSE2)),✅,❌) Compiler $(if $(filter 1,$(MK_COMPILER_SUPPORTS_SSE2)),✅,❌)"
@echo "BMI2: Host $(if $(filter 1,$(MK_HOST_SUPPORTS_BMI2)),✅,❌) Compiler $(if $(filter 1,$(MK_COMPILER_SUPPORTS_BMI2)),✅,❌)"
else ifeq ($(ARCH),aarch64)
@echo "=== AArch64 Feature Support ==="
@echo "SHA3: Host $(if $(filter 1,$(MK_HOST_SUPPORTS_SHA3)),✅,❌) Compiler $(if $(filter 1,$(MK_COMPILER_SUPPORTS_SHA3)),✅,❌)"
else
@echo "=== Architecture Not Supported ==="
@echo "No specific feature detection available for $(ARCH)"
endif

clean:
-$(RM) -rf *.gcno *.gcda *.lcov *.o *.so
-$(RM) -rf $(BUILD_DIR)
Expand Down
4 changes: 2 additions & 2 deletions examples/monolithic_build_multilevel_native/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ endif
# Native compilation
ifeq ($(CROSS_PREFIX),)
ifeq ($(HOST_PLATFORM),Linux-x86_64)
CFLAGS += -mavx2 -mbmi2 -mpopcnt -maes
CFLAGS += -mavx2 -mbmi2
CFLAGS += -DMLK_FORCE_X86_64
else ifeq ($(HOST_PLATFORM),Linux-aarch64)
CFLAGS += -DMLK_FORCE_AARCH64
Expand All @@ -70,7 +70,7 @@ else ifeq ($(HOST_PLATFORM),Darwin-arm64)
endif
# Cross compilation
else ifneq ($(findstring x86_64, $(CROSS_PREFIX)),)
CFLAGS += -mavx2 -mbmi2 -mpopcnt -maes
CFLAGS += -mavx2 -mbmi2
CFLAGS += -DMLK_FORCE_X86_64
else ifneq ($(findstring aarch64_be, $(CROSS_PREFIX)),)
CFLAGS += -DMLK_FORCE_AARCH64_EB
Expand Down
4 changes: 2 additions & 2 deletions examples/multilevel_build_native/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ endif
# Native compilation
ifeq ($(CROSS_PREFIX),)
ifeq ($(HOST_PLATFORM),Linux-x86_64)
CFLAGS += -mavx2 -mbmi2 -mpopcnt -maes
CFLAGS += -mavx2 -mbmi2
CFLAGS += -DMLK_FORCE_X86_64
else ifeq ($(HOST_PLATFORM),Linux-aarch64)
CFLAGS += -DMLK_FORCE_AARCH64
Expand All @@ -37,7 +37,7 @@ else ifeq ($(HOST_PLATFORM),Darwin-arm64)
endif
# Cross compilation
else ifneq ($(findstring x86_64, $(CROSS_PREFIX)),)
CFLAGS += -mavx2 -mbmi2 -mpopcnt -maes
CFLAGS += -mavx2 -mbmi2
CFLAGS += -DMLK_FORCE_X86_64
else ifneq ($(findstring aarch64_be, $(CROSS_PREFIX)),)
CFLAGS += -DMLK_FORCE_AARCH64_EB
Expand Down
128 changes: 106 additions & 22 deletions test/mk/auto.mk
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
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
65 changes: 65 additions & 0 deletions test/mk/compiler.mk
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

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
4 changes: 0 additions & 4 deletions test/mk/config.mk
Original file line number Diff line number Diff line change
Expand Up @@ -81,10 +81,6 @@ CYCLES ?=
OPT ?= 1
RETAINED_VARS := CROSS_PREFIX CYCLES OPT AUTO

ifeq ($(AUTO),1)
include test/mk/auto.mk
endif

BUILD_DIR ?= test/build

MAKE_OBJS = $(2:%=$(1)/%.o)
Expand Down
Loading