OpenShot Audio Library | OpenShotAudio  0.3.1
juce_SIMDRegister_Impl.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 
33 //==============================================================================
34 template <typename Type>
35 struct SIMDRegister<Type>::ElementAccess
36 {
37  operator Type() const { return simd.get (idx); }
38  ElementAccess& operator= (Type scalar) noexcept { simd.set (idx, scalar); return *this; }
39  ElementAccess& operator= (ElementAccess& o) noexcept { return operator= ((Type) o); }
40 
41 private:
42  friend struct SIMDRegister;
43  ElementAccess (SIMDRegister& owner, size_t index) noexcept : simd (owner), idx (index) {}
44  SIMDRegister& simd;
45  size_t idx;
46 };
47 
48 #ifndef DOXYGEN
49 //==============================================================================
50 /* This class is used internally by SIMDRegister to abstract away differences
51  in operations which are different for complex and pure floating point types. */
52 
53 // the pure floating-point version
54 template <typename Scalar>
55 struct CmplxSIMDOps
56 {
57  using vSIMDType = typename SIMDNativeOps<Scalar>::vSIMDType;
58 
59  static inline vSIMDType JUCE_VECTOR_CALLTYPE load (const Scalar* a) noexcept
60  {
61  return SIMDNativeOps<Scalar>::load (a);
62  }
63 
64  static inline void JUCE_VECTOR_CALLTYPE store (vSIMDType value, Scalar* dest) noexcept
65  {
66  SIMDNativeOps<Scalar>::store (value, dest);
67  }
68 
69  static inline vSIMDType JUCE_VECTOR_CALLTYPE expand (Scalar s) noexcept
70  {
71  return SIMDNativeOps<Scalar>::expand (s);
72  }
73 
74  static inline Scalar JUCE_VECTOR_CALLTYPE get (vSIMDType v, std::size_t i) noexcept
75  {
76  return SIMDNativeOps<Scalar>::get (v, i);
77  }
78 
79  static inline vSIMDType JUCE_VECTOR_CALLTYPE set (vSIMDType v, std::size_t i, Scalar s) noexcept
80  {
81  return SIMDNativeOps<Scalar>::set (v, i, s);
82  }
83 
84  static inline Scalar JUCE_VECTOR_CALLTYPE sum (vSIMDType a) noexcept
85  {
86  return SIMDNativeOps<Scalar>::sum (a);
87  }
88 
89  static inline vSIMDType JUCE_VECTOR_CALLTYPE mul (vSIMDType a, vSIMDType b) noexcept
90  {
91  return SIMDNativeOps<Scalar>::mul (a, b);
92  }
93 
94  static inline vSIMDType JUCE_VECTOR_CALLTYPE muladd (vSIMDType a, vSIMDType b, vSIMDType c) noexcept
95  {
96  return SIMDNativeOps<Scalar>::multiplyAdd (a, b, c);
97  }
98 };
99 
100 // The pure complex version
101 template <typename Scalar>
102 struct CmplxSIMDOps<std::complex<Scalar>>
103 {
104  using vSIMDType = typename SIMDNativeOps<Scalar>::vSIMDType;
105 
106  static inline vSIMDType JUCE_VECTOR_CALLTYPE load (const std::complex<Scalar>* a) noexcept
107  {
108  return SIMDNativeOps<Scalar>::load (reinterpret_cast<const Scalar*> (a));
109  }
110 
111  static inline void JUCE_VECTOR_CALLTYPE store (vSIMDType value, std::complex<Scalar>* dest) noexcept
112  {
113  SIMDNativeOps<Scalar>::store (value, reinterpret_cast<Scalar*> (dest));
114  }
115 
116  static inline vSIMDType JUCE_VECTOR_CALLTYPE expand (std::complex<Scalar> s) noexcept
117  {
118  const int n = sizeof (vSIMDType) / sizeof (Scalar);
119 
120  union
121  {
122  vSIMDType v;
123  Scalar floats[(size_t) n];
124  } u;
125 
126  for (int i = 0; i < n; ++i)
127  u.floats[i] = (i & 1) == 0 ? s.real() : s.imag();
128 
129  return u.v;
130  }
131 
132  static inline std::complex<Scalar> JUCE_VECTOR_CALLTYPE get (vSIMDType v, std::size_t i) noexcept
133  {
134  auto j = i << 1;
135  return std::complex<Scalar> (SIMDNativeOps<Scalar>::get (v, j), SIMDNativeOps<Scalar>::get (v, j + 1));
136  }
137 
138  static inline vSIMDType JUCE_VECTOR_CALLTYPE set (vSIMDType v, std::size_t i, std::complex<Scalar> s) noexcept
139  {
140  auto j = i << 1;
141  return SIMDNativeOps<Scalar>::set (SIMDNativeOps<Scalar>::set (v, j, s.real()), j + 1, s.imag());
142  }
143 
144  static inline std::complex<Scalar> JUCE_VECTOR_CALLTYPE sum (vSIMDType a) noexcept
145  {
146  vSIMDType result = SIMDNativeOps<Scalar>::oddevensum (a);
147  auto* ptr = reinterpret_cast<const Scalar*> (&result);
148  return std::complex<Scalar> (ptr[0], ptr[1]);
149  }
150 
151  static inline vSIMDType JUCE_VECTOR_CALLTYPE mul (vSIMDType a, vSIMDType b) noexcept
152  {
153  return SIMDNativeOps<Scalar>::cmplxmul (a, b);
154  }
155 
156  static inline vSIMDType JUCE_VECTOR_CALLTYPE muladd (vSIMDType a, vSIMDType b, vSIMDType c) noexcept
157  {
158  return SIMDNativeOps<Scalar>::add (a, SIMDNativeOps<Scalar>::cmplxmul (b, c));
159  }
160 };
161 #endif
162 
163 //==============================================================================
164  namespace util
165  {
166  template <typename Type>
167  inline void snapToZero (SIMDRegister<Type>&) noexcept {}
168  }
169 
170 } // namespace dsp
171 
172 // Extend some common used global functions to SIMDRegister types
173 template <typename Type>
174 inline dsp::SIMDRegister<Type> JUCE_VECTOR_CALLTYPE jmin (dsp::SIMDRegister<Type> a, dsp::SIMDRegister<Type> b) { return dsp::SIMDRegister<Type>::min (a, b); }
175 template <typename Type>
176 inline dsp::SIMDRegister<Type> JUCE_VECTOR_CALLTYPE jmax (dsp::SIMDRegister<Type> a, dsp::SIMDRegister<Type> b) { return dsp::SIMDRegister<Type>::max (a, b); }
177 
178 } // namespace juce
ElementType sum() const noexcept
static SIMDRegister JUCE_VECTOR_CALLTYPE min(SIMDRegister a, SIMDRegister b) noexcept
Definition: juce_Uuid.h:140
static SIMDRegister JUCE_VECTOR_CALLTYPE expand(ElementType s) noexcept
SIMDRegister() noexcept=default
SIMDRegister &JUCE_VECTOR_CALLTYPE operator=(ElementType s) noexcept
void JUCE_VECTOR_CALLTYPE set(size_t idx, ElementType v) noexcept
typename NativeOps::vSIMDType vSIMDType
static SIMDRegister JUCE_VECTOR_CALLTYPE max(SIMDRegister a, SIMDRegister b) noexcept