| @@ -61,21 +61,24 @@ template <typename Type> | |||
| 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 | |||
| 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 | |||
| /** 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) */ | |||
| typedef SIMDNativeOps<ElementType> NativeOps; | |||
| typedef SIMDNativeOps<PrimitiveType> NativeOps; | |||
| /** The native type (used internally). */ | |||
| typedef typename NativeOps::vSIMDType vSIMDType; | |||
| @@ -88,14 +91,14 @@ struct SIMDRegister | |||
| /** Wrapper for operations which need to be handled differently for complex | |||
| and scalar types (used internally). */ | |||
| typedef CmplxSIMDOps<Type> CmplxOps; | |||
| typedef CmplxSIMDOps<ElementType> CmplxOps; | |||
| //============================================================================== | |||
| /** The size in bytes of this register. */ | |||
| static constexpr size_t SIMDRegisterSize = sizeof (vSIMDType); | |||
| /** 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; | |||
| @@ -106,7 +109,7 @@ struct SIMDRegister | |||
| //============================================================================== | |||
| /** Creates a new SIMDRegister from the corresponding scalar primitive. | |||
| 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 | |||
| __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 | |||
| 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); | |||
| 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 | |||
| 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); | |||
| 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. */ | |||
| 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. */ | |||
| 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. */ | |||
| 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. */ | |||
| 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. */ | |||
| @@ -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.*/ | |||
| 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.*/ | |||
| 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.*/ | |||
| 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. */ | |||
| @@ -262,11 +265,11 @@ struct SIMDRegister | |||
| //============================================================================== | |||
| /** 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. */ | |||
| static inline bool isSIMDAligned (Type* ptr) noexcept | |||
| static inline bool isSIMDAligned (ElementType* ptr) noexcept | |||
| { | |||
| uintptr_t bitmask = SIMDRegisterSize - 1; | |||
| 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 | |||
| will simply return the pointer. | |||
| */ | |||
| static inline Type* getNextSIMDAlignedPtr (Type* ptr) noexcept | |||
| static inline ElementType* getNextSIMDAlignedPtr (ElementType* ptr) noexcept | |||
| { | |||
| return snapPointerToAlignment (ptr, SIMDRegisterSize); | |||
| } | |||