Fixed-point audio codecs often use saturating arithmetic, and
special instructions for these operations are common.
Signed-off-by: Mans Rullgard <mans@mansr.com>
... | ... |
@@ -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 |