Index: celt/entcode.h |
diff --git a/celt/entcode.h b/celt/entcode.h |
index dd13e49e50499601ea3005c8ec4f8d5295609915..13d6c84ef0fa39205166d3e776134b9bc23275c5 100644 |
--- a/celt/entcode.h |
+++ b/celt/entcode.h |
@@ -34,6 +34,12 @@ |
# include <stddef.h> |
# include "ecintrin.h" |
+extern const opus_uint32 SMALL_DIV_TABLE[129]; |
+ |
+#ifdef OPUS_ARM_ASM |
+#define USE_SMALL_DIV_TABLE |
+#endif |
+ |
/*OPT: ec_window must be at least 32 bits, but if you have fast arithmetic on a |
larger type, you can speed up the decoder by using it here.*/ |
typedef opus_uint32 ec_window; |
@@ -114,4 +120,33 @@ static OPUS_INLINE int ec_tell(ec_ctx *_this){ |
rounding error is in the positive direction).*/ |
opus_uint32 ec_tell_frac(ec_ctx *_this); |
+/* Tested exhaustively for all n and for 1<=d<=256 */ |
+static OPUS_INLINE opus_uint32 celt_udiv(opus_uint32 n, opus_uint32 d) { |
+ celt_assert(d>0); |
+#ifdef USE_SMALL_DIV_TABLE |
+ if (d>256) |
+ return n/d; |
+ else { |
+ opus_uint32 t, q; |
+ t = EC_ILOG(d&-d); |
+ q = (opus_uint64)SMALL_DIV_TABLE[d>>t]*(n>>(t-1))>>32; |
+ return q+(n-q*d >= d); |
+ } |
+#else |
+ return n/d; |
+#endif |
+} |
+ |
+static OPUS_INLINE opus_int32 celt_sudiv(opus_int32 n, opus_int32 d) { |
+ celt_assert(d>0); |
+#ifdef USE_SMALL_DIV_TABLE |
+ if (n<0) |
+ return -(opus_int32)celt_udiv(-n, d); |
+ else |
+ return celt_udiv(n, d); |
+#else |
+ return n/d; |
+#endif |
+} |
+ |
#endif |