-
Notifications
You must be signed in to change notification settings - Fork 45
Expand file tree
/
Copy pathauto.mk
More file actions
209 lines (171 loc) · 7.04 KB
/
auto.mk
File metadata and controls
209 lines (171 loc) · 7.04 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
# Copyright (c) The mlkem-native project authors
# Copyright (c) The mldsa-native project authors
# SPDX-License-Identifier: Apache-2.0 OR ISC OR MIT
# 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.
#
# Compiler 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 _AUTO_MK
_AUTO_MK :=
# Override ARCH for cross-compilation based on CROSS_PREFIX
ifeq ($(CROSS_PREFIX),)
ARCH := $(shell uname -m)
# Normalize architecture names
ifeq ($(ARCH),arm64)
ARCH := aarch64
endif
else # 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
else ifneq ($(findstring arm-none-eabi-, $(CROSS_PREFIX)),)
ARCH := arm
else
ifeq ($(AUTO),1)
$(warning Unknown cross-compilation prefix $(CROSS_PREFIX), no automatic detection of CFLAGS.)
ARCH := unknown
endif
endif
endif # CROSS_PREFIX
# x86_64 compiler feature detection
ifeq ($(ARCH),x86_64)
# Test AVX2 support using C with inline assembly
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
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
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 compiler detection
# AArch64 compiler feature detection
ifeq ($(ARCH),aarch64)
# Test SHA3 support (Armv8.4-a+SHA3) using C with inline assembly
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 compiler detection
# RISC-V 64-bit compiler feature detection
ifeq ($(ARCH),riscv64)
# Test RVV support using C with inline assembly
MK_COMPILER_SUPPORTS_RVV ?= $(shell echo 'int main() { __asm__("vadd.vv v0, v1, v2"); return 0; }' | $(CC) -march=rv64gcv -x c - -c -o /dev/null 2>/dev/null && echo 1 || echo 0)
endif # riscv64 compiler detection
# Define HOST_PLATFORM if not already defined
HOST_PLATFORM ?= $(shell uname -s)-$(shell uname -m)
# 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)
# 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)
# 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
# RISC-V 64-bit architecture detection
ifeq ($(ARCH),riscv64)
# Host CPU feature detection for RISC-V 64-bit
ifeq ($(HOST_PLATFORM),Linux-riscv64)
# Linux: Parse ISA string from /proc/cpuinfo
# Format: rv64imafdcv_sscofpmf_... -- extract single-letter extensions
# (before first '_') and check for 'v'
MK_HOST_SUPPORTS_RVV := $(shell sed -n '/^isa/{s/.*rv64//;s/_.*//;p;q}' /proc/cpuinfo 2>/dev/null | grep -q v && echo 1 || echo 0)
else ifneq ($(CROSS_PREFIX),)
# Cross-compilation: assume all features are supported
MK_HOST_SUPPORTS_RVV := 1
else
# Other platforms: assume no support
MK_HOST_SUPPORTS_RVV := 0
endif # HOST_PLATFORM riscv64
endif # riscv64
# Only apply CFLAGS modifications if AUTO=1
ifeq ($(AUTO),1)
# x86_64 CFLAGS configuration
ifeq ($(ARCH),x86_64)
CFLAGS += -DMLD_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
ifeq ($(MK_COMPILER_SUPPORTS_BMI2)$(MK_HOST_SUPPORTS_BMI2),11)
CFLAGS += -mbmi2
endif
endif # x86_64
# AArch64 CFLAGS configuration
ifeq ($(ARCH),aarch64)
CFLAGS += -DMLD_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 += -DMLD_FORCE_AARCH64_EB
endif # aarch64_be
# RISC-V 64-bit CFLAGS configuration
ifeq ($(ARCH),riscv64)
CFLAGS += -DMLD_FORCE_RISCV64
# Add RVV flags only if both compiler and host support it
ifeq ($(MK_COMPILER_SUPPORTS_RVV)$(MK_HOST_SUPPORTS_RVV),11)
CFLAGS += -march=rv64gcv
endif
endif # riscv64
# RISC-V 32-bit CFLAGS configuration
ifeq ($(ARCH),riscv32)
CFLAGS += -DMLD_FORCE_RISCV32
endif # riscv32
# PowerPC 64-bit Little Endian CFLAGS configuration
ifeq ($(ARCH),powerpc64le)
CFLAGS += -DMLD_FORCE_PPC64LE
endif # powerpc64le
endif # AUTO=1
endif # _AUTO_MK