diff --git a/benchmarks/BM_OPF_high_vs_low.cpp b/benchmarks/BM_OPF_high_vs_low.cpp index 545bf801..db9585bb 100644 --- a/benchmarks/BM_OPF_high_vs_low.cpp +++ b/benchmarks/BM_OPF_high_vs_low.cpp @@ -5,17 +5,14 @@ // If not, contact the sfizz maintainers at https://github.com/sfztools/sfizz #include "Config.h" +#include "SIMDConfig.h" #include #include #include #include -#if HAVE_X86INTRIN_H -#include -#endif - -#if HAVE_INTRIN_H -#include +#if SFIZZ_HAVE_SSE2 +#include #endif constexpr float filterGain { 0.25f }; diff --git a/cmake/SfizzSIMDSourceFilesCheck.cmake b/cmake/SfizzSIMDSourceFilesCheck.cmake index 94eb80fb..c8dc925d 100644 --- a/cmake/SfizzSIMDSourceFilesCheck.cmake +++ b/cmake/SfizzSIMDSourceFilesCheck.cmake @@ -1,31 +1,14 @@ -# Check SIMD -include (CheckIncludeFiles) -CHECK_INCLUDE_FILES(x86intrin.h HAVE_X86INTRIN_H) -CHECK_INCLUDE_FILES(intrin.h HAVE_INTRIN_H) - -if (!APPLE) -CHECK_INCLUDE_FILES (arm_neon.h HAVE_ARM_NEON_H) -endif() +set (SFIZZ_SIMD_SOURCES + sfizz/SIMDSSE.cpp + sfizz/SIMDNEON.cpp + sfizz/SIMDDummy.cpp) # SIMD checks -if (HAVE_X86INTRIN_H AND UNIX) - add_compile_options (-DHAVE_X86INTRIN_H) - set (SFIZZ_SIMD_SOURCES sfizz/SIMDSSE.cpp) -elseif (HAVE_INTRIN_H AND WIN32) - if (CMAKE_CXX_COMPILER_ID MATCHES "MSVC") - add_compile_options ("/DHAVE_INTRIN_H") - else() - add_compile_options ("-DHAVE_INTRIN_H") - endif() - set (SFIZZ_SIMD_SOURCES sfizz/SIMDSSE.cpp) -elseif (CMAKE_SYSTEM_PROCESSOR STREQUAL "armv7l") +if (CMAKE_SYSTEM_PROCESSOR STREQUAL "armv7l") add_compile_options (-DHAVE_ARM_NEON_H) add_compile_options (-mfpu=neon) add_compile_options (-march=native) add_compile_options (-mtune=cortex-a53) - set (SFIZZ_SIMD_SOURCES sfizz/SIMDNEON.cpp) -else() - set (SFIZZ_SIMD_SOURCES sfizz/SIMDDummy.cpp) endif() set (SFIZZ_SOURCES ${SFIZZ_SOURCES} ${SFIZZ_SIMD_SOURCES}) diff --git a/src/sfizz/SIMDConfig.h b/src/sfizz/SIMDConfig.h new file mode 100644 index 00000000..8b7f427f --- /dev/null +++ b/src/sfizz/SIMDConfig.h @@ -0,0 +1,69 @@ +// SPDX-License-Identifier: BSD-2-Clause + +// This code is part of the sfizz library and is licensed under a BSD 2-clause +// license. You should have receive a LICENSE.md file along with the code. +// If not, contact the sfizz maintainers at https://github.com/sfztools/sfizz + +#pragma once + +/** + Define the following macros, 1 if available, otherwise 0. + These are allowed to be defined externally, in case automatic detection would + fail based on the compiler predefinitions. + + - SFIZZ_HAVE_SSE + - SFIZZ_HAVE_SSE2 + - SFIZZ_HAVE_NEON + */ + +#if defined(__GNUC__) +# if defined(__SSE2__) +# define SFIZZ_DETECT_SSE 1 +# define SFIZZ_DETECT_SSE2 1 +# elif defined(__SSE__) +# define SFIZZ_DETECT_SSE 1 +# define SFIZZ_DETECT_SSE2 0 +# else +# define SFIZZ_DETECT_SSE 0 +# define SFIZZ_DETECT_SSE2 0 +# endif +# if defined(__ARM_NEON__) +# define SFIZZ_DETECT_NEON 1 +# else +# define SFIZZ_DETECT_NEON 0 +# endif +#elif defined(_MSC_VER) +# if defined(_M_AMD64) || defined(_M_X64) +# define SFIZZ_DETECT_SSE 1 +# define SFIZZ_DETECT_SSE2 1 +# elif _M_IX86_FP == 2 +# define SFIZZ_DETECT_SSE 1 +# define SFIZZ_DETECT_SSE2 1 +# elif _M_IX86_FP == 1 +# define SFIZZ_DETECT_SSE 1 +# define SFIZZ_DETECT_SSE2 0 +# endif +// TODO: how to check for NEON on MSVC ARM? +#endif + +#ifndef SFIZZ_HAVE_SSE +# ifdef SFIZZ_DETECT_SSE +# define SFIZZ_HAVE_SSE SFIZZ_DETECT_SSE +# else +# define SFIZZ_HAVE_SSE 0 +# endif +#endif +#ifndef SFIZZ_HAVE_SSE2 +# ifdef SFIZZ_DETECT_SSE2 +# define SFIZZ_HAVE_SSE2 SFIZZ_DETECT_SSE2 +# else +# define SFIZZ_HAVE_SSE2 0 +# endif +#endif +#ifndef SFIZZ_HAVE_NEON +# ifdef SFIZZ_DETECT_NEON +# define SFIZZ_HAVE_NEON SFIZZ_DETECT_NEON +# else +# define SFIZZ_HAVE_NEON 0 +# endif +#endif diff --git a/src/sfizz/SIMDDummy.cpp b/src/sfizz/SIMDDummy.cpp index b4300042..22a1140b 100644 --- a/src/sfizz/SIMDDummy.cpp +++ b/src/sfizz/SIMDDummy.cpp @@ -4,6 +4,10 @@ // license. You should have receive a LICENSE.md file along with the code. // If not, contact the sfizz maintainers at https://github.com/sfztools/sfizz +#include "SIMDConfig.h" + +#if !(SFIZZ_HAVE_SSE2 || SFIZZ_HAVE_NEON) + #include "SIMDHelpers.h" template <> @@ -163,3 +167,5 @@ void sfz::diff(absl::Span input, absl::Span out { diff(input, output); } + +#endif // !(SFIZZ_HAVE_SSE2 || SFIZZ_HAVE_NEON) diff --git a/src/sfizz/SIMDNEON.cpp b/src/sfizz/SIMDNEON.cpp index c3321944..eb79cf7f 100644 --- a/src/sfizz/SIMDNEON.cpp +++ b/src/sfizz/SIMDNEON.cpp @@ -21,8 +21,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#include +#include "SIMDConfig.h" + +#if SFIZZ_HAVE_NEON + #include "SIMDHelpers.h" +#include using Type = float; [[maybe_unused]] constexpr uintptr_t TypeAlignment { 4 }; @@ -234,3 +238,5 @@ void sfz::diff(absl::Span input, absl::Span out { diff(input, output); } + +#endif // SFIZZ_HAVE_NEON diff --git a/src/sfizz/SIMDSSE.cpp b/src/sfizz/SIMDSSE.cpp index 0f4399c4..8b541657 100644 --- a/src/sfizz/SIMDSSE.cpp +++ b/src/sfizz/SIMDSSE.cpp @@ -4,16 +4,14 @@ // license. You should have receive a LICENSE.md file along with the code. // If not, contact the sfizz maintainers at https://github.com/sfztools/sfizz +#include "SIMDConfig.h" + +#if SFIZZ_HAVE_SSE2 + #include "SIMDHelpers.h" #include #include -#if HAVE_X86INTRIN_H -#include -#endif - -#if HAVE_INTRIN_H -#include -#endif +#include #include "mathfuns/sse_mathfun.h" @@ -783,3 +781,5 @@ void sfz::diff(absl::Span input, absl::Span out while (in < sentinel) _internals::snippetDiff(in, out); } + +#endif // SFIZZ_HAVE_SSE2 diff --git a/src/sfizz/ScopedFTZ.cpp b/src/sfizz/ScopedFTZ.cpp index 1b0d5c03..1f5b1c58 100644 --- a/src/sfizz/ScopedFTZ.cpp +++ b/src/sfizz/ScopedFTZ.cpp @@ -5,22 +5,21 @@ // If not, contact the sfizz maintainers at https://github.com/sfztools/sfizz #include "ScopedFTZ.h" -#if (HAVE_X86INTRIN_H) -#include -#elif (HAVE_INTRIN_H) -#include -#elif (HAVE_ARM_NEON_H) +#include "SIMDConfig.h" +#if SFIZZ_HAVE_SSE +#include // x86 CSR is SSE, but FTZ bits SSE3 and up +#elif SFIZZ_HAVE_NEON #include "arm_neon.h" #endif ScopedFTZ::ScopedFTZ() { -#if (HAVE_X86INTRIN_H || HAVE_INTRIN_H) +#if SFIZZ_HAVE_SSE unsigned mask = _MM_DENORMALS_ZERO_MASK | _MM_FLUSH_ZERO_MASK; registerState = _mm_getcsr(); _mm_setcsr((registerState & (~mask)) | mask); -#elif HAVE_ARM_NEON_H +#elif SFIZZ_HAVE_NEON intptr_t mask = (1 << 24); asm volatile("vmrs %0, fpscr" : "=r"(registerState)); asm volatile("vmsr fpscr, %0" : : "ri"((registerState & (~mask)) | mask)); @@ -29,9 +28,9 @@ ScopedFTZ::ScopedFTZ() ScopedFTZ::~ScopedFTZ() { -#if (HAVE_X86INTRIN_H || HAVE_INTRIN_H) +#if SFIZZ_HAVE_SSE _mm_setcsr(registerState); -#elif HAVE_ARM_NEON_H +#elif SFIZZ_HAVE_NEON asm volatile("vmrs %0, fpscr" : : "ri"(registerState)); #endif }