OpenShot Audio Library | OpenShotAudio 0.3.2
Loading...
Searching...
No Matches
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
27namespace juce
28{
29namespace dsp
30{
31
32
33//==============================================================================
34template <typename Type>
35struct 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
41private:
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
54template <typename Scalar>
55struct 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
101template <typename Scalar>
102struct 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
173template <typename Type>
174inline dsp::SIMDRegister<Type> JUCE_VECTOR_CALLTYPE jmin (dsp::SIMDRegister<Type> a, dsp::SIMDRegister<Type> b) { return dsp::SIMDRegister<Type>::min (a, b); }
175template <typename Type>
176inline 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
SIMDRegister &JUCE_VECTOR_CALLTYPE operator=(ElementType s) noexcept
static SIMDRegister JUCE_VECTOR_CALLTYPE max(SIMDRegister a, SIMDRegister b) noexcept
SIMDRegister() noexcept=default
static SIMDRegister JUCE_VECTOR_CALLTYPE min(SIMDRegister a, SIMDRegister b) noexcept
void JUCE_VECTOR_CALLTYPE set(size_t idx, ElementType v) noexcept