Loading...
Searching...
No Matches
juce_SIMDRegister.h
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
Agreement and JUCE Privacy Policy.
End User License Agreement: www.juce.com/juce-7-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
namespace juce::dsp
{
#ifndef DOXYGEN
// This class is needed internally.
template <typename Scalar>
struct CmplxSIMDOps;
#endif
//==============================================================================
template <typename Type>
struct SIMDRegister
{
//==============================================================================
using ElementType = Type;
using value_type = ElementType;
using MaskType = SIMDInternal::MaskType<ElementType>;
//==============================================================================
// Here are some types which are needed internally
using PrimitiveType = typename SIMDInternal::PrimitiveType<ElementType>::type;
using NativeOps = SIMDNativeOps<PrimitiveType>;
using vSIMDType = typename NativeOps::vSIMDType;
using vMaskType = SIMDRegister<MaskType>;
using vMaskSIMDType = typename vMaskType::vSIMDType;
using CmplxOps = CmplxSIMDOps<ElementType>;
struct ElementAccess;
//==============================================================================
static constexpr size_t SIMDRegisterSize = sizeof (vSIMDType);
static constexpr size_t SIMDNumElements = SIMDRegisterSize / sizeof (ElementType);
vSIMDType value;
inline SIMDRegister() noexcept = default;
inline SIMDRegister (vSIMDType a) noexcept : value (a) {}
inline SIMDRegister (Type s) noexcept { *this = s; }
//==============================================================================
static constexpr size_t size() noexcept { return SIMDNumElements; }
//==============================================================================
static SIMDRegister JUCE_VECTOR_CALLTYPE expand (ElementType s) noexcept { return {CmplxOps::expand (s)}; }
static SIMDRegister JUCE_VECTOR_CALLTYPE fromNative (vSIMDType a) noexcept { return {a}; }
static SIMDRegister JUCE_VECTOR_CALLTYPE fromRawArray (const ElementType* a) noexcept
{
jassert (isSIMDAligned (a));
return {CmplxOps::load (a)};
}
inline void JUCE_VECTOR_CALLTYPE copyToRawArray (ElementType* a) const noexcept
{
jassert (isSIMDAligned (a));
CmplxOps::store (value, a);
}
//==============================================================================
inline ElementType JUCE_VECTOR_CALLTYPE get (size_t idx) const noexcept
{
jassert (idx < SIMDNumElements);
return CmplxOps::get (value, idx);
}
inline void JUCE_VECTOR_CALLTYPE set (size_t idx, ElementType v) noexcept
{
jassert (idx < SIMDNumElements);
value = CmplxOps::set (value, idx, v);
}
//==============================================================================
inline ElementType JUCE_VECTOR_CALLTYPE operator[] (size_t idx) const noexcept
{
return get (idx);
}
inline ElementAccess JUCE_VECTOR_CALLTYPE operator[] (size_t idx) noexcept
{
jassert (idx < SIMDNumElements);
return ElementAccess (*this, idx);
}
//==============================================================================
inline SIMDRegister& JUCE_VECTOR_CALLTYPE operator+= (SIMDRegister v) noexcept { value = NativeOps::add (value, v.value); return *this; }
inline SIMDRegister& JUCE_VECTOR_CALLTYPE operator-= (SIMDRegister v) noexcept { value = NativeOps::sub (value, v.value); return *this; }
inline SIMDRegister& JUCE_VECTOR_CALLTYPE operator*= (SIMDRegister v) noexcept { value = CmplxOps::mul (value, v.value); return *this; }
//==============================================================================
inline SIMDRegister& JUCE_VECTOR_CALLTYPE operator= (ElementType s) noexcept { value = CmplxOps::expand (s); return *this; }
inline SIMDRegister& JUCE_VECTOR_CALLTYPE operator+= (ElementType s) noexcept { value = NativeOps::add (value, CmplxOps::expand (s)); return *this; }
inline SIMDRegister& JUCE_VECTOR_CALLTYPE operator-= (ElementType s) noexcept { value = NativeOps::sub (value, CmplxOps::expand (s)); return *this; }
inline SIMDRegister& JUCE_VECTOR_CALLTYPE operator*= (ElementType s) noexcept { value = CmplxOps::mul (value, CmplxOps::expand (s)); return *this; }
//==============================================================================
inline SIMDRegister& JUCE_VECTOR_CALLTYPE operator&= (vMaskType v) noexcept { value = NativeOps::bit_and (value, toVecType (v.value)); return *this; }
inline SIMDRegister& JUCE_VECTOR_CALLTYPE operator|= (vMaskType v) noexcept { value = NativeOps::bit_or (value, toVecType (v.value)); return *this; }
inline SIMDRegister& JUCE_VECTOR_CALLTYPE operator^= (vMaskType v) noexcept { value = NativeOps::bit_xor (value, toVecType (v.value)); return *this; }
//==============================================================================
inline SIMDRegister& JUCE_VECTOR_CALLTYPE operator&= (MaskType s) noexcept { value = NativeOps::bit_and (value, toVecType (s)); return *this; }
inline SIMDRegister& JUCE_VECTOR_CALLTYPE operator|= (MaskType s) noexcept { value = NativeOps::bit_or (value, toVecType (s)); return *this; }
inline SIMDRegister& JUCE_VECTOR_CALLTYPE operator^= (MaskType s) noexcept { value = NativeOps::bit_xor (value, toVecType (s)); return *this; }
//==============================================================================
inline SIMDRegister JUCE_VECTOR_CALLTYPE operator+ (SIMDRegister v) const noexcept { return { NativeOps::add (value, v.value) }; }
inline SIMDRegister JUCE_VECTOR_CALLTYPE operator- (SIMDRegister v) const noexcept { return { NativeOps::sub (value, v.value) }; }
inline SIMDRegister JUCE_VECTOR_CALLTYPE operator* (SIMDRegister v) const noexcept { return { CmplxOps::mul (value, v.value) }; }
//==============================================================================
inline SIMDRegister JUCE_VECTOR_CALLTYPE operator+ (ElementType s) const noexcept { return { NativeOps::add (value, CmplxOps::expand (s)) }; }
inline SIMDRegister JUCE_VECTOR_CALLTYPE operator- (ElementType s) const noexcept { return { NativeOps::sub (value, CmplxOps::expand (s)) }; }
inline SIMDRegister JUCE_VECTOR_CALLTYPE operator* (ElementType s) const noexcept { return { CmplxOps::mul (value, CmplxOps::expand (s)) }; }
//==============================================================================
inline SIMDRegister JUCE_VECTOR_CALLTYPE operator& (vMaskType v) const noexcept { return { NativeOps::bit_and (value, toVecType (v.value)) }; }
inline SIMDRegister JUCE_VECTOR_CALLTYPE operator| (vMaskType v) const noexcept { return { NativeOps::bit_or (value, toVecType (v.value)) }; }
inline SIMDRegister JUCE_VECTOR_CALLTYPE operator^ (vMaskType v) const noexcept { return { NativeOps::bit_xor (value, toVecType (v.value)) }; }
inline SIMDRegister JUCE_VECTOR_CALLTYPE operator~() const noexcept { return { NativeOps::bit_not (value) }; }
//==============================================================================
inline SIMDRegister JUCE_VECTOR_CALLTYPE operator& (MaskType s) const noexcept { return { NativeOps::bit_and (value, toVecType (s)) }; }
inline SIMDRegister JUCE_VECTOR_CALLTYPE operator| (MaskType s) const noexcept { return { NativeOps::bit_or (value, toVecType (s)) }; }
inline SIMDRegister JUCE_VECTOR_CALLTYPE operator^ (MaskType s) const noexcept { return { NativeOps::bit_xor (value, toVecType (s)) }; }
//==============================================================================
inline bool JUCE_VECTOR_CALLTYPE operator== (SIMDRegister other) const noexcept { return NativeOps::allEqual (value, other.value); }
inline bool JUCE_VECTOR_CALLTYPE operator!= (SIMDRegister other) const noexcept { return ! (*this == other); }
inline bool JUCE_VECTOR_CALLTYPE operator== (Type s) const noexcept { return *this == SIMDRegister::expand (s); }
inline bool JUCE_VECTOR_CALLTYPE operator!= (Type s) const noexcept { return ! (*this == s); }
//==============================================================================
static vMaskType JUCE_VECTOR_CALLTYPE equal (SIMDRegister a, SIMDRegister b) noexcept { return toMaskType (NativeOps::equal (a.value, b.value)); }
static vMaskType JUCE_VECTOR_CALLTYPE notEqual (SIMDRegister a, SIMDRegister b) noexcept { return toMaskType (NativeOps::notEqual (a.value, b.value)); }
static vMaskType JUCE_VECTOR_CALLTYPE lessThan (SIMDRegister a, SIMDRegister b) noexcept { return toMaskType (NativeOps::greaterThan (b.value, a.value)); }
static vMaskType JUCE_VECTOR_CALLTYPE lessThanOrEqual (SIMDRegister a, SIMDRegister b) noexcept { return toMaskType (NativeOps::greaterThanOrEqual (b.value, a.value)); }
static vMaskType JUCE_VECTOR_CALLTYPE greaterThan (SIMDRegister a, SIMDRegister b) noexcept { return toMaskType (NativeOps::greaterThan (a.value, b.value)); }
static vMaskType JUCE_VECTOR_CALLTYPE greaterThanOrEqual (SIMDRegister a, SIMDRegister b) noexcept { return toMaskType (NativeOps::greaterThanOrEqual (a.value, b.value)); }
//==============================================================================
static SIMDRegister JUCE_VECTOR_CALLTYPE min (SIMDRegister a, SIMDRegister b) noexcept { return { NativeOps::min (a.value, b.value) }; }
static SIMDRegister JUCE_VECTOR_CALLTYPE max (SIMDRegister a, SIMDRegister b) noexcept { return { NativeOps::max (a.value, b.value) }; }
//==============================================================================
static SIMDRegister JUCE_VECTOR_CALLTYPE multiplyAdd (SIMDRegister a, const SIMDRegister b, SIMDRegister c) noexcept
{
return { CmplxOps::muladd (a.value, b.value, c.value) };
}
//==============================================================================
inline ElementType sum() const noexcept { return CmplxOps::sum (value); }
//==============================================================================
static SIMDRegister JUCE_VECTOR_CALLTYPE truncate (SIMDRegister a) noexcept { return { NativeOps::truncate (a.value) }; }
//==============================================================================
static SIMDRegister JUCE_VECTOR_CALLTYPE abs (SIMDRegister a) noexcept
{
return a - (a * (expand (ElementType (2)) & lessThan (a, expand (ElementType (0)))));
}
//==============================================================================
static bool isSIMDAligned (const ElementType* ptr) noexcept
{
uintptr_t bitmask = SIMDRegisterSize - 1;
return (reinterpret_cast<uintptr_t> (ptr) & bitmask) == 0;
}
static ElementType* getNextSIMDAlignedPtr (ElementType* ptr) noexcept
{
return snapPointerToAlignment (ptr, SIMDRegisterSize);
}
private:
static vMaskType JUCE_VECTOR_CALLTYPE toMaskType (vSIMDType a) noexcept
{
union
{
vSIMDType in;
vMaskSIMDType out;
} u;
u.in = a;
return vMaskType::fromNative (u.out);
}
static vSIMDType JUCE_VECTOR_CALLTYPE toVecType (vMaskSIMDType a) noexcept
{
union
{
vMaskSIMDType in;
vSIMDType out;
} u;
u.in = a;
return u.out;
}
static vSIMDType JUCE_VECTOR_CALLTYPE toVecType (MaskType a) noexcept
{
union
{
vMaskSIMDType in;
vSIMDType out;
} u;
u.in = CmplxSIMDOps<MaskType>::expand (a);
return u.out;
}
};
} // namespace juce::dsp
juce::dsp::SIMDRegister::truncate
static SIMDRegister JUCE_VECTOR_CALLTYPE truncate(SIMDRegister a) noexcept
Definition juce_SIMDRegister.h:328
juce::dsp::SIMDRegister::operator*=
SIMDRegister &JUCE_VECTOR_CALLTYPE operator*=(SIMDRegister v) noexcept
Definition juce_SIMDRegister.h:185
juce::dsp::SIMDRegister::expand
static SIMDRegister JUCE_VECTOR_CALLTYPE expand(ElementType s) noexcept
Definition juce_SIMDRegister.h:124
juce::dsp::SIMDRegister::vSIMDType
typename NativeOps::vSIMDType vSIMDType
Definition juce_SIMDRegister.h:83
juce::dsp::SIMDRegister::sum
ElementType sum() const noexcept
Definition juce_SIMDRegister.h:323
juce::dsp::SIMDRegister::copyToRawArray
void JUCE_VECTOR_CALLTYPE copyToRawArray(ElementType *a) const noexcept
Definition juce_SIMDRegister.h:138
juce::dsp::SIMDRegister::operator=
SIMDRegister &JUCE_VECTOR_CALLTYPE operator=(ElementType s) noexcept
Definition juce_SIMDRegister.h:189
juce::dsp::SIMDRegister::max
static SIMDRegister JUCE_VECTOR_CALLTYPE max(SIMDRegister a, SIMDRegister b) noexcept
Definition juce_SIMDRegister.h:312
juce::dsp::SIMDRegister::getNextSIMDAlignedPtr
static ElementType * getNextSIMDAlignedPtr(ElementType *ptr) noexcept
Definition juce_SIMDRegister.h:350
juce::dsp::SIMDRegister::greaterThanOrEqual
static vMaskType JUCE_VECTOR_CALLTYPE greaterThanOrEqual(SIMDRegister a, SIMDRegister b) noexcept
Definition juce_SIMDRegister.h:305
juce::dsp::SIMDRegister::greaterThan
static vMaskType JUCE_VECTOR_CALLTYPE greaterThan(SIMDRegister a, SIMDRegister b) noexcept
Definition juce_SIMDRegister.h:300
juce::dsp::SIMDRegister::operator!=
bool JUCE_VECTOR_CALLTYPE operator!=(SIMDRegister other) const noexcept
Definition juce_SIMDRegister.h:268
juce::dsp::SIMDRegister< MaskType >::isSIMDAligned
static bool isSIMDAligned(const ElementType *ptr) noexcept
Definition juce_SIMDRegister.h:339
juce::dsp::SIMDRegister::abs
static SIMDRegister JUCE_VECTOR_CALLTYPE abs(SIMDRegister a) noexcept
Definition juce_SIMDRegister.h:332
juce::dsp::SIMDRegister::operator|
SIMDRegister JUCE_VECTOR_CALLTYPE operator|(vMaskType v) const noexcept
Definition juce_SIMDRegister.h:245
juce::dsp::SIMDRegister::vMaskType
SIMDRegister< MaskType > vMaskType
Definition juce_SIMDRegister.h:86
juce::dsp::SIMDRegister< MaskType >::SIMDRegisterSize
static constexpr size_t SIMDRegisterSize
Definition juce_SIMDRegister.h:101
juce::dsp::SIMDRegister::operator^=
SIMDRegister &JUCE_VECTOR_CALLTYPE operator^=(vMaskType v) noexcept
Definition juce_SIMDRegister.h:208
juce::dsp::SIMDRegister::equal
static vMaskType JUCE_VECTOR_CALLTYPE equal(SIMDRegister a, SIMDRegister b) noexcept
Definition juce_SIMDRegister.h:280
juce::dsp::SIMDRegister::get
ElementType JUCE_VECTOR_CALLTYPE get(size_t idx) const noexcept
Definition juce_SIMDRegister.h:147
juce::dsp::SIMDRegister::operator-=
SIMDRegister &JUCE_VECTOR_CALLTYPE operator-=(SIMDRegister v) noexcept
Definition juce_SIMDRegister.h:182
juce::dsp::SIMDRegister::operator&=
SIMDRegister &JUCE_VECTOR_CALLTYPE operator&=(vMaskType v) noexcept
Definition juce_SIMDRegister.h:202
juce::dsp::SIMDRegister::NativeOps
SIMDNativeOps< PrimitiveType > NativeOps
Definition juce_SIMDRegister.h:80
juce::dsp::SIMDRegister::multiplyAdd
static SIMDRegister JUCE_VECTOR_CALLTYPE multiplyAdd(SIMDRegister a, const SIMDRegister b, SIMDRegister c) noexcept
Definition juce_SIMDRegister.h:316
juce::dsp::SIMDRegister::size
static constexpr size_t size() noexcept
Definition juce_SIMDRegister.h:119
juce::dsp::SIMDRegister::lessThan
static vMaskType JUCE_VECTOR_CALLTYPE lessThan(SIMDRegister a, SIMDRegister b) noexcept
Definition juce_SIMDRegister.h:290
juce::dsp::SIMDRegister::SIMDRegister
SIMDRegister() noexcept=default
juce::dsp::SIMDRegister::ElementType
Type ElementType
Definition juce_SIMDRegister.h:64
juce::dsp::SIMDRegister::min
static SIMDRegister JUCE_VECTOR_CALLTYPE min(SIMDRegister a, SIMDRegister b) noexcept
Definition juce_SIMDRegister.h:309
juce::dsp::SIMDRegister< MaskType >::SIMDNumElements
static constexpr size_t SIMDNumElements
Definition juce_SIMDRegister.h:104
juce::dsp::SIMDRegister< MaskType >::vMaskSIMDType
typename vMaskType::vSIMDType vMaskSIMDType
Definition juce_SIMDRegister.h:89
juce::dsp::SIMDRegister::MaskType
SIMDInternal::MaskType< ElementType > MaskType
Definition juce_SIMDRegister.h:71
juce::dsp::SIMDRegister::set
void JUCE_VECTOR_CALLTYPE set(size_t idx, ElementType v) noexcept
Definition juce_SIMDRegister.h:155
juce::dsp::SIMDRegister::operator+=
SIMDRegister &JUCE_VECTOR_CALLTYPE operator+=(SIMDRegister v) noexcept
Definition juce_SIMDRegister.h:179
juce::dsp::SIMDRegister::lessThanOrEqual
static vMaskType JUCE_VECTOR_CALLTYPE lessThanOrEqual(SIMDRegister a, SIMDRegister b) noexcept
Definition juce_SIMDRegister.h:295
juce::dsp::SIMDRegister::operator~
SIMDRegister JUCE_VECTOR_CALLTYPE operator~() const noexcept
Definition juce_SIMDRegister.h:251
juce::dsp::SIMDRegister::operator^
SIMDRegister JUCE_VECTOR_CALLTYPE operator^(vMaskType v) const noexcept
Definition juce_SIMDRegister.h:248
juce::dsp::SIMDRegister::SIMDRegister
SIMDRegister(Type s) noexcept
Definition juce_SIMDRegister.h:115
juce::dsp::SIMDRegister::fromNative
static SIMDRegister JUCE_VECTOR_CALLTYPE fromNative(vSIMDType a) noexcept
Definition juce_SIMDRegister.h:128
juce::dsp::SIMDRegister< MaskType >::CmplxOps
CmplxSIMDOps< ElementType > CmplxOps
Definition juce_SIMDRegister.h:93
juce::dsp::SIMDRegister::PrimitiveType
typename SIMDInternal::PrimitiveType< ElementType >::type PrimitiveType
Definition juce_SIMDRegister.h:77
juce::dsp::SIMDRegister::operator|=
SIMDRegister &JUCE_VECTOR_CALLTYPE operator|=(vMaskType v) noexcept
Definition juce_SIMDRegister.h:205
juce::dsp::SIMDRegister::operator&
SIMDRegister JUCE_VECTOR_CALLTYPE operator&(vMaskType v) const noexcept
Definition juce_SIMDRegister.h:242
juce::dsp::SIMDRegister::fromRawArray
static SIMDRegister JUCE_VECTOR_CALLTYPE fromRawArray(const ElementType *a) noexcept
Definition juce_SIMDRegister.h:131
juce::dsp::SIMDRegister::operator+
SIMDRegister JUCE_VECTOR_CALLTYPE operator+(SIMDRegister v) const noexcept
Definition juce_SIMDRegister.h:222
juce::dsp::SIMDRegister::operator[]
ElementType JUCE_VECTOR_CALLTYPE operator[](size_t idx) const noexcept
Definition juce_SIMDRegister.h:164
juce::dsp::SIMDRegister::notEqual
static vMaskType JUCE_VECTOR_CALLTYPE notEqual(SIMDRegister a, SIMDRegister b) noexcept
Definition juce_SIMDRegister.h:285
juce::dsp::SIMDRegister::operator*
SIMDRegister JUCE_VECTOR_CALLTYPE operator*(SIMDRegister v) const noexcept
Definition juce_SIMDRegister.h:228
juce::dsp::SIMDRegister::operator-
SIMDRegister JUCE_VECTOR_CALLTYPE operator-(SIMDRegister v) const noexcept
Definition juce_SIMDRegister.h:225
juce::dsp::SIMDRegister::value_type
ElementType value_type
Definition juce_SIMDRegister.h:67
juce::dsp::SIMDRegister::operator==
bool JUCE_VECTOR_CALLTYPE operator==(SIMDRegister other) const noexcept
Definition juce_SIMDRegister.h:265