Blame cmake/cpu.cmake

Packit 9c6abc
## Check for SIMD extensions.
Packit 9c6abc
include(CMakePushCheckState)
Packit 9c6abc
Packit 9c6abc
function(webp_check_compiler_flag WEBP_SIMD_FLAG ENABLE_SIMD)
Packit 9c6abc
  if(NOT ENABLE_SIMD)
Packit 9c6abc
    message(STATUS "Disabling ${WEBP_SIMD_FLAG} optimization.")
Packit 9c6abc
    set(WEBP_HAVE_${WEBP_SIMD_FLAG} 0 PARENT_SCOPE)
Packit 9c6abc
    return()
Packit 9c6abc
  endif()
Packit 9c6abc
  unset(WEBP_HAVE_FLAG_${WEBP_SIMD_FLAG} CACHE)
Packit 9c6abc
  cmake_push_check_state()
Packit 9c6abc
  set(CMAKE_REQUIRED_INCLUDES ${CMAKE_CURRENT_SOURCE_DIR})
Packit 9c6abc
  check_c_source_compiles("
Packit 9c6abc
      #include \"${CMAKE_CURRENT_LIST_DIR}/../src/dsp/dsp.h\"
Packit 9c6abc
      int main(void) {
Packit 9c6abc
        #if !defined(WEBP_USE_${WEBP_SIMD_FLAG})
Packit 9c6abc
        this is not valid code
Packit 9c6abc
        #endif
Packit 9c6abc
        return 0;
Packit 9c6abc
      }
Packit 9c6abc
    " WEBP_HAVE_FLAG_${WEBP_SIMD_FLAG}
Packit 9c6abc
  )
Packit 9c6abc
  cmake_pop_check_state()
Packit 9c6abc
  if(WEBP_HAVE_FLAG_${WEBP_SIMD_FLAG})
Packit 9c6abc
    set(WEBP_HAVE_${WEBP_SIMD_FLAG} 1 PARENT_SCOPE)
Packit 9c6abc
  else()
Packit 9c6abc
    set(WEBP_HAVE_${WEBP_SIMD_FLAG} 0 PARENT_SCOPE)
Packit 9c6abc
  endif()
Packit 9c6abc
endfunction()
Packit 9c6abc
Packit 9c6abc
# those are included in the names of WEBP_USE_* in c++ code.
Packit 9c6abc
set(WEBP_SIMD_FLAGS "SSE2;SSE41;AVX2;MIPS32;MIPS_DSP_R2;NEON;MSA")
Packit 9c6abc
set(WEBP_SIMD_FILE_EXTENSIONS "_sse2.c;_sse41.c;_avx2.c;_mips32.c;_mips_dsp_r2.c;_neon.c;_msa.c")
Packit 9c6abc
if(MSVC)
Packit 9c6abc
  # MSVC does not have a SSE4 flag but AVX2 support implies
Packit 9c6abc
  # SSE4 support.
Packit 9c6abc
  set(SIMD_ENABLE_FLAGS "/arch:SSE2;/arch:AVX2;/arch:AVX2;;;;")
Packit 9c6abc
  set(SIMD_DISABLE_FLAGS)
Packit 9c6abc
else()
Packit 9c6abc
  set(SIMD_ENABLE_FLAGS "-msse2;-msse4.1;-mavx2;-mips32;-mdspr2;-mfpu=neon;-mmsa")
Packit 9c6abc
  set(SIMD_DISABLE_FLAGS "-mno-sse2;-mno-sse4.1;-mno-avx2;;-mno-dspr2;;-mno-msa")
Packit 9c6abc
endif()
Packit 9c6abc
Packit 9c6abc
set(WEBP_SIMD_FILES_TO_NOT_INCLUDE)
Packit 9c6abc
set(WEBP_SIMD_FILES_TO_INCLUDE)
Packit 9c6abc
set(WEBP_SIMD_FLAGS_TO_INCLUDE)
Packit 9c6abc
Packit 9c6abc
if(${ANDROID})
Packit 9c6abc
  if(${ANDROID_ABI} STREQUAL "armeabi-v7a")
Packit 9c6abc
    # This is because Android studio uses the configuration
Packit 9c6abc
    # "-march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16"
Packit 9c6abc
    # that does not trigger neon optimizations but should
Packit 9c6abc
    # (as this configuration does not exist anymore).
Packit 9c6abc
    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mfpu=neon ")
Packit 9c6abc
  endif()
Packit 9c6abc
endif()
Packit 9c6abc
Packit 9c6abc
list(LENGTH WEBP_SIMD_FLAGS WEBP_SIMD_FLAGS_LENGTH)
Packit 9c6abc
math(EXPR WEBP_SIMD_FLAGS_RANGE "${WEBP_SIMD_FLAGS_LENGTH} - 1")
Packit 9c6abc
Packit 9c6abc
foreach(I_SIMD RANGE ${WEBP_SIMD_FLAGS_RANGE})
Packit 9c6abc
  list(GET WEBP_SIMD_FLAGS ${I_SIMD} WEBP_SIMD_FLAG)
Packit 9c6abc
Packit 9c6abc
  # First try with no extra flag added as the compiler might have default flags
Packit 9c6abc
  # (especially on Android).
Packit 9c6abc
  unset(WEBP_HAVE_${WEBP_SIMD_FLAG} CACHE)
Packit 9c6abc
  cmake_push_check_state()
Packit 9c6abc
  set(CMAKE_REQUIRED_FLAGS)
Packit 9c6abc
  webp_check_compiler_flag(${WEBP_SIMD_FLAG} ${WEBP_ENABLE_SIMD})
Packit 9c6abc
  if(NOT WEBP_HAVE_${WEBP_SIMD_FLAG})
Packit 9c6abc
    list(GET SIMD_ENABLE_FLAGS ${I_SIMD} SIMD_COMPILE_FLAG)
Packit 9c6abc
    set(CMAKE_REQUIRED_FLAGS ${SIMD_COMPILE_FLAG})
Packit 9c6abc
    webp_check_compiler_flag(${WEBP_SIMD_FLAG} ${WEBP_ENABLE_SIMD})
Packit 9c6abc
  else()
Packit 9c6abc
    set(SIMD_COMPILE_FLAG " ")
Packit 9c6abc
  endif()
Packit 9c6abc
  # Check which files we should include or not.
Packit 9c6abc
  list(GET WEBP_SIMD_FILE_EXTENSIONS ${I_SIMD} WEBP_SIMD_FILE_EXTENSION)
Packit 9c6abc
  file(GLOB SIMD_FILES "${CMAKE_CURRENT_LIST_DIR}/../"
Packit 9c6abc
    "src/dsp/*${WEBP_SIMD_FILE_EXTENSION}"
Packit 9c6abc
  )
Packit 9c6abc
  if(WEBP_HAVE_${WEBP_SIMD_FLAG})
Packit 9c6abc
    # Memorize the file and flags.
Packit 9c6abc
    foreach(FILE ${SIMD_FILES})
Packit 9c6abc
      list(APPEND WEBP_SIMD_FILES_TO_INCLUDE ${FILE})
Packit 9c6abc
      list(APPEND WEBP_SIMD_FLAGS_TO_INCLUDE ${SIMD_COMPILE_FLAG})
Packit 9c6abc
    endforeach()
Packit 9c6abc
  else()
Packit 9c6abc
    # Remove the file from the list.
Packit 9c6abc
    foreach(FILE ${SIMD_FILES})
Packit 9c6abc
      list(APPEND WEBP_SIMD_FILES_NOT_TO_INCLUDE ${FILE})
Packit 9c6abc
    endforeach()
Packit 9c6abc
    # Explicitly disable SIMD.
Packit 9c6abc
    if(SIMD_DISABLE_FLAGS)
Packit 9c6abc
      list(GET SIMD_DISABLE_FLAGS ${I_SIMD} SIMD_COMPILE_FLAG)
Packit 9c6abc
      include(CheckCCompilerFlag)
Packit 9c6abc
      if(SIMD_COMPILE_FLAG)
Packit 9c6abc
        unset(HAS_COMPILE_FLAG CACHE)
Packit 9c6abc
        check_c_compiler_flag(${SIMD_COMPILE_FLAG} HAS_COMPILE_FLAG)
Packit 9c6abc
        if(HAS_COMPILE_FLAG)
Packit 9c6abc
          # Do one more check for Clang to circumvent CMake issue 13194.
Packit 9c6abc
          if(COMMAND check_compiler_flag_common_patterns)
Packit 9c6abc
            # Only in CMake 3.0 and above.
Packit 9c6abc
            check_compiler_flag_common_patterns(COMMON_PATTERNS)
Packit 9c6abc
          else()
Packit 9c6abc
            set(COMMON_PATTERNS)
Packit 9c6abc
          endif()
Packit 9c6abc
          set(CMAKE_REQUIRED_DEFINITIONS ${SIMD_COMPILE_FLAG})
Packit 9c6abc
          check_c_source_compiles("int main(void) {return 0;}"
Packit 9c6abc
            FLAG_${SIMD_COMPILE_FLAG}
Packit 9c6abc
            FAIL_REGEX "warning: argument unused during compilation:"
Packit 9c6abc
            ${COMMON_PATTERNS}
Packit 9c6abc
          )
Packit 9c6abc
          if(NOT FLAG_${SIMD_COMPILE_FLAG})
Packit 9c6abc
            unset(HAS_COMPILE_FLAG CACHE)
Packit 9c6abc
          endif()
Packit 9c6abc
        endif()
Packit 9c6abc
        if(HAS_COMPILE_FLAG)
Packit 9c6abc
          set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${SIMD_COMPILE_FLAG}")
Packit 9c6abc
        endif()
Packit 9c6abc
      endif()
Packit 9c6abc
    endif()
Packit 9c6abc
  endif()
Packit 9c6abc
  cmake_pop_check_state()
Packit 9c6abc
endforeach()