OpenShot Library | OpenShotAudio  0.2.2
juce_SIMDRegister_Impl.h
1 
2 /** @weakgroup juce_dsp-containers
3  * @{
4  */
5 /*
6  ==============================================================================
7 
8  This file is part of the JUCE library.
9  Copyright (c) 2017 - ROLI Ltd.
10 
11  JUCE is an open source library subject to commercial or open-source
12  licensing.
13 
14  By using JUCE, you agree to the terms of both the JUCE 5 End-User License
15  Agreement and JUCE 5 Privacy Policy (both updated and effective as of the
16  27th April 2017).
17 
18  End User License Agreement: www.juce.com/juce-5-licence
19  Privacy Policy: www.juce.com/juce-5-privacy-policy
20 
21  Or: You may also use this code under the terms of the GPL v3 (see
22  www.gnu.org/licenses).
23 
24  JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
25  EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
26  DISCLAIMED.
27 
28  ==============================================================================
29 */
30 
31 namespace juce
32 {
33 namespace dsp
34 {
35 
36 
37 //==============================================================================
38 template <typename Type>
40 {
41  operator Type() const { return simd.get (idx); }
42  ElementAccess& operator= (Type scalar) noexcept { simd.set (idx, scalar); return *this; }
43  ElementAccess& operator= (ElementAccess& o) noexcept { return operator= ((Type) o); }
44 
45 private:
46  friend struct SIMDRegister;
47  ElementAccess (SIMDRegister& owner, size_t index) noexcept : simd (owner), idx (index) {}
48  SIMDRegister& simd;
49  size_t idx;
50 };
51 
52 #ifndef DOXYGEN
53 //==============================================================================
54 /* This class is used internally by SIMDRegister to abstract away differences
55  in operations which are different for complex and pure floating point types. */
56 
57 // the pure floating-point version
58 template <typename Scalar>
59 struct CmplxSIMDOps
60 {
61  using vSIMDType = typename SIMDNativeOps<Scalar>::vSIMDType;
62 
63  static inline vSIMDType JUCE_VECTOR_CALLTYPE load (const Scalar* a) noexcept
64  {
65  return SIMDNativeOps<Scalar>::load (a);
66  }
67 
68  static inline void JUCE_VECTOR_CALLTYPE store (vSIMDType value, Scalar* dest) noexcept
69  {
70  SIMDNativeOps<Scalar>::store (value, dest);
71  }
72 
73  static inline vSIMDType JUCE_VECTOR_CALLTYPE expand (Scalar s) noexcept
74  {
75  return SIMDNativeOps<Scalar>::expand (s);
76  }
77 
78  static inline Scalar JUCE_VECTOR_CALLTYPE get (vSIMDType v, std::size_t i) noexcept
79  {
80  return SIMDNativeOps<Scalar>::get (v, i);
81  }
82 
83  static inline vSIMDType JUCE_VECTOR_CALLTYPE set (vSIMDType v, std::size_t i, Scalar s) noexcept
84  {
85  return SIMDNativeOps<Scalar>::set (v, i, s);
86  }
87 
88  static inline Scalar JUCE_VECTOR_CALLTYPE sum (vSIMDType a) noexcept
89  {
90  return SIMDNativeOps<Scalar>::sum (a);
91  }
92 
93  static inline vSIMDType JUCE_VECTOR_CALLTYPE mul (vSIMDType a, vSIMDType b) noexcept
94  {
95  return SIMDNativeOps<Scalar>::mul (a, b);
96  }
97 
98  static inline vSIMDType JUCE_VECTOR_CALLTYPE muladd (vSIMDType a, vSIMDType b, vSIMDType c) noexcept
99  {
100  return SIMDNativeOps<Scalar>::multiplyAdd (a, b, c);
101  }
102 };
103 
104 // The pure complex version
105 template <typename Scalar>
106 struct CmplxSIMDOps<std::complex<Scalar>>
107 {
108  using vSIMDType = typename SIMDNativeOps<Scalar>::vSIMDType;
109 
110  static inline vSIMDType JUCE_VECTOR_CALLTYPE load (const std::complex<Scalar>* a) noexcept
111  {
112  return SIMDNativeOps<Scalar>::load (reinterpret_cast<const Scalar*> (a));
113  }
114 
115  static inline void JUCE_VECTOR_CALLTYPE store (vSIMDType value, std::complex<Scalar>* dest) noexcept
116  {
117  SIMDNativeOps<Scalar>::store (value, reinterpret_cast<Scalar*> (dest));
118  }
119 
120  static inline vSIMDType JUCE_VECTOR_CALLTYPE expand (std::complex<Scalar> s) noexcept
121  {
122  const int n = sizeof (vSIMDType) / sizeof (Scalar);
123 
124  union
125  {
126  vSIMDType v;
127  Scalar floats[(size_t) n];
128  } u;
129 
130  for (int i = 0; i < n; ++i)
131  u.floats[i] = (i & 1) == 0 ? s.real() : s.imag();
132 
133  return u.v;
134  }
135 
136  static inline std::complex<Scalar> JUCE_VECTOR_CALLTYPE get (vSIMDType v, std::size_t i) noexcept
137  {
138  auto j = i << 1;
139  return std::complex<Scalar> (SIMDNativeOps<Scalar>::get (v, j), SIMDNativeOps<Scalar>::get (v, j + 1));
140  }
141 
142  static inline vSIMDType JUCE_VECTOR_CALLTYPE set (vSIMDType v, std::size_t i, std::complex<Scalar> s) noexcept
143  {
144  auto j = i << 1;
145  return SIMDNativeOps<Scalar>::set (SIMDNativeOps<Scalar>::set (v, j, s.real()), j + 1, s.imag());
146  }
147 
148  static inline std::complex<Scalar> JUCE_VECTOR_CALLTYPE sum (vSIMDType a) noexcept
149  {
150  vSIMDType result = SIMDNativeOps<Scalar>::oddevensum (a);
151  auto* ptr = reinterpret_cast<const Scalar*> (&result);
152  return std::complex<Scalar> (ptr[0], ptr[1]);
153  }
154 
155  static inline vSIMDType JUCE_VECTOR_CALLTYPE mul (vSIMDType a, vSIMDType b) noexcept
156  {
157  return SIMDNativeOps<Scalar>::cmplxmul (a, b);
158  }
159 
160  static inline vSIMDType JUCE_VECTOR_CALLTYPE muladd (vSIMDType a, vSIMDType b, vSIMDType c) noexcept
161  {
162  return SIMDNativeOps<Scalar>::add (a, SIMDNativeOps<Scalar>::cmplxmul (b, c));
163  }
164 };
165 #endif
166 
167 //==============================================================================
168  namespace util
169  {
170  template <typename Type>
171  inline void snapToZero (SIMDRegister<Type>&) noexcept {}
172  }
173 
174 } // namespace dsp
175 
176 // Extend some common used global functions to SIMDRegister types
177 template <typename Type>
178 inline dsp::SIMDRegister<Type> JUCE_VECTOR_CALLTYPE jmin (dsp::SIMDRegister<Type> a, dsp::SIMDRegister<Type> b) { return dsp::SIMDRegister<Type>::min (a, b); }
179 template <typename Type>
180 inline dsp::SIMDRegister<Type> JUCE_VECTOR_CALLTYPE jmax (dsp::SIMDRegister<Type> a, dsp::SIMDRegister<Type> b) { return dsp::SIMDRegister<Type>::max (a, b); }
181 
182 } // namespace juce
183 
184 /** @}*/
ElementType sum() const noexcept
Returns a scalar which is the sum of all elements of the receiver.
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...
A wrapper around the platform&#39;s native SIMD register type.
static SIMDRegister JUCE_VECTOR_CALLTYPE expand(ElementType s) noexcept
Creates a new SIMDRegister from the corresponding scalar primitive.
SIMDRegister &JUCE_VECTOR_CALLTYPE operator=(ElementType s) noexcept
Broadcasts the scalar to all elements of the receiver.
void JUCE_VECTOR_CALLTYPE set(size_t idx, ElementType v) noexcept
Sets the idx-th element of the receiver.
typename NativeOps::vSIMDType vSIMDType
The native type (used internally).
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...