Skip to content

Commit f2f4e31

Browse files
committed
CMakeLists.txt: option ENABLE_NEON_SIMD, define NEON_INTRINSICS, compiler Arm level flags, aarch64 source code include, Ninja+cl workarounds
1 parent 52ad9cb commit f2f4e31

3 files changed

Lines changed: 123 additions & 11 deletions

File tree

CMakeLists.txt

Lines changed: 58 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -99,16 +99,19 @@ if(NOT HEADERS_ONLY)
9999
endif()
100100

101101
# Detect Intel processors and turn Intel SIMD on or off automatically.
102+
# Detect AArch64 processors and turn AArch64 NEON SIMD on or off automatically.
102103
# Old logic relied on the host processor: ${CMAKE_SYSTEM_PROCESSOR}
103104

104105
set(INTEL_SIMD "OFF")
105-
# Use a list of known Intel-compatible architecture names for the default ON state.
106+
set(NEON_SIMD "OFF")
107+
# Use a list of known Intel-compatible/aarch64 architecture names for the default ON state.
106108
set(INTEL_ARCH_NAMES "win32" "x64" "x86" "i386" "amd64" "x86_64" "i686")
109+
set(ARM_ARCH_NAMES "arm64" "aarch64")
107110

108111
# Check the TARGET architecture using the most reliable variables (CMAKE_GENERATOR_PLATFORM and PLATFORMID_LOWER)
109112
string(TOLOWER "${PLATFORMID}" PLATFORMID_LOWER)
110113
string(TOLOWER "${CMAKE_GENERATOR_PLATFORM}" GEN_PLATFORM_LOWER) # Often holds x64, ARM64, etc.
111-
string(TOLOWER "${CMAKE_SYSTEM_PROCESSOR}" HOST_ARCH_LOWER)
114+
string(TOLOWER "${CMAKE_SYSTEM_PROCESSOR}" HOST_ARCH_LOWER) # ninja with ative aarch64 gcc: probably only this exists
112115

113116
# --- DEBUG OUTPUT START ---
114117
# message(STATUS "--- SIMD Detection Variables ---")
@@ -125,14 +128,20 @@ if(NOT HEADERS_ONLY)
125128
# PLATFORMID_LOWER (VS Target Platform):
126129
# CMAKE_GENERATOR_PLATFORM (Generator Target): ARM64
127130

131+
# check aarch64 variants
132+
list(FIND ARM_ARCH_NAMES "${HOST_ARCH_LOWER}" _found_arm_host) # New check
133+
list(FIND ARM_ARCH_NAMES "${PLATFORMID_LOWER}" _found_arm_platform_id)
134+
list(FIND ARM_ARCH_NAMES "${GEN_PLATFORM_LOWER}" _found_arm_gen)
135+
# check intel variants
128136
list(FIND INTEL_ARCH_NAMES "${HOST_ARCH_LOWER}" _found_arch)
129137
list(FIND INTEL_ARCH_NAMES "${PLATFORMID_LOWER}" _found_target_platform_id)
130138
list(FIND INTEL_ARCH_NAMES "${GEN_PLATFORM_LOWER}" _found_target_gen)
131139

132140
# 1. Check if the target platform is explicitly known non-Intel (ARM64, AARCH64)
133-
if("${PLATFORMID_LOWER}" STREQUAL "arm64" OR "${GEN_PLATFORM_LOWER}" STREQUAL "arm64")
141+
if(_found_arm_platform_id GREATER -1 OR _found_arm_gen GREATER -1 OR _found_arm_host GREATER -1)
134142
set(INTEL_SIMD "OFF")
135-
message(STATUS "Target is ARM64/AARCH64, INTEL_SIMD forced OFF.")
143+
set(NEON_SIMD "ON")
144+
message(STATUS "Target is aarch64, turn NEON_SIMD ON.")
136145
else()
137146
# 2. Inclusion Check: We are NOT targeting ARM64.
138147

@@ -150,6 +159,7 @@ if(NOT HEADERS_ONLY)
150159
endif()
151160
# message(STATUS "Final INTEL_SIMD initial assumption: ${INTEL_SIMD}")
152161
option(ENABLE_INTEL_SIMD "Enable SIMD intrinsics for Intel processors" "${INTEL_SIMD}")
162+
option(ENABLE_NEON_SIMD "Enable SIMD intrinsics for AArch64 processors" "${NEON_SIMD}")
153163

154164
option(ENABLE_PLUGINS "Build set of default external plugins" ON)
155165
set(USER_AVS_PLUGINDIR_LOCATION ".local/lib/avisynth" CACHE STRING "Override path for user-local plugins, with $HOME omitted (default: .local/lib/avisynth)")
@@ -180,9 +190,10 @@ if(NOT HEADERS_ONLY)
180190
endif()
181191

182192
# Use this one to be safe:
183-
# Check for the Visual Studio generator, not the MSVC compiler ID, as this
184-
# block configures VS project structure (platforms/toolsets), which fails for Ninja/MSVC.
185-
if( CMAKE_GENERATOR MATCHES "Visual Studio" )
193+
# Check for the Visual Studio generator OR the MSVC compiler/toolchain on Windows
194+
# (which includes Ninja with cl.exe).
195+
# We use the MSVC variable to ensure the configuration block runs when cl.exe is detected.
196+
if( CMAKE_GENERATOR MATCHES "Visual Studio" OR (MSVC AND WIN32) )
186197
## IF( MSVC ) # Check for Visual Studio
187198

188199
#1910-1919 = VS 15.0 (v141 toolset) Visual Studio 2017
@@ -191,10 +202,37 @@ if(NOT HEADERS_ONLY)
191202
# ( 1940-1949 = VS v17.10+: Toolset v143 (Still!) | Compiler 19.4x)
192203
#1950-1959 = VS 18.0 (v145 toolset) Visual Studio 2026
193204

205+
# --- Determine MSVC target platform, Ninja makes a bit more work for us
206+
# Since CMAKE_VS_PLATFORM_NAME is empty, only valid for Visual Studio generators.
207+
208+
# Detect the target platform based on the most reliable variables for MSVC/Ninja:
209+
# 1. start with the VS Generator's specific variable. If it's not set, it will be empty.
210+
set(TARGET_PLATFORM_TO_CHECK "${CMAKE_VS_PLATFORM_NAME}")
211+
212+
# message(STATUS "DEBUG: CMAKE_VS_PLATFORM_NAME = '${CMAKE_VS_PLATFORM_NAME}'")
213+
# message(STATUS "DEBUG: CMAKE_GENERATOR_PLATFORM = '${CMAKE_GENERATOR_PLATFORM}'")
214+
# message(STATUS "DEBUG: CMAKE_SIZEOF_VOID_P = '${CMAKE_SIZEOF_VOID_P}'")
215+
216+
# 2. If CMAKE_VS_PLATFORM_NAME is empty (e.g., Ninja generator), try to infer from pointer size.
217+
if(NOT TARGET_PLATFORM_TO_CHECK)
218+
# 3. Check the pointer size (most reliable indicator for x64/Win32)
219+
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
220+
# 64-bit target
221+
set(TARGET_PLATFORM_TO_CHECK "x64")
222+
elseif(CMAKE_SIZEOF_VOID_P EQUAL 4)
223+
# 32-bit target
224+
set(TARGET_PLATFORM_TO_CHECK "Win32")
225+
endif()
226+
endif()
227+
228+
# 4. final attempt: If CMAKE_GENERATOR_PLATFORM has a value and TARGET_PLATFORM_TO_CHECK is still empty
229+
if(NOT TARGET_PLATFORM_TO_CHECK AND CMAKE_GENERATOR_PLATFORM)
230+
set(TARGET_PLATFORM_TO_CHECK "${CMAKE_GENERATOR_PLATFORM}")
231+
endif()
232+
194233
# detect if the target is for x86
195234
# PLATFORMID_LOWER is just a lowercase copy of CMAKE_VS_PLATFORM_NAME
196-
string(TOLOWER "${CMAKE_VS_PLATFORM_NAME}" PLATFORMID_LOWER)
197-
235+
string(TOLOWER "${TARGET_PLATFORM_TO_CHECK}" PLATFORMID_LOWER)
198236
# message("-- PLATFORMID_LOWER: ${PLATFORMID_LOWER}")
199237

200238
if(("${PLATFORMID_LOWER}" STREQUAL "win32") OR
@@ -393,7 +431,7 @@ if(NOT HEADERS_ONLY)
393431
# -----------------------------------------------------------------------
394432
foreach(AFFECTED_TARGET ${ALL_AFFECTED_TARGETS})
395433
if(TARGET ${AFFECTED_TARGET})
396-
message(STATUS "Applying Intel/Clang compiler fixes to target: ${AFFECTED_TARGET}")
434+
message(STATUS "Applying compiler fixes to target: ${AFFECTED_TARGET}")
397435

398436
# Check if the target is a library or executable (exclude INTERFACE targets)
399437
get_target_property(_target_type ${AFFECTED_TARGET} TYPE)
@@ -413,6 +451,7 @@ if(NOT HEADERS_ONLY)
413451
# This robust check ensures that the MSVC block only runs in an MSVC environment.
414452

415453
# Handle ARM64 soft intrinsics if requested (for AvsCore logic)
454+
# Was experimental, never true
416455
if("${PLATFORMID}" STREQUAL "ARM64" AND ENABLE_INTEL_SIMD)
417456
target_compile_definitions(${AFFECTED_TARGET} PRIVATE USE_SOFT_INTRINSICS)
418457
endif()
@@ -433,6 +472,12 @@ if(NOT HEADERS_ONLY)
433472
if(ENABLE_INTEL_SIMD)
434473
target_compile_definitions(${AFFECTED_TARGET} PRIVATE INTEL_INTRINSICS)
435474
endif()
475+
# NEON intrinsics master switch (if enabled)
476+
if(ENABLE_NEON_SIMD)
477+
target_compile_definitions(${AFFECTED_TARGET} PRIVATE NEON_INTRINSICS)
478+
endif()
479+
480+
# FIXME: With Ninja, we can see cl : Command line warning D9025 : overriding '/EHs' with '/EHa'
436481

437482
# Compiler-specific options for IntelLLVM / Clang
438483
if(CLANG_IN_VS STREQUAL "1")
@@ -498,6 +543,9 @@ if(NOT HEADERS_ONLY)
498543
target_compile_options(${AFFECTED_TARGET} PRIVATE -msse2)
499544
target_compile_definitions(${AFFECTED_TARGET} PRIVATE INTEL_INTRINSICS)
500545
endif()
546+
if(ENABLE_NEON_SIMD)
547+
target_compile_definitions(${AFFECTED_TARGET} PRIVATE NEON_INTRINSICS)
548+
endif()
501549
if(WIN32)
502550
target_compile_definitions(${AFFECTED_TARGET} PRIVATE __CRT__NO_INLINE=1)
503551
endif()

avs_core/CMakeLists.txt

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,22 +112,58 @@ function(handle_arch_flags ARCH_SUFFIX GCC_FLAGS MSVC_FLAGS)
112112
string(TOLOWER "${ARCH_SUFFIX}" ARCH_SUFFIX_LOWER)
113113
file(GLOB_RECURSE SRCS_${ARCH_SUFFIX} "*_${ARCH_SUFFIX_LOWER}.cpp")
114114
if(SRCS_${ARCH_SUFFIX})
115-
if (MSVC_IDE)
115+
# Check for any MSVC-based toolchain (VS IDE or cl.exe with Ninja) on Windows.
116+
if (MSVC) # MSVC can do Win32 and ARM64 as well.
117+
# not this: if (MSVC_IDE), Ninja leaves MSVC_IDE off
118+
# Check for MSVC-frontends that use GCC/Clang-like flags (e.g., ClangCL, IntelLLVM)
116119
IF(CLANG_IN_VS STREQUAL "1" OR IntelLLVM_IN_VS STREQUAL "1" OR IntelClassic_IN_VS STREQUAL "1")
117120
set_source_files_properties(${SRCS_${ARCH_SUFFIX}} PROPERTIES COMPILE_FLAGS "${GCC_FLAGS}")
118121
ELSE()
122+
# Native MSVC (cl.exe, including when used with Ninja)
123+
IF(WIN32)
119124
# MSVC gives warning in x64 when SSE2 flag is added, it's just required as a minimum
120125
if(NOT (CMAKE_SIZEOF_VOID_P EQUAL 8 AND "${MSVC_FLAGS}" STREQUAL " /arch:SSE2 "))
121126
set_source_files_properties(${SRCS_${ARCH_SUFFIX}} PROPERTIES COMPILE_FLAGS "${MSVC_FLAGS}")
122127
endif()
128+
endif()
123129
ENDIF()
124130
else()
131+
# Fallback for all non-MSVC compilers (GCC, Clang on Linux/macOS, MinGW)
125132
set_source_files_properties(${SRCS_${ARCH_SUFFIX}} PROPERTIES COMPILE_FLAGS "${GCC_FLAGS}")
126133
endif()
127134
list(APPEND AvsCore_Sources ${SRCS_${ARCH_SUFFIX}})
128135
endif()
129136
endfunction()
130137

138+
if(ENABLE_NEON_SIMD)
139+
# =========================================================================
140+
# AArch64 (ARM64) SIMD Flags
141+
# =========================================================================
142+
# See: Arch64 SIMD Compilation and Source Code Rules
143+
# Files must be located in 'aarch64' subdirectory.
144+
145+
# Baseline NEON (ASIMD)
146+
# GCC/Clang: Implicit (or -march=armv8-a) MSVC: /arch:armv8.0
147+
# asm output debug, leave it here pls.: handle_arch_flags(NEON " -march=armv8-a -S -g -fverbose-asm -Wa,-adhln " " /arch:armv8.0 ")
148+
handle_arch_flags(NEON " -march=armv8-a " " /arch:armv8.0 ")
149+
150+
# Dot Product (FEAT_DotProd / ARMv8.1-A) compulsory from ARMv8.4-A
151+
handle_arch_flags(DP " -march=armv8.1-a+dotprod " " /arch:armv8.1 ")
152+
153+
# Int8 Matrix Multiply (FEAT_I8MM / ARMv8.2-A) Compulsory from ARMv8.6-A
154+
# Use the base arch flag to enable the features, relying on modern toolchain support.
155+
handle_arch_flags(I8MM " -march=armv8.2-a+i8mm " " /arch:armv8.2 ")
156+
157+
# SVE2 (Scalable Vector Extension 2) (FEAT_SVE2 / ARMv8.5-A) Compulsory from ARMv9.0-A
158+
handle_arch_flags(SVE2 " -march=armv8.5-a+sve2 " " /arch:armv8.5 ")
159+
160+
# SVE2.1 (FEAT_SVE2p1 / ARMv9.1-A)
161+
handle_arch_flags(SVE2_1 " -march=armv9.1-a+sve2.1 " " /arch:armv9.1 ")
162+
163+
else()
164+
# =========================================================================
165+
# Intel (x86/x64) SIMD Flags
166+
# =========================================================================
131167
# gcc/llvm/clang-like flags, MSVC flags
132168
handle_arch_flags(SSSE3 " -mssse3 " " /arch:SSE2 ") # no special SSSE3 option in MSVC
133169
handle_arch_flags(SSE41 " -msse4.1 " " /arch:SSE2 ") # no special SSE4.1 option in MSVC
@@ -148,6 +184,7 @@ if(DEFINE_AVX512)
148184
# GCC/Clang/Intel compilers use the -mavx512... flags inside handle_arch_flags when running in MSVC_IDE
149185
handle_arch_flags(AVX512 "${AVX512_FAST_GCC_FLAGS}" " /arch:AVX512 ")
150186
endif()
187+
ENDIF()
151188

152189
# Specify include directories
153190
target_include_directories("AvsCore" PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include)

avs_core/Files.cmake

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,33 @@ FILE(GLOB AvsCore_Sources RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}"
3838

3939
)
4040

41+
IF(ENABLE_NEON_SIMD)
42+
FILE(GLOB Conditional_Filter_Cpu_Sources RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}"
43+
"filters/conditional/aarch64/*.cpp"
44+
"filters/conditional/aarch64/*.h")
45+
LIST(APPEND AvsCore_Sources "${Conditional_Filter_Cpu_Sources}")
46+
47+
FILE(GLOB Convert_Cpu_Sources RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}"
48+
"convert/aarch64/*.cpp"
49+
"convert/aarch64/*.h")
50+
LIST(APPEND AvsCore_Sources "${Convert_Cpu_Sources}")
51+
52+
FILE(GLOB Filters_Cpu_Sources RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}"
53+
"filters/aarch64/*.cpp"
54+
"filters/aarch64/*.h")
55+
LIST(REMOVE_ITEM AvsCore_Sources "")
56+
57+
LIST(APPEND AvsCore_Sources "${Filters_Cpu_Sources}")
58+
59+
FILE(GLOB Overlay_Cpu_Sources RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}"
60+
"filters/overlay/aarch64/*.cpp"
61+
"filters/overlay/aarch64/*.h")
62+
#not removing yet, unlike for Intel, no SIMD replacement
63+
#LIST(REMOVE_ITEM AvsCore_Sources "filters/overlay/444convert.cpp"
64+
# "filters/overlay/444convert.h")
65+
LIST(APPEND AvsCore_Sources "${Overlay_Cpu_Sources}")
66+
ENDIF()
67+
4168
IF(ENABLE_INTEL_SIMD)
4269
FILE(GLOB Conditional_Filter_Cpu_Sources RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}"
4370
"filters/conditional/intel/*.cpp"

0 commit comments

Comments
 (0)