INCLUDE(CheckCSourceRuns)
INCLUDE(CheckCXXSourceRuns)

SET(AVX2_CODE "
#include <immintrin.h>
int main(){
  __m256d a,b;
  a = _mm256_set_pd(0,0,0,0);
  b = _mm256_permute4x64_pd(a, 0);
  return 0;
}
")


MACRO(CHECK_AVX2_WINDOWS)
  SET(CMAKE_REQUIRED_FLAGS_SAVE ${CMAKE_REQUIRED_FLAGS})

  SET(CMAKE_REQUIRED_FLAGS "/arch:AVX2")
  CHECK_CXX_SOURCE_RUNS("${AVX2_CODE}" CXX_HAS_AVX2)
  CHECK_C_SOURCE_RUNS("${AVX2_CODE}" C_HAS_AVX2)
  #message(STATUS "C_HAS_AVX2 = ${C_HAS_AVX2}")
  #message(STATUS "CXX_HAS_AVX2 = ${CXX_HAS_AVX2}")
  IF(C_HAS_AVX2 AND CXX_HAS_AVX2)
    SET(AVX2_FOUND TRUE CACHE BOOL "AVX2 support")
  ELSE()
    SET(AVX2_FOUND FALSE CACHE BOOL "AVX2 support")
  ENDIF()

  SET(CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS_SAVE})
  MARK_AS_ADVANCED(AVX2_FOUND)
ENDMACRO()

MACRO(CHECK_AVX2_LINUX)
  SET(CMAKE_REQUIRED_FLAGS_SAVE ${CMAKE_REQUIRED_FLAGS})

  SET(CMAKE_REQUIRED_FLAGS "-mavx2")
  CHECK_C_SOURCE_RUNS("${AVX2_CODE}" C_HAS_AVX2)
  CHECK_CXX_SOURCE_RUNS("${AVX2_CODE}" CXX_HAS_AVX2)
  
  SET(C_HAS_AVX2 TRUE)
  SET(CXX_HAS_AVX2 TRUE)
  #message(STATUS "C_HAS_AVX2 = ${C_HAS_AVX2}")
  #message(STATUS "CXX_HAS_AVX2 = ${CXX_HAS_AVX2}")

  IF(C_HAS_AVX2 AND CXX_HAS_AVX2)
    SET(AVX2_FOUND TRUE CACHE BOOL "AVX2 support")
  ELSE()
    SET(AVX2_FOUND FALSE CACHE BOOL "AVX2 support")
  ENDIF()

  SET(CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS_SAVE})
  MARK_AS_ADVANCED(AVX2_FOUND)
ENDMACRO()

#CHECK_AVX2_WINDOWS()
#CHECK_AVX2_LINUX()
#message(STATUS "AVX2_FOUND = ${AVX2_FOUND}")
