OpenShot Audio Library | OpenShotAudio  0.3.1
juce_SIMDRegister.h
1 /*
2  ==============================================================================
3 
4  This file is part of the JUCE library.
5  Copyright (c) 2017 - ROLI Ltd.
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 5 End-User License
11  Agreement and JUCE 5 Privacy Policy (both updated and effective as of the
12  27th April 2017).
13 
14  End User License Agreement: www.juce.com/juce-5-licence
15  Privacy Policy: www.juce.com/juce-5-privacy-policy
16 
17  Or: You may also use this code under the terms of the GPL v3 (see
18  www.gnu.org/licenses).
19 
20  JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
21  EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
22  DISCLAIMED.
23 
24  ==============================================================================
25 */
26 
27 namespace juce
28 {
29 namespace dsp
30 {
31 
32 #ifndef DOXYGEN
33  // This class is needed internally.
34  template <typename Scalar>
35  struct CmplxSIMDOps;
36 #endif
37 
38 //==============================================================================
62 template <typename Type>
64 {
65  //==============================================================================
67  using ElementType = Type;
68 
71 
74  using MaskType = typename SIMDInternal::MaskTypeFor<ElementType>::type;
75 
76  //==============================================================================
77  // Here are some types which are needed internally
78 
80  using PrimitiveType = typename SIMDInternal::PrimitiveType<ElementType>::type;
81 
83  using NativeOps = SIMDNativeOps<PrimitiveType>;
84 
86  using vSIMDType = typename NativeOps::vSIMDType;
87 
90 
93 
96  using CmplxOps = CmplxSIMDOps<ElementType>;
97 
100  struct ElementAccess;
101 
102  //==============================================================================
104  static constexpr size_t SIMDRegisterSize = sizeof (vSIMDType);
105 
107  static constexpr size_t SIMDNumElements = SIMDRegisterSize / sizeof (ElementType);
108 
109  vSIMDType value;
110 
112  inline SIMDRegister() noexcept = default;
113 
115  inline SIMDRegister (vSIMDType a) noexcept : value (a) {}
116 
118  inline SIMDRegister (Type s) noexcept { *this = s; }
119 
121  inline ~SIMDRegister() noexcept = default;
122 
123  //==============================================================================
125  static constexpr size_t size() noexcept { return SIMDNumElements; }
126 
127  //==============================================================================
130  inline static SIMDRegister JUCE_VECTOR_CALLTYPE expand (ElementType s) noexcept { return {CmplxOps::expand (s)}; }
131 
134  inline static SIMDRegister JUCE_VECTOR_CALLTYPE fromNative (vSIMDType a) noexcept { return {a}; }
135 
137  inline static SIMDRegister JUCE_VECTOR_CALLTYPE fromRawArray (const ElementType* a) noexcept
138  {
139  jassert (isSIMDAligned (a));
140  return {CmplxOps::load (a)};
141  }
142 
144  inline void JUCE_VECTOR_CALLTYPE copyToRawArray (ElementType* a) const noexcept
145  {
146  jassert (isSIMDAligned (a));
147  CmplxOps::store (value, a);
148  }
149 
150  //==============================================================================
153  inline ElementType JUCE_VECTOR_CALLTYPE get (size_t idx) const noexcept
154  {
155  jassert (idx < SIMDNumElements);
156  return CmplxOps::get (value, idx);
157  }
158 
161  inline void JUCE_VECTOR_CALLTYPE set (size_t idx, ElementType v) noexcept
162  {
163  jassert (idx < SIMDNumElements);
164  value = CmplxOps::set (value, idx, v);
165  }
166 
167  //==============================================================================
170  inline ElementType JUCE_VECTOR_CALLTYPE operator[] (size_t idx) const noexcept
171  {
172  return get (idx);
173  }
174 
177  inline ElementAccess JUCE_VECTOR_CALLTYPE operator[] (size_t idx) noexcept
178  {
179  jassert (idx < SIMDNumElements);
180  return ElementAccess (*this, idx);
181  }
182 
183  //==============================================================================
185  inline SIMDRegister& JUCE_VECTOR_CALLTYPE operator+= (SIMDRegister v) noexcept { value = NativeOps::add (value, v.value); return *this; }
186 
188  inline SIMDRegister& JUCE_VECTOR_CALLTYPE operator-= (SIMDRegister v) noexcept { value = NativeOps::sub (value, v.value); return *this; }
189 
191  inline SIMDRegister& JUCE_VECTOR_CALLTYPE operator*= (SIMDRegister v) noexcept { value = CmplxOps::mul (value, v.value); return *this; }
192 
193  //==============================================================================
195  inline SIMDRegister& JUCE_VECTOR_CALLTYPE operator= (ElementType s) noexcept { value = CmplxOps::expand (s); return *this; }
196 
198  inline SIMDRegister& JUCE_VECTOR_CALLTYPE operator+= (ElementType s) noexcept { value = NativeOps::add (value, CmplxOps::expand (s)); return *this; }
199 
201  inline SIMDRegister& JUCE_VECTOR_CALLTYPE operator-= (ElementType s) noexcept { value = NativeOps::sub (value, CmplxOps::expand (s)); return *this; }
202 
204  inline SIMDRegister& JUCE_VECTOR_CALLTYPE operator*= (ElementType s) noexcept { value = CmplxOps::mul (value, CmplxOps::expand (s)); return *this; }
205 
206  //==============================================================================
208  inline SIMDRegister& JUCE_VECTOR_CALLTYPE operator&= (vMaskType v) noexcept { value = NativeOps::bit_and (value, toVecType (v.value)); return *this; }
209 
211  inline SIMDRegister& JUCE_VECTOR_CALLTYPE operator|= (vMaskType v) noexcept { value = NativeOps::bit_or (value, toVecType (v.value)); return *this; }
212 
214  inline SIMDRegister& JUCE_VECTOR_CALLTYPE operator^= (vMaskType v) noexcept { value = NativeOps::bit_xor (value, toVecType (v.value)); return *this; }
215 
216  //==============================================================================
218  inline SIMDRegister& JUCE_VECTOR_CALLTYPE operator&= (MaskType s) noexcept { value = NativeOps::bit_and (value, toVecType (s)); return *this; }
219 
221  inline SIMDRegister& JUCE_VECTOR_CALLTYPE operator|= (MaskType s) noexcept { value = NativeOps::bit_or (value, toVecType (s)); return *this; }
222 
224  inline SIMDRegister& JUCE_VECTOR_CALLTYPE operator^= (MaskType s) noexcept { value = NativeOps::bit_xor (value, toVecType (s)); return *this; }
225 
226  //==============================================================================
228  inline SIMDRegister JUCE_VECTOR_CALLTYPE operator+ (SIMDRegister v) const noexcept { return { NativeOps::add (value, v.value) }; }
229 
231  inline SIMDRegister JUCE_VECTOR_CALLTYPE operator- (SIMDRegister v) const noexcept { return { NativeOps::sub (value, v.value) }; }
232 
234  inline SIMDRegister JUCE_VECTOR_CALLTYPE operator* (SIMDRegister v) const noexcept { return { CmplxOps::mul (value, v.value) }; }
235 
236  //==============================================================================
238  inline SIMDRegister JUCE_VECTOR_CALLTYPE operator+ (ElementType s) const noexcept { return { NativeOps::add (value, CmplxOps::expand (s)) }; }
239 
241  inline SIMDRegister JUCE_VECTOR_CALLTYPE operator- (ElementType s) const noexcept { return { NativeOps::sub (value, CmplxOps::expand (s)) }; }
242 
244  inline SIMDRegister JUCE_VECTOR_CALLTYPE operator* (ElementType s) const noexcept { return { CmplxOps::mul (value, CmplxOps::expand (s)) }; }
245 
246  //==============================================================================
248  inline SIMDRegister JUCE_VECTOR_CALLTYPE operator& (vMaskType v) const noexcept { return { NativeOps::bit_and (value, toVecType (v.value)) }; }
249 
251  inline SIMDRegister JUCE_VECTOR_CALLTYPE operator| (vMaskType v) const noexcept { return { NativeOps::bit_or (value, toVecType (v.value)) }; }
252 
254  inline SIMDRegister JUCE_VECTOR_CALLTYPE operator^ (vMaskType v) const noexcept { return { NativeOps::bit_xor (value, toVecType (v.value)) }; }
255 
257  inline SIMDRegister JUCE_VECTOR_CALLTYPE operator~() const noexcept { return { NativeOps::bit_not (value) }; }
258 
259  //==============================================================================
261  inline SIMDRegister JUCE_VECTOR_CALLTYPE operator& (MaskType s) const noexcept { return { NativeOps::bit_and (value, toVecType (s)) }; }
262 
264  inline SIMDRegister JUCE_VECTOR_CALLTYPE operator| (MaskType s) const noexcept { return { NativeOps::bit_or (value, toVecType (s)) }; }
265 
267  inline SIMDRegister JUCE_VECTOR_CALLTYPE operator^ (MaskType s) const noexcept { return { NativeOps::bit_xor (value, toVecType (s)) }; }
268 
269  //==============================================================================
271  inline bool JUCE_VECTOR_CALLTYPE operator== (SIMDRegister other) const noexcept { return NativeOps::allEqual (value, other.value); }
272 
274  inline bool JUCE_VECTOR_CALLTYPE operator!= (SIMDRegister other) const noexcept { return ! (*this == other); }
275 
277  inline bool JUCE_VECTOR_CALLTYPE operator== (Type s) const noexcept { return *this == SIMDRegister::expand (s); }
278 
280  inline bool JUCE_VECTOR_CALLTYPE operator!= (Type s) const noexcept { return ! (*this == s); }
281 
282  //==============================================================================
286  static inline vMaskType JUCE_VECTOR_CALLTYPE equal (SIMDRegister a, SIMDRegister b) noexcept { return toMaskType (NativeOps::equal (a.value, b.value)); }
287 
291  static inline vMaskType JUCE_VECTOR_CALLTYPE notEqual (SIMDRegister a, SIMDRegister b) noexcept { return toMaskType (NativeOps::notEqual (a.value, b.value)); }
292 
296  static inline vMaskType JUCE_VECTOR_CALLTYPE lessThan (SIMDRegister a, SIMDRegister b) noexcept { return toMaskType (NativeOps::greaterThan (b.value, a.value)); }
297 
301  static inline vMaskType JUCE_VECTOR_CALLTYPE lessThanOrEqual (SIMDRegister a, SIMDRegister b) noexcept { return toMaskType (NativeOps::greaterThanOrEqual (b.value, a.value)); }
302 
306  static inline vMaskType JUCE_VECTOR_CALLTYPE greaterThan (SIMDRegister a, SIMDRegister b) noexcept { return toMaskType (NativeOps::greaterThan (a.value, b.value)); }
307 
311  static inline vMaskType JUCE_VECTOR_CALLTYPE greaterThanOrEqual (SIMDRegister a, SIMDRegister b) noexcept { return toMaskType (NativeOps::greaterThanOrEqual (a.value, b.value)); }
312 
313  //==============================================================================
315  static inline SIMDRegister JUCE_VECTOR_CALLTYPE min (SIMDRegister a, SIMDRegister b) noexcept { return { NativeOps::min (a.value, b.value) }; }
316 
318  static inline SIMDRegister JUCE_VECTOR_CALLTYPE max (SIMDRegister a, SIMDRegister b) noexcept { return { NativeOps::max (a.value, b.value) }; }
319 
320  //==============================================================================
322  static inline SIMDRegister JUCE_VECTOR_CALLTYPE multiplyAdd (SIMDRegister a, const SIMDRegister b, SIMDRegister c) noexcept
323  {
324  return { CmplxOps::muladd (a.value, b.value, c.value) };
325  }
326 
327  //==============================================================================
329  inline ElementType sum() const noexcept { return CmplxOps::sum (value); }
330 
331  //==============================================================================
334  static inline SIMDRegister JUCE_VECTOR_CALLTYPE truncate (SIMDRegister a) noexcept { return { NativeOps::truncate (a.value) }; }
335 
336  //==============================================================================
338  static inline SIMDRegister JUCE_VECTOR_CALLTYPE abs (SIMDRegister a) noexcept
339  {
340  return a - (a * (expand (ElementType (2)) & lessThan (a, expand (ElementType (0)))));
341  }
342 
343  //==============================================================================
345  static inline bool isSIMDAligned (const ElementType* ptr) noexcept
346  {
347  uintptr_t bitmask = SIMDRegisterSize - 1;
348  return (reinterpret_cast<uintptr_t> (ptr) & bitmask) == 0;
349  }
350 
356  static inline ElementType* getNextSIMDAlignedPtr (ElementType* ptr) noexcept
357  {
358  return snapPointerToAlignment (ptr, SIMDRegisterSize);
359  }
360 
361 private:
362  static inline vMaskType JUCE_VECTOR_CALLTYPE toMaskType (vSIMDType a) noexcept
363  {
364  union
365  {
366  vSIMDType in;
367  vMaskSIMDType out;
368  } u;
369 
370  u.in = a;
371  return vMaskType::fromNative (u.out);
372  }
373 
374  static inline vSIMDType JUCE_VECTOR_CALLTYPE toVecType (vMaskSIMDType a) noexcept
375  {
376  union
377  {
378  vMaskSIMDType in;
379  vSIMDType out;
380  } u;
381 
382  u.in = a;
383  return u.out;
384  }
385 
386  static inline vSIMDType JUCE_VECTOR_CALLTYPE toVecType (MaskType a) noexcept
387  {
388  union
389  {
390  vMaskSIMDType in;
391  vSIMDType out;
392  } u;
393 
394  u.in = CmplxSIMDOps<MaskType>::expand (a);
395  return u.out;
396  }
397 };
398 
399 } // namespace dsp
400 } // namespace juce
401 
402 #ifndef DOXYGEN
403  #include "juce_SIMDRegister_Impl.h"
404 #endif
static SIMDRegister JUCE_VECTOR_CALLTYPE truncate(SIMDRegister a) noexcept
static SIMDRegister JUCE_VECTOR_CALLTYPE expand(ElementType s) noexcept
typename NativeOps::vSIMDType vSIMDType
ElementType sum() const noexcept
void JUCE_VECTOR_CALLTYPE copyToRawArray(ElementType *a) const noexcept
SIMDRegister &JUCE_VECTOR_CALLTYPE operator|=(vMaskType v) noexcept
static SIMDRegister JUCE_VECTOR_CALLTYPE max(SIMDRegister a, SIMDRegister b) noexcept
static vMaskType JUCE_VECTOR_CALLTYPE greaterThanOrEqual(SIMDRegister a, SIMDRegister b) noexcept
SIMDRegister &JUCE_VECTOR_CALLTYPE operator&=(vMaskType v) noexcept
static vMaskType JUCE_VECTOR_CALLTYPE greaterThan(SIMDRegister a, SIMDRegister b) noexcept
bool JUCE_VECTOR_CALLTYPE operator!=(SIMDRegister other) const noexcept
static bool isSIMDAligned(const ElementType *ptr) noexcept
static SIMDRegister JUCE_VECTOR_CALLTYPE abs(SIMDRegister a) noexcept
SIMDRegister JUCE_VECTOR_CALLTYPE operator|(vMaskType v) const noexcept
SIMDRegister< MaskType > vMaskType
static constexpr size_t SIMDRegisterSize
static vMaskType JUCE_VECTOR_CALLTYPE equal(SIMDRegister a, SIMDRegister b) noexcept
ElementType JUCE_VECTOR_CALLTYPE get(size_t idx) const noexcept
SIMDRegister &JUCE_VECTOR_CALLTYPE operator=(ElementType s) noexcept
SIMDNativeOps< PrimitiveType > NativeOps
SIMDRegister &JUCE_VECTOR_CALLTYPE operator^=(vMaskType v) noexcept
static SIMDRegister JUCE_VECTOR_CALLTYPE multiplyAdd(SIMDRegister a, const SIMDRegister b, SIMDRegister c) noexcept
static constexpr size_t size() noexcept
static vMaskType JUCE_VECTOR_CALLTYPE lessThan(SIMDRegister a, SIMDRegister b) noexcept
SIMDRegister() noexcept=default
static SIMDRegister JUCE_VECTOR_CALLTYPE min(SIMDRegister a, SIMDRegister b) noexcept
static constexpr size_t SIMDNumElements
typename vMaskType::vSIMDType vMaskSIMDType
~SIMDRegister() noexcept=default
void JUCE_VECTOR_CALLTYPE set(size_t idx, ElementType v) noexcept
static vMaskType JUCE_VECTOR_CALLTYPE lessThanOrEqual(SIMDRegister a, SIMDRegister b) noexcept
SIMDRegister JUCE_VECTOR_CALLTYPE operator~() const noexcept
SIMDRegister JUCE_VECTOR_CALLTYPE operator^(vMaskType v) const noexcept
SIMDRegister &JUCE_VECTOR_CALLTYPE operator-=(SIMDRegister v) noexcept
static ElementType * getNextSIMDAlignedPtr(ElementType *ptr) noexcept
SIMDRegister(Type s) noexcept
static SIMDRegister JUCE_VECTOR_CALLTYPE fromNative(vSIMDType a) noexcept
typename SIMDInternal::MaskTypeFor< ElementType >::type MaskType
CmplxSIMDOps< ElementType > CmplxOps
typename SIMDInternal::PrimitiveType< ElementType >::type PrimitiveType
SIMDRegister JUCE_VECTOR_CALLTYPE operator&(vMaskType v) const noexcept
static SIMDRegister JUCE_VECTOR_CALLTYPE fromRawArray(const ElementType *a) noexcept
SIMDRegister &JUCE_VECTOR_CALLTYPE operator*=(SIMDRegister v) noexcept
SIMDRegister JUCE_VECTOR_CALLTYPE operator+(SIMDRegister v) const noexcept
ElementType JUCE_VECTOR_CALLTYPE operator[](size_t idx) const noexcept
static vMaskType JUCE_VECTOR_CALLTYPE notEqual(SIMDRegister a, SIMDRegister b) noexcept
SIMDRegister JUCE_VECTOR_CALLTYPE operator*(SIMDRegister v) const noexcept
SIMDRegister JUCE_VECTOR_CALLTYPE operator-(SIMDRegister v) const noexcept
SIMDRegister &JUCE_VECTOR_CALLTYPE operator+=(SIMDRegister v) noexcept
bool JUCE_VECTOR_CALLTYPE operator==(SIMDRegister other) const noexcept