Detect SIMD availability from compiler

This commit is contained in:
Jean Pierre Cimalando 2020-02-09 14:58:21 +01:00
parent 8f49b5c78e
commit afbe8c7e48
7 changed files with 105 additions and 45 deletions

View file

@ -5,17 +5,14 @@
// If not, contact the sfizz maintainers at https://github.com/sfztools/sfizz // If not, contact the sfizz maintainers at https://github.com/sfztools/sfizz
#include "Config.h" #include "Config.h"
#include "SIMDConfig.h"
#include <benchmark/benchmark.h> #include <benchmark/benchmark.h>
#include <absl/types/span.h> #include <absl/types/span.h>
#include <random> #include <random>
#include <algorithm> #include <algorithm>
#if HAVE_X86INTRIN_H #if SFIZZ_HAVE_SSE2
#include <x86intrin.h> #include <emmintrin.h>
#endif
#if HAVE_INTRIN_H
#include <intrin.h>
#endif #endif
constexpr float filterGain { 0.25f }; constexpr float filterGain { 0.25f };

View file

@ -1,31 +1,14 @@
# Check SIMD set (SFIZZ_SIMD_SOURCES
include (CheckIncludeFiles) sfizz/SIMDSSE.cpp
CHECK_INCLUDE_FILES(x86intrin.h HAVE_X86INTRIN_H) sfizz/SIMDNEON.cpp
CHECK_INCLUDE_FILES(intrin.h HAVE_INTRIN_H) sfizz/SIMDDummy.cpp)
if (!APPLE)
CHECK_INCLUDE_FILES (arm_neon.h HAVE_ARM_NEON_H)
endif()
# SIMD checks # SIMD checks
if (HAVE_X86INTRIN_H AND UNIX) if (CMAKE_SYSTEM_PROCESSOR STREQUAL "armv7l")
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")
add_compile_options (-DHAVE_ARM_NEON_H) add_compile_options (-DHAVE_ARM_NEON_H)
add_compile_options (-mfpu=neon) add_compile_options (-mfpu=neon)
add_compile_options (-march=native) add_compile_options (-march=native)
add_compile_options (-mtune=cortex-a53) add_compile_options (-mtune=cortex-a53)
set (SFIZZ_SIMD_SOURCES sfizz/SIMDNEON.cpp)
else()
set (SFIZZ_SIMD_SOURCES sfizz/SIMDDummy.cpp)
endif() endif()
set (SFIZZ_SOURCES ${SFIZZ_SOURCES} ${SFIZZ_SIMD_SOURCES}) set (SFIZZ_SOURCES ${SFIZZ_SOURCES} ${SFIZZ_SIMD_SOURCES})

69
src/sfizz/SIMDConfig.h Normal file
View file

@ -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

View file

@ -4,6 +4,10 @@
// license. You should have receive a LICENSE.md file along with the code. // 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 // 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" #include "SIMDHelpers.h"
template <> template <>
@ -163,3 +167,5 @@ void sfz::diff<float, true>(absl::Span<const float> input, absl::Span<float> out
{ {
diff<float, false>(input, output); diff<float, false>(input, output);
} }
#endif // !(SFIZZ_HAVE_SSE2 || SFIZZ_HAVE_NEON)

View file

@ -21,8 +21,12 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <arm_neon.h> #include "SIMDConfig.h"
#if SFIZZ_HAVE_NEON
#include "SIMDHelpers.h" #include "SIMDHelpers.h"
#include <arm_neon.h>
using Type = float; using Type = float;
[[maybe_unused]] constexpr uintptr_t TypeAlignment { 4 }; [[maybe_unused]] constexpr uintptr_t TypeAlignment { 4 };
@ -234,3 +238,5 @@ void sfz::diff<float, true>(absl::Span<const float> input, absl::Span<float> out
{ {
diff<float, false>(input, output); diff<float, false>(input, output);
} }
#endif // SFIZZ_HAVE_NEON

View file

@ -4,16 +4,14 @@
// license. You should have receive a LICENSE.md file along with the code. // 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 // If not, contact the sfizz maintainers at https://github.com/sfztools/sfizz
#include "SIMDConfig.h"
#if SFIZZ_HAVE_SSE2
#include "SIMDHelpers.h" #include "SIMDHelpers.h"
#include <array> #include <array>
#include <xmmintrin.h> #include <xmmintrin.h>
#if HAVE_X86INTRIN_H #include <emmintrin.h>
#include <x86intrin.h>
#endif
#if HAVE_INTRIN_H
#include <intrin.h>
#endif
#include "mathfuns/sse_mathfun.h" #include "mathfuns/sse_mathfun.h"
@ -783,3 +781,5 @@ void sfz::diff<float, true>(absl::Span<const float> input, absl::Span<float> out
while (in < sentinel) while (in < sentinel)
_internals::snippetDiff(in, out); _internals::snippetDiff(in, out);
} }
#endif // SFIZZ_HAVE_SSE2

View file

@ -5,22 +5,21 @@
// If not, contact the sfizz maintainers at https://github.com/sfztools/sfizz // If not, contact the sfizz maintainers at https://github.com/sfztools/sfizz
#include "ScopedFTZ.h" #include "ScopedFTZ.h"
#if (HAVE_X86INTRIN_H) #include "SIMDConfig.h"
#include <x86intrin.h> #if SFIZZ_HAVE_SSE
#elif (HAVE_INTRIN_H) #include <pmmintrin.h> // x86 CSR is SSE, but FTZ bits SSE3 and up
#include <intrin.h> #elif SFIZZ_HAVE_NEON
#elif (HAVE_ARM_NEON_H)
#include "arm_neon.h" #include "arm_neon.h"
#endif #endif
ScopedFTZ::ScopedFTZ() ScopedFTZ::ScopedFTZ()
{ {
#if (HAVE_X86INTRIN_H || HAVE_INTRIN_H) #if SFIZZ_HAVE_SSE
unsigned mask = _MM_DENORMALS_ZERO_MASK | _MM_FLUSH_ZERO_MASK; unsigned mask = _MM_DENORMALS_ZERO_MASK | _MM_FLUSH_ZERO_MASK;
registerState = _mm_getcsr(); registerState = _mm_getcsr();
_mm_setcsr((registerState & (~mask)) | mask); _mm_setcsr((registerState & (~mask)) | mask);
#elif HAVE_ARM_NEON_H #elif SFIZZ_HAVE_NEON
intptr_t mask = (1 << 24); intptr_t mask = (1 << 24);
asm volatile("vmrs %0, fpscr" : "=r"(registerState)); asm volatile("vmrs %0, fpscr" : "=r"(registerState));
asm volatile("vmsr fpscr, %0" : : "ri"((registerState & (~mask)) | mask)); asm volatile("vmsr fpscr, %0" : : "ri"((registerState & (~mask)) | mask));
@ -29,9 +28,9 @@ ScopedFTZ::ScopedFTZ()
ScopedFTZ::~ScopedFTZ() ScopedFTZ::~ScopedFTZ()
{ {
#if (HAVE_X86INTRIN_H || HAVE_INTRIN_H) #if SFIZZ_HAVE_SSE
_mm_setcsr(registerState); _mm_setcsr(registerState);
#elif HAVE_ARM_NEON_H #elif SFIZZ_HAVE_NEON
asm volatile("vmrs %0, fpscr" : : "ri"(registerState)); asm volatile("vmrs %0, fpscr" : : "ri"(registerState));
#endif #endif
} }