118 строки
4.1 KiB
CMake
118 строки
4.1 KiB
CMake
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
|
# file Copyright.txt or https://cmake.org/licensing for details.
|
|
|
|
#[=======================================================================[.rst:
|
|
CheckCompilerMachineOption
|
|
-------------------------------
|
|
|
|
Check compiler flag for machine optimization. Returns compiler flag
|
|
for specified feature such as SSE AVX2 if available.
|
|
if not available, return "".
|
|
|
|
.. command:: check_compiler_machine_option
|
|
|
|
compiler_machine_option(<output variable> <feature>)
|
|
|
|
#]=======================================================================]
|
|
|
|
|
|
include(CheckCCompilerFlag)
|
|
include(CheckCXXCompilerFlag)
|
|
include(CheckIncludeFileCXX)
|
|
include(CheckIncludeFile)
|
|
|
|
function(check_compiler_machine_option outvar feature)
|
|
macro(__check_compiler_flag _flag _result)
|
|
if(CMAKE_CXX_COMPILER_LOADED)
|
|
check_cxx_compiler_flag("${_flag}" ${_result})
|
|
elseif(CMAKE_C_COMPILER_LOADED)
|
|
check_c_compiler_flag("${_flag}" ${_result})
|
|
endif()
|
|
endmacro()
|
|
|
|
set(_FLAGS)
|
|
if("${CMAKE_SYSTEM_PROCESSOR}" MATCHES "(x86|AMD64)")
|
|
if(MSVC AND (${feature} MATCHES "SSE"))
|
|
# SSE2 and SSE are default on
|
|
set(_FLAGS " ")
|
|
elseif(MSVC)
|
|
# Only Visual Studio 2017 version 15.3 / Visual C++ 19.11 & up have support for AVX-512.
|
|
# https://blogs.msdn.microsoft.com/vcblog/2017/07/11/microsoft-visual-studio-2017-supports-intel-avx-512/
|
|
set(MSVC_FLAG_MAP AVX512 "-arch:AVX512" AVX2 "-arch:AVX2" AVX "-arch:AVX")
|
|
list(FIND MSVC_FLAG_MAP ${feature} _found)
|
|
if(_found GREATER -1)
|
|
math(EXPR index "${_found}+1")
|
|
list(GET MSVC_FLAG_MAP ${index} _flag)
|
|
__check_compiler_flag("${_flag}" test_${feature})
|
|
if(test_${feature})
|
|
set(_FLAGS "${_flag}")
|
|
endif()
|
|
endif()
|
|
elseif(CMAKE_CXX_COMPILER MATCHES "/(icpc|icc)$") # ICC (on Linux)
|
|
set(map_flag AVX2 "-xCORE_AVX2" AVX "-xAVX" SSE4_2 "-xSSE4.2" SSE4_1 "-xSSE4.1" SSSE3 "-xSSSE3"
|
|
AVX512 "-xCORE-AVX512;-xMIC-AVX512" )
|
|
list(FIND map_flag "${feature}" _found)
|
|
if(_found GREATER -1)
|
|
math(EXPR index "${_found}+1")
|
|
list(GET map_flag ${index} _flag)
|
|
foreach(flag IN ITEMS ${_flag})
|
|
__check_compiler_flag(${_flag} _ok)
|
|
if(_ok)
|
|
set(_FLAGS ${_flag})
|
|
break()
|
|
endif()
|
|
endforeach()
|
|
endif()
|
|
else() # not MSVC and not ICC => GCC, Clang, Open64
|
|
string(TOLOWER ${feature} _flag)
|
|
string(REPLACE "_" "." _flag "${_flag}")
|
|
__check_compiler_flag("-m${_flag}" test_${_flag})
|
|
if(test_${_flag})
|
|
set(header_table
|
|
"sse" "xmmintrin.h"
|
|
"sse2" "emmintrin.h"
|
|
"sse3" "pmmintrin.h"
|
|
"ssse3" "tmmintrin.h"
|
|
"sse4.1" "smmintrin.h"
|
|
"sse4.2" "smmintrin.h"
|
|
"sse4a" "ammintrin.h"
|
|
"avx" "immintrin.h"
|
|
"avx2" "immintrin.h"
|
|
"fma4" "x86intrin.h"
|
|
"xop" "x86intrin.h")
|
|
set(_header FALSE)
|
|
list(FIND header_table ${_flag} _found)
|
|
if(_found GREATER -1)
|
|
math(EXPR index "${_found} + 1")
|
|
list(GET header_table ${index} _header)
|
|
endif()
|
|
set(_resultVar "HAVE_${_header}")
|
|
string(REPLACE "." "_" _resultVar "${_resultVar}")
|
|
if(_header)
|
|
if(CMAKE_CXX_COMPILER_LOADED)
|
|
check_include_file_cxx("${_header}" ${_resultVar} "-m${_flag}")
|
|
elseif(CMAKE_C_COMPILER_LOADED)
|
|
check_include_file("${_header}" ${_resultVar} "-m${_flag}")
|
|
endif()
|
|
if(NOT _header OR ${_resultVar})
|
|
set(_FLAGS "-m${_flag}")
|
|
endif()
|
|
endif()
|
|
endif()
|
|
endif()
|
|
elseif("${CMAKE_SYSTEM_PROCESSOR}" MATCHES "(ARM|aarch64)")
|
|
if(MSVC)
|
|
# TODO implement me
|
|
elseif(CMAKE_CXX_COMPILER MATCHES "/(icpc|icc)$") # ICC (on Linux)
|
|
# TODO implement me
|
|
else() # not MSVC and not ICC => GCC, Clang, Open64
|
|
string(TOLOWER ${feature} _flag)
|
|
__check_compiler_flag("-m${_flag}" test_${_flag})
|
|
if(test_${_flag})
|
|
set(_FLAGS "-m${_flag}")
|
|
endif()
|
|
endif()
|
|
endif()
|
|
set(${outvar} "${_FLAGS}" PARENT_SCOPE)
|
|
endfunction()
|