diff --git a/CMakeLists.txt b/CMakeLists.txt index 5f728d72..f8f7ae41 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -40,6 +40,7 @@ include (GNUInstallDirs) include (FeatureSummary) include (CMakeDependentOption) include (CTest) +include (CheckCCompilerFlag) # # Options @@ -85,6 +86,18 @@ endif () cmake_dependent_option (ENABLE_COMPATIBLE_LIBSNDFILE_NAME "Set DLL name to libsndfile-1.dll (canonical name), sndfile.dll otherwise" OFF "WIN32;BUILD_SHARED_LIBS" OFF) cmake_dependent_option (INSTALL_MANPAGES "Install man pages for programs" ON "BUILD_PROGRAMS" OFF) +if (NOT MSVC) + if (CPU_IS_X86) + check_c_compiler_flag (-msse2 HAVE_MSSE2_COMPILER_FLAG) + if (HAVE_MSSE2_COMPILER_FLAG) + cmake_dependent_option (ENABLE_SSE2 "Add SSE2 compiler flag" ON "HAVE_MSSE2_COMPILER_FLAG" OFF) + endif () + endif () +endif () +if (ENABLE_SSE2) + add_compile_options (-msse2) +endif () + set (HAVE_EXTERNAL_XIPH_LIBS ${ENABLE_EXTERNAL_LIBS}) set (HAVE_SQLITE3 ${BUILD_REGTEST}) set (HAVE_ALSA_ASOUNDLIB_H ${ALSA_FOUND}) @@ -109,10 +122,13 @@ if (WIN32 AND BUILD_SHARED_LIBS) add_feature_info (ENABLE_COMPATIBLE_LIBSNDFILE_NAME ENABLE_COMPATIBLE_LIBSNDFILE_NAME "Set DLL name to libsndfile-1.dll (canonical name), sndfile.dll otherwise") endif () -if ((MSVC AND (DEFINED ENABLE_STATIC_RUNTIME)) OR MINGW) - add_feature_info (ENABLE_STATIC_RUNTIME ENABLE_STATIC_RUNTIME "Enable static runtime") +if (HAVE_MSSE2_COMPILER_FLAG) + add_feature_info (ENABLE_SSE2 ENABLE_SSE2 "add SSE2 compiler flag") endif () + + + set_package_properties (Ogg PROPERTIES TYPE RECOMMENDED URL "www.xiph.org/ogg/" diff --git a/Makefile.am b/Makefile.am index 5a097caf..0b8bfa14 100644 --- a/Makefile.am +++ b/Makefile.am @@ -22,7 +22,8 @@ cmake_files = cmake/ClipMode.cmake cmake/FindFLAC.cmake \ cmake/FindSpeex.cmake cmake/sqlite/FindSQLite3.cmake \ cmake/SndFileChecks.cmake cmake/TestInline.cmake \ cmake/TestLargeFiles.cmake cmake/TestInline.c.in \ - cmake/FindOpus.cmake cmake/SndFileConfig.cmake.in + cmake/FindOpus.cmake cmake/SndFileConfig.cmake.in \ + cmake/CheckCPUArch.cmake cmake/CheckCPUArch.c.in pkgconfig_DATA = sndfile.pc diff --git a/NEWS b/NEWS index c42d807b..85e715d7 100644 --- a/NEWS +++ b/NEWS @@ -1,7 +1,8 @@ Unreleased * Implement fast SSE2 optimized psf_lrintf() and psf_lrintf() functions to improve perfomance when libsndfile is built using Visual C++ (especially) - and other compilers on x86 and AMD64 platforms. + and other compilers on x86 and AMD64 platforms. See also description of + ENABLE_SSE2 CMake option in README.md. * Documentation: * Move site to new URL: http://libsndfile.github.io/libsndfile/ * Convert documentation pages from HTML to Markdown diff --git a/README.md b/README.md index 60d0463c..61b50e03 100644 --- a/README.md +++ b/README.md @@ -135,7 +135,6 @@ You can pass additional options with `/D=` when you run * `ENABLE_PACKAGE_CONFIG` - generate and install [package config file](https://cmake.org/cmake/help/latest/manual/cmake-packages.7.html#config-file-packages). * `INSTALL_PKGCONFIG_MODULE` - generate and install [pkg-config module](https://people.freedesktop.org/~dbn/pkg-config-guide.html). * `INSTALL_MANPAGES` - install [man pages](https://en.wikipedia.org/wiki/Man_page) for programs. This option is `ON` by default - * `ENABLE_STATIC_RUNTIME` - enable static runtime on Windows platform (MSVC and MinGW), `OFF` by default. @@ -157,6 +156,16 @@ You can pass additional options with `/D=` when you run because you can search library using package manager or CMake's `find_library` command on any platform using the same `sndfile` name. +* `ENABLE_SSE2` - add compiler flag to enable SSE2 if required, `ON` by default. + + This option is for X86 and GCC compatible compilers configurations only. + + If you compile for other SIMD set, e.g. AVX2, you may want to set + `ENABLE_SSE2` to `OFF`. + + **Note**: This option is not active for X64 configuration, because SSE2 is + always available in this mode and all optimizations are enabled by default. + Deprecated options: * `DISABLE_EXTERNAL_LIBS` - disable Ogg, Vorbis and FLAC support. Replaced by diff --git a/cmake/CheckCPUArch.c.in b/cmake/CheckCPUArch.c.in new file mode 100644 index 00000000..54931394 --- /dev/null +++ b/cmake/CheckCPUArch.c.in @@ -0,0 +1,7 @@ +int main(void) { +#if @CHECK_CPU_ARCH_DEFINES@ + return 0; +#else + fail +#endif +} diff --git a/cmake/CheckCPUArch.cmake b/cmake/CheckCPUArch.cmake new file mode 100644 index 00000000..1fdb3c86 --- /dev/null +++ b/cmake/CheckCPUArch.cmake @@ -0,0 +1,23 @@ +macro (_CHECK_CPU_ARCH ARCH ARCH_DEFINES VARIABLE) + if (NOT DEFINED HAVE_${VARIABLE}) + message (STATUS "Check CPU architecture is ${ARCH}") + set (CHECK_CPU_ARCH_DEFINES ${ARCH_DEFINES}) + configure_file (${PROJECT_SOURCE_DIR}/cmake/CheckCPUArch.c.in ${PROJECT_BINARY_DIR}/CMakeFiles/CMakeTmp/CheckCPUArch.c @ONLY) + try_compile (HAVE_${VARIABLE} "${PROJECT_BINARY_DIR}" + "${PROJECT_BINARY_DIR}/CMakeFiles/CMakeTmp/CheckCPUArch.c") + if(HAVE_${VARIABLE}) + message (STATUS "Check CPU architecture is ${ARCH} - yes") + set (${VARIABLE} 1 CACHE INTERNAL "Result of CHECK_CPU_ARCH_X64" FORCE) + else () + message (STATUS "Check CPU architecture is ${ARCH} - no") + endif () + endif () +endmacro (_CHECK_CPU_ARCH) + +macro (CHECK_CPU_ARCH_X64 VARIABLE) + _CHECK_CPU_ARCH (x64 "defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64) || defined(_M_X64) || defined(_M_AMD64)" ${VARIABLE}) +endmacro (CHECK_CPU_ARCH_X64) + +macro (CHECK_CPU_ARCH_X86 VARIABLE) + _CHECK_CPU_ARCH (x86 "defined(__i386__) || defined(__i486__) || defined(__i586__) || defined(__i686__) ||defined( __i386) || defined(_M_IX86)" ${VARIABLE}) +endmacro (CHECK_CPU_ARCH_X86) diff --git a/cmake/SndFileChecks.cmake b/cmake/SndFileChecks.cmake index b7c6a41f..e5caf01e 100644 --- a/cmake/SndFileChecks.cmake +++ b/cmake/SndFileChecks.cmake @@ -7,7 +7,8 @@ include (TestBigEndian) include (TestInline) include (ClipMode) -include(TestLargeFiles) +include (TestLargeFiles) +include (CheckCPUArch) test_large_files (_LARGEFILES) @@ -69,6 +70,12 @@ check_include_file (sys/types.h HAVE_SYS_TYPES_H) check_include_file (unistd.h HAVE_UNISTD_H) check_include_file (immintrin.h HAVE_IMMINTRIN_H) +check_cpu_arch_x86 (CPU_IS_X86) +check_cpu_arch_x64 (CPU_IS_X64) +if ((CPU_IS_X86 OR CPU_IS_X64) AND HAVE_IMMINTRIN_H) + set (HAVE_SSE2 1) +endif () + # Never checked # check_include_file (stdlib.h HAVE_STDLIB_H) # check_include_file (string.h HAVE_STRING_H) diff --git a/src/config.h.cmake b/src/config.h.cmake index 03e4f425..c33bcbc8 100644 --- a/src/config.h.cmake +++ b/src/config.h.cmake @@ -193,6 +193,9 @@ /* Set to 1 if compiling for Win32 */ #cmakedefine01 OS_IS_WIN32 +/* Set to 1 if SSE2 is enabled */ +#cmakedefine USE_SSE2 + /* Name of package */ #define PACKAGE "@PACKAGE_NAME@" diff --git a/src/sfconfig.h b/src/sfconfig.h index edb5a820..d70f405b 100644 --- a/src/sfconfig.h +++ b/src/sfconfig.h @@ -124,7 +124,7 @@ #define CPU_IS_X86_64 0 #endif -#if CPU_IS_X86 && HAVE_IMMINTRIN_H +#if (defined (__SSE2__) || defined (_M_AMD64) || (defined (_M_IX86_FP) && (_M_IX86_FP >= 2)) && HAVE_IMMINTRIN_H) #define USE_SSE2 #endif