| @@ -61,21 +61,24 @@ template <typename Type> | |||||
| struct SIMDRegister | struct SIMDRegister | ||||
| { | { | ||||
| //============================================================================== | //============================================================================== | ||||
| /** The type that represents the individual constituents of the SIMD Register */ | |||||
| typedef Type ElementType; | |||||
| /** STL compatible value_type definition (same as ElementType). */ | |||||
| typedef ElementType value_type; | |||||
| /** The corresponding primitive integer type, for example, this will be int32_t | /** The corresponding primitive integer type, for example, this will be int32_t | ||||
| if type is a float. */ | if type is a float. */ | ||||
| typedef typename SIMDInternal::MaskTypeFor<Type>::type MaskType; | |||||
| typedef typename SIMDInternal::MaskTypeFor<ElementType>::type MaskType; | |||||
| //============================================================================== | //============================================================================== | ||||
| // Here are some types which are needed internally | // Here are some types which are needed internally | ||||
| /** The native primitive type (used internally). */ | /** The native primitive type (used internally). */ | ||||
| typedef typename SIMDInternal::PrimitiveType<Type>::type ElementType; | |||||
| /** STL compatible value_type definition. */ | |||||
| typedef typename SIMDInternal::PrimitiveType<Type>::type value_type; | |||||
| typedef typename SIMDInternal::PrimitiveType<ElementType>::type PrimitiveType; | |||||
| /** The native operations for this platform and type combination (used internally) */ | /** The native operations for this platform and type combination (used internally) */ | ||||
| typedef SIMDNativeOps<ElementType> NativeOps; | |||||
| typedef SIMDNativeOps<PrimitiveType> NativeOps; | |||||
| /** The native type (used internally). */ | /** The native type (used internally). */ | ||||
| typedef typename NativeOps::vSIMDType vSIMDType; | typedef typename NativeOps::vSIMDType vSIMDType; | ||||
| @@ -88,14 +91,14 @@ struct SIMDRegister | |||||
| /** Wrapper for operations which need to be handled differently for complex | /** Wrapper for operations which need to be handled differently for complex | ||||
| and scalar types (used internally). */ | and scalar types (used internally). */ | ||||
| typedef CmplxSIMDOps<Type> CmplxOps; | |||||
| typedef CmplxSIMDOps<ElementType> CmplxOps; | |||||
| //============================================================================== | //============================================================================== | ||||
| /** The size in bytes of this register. */ | /** The size in bytes of this register. */ | ||||
| static constexpr size_t SIMDRegisterSize = sizeof (vSIMDType); | static constexpr size_t SIMDRegisterSize = sizeof (vSIMDType); | ||||
| /** The number of elements that this vector can hold. */ | /** The number of elements that this vector can hold. */ | ||||
| static constexpr size_t SIMDNumElements = SIMDRegisterSize / sizeof (Type); | |||||
| static constexpr size_t SIMDNumElements = SIMDRegisterSize / sizeof (ElementType); | |||||
| vSIMDType value; | vSIMDType value; | ||||
| @@ -106,7 +109,7 @@ struct SIMDRegister | |||||
| //============================================================================== | //============================================================================== | ||||
| /** Creates a new SIMDRegister from the corresponding scalar primitive. | /** Creates a new SIMDRegister from the corresponding scalar primitive. | ||||
| The scalar is extended to all elements of the vector. */ | The scalar is extended to all elements of the vector. */ | ||||
| inline static SIMDRegister JUCE_VECTOR_CALLTYPE expand (Type s) noexcept { return {CmplxOps::expand (s)}; } | |||||
| inline static SIMDRegister JUCE_VECTOR_CALLTYPE expand (ElementType s) noexcept { return {CmplxOps::expand (s)}; } | |||||
| /** Creates a new SIMDRegister from the internal SIMD type (for example | /** Creates a new SIMDRegister from the internal SIMD type (for example | ||||
| __mm128 for single-precision floating point on SSE architectures). */ | __mm128 for single-precision floating point on SSE architectures). */ | ||||
| @@ -115,18 +118,18 @@ struct SIMDRegister | |||||
| //============================================================================== | //============================================================================== | ||||
| /** Returns the idx-th element of the receiver. Note that this does not check if idx | /** Returns the idx-th element of the receiver. Note that this does not check if idx | ||||
| is larger than the native register size. */ | is larger than the native register size. */ | ||||
| inline Type JUCE_VECTOR_CALLTYPE operator[] (size_t idx) const noexcept | |||||
| inline ElementType JUCE_VECTOR_CALLTYPE operator[] (size_t idx) const noexcept | |||||
| { | { | ||||
| jassert (idx < SIMDNumElements); | jassert (idx < SIMDNumElements); | ||||
| return reinterpret_cast<const Type*> (&value) [idx]; | |||||
| return reinterpret_cast<const ElementType*> (&value) [idx]; | |||||
| } | } | ||||
| /** Returns the idx-th element of the receiver. Note that this does not check if idx | /** Returns the idx-th element of the receiver. Note that this does not check if idx | ||||
| is larger than the native register size. */ | is larger than the native register size. */ | ||||
| inline Type& JUCE_VECTOR_CALLTYPE operator[] (size_t idx) noexcept | |||||
| inline ElementType& JUCE_VECTOR_CALLTYPE operator[] (size_t idx) noexcept | |||||
| { | { | ||||
| jassert (idx < SIMDNumElements); | jassert (idx < SIMDNumElements); | ||||
| return reinterpret_cast<Type*> (&value) [idx]; | |||||
| return reinterpret_cast<ElementType*> (&value) [idx]; | |||||
| } | } | ||||
| //============================================================================== | //============================================================================== | ||||
| @@ -141,16 +144,16 @@ struct SIMDRegister | |||||
| //============================================================================== | //============================================================================== | ||||
| /** Broadcasts the scalar to all elements of the receiver. */ | /** Broadcasts the scalar to all elements of the receiver. */ | ||||
| inline SIMDRegister& JUCE_VECTOR_CALLTYPE operator= (Type s) noexcept { value = CmplxOps::expand (s); return *this; } | |||||
| inline SIMDRegister& JUCE_VECTOR_CALLTYPE operator= (ElementType s) noexcept { value = CmplxOps::expand (s); return *this; } | |||||
| /** Adds a scalar to the receiver. */ | /** Adds a scalar to the receiver. */ | ||||
| inline SIMDRegister& JUCE_VECTOR_CALLTYPE operator+= (Type s) noexcept { value = NativeOps::add (value, CmplxOps::expand (s)); return *this; } | |||||
| inline SIMDRegister& JUCE_VECTOR_CALLTYPE operator+= (ElementType s) noexcept { value = NativeOps::add (value, CmplxOps::expand (s)); return *this; } | |||||
| /** Subtracts a scalar to the receiver. */ | /** Subtracts a scalar to the receiver. */ | ||||
| inline SIMDRegister& JUCE_VECTOR_CALLTYPE operator-= (Type s) noexcept { value = NativeOps::sub (value, CmplxOps::expand (s)); return *this; } | |||||
| inline SIMDRegister& JUCE_VECTOR_CALLTYPE operator-= (ElementType s) noexcept { value = NativeOps::sub (value, CmplxOps::expand (s)); return *this; } | |||||
| /** Multiplies a scalar to the receiver. */ | /** Multiplies a scalar to the receiver. */ | ||||
| inline SIMDRegister& JUCE_VECTOR_CALLTYPE operator*= (Type s) noexcept { value = CmplxOps::mul (value, CmplxOps::expand (s)); return *this; } | |||||
| inline SIMDRegister& JUCE_VECTOR_CALLTYPE operator*= (ElementType s) noexcept { value = CmplxOps::mul (value, CmplxOps::expand (s)); return *this; } | |||||
| //============================================================================== | //============================================================================== | ||||
| /** Bit-and the reciver with SIMDRegister v and store the result in the receiver. */ | /** Bit-and the reciver with SIMDRegister v and store the result in the receiver. */ | ||||
| @@ -184,13 +187,13 @@ struct SIMDRegister | |||||
| //============================================================================== | //============================================================================== | ||||
| /** Returns a vector where each element is the sum of the corresponding element in the receiver and the scalar s.*/ | /** Returns a vector where each element is the sum of the corresponding element in the receiver and the scalar s.*/ | ||||
| inline SIMDRegister JUCE_VECTOR_CALLTYPE operator+ (Type s) const noexcept { return { NativeOps::add (value, CmplxOps::expand (s)) }; } | |||||
| inline SIMDRegister JUCE_VECTOR_CALLTYPE operator+ (ElementType s) const noexcept { return { NativeOps::add (value, CmplxOps::expand (s)) }; } | |||||
| /** Returns a vector where each element is the difference of the corresponding element in the receiver and the scalar s.*/ | /** Returns a vector where each element is the difference of the corresponding element in the receiver and the scalar s.*/ | ||||
| inline SIMDRegister JUCE_VECTOR_CALLTYPE operator- (Type s) const noexcept { return { NativeOps::sub (value, CmplxOps::expand (s)) }; } | |||||
| inline SIMDRegister JUCE_VECTOR_CALLTYPE operator- (ElementType s) const noexcept { return { NativeOps::sub (value, CmplxOps::expand (s)) }; } | |||||
| /** Returns a vector where each element is the difference of the corresponding element in the receiver and the scalar s.*/ | /** Returns a vector where each element is the difference of the corresponding element in the receiver and the scalar s.*/ | ||||
| inline SIMDRegister JUCE_VECTOR_CALLTYPE operator* (Type s) const noexcept { return { CmplxOps::mul (value, CmplxOps::expand (s)) }; } | |||||
| inline SIMDRegister JUCE_VECTOR_CALLTYPE operator* (ElementType s) const noexcept { return { CmplxOps::mul (value, CmplxOps::expand (s)) }; } | |||||
| //============================================================================== | //============================================================================== | ||||
| /** Returns the bit-and of the receiver and v. */ | /** Returns the bit-and of the receiver and v. */ | ||||
| @@ -262,11 +265,11 @@ struct SIMDRegister | |||||
| //============================================================================== | //============================================================================== | ||||
| /** Returns a scalar which is the sum of all elements of the receiver. */ | /** Returns a scalar which is the sum of all elements of the receiver. */ | ||||
| inline Type sum() const noexcept { return CmplxOps::sum (value); } | |||||
| inline ElementType sum() const noexcept { return CmplxOps::sum (value); } | |||||
| //============================================================================== | //============================================================================== | ||||
| /** Checks if the given pointer is suffeciently aligned for using SIMD operations. */ | /** Checks if the given pointer is suffeciently aligned for using SIMD operations. */ | ||||
| static inline bool isSIMDAligned (Type* ptr) noexcept | |||||
| static inline bool isSIMDAligned (ElementType* ptr) noexcept | |||||
| { | { | ||||
| uintptr_t bitmask = SIMDRegisterSize - 1; | uintptr_t bitmask = SIMDRegisterSize - 1; | ||||
| return (reinterpret_cast<uintptr_t> (ptr) & bitmask) == 0; | return (reinterpret_cast<uintptr_t> (ptr) & bitmask) == 0; | ||||
| @@ -277,7 +280,7 @@ struct SIMDRegister | |||||
| If the current position in memory is already aligned then this method | If the current position in memory is already aligned then this method | ||||
| will simply return the pointer. | will simply return the pointer. | ||||
| */ | */ | ||||
| static inline Type* getNextSIMDAlignedPtr (Type* ptr) noexcept | |||||
| static inline ElementType* getNextSIMDAlignedPtr (ElementType* ptr) noexcept | |||||
| { | { | ||||
| return snapPointerToAlignment (ptr, SIMDRegisterSize); | return snapPointerToAlignment (ptr, SIMDRegisterSize); | ||||
| } | } | ||||