diff --git a/modules/juce_dsp/containers/juce_SIMDRegister.h b/modules/juce_dsp/containers/juce_SIMDRegister.h index e03bb1a5e8..23e7ab5b30 100644 --- a/modules/juce_dsp/containers/juce_SIMDRegister.h +++ b/modules/juce_dsp/containers/juce_SIMDRegister.h @@ -328,6 +328,11 @@ struct SIMDRegister /** Returns a scalar which is the sum of all elements of the receiver. */ inline ElementType sum() const noexcept { return CmplxOps::sum (value); } + //============================================================================== + /** Truncates each element to its integer part. + Effectively discards the fractional part of each element. A.k.a. round to zero. */ + static inline SIMDRegister JUCE_VECTOR_CALLTYPE truncate (SIMDRegister a) noexcept { return { NativeOps::truncate (a.value) }; } + //============================================================================== /** Returns the absolute value of each element. */ static inline SIMDRegister JUCE_VECTOR_CALLTYPE abs (SIMDRegister a) noexcept diff --git a/modules/juce_dsp/containers/juce_SIMDRegister_test.cpp b/modules/juce_dsp/containers/juce_SIMDRegister_test.cpp index 44d4868495..fd36bbfe96 100644 --- a/modules/juce_dsp/containers/juce_SIMDRegister_test.cpp +++ b/modules/juce_dsp/containers/juce_SIMDRegister_test.cpp @@ -758,6 +758,27 @@ public: } }; + struct CheckTruncate + { + template + static void run (UnitTest& u, Random& random) + { + type inArray[SIMDRegister::SIMDNumElements]; + type outArray[SIMDRegister::SIMDNumElements]; + + SIMDRegister_test_internal::VecFiller::fill (inArray, SIMDRegister::SIMDNumElements, random); + + SIMDRegister a; + copy (a, inArray); + a = SIMDRegister::truncate (a); + + for (size_t j = 0; j < SIMDRegister::SIMDNumElements; ++j) + outArray[j] = (type) (int) inArray[j]; + + u.expect (vecEqualToArray (a, outArray)); + } + }; + struct CheckBoolEquals { template @@ -795,6 +816,18 @@ public: } }; + //============================================================================== + template + void runTestFloatingPoint (const char* unitTestName) + { + beginTest (unitTestName); + + Random random = getRandom(); + + TheTest::template run (*this, random); + TheTest::template run (*this, random); + } + //============================================================================== template void runTestForAllTypes (const char* unitTestName) @@ -873,6 +906,8 @@ public: runTestForAllTypes ("CheckSum"); runTestSigned ("CheckAbs"); + + runTestFloatingPoint ("CheckTruncate"); } }; diff --git a/modules/juce_dsp/native/juce_avx_SIMDNativeOps.h b/modules/juce_dsp/native/juce_avx_SIMDNativeOps.h index b506c162a9..942f6ede3b 100644 --- a/modules/juce_dsp/native/juce_avx_SIMDNativeOps.h +++ b/modules/juce_dsp/native/juce_avx_SIMDNativeOps.h @@ -97,6 +97,8 @@ struct SIMDNativeOps static forcedinline __m256 JUCE_VECTOR_CALLTYPE swapevenodd (__m256 a) noexcept { return _mm256_shuffle_ps (a, a, _MM_SHUFFLE (2, 3, 0, 1)); } static forcedinline float JUCE_VECTOR_CALLTYPE get (__m256 v, size_t i) noexcept { return SIMDFallbackOps::get (v, i); } static forcedinline __m256 JUCE_VECTOR_CALLTYPE set (__m256 v, size_t i, float s) noexcept { return SIMDFallbackOps::set (v, i, s); } + static forcedinline __m256 JUCE_VECTOR_CALLTYPE truncate (__m256 a) noexcept { return _mm256_cvtepi32_ps (_mm256_cvttps_epi32 (a)); } + static forcedinline __m256 JUCE_VECTOR_CALLTYPE oddevensum (__m256 a) noexcept { a = _mm256_add_ps (_mm256_shuffle_ps (a, a, _MM_SHUFFLE (1, 0, 3, 2)), a); @@ -168,7 +170,7 @@ struct SIMDNativeOps static forcedinline __m256d JUCE_VECTOR_CALLTYPE oddevensum (__m256d a) noexcept { return _mm256_add_pd (_mm256_permute2f128_pd (a, a, 1), a); } static forcedinline double JUCE_VECTOR_CALLTYPE get (__m256d v, size_t i) noexcept { return SIMDFallbackOps::get (v, i); } static forcedinline __m256d JUCE_VECTOR_CALLTYPE set (__m256d v, size_t i, double s) noexcept { return SIMDFallbackOps::set (v, i, s); } - + static forcedinline __m256d JUCE_VECTOR_CALLTYPE truncate (__m256d a) noexcept { return _mm256_cvtepi32_pd (_mm256_cvttpd_epi32 (a)); } //============================================================================== static forcedinline __m256d JUCE_VECTOR_CALLTYPE cmplxmul (__m256d a, __m256d b) noexcept @@ -225,6 +227,7 @@ struct SIMDNativeOps static forcedinline __m256i JUCE_VECTOR_CALLTYPE notEqual (__m256i a, __m256i b) noexcept { return bit_not (equal (a, b)); } static forcedinline int8_t JUCE_VECTOR_CALLTYPE get (__m256i v, size_t i) noexcept { return SIMDFallbackOps::get (v, i); } static forcedinline __m256i JUCE_VECTOR_CALLTYPE set (__m256i v, size_t i, int8_t s) noexcept { return SIMDFallbackOps::set (v, i, s); } + static forcedinline __m256i JUCE_VECTOR_CALLTYPE truncate (__m256i a) noexcept { return a; } //============================================================================== static forcedinline int8_t JUCE_VECTOR_CALLTYPE sum (__m256i a) noexcept @@ -300,6 +303,7 @@ struct SIMDNativeOps static forcedinline __m256i JUCE_VECTOR_CALLTYPE notEqual (__m256i a, __m256i b) noexcept { return bit_not (equal (a, b)); } static forcedinline uint8_t JUCE_VECTOR_CALLTYPE get (__m256i v, size_t i) noexcept { return SIMDFallbackOps::get (v, i); } static forcedinline __m256i JUCE_VECTOR_CALLTYPE set (__m256i v, size_t i, uint8_t s) noexcept { return SIMDFallbackOps::set (v, i, s); } + static forcedinline __m256i JUCE_VECTOR_CALLTYPE truncate (__m256i a) noexcept { return a; } //============================================================================== static forcedinline uint8_t JUCE_VECTOR_CALLTYPE sum (__m256i a) noexcept @@ -375,6 +379,7 @@ struct SIMDNativeOps static forcedinline bool JUCE_VECTOR_CALLTYPE allEqual (__m256i a, __m256i b) noexcept { return (_mm256_movemask_epi8 (equal (a, b)) == -1); } static forcedinline int16_t JUCE_VECTOR_CALLTYPE get (__m256i v, size_t i) noexcept { return SIMDFallbackOps::get (v, i); } static forcedinline __m256i JUCE_VECTOR_CALLTYPE set (__m256i v, size_t i, int16_t s) noexcept { return SIMDFallbackOps::set (v, i, s); } + static forcedinline __m256i JUCE_VECTOR_CALLTYPE truncate (__m256i a) noexcept { return a; } //============================================================================== static forcedinline int16_t JUCE_VECTOR_CALLTYPE sum (__m256i a) noexcept @@ -432,6 +437,7 @@ struct SIMDNativeOps static forcedinline bool JUCE_VECTOR_CALLTYPE allEqual (__m256i a, __m256i b) noexcept { return (_mm256_movemask_epi8 (equal (a, b)) == -1); } static forcedinline uint16_t JUCE_VECTOR_CALLTYPE get (__m256i v, size_t i) noexcept { return SIMDFallbackOps::get (v, i); } static forcedinline __m256i JUCE_VECTOR_CALLTYPE set (__m256i v, size_t i, uint16_t s) noexcept { return SIMDFallbackOps::set (v, i, s); } + static forcedinline __m256i JUCE_VECTOR_CALLTYPE truncate (__m256i a) noexcept { return a; } //============================================================================== static forcedinline uint16_t JUCE_VECTOR_CALLTYPE sum (__m256i a) noexcept @@ -488,6 +494,7 @@ struct SIMDNativeOps static forcedinline bool JUCE_VECTOR_CALLTYPE allEqual (__m256i a, __m256i b) noexcept { return (_mm256_movemask_epi8 (equal (a, b)) == -1); } static forcedinline int32_t JUCE_VECTOR_CALLTYPE get (__m256i v, size_t i) noexcept { return SIMDFallbackOps::get (v, i); } static forcedinline __m256i JUCE_VECTOR_CALLTYPE set (__m256i v, size_t i, int32_t s) noexcept { return SIMDFallbackOps::set (v, i, s); } + static forcedinline __m256i JUCE_VECTOR_CALLTYPE truncate (__m256i a) noexcept { return a; } //============================================================================== static forcedinline int32_t JUCE_VECTOR_CALLTYPE sum (__m256i a) noexcept @@ -543,6 +550,7 @@ struct SIMDNativeOps static forcedinline bool JUCE_VECTOR_CALLTYPE allEqual (__m256i a, __m256i b) noexcept { return (_mm256_movemask_epi8 (equal (a, b)) == -1); } static forcedinline uint32_t JUCE_VECTOR_CALLTYPE get (__m256i v, size_t i) noexcept { return SIMDFallbackOps::get (v, i); } static forcedinline __m256i JUCE_VECTOR_CALLTYPE set (__m256i v, size_t i, uint32_t s) noexcept { return SIMDFallbackOps::set (v, i, s); } + static forcedinline __m256i JUCE_VECTOR_CALLTYPE truncate (__m256i a) noexcept { return a; } //============================================================================== static forcedinline uint32_t JUCE_VECTOR_CALLTYPE sum (__m256i a) noexcept @@ -597,6 +605,7 @@ struct SIMDNativeOps static forcedinline __m256i JUCE_VECTOR_CALLTYPE set (__m256i v, size_t i, int64_t s) noexcept { return SIMDFallbackOps::set (v, i, s); } static forcedinline int64_t JUCE_VECTOR_CALLTYPE sum (__m256i a) noexcept { return SIMDFallbackOps::sum (a); } static forcedinline __m256i JUCE_VECTOR_CALLTYPE mul (__m256i a, __m256i b) noexcept { return SIMDFallbackOps::mul (a, b); } + static forcedinline __m256i JUCE_VECTOR_CALLTYPE truncate (__m256i a) noexcept { return a; } }; //============================================================================== @@ -637,6 +646,7 @@ struct SIMDNativeOps static forcedinline __m256i JUCE_VECTOR_CALLTYPE set (__m256i v, size_t i, uint64_t s) noexcept { return SIMDFallbackOps::set (v, i, s); } static forcedinline uint64_t JUCE_VECTOR_CALLTYPE sum (__m256i a) noexcept { return SIMDFallbackOps::sum (a); } static forcedinline __m256i JUCE_VECTOR_CALLTYPE mul (__m256i a, __m256i b) noexcept { return SIMDFallbackOps::mul (a, b); } + static forcedinline __m256i JUCE_VECTOR_CALLTYPE truncate (__m256i a) noexcept { return a; } }; #endif diff --git a/modules/juce_dsp/native/juce_fallback_SIMDNativeOps.h b/modules/juce_dsp/native/juce_fallback_SIMDNativeOps.h index 92447a8b23..87d0fc2e64 100644 --- a/modules/juce_dsp/native/juce_fallback_SIMDNativeOps.h +++ b/modules/juce_dsp/native/juce_fallback_SIMDNativeOps.h @@ -120,6 +120,19 @@ struct SIMDFallbackOps return retval; } + static forcedinline vSIMDType truncate (vSIMDType av) noexcept + { + UnionType a {av}; + + for (size_t i = 0; i < n; ++i) + { + jassert (a.s[i] >= ScalarType (0)); + a.s[i] = static_cast (static_cast (a.s[i])); + } + + return a.v; + } + static forcedinline vSIMDType multiplyAdd (vSIMDType av, vSIMDType bv, vSIMDType cv) noexcept { UnionType a {av}, b {bv}, c {cv}; diff --git a/modules/juce_dsp/native/juce_neon_SIMDNativeOps.h b/modules/juce_dsp/native/juce_neon_SIMDNativeOps.h index 06d9457e73..4fc4997e64 100644 --- a/modules/juce_dsp/native/juce_neon_SIMDNativeOps.h +++ b/modules/juce_dsp/native/juce_neon_SIMDNativeOps.h @@ -92,6 +92,8 @@ struct SIMDNativeOps static forcedinline vSIMDType greaterThan (vSIMDType a, vSIMDType b) noexcept { return (vSIMDType) vcgtq_u32 (a, b); } static forcedinline vSIMDType greaterThanOrEqual (vSIMDType a, vSIMDType b) noexcept { return (vSIMDType) vcgeq_u32 (a, b); } static forcedinline vSIMDType multiplyAdd (vSIMDType a, vSIMDType b, vSIMDType c) noexcept { return vmlaq_u32 (a, b, c); } + static forcedinline vSIMDType truncate (vSIMDType a) noexcept { return a; } + static forcedinline uint32_t sum (vSIMDType a) noexcept { auto rr = vadd_u32 (vget_high_u32 (a), vget_low_u32 (a)); @@ -136,6 +138,8 @@ struct SIMDNativeOps static forcedinline vSIMDType greaterThan (vSIMDType a, vSIMDType b) noexcept { return (vSIMDType) vcgtq_s32 (a, b); } static forcedinline vSIMDType greaterThanOrEqual (vSIMDType a, vSIMDType b) noexcept { return (vSIMDType) vcgeq_s32 (a, b); } static forcedinline vSIMDType multiplyAdd (vSIMDType a, vSIMDType b, vSIMDType c) noexcept { return vmlaq_s32 (a, b, c); } + static forcedinline vSIMDType truncate (vSIMDType a) noexcept { return a; } + static forcedinline int32_t sum (vSIMDType a) noexcept { auto rr = vadd_s32 (vget_high_s32 (a), vget_low_s32 (a)); @@ -182,6 +186,7 @@ struct SIMDNativeOps static forcedinline bool allEqual (vSIMDType a, vSIMDType b) noexcept { return (SIMDNativeOps::sum ((SIMDNativeOps::vSIMDType) notEqual (a, b)) == 0); } static forcedinline vSIMDType multiplyAdd (vSIMDType a, vSIMDType b, vSIMDType c) noexcept { return vmlaq_s8 (a, b, c); } static forcedinline int8_t sum (vSIMDType a) noexcept { return fb::sum (a); } + static forcedinline vSIMDType truncate (vSIMDType a) noexcept { return a; } }; //============================================================================== @@ -222,6 +227,7 @@ struct SIMDNativeOps static forcedinline bool allEqual (vSIMDType a, vSIMDType b) noexcept { return (SIMDNativeOps::sum ((SIMDNativeOps::vSIMDType) notEqual (a, b)) == 0); } static forcedinline vSIMDType multiplyAdd (vSIMDType a, vSIMDType b, vSIMDType c) noexcept { return vmlaq_u8 (a, b, c); } static forcedinline uint8_t sum (vSIMDType a) noexcept { return fb::sum (a); } + static forcedinline vSIMDType truncate (vSIMDType a) noexcept { return a; } }; //============================================================================== @@ -262,6 +268,7 @@ struct SIMDNativeOps static forcedinline bool allEqual (vSIMDType a, vSIMDType b) noexcept { return (SIMDNativeOps::sum ((SIMDNativeOps::vSIMDType) notEqual (a, b)) == 0); } static forcedinline vSIMDType multiplyAdd (vSIMDType a, vSIMDType b, vSIMDType c) noexcept { return vmlaq_s16 (a, b, c); } static forcedinline int16_t sum (vSIMDType a) noexcept { return fb::sum (a); } + static forcedinline vSIMDType truncate (vSIMDType a) noexcept { return a; } }; @@ -303,6 +310,7 @@ struct SIMDNativeOps static forcedinline bool allEqual (vSIMDType a, vSIMDType b) noexcept { return (SIMDNativeOps::sum ((SIMDNativeOps::vSIMDType) notEqual (a, b)) == 0); } static forcedinline vSIMDType multiplyAdd (vSIMDType a, vSIMDType b, vSIMDType c) noexcept { return vmlaq_u16 (a, b, c); } static forcedinline uint16_t sum (vSIMDType a) noexcept { return fb::sum (a); } + static forcedinline vSIMDType truncate (vSIMDType a) noexcept { return a; } }; //============================================================================== @@ -343,6 +351,7 @@ struct SIMDNativeOps static forcedinline bool allEqual (vSIMDType a, vSIMDType b) noexcept { return (SIMDNativeOps::sum ((SIMDNativeOps::vSIMDType) notEqual (a, b)) == 0); } static forcedinline vSIMDType multiplyAdd (vSIMDType a, vSIMDType b, vSIMDType c) noexcept { return fb::multiplyAdd (a, b, c); } static forcedinline int64_t sum (vSIMDType a) noexcept { return fb::sum (a); } + static forcedinline vSIMDType truncate (vSIMDType a) noexcept { return a; } }; @@ -383,7 +392,8 @@ struct SIMDNativeOps static forcedinline vSIMDType greaterThanOrEqual (vSIMDType a, vSIMDType b) noexcept { return fb::greaterThanOrEqual (a, b); } static forcedinline bool allEqual (vSIMDType a, vSIMDType b) noexcept { return (SIMDNativeOps::sum ((SIMDNativeOps::vSIMDType) notEqual (a, b)) == 0); } static forcedinline vSIMDType multiplyAdd (vSIMDType a, vSIMDType b, vSIMDType c) noexcept { return fb::multiplyAdd (a, b, c); } - static forcedinline uint64_t sum (vSIMDType a) noexcept { return fb::sum (a); } + static forcedinline uint64_t sum (vSIMDType a) noexcept { return fb::sum (a); } + static forcedinline vSIMDType truncate (vSIMDType a) noexcept { return a; } }; //============================================================================== @@ -430,6 +440,7 @@ struct SIMDNativeOps static forcedinline vSIMDType dupodd (vSIMDType a) noexcept { return fb::shuffle<(1 << 0) | (1 << 2) | (3 << 4) | (3 << 6)> (a); } static forcedinline vSIMDType swapevenodd (vSIMDType a) noexcept { return fb::shuffle<(1 << 0) | (0 << 2) | (3 << 4) | (2 << 6)> (a); } static forcedinline vSIMDType oddevensum (vSIMDType a) noexcept { return add (fb::shuffle<(2 << 0) | (3 << 2) | (0 << 4) | (1 << 6)> (a), a); } + static forcedinline vSIMDType truncate (vSIMDType a) noexcept { return vcvtq_f32_s32 (vcvtq_s32_f32 (a)); } //============================================================================== static forcedinline vSIMDType cmplxmul (vSIMDType a, vSIMDType b) noexcept @@ -483,6 +494,7 @@ struct SIMDNativeOps static forcedinline vSIMDType cmplxmul (vSIMDType a, vSIMDType b) noexcept { return fb::cmplxmul (a, b); } static forcedinline double sum (vSIMDType a) noexcept { return fb::sum (a); } static forcedinline vSIMDType oddevensum (vSIMDType a) noexcept { return a; } + static forcedinline vSIMDType truncate (vSIMDType a) noexcept { return fb::truncate (a); } }; #endif diff --git a/modules/juce_dsp/native/juce_sse_SIMDNativeOps.h b/modules/juce_dsp/native/juce_sse_SIMDNativeOps.h index c4c320e9e1..a9a7c7ae3d 100644 --- a/modules/juce_dsp/native/juce_sse_SIMDNativeOps.h +++ b/modules/juce_dsp/native/juce_sse_SIMDNativeOps.h @@ -97,6 +97,7 @@ struct SIMDNativeOps static forcedinline __m128 JUCE_VECTOR_CALLTYPE oddevensum (__m128 a) noexcept { return _mm_add_ps (_mm_shuffle_ps (a, a, _MM_SHUFFLE (1, 0, 3, 2)), a); } static forcedinline float JUCE_VECTOR_CALLTYPE get (__m128 v, size_t i) noexcept { return SIMDFallbackOps::get (v, i); } static forcedinline __m128 JUCE_VECTOR_CALLTYPE set (__m128 v, size_t i, float s) noexcept { return SIMDFallbackOps::set (v, i, s); } + static forcedinline __m128 JUCE_VECTOR_CALLTYPE truncate (__m128 a) noexcept { return _mm_cvtepi32_ps (_mm_cvttps_epi32 (a)); } //============================================================================== static forcedinline __m128 JUCE_VECTOR_CALLTYPE cmplxmul (__m128 a, __m128 b) noexcept @@ -164,6 +165,7 @@ struct SIMDNativeOps static forcedinline __m128d JUCE_VECTOR_CALLTYPE oddevensum (__m128d a) noexcept { return a; } static forcedinline double JUCE_VECTOR_CALLTYPE get (__m128d v, size_t i) noexcept { return SIMDFallbackOps::get (v, i); } static forcedinline __m128d JUCE_VECTOR_CALLTYPE set (__m128d v, size_t i, double s) noexcept { return SIMDFallbackOps::set (v, i, s); } + static forcedinline __m128d JUCE_VECTOR_CALLTYPE truncate (__m128d a) noexcept { return _mm_cvtepi32_pd (_mm_cvttpd_epi32 (a)); } //============================================================================== static forcedinline __m128d JUCE_VECTOR_CALLTYPE cmplxmul (__m128d a, __m128d b) noexcept @@ -226,6 +228,7 @@ struct SIMDNativeOps static forcedinline bool JUCE_VECTOR_CALLTYPE allEqual (__m128i a, __m128i b) noexcept { return (_mm_movemask_epi8 (equal (a, b)) == 0xffff); } static forcedinline int8_t JUCE_VECTOR_CALLTYPE get (__m128i v, size_t i) noexcept { return SIMDFallbackOps::get (v, i); } static forcedinline __m128i JUCE_VECTOR_CALLTYPE set (__m128i v, size_t i, int8_t s) noexcept { return SIMDFallbackOps::set (v, i, s); } + static forcedinline __m128i JUCE_VECTOR_CALLTYPE truncate (__m128i a) noexcept { return a; } //============================================================================== static forcedinline int8_t JUCE_VECTOR_CALLTYPE sum (__m128i a) noexcept @@ -294,6 +297,7 @@ struct SIMDNativeOps static forcedinline bool JUCE_VECTOR_CALLTYPE allEqual (__m128i a, __m128i b) noexcept { return (_mm_movemask_epi8 (equal (a, b)) == 0xffff); } static forcedinline uint8_t JUCE_VECTOR_CALLTYPE get (__m128i v, size_t i) noexcept { return SIMDFallbackOps::get (v, i); } static forcedinline __m128i JUCE_VECTOR_CALLTYPE set (__m128i v, size_t i, uint8_t s) noexcept { return SIMDFallbackOps::set (v, i, s); } + static forcedinline __m128i JUCE_VECTOR_CALLTYPE truncate (__m128i a) noexcept { return a; } //============================================================================== static forcedinline uint8_t JUCE_VECTOR_CALLTYPE sum (__m128i a) noexcept @@ -363,6 +367,7 @@ struct SIMDNativeOps static forcedinline bool JUCE_VECTOR_CALLTYPE allEqual (__m128i a, __m128i b) noexcept { return (_mm_movemask_epi8 (equal (a, b)) == 0xffff); } static forcedinline int16_t JUCE_VECTOR_CALLTYPE get (__m128i v, size_t i) noexcept { return SIMDFallbackOps::get (v, i); } static forcedinline __m128i JUCE_VECTOR_CALLTYPE set (__m128i v, size_t i, int16_t s) noexcept { return SIMDFallbackOps::set (v, i, s); } + static forcedinline __m128i JUCE_VECTOR_CALLTYPE truncate (__m128i a) noexcept { return a; } //============================================================================== static forcedinline int16_t JUCE_VECTOR_CALLTYPE sum (__m128i a) noexcept @@ -423,6 +428,7 @@ struct SIMDNativeOps static forcedinline bool JUCE_VECTOR_CALLTYPE allEqual (__m128i a, __m128i b) noexcept { return (_mm_movemask_epi8 (equal (a, b)) == 0xffff); } static forcedinline uint16_t JUCE_VECTOR_CALLTYPE get (__m128i v, size_t i) noexcept { return SIMDFallbackOps::get (v, i); } static forcedinline __m128i JUCE_VECTOR_CALLTYPE set (__m128i v, size_t i, uint16_t s) noexcept { return SIMDFallbackOps::set (v, i, s); } + static forcedinline __m128i JUCE_VECTOR_CALLTYPE truncate (__m128i a) noexcept { return a; } //============================================================================== static forcedinline uint16_t JUCE_VECTOR_CALLTYPE sum (__m128i a) noexcept @@ -473,6 +479,7 @@ struct SIMDNativeOps static forcedinline bool JUCE_VECTOR_CALLTYPE allEqual (__m128i a, __m128i b) noexcept { return (_mm_movemask_epi8 (equal (a, b)) == 0xffff); } static forcedinline int32_t JUCE_VECTOR_CALLTYPE get (__m128i v, size_t i) noexcept { return SIMDFallbackOps::get (v, i); } static forcedinline __m128i JUCE_VECTOR_CALLTYPE set (__m128i v, size_t i, int32_t s) noexcept { return SIMDFallbackOps::set (v, i, s); } + static forcedinline __m128i JUCE_VECTOR_CALLTYPE truncate (__m128i a) noexcept { return a; } //============================================================================== static forcedinline int32_t JUCE_VECTOR_CALLTYPE sum (__m128i a) noexcept @@ -554,6 +561,7 @@ struct SIMDNativeOps static forcedinline bool JUCE_VECTOR_CALLTYPE allEqual (__m128i a, __m128i b) noexcept { return (_mm_movemask_epi8 (equal (a, b)) == 0xffff); } static forcedinline uint32_t JUCE_VECTOR_CALLTYPE get (__m128i v, size_t i) noexcept { return SIMDFallbackOps::get (v, i); } static forcedinline __m128i JUCE_VECTOR_CALLTYPE set (__m128i v, size_t i, uint32_t s) noexcept { return SIMDFallbackOps::set (v, i, s); } + static forcedinline __m128i JUCE_VECTOR_CALLTYPE truncate (__m128i a) noexcept { return a; } //============================================================================== static forcedinline uint32_t JUCE_VECTOR_CALLTYPE sum (__m128i a) noexcept @@ -634,6 +642,7 @@ struct SIMDNativeOps static forcedinline __m128i JUCE_VECTOR_CALLTYPE set (__m128i v, size_t i, int64_t s) noexcept { return SIMDFallbackOps::set (v, i, s); } static forcedinline int64_t JUCE_VECTOR_CALLTYPE sum (__m128i a) noexcept { return SIMDFallbackOps::sum (a); } static forcedinline __m128i JUCE_VECTOR_CALLTYPE mul (__m128i a, __m128i b) noexcept { return SIMDFallbackOps::mul (a, b); } + static forcedinline __m128i JUCE_VECTOR_CALLTYPE truncate (__m128i a) noexcept { return a; } static forcedinline __m128i JUCE_VECTOR_CALLTYPE equal (__m128i a, __m128i b) noexcept { @@ -693,6 +702,7 @@ struct SIMDNativeOps static forcedinline __m128i JUCE_VECTOR_CALLTYPE set (__m128i v, size_t i, uint64_t s) noexcept { return SIMDFallbackOps::set (v, i, s); } static forcedinline uint64_t JUCE_VECTOR_CALLTYPE sum (__m128i a) noexcept { return SIMDFallbackOps::sum (a); } static forcedinline __m128i JUCE_VECTOR_CALLTYPE mul (__m128i a, __m128i b) noexcept { return SIMDFallbackOps::mul (a, b); } + static forcedinline __m128i JUCE_VECTOR_CALLTYPE truncate (__m128i a) noexcept { return a; } static forcedinline __m128i JUCE_VECTOR_CALLTYPE equal (__m128i a, __m128i b) noexcept {