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
#include "Config.h"
#include "SIMDConfig.h"
#include <benchmark/benchmark.h>
#include <absl/types/span.h>
#include <random>
#include <algorithm>
#if HAVE_X86INTRIN_H
#include <x86intrin.h>
#endif
#if HAVE_INTRIN_H
#include <intrin.h>
#if SFIZZ_HAVE_SSE2
#include <emmintrin.h>
#endif
constexpr float filterGain { 0.25f };

View file

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

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.
// 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<float, true>(absl::Span<const float> input, absl::Span<float> out
{
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
// 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 <arm_neon.h>
using Type = float;
[[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);
}
#endif // SFIZZ_HAVE_NEON

View file

@ -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 <array>
#include <xmmintrin.h>
#if HAVE_X86INTRIN_H
#include <x86intrin.h>
#endif
#if HAVE_INTRIN_H
#include <intrin.h>
#endif
#include <emmintrin.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)
_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
#include "ScopedFTZ.h"
#if (HAVE_X86INTRIN_H)
#include <x86intrin.h>
#elif (HAVE_INTRIN_H)
#include <intrin.h>
#elif (HAVE_ARM_NEON_H)
#include "SIMDConfig.h"
#if SFIZZ_HAVE_SSE
#include <pmmintrin.h> // 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
}