28 #if !defined(_SPANDSP_SATURATED_H_)
29 #define _SPANDSP_SATURATED_H_
40 #if defined(__cplusplus)
46 static __inline__ int16_t saturate(int32_t amp)
51 amp16 = (int16_t) amp;
60 static __inline__ int16_t saturate16(int32_t amp)
62 #if defined(__GNUC__) && (defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_7A__))
66 " ssat %[z],#16,%[amp];\n"
86 static __inline__ int16_t saturate15(int32_t amp)
88 #if defined(__GNUC__) && (defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_7A__))
92 " ssat %[z],#15,%[amp];\n"
102 return (int16_t) amp;
107 static __inline__ uint16_t saturateu16(int32_t amp)
109 #if defined(__GNUC__) && (defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_7A__))
112 __asm__ __volatile__(
113 " usat %[z],#16,%[amp];\n"
125 if (amp > UINT16_MAX)
132 static __inline__ uint8_t saturateu8(int32_t amp)
134 #if defined(__GNUC__) && (defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_7A__))
137 __asm__ __volatile__(
138 " usat %[z],#8,%[amp];\n"
157 static __inline__ int16_t fsaturatef(
float famp)
159 if (famp > (
float) INT16_MAX)
161 if (famp < (
float) INT16_MIN)
163 return (int16_t) lrintf(famp);
167 static __inline__ int16_t fsaturate(
double damp)
169 if (damp > (
double) INT16_MAX)
171 if (damp < (
double) INT16_MIN)
173 return (int16_t) lrint(damp);
178 static __inline__ int16_t ffastsaturatef(
float famp)
180 if (famp > (
float) INT16_MAX)
182 if (famp < (
float) INT16_MIN)
184 return (int16_t) lfastrintf(famp);
189 static __inline__ int16_t ffastsaturate(
double damp)
191 if (damp > (
double) INT16_MAX)
193 if (damp < (
double) INT16_MIN)
195 return (int16_t) lfastrint(damp);
200 static __inline__
float ffsaturatef(
float famp)
202 if (famp > (
float) INT16_MAX)
203 return (
float) INT16_MAX;
204 if (famp < (
float) INT16_MIN)
205 return (
float) INT16_MIN;
211 static __inline__
double ffsaturate(
double famp)
213 if (famp > (
double) INT16_MAX)
214 return (
double) INT16_MAX;
215 if (famp < (
double) INT16_MIN)
216 return (
double) INT16_MIN;
221 static __inline__ int16_t saturated_add16(int16_t x, int16_t y)
223 #if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
224 __asm__ __volatile__(
" addw %[y],%[x];\n"
226 " movw $0x7FFF,%[x];\n"
233 #elif defined(__GNUC__) && (defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_7A__))
236 __asm__ __volatile__(
237 " qadd16 %[z],%[x],%[y];\n"
239 : [x]
"r" (x), [y]
"r" (y)
244 return saturate16((int32_t) x + y);
249 static __inline__ int32_t saturated_add32(int32_t x, int32_t y)
251 #if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
252 __asm__ __volatile__(
" addl %[y],%[x];\n"
254 " movl $0x7FFFFFFF,%[x];\n"
261 #elif defined(__GNUC__) && (defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_7A__))
264 __asm__ __volatile__(
" qadd %[z],%[x],%[y];\n"
266 : [x]
"r" (x), [y]
"r" (y));
276 z = (x < 0) ? INT32_MIN : INT32_MAX;
283 static __inline__ int16_t saturated_sub16(int16_t x, int16_t y)
285 #if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
286 __asm__ __volatile__(
" subw %[y],%[x];\n"
288 " movw $0x8000,%[x];\n"
295 #elif defined(__GNUC__) && (defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_7A__))
298 __asm__ __volatile__(
" qsub16 %[z],%[x],%[y];\n"
300 : [x]
"r" (x), [y]
"r" (y));
304 return saturate16((int32_t) x - y);
309 static __inline__ int32_t saturated_sub32(int32_t x, int32_t y)
311 #if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
312 __asm__ __volatile__(
" subl %[y],%[x];\n"
314 " movl $0x80000000,%[x];\n"
321 #elif defined(__GNUC__) && (defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_7A__))
324 __asm__ __volatile__(
" qsub %[z],%[x],%[y];\n"
326 : [x]
"r" (x), [y]
"r" (y));
336 z = (x < 0L) ? INT32_MIN : INT32_MAX;
343 static __inline__ int16_t saturated_mul16(int16_t x, int16_t y)
347 #if defined(__GNUC__) && (defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_7A__))
348 __asm__ __volatile__(
" smulbb %[z],%[x],%[y];\n"
349 " qadd %[z],%[z],%[z];\n"
351 : [x]
"r" (x), [y]
"r" (y));
353 return (int16_t) (z >> 16);
359 return (int16_t) (z >> 15);
364 static __inline__ int32_t saturated_mul16_32(int16_t x, int16_t y)
368 #if defined(__GNUC__) && (defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_7A__))
369 __asm__ __volatile__(
" smulbb %[z],%[x],%[y];\n"
370 " qadd %[z],%[z],%[z];\n"
372 : [x]
"r" (x), [y]
"r" (y));
383 static __inline__ int16_t saturated_abs16(int16_t x)
387 return (int16_t) abs(x);
391 static __inline__ int32_t sat_abs32(int32_t x)
399 #if defined(__cplusplus)