OpenShot Audio Library | OpenShotAudio 0.4.0

Loading...
Searching...
No Matches
juce_SIMDRegister_Impl.h
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
26 namespace juce
27{
28 namespace dsp
29{
30
31
32//==============================================================================
33 template <typename Type>
34 struct SIMDRegister<Type>::ElementAccess
35{
36 ElementAccess (const ElementAccess&) = default;
37 operator Type() const { return simd.get (idx); }
38 ElementAccess& operator= (Type scalar) noexcept { simd.set (idx, scalar); return *this; }
39 ElementAccess& operator= (const 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 vSIMDType JUCE_VECTOR_CALLTYPE load (const Scalar* a) noexcept
60 {
61 return SIMDNativeOps<Scalar>::load (a);
62 }
63
64 static void JUCE_VECTOR_CALLTYPE store (vSIMDType value, Scalar* dest) noexcept
65 {
66 SIMDNativeOps<Scalar>::store (value, dest);
67 }
68
69 static vSIMDType JUCE_VECTOR_CALLTYPE expand (Scalar s) noexcept
70 {
71 return SIMDNativeOps<Scalar>::expand (s);
72 }
73
74 static Scalar JUCE_VECTOR_CALLTYPE get (vSIMDType v, std::size_t i) noexcept
75 {
76 return SIMDNativeOps<Scalar>::get (v, i);
77 }
78
79 static 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 Scalar JUCE_VECTOR_CALLTYPE sum (vSIMDType a) noexcept
85 {
86 return SIMDNativeOps<Scalar>::sum (a);
87 }
88
89 static vSIMDType JUCE_VECTOR_CALLTYPE mul (vSIMDType a, vSIMDType b) noexcept
90 {
91 return SIMDNativeOps<Scalar>::mul (a, b);
92 }
93
94 static 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 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 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 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 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 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 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 vSIMDType JUCE_VECTOR_CALLTYPE mul (vSIMDType a, vSIMDType b) noexcept
152 {
153 return SIMDNativeOps<Scalar>::cmplxmul (a, b);
154 }
155
156 static 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
juce::dsp::SIMDRegister::operator=
SIMDRegister &JUCE_VECTOR_CALLTYPE operator=(ElementType s) noexcept
Definition juce_SIMDRegister.h:189
juce::dsp::SIMDRegister::max
static SIMDRegister JUCE_VECTOR_CALLTYPE max(SIMDRegister a, SIMDRegister b) noexcept
Definition juce_SIMDRegister.h:312
juce::dsp::SIMDRegister::SIMDRegister
SIMDRegister() noexcept=default
juce::dsp::SIMDRegister::min
static SIMDRegister JUCE_VECTOR_CALLTYPE min(SIMDRegister a, SIMDRegister b) noexcept
Definition juce_SIMDRegister.h:309