2025-03-09 23:45:43 +09:00

138 lines
2.2 KiB
C

/**
* @file rem_dsp.h DSP routines
*
* Copyright (C) 2010 Creytiv.com
*/
#ifndef UINT8_MAX
#define UINT8_MAX (255U)
#endif
#define INT15_MAX 0x3fff
#define INT15_MIN (-INT15_MAX - 1)
#ifndef INT16_MAX
#define INT16_MAX 0x7fff
#endif
#ifndef INT16_MIN
#define INT16_MIN (-INT16_MAX - 1)
#endif
/* todo: check which preprocessor macros to use */
#if defined (HAVE_ARMV6) || defined (HAVE_NEON)
static inline uint8_t saturate_u8(int32_t a)
{
uint8_t r;
__asm__ __volatile__ ("usat %0, #8, %1" : "=r"(r) : "r"(a));
return r;
}
static inline int16_t saturate_s15(int32_t a)
{
__asm__ __volatile__ ("ssat %0, #15, %1 \n\t"
: "+r"(a)
: "r"(a)
);
return a;
}
static inline int16_t saturate_s16(int32_t a)
{
__asm__ __volatile__ ("ssat %0, #16, %1 \n\t"
: "+r"(a)
: "r"(a)
);
return a;
}
static inline int16_t saturate_add16(int32_t a, int32_t b)
{
__asm__ __volatile__ ("add %0, %1, %2 \n\t"
"ssat %0, #16, %0 \n\t"
:"+r"(a)
:"r"(a), "r"(b)
);
return a;
}
static inline int16_t saturate_sub16(int32_t a, int32_t b)
{
__asm__ __volatile__ ("sub %0, %1, %2 \n\t"
"ssat %0, #16, %0 \n\t"
:"+r"(a)
:"r"(a), "r"(b)
);
return a;
}
#else
static inline uint8_t saturate_u8(int32_t a)
{
return (a > (int32_t)UINT8_MAX) ? UINT8_MAX : ((a < 0) ? 0 : a);
}
static inline int16_t saturate_s15(int32_t a)
{
if (a > INT15_MAX)
return INT15_MAX;
else if (a < INT15_MIN)
return INT15_MIN;
else
return a;
}
static inline int16_t saturate_s16(int32_t a)
{
if (a > INT16_MAX)
return INT16_MAX;
else if (a < INT16_MIN)
return INT16_MIN;
else
return a;
}
static inline int16_t saturate_add16(int32_t a, int32_t b)
{
return saturate_s16(a + b);
}
static inline int16_t saturate_sub16(int32_t a, int32_t b)
{
return saturate_s16(a - b);
}
#endif
#ifdef HAVE_NEON
static inline int ABS32(int a)
{
int r;
__asm__ __volatile__ ("vmov.s32 d0[0], %1 \t\n"
"vabs.s32 d0, d0 \t\n"
"vmov.s32 %0, d0[0] \t\n"
: "=r"(r)
: "r"(a)
);
return a;
}
#else
static inline int ABS32(int a)
{
return a > 0 ? a : -a;
}
#endif