libavutil: add saturating addition functions
authorMans Rullgard <mans@mansr.com>
Sat, 11 Aug 2012 00:15:19 +0000 (01:15 +0100)
committerMans Rullgard <mans@mansr.com>
Mon, 13 Aug 2012 00:03:10 +0000 (01:03 +0100)
Fixed-point audio codecs often use saturating arithmetic, and
special instructions for these operations are common.

Signed-off-by: Mans Rullgard <mans@mansr.com>
libavutil/arm/intmath.h
libavutil/common.h

index ce73404..d5a343c 100644 (file)
@@ -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 */
 
index c99d858..433e8e4 100644 (file)
@@ -181,6 +181,30 @@ static av_always_inline av_const unsigned av_clip_uintp2_c(int a, int p)
     else                   return  a;
 }
 
+/**
+ * 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
@@ -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