diff options
author | Mans Rullgard <mans@mansr.com> | 2012-08-11 01:15:19 +0100 |
---|---|---|
committer | Mans Rullgard <mans@mansr.com> | 2012-08-13 01:03:10 +0100 |
commit | 6c4975eaafd7f8f91e81ad8d6be744a434241fd3 (patch) | |
tree | 9edb4f8cc534f15a876d417ab310468e43f26c1c /libavutil | |
parent | 17c11cef9f99d31e31dd9176ee2f26bdf6e5d351 (diff) | |
download | ffmpeg-6c4975eaafd7f8f91e81ad8d6be744a434241fd3.tar.gz |
libavutil: add saturating addition functions
Fixed-point audio codecs often use saturating arithmetic, and
special instructions for these operations are common.
Signed-off-by: Mans Rullgard <mans@mansr.com>
Diffstat (limited to 'libavutil')
-rw-r--r-- | libavutil/arm/intmath.h | 15 | ||||
-rw-r--r-- | libavutil/common.h | 30 |
2 files changed, 45 insertions, 0 deletions
diff --git a/libavutil/arm/intmath.h b/libavutil/arm/intmath.h index ce73404b37..d5a343c95f 100644 --- a/libavutil/arm/intmath.h +++ b/libavutil/arm/intmath.h @@ -83,6 +83,21 @@ static av_always_inline av_const unsigned av_clip_uintp2_arm(int a, int p) return x; } +#define av_sat_add32 av_sat_add32_arm +static av_always_inline int av_sat_add32_arm(int a, int b) +{ + int r; + __asm__ ("qadd %0, %1, %2" : "=r"(r) : "r"(a), "r"(b)); + return r; +} + +#define av_sat_dadd32 av_sat_dadd32_arm +static av_always_inline int av_sat_dadd32_arm(int a, int b) +{ + int r; + __asm__ ("qdadd %0, %1, %2" : "=r"(r) : "r"(a), "r"(b)); + return r; +} #else /* HAVE_ARMV6 */ diff --git a/libavutil/common.h b/libavutil/common.h index c99d858472..433e8e490a 100644 --- a/libavutil/common.h +++ b/libavutil/common.h @@ -182,6 +182,30 @@ static av_always_inline av_const unsigned av_clip_uintp2_c(int a, int p) } /** + * Add two signed 32-bit values with saturation. + * + * @param a one value + * @param b another value + * @return sum with signed saturation + */ +static av_always_inline int av_sat_add32_c(int a, int b) +{ + return av_clipl_int32((int64_t)a + b); +} + +/** + * Add a doubled value to another value with saturation at both stages. + * + * @param a first value + * @param b value doubled and added to a + * @return sum with signed saturation + */ +static av_always_inline int av_sat_dadd32_c(int a, int b) +{ + return av_sat_add32(a, av_sat_add32(b, b)); +} + +/** * Clip a float value into the amin-amax range. * @param a value to clip * @param amin minimum value of the clip range @@ -387,6 +411,12 @@ static av_always_inline av_const int av_popcount64_c(uint64_t x) #ifndef av_clip_uintp2 # define av_clip_uintp2 av_clip_uintp2_c #endif +#ifndef av_sat_add32 +# define av_sat_add32 av_sat_add32_c +#endif +#ifndef av_sat_dadd32 +# define av_sat_dadd32 av_sat_dadd32_c +#endif #ifndef av_clipf # define av_clipf av_clipf_c #endif |