Browse code

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>

Mans Rullgard authored on 2012/08/11 09:15:19
Showing 2 changed files
... ...
@@ -83,6 +83,21 @@ static av_always_inline av_const unsigned av_clip_uintp2_arm(int a, int p)
83 83
     return x;
84 84
 }
85 85
 
86
+#define av_sat_add32 av_sat_add32_arm
87
+static av_always_inline int av_sat_add32_arm(int a, int b)
88
+{
89
+    int r;
90
+    __asm__ ("qadd %0, %1, %2" : "=r"(r) : "r"(a), "r"(b));
91
+    return r;
92
+}
93
+
94
+#define av_sat_dadd32 av_sat_dadd32_arm
95
+static av_always_inline int av_sat_dadd32_arm(int a, int b)
96
+{
97
+    int r;
98
+    __asm__ ("qdadd %0, %1, %2" : "=r"(r) : "r"(a), "r"(b));
99
+    return r;
100
+}
86 101
 
87 102
 #else /* HAVE_ARMV6 */
88 103
 
... ...
@@ -182,6 +182,30 @@ static av_always_inline av_const unsigned av_clip_uintp2_c(int a, int p)
182 182
 }
183 183
 
184 184
 /**
185
+ * Add two signed 32-bit values with saturation.
186
+ *
187
+ * @param  a one value
188
+ * @param  b another value
189
+ * @return sum with signed saturation
190
+ */
191
+static av_always_inline int av_sat_add32_c(int a, int b)
192
+{
193
+    return av_clipl_int32((int64_t)a + b);
194
+}
195
+
196
+/**
197
+ * Add a doubled value to another value with saturation at both stages.
198
+ *
199
+ * @param  a first value
200
+ * @param  b value doubled and added to a
201
+ * @return sum with signed saturation
202
+ */
203
+static av_always_inline int av_sat_dadd32_c(int a, int b)
204
+{
205
+    return av_sat_add32(a, av_sat_add32(b, b));
206
+}
207
+
208
+/**
185 209
  * Clip a float value into the amin-amax range.
186 210
  * @param a value to clip
187 211
  * @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)
387 387
 #ifndef av_clip_uintp2
388 388
 #   define av_clip_uintp2   av_clip_uintp2_c
389 389
 #endif
390
+#ifndef av_sat_add32
391
+#   define av_sat_add32     av_sat_add32_c
392
+#endif
393
+#ifndef av_sat_dadd32
394
+#   define av_sat_dadd32    av_sat_dadd32_c
395
+#endif
390 396
 #ifndef av_clipf
391 397
 #   define av_clipf         av_clipf_c
392 398
 #endif