8#ifndef __SOF_AUDIO_ARM_SIMD_H__
9#define __SOF_AUDIO_ARM_SIMD_H__
14#if (defined(__arm__) || defined(__thumb__) || defined(CONFIG_ARM)) && \
15 defined(__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1)
17#if defined(__ZEPHYR__)
18#include <cmsis_core.h>
28 __asm__(
"ssat %0, #16, %1" :
"=r"(res) :
"r"(val));
31 return (int16_t)__SSAT(val, 16);
45 __asm__(
"ssat %0, #24, %1" :
"=r"(res) :
"r"(val));
48 return __SSAT(val, 24);
60 if (__builtin_expect(val >= (int64_t)INT32_MIN && val <= (int64_t)INT32_MAX, 1))
62 return (val > INT32_MAX) ? INT32_MAX : INT32_MIN;
68static inline uint32_t
arm_qadd16(uint32_t a, uint32_t b)
72 __asm__(
"qadd16 %0, %1, %2" :
"=r"(res) :
"r"(a),
"r"(b));
74#elif defined(__QADD16)
75 return __QADD16(a, b);
77 int16_t a_l = (int16_t)(a & 0xffff);
78 int16_t a_h = (int16_t)(a >> 16);
79 int16_t b_l = (int16_t)(b & 0xffff);
80 int16_t b_h = (int16_t)(b >> 16);
83 return ((uint32_t)(uint16_t)r_h << 16) | (uint16_t)r_l;
87static inline uint32_t
arm_qsub16(uint32_t a, uint32_t b)
91 __asm__(
"qsub16 %0, %1, %2" :
"=r"(res) :
"r"(a),
"r"(b));
93#elif defined(__QSUB16)
94 return __QSUB16(a, b);
96 int16_t a_l = (int16_t)(a & 0xffff);
97 int16_t a_h = (int16_t)(a >> 16);
98 int16_t b_l = (int16_t)(b & 0xffff);
99 int16_t b_h = (int16_t)(b >> 16);
102 return ((uint32_t)(uint16_t)r_h << 16) | (uint16_t)r_l;
106static inline int32_t
arm_qadd(int32_t a, int32_t b)
110 __asm__(
"qadd %0, %1, %2" :
"=r"(res) :
"r"(a),
"r"(b));
115 int64_t sum = (int64_t)a + b;
120static inline int32_t
arm_qsub(int32_t a, int32_t b)
124 __asm__(
"qsub %0, %1, %2" :
"=r"(res) :
"r"(a),
"r"(b));
129 int64_t diff = (int64_t)a - b;
137static inline int32_t
arm_smulbb(int32_t a, int32_t b)
141 __asm__(
"smulbb %0, %1, %2" :
"=r"(res) :
"r"(a),
"r"(b));
144 return (int32_t)(int16_t)(a & 0xffff) * (int16_t)(b & 0xffff);
148static inline int32_t
arm_smultt(int32_t a, int32_t b)
152 __asm__(
"smultt %0, %1, %2" :
"=r"(res) :
"r"(a),
"r"(b));
155 return (int32_t)(int16_t)(a >> 16) * (int16_t)(b >> 16);
164static inline int32_t
arm_smmulr(int32_t a, int32_t b)
168 __asm__(
"smmulr %0, %1, %2" :
"=r"(res) :
"r"(a),
"r"(b));
171 return (int32_t)(((int64_t)a * b + (1LL << 31)) >> 32);
179static inline int64_t
arm_smlal(int64_t acc, int32_t a, int32_t b)
182 uint32_t lo = (uint32_t)acc;
183 int32_t hi = (int32_t)(acc >> 32);
184 __asm__(
"smlal %0, %1, %2, %3" :
"+r"(lo),
"+r"(hi) :
"r"(a),
"r"(b));
185 return ((int64_t)hi << 32) | lo;
187 return acc + ((int64_t)a * b);
194static inline int32_t
arm_smlawb(int32_t acc, int32_t a, int32_t b)
198 __asm__(
"smlawb %0, %1, %2, %3" :
"=r"(res) :
"r"(a),
"r"(b),
"r"(acc));
201 return acc + (int32_t)(((int64_t)a * (int16_t)(b & 0xffff)) >> 16);
205static inline int32_t
arm_smlawt(int32_t acc, int32_t a, int32_t b)
209 __asm__(
"smlawt %0, %1, %2, %3" :
"=r"(res) :
"r"(a),
"r"(b),
"r"(acc));
212 return acc + (int32_t)(((int64_t)a * (int16_t)(b >> 16)) >> 16);
220#define arm_pkhbt(a, b, lsl_shift) \
225 __asm__("pkhbt %0, %1, %2, lsl %3" : "=r"(_res) : "r"(_a), "r"(_b), "I"(lsl_shift)); \
228#elif defined(__PKHBT)
229#define arm_pkhbt(a, b, lsl_shift) __PKHBT(a, b, lsl_shift)
231static inline uint32_t
arm_pkhbt(uint32_t a, uint32_t b, uint32_t lsl_shift)
233 return (a & 0xffff) | ((b << lsl_shift) & 0xffff0000);
240static inline int32_t
arm_smlad(uint32_t a, uint32_t b, int32_t acc)
244 __asm__(
"smlad %0, %1, %2, %3" :
"=r"(res) :
"r"(a),
"r"(b),
"r"(acc));
246#elif defined(__SMLAD)
247 return __SMLAD(a, b, acc);
249 int16_t a0 = (int16_t)(a & 0xffff);
250 int16_t a1 = (int16_t)(a >> 16);
251 int16_t b0 = (int16_t)(b & 0xffff);
252 int16_t b1 = (int16_t)(b >> 16);
253 return acc + (int32_t)a0 * b0 + (int32_t)a1 * b1;
257static inline int64_t
arm_smlald(uint32_t a, uint32_t b, int64_t acc)
260 uint32_t lo = (uint32_t)acc;
261 int32_t hi = (int32_t)(acc >> 32);
262 __asm__(
"smlald %0, %1, %2, %3" :
"+r"(lo),
"+r"(hi) :
"r"(a),
"r"(b));
263 return ((int64_t)hi << 32) | lo;
264#elif defined(__SMLALD)
265 return __SMLALD(a, b, acc);
267 int16_t a0 = (int16_t)(a & 0xffff);
268 int16_t a1 = (int16_t)(a >> 16);
269 int16_t b0 = (int16_t)(b & 0xffff);
270 int16_t b1 = (int16_t)(b >> 16);
271 return acc + ((int64_t)a0 * b0) + ((int64_t)a1 * b1);
278static inline int32_t
arm_sxth(int32_t val)
282 __asm__(
"sxth %0, %1" :
"=r"(res) :
"r"(val));
287 return (int32_t)(int16_t)(val & 0xffff);
294static inline uint32_t
arm_clz(uint32_t val)
296 return (uint32_t)__builtin_clz(val);
303 if (val > 32767)
return 32767;
304 if (val < -32768)
return -32768;
310 if (val > 8388607)
return 8388607;
311 if (val < -8388608)
return -8388608;
317 if (val > INT32_MAX)
return INT32_MAX;
318 if (val < INT32_MIN)
return INT32_MIN;
324 int16_t a_l = (int16_t)(a & 0xffff);
325 int16_t a_h = (int16_t)(a >> 16);
326 int16_t b_l = (int16_t)(b & 0xffff);
327 int16_t b_h = (int16_t)(b >> 16);
330 return ((uint32_t)(uint16_t)r_h << 16) | (uint16_t)r_l;
335 int16_t a_l = (int16_t)(a & 0xffff);
336 int16_t a_h = (int16_t)(a >> 16);
337 int16_t b_l = (int16_t)(b & 0xffff);
338 int16_t b_h = (int16_t)(b >> 16);
341 return ((uint32_t)(uint16_t)r_h << 16) | (uint16_t)r_l;
344static inline int32_t
arm_qadd(int32_t a, int32_t b)
349static inline int32_t
arm_qsub(int32_t a, int32_t b)
356 return (int32_t)(int16_t)(a & 0xffff) * (int16_t)(b & 0xffff);
361 return (int32_t)(int16_t)(a >> 16) * (int16_t)(b >> 16);
366 return (int32_t)(((int64_t)a * b + (1LL << 31)) >> 32);
369static inline int64_t
arm_smlal(int64_t acc, int32_t a, int32_t b)
371 return acc + ((int64_t)a * b);
374static inline uint32_t
arm_pkhbt(uint32_t a, uint32_t b, uint32_t lsl_shift)
376 return (a & 0xffff) | ((b << lsl_shift) & 0xffff0000);
379static inline int32_t
arm_smlad(uint32_t a, uint32_t b, int32_t acc)
381 int16_t a0 = (int16_t)(a & 0xffff);
382 int16_t a1 = (int16_t)(a >> 16);
383 int16_t b0 = (int16_t)(b & 0xffff);
384 int16_t b1 = (int16_t)(b >> 16);
385 return acc + (int32_t)a0 * b0 + (int32_t)a1 * b1;
388static inline int64_t
arm_smlald(uint32_t a, uint32_t b, int64_t acc)
390 int16_t a0 = (int16_t)(a & 0xffff);
391 int16_t a1 = (int16_t)(a >> 16);
392 int16_t b0 = (int16_t)(b & 0xffff);
393 int16_t b1 = (int16_t)(b >> 16);
394 return acc + ((int64_t)a0 * b0) + ((int64_t)a1 * b1);
397static inline int32_t
arm_smlawb(int32_t acc, int32_t a, int32_t b)
399 return acc + (int32_t)(((int64_t)a * (int16_t)(b & 0xffff)) >> 16);
402static inline int32_t
arm_smlawt(int32_t acc, int32_t a, int32_t b)
404 return acc + (int32_t)(((int64_t)a * (int16_t)(b >> 16)) >> 16);
409 return (int32_t)(int16_t)(val & 0xffff);
414 return (uint32_t)__builtin_clz(val);
static int64_t arm_smlald(uint32_t a, uint32_t b, int64_t acc)
Definition arm_simd.h:388
static int32_t arm_qsub(int32_t a, int32_t b)
Definition arm_simd.h:349
static int32_t arm_smultt(int32_t a, int32_t b)
Definition arm_simd.h:359
static uint32_t arm_qadd16(uint32_t a, uint32_t b)
Definition arm_simd.h:322
static int32_t arm_smlawt(int32_t acc, int32_t a, int32_t b)
Definition arm_simd.h:402
static int32_t arm_smlad(uint32_t a, uint32_t b, int32_t acc)
Definition arm_simd.h:379
static uint32_t arm_pkhbt(uint32_t a, uint32_t b, uint32_t lsl_shift)
Definition arm_simd.h:374
static uint32_t arm_qsub16(uint32_t a, uint32_t b)
Definition arm_simd.h:333
static int32_t arm_smulbb(int32_t a, int32_t b)
Definition arm_simd.h:354
static int64_t arm_smlal(int64_t acc, int32_t a, int32_t b)
Definition arm_simd.h:369
static int32_t arm_sat_q31(int64_t val)
Definition arm_simd.h:315
static int32_t arm_qadd(int32_t a, int32_t b)
Definition arm_simd.h:344
static int32_t arm_smlawb(int32_t acc, int32_t a, int32_t b)
Definition arm_simd.h:397
static int16_t arm_sat_s16(int32_t val)
Definition arm_simd.h:301
static int32_t arm_sxth(int32_t val)
Definition arm_simd.h:407
static uint32_t arm_clz(uint32_t val)
Definition arm_simd.h:412
static int32_t arm_sat_s24(int32_t val)
Definition arm_simd.h:308
static int32_t arm_smmulr(int32_t a, int32_t b)
Definition arm_simd.h:364