123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385 |
- macro(simd_fail message)
- if(REQUIRE_SIMD)
- message(FATAL_ERROR "${message}.")
- else()
- message(WARNING "${message}. Performance will suffer.")
- set(WITH_SIMD 0 PARENT_SCOPE)
- endif()
- endmacro()
- ###############################################################################
- # x86[-64] (NASM)
- ###############################################################################
- if(CPU_TYPE STREQUAL "x86_64" OR CPU_TYPE STREQUAL "i386")
- set(CMAKE_ASM_NASM_FLAGS_DEBUG_INIT "-g")
- set(CMAKE_ASM_NASM_FLAGS_RELWITHDEBINFO_INIT "-g")
- # Allow the location of the NASM executable to be specified using the ASM_NASM
- # environment variable. This should happen automatically, but unfortunately
- # enable_language(ASM_NASM) doesn't parse the ASM_NASM environment variable
- # until after CMAKE_ASM_NASM_COMPILER has been populated with the results of
- # searching for NASM or YASM in the PATH.
- if(NOT DEFINED CMAKE_ASM_NASM_COMPILER AND DEFINED ENV{ASM_NASM})
- set(CMAKE_ASM_NASM_COMPILER $ENV{ASM_NASM})
- endif()
- if(CPU_TYPE STREQUAL "x86_64")
- if(CYGWIN)
- set(CMAKE_ASM_NASM_OBJECT_FORMAT win64)
- endif()
- elseif(CPU_TYPE STREQUAL "i386")
- if(BORLAND)
- set(CMAKE_ASM_NASM_OBJECT_FORMAT obj)
- elseif(CYGWIN)
- set(CMAKE_ASM_NASM_OBJECT_FORMAT win32)
- endif()
- endif()
- if(NOT REQUIRE_SIMD)
- include(CheckLanguage)
- check_language(ASM_NASM)
- if(NOT CMAKE_ASM_NASM_COMPILER)
- simd_fail("SIMD extensions disabled: could not find NASM compiler")
- return()
- endif()
- endif()
- enable_language(ASM_NASM)
- message(STATUS "CMAKE_ASM_NASM_COMPILER = ${CMAKE_ASM_NASM_COMPILER}")
- if(CMAKE_ASM_NASM_OBJECT_FORMAT MATCHES "macho*")
- set(CMAKE_ASM_NASM_FLAGS "${CMAKE_ASM_NASM_FLAGS} -DMACHO")
- elseif(CMAKE_ASM_NASM_OBJECT_FORMAT MATCHES "elf*")
- set(CMAKE_ASM_NASM_FLAGS "${CMAKE_ASM_NASM_FLAGS} -DELF")
- set(CMAKE_ASM_NASM_DEBUG_FORMAT "dwarf2")
- endif()
- if(CPU_TYPE STREQUAL "x86_64")
- if(WIN32 OR CYGWIN)
- set(CMAKE_ASM_NASM_FLAGS "${CMAKE_ASM_NASM_FLAGS} -DWIN64")
- endif()
- set(CMAKE_ASM_NASM_FLAGS "${CMAKE_ASM_NASM_FLAGS} -D__x86_64__")
- elseif(CPU_TYPE STREQUAL "i386")
- if(BORLAND)
- set(CMAKE_ASM_NASM_FLAGS "${CMAKE_ASM_NASM_FLAGS} -DOBJ32")
- elseif(WIN32 OR CYGWIN)
- set(CMAKE_ASM_NASM_FLAGS "${CMAKE_ASM_NASM_FLAGS} -DWIN32")
- endif()
- endif()
- message(STATUS "CMAKE_ASM_NASM_OBJECT_FORMAT = ${CMAKE_ASM_NASM_OBJECT_FORMAT}")
- if(NOT CMAKE_ASM_NASM_OBJECT_FORMAT)
- simd_fail("SIMD extensions disabled: could not determine NASM object format")
- return()
- endif()
- get_filename_component(CMAKE_ASM_NASM_COMPILER_TYPE
- "${CMAKE_ASM_NASM_COMPILER}" NAME_WE)
- if(CMAKE_ASM_NASM_COMPILER_TYPE MATCHES "yasm")
- foreach(var CMAKE_ASM_NASM_FLAGS_DEBUG CMAKE_ASM_NASM_FLAGS_RELWITHDEBINFO)
- if(${var} STREQUAL "-g")
- if(CMAKE_ASM_NASM_DEBUG_FORMAT)
- set_property(CACHE ${var} PROPERTY VALUE "-g ${CMAKE_ASM_NASM_DEBUG_FORMAT}")
- else()
- set_property(CACHE ${var} PROPERTY VALUE "")
- endif()
- endif()
- endforeach()
- endif()
- if(NOT WIN32 AND (CMAKE_POSITION_INDEPENDENT_CODE OR ENABLE_SHARED))
- set(CMAKE_ASM_NASM_FLAGS "${CMAKE_ASM_NASM_FLAGS} -DPIC")
- endif()
- string(TOUPPER ${CMAKE_BUILD_TYPE} CMAKE_BUILD_TYPE_UC)
- set(EFFECTIVE_ASM_NASM_FLAGS "${CMAKE_ASM_NASM_FLAGS} ${CMAKE_ASM_NASM_FLAGS_${CMAKE_BUILD_TYPE_UC}}")
- message(STATUS "CMAKE_ASM_NASM_FLAGS = ${EFFECTIVE_ASM_NASM_FLAGS}")
- set(CMAKE_ASM_NASM_FLAGS "${CMAKE_ASM_NASM_FLAGS} -I\"${CMAKE_CURRENT_SOURCE_DIR}/nasm/\" -I\"${CMAKE_CURRENT_SOURCE_DIR}/${CPU_TYPE}/\"")
- set(GREP grep)
- if(CMAKE_SYSTEM_NAME STREQUAL "SunOS")
- set(GREP ggrep)
- endif()
- add_custom_target(jsimdcfg COMMAND
- ${CMAKE_C_COMPILER} -E -I${CMAKE_BINARY_DIR} -I${CMAKE_CURRENT_BINARY_DIR}
- -I${CMAKE_CURRENT_SOURCE_DIR}
- ${CMAKE_CURRENT_SOURCE_DIR}/nasm/jsimdcfg.inc.h |
- ${GREP} -E '^[\;%]|^\ %' | sed 's%_cpp_protection_%%' |
- sed 's@% define@%define@g' >${CMAKE_CURRENT_SOURCE_DIR}/nasm/jsimdcfg.inc)
- if(CPU_TYPE STREQUAL "x86_64")
- set(SIMD_SOURCES x86_64/jsimdcpu.asm x86_64/jfdctflt-sse.asm
- x86_64/jccolor-sse2.asm x86_64/jcgray-sse2.asm x86_64/jchuff-sse2.asm
- x86_64/jcphuff-sse2.asm x86_64/jcsample-sse2.asm x86_64/jdcolor-sse2.asm
- x86_64/jdmerge-sse2.asm x86_64/jdsample-sse2.asm x86_64/jfdctfst-sse2.asm
- x86_64/jfdctint-sse2.asm x86_64/jidctflt-sse2.asm x86_64/jidctfst-sse2.asm
- x86_64/jidctint-sse2.asm x86_64/jidctred-sse2.asm x86_64/jquantf-sse2.asm
- x86_64/jquanti-sse2.asm
- x86_64/jccolor-avx2.asm x86_64/jcgray-avx2.asm x86_64/jcsample-avx2.asm
- x86_64/jdcolor-avx2.asm x86_64/jdmerge-avx2.asm x86_64/jdsample-avx2.asm
- x86_64/jfdctint-avx2.asm x86_64/jidctint-avx2.asm x86_64/jquanti-avx2.asm)
- else()
- set(SIMD_SOURCES i386/jsimdcpu.asm i386/jfdctflt-3dn.asm
- i386/jidctflt-3dn.asm i386/jquant-3dn.asm
- i386/jccolor-mmx.asm i386/jcgray-mmx.asm i386/jcsample-mmx.asm
- i386/jdcolor-mmx.asm i386/jdmerge-mmx.asm i386/jdsample-mmx.asm
- i386/jfdctfst-mmx.asm i386/jfdctint-mmx.asm i386/jidctfst-mmx.asm
- i386/jidctint-mmx.asm i386/jidctred-mmx.asm i386/jquant-mmx.asm
- i386/jfdctflt-sse.asm i386/jidctflt-sse.asm i386/jquant-sse.asm
- i386/jccolor-sse2.asm i386/jcgray-sse2.asm i386/jchuff-sse2.asm
- i386/jcphuff-sse2.asm i386/jcsample-sse2.asm i386/jdcolor-sse2.asm
- i386/jdmerge-sse2.asm i386/jdsample-sse2.asm i386/jfdctfst-sse2.asm
- i386/jfdctint-sse2.asm i386/jidctflt-sse2.asm i386/jidctfst-sse2.asm
- i386/jidctint-sse2.asm i386/jidctred-sse2.asm i386/jquantf-sse2.asm
- i386/jquanti-sse2.asm
- i386/jccolor-avx2.asm i386/jcgray-avx2.asm i386/jcsample-avx2.asm
- i386/jdcolor-avx2.asm i386/jdmerge-avx2.asm i386/jdsample-avx2.asm
- i386/jfdctint-avx2.asm i386/jidctint-avx2.asm i386/jquanti-avx2.asm)
- endif()
- if(MSVC_IDE)
- set(OBJDIR "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}")
- string(REGEX REPLACE " " ";" CMAKE_ASM_NASM_FLAGS "${CMAKE_ASM_NASM_FLAGS}")
- elseif(XCODE)
- set(OBJDIR "${CMAKE_CURRENT_BINARY_DIR}")
- string(REGEX REPLACE " " ";" CMAKE_ASM_NASM_FLAGS "${CMAKE_ASM_NASM_FLAGS}")
- endif()
- file(GLOB INC_FILES nasm/*.inc)
- foreach(file ${SIMD_SOURCES})
- set(OBJECT_DEPENDS "")
- if(${file} MATCHES jccolor)
- string(REGEX REPLACE "jccolor" "jccolext" DEPFILE ${file})
- set(OBJECT_DEPENDS ${OBJECT_DEPENDS}
- ${CMAKE_CURRENT_SOURCE_DIR}/${DEPFILE})
- endif()
- if(${file} MATCHES jcgray)
- string(REGEX REPLACE "jcgray" "jcgryext" DEPFILE ${file})
- set(OBJECT_DEPENDS ${OBJECT_DEPENDS}
- ${CMAKE_CURRENT_SOURCE_DIR}/${DEPFILE})
- endif()
- if(${file} MATCHES jdcolor)
- string(REGEX REPLACE "jdcolor" "jdcolext" DEPFILE ${file})
- set(OBJECT_DEPENDS ${OBJECT_DEPENDS}
- ${CMAKE_CURRENT_SOURCE_DIR}/${DEPFILE})
- endif()
- if(${file} MATCHES jdmerge)
- string(REGEX REPLACE "jdmerge" "jdmrgext" DEPFILE ${file})
- set(OBJECT_DEPENDS ${OBJECT_DEPENDS}
- ${CMAKE_CURRENT_SOURCE_DIR}/${DEPFILE})
- endif()
- set(OBJECT_DEPENDS ${OBJECT_DEPENDS} ${INC_FILES})
- if(MSVC_IDE OR XCODE)
- # The CMake Visual Studio generators do not work properly with the ASM_NASM
- # language, so we have to go rogue here and use a custom command like we
- # did in prior versions of libjpeg-turbo. (This is why we can't have nice
- # things.)
- string(REGEX REPLACE "${CPU_TYPE}/" "" filename ${file})
- set(SIMD_OBJ ${OBJDIR}/${filename}${CMAKE_C_OUTPUT_EXTENSION})
- add_custom_command(OUTPUT ${SIMD_OBJ} DEPENDS ${file} ${OBJECT_DEPENDS}
- COMMAND ${CMAKE_ASM_NASM_COMPILER} -f${CMAKE_ASM_NASM_OBJECT_FORMAT}
- ${CMAKE_ASM_NASM_FLAGS} ${CMAKE_CURRENT_SOURCE_DIR}/${file}
- -o${SIMD_OBJ})
- set(SIMD_OBJS ${SIMD_OBJS} ${SIMD_OBJ})
- else()
- set_source_files_properties(${file} PROPERTIES OBJECT_DEPENDS
- "${OBJECT_DEPENDS}")
- endif()
- endforeach()
- if(MSVC_IDE OR XCODE)
- set(SIMD_OBJS ${SIMD_OBJS} PARENT_SCOPE)
- add_library(simd OBJECT ${CPU_TYPE}/jsimd.c)
- add_custom_target(simd-objs DEPENDS ${SIMD_OBJS})
- add_dependencies(simd simd-objs)
- else()
- add_library(simd OBJECT ${SIMD_SOURCES} ${CPU_TYPE}/jsimd.c)
- endif()
- if(NOT WIN32 AND (CMAKE_POSITION_INDEPENDENT_CODE OR ENABLE_SHARED))
- set_target_properties(simd PROPERTIES POSITION_INDEPENDENT_CODE 1)
- endif()
- ###############################################################################
- # ARM (GAS)
- ###############################################################################
- elseif(CPU_TYPE STREQUAL "arm64" OR CPU_TYPE STREQUAL "arm")
- enable_language(ASM)
- set(CMAKE_ASM_FLAGS "${CMAKE_C_FLAGS} ${CMAKE_ASM_FLAGS}")
- string(TOUPPER ${CMAKE_BUILD_TYPE} CMAKE_BUILD_TYPE_UC)
- set(EFFECTIVE_ASM_FLAGS "${CMAKE_ASM_FLAGS} ${CMAKE_ASM_FLAGS_${CMAKE_BUILD_TYPE_UC}}")
- message(STATUS "CMAKE_ASM_FLAGS = ${EFFECTIVE_ASM_FLAGS}")
- # Test whether we need gas-preprocessor.pl
- if(CPU_TYPE STREQUAL "arm")
- file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/gastest.S "
- .text
- .fpu neon
- .arch armv7a
- .object_arch armv4
- .arm
- pld [r0]
- vmovn.u16 d0, q0")
- else()
- file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/gastest.S "
- .text
- MYVAR .req x0
- movi v0.16b, #100
- mov MYVAR, #100
- .unreq MYVAR")
- endif()
- separate_arguments(CMAKE_ASM_FLAGS_SEP UNIX_COMMAND "${CMAKE_ASM_FLAGS}")
- execute_process(COMMAND ${CMAKE_ASM_COMPILER} ${CMAKE_ASM_FLAGS_SEP}
- -x assembler-with-cpp -c ${CMAKE_CURRENT_BINARY_DIR}/gastest.S
- RESULT_VARIABLE RESULT OUTPUT_VARIABLE OUTPUT ERROR_VARIABLE ERROR)
- if(NOT RESULT EQUAL 0)
- message(STATUS "GAS appears to be broken. Trying gas-preprocessor.pl ...")
- execute_process(COMMAND gas-preprocessor.pl ${CMAKE_ASM_COMPILER}
- ${CMAKE_ASM_FLAGS_SEP} -x assembler-with-cpp -c
- ${CMAKE_CURRENT_BINARY_DIR}/gastest.S
- RESULT_VARIABLE RESULT OUTPUT_VARIABLE OUTPUT ERROR_VARIABLE ERROR)
- if(NOT RESULT EQUAL 0)
- simd_fail("SIMD extensions disabled: GAS is not working properly")
- return()
- else()
- message(STATUS "Using gas-preprocessor.pl")
- configure_file(gas-preprocessor.in gas-preprocessor @ONLY)
- set(CMAKE_ASM_COMPILER ${CMAKE_CURRENT_BINARY_DIR}/gas-preprocessor)
- endif()
- else()
- message(STATUS "GAS is working properly")
- endif()
- file(REMOVE ${CMAKE_CURRENT_BINARY_DIR}/gastest.S)
- add_library(simd OBJECT ${CPU_TYPE}/jsimd_neon.S ${CPU_TYPE}/jsimd.c)
- if(CMAKE_POSITION_INDEPENDENT_CODE OR ENABLE_SHARED)
- set_target_properties(simd PROPERTIES POSITION_INDEPENDENT_CODE 1)
- endif()
- ###############################################################################
- # MIPS (GAS)
- ###############################################################################
- elseif(CPU_TYPE STREQUAL "mips" OR CPU_TYPE STREQUAL "mipsel")
- enable_language(ASM)
- string(TOUPPER ${CMAKE_BUILD_TYPE} CMAKE_BUILD_TYPE_UC)
- set(EFFECTIVE_ASM_FLAGS "${CMAKE_ASM_FLAGS} ${CMAKE_ASM_FLAGS_${CMAKE_BUILD_TYPE_UC}}")
- message(STATUS "CMAKE_ASM_FLAGS = ${EFFECTIVE_ASM_FLAGS}")
- set(CMAKE_REQUIRED_FLAGS -mdspr2)
- check_c_source_compiles("
- #if !(defined(__mips__) && __mips_isa_rev >= 2)
- #error MIPS DSPr2 is currently only available on MIPS32r2 platforms.
- #endif
- int main(void) {
- int c = 0, a = 0, b = 0;
- __asm__ __volatile__ (
- \"precr.qb.ph %[c], %[a], %[b]\"
- : [c] \"=r\" (c)
- : [a] \"r\" (a), [b] \"r\" (b)
- );
- return c;
- }" HAVE_DSPR2)
- unset(CMAKE_REQUIRED_FLAGS)
- if(NOT HAVE_DSPR2)
- simd_fail("SIMD extensions not available for this CPU")
- return()
- endif()
- add_library(simd OBJECT mips/jsimd_dspr2.S mips/jsimd.c)
- if(CMAKE_POSITION_INDEPENDENT_CODE OR ENABLE_SHARED)
- set_target_properties(simd PROPERTIES POSITION_INDEPENDENT_CODE 1)
- endif()
- ###############################################################################
- # Loongson (Intrinsics)
- ###############################################################################
- elseif(CPU_TYPE STREQUAL "loongson")
- set(SIMD_SOURCES loongson/jccolor-mmi.c loongson/jcsample-mmi.c
- loongson/jdcolor-mmi.c loongson/jdsample-mmi.c loongson/jfdctint-mmi.c
- loongson/jidctint-mmi.c loongson/jquanti-mmi.c)
- if(CMAKE_COMPILER_IS_GNUCC)
- foreach(file ${SIMD_SOURCES})
- set_property(SOURCE ${file} APPEND_STRING PROPERTY COMPILE_FLAGS
- " -fno-strict-aliasing")
- endforeach()
- endif()
- add_library(simd OBJECT ${SIMD_SOURCES} loongson/jsimd.c)
- if(CMAKE_POSITION_INDEPENDENT_CODE OR ENABLE_SHARED)
- set_target_properties(simd PROPERTIES POSITION_INDEPENDENT_CODE 1)
- endif()
- ###############################################################################
- # PowerPC (Intrinsics)
- ###############################################################################
- elseif(CPU_TYPE STREQUAL "powerpc")
- set(CMAKE_REQUIRED_FLAGS -maltivec)
- check_c_source_compiles("
- #include <altivec.h>
- int main(void) {
- __vector int vi = { 0, 0, 0, 0 };
- int i[4];
- vec_st(vi, 0, i);
- return i[0];
- }" HAVE_ALTIVEC)
- unset(CMAKE_REQUIRED_FLAGS)
- if(NOT HAVE_ALTIVEC)
- simd_fail("SIMD extensions not available for this CPU (PowerPC SPE)")
- return()
- endif()
- set(SIMD_SOURCES powerpc/jccolor-altivec.c powerpc/jcgray-altivec.c
- powerpc/jcsample-altivec.c powerpc/jdcolor-altivec.c
- powerpc/jdmerge-altivec.c powerpc/jdsample-altivec.c
- powerpc/jfdctfst-altivec.c powerpc/jfdctint-altivec.c
- powerpc/jidctfst-altivec.c powerpc/jidctint-altivec.c
- powerpc/jquanti-altivec.c)
- set_source_files_properties(${SIMD_SOURCES} PROPERTIES
- COMPILE_FLAGS -maltivec)
- add_library(simd OBJECT ${SIMD_SOURCES} powerpc/jsimd.c)
- if(CMAKE_POSITION_INDEPENDENT_CODE OR ENABLE_SHARED)
- set_target_properties(simd PROPERTIES POSITION_INDEPENDENT_CODE 1)
- endif()
- ###############################################################################
- # None
- ###############################################################################
- else()
- simd_fail("SIMD extensions not available for this CPU (${CMAKE_SYSTEM_PROCESSOR})")
- endif() # CPU_TYPE
|