JUCE-7.0.12-0-g4f43011b96 JUCE-7.0.12-0-g4f43011b96
JUCE — C++ application framework with suport for VST, VST3, LV2 audio plug-ins

« « « Anklang Documentation
Loading...
Searching...
No Matches
juce_SIMDRegister.h
Go to the documentation of this file.
1 /*
2 ==============================================================================
3
4 This file is part of the JUCE library.
5 Copyright (c) 2022 - Raw Material Software Limited
6
7 JUCE is an open source library subject to commercial or open-source
8 licensing.
9
10 By using JUCE, you agree to the terms of both the JUCE 7 End-User License
11 Agreement and JUCE Privacy Policy.
12
13 End User License Agreement: www.juce.com/juce-7-licence
14 Privacy Policy: www.juce.com/juce-privacy-policy
15
16 Or: You may also use this code under the terms of the GPL v3 (see
17 www.gnu.org/licenses).
18
19 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
20 EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
21 DISCLAIMED.
22
23 ==============================================================================
24*/
25
26namespace juce::dsp
27{
28
29#ifndef DOXYGEN
30 // This class is needed internally.
31 template <typename Scalar>
32 struct CmplxSIMDOps;
33#endif
34
35//==============================================================================
59template <typename Type>
61{
62 //==============================================================================
64 using ElementType = Type;
65
68
71 using MaskType = SIMDInternal::MaskType<ElementType>;
72
73 //==============================================================================
74 // Here are some types which are needed internally
75
78
81
83 using vSIMDType = typename NativeOps::vSIMDType;
84
87
90
94
97 struct ElementAccess;
98
99 //==============================================================================
101 static constexpr size_t SIMDRegisterSize = sizeof (vSIMDType);
102
104 static constexpr size_t SIMDNumElements = SIMDRegisterSize / sizeof (ElementType);
105
106 vSIMDType value;
107
109 inline SIMDRegister() noexcept = default;
110
112 inline SIMDRegister (vSIMDType a) noexcept : value (a) {}
113
115 inline SIMDRegister (Type s) noexcept { *this = s; }
116
117 //==============================================================================
119 static constexpr size_t size() noexcept { return SIMDNumElements; }
120
121 //==============================================================================
124 static SIMDRegister JUCE_VECTOR_CALLTYPE expand (ElementType s) noexcept { return {CmplxOps::expand (s)}; }
125
128 static SIMDRegister JUCE_VECTOR_CALLTYPE fromNative (vSIMDType a) noexcept { return {a}; }
129
131 static SIMDRegister JUCE_VECTOR_CALLTYPE fromRawArray (const ElementType* a) noexcept
132 {
134 return {CmplxOps::load (a)};
135 }
136
138 inline void JUCE_VECTOR_CALLTYPE copyToRawArray (ElementType* a) const noexcept
139 {
141 CmplxOps::store (value, a);
142 }
143
144 //==============================================================================
147 inline ElementType JUCE_VECTOR_CALLTYPE get (size_t idx) const noexcept
148 {
149 jassert (idx < SIMDNumElements);
150 return CmplxOps::get (value, idx);
151 }
152
155 inline void JUCE_VECTOR_CALLTYPE set (size_t idx, ElementType v) noexcept
156 {
157 jassert (idx < SIMDNumElements);
158 value = CmplxOps::set (value, idx, v);
159 }
160
161 //==============================================================================
164 inline ElementType JUCE_VECTOR_CALLTYPE operator[] (size_t idx) const noexcept
165 {
166 return get (idx);
167 }
168
171 inline ElementAccess JUCE_VECTOR_CALLTYPE operator[] (size_t idx) noexcept
172 {
173 jassert (idx < SIMDNumElements);
174 return ElementAccess (*this, idx);
175 }
176
177 //==============================================================================
179 inline SIMDRegister& JUCE_VECTOR_CALLTYPE operator+= (SIMDRegister v) noexcept { value = NativeOps::add (value, v.value); return *this; }
180
182 inline SIMDRegister& JUCE_VECTOR_CALLTYPE operator-= (SIMDRegister v) noexcept { value = NativeOps::sub (value, v.value); return *this; }
183
185 inline SIMDRegister& JUCE_VECTOR_CALLTYPE operator*= (SIMDRegister v) noexcept { value = CmplxOps::mul (value, v.value); return *this; }
186
187 //==============================================================================
189 inline SIMDRegister& JUCE_VECTOR_CALLTYPE operator= (ElementType s) noexcept { value = CmplxOps::expand (s); return *this; }
190
192 inline SIMDRegister& JUCE_VECTOR_CALLTYPE operator+= (ElementType s) noexcept { value = NativeOps::add (value, CmplxOps::expand (s)); return *this; }
193
195 inline SIMDRegister& JUCE_VECTOR_CALLTYPE operator-= (ElementType s) noexcept { value = NativeOps::sub (value, CmplxOps::expand (s)); return *this; }
196
198 inline SIMDRegister& JUCE_VECTOR_CALLTYPE operator*= (ElementType s) noexcept { value = CmplxOps::mul (value, CmplxOps::expand (s)); return *this; }
199
200 //==============================================================================
202 inline SIMDRegister& JUCE_VECTOR_CALLTYPE operator&= (vMaskType v) noexcept { value = NativeOps::bit_and (value, toVecType (v.value)); return *this; }
203
205 inline SIMDRegister& JUCE_VECTOR_CALLTYPE operator|= (vMaskType v) noexcept { value = NativeOps::bit_or (value, toVecType (v.value)); return *this; }
206
208 inline SIMDRegister& JUCE_VECTOR_CALLTYPE operator^= (vMaskType v) noexcept { value = NativeOps::bit_xor (value, toVecType (v.value)); return *this; }
209
210 //==============================================================================
212 inline SIMDRegister& JUCE_VECTOR_CALLTYPE operator&= (MaskType s) noexcept { value = NativeOps::bit_and (value, toVecType (s)); return *this; }
213
215 inline SIMDRegister& JUCE_VECTOR_CALLTYPE operator|= (MaskType s) noexcept { value = NativeOps::bit_or (value, toVecType (s)); return *this; }
216
218 inline SIMDRegister& JUCE_VECTOR_CALLTYPE operator^= (MaskType s) noexcept { value = NativeOps::bit_xor (value, toVecType (s)); return *this; }
219
220 //==============================================================================
222 inline SIMDRegister JUCE_VECTOR_CALLTYPE operator+ (SIMDRegister v) const noexcept { return { NativeOps::add (value, v.value) }; }
223
225 inline SIMDRegister JUCE_VECTOR_CALLTYPE operator- (SIMDRegister v) const noexcept { return { NativeOps::sub (value, v.value) }; }
226
228 inline SIMDRegister JUCE_VECTOR_CALLTYPE operator* (SIMDRegister v) const noexcept { return { CmplxOps::mul (value, v.value) }; }
229
230 //==============================================================================
232 inline SIMDRegister JUCE_VECTOR_CALLTYPE operator+ (ElementType s) const noexcept { return { NativeOps::add (value, CmplxOps::expand (s)) }; }
233
235 inline SIMDRegister JUCE_VECTOR_CALLTYPE operator- (ElementType s) const noexcept { return { NativeOps::sub (value, CmplxOps::expand (s)) }; }
236
238 inline SIMDRegister JUCE_VECTOR_CALLTYPE operator* (ElementType s) const noexcept { return { CmplxOps::mul (value, CmplxOps::expand (s)) }; }
239
240 //==============================================================================
242 inline SIMDRegister JUCE_VECTOR_CALLTYPE operator& (vMaskType v) const noexcept { return { NativeOps::bit_and (value, toVecType (v.value)) }; }
243
245 inline SIMDRegister JUCE_VECTOR_CALLTYPE operator| (vMaskType v) const noexcept { return { NativeOps::bit_or (value, toVecType (v.value)) }; }
246
248 inline SIMDRegister JUCE_VECTOR_CALLTYPE operator^ (vMaskType v) const noexcept { return { NativeOps::bit_xor (value, toVecType (v.value)) }; }
249
251 inline SIMDRegister JUCE_VECTOR_CALLTYPE operator~() const noexcept { return { NativeOps::bit_not (value) }; }
252
253 //==============================================================================
255 inline SIMDRegister JUCE_VECTOR_CALLTYPE operator& (MaskType s) const noexcept { return { NativeOps::bit_and (value, toVecType (s)) }; }
256
258 inline SIMDRegister JUCE_VECTOR_CALLTYPE operator| (MaskType s) const noexcept { return { NativeOps::bit_or (value, toVecType (s)) }; }
259
261 inline SIMDRegister JUCE_VECTOR_CALLTYPE operator^ (MaskType s) const noexcept { return { NativeOps::bit_xor (value, toVecType (s)) }; }
262
263 //==============================================================================
265 inline bool JUCE_VECTOR_CALLTYPE operator== (SIMDRegister other) const noexcept { return NativeOps::allEqual (value, other.value); }
266
268 inline bool JUCE_VECTOR_CALLTYPE operator!= (SIMDRegister other) const noexcept { return ! (*this == other); }
269
271 inline bool JUCE_VECTOR_CALLTYPE operator== (Type s) const noexcept { return *this == SIMDRegister::expand (s); }
272
274 inline bool JUCE_VECTOR_CALLTYPE operator!= (Type s) const noexcept { return ! (*this == s); }
275
276 //==============================================================================
280 static vMaskType JUCE_VECTOR_CALLTYPE equal (SIMDRegister a, SIMDRegister b) noexcept { return toMaskType (NativeOps::equal (a.value, b.value)); }
281
285 static vMaskType JUCE_VECTOR_CALLTYPE notEqual (SIMDRegister a, SIMDRegister b) noexcept { return toMaskType (NativeOps::notEqual (a.value, b.value)); }
286
290 static vMaskType JUCE_VECTOR_CALLTYPE lessThan (SIMDRegister a, SIMDRegister b) noexcept { return toMaskType (NativeOps::greaterThan (b.value, a.value)); }
291
295 static vMaskType JUCE_VECTOR_CALLTYPE lessThanOrEqual (SIMDRegister a, SIMDRegister b) noexcept { return toMaskType (NativeOps::greaterThanOrEqual (b.value, a.value)); }
296
300 static vMaskType JUCE_VECTOR_CALLTYPE greaterThan (SIMDRegister a, SIMDRegister b) noexcept { return toMaskType (NativeOps::greaterThan (a.value, b.value)); }
301
305 static vMaskType JUCE_VECTOR_CALLTYPE greaterThanOrEqual (SIMDRegister a, SIMDRegister b) noexcept { return toMaskType (NativeOps::greaterThanOrEqual (a.value, b.value)); }
306
307 //==============================================================================
309 static SIMDRegister JUCE_VECTOR_CALLTYPE min (SIMDRegister a, SIMDRegister b) noexcept { return { NativeOps::min (a.value, b.value) }; }
310
312 static SIMDRegister JUCE_VECTOR_CALLTYPE max (SIMDRegister a, SIMDRegister b) noexcept { return { NativeOps::max (a.value, b.value) }; }
313
314 //==============================================================================
316 static SIMDRegister JUCE_VECTOR_CALLTYPE multiplyAdd (SIMDRegister a, const SIMDRegister b, SIMDRegister c) noexcept
317 {
318 return { CmplxOps::muladd (a.value, b.value, c.value) };
319 }
320
321 //==============================================================================
323 inline ElementType sum() const noexcept { return CmplxOps::sum (value); }
324
325 //==============================================================================
328 static SIMDRegister JUCE_VECTOR_CALLTYPE truncate (SIMDRegister a) noexcept { return { NativeOps::truncate (a.value) }; }
329
330 //==============================================================================
332 static SIMDRegister JUCE_VECTOR_CALLTYPE abs (SIMDRegister a) noexcept
333 {
334 return a - (a * (expand (ElementType (2)) & lessThan (a, expand (ElementType (0)))));
335 }
336
337 //==============================================================================
339 static bool isSIMDAligned (const ElementType* ptr) noexcept
340 {
342 return (reinterpret_cast<uintptr_t> (ptr) & bitmask) == 0;
343 }
344
351 {
353 }
354
355private:
356 static vMaskType JUCE_VECTOR_CALLTYPE toMaskType (vSIMDType a) noexcept
357 {
358 union
359 {
360 vSIMDType in;
361 vMaskSIMDType out;
362 } u;
363
364 u.in = a;
365 return vMaskType::fromNative (u.out);
366 }
367
368 static vSIMDType JUCE_VECTOR_CALLTYPE toVecType (vMaskSIMDType a) noexcept
369 {
370 union
371 {
372 vMaskSIMDType in;
373 vSIMDType out;
374 } u;
375
376 u.in = a;
377 return u.out;
378 }
379
380 static vSIMDType JUCE_VECTOR_CALLTYPE toVecType (MaskType a) noexcept
381 {
382 union
383 {
384 vMaskSIMDType in;
385 vSIMDType out;
386 } u;
387
388 u.in = CmplxSIMDOps<MaskType>::expand (a);
389 return u.out;
390 }
391};
392
393} // namespace juce::dsp
#define jassert(expression)
Platform-independent assertion macro.
Type unalignedPointerCast(void *ptr) noexcept
Casts a pointer to another type via void*, which suppresses the cast-align warning which sometimes ar...
Definition juce_Memory.h:88
Type * snapPointerToAlignment(Type *basePointer, IntegerType alignmentBytes) noexcept
A handy function to round up a pointer to the nearest multiple of a given number of bytes.
Definition juce_Memory.h:45
typedef uintptr_t
A wrapper around the platform's native SIMD register type.
static SIMDRegister JUCE_VECTOR_CALLTYPE truncate(SIMDRegister a) noexcept
Truncates each element to its integer part.
SIMDRegister &JUCE_VECTOR_CALLTYPE operator*=(SIMDRegister v) noexcept
Multiplies another SIMDRegister to the receiver.
static SIMDRegister JUCE_VECTOR_CALLTYPE expand(ElementType s) noexcept
Creates a new SIMDRegister from the corresponding scalar primitive.
typename NativeOps::vSIMDType vSIMDType
The native type (used internally).
ElementType sum() const noexcept
Returns a scalar which is the sum of all elements of the receiver.
void JUCE_VECTOR_CALLTYPE copyToRawArray(ElementType *a) const noexcept
Copies the elements of the SIMDRegister to a scalar array in memory.
SIMDRegister &JUCE_VECTOR_CALLTYPE operator=(ElementType s) noexcept
Broadcasts the scalar to all elements of the receiver.
static SIMDRegister JUCE_VECTOR_CALLTYPE max(SIMDRegister a, SIMDRegister b) noexcept
Returns a new vector where each element is the maximum of the corresponding element of a and b.
static ElementType * getNextSIMDAlignedPtr(ElementType *ptr) noexcept
Returns the next position in memory where isSIMDAligned returns true.
static vMaskType JUCE_VECTOR_CALLTYPE greaterThanOrEqual(SIMDRegister a, SIMDRegister b) noexcept
Returns a SIMDRegister of the corresponding integral type where each element has each bit set if the ...
static vMaskType JUCE_VECTOR_CALLTYPE greaterThan(SIMDRegister a, SIMDRegister b) noexcept
Returns a SIMDRegister of the corresponding integral type where each element has each bit set if the ...
bool JUCE_VECTOR_CALLTYPE operator!=(SIMDRegister other) const noexcept
Returns true if any element-wise comparisons return false.
static bool isSIMDAligned(const ElementType *ptr) noexcept
Checks if the given pointer is sufficiently aligned for using SIMD operations.
static SIMDRegister JUCE_VECTOR_CALLTYPE abs(SIMDRegister a) noexcept
Returns the absolute value of each element.
SIMDRegister JUCE_VECTOR_CALLTYPE operator|(vMaskType v) const noexcept
Returns the bit-or of the receiver and v.
SIMDRegister< MaskType > vMaskType
The corresponding integer SIMDRegister type (used internally).
static constexpr size_t SIMDRegisterSize
The size in bytes of this register.
SIMDRegister &JUCE_VECTOR_CALLTYPE operator^=(vMaskType v) noexcept
Bit-xor the receiver with SIMDRegister v and store the result in the receiver.
static vMaskType JUCE_VECTOR_CALLTYPE equal(SIMDRegister a, SIMDRegister b) noexcept
Returns a SIMDRegister of the corresponding integral type where each element has each bit set if the ...
ElementType JUCE_VECTOR_CALLTYPE get(size_t idx) const noexcept
Returns the idx-th element of the receiver.
SIMDRegister &JUCE_VECTOR_CALLTYPE operator-=(SIMDRegister v) noexcept
Subtracts another SIMDRegister to the receiver.
SIMDRegister &JUCE_VECTOR_CALLTYPE operator&=(vMaskType v) noexcept
Bit-and the receiver with SIMDRegister v and store the result in the receiver.
SIMDNativeOps< PrimitiveType > NativeOps
The native operations for this platform and type combination (used internally)
static SIMDRegister JUCE_VECTOR_CALLTYPE multiplyAdd(SIMDRegister a, const SIMDRegister b, SIMDRegister c) noexcept
Multiplies b and c and adds the result to a.
static constexpr size_t size() noexcept
Returns the number of elements in this vector.
static vMaskType JUCE_VECTOR_CALLTYPE lessThan(SIMDRegister a, SIMDRegister b) noexcept
Returns a SIMDRegister of the corresponding integral type where each element has each bit set if the ...
SIMDRegister() noexcept=default
Default constructor.
Type ElementType
The type that represents the individual constituents of the SIMD Register.
static SIMDRegister JUCE_VECTOR_CALLTYPE min(SIMDRegister a, SIMDRegister b) noexcept
Returns a new vector where each element is the minimum of the corresponding element of a and b.
static constexpr size_t SIMDNumElements
The number of elements that this vector can hold.
typename vMaskType::vSIMDType vMaskSIMDType
The internal native type for the corresponding mask type (used internally).
SIMDInternal::MaskType< ElementType > MaskType
The corresponding primitive integer type, for example, this will be int32_t if type is a float.
void JUCE_VECTOR_CALLTYPE set(size_t idx, ElementType v) noexcept
Sets the idx-th element of the receiver.
SIMDRegister &JUCE_VECTOR_CALLTYPE operator+=(SIMDRegister v) noexcept
Adds another SIMDRegister to the receiver.
static vMaskType JUCE_VECTOR_CALLTYPE lessThanOrEqual(SIMDRegister a, SIMDRegister b) noexcept
Returns a SIMDRegister of the corresponding integral type where each element has each bit set if the ...
SIMDRegister JUCE_VECTOR_CALLTYPE operator~() const noexcept
Returns a vector where each element is the bit-inverted value of the corresponding element in the rec...
SIMDRegister JUCE_VECTOR_CALLTYPE operator^(vMaskType v) const noexcept
Returns the bit-xor of the receiver and v.
SIMDRegister(Type s) noexcept
Constructs an object from a scalar type by broadcasting it to all elements.
static SIMDRegister JUCE_VECTOR_CALLTYPE fromNative(vSIMDType a) noexcept
Creates a new SIMDRegister from the internal SIMD type (for example __mm128 for single-precision floa...
CmplxSIMDOps< ElementType > CmplxOps
Wrapper for operations which need to be handled differently for complex and scalar types (used intern...
typename SIMDInternal::PrimitiveType< ElementType >::type PrimitiveType
The native primitive type (used internally).
SIMDRegister &JUCE_VECTOR_CALLTYPE operator|=(vMaskType v) noexcept
Bit-or the receiver with SIMDRegister v and store the result in the receiver.
SIMDRegister JUCE_VECTOR_CALLTYPE operator&(vMaskType v) const noexcept
Returns the bit-and of the receiver and v.
static SIMDRegister JUCE_VECTOR_CALLTYPE fromRawArray(const ElementType *a) noexcept
Creates a new SIMDRegister from the first SIMDNumElements of a scalar array.
SIMDRegister JUCE_VECTOR_CALLTYPE operator+(SIMDRegister v) const noexcept
Returns the sum of the receiver and v.
ElementType JUCE_VECTOR_CALLTYPE operator[](size_t idx) const noexcept
Returns the idx-th element of the receiver.
static vMaskType JUCE_VECTOR_CALLTYPE notEqual(SIMDRegister a, SIMDRegister b) noexcept
Returns a SIMDRegister of the corresponding integral type where each element has each bit set if the ...
SIMDRegister JUCE_VECTOR_CALLTYPE operator*(SIMDRegister v) const noexcept
Returns the product of the receiver and v.
SIMDRegister JUCE_VECTOR_CALLTYPE operator-(SIMDRegister v) const noexcept
Returns the difference of the receiver and v.
ElementType value_type
STL compatible value_type definition (same as ElementType).
bool JUCE_VECTOR_CALLTYPE operator==(SIMDRegister other) const noexcept
Returns true if all element-wise comparisons return true.