diff --git a/.github/workflows/build_pull_request.yml b/.github/workflows/build_pull_request.yml index 2bfa79b..5d56f7f 100644 --- a/.github/workflows/build_pull_request.yml +++ b/.github/workflows/build_pull_request.yml @@ -162,15 +162,25 @@ jobs: matrix: compiler: [vs2022, vs2022-clang] build_config: [debug, release] - cpu: [x86, x64, arm64] + cpu: [x86, x64, arm64, arm64ec] simd: [-simd, -nosimd, -avx] exclude: # Don't run arm64 with clang - compiler: vs2022-clang cpu: arm64 + # Don't run arm64ec with clang + - compiler: vs2022-clang + cpu: arm64ec # Don't run AVX with arm64 - cpu: arm64 simd: -avx + # Don't run AVX with arm64ec + - cpu: arm64ec + simd: -avx + # Don't run x86 AVX with VS2022 to avoid toolchain code generation bug, see #248 + - compiler: vs2022 + cpu: x86 + simd: -avx steps: - name: Git checkout uses: actions/checkout@v4 diff --git a/.github/workflows/build_push.yml b/.github/workflows/build_push.yml index fcb13cf..1aa5835 100644 --- a/.github/workflows/build_push.yml +++ b/.github/workflows/build_push.yml @@ -162,15 +162,25 @@ jobs: matrix: compiler: [vs2022, vs2022-clang] build_config: [debug, release] - cpu: [x86, x64, arm64] + cpu: [x86, x64, arm64, arm64ec] simd: [-simd, -nosimd, -avx] exclude: # Don't run arm64 with clang - compiler: vs2022-clang cpu: arm64 + # Don't run arm64ec with clang + - compiler: vs2022-clang + cpu: arm64ec # Don't run AVX with arm64 - cpu: arm64 simd: -avx + # Don't run AVX with arm64ec + - cpu: arm64ec + simd: -avx + # Don't run x86 AVX with VS2022 to avoid toolchain code generation bug, see #248 + - compiler: vs2022 + cpu: x86 + simd: -avx steps: - name: Git checkout uses: actions/checkout@v4 diff --git a/CMakeLists.txt b/CMakeLists.txt index 60e2b11..50f6103 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,6 +13,7 @@ set(USE_SIMD_INSTRUCTIONS true CACHE BOOL "Use SIMD instructions") set(WITH_VECTOR_MIX_TESTS false CACHE BOOL "Enable vector_mix unit tests") set(CPU_INSTRUCTION_SET false CACHE STRING "CPU instruction set") set(BUILD_BENCHMARK_EXE false CACHE BOOL "Enable the benchmark projects") +set(IS_CROSS_COMPILING false CACHE BOOL "Whether or not we are cross-compiling") if(CMAKE_CONFIGURATION_TYPES) set(CMAKE_CONFIGURATION_TYPES Debug Release) diff --git a/README.md b/README.md index ed40b65..c8b69d5 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ Much thought was put into designing the library for it to be as flexible and pow Continuous integration tests a variety of platforms and configurations but it generally runs as-is anywhere where C++11 (or later) is supported. CI currently tests: -* Windows VS2022: x86, x64, ARM64 +* Windows VS2022: x86, x64, ARM64, ARM64EC * Linux GCC 12+: x86, x64 * Linux Clang 15+: x86, x64 * OS X XCode 15+: ARM64 diff --git a/includes/rtm/impl/detect_arch.h b/includes/rtm/impl/detect_arch.h index f7f705a..82d9fed 100644 --- a/includes/rtm/impl/detect_arch.h +++ b/includes/rtm/impl/detect_arch.h @@ -27,12 +27,15 @@ ////////////////////////////////////////////////////////////////////////// // Macro to identify our platform architecture ////////////////////////////////////////////////////////////////////////// -#if defined(_M_X64) || defined(__x86_64__) - #define RTM_ARCH_X64 -#elif defined(_M_IX86) || defined(__i386__) - #define RTM_ARCH_X86 -#elif defined(_M_ARM64) || defined(__aarch64__) + +// Test ARM64 first because ARM64EC also defines _M_X64, it's a hybrid architecture +// used by MSVC to facilitate SIMD porting to ARM platforms +#if defined(_M_ARM64) || defined(__aarch64__) || defined(_M_ARM64EC) #define RTM_ARCH_ARM64 #elif defined(_M_ARM) || defined(__ARM_NEON) #define RTM_ARCH_ARM +#elif defined(_M_X64) || defined(__x86_64__) + #define RTM_ARCH_X64 +#elif defined(_M_IX86) || defined(__i386__) + #define RTM_ARCH_X86 #endif diff --git a/make.py b/make.py index 754456f..c9425b2 100644 --- a/make.py +++ b/make.py @@ -21,7 +21,7 @@ def parse_argv(): target = parser.add_argument_group(title='Target') target.add_argument('-compiler', choices=['vs2015', 'vs2017', 'vs2019', 'vs2019-clang', 'vs2022', 'vs2022-clang', 'android', 'clang4', 'clang5', 'clang6', 'clang7', 'clang8', 'clang9', 'clang10', 'clang11', 'clang12', 'clang13', 'clang14', 'clang15', 'clang16', 'clang17', 'clang18', 'gcc5', 'gcc6', 'gcc7', 'gcc8', 'gcc9', 'gcc10', 'gcc11', 'gcc12', 'gcc13', 'osx', 'ios', 'emscripten'], help='Defaults to the host system\'s default compiler') target.add_argument('-config', choices=['Debug', 'Release'], type=str.capitalize) - target.add_argument('-cpu', choices=['x86', 'x64', 'armv7', 'arm64', 'wasm'], help='Defaults to the host system\'s architecture') + target.add_argument('-cpu', choices=['x86', 'x64', 'armv7', 'arm64', 'arm64ec', 'wasm'], help='Defaults to the host system\'s architecture') target.add_argument('-cpp_version', choices=['11', '14', '17', '20'], help='Defaults to C++11') misc = parser.add_argument_group(title='Miscellaneous') @@ -127,7 +127,11 @@ def parse_argv(): is_arm_supported = True if not is_arm_supported: - print('arm64 is only supported with VS2017, VS2019, OS X (M1 processors), Linux, Android, and iOS') + print('arm64 is only supported with VS2017, VS2019, VS2022, OS X (M* processors), Linux, Android, and iOS') + sys.exit(1) + elif args.cpu == 'arm64ec': + if not args.compiler in ['vs2019', 'vs2022']: + print('arm64ec is only supported with VS2019 and VS2022') sys.exit(1) elif args.cpu == 'armv7': if not args.compiler == 'android': @@ -309,6 +313,10 @@ def do_generate_solution(build_dir, cmake_script_dir, args): cpu = args.cpu config = args.config + is_arm64_cpu = False + if platform.machine() == 'arm64' or platform.machine() == 'aarch64': + is_arm64_cpu = True + if compiler: set_compiler_env(compiler, args) @@ -316,6 +324,10 @@ def do_generate_solution(build_dir, cmake_script_dir, args): extra_switches.append('-DCPU_INSTRUCTION_SET:STRING={}'.format(cpu)) extra_switches.append('-DCMAKE_CXX_STANDARD:STRING={}'.format(args.cpp_version)) + if platform.system() == 'Windows' and not is_arm64_cpu: + if cpu == 'arm64' or cpu == 'arm64ec': + extra_switches.append('-DIS_CROSS_COMPILING:BOOL=true') + if args.use_avx: print('Enabling AVX usage') extra_switches.append('-DUSE_AVX_INSTRUCTIONS:BOOL=true') diff --git a/tests/main_generic/CMakeLists.txt b/tests/main_generic/CMakeLists.txt index d2f3213..f36a4c1 100644 --- a/tests/main_generic/CMakeLists.txt +++ b/tests/main_generic/CMakeLists.txt @@ -19,10 +19,13 @@ create_source_groups("${ALL_MAIN_SOURCE_FILES}" ${PROJECT_SOURCE_DIR}) add_executable(${PROJECT_NAME} ${ALL_TEST_SOURCE_FILES} ${ALL_MAIN_SOURCE_FILES}) -list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/../../external/catch2/contrib") -include(CTest) -include(Catch) -catch_discover_tests(${PROJECT_NAME}) +if(NOT IS_CROSS_COMPILING) + # Don't attempt to detect unit tests if we are cross-compiling + list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/../../external/catch2/contrib") + include(CTest) + include(Catch) + catch_discover_tests(${PROJECT_NAME}) +endif() setup_default_compiler_flags(${PROJECT_NAME})