1# ------------------------------------------------------------------------------ 2# Cpu features definition and flags 3# ------------------------------------------------------------------------------ 4 5# Initialize ALL_CPU_FEATURES as empty list. 6set(ALL_CPU_FEATURES "") 7 8if(${LIBC_TARGET_ARCHITECTURE_IS_X86}) 9 set(ALL_CPU_FEATURES SSE2 SSE4_2 AVX2 AVX512F) 10 set(LIBC_COMPILE_OPTIONS_NATIVE -march=native) 11elseif(${LIBC_TARGET_ARCHITECTURE_IS_AARCH64}) 12 set(LIBC_COMPILE_OPTIONS_NATIVE -mcpu=native) 13endif() 14 15# Making sure ALL_CPU_FEATURES is sorted. 16list(SORT ALL_CPU_FEATURES) 17 18# Function to check whether the target CPU supports the provided set of features. 19# Usage: 20# cpu_supports( 21# <output variable> 22# <list of cpu features> 23# ) 24function(cpu_supports output_var features) 25 _intersection(var "${LIBC_CPU_FEATURES}" "${features}") 26 if("${var}" STREQUAL "${features}") 27 set(${output_var} TRUE PARENT_SCOPE) 28 else() 29 unset(${output_var} PARENT_SCOPE) 30 endif() 31endfunction() 32 33# ------------------------------------------------------------------------------ 34# Internal helpers and utilities. 35# ------------------------------------------------------------------------------ 36 37# Computes the intersection between two lists. 38function(_intersection output_var list1 list2) 39 foreach(element IN LISTS list1) 40 if("${list2}" MATCHES "(^|;)${element}(;|$)") 41 list(APPEND tmp "${element}") 42 endif() 43 endforeach() 44 set(${output_var} ${tmp} PARENT_SCOPE) 45endfunction() 46 47# Generates a cpp file to introspect the compiler defined flags. 48function(_generate_check_code) 49 foreach(feature IN LISTS ALL_CPU_FEATURES) 50 set(DEFINITIONS 51 "${DEFINITIONS} 52#ifdef __${feature}__ 53 \"${feature}\", 54#endif") 55 endforeach() 56 configure_file( 57 "${LIBC_SOURCE_DIR}/cmake/modules/cpu_features/check_cpu_features.cpp.in" 58 "cpu_features/check_cpu_features.cpp" @ONLY) 59endfunction() 60_generate_check_code() 61 62set(LIBC_CPU_FEATURES "" CACHE PATH "Host supported CPU features") 63 64if(CMAKE_CROSSCOMPILING) 65 _intersection(cpu_features "${ALL_CPU_FEATURES}" "${LIBC_CPU_FEATURES}") 66 if(NOT "${cpu_features}" STREQUAL "${LIBC_CPU_FEATURES}") 67 message(FATAL_ERROR "Unsupported CPU features: ${cpu_features}") 68 endif() 69 set(LIBC_CPU_FEATURES "${cpu_features}") 70else() 71 # Populates the LIBC_CPU_FEATURES list from host. 72 try_run( 73 run_result compile_result "${CMAKE_CURRENT_BINARY_DIR}/check_${feature}" 74 "${CMAKE_CURRENT_BINARY_DIR}/cpu_features/check_cpu_features.cpp" 75 COMPILE_DEFINITIONS ${LIBC_COMPILE_OPTIONS_NATIVE} 76 COMPILE_OUTPUT_VARIABLE compile_output 77 RUN_OUTPUT_VARIABLE run_output) 78 if("${run_result}" EQUAL 0) 79 set(LIBC_CPU_FEATURES "${run_output}") 80 elseif(NOT ${compile_result}) 81 message(FATAL_ERROR "Failed to compile: ${compile_output}") 82 else() 83 message(FATAL_ERROR "Failed to run: ${run_output}") 84 endif() 85endif() 86