From a900580a665c2e1cf77a343c683e4baada63b69d Mon Sep 17 00:00:00 2001 From: paulfd Date: Sun, 15 Sep 2019 22:47:24 +0200 Subject: [PATCH] Added another subtract SIMD helper --- sfizz/SIMDDummy.cpp | 7 +++++++ sfizz/SIMDHelpers.h | 17 +++++++++++++++++ sfizz/SIMDSSE.cpp | 20 ++++++++++++++++++++ 3 files changed, 44 insertions(+) diff --git a/sfizz/SIMDDummy.cpp b/sfizz/SIMDDummy.cpp index 507c15d5..fd19d1c2 100644 --- a/sfizz/SIMDDummy.cpp +++ b/sfizz/SIMDDummy.cpp @@ -126,6 +126,13 @@ void subtract(absl::Span input, absl::Span outp subtract(input, output); } +template <> +void subtract(const float value, absl::Span output) noexcept +{ + subtract(value, output); +} + + template <> void copy(absl::Span input, absl::Span output) noexcept { diff --git a/sfizz/SIMDHelpers.h b/sfizz/SIMDHelpers.h index db4de29e..6a9b2a90 100644 --- a/sfizz/SIMDHelpers.h +++ b/sfizz/SIMDHelpers.h @@ -374,6 +374,21 @@ inline void snippetSubtract(const T*& input, T*& output) *output++ -= *input++; } +template +inline void snippetSubtract(const T value, T*& output) +{ + *output++ -= value; +} + +template +void subtract(const T value, absl::Span output) noexcept +{ + auto* out = output.begin(); + auto* sentinel = output.end(); + while (out < sentinel) + snippetSubtract(value, out); +} + template void subtract(absl::Span input, absl::Span output) noexcept { @@ -388,6 +403,8 @@ void subtract(absl::Span input, absl::Span output) noexcept template <> void subtract(absl::Span input, absl::Span output) noexcept; +template <> +void subtract(const float value, absl::Span output) noexcept; template void snippetCopy(const T*& input, T*& output) diff --git a/sfizz/SIMDSSE.cpp b/sfizz/SIMDSSE.cpp index 63a11fa4..69b9fd07 100644 --- a/sfizz/SIMDSSE.cpp +++ b/sfizz/SIMDSSE.cpp @@ -564,6 +564,26 @@ void subtract(absl::Span input, absl::Span outp snippetSubtract(in, out); } +template <> +void subtract(const float value, absl::Span output) noexcept +{ + auto* out = output.begin(); + auto* sentinel = output.end(); + const auto* lastAligned = prevAligned(sentinel); + + while (unaligned(out) && out < lastAligned) + snippetSubtract(value, out); + + auto mmValue = _mm_set_ps1(value); + while (out < lastAligned) { + _mm_store_ps(out, _mm_sub_ps(_mm_load_ps(out), mmValue)); + out += TypeAlignment; + } + + while (out < sentinel) + snippetSubtract(value, out); +} + template <> void copy(absl::Span input, absl::Span output) noexcept {