diff --git a/cmake/SfizzSIMDSourceFiles.cmake b/cmake/SfizzSIMDSourceFiles.cmake index 962d0fb0..edca20e6 100644 --- a/cmake/SfizzSIMDSourceFiles.cmake +++ b/cmake/SfizzSIMDSourceFiles.cmake @@ -2,10 +2,7 @@ macro(sfizz_add_simd_sources SOURCES_VAR PREFIX) # It needs a macro, otherwise the source properties cannot take effect. list (APPEND ${SOURCES_VAR} - ${PREFIX}/sfizz/SIMDSSE.cpp - ${PREFIX}/sfizz/SIMDHelpers.cpp - ${PREFIX}/sfizz/SIMDNEON.cpp - ${PREFIX}/sfizz/SIMDDummy.cpp) + ${PREFIX}/sfizz/SIMDHelpers.cpp) # For CPU-dispatched X86 sources # Always build them for all X86 targets. diff --git a/dpf.mk b/dpf.mk index a2734283..e9bfb051 100644 --- a/dpf.mk +++ b/dpf.mk @@ -96,9 +96,7 @@ SFIZZ_SOURCES = \ src/sfizz/sfizz_wrapper.cpp \ src/sfizz/SfzFilter.cpp \ src/sfizz/SfzHelpers.cpp \ - src/sfizz/SIMDDummy.cpp \ - src/sfizz/SIMDNEON.cpp \ - src/sfizz/SIMDSSE.cpp \ + src/sfizz/SIMDHelpers.cpp \ src/sfizz/Synth.cpp \ src/sfizz/Tuning.cpp \ src/sfizz/Voice.cpp \ diff --git a/scripts/run_clang_tidy.sh b/scripts/run_clang_tidy.sh index 6c1f6f8a..370171df 100755 --- a/scripts/run_clang_tidy.sh +++ b/scripts/run_clang_tidy.sh @@ -17,7 +17,7 @@ clang-tidy \ src/sfizz/sfizz.cpp \ src/sfizz/Region.cpp \ src/sfizz/SfzHelpers.cpp \ - src/sfizz/SIMDSSE.cpp \ + src/sfizz/SIMDHelpers.cpp \ src/sfizz/Synth.cpp \ src/sfizz/Voice.cpp \ src/sfizz/effects/Eq.cpp \ diff --git a/src/sfizz/SIMDDummy.cpp b/src/sfizz/SIMDDummy.cpp deleted file mode 100644 index 718d8a1c..00000000 --- a/src/sfizz/SIMDDummy.cpp +++ /dev/null @@ -1,177 +0,0 @@ -// 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 - -#include "SIMDConfig.h" - -#if !(SFIZZ_HAVE_SSE2 || SFIZZ_HAVE_NEON) - -#include "SIMDHelpers.h" - -template <> -void sfz::readInterleaved(absl::Span input, absl::Span outputLeft, absl::Span outputRight) noexcept -{ - readInterleaved(input, outputLeft, outputRight); -} - -template <> -void sfz::writeInterleaved(absl::Span inputLeft, absl::Span inputRight, absl::Span output) noexcept -{ - writeInterleaved(inputLeft, inputRight, output); -} - -template <> -void sfz::fill(absl::Span output, float value) noexcept -{ - fill(output, value); -} - -template <> -void sfz::exp(absl::Span input, absl::Span output) noexcept -{ - exp(input, output); -} - -template <> -void sfz::log(absl::Span input, absl::Span output) noexcept -{ - log(input, output); -} - -template <> -void sfz::sin(absl::Span input, absl::Span output) noexcept -{ - sin(input, output); -} - -template <> -void sfz::cos(absl::Span input, absl::Span output) noexcept -{ - cos(input, output); -} - -template <> -void sfz::applyGain(float gain, absl::Span input, absl::Span output) noexcept -{ - applyGain(gain, input, output); -} - -template <> -void sfz::applyGain(absl::Span gain, absl::Span input, absl::Span output) noexcept -{ - applyGain(gain, input, output); -} - -template <> -void sfz::divide(absl::Span input, absl::Span divisor, absl::Span output) noexcept -{ - divide(input, divisor, output); -} - -template <> -void sfz::multiplyAdd(absl::Span gain, absl::Span input, absl::Span output) noexcept -{ - multiplyAdd(gain, input, output); -} - -template <> -void sfz::multiplyAdd(const float gain, absl::Span input, absl::Span output) noexcept -{ - multiplyAdd(gain, input, output); -} - -template <> -float sfz::loopingSFZIndex(absl::Span jumps, absl::Span leftCoeff, absl::Span rightCoeff, absl::Span indices, float floatIndex, float loopEnd, float loopStart) noexcept -{ - return loopingSFZIndex(jumps, leftCoeff, rightCoeff, indices, floatIndex, loopEnd, loopStart); -} - -template <> -float sfz::saturatingSFZIndex(absl::Span jumps, absl::Span leftCoeff, absl::Span rightCoeff, absl::Span indices, float floatIndex, float loopEnd) noexcept -{ - return saturatingSFZIndex(jumps, leftCoeff, rightCoeff, indices, floatIndex, loopEnd); -} - - -template <> -float sfz::linearRamp(absl::Span output, float start, float step) noexcept -{ - return linearRamp(output, start, step); -} - -template <> -float sfz::multiplicativeRamp(absl::Span output, float start, float step) noexcept -{ - return multiplicativeRamp(output, start, step); -} - -template <> -void sfz::add(absl::Span input, absl::Span output) noexcept -{ - add(input, output); -} - -template <> -void sfz::add(float value, absl::Span output) noexcept -{ - add(value, output); -} - -template <> -void sfz::subtract(absl::Span input, absl::Span output) noexcept -{ - subtract(input, output); -} - -template <> -void sfz::subtract(const float value, absl::Span output) noexcept -{ - subtract(value, output); -} - - -template <> -void sfz::copy(absl::Span input, absl::Span output) noexcept -{ - copy(input, output); -} - -template <> -void sfz::pan(absl::Span panEnvelope, absl::Span leftBuffer, absl::Span rightBuffer) noexcept -{ - pan(panEnvelope, leftBuffer, rightBuffer); -} - -template <> -float sfz::mean(absl::Span vector) noexcept -{ - return mean(vector); -} - -template <> -float sfz::meanSquared(absl::Span vector) noexcept -{ - return meanSquared(vector); -} - -template <> -void sfz::cumsum(absl::Span input, absl::Span output) noexcept -{ - cumsum(input, output); -} - -template<> -void sfz::sfzInterpolationCast(absl::Span floatJumps, absl::Span jumps, absl::Span coeffs) noexcept -{ - sfzInterpolationCast(floatJumps, jumps, coeffs); -} - -template <> -void sfz::diff(absl::Span input, absl::Span output) noexcept -{ - diff(input, output); -} - -#endif // !(SFIZZ_HAVE_SSE2 || SFIZZ_HAVE_NEON) diff --git a/src/sfizz/SIMDHelpers.cpp b/src/sfizz/SIMDHelpers.cpp index da87bc8e..5fd4d226 100644 --- a/src/sfizz/SIMDHelpers.cpp +++ b/src/sfizz/SIMDHelpers.cpp @@ -9,6 +9,10 @@ #include #endif +#if SFIZZ_HAVE_NEON +#include +#endif + namespace sfz { static std::array(SIMDOps::_sentinel)> simdStatus; @@ -100,6 +104,12 @@ void readInterleaved(const float* input, float* outputLeft, float* outputRight, // Fallthrough from lastAligned to sentinel } #endif + +#if 0 // NEON wip + auto reg = vld2q_f32(in); + vst1q_f32(lOut, reg.val[0]); + vst1q_f32(rOut, reg.val[1]); +#endif } while (input < sentinel) diff --git a/src/sfizz/SIMDHelpers.h b/src/sfizz/SIMDHelpers.h index 5d3fea02..acc2c526 100644 --- a/src/sfizz/SIMDHelpers.h +++ b/src/sfizz/SIMDHelpers.h @@ -12,16 +12,8 @@ * These functions are templated to apply on * various underlying buffer types, and this file contains the generic version of the * function. Some templates specializations exists for different architecture that try - * to make use of SIMD intrinsics; you can find such a file in SIMDSSE.cpp and possibly - * someday SIMDNEON.cpp for ARM platforms. - * - * If you want to write specializations for float buffers the idea is to start from the SIMDDummy - * file that just calls back the generic implementation, and implement the specializations you - * wish from this list. You can then either activate or deactivate a SIMD version by default - * using the variables in Config.h, or call e.g. writeInterleaved(...) to use the - * SIMD version of writeInterleaved. To implement e.g. double template specializations you - * will need to amend this file to pre-declare the specializations, and create a file similar to - * SIMDxxx.cpp. + * to make use of SIMD intrinsics in SIMDHelpers.cpp. A runtime dispatch can help if you + * write implementation for larger/newer SIMD operations. * * All the SIMD functions are benchmarked. If you run the benchmark for a given function you can check * if it is interesting to run the SIMD version by default. The interest is that you can activate diff --git a/src/sfizz/SIMDNEON.cpp b/src/sfizz/SIMDNEON.cpp deleted file mode 100644 index e229d954..00000000 --- a/src/sfizz/SIMDNEON.cpp +++ /dev/null @@ -1,241 +0,0 @@ -// Copyright (c) 2019, Paul Ferrand -// All rights reserved. - -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: - -// 1. Redistributions of source code must retain the above copyright notice, this -// list of conditions and the following disclaimer. -// 2. Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. - -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (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 "SIMDConfig.h" - -#if SFIZZ_HAVE_NEON - -#include "SIMDHelpers.h" -#include - -using Type = float; -constexpr uintptr_t TypeAlignment { 4 }; -constexpr uintptr_t ByteAlignment { TypeAlignment * sizeof(Type) }; -constexpr uintptr_t ByteAlignmentMask { ByteAlignment - 1 }; - -float* nextAligned(const float* ptr) -{ - return reinterpret_cast((reinterpret_cast(ptr) + ByteAlignmentMask) & (~ByteAlignmentMask)); -} - -float* prevAligned(const float* ptr) -{ - return reinterpret_cast(reinterpret_cast(ptr) & (~ByteAlignmentMask)); -} - -bool unaligned(const float* ptr) -{ - return (reinterpret_cast(ptr) & ByteAlignmentMask) != 0; -} - -template -bool unaligned(const float* ptr1, Args... rest) -{ - return unaligned(ptr1) || unaligned(rest...); -} - -template <> -void sfz::readInterleaved(absl::Span input, absl::Span outputLeft, absl::Span outputRight) noexcept -{ - // The size of the outputs is not big enough for the input... - ASSERT(outputLeft.size() >= input.size() / 2); - ASSERT(outputRight.size() >= input.size() / 2); - // Input is too small - ASSERT(input.size() > 1); - - auto* in = input.begin(); - auto* lOut = outputLeft.begin(); - auto* rOut = outputRight.begin(); - - const auto size = std::min(input.size(), std::min(outputLeft.size() * 2, outputRight.size() * 2)); - const auto* lastAligned = prevAligned(input.begin() + size - TypeAlignment); - - while (unaligned(in, lOut, rOut) && in < lastAligned) - _internals::snippetRead(in, lOut, rOut); - - while (in < lastAligned) { - auto reg = vld2q_f32(in); - vst1q_f32(lOut, reg.val[0]); - vst1q_f32(rOut, reg.val[1]); - // *lOut = reg.val[0]; - // *rOut = reg.val[1]; - incrementAll(in, in, lOut, rOut); - } - - while (in < input.end() - 1) - _internals::snippetRead(in, lOut, rOut); -} - -template <> -void sfz::writeInterleaved(absl::Span inputLeft, absl::Span inputRight, absl::Span output) noexcept -{ - writeInterleaved(inputLeft, inputRight, output); -} - -template <> -void sfz::fill(absl::Span output, float value) noexcept -{ - fill(output, value); -} - -template <> -void sfz::exp(absl::Span input, absl::Span output) noexcept -{ - exp(input, output); -} - -template <> -void sfz::log(absl::Span input, absl::Span output) noexcept -{ - log(input, output); -} - -template <> -void sfz::sin(absl::Span input, absl::Span output) noexcept -{ - sin(input, output); -} - -template <> -void sfz::cos(absl::Span input, absl::Span output) noexcept -{ - cos(input, output); -} - -template <> -void sfz::applyGain(float gain, absl::Span input, absl::Span output) noexcept -{ - applyGain(gain, input, output); -} - -template <> -void sfz::applyGain(absl::Span gain, absl::Span input, absl::Span output) noexcept -{ - applyGain(gain, input, output); -} - -template <> -void sfz::divide(absl::Span input, absl::Span divisor, absl::Span output) noexcept -{ - divide(input, divisor, output); -} - -template <> -void sfz::multiplyAdd(absl::Span gain, absl::Span input, absl::Span output) noexcept -{ - multiplyAdd(gain, input, output); -} - -template <> -float sfz::loopingSFZIndex(absl::Span jumps, absl::Span leftCoeff, absl::Span rightCoeff, absl::Span indices, float floatIndex, float loopEnd, float loopStart) noexcept -{ - return loopingSFZIndex(jumps, leftCoeff, rightCoeff, indices, floatIndex, loopEnd, loopStart); -} - -template <> -float sfz::saturatingSFZIndex(absl::Span jumps, absl::Span leftCoeff, absl::Span rightCoeff, absl::Span indices, float floatIndex, float loopEnd) noexcept -{ - return saturatingSFZIndex(jumps, leftCoeff, rightCoeff, indices, floatIndex, loopEnd); -} - - -template <> -float sfz::linearRamp(absl::Span output, float start, float step) noexcept -{ - return linearRamp(output, start, step); -} - -template <> -float sfz::multiplicativeRamp(absl::Span output, float start, float step) noexcept -{ - return multiplicativeRamp(output, start, step); -} - -template <> -void sfz::add(absl::Span input, absl::Span output) noexcept -{ - add(input, output); -} - -template <> -void sfz::add(float value, absl::Span output) noexcept -{ - add(value, output); -} - -template <> -void sfz::subtract(absl::Span input, absl::Span output) noexcept -{ - subtract(input, output); -} - -template <> -void sfz::subtract(const float value, absl::Span output) noexcept -{ - subtract(value, output); -} - - -template <> -void sfz::copy(absl::Span input, absl::Span output) noexcept -{ - copy(input, output); -} - -template <> -void sfz::pan(absl::Span panEnvelope, absl::Span leftBuffer, absl::Span rightBuffer) noexcept -{ - pan(panEnvelope, leftBuffer, rightBuffer); -} - -template <> -float sfz::mean(absl::Span vector) noexcept -{ - return mean(vector); -} - -template <> -float sfz::meanSquared(absl::Span vector) noexcept -{ - return meanSquared(vector); -} - -template <> -void sfz::cumsum(absl::Span input, absl::Span output) noexcept -{ - cumsum(input, output); -} - -template<> -void sfz::sfzInterpolationCast(absl::Span floatJumps, absl::Span jumps, absl::Span coeffs) noexcept -{ - sfzInterpolationCast(floatJumps, jumps, coeffs); -} - -template <> -void sfz::diff(absl::Span input, absl::Span output) noexcept -{ - diff(input, output); -} - -#endif // SFIZZ_HAVE_NEON diff --git a/src/sfizz/SIMDSSE.cpp b/src/sfizz/SIMDSSE.cpp deleted file mode 100644 index d3c023db..00000000 --- a/src/sfizz/SIMDSSE.cpp +++ /dev/null @@ -1,19 +0,0 @@ -// 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 - -#include "SIMDConfig.h" - -#if SFIZZ_HAVE_SSE2 - -#include "SIMDHelpers.h" -#include -#include -#include -#include "mathfuns/sse_mathfun.h" - -constexpr uintptr_t TypeAlignment = 4; - -#endif // SFIZZ_HAVE_SSE2