if(MSVC_IDE)
set(OBJDIR "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}")
-else()
- set(OBJDIR ${CMAKE_CURRENT_BINARY_DIR})
+ string(REGEX REPLACE " " ";" CMAKE_ASM_NASM_FLAGS "${CMAKE_ASM_NASM_FLAGS}")
endif()
-file(GLOB INC_FILES *.inc)
+file(GLOB INC_FILES nasm/*.inc)
-foreach(file ${SIMD_BASENAMES})
- set(DEPFILE "")
- set(SIMD_SRC ${CMAKE_CURRENT_SOURCE_DIR}/${file}.asm)
+foreach(file ${SIMD_SOURCES})
+ set(OBJECT_DEPENDS "")
if(${file} MATCHES jccolor)
- set(DEPFILE ${file})
- string(REGEX REPLACE "jccolor" "jccolext" DEPFILE ${DEPFILE})
- set(DEPFILE ${CMAKE_CURRENT_SOURCE_DIR}/${DEPFILE}.asm)
+ string(REGEX REPLACE "jccolor" "jccolext" DEPFILE ${file})
+ set(OBJECT_DEPENDS ${OBJECT_DEPENDS}
+ ${CMAKE_CURRENT_SOURCE_DIR}/${DEPFILE})
endif()
if(${file} MATCHES jcgray)
- set(DEPFILE ${file})
- string(REGEX REPLACE "jcgray" "jcgryext" DEPFILE ${DEPFILE})
- set(DEPFILE ${CMAKE_CURRENT_SOURCE_DIR}/${DEPFILE}.asm)
+ string(REGEX REPLACE "jcgray" "jcgryext" DEPFILE ${file})
+ set(OBJECT_DEPENDS ${OBJECT_DEPENDS}
+ ${CMAKE_CURRENT_SOURCE_DIR}/${DEPFILE})
endif()
if(${file} MATCHES jdcolor)
- set(DEPFILE ${file})
- string(REGEX REPLACE "jdcolor" "jdcolext" DEPFILE ${DEPFILE})
- set(DEPFILE ${CMAKE_CURRENT_SOURCE_DIR}/${DEPFILE}.asm)
+ string(REGEX REPLACE "jdcolor" "jdcolext" DEPFILE ${file})
+ set(OBJECT_DEPENDS ${OBJECT_DEPENDS}
+ ${CMAKE_CURRENT_SOURCE_DIR}/${DEPFILE})
endif()
if(${file} MATCHES jdmerge)
- set(DEPFILE ${file})
- string(REGEX REPLACE "jdmerge" "jdmrgext" DEPFILE ${DEPFILE})
- set(DEPFILE ${CMAKE_CURRENT_SOURCE_DIR}/${DEPFILE}.asm)
+ 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} ${JSIMDCFG_INC})
+ if(MSVC_IDE)
+ # 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}.obj)
+ 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()
- set(SIMD_OBJ ${OBJDIR}/${file}.obj)
- add_custom_command(OUTPUT ${SIMD_OBJ}
- DEPENDS ${SIMD_SRC} ${DEPFILE} ${INC_FILES}
- COMMAND ${NASM} ${NAFLAGS} ${SIMD_SRC} -o${SIMD_OBJ})
- set(SIMD_OBJS ${SIMD_OBJS} ${SIMD_OBJ})
endforeach()
-set(SIMD_OBJS ${SIMD_OBJS} PARENT_SCOPE)
-add_custom_target(simd DEPENDS ${SIMD_OBJS})
+if(MSVC_IDE)
+ 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")
+
+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}")
+
+add_library(simd OBJECT ${CPU_TYPE}/jsimd_dspr2.S ${CPU_TYPE}/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 };
- return vi[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