31JUCE_BEGIN_IGNORE_WARNINGS_GCC_LIKE (
"-Wignored-attributes")
34 #define DECLARE_NEON_SIMD_CONST(type, name) \
35 static __declspec (align (16)) const type name [16 / sizeof (type)]
37 #define DEFINE_NEON_SIMD_CONST(type, class_type, name) \
38 __declspec (align (16)) const type SIMDNativeOps<class_type>:: name [16 / sizeof (type)]
41 #define DECLARE_NEON_SIMD_CONST(type, name) \
42 static const type name [16 / sizeof (type)] __attribute__ ((aligned (16)))
44 #define DEFINE_NEON_SIMD_CONST(type, class_type, name) \
45 const type SIMDNativeOps<class_type>:: name [16 / sizeof (type)] __attribute__ ((aligned (16)))
49template <
typename type>
58struct SIMDNativeOps<uint32_t>
61 using vSIMDType = uint32x4_t;
62 using fb = SIMDFallbackOps<uint32_t, vSIMDType>;
65 DECLARE_NEON_SIMD_CONST (uint32_t, kAllBitsSet);
68 static forcedinline vSIMDType expand (uint32_t s)
noexcept {
return vdupq_n_u32 (s); }
69 static forcedinline vSIMDType load (
const uint32_t* a)
noexcept {
return vld1q_u32 (a); }
70 static forcedinline
void store (vSIMDType value, uint32_t* a)
noexcept { vst1q_u32 (a, value); }
71 static forcedinline uint32_t get (vSIMDType v,
size_t i)
noexcept {
return fb::get (v, i); }
72 static forcedinline vSIMDType set (vSIMDType v,
size_t i, uint32_t s)
noexcept {
return fb::set (v, i, s); }
73 static forcedinline vSIMDType add (vSIMDType a, vSIMDType b)
noexcept {
return vaddq_u32 (a, b); }
74 static forcedinline vSIMDType sub (vSIMDType a, vSIMDType b)
noexcept {
return vsubq_u32 (a, b); }
75 static forcedinline vSIMDType mul (vSIMDType a, vSIMDType b)
noexcept {
return vmulq_u32 (a, b); }
76 static forcedinline vSIMDType bit_and (vSIMDType a, vSIMDType b)
noexcept {
return vandq_u32 (a, b); }
77 static forcedinline vSIMDType bit_or (vSIMDType a, vSIMDType b)
noexcept {
return vorrq_u32 (a, b); }
78 static forcedinline vSIMDType bit_xor (vSIMDType a, vSIMDType b)
noexcept {
return veorq_u32 (a, b); }
79 static forcedinline vSIMDType bit_notand (vSIMDType a, vSIMDType b)
noexcept {
return vbicq_u32 (b, a); }
80 static forcedinline vSIMDType bit_not (vSIMDType a)
noexcept {
return bit_notand (a, vld1q_u32 ((uint32_t*) kAllBitsSet)); }
81 static forcedinline vSIMDType min (vSIMDType a, vSIMDType b)
noexcept {
return vminq_u32 (a, b); }
82 static forcedinline vSIMDType max (vSIMDType a, vSIMDType b)
noexcept {
return vmaxq_u32 (a, b); }
83 static forcedinline vSIMDType equal (vSIMDType a, vSIMDType b)
noexcept {
return (vSIMDType) vceqq_u32 (a, b); }
84 static forcedinline
bool allEqual (vSIMDType a, vSIMDType b)
noexcept {
return (sum (notEqual (a, b)) == 0); }
85 static forcedinline vSIMDType notEqual (vSIMDType a, vSIMDType b)
noexcept {
return bit_not (equal (a, b)); }
86 static forcedinline vSIMDType greaterThan (vSIMDType a, vSIMDType b)
noexcept {
return (vSIMDType) vcgtq_u32 (a, b); }
87 static forcedinline vSIMDType greaterThanOrEqual (vSIMDType a, vSIMDType b)
noexcept {
return (vSIMDType) vcgeq_u32 (a, b); }
88 static forcedinline vSIMDType multiplyAdd (vSIMDType a, vSIMDType b, vSIMDType c)
noexcept {
return vmlaq_u32 (a, b, c); }
89 static forcedinline vSIMDType truncate (vSIMDType a)
noexcept {
return a; }
91 static forcedinline uint32_t sum (vSIMDType a)
noexcept
93 auto rr = vadd_u32 (vget_high_u32 (a), vget_low_u32 (a));
94 return vget_lane_u32 (vpadd_u32 (rr, rr), 0);
104struct SIMDNativeOps<int32_t>
107 using vSIMDType = int32x4_t;
108 using fb = SIMDFallbackOps<int32_t, vSIMDType>;
111 DECLARE_NEON_SIMD_CONST (int32_t, kAllBitsSet);
114 static forcedinline vSIMDType expand (int32_t s)
noexcept {
return vdupq_n_s32 (s); }
115 static forcedinline vSIMDType load (
const int32_t* a)
noexcept {
return vld1q_s32 (a); }
116 static forcedinline
void store (vSIMDType value, int32_t* a)
noexcept { vst1q_s32 (a, value); }
117 static forcedinline int32_t get (vSIMDType v,
size_t i)
noexcept {
return fb::get (v, i); }
118 static forcedinline vSIMDType set (vSIMDType v,
size_t i, int32_t s)
noexcept {
return fb::set (v, i, s); }
119 static forcedinline vSIMDType add (vSIMDType a, vSIMDType b)
noexcept {
return vaddq_s32 (a, b); }
120 static forcedinline vSIMDType sub (vSIMDType a, vSIMDType b)
noexcept {
return vsubq_s32 (a, b); }
121 static forcedinline vSIMDType mul (vSIMDType a, vSIMDType b)
noexcept {
return vmulq_s32 (a, b); }
122 static forcedinline vSIMDType bit_and (vSIMDType a, vSIMDType b)
noexcept {
return vandq_s32 (a, b); }
123 static forcedinline vSIMDType bit_or (vSIMDType a, vSIMDType b)
noexcept {
return vorrq_s32 (a, b); }
124 static forcedinline vSIMDType bit_xor (vSIMDType a, vSIMDType b)
noexcept {
return veorq_s32 (a, b); }
125 static forcedinline vSIMDType bit_notand (vSIMDType a, vSIMDType b)
noexcept {
return vbicq_s32 (b, a); }
126 static forcedinline vSIMDType bit_not (vSIMDType a)
noexcept {
return bit_notand (a, vld1q_s32 ((int32_t*) kAllBitsSet)); }
127 static forcedinline vSIMDType min (vSIMDType a, vSIMDType b)
noexcept {
return vminq_s32 (a, b); }
128 static forcedinline vSIMDType max (vSIMDType a, vSIMDType b)
noexcept {
return vmaxq_s32 (a, b); }
129 static forcedinline vSIMDType equal (vSIMDType a, vSIMDType b)
noexcept {
return (vSIMDType) vceqq_s32 (a, b); }
130 static forcedinline
bool allEqual (vSIMDType a, vSIMDType b)
noexcept {
return (sum (notEqual (a, b)) == 0); }
131 static forcedinline vSIMDType notEqual (vSIMDType a, vSIMDType b)
noexcept {
return bit_not (equal (a, b)); }
132 static forcedinline vSIMDType greaterThan (vSIMDType a, vSIMDType b)
noexcept {
return (vSIMDType) vcgtq_s32 (a, b); }
133 static forcedinline vSIMDType greaterThanOrEqual (vSIMDType a, vSIMDType b)
noexcept {
return (vSIMDType) vcgeq_s32 (a, b); }
134 static forcedinline vSIMDType multiplyAdd (vSIMDType a, vSIMDType b, vSIMDType c)
noexcept {
return vmlaq_s32 (a, b, c); }
135 static forcedinline vSIMDType truncate (vSIMDType a)
noexcept {
return a; }
137 static forcedinline int32_t sum (vSIMDType a)
noexcept
139 auto rr = vadd_s32 (vget_high_s32 (a), vget_low_s32 (a));
140 rr = vpadd_s32 (rr, rr);
141 return vget_lane_s32 (rr, 0);
151struct SIMDNativeOps<int8_t>
154 using vSIMDType = int8x16_t;
155 using fb = SIMDFallbackOps<int8_t, vSIMDType>;
158 DECLARE_NEON_SIMD_CONST (int8_t, kAllBitsSet);
161 static forcedinline vSIMDType expand (int8_t s)
noexcept {
return vdupq_n_s8 (s); }
162 static forcedinline vSIMDType load (
const int8_t* a)
noexcept {
return vld1q_s8 (a); }
163 static forcedinline
void store (vSIMDType value, int8_t* a)
noexcept { vst1q_s8 (a, value); }
164 static forcedinline int8_t get (vSIMDType v,
size_t i)
noexcept {
return fb::get (v, i); }
165 static forcedinline vSIMDType set (vSIMDType v,
size_t i, int8_t s)
noexcept {
return fb::set (v, i, s); }
166 static forcedinline vSIMDType add (vSIMDType a, vSIMDType b)
noexcept {
return vaddq_s8 (a, b); }
167 static forcedinline vSIMDType sub (vSIMDType a, vSIMDType b)
noexcept {
return vsubq_s8 (a, b); }
168 static forcedinline vSIMDType mul (vSIMDType a, vSIMDType b)
noexcept {
return vmulq_s8 (a, b); }
169 static forcedinline vSIMDType bit_and (vSIMDType a, vSIMDType b)
noexcept {
return vandq_s8 (a, b); }
170 static forcedinline vSIMDType bit_or (vSIMDType a, vSIMDType b)
noexcept {
return vorrq_s8 (a, b); }
171 static forcedinline vSIMDType bit_xor (vSIMDType a, vSIMDType b)
noexcept {
return veorq_s8 (a, b); }
172 static forcedinline vSIMDType bit_notand (vSIMDType a, vSIMDType b)
noexcept {
return vbicq_s8 (b, a); }
173 static forcedinline vSIMDType bit_not (vSIMDType a)
noexcept {
return bit_notand (a, vld1q_s8 ((int8_t*) kAllBitsSet)); }
174 static forcedinline vSIMDType min (vSIMDType a, vSIMDType b)
noexcept {
return vminq_s8 (a, b); }
175 static forcedinline vSIMDType max (vSIMDType a, vSIMDType b)
noexcept {
return vmaxq_s8 (a, b); }
176 static forcedinline vSIMDType equal (vSIMDType a, vSIMDType b)
noexcept {
return (vSIMDType) vceqq_s8 (a, b); }
177 static forcedinline vSIMDType notEqual (vSIMDType a, vSIMDType b)
noexcept {
return bit_not (equal (a, b)); }
178 static forcedinline vSIMDType greaterThan (vSIMDType a, vSIMDType b)
noexcept {
return (vSIMDType) vcgtq_s8 (a, b); }
179 static forcedinline vSIMDType greaterThanOrEqual (vSIMDType a, vSIMDType b)
noexcept {
return (vSIMDType) vcgeq_s8 (a, b); }
180 static forcedinline
bool allEqual (vSIMDType a, vSIMDType b)
noexcept {
return (SIMDNativeOps<int32_t>::sum ((SIMDNativeOps<int32_t>::vSIMDType) notEqual (a, b)) == 0); }
181 static forcedinline vSIMDType multiplyAdd (vSIMDType a, vSIMDType b, vSIMDType c)
noexcept {
return vmlaq_s8 (a, b, c); }
182 static forcedinline int8_t sum (vSIMDType a)
noexcept {
return fb::sum (a); }
183 static forcedinline vSIMDType truncate (vSIMDType a)
noexcept {
return a; }
192struct SIMDNativeOps<uint8_t>
195 using vSIMDType = uint8x16_t;
196 using fb = SIMDFallbackOps<uint8_t, vSIMDType>;
199 DECLARE_NEON_SIMD_CONST (uint8_t, kAllBitsSet);
202 static forcedinline vSIMDType expand (uint8_t s)
noexcept {
return vdupq_n_u8 (s); }
203 static forcedinline vSIMDType load (
const uint8_t* a)
noexcept {
return vld1q_u8 (a); }
204 static forcedinline
void store (vSIMDType value, uint8_t* a)
noexcept { vst1q_u8 (a, value); }
205 static forcedinline uint8_t get (vSIMDType v,
size_t i)
noexcept {
return fb::get (v, i); }
206 static forcedinline vSIMDType set (vSIMDType v,
size_t i, uint8_t s)
noexcept {
return fb::set (v, i, s); }
207 static forcedinline vSIMDType add (vSIMDType a, vSIMDType b)
noexcept {
return vaddq_u8 (a, b); }
208 static forcedinline vSIMDType sub (vSIMDType a, vSIMDType b)
noexcept {
return vsubq_u8 (a, b); }
209 static forcedinline vSIMDType mul (vSIMDType a, vSIMDType b)
noexcept {
return vmulq_u8 (a, b); }
210 static forcedinline vSIMDType bit_and (vSIMDType a, vSIMDType b)
noexcept {
return vandq_u8 (a, b); }
211 static forcedinline vSIMDType bit_or (vSIMDType a, vSIMDType b)
noexcept {
return vorrq_u8 (a, b); }
212 static forcedinline vSIMDType bit_xor (vSIMDType a, vSIMDType b)
noexcept {
return veorq_u8 (a, b); }
213 static forcedinline vSIMDType bit_notand (vSIMDType a, vSIMDType b)
noexcept {
return vbicq_u8 (b, a); }
214 static forcedinline vSIMDType bit_not (vSIMDType a)
noexcept {
return bit_notand (a, vld1q_u8 ((uint8_t*) kAllBitsSet)); }
215 static forcedinline vSIMDType min (vSIMDType a, vSIMDType b)
noexcept {
return vminq_u8 (a, b); }
216 static forcedinline vSIMDType max (vSIMDType a, vSIMDType b)
noexcept {
return vmaxq_u8 (a, b); }
217 static forcedinline vSIMDType equal (vSIMDType a, vSIMDType b)
noexcept {
return (vSIMDType) vceqq_u8 (a, b); }
218 static forcedinline vSIMDType notEqual (vSIMDType a, vSIMDType b)
noexcept {
return bit_not (equal (a, b)); }
219 static forcedinline vSIMDType greaterThan (vSIMDType a, vSIMDType b)
noexcept {
return (vSIMDType) vcgtq_u8 (a, b); }
220 static forcedinline vSIMDType greaterThanOrEqual (vSIMDType a, vSIMDType b)
noexcept {
return (vSIMDType) vcgeq_u8 (a, b); }
221 static forcedinline
bool allEqual (vSIMDType a, vSIMDType b)
noexcept {
return (SIMDNativeOps<uint32_t>::sum ((SIMDNativeOps<uint32_t>::vSIMDType) notEqual (a, b)) == 0); }
222 static forcedinline vSIMDType multiplyAdd (vSIMDType a, vSIMDType b, vSIMDType c)
noexcept {
return vmlaq_u8 (a, b, c); }
223 static forcedinline uint8_t sum (vSIMDType a)
noexcept {
return fb::sum (a); }
224 static forcedinline vSIMDType truncate (vSIMDType a)
noexcept {
return a; }
233struct SIMDNativeOps<int16_t>
236 using vSIMDType = int16x8_t;
237 using fb = SIMDFallbackOps<int16_t, vSIMDType>;
240 DECLARE_NEON_SIMD_CONST (int16_t, kAllBitsSet);
243 static forcedinline vSIMDType expand (int16_t s)
noexcept {
return vdupq_n_s16 (s); }
244 static forcedinline vSIMDType load (
const int16_t* a)
noexcept {
return vld1q_s16 (a); }
245 static forcedinline
void store (vSIMDType value, int16_t* a)
noexcept { vst1q_s16 (a, value); }
246 static forcedinline int16_t get (vSIMDType v,
size_t i)
noexcept {
return fb::get (v, i); }
247 static forcedinline vSIMDType set (vSIMDType v,
size_t i, int16_t s)
noexcept {
return fb::set (v, i, s); }
248 static forcedinline vSIMDType add (vSIMDType a, vSIMDType b)
noexcept {
return vaddq_s16 (a, b); }
249 static forcedinline vSIMDType sub (vSIMDType a, vSIMDType b)
noexcept {
return vsubq_s16 (a, b); }
250 static forcedinline vSIMDType mul (vSIMDType a, vSIMDType b)
noexcept {
return vmulq_s16 (a, b); }
251 static forcedinline vSIMDType bit_and (vSIMDType a, vSIMDType b)
noexcept {
return vandq_s16 (a, b); }
252 static forcedinline vSIMDType bit_or (vSIMDType a, vSIMDType b)
noexcept {
return vorrq_s16 (a, b); }
253 static forcedinline vSIMDType bit_xor (vSIMDType a, vSIMDType b)
noexcept {
return veorq_s16 (a, b); }
254 static forcedinline vSIMDType bit_notand (vSIMDType a, vSIMDType b)
noexcept {
return vbicq_s16 (b, a); }
255 static forcedinline vSIMDType bit_not (vSIMDType a)
noexcept {
return bit_notand (a, vld1q_s16 ((int16_t*) kAllBitsSet)); }
256 static forcedinline vSIMDType min (vSIMDType a, vSIMDType b)
noexcept {
return vminq_s16 (a, b); }
257 static forcedinline vSIMDType max (vSIMDType a, vSIMDType b)
noexcept {
return vmaxq_s16 (a, b); }
258 static forcedinline vSIMDType equal (vSIMDType a, vSIMDType b)
noexcept {
return (vSIMDType) vceqq_s16 (a, b); }
259 static forcedinline vSIMDType notEqual (vSIMDType a, vSIMDType b)
noexcept {
return bit_not (equal (a, b)); }
260 static forcedinline vSIMDType greaterThan (vSIMDType a, vSIMDType b)
noexcept {
return (vSIMDType) vcgtq_s16 (a, b); }
261 static forcedinline vSIMDType greaterThanOrEqual (vSIMDType a, vSIMDType b)
noexcept {
return (vSIMDType) vcgeq_s16 (a, b); }
262 static forcedinline
bool allEqual (vSIMDType a, vSIMDType b)
noexcept {
return (SIMDNativeOps<int32_t>::sum ((SIMDNativeOps<int32_t>::vSIMDType) notEqual (a, b)) == 0); }
263 static forcedinline vSIMDType multiplyAdd (vSIMDType a, vSIMDType b, vSIMDType c)
noexcept {
return vmlaq_s16 (a, b, c); }
264 static forcedinline int16_t sum (vSIMDType a)
noexcept {
return fb::sum (a); }
265 static forcedinline vSIMDType truncate (vSIMDType a)
noexcept {
return a; }
275struct SIMDNativeOps<uint16_t>
278 using vSIMDType = uint16x8_t;
279 using fb = SIMDFallbackOps<uint16_t, vSIMDType>;
282 DECLARE_NEON_SIMD_CONST (uint16_t, kAllBitsSet);
285 static forcedinline vSIMDType expand (uint16_t s)
noexcept {
return vdupq_n_u16 (s); }
286 static forcedinline vSIMDType load (
const uint16_t* a)
noexcept {
return vld1q_u16 (a); }
287 static forcedinline
void store (vSIMDType value, uint16_t* a)
noexcept { vst1q_u16 (a, value); }
288 static forcedinline uint16_t get (vSIMDType v,
size_t i)
noexcept {
return fb::get (v, i); }
289 static forcedinline vSIMDType set (vSIMDType v,
size_t i, uint16_t s)
noexcept {
return fb::set (v, i, s); }
290 static forcedinline vSIMDType add (vSIMDType a, vSIMDType b)
noexcept {
return vaddq_u16 (a, b); }
291 static forcedinline vSIMDType sub (vSIMDType a, vSIMDType b)
noexcept {
return vsubq_u16 (a, b); }
292 static forcedinline vSIMDType mul (vSIMDType a, vSIMDType b)
noexcept {
return vmulq_u16 (a, b); }
293 static forcedinline vSIMDType bit_and (vSIMDType a, vSIMDType b)
noexcept {
return vandq_u16 (a, b); }
294 static forcedinline vSIMDType bit_or (vSIMDType a, vSIMDType b)
noexcept {
return vorrq_u16 (a, b); }
295 static forcedinline vSIMDType bit_xor (vSIMDType a, vSIMDType b)
noexcept {
return veorq_u16 (a, b); }
296 static forcedinline vSIMDType bit_notand (vSIMDType a, vSIMDType b)
noexcept {
return vbicq_u16 (b, a); }
297 static forcedinline vSIMDType bit_not (vSIMDType a)
noexcept {
return bit_notand (a, vld1q_u16 ((uint16_t*) kAllBitsSet)); }
298 static forcedinline vSIMDType min (vSIMDType a, vSIMDType b)
noexcept {
return vminq_u16 (a, b); }
299 static forcedinline vSIMDType max (vSIMDType a, vSIMDType b)
noexcept {
return vmaxq_u16 (a, b); }
300 static forcedinline vSIMDType equal (vSIMDType a, vSIMDType b)
noexcept {
return (vSIMDType) vceqq_u16 (a, b); }
301 static forcedinline vSIMDType notEqual (vSIMDType a, vSIMDType b)
noexcept {
return bit_not (equal (a, b)); }
302 static forcedinline vSIMDType greaterThan (vSIMDType a, vSIMDType b)
noexcept {
return (vSIMDType) vcgtq_u16 (a, b); }
303 static forcedinline vSIMDType greaterThanOrEqual (vSIMDType a, vSIMDType b)
noexcept {
return (vSIMDType) vcgeq_u16 (a, b); }
304 static forcedinline
bool allEqual (vSIMDType a, vSIMDType b)
noexcept {
return (SIMDNativeOps<uint32_t>::sum ((SIMDNativeOps<uint32_t>::vSIMDType) notEqual (a, b)) == 0); }
305 static forcedinline vSIMDType multiplyAdd (vSIMDType a, vSIMDType b, vSIMDType c)
noexcept {
return vmlaq_u16 (a, b, c); }
306 static forcedinline uint16_t sum (vSIMDType a)
noexcept {
return fb::sum (a); }
307 static forcedinline vSIMDType truncate (vSIMDType a)
noexcept {
return a; }
316struct SIMDNativeOps<int64_t>
319 using vSIMDType = int64x2_t;
320 using fb = SIMDFallbackOps<int64_t, vSIMDType>;
323 DECLARE_NEON_SIMD_CONST (int64_t, kAllBitsSet);
326 static forcedinline vSIMDType expand (int64_t s)
noexcept {
return vdupq_n_s64 (s); }
327 static forcedinline vSIMDType load (
const int64_t* a)
noexcept {
return vld1q_s64 (a); }
328 static forcedinline
void store (vSIMDType value, int64_t* a)
noexcept { vst1q_s64 (a, value); }
329 static forcedinline int64_t get (vSIMDType v,
size_t i)
noexcept {
return fb::get (v, i); }
330 static forcedinline vSIMDType set (vSIMDType v,
size_t i, int64_t s)
noexcept {
return fb::set (v, i, s); }
331 static forcedinline vSIMDType add (vSIMDType a, vSIMDType b)
noexcept {
return vaddq_s64 (a, b); }
332 static forcedinline vSIMDType sub (vSIMDType a, vSIMDType b)
noexcept {
return vsubq_s64 (a, b); }
333 static forcedinline vSIMDType mul (vSIMDType a, vSIMDType b)
noexcept {
return fb::mul (a, b); }
334 static forcedinline vSIMDType bit_and (vSIMDType a, vSIMDType b)
noexcept {
return vandq_s64 (a, b); }
335 static forcedinline vSIMDType bit_or (vSIMDType a, vSIMDType b)
noexcept {
return vorrq_s64 (a, b); }
336 static forcedinline vSIMDType bit_xor (vSIMDType a, vSIMDType b)
noexcept {
return veorq_s64 (a, b); }
337 static forcedinline vSIMDType bit_notand (vSIMDType a, vSIMDType b)
noexcept {
return vbicq_s64 (b, a); }
338 static forcedinline vSIMDType bit_not (vSIMDType a)
noexcept {
return bit_notand (a, vld1q_s64 ((int64_t*) kAllBitsSet)); }
339 static forcedinline vSIMDType min (vSIMDType a, vSIMDType b)
noexcept {
return fb::min (a, b); }
340 static forcedinline vSIMDType max (vSIMDType a, vSIMDType b)
noexcept {
return fb::max (a, b); }
341 static forcedinline vSIMDType equal (vSIMDType a, vSIMDType b)
noexcept {
return fb::equal (a, b); }
342 static forcedinline vSIMDType notEqual (vSIMDType a, vSIMDType b)
noexcept {
return fb::notEqual (a, b); }
343 static forcedinline vSIMDType greaterThan (vSIMDType a, vSIMDType b)
noexcept {
return fb::greaterThan (a, b); }
344 static forcedinline vSIMDType greaterThanOrEqual (vSIMDType a, vSIMDType b)
noexcept {
return fb::greaterThanOrEqual (a, b); }
345 static forcedinline
bool allEqual (vSIMDType a, vSIMDType b)
noexcept {
return (SIMDNativeOps<int32_t>::sum ((SIMDNativeOps<int32_t>::vSIMDType) notEqual (a, b)) == 0); }
346 static forcedinline vSIMDType multiplyAdd (vSIMDType a, vSIMDType b, vSIMDType c)
noexcept {
return fb::multiplyAdd (a, b, c); }
347 static forcedinline int64_t sum (vSIMDType a)
noexcept {
return fb::sum (a); }
348 static forcedinline vSIMDType truncate (vSIMDType a)
noexcept {
return a; }
358struct SIMDNativeOps<uint64_t>
361 using vSIMDType = uint64x2_t;
362 using fb = SIMDFallbackOps<uint64_t, vSIMDType>;
365 DECLARE_NEON_SIMD_CONST (uint64_t, kAllBitsSet);
368 static forcedinline vSIMDType expand (uint64_t s)
noexcept {
return vdupq_n_u64 (s); }
369 static forcedinline vSIMDType load (
const uint64_t* a)
noexcept {
return vld1q_u64 (a); }
370 static forcedinline
void store (vSIMDType value, uint64_t* a)
noexcept { vst1q_u64 (a, value); }
371 static forcedinline uint64_t get (vSIMDType v,
size_t i)
noexcept {
return fb::get (v, i); }
372 static forcedinline vSIMDType set (vSIMDType v,
size_t i, uint64_t s)
noexcept {
return fb::set (v, i, s); }
373 static forcedinline vSIMDType add (vSIMDType a, vSIMDType b)
noexcept {
return vaddq_u64 (a, b); }
374 static forcedinline vSIMDType sub (vSIMDType a, vSIMDType b)
noexcept {
return vsubq_u64 (a, b); }
375 static forcedinline vSIMDType mul (vSIMDType a, vSIMDType b)
noexcept {
return fb::mul (a, b); }
376 static forcedinline vSIMDType bit_and (vSIMDType a, vSIMDType b)
noexcept {
return vandq_u64 (a, b); }
377 static forcedinline vSIMDType bit_or (vSIMDType a, vSIMDType b)
noexcept {
return vorrq_u64 (a, b); }
378 static forcedinline vSIMDType bit_xor (vSIMDType a, vSIMDType b)
noexcept {
return veorq_u64 (a, b); }
379 static forcedinline vSIMDType bit_notand (vSIMDType a, vSIMDType b)
noexcept {
return vbicq_u64 (b, a); }
380 static forcedinline vSIMDType bit_not (vSIMDType a)
noexcept {
return bit_notand (a, vld1q_u64 ((uint64_t*) kAllBitsSet)); }
381 static forcedinline vSIMDType min (vSIMDType a, vSIMDType b)
noexcept {
return fb::min (a, b); }
382 static forcedinline vSIMDType max (vSIMDType a, vSIMDType b)
noexcept {
return fb::max (a, b); }
383 static forcedinline vSIMDType equal (vSIMDType a, vSIMDType b)
noexcept {
return fb::equal (a, b); }
384 static forcedinline vSIMDType notEqual (vSIMDType a, vSIMDType b)
noexcept {
return fb::notEqual (a, b); }
385 static forcedinline vSIMDType greaterThan (vSIMDType a, vSIMDType b)
noexcept {
return fb::greaterThan (a, b); }
386 static forcedinline vSIMDType greaterThanOrEqual (vSIMDType a, vSIMDType b)
noexcept {
return fb::greaterThanOrEqual (a, b); }
387 static forcedinline
bool allEqual (vSIMDType a, vSIMDType b)
noexcept {
return (SIMDNativeOps<uint32_t>::sum ((SIMDNativeOps<uint32_t>::vSIMDType) notEqual (a, b)) == 0); }
388 static forcedinline vSIMDType multiplyAdd (vSIMDType a, vSIMDType b, vSIMDType c)
noexcept {
return fb::multiplyAdd (a, b, c); }
389 static forcedinline uint64_t sum (vSIMDType a)
noexcept {
return fb::sum (a); }
390 static forcedinline vSIMDType truncate (vSIMDType a)
noexcept {
return a; }
399struct SIMDNativeOps<float>
402 using vSIMDType = float32x4_t;
403 using vMaskType = uint32x4_t;
404 using fb = SIMDFallbackOps<float, vSIMDType>;
407 DECLARE_NEON_SIMD_CONST (int32_t, kAllBitsSet);
408 DECLARE_NEON_SIMD_CONST (int32_t, kEvenHighBit);
409 DECLARE_NEON_SIMD_CONST (
float, kOne);
412 static forcedinline vSIMDType expand (
float s)
noexcept {
return vdupq_n_f32 (s); }
413 static forcedinline vSIMDType load (
const float* a)
noexcept {
return vld1q_f32 (a); }
414 static forcedinline
float get (vSIMDType v,
size_t i)
noexcept {
return fb::get (v, i); }
415 static forcedinline vSIMDType set (vSIMDType v,
size_t i,
float s)
noexcept {
return fb::set (v, i, s); }
416 static forcedinline
void store (vSIMDType value,
float* a)
noexcept { vst1q_f32 (a, value); }
417 static forcedinline vSIMDType add (vSIMDType a, vSIMDType b)
noexcept {
return vaddq_f32 (a, b); }
418 static forcedinline vSIMDType sub (vSIMDType a, vSIMDType b)
noexcept {
return vsubq_f32 (a, b); }
419 static forcedinline vSIMDType mul (vSIMDType a, vSIMDType b)
noexcept {
return vmulq_f32 (a, b); }
420 static forcedinline vSIMDType bit_and (vSIMDType a, vSIMDType b)
noexcept {
return (vSIMDType) vandq_u32 ((vMaskType) a, (vMaskType) b); }
421 static forcedinline vSIMDType bit_or (vSIMDType a, vSIMDType b)
noexcept {
return (vSIMDType) vorrq_u32 ((vMaskType) a, (vMaskType) b); }
422 static forcedinline vSIMDType bit_xor (vSIMDType a, vSIMDType b)
noexcept {
return (vSIMDType) veorq_u32 ((vMaskType) a, (vMaskType) b); }
423 static forcedinline vSIMDType bit_notand (vSIMDType a, vSIMDType b)
noexcept {
return (vSIMDType) vbicq_u32 ((vMaskType) b, (vMaskType) a); }
424 static forcedinline vSIMDType bit_not (vSIMDType a)
noexcept {
return bit_notand (a, vld1q_f32 ((
float*) kAllBitsSet)); }
425 static forcedinline vSIMDType min (vSIMDType a, vSIMDType b)
noexcept {
return vminq_f32 (a, b); }
426 static forcedinline vSIMDType max (vSIMDType a, vSIMDType b)
noexcept {
return vmaxq_f32 (a, b); }
427 static forcedinline vSIMDType equal (vSIMDType a, vSIMDType b)
noexcept {
return (vSIMDType) vceqq_f32 (a, b); }
428 static forcedinline vSIMDType notEqual (vSIMDType a, vSIMDType b)
noexcept {
return bit_not (equal (a, b)); }
429 static forcedinline vSIMDType greaterThan (vSIMDType a, vSIMDType b)
noexcept {
return (vSIMDType) vcgtq_f32 (a, b); }
430 static forcedinline vSIMDType greaterThanOrEqual (vSIMDType a, vSIMDType b)
noexcept {
return (vSIMDType) vcgeq_f32 (a, b); }
431 static forcedinline
bool allEqual (vSIMDType a, vSIMDType b)
noexcept {
return (SIMDNativeOps<uint32_t>::sum ((SIMDNativeOps<uint32_t>::vSIMDType) notEqual (a, b)) == 0); }
432 static forcedinline vSIMDType multiplyAdd (vSIMDType a, vSIMDType b, vSIMDType c)
noexcept {
return vmlaq_f32 (a, b, c); }
433 static forcedinline vSIMDType dupeven (vSIMDType a)
noexcept {
return fb::shuffle<(0 << 0) | (0 << 2) | (2 << 4) | (2 << 6)> (a); }
434 static forcedinline vSIMDType dupodd (vSIMDType a)
noexcept {
return fb::shuffle<(1 << 0) | (1 << 2) | (3 << 4) | (3 << 6)> (a); }
435 static forcedinline vSIMDType swapevenodd (vSIMDType a)
noexcept {
return fb::shuffle<(1 << 0) | (0 << 2) | (3 << 4) | (2 << 6)> (a); }
436 static forcedinline vSIMDType oddevensum (vSIMDType a)
noexcept {
return add (fb::shuffle<(2 << 0) | (3 << 2) | (0 << 4) | (1 << 6)> (a), a); }
437 static forcedinline vSIMDType truncate (vSIMDType a)
noexcept {
return vcvtq_f32_s32 (vcvtq_s32_f32 (a)); }
440 static forcedinline vSIMDType cmplxmul (vSIMDType a, vSIMDType b)
noexcept
442 vSIMDType rr_ir = mul (a, dupeven (b));
443 vSIMDType ii_ri = mul (swapevenodd (a), dupodd (b));
444 return add (rr_ir, bit_xor (ii_ri, vld1q_f32 ((
float*) kEvenHighBit)));
447 static forcedinline
float sum (vSIMDType a)
noexcept
449 auto rr = vadd_f32 (vget_high_f32 (a), vget_low_f32 (a));
450 return vget_lane_f32 (vpadd_f32 (rr, rr), 0);
462struct SIMDNativeOps<double>
465 using vSIMDType = float64x2_t;
466 using vMaskType = uint64x2_t;
467 using fb = SIMDFallbackOps<double, vSIMDType>;
470 DECLARE_NEON_SIMD_CONST (int64_t, kAllBitsSet);
471 DECLARE_NEON_SIMD_CONST (
double, kOne);
474 static forcedinline vSIMDType expand (
double s)
noexcept {
return vdupq_n_f64 (s); }
475 static forcedinline vSIMDType load (
const double* a)
noexcept {
return vld1q_f64 (a); }
476 static forcedinline
double get (vSIMDType v,
size_t i)
noexcept {
return fb::get (v, i); }
477 static forcedinline vSIMDType set (vSIMDType v,
size_t i,
double s)
noexcept {
return fb::set (v, i, s); }
478 static forcedinline
void store (vSIMDType value,
double* a)
noexcept { vst1q_f64 (a, value); }
479 static forcedinline vSIMDType add (vSIMDType a, vSIMDType b)
noexcept {
return vaddq_f64 (a, b); }
480 static forcedinline vSIMDType sub (vSIMDType a, vSIMDType b)
noexcept {
return vsubq_f64 (a, b); }
481 static forcedinline vSIMDType mul (vSIMDType a, vSIMDType b)
noexcept {
return vmulq_f64 (a, b); }
482 static forcedinline vSIMDType bit_and (vSIMDType a, vSIMDType b)
noexcept {
return (vSIMDType) vandq_u64 ((vMaskType) a, (vMaskType) b); }
483 static forcedinline vSIMDType bit_or (vSIMDType a, vSIMDType b)
noexcept {
return (vSIMDType) vorrq_u64 ((vMaskType) a, (vMaskType) b); }
484 static forcedinline vSIMDType bit_xor (vSIMDType a, vSIMDType b)
noexcept {
return (vSIMDType) veorq_u64 ((vMaskType) a, (vMaskType) b); }
485 static forcedinline vSIMDType bit_notand (vSIMDType a, vSIMDType b)
noexcept {
return (vSIMDType) vbicq_u64 ((vMaskType) b, (vMaskType) a); }
486 static forcedinline vSIMDType bit_not (vSIMDType a)
noexcept {
return bit_notand (a, vld1q_f64 ((
double*) kAllBitsSet)); }
487 static forcedinline vSIMDType min (vSIMDType a, vSIMDType b)
noexcept {
return vminq_f64 (a, b); }
488 static forcedinline vSIMDType max (vSIMDType a, vSIMDType b)
noexcept {
return vmaxq_f64 (a, b); }
489 static forcedinline vSIMDType equal (vSIMDType a, vSIMDType b)
noexcept {
return (vSIMDType) vceqq_f64 (a, b); }
490 static forcedinline vSIMDType notEqual (vSIMDType a, vSIMDType b)
noexcept {
return bit_not (equal (a, b)); }
491 static forcedinline vSIMDType greaterThan (vSIMDType a, vSIMDType b)
noexcept {
return (vSIMDType) vcgtq_f64 (a, b); }
492 static forcedinline vSIMDType greaterThanOrEqual (vSIMDType a, vSIMDType b)
noexcept {
return (vSIMDType) vcgeq_f64 (a, b); }
493 static forcedinline
bool allEqual (vSIMDType a, vSIMDType b)
noexcept {
return (SIMDNativeOps<uint32_t>::sum ((SIMDNativeOps<uint32_t>::vSIMDType) notEqual (a, b)) == 0); }
494 static forcedinline vSIMDType multiplyAdd (vSIMDType a, vSIMDType b, vSIMDType c)
noexcept {
return vmlaq_f64 (a, b, c); }
495 static forcedinline vSIMDType cmplxmul (vSIMDType a, vSIMDType b)
noexcept {
return fb::cmplxmul (a, b); }
496 static forcedinline
double sum (vSIMDType a)
noexcept {
return fb::sum (a); }
497 static forcedinline vSIMDType oddevensum (vSIMDType a)
noexcept {
return a; }
498 static forcedinline vSIMDType truncate (vSIMDType a)
noexcept {
return vcvtq_f64_s64 (vcvtq_s64_f64 (a)); }
502struct SIMDNativeOps<double>
505 using vSIMDType =
struct {
double v[2]; };
506 using fb = SIMDFallbackOps<double, vSIMDType>;
508 static forcedinline vSIMDType expand (
double s)
noexcept {
return {{s, s}}; }
509 static forcedinline vSIMDType load (
const double* a)
noexcept {
return {{a[0], a[1]}}; }
510 static forcedinline
void store (vSIMDType v,
double* a)
noexcept { a[0] = v.v[0]; a[1] = v.v[1]; }
511 static forcedinline
double get (vSIMDType v,
size_t i)
noexcept {
return v.v[i]; }
512 static forcedinline vSIMDType set (vSIMDType v,
size_t i,
double s)
noexcept { v.v[i] = s;
return v; }
513 static forcedinline vSIMDType add (vSIMDType a, vSIMDType b)
noexcept {
return {{a.v[0] + b.v[0], a.v[1] + b.v[1]}}; }
514 static forcedinline vSIMDType sub (vSIMDType a, vSIMDType b)
noexcept {
return {{a.v[0] - b.v[0], a.v[1] - b.v[1]}}; }
515 static forcedinline vSIMDType mul (vSIMDType a, vSIMDType b)
noexcept {
return {{a.v[0] * b.v[0], a.v[1] * b.v[1]}}; }
516 static forcedinline vSIMDType bit_and (vSIMDType a, vSIMDType b)
noexcept {
return fb::bit_and (a, b); }
517 static forcedinline vSIMDType bit_or (vSIMDType a, vSIMDType b)
noexcept {
return fb::bit_or (a, b); }
518 static forcedinline vSIMDType bit_xor (vSIMDType a, vSIMDType b)
noexcept {
return fb::bit_xor (a, b); }
519 static forcedinline vSIMDType bit_notand (vSIMDType a, vSIMDType b)
noexcept {
return fb::bit_notand (a, b); }
520 static forcedinline vSIMDType bit_not (vSIMDType a)
noexcept {
return fb::bit_not (a); }
521 static forcedinline vSIMDType min (vSIMDType a, vSIMDType b)
noexcept {
return fb::min (a, b); }
522 static forcedinline vSIMDType max (vSIMDType a, vSIMDType b)
noexcept {
return fb::max (a, b); }
523 static forcedinline vSIMDType equal (vSIMDType a, vSIMDType b)
noexcept {
return fb::equal (a, b); }
524 static forcedinline vSIMDType notEqual (vSIMDType a, vSIMDType b)
noexcept {
return fb::notEqual (a, b); }
525 static forcedinline vSIMDType greaterThan (vSIMDType a, vSIMDType b)
noexcept {
return fb::greaterThan (a, b); }
526 static forcedinline vSIMDType greaterThanOrEqual (vSIMDType a, vSIMDType b)
noexcept {
return fb::greaterThanOrEqual (a, b); }
527 static forcedinline
bool allEqual (vSIMDType a, vSIMDType b)
noexcept {
return fb::allEqual (a, b); }
528 static forcedinline vSIMDType multiplyAdd (vSIMDType a, vSIMDType b, vSIMDType c)
noexcept {
return fb::multiplyAdd (a, b, c); }
529 static forcedinline vSIMDType cmplxmul (vSIMDType a, vSIMDType b)
noexcept {
return fb::cmplxmul (a, b); }
530 static forcedinline
double sum (vSIMDType a)
noexcept {
return fb::sum (a); }
531 static forcedinline vSIMDType oddevensum (vSIMDType a)
noexcept {
return a; }
532 static forcedinline vSIMDType truncate (vSIMDType a)
noexcept {
return fb::truncate (a); }
537JUCE_END_IGNORE_WARNINGS_GCC_LIKE