Defining IMUL32 for 32x32=>32 int multiplications and using it in the range
authorJean-Marc Valin <jean-marc.valin@usherbrooke.ca>
Thu, 10 Apr 2008 03:24:48 +0000 (13:24 +1000)
committerJean-Marc Valin <jean-marc.valin@usherbrooke.ca>
Thu, 10 Apr 2008 03:24:48 +0000 (13:24 +1000)
coder

libcelt/arch.h
libcelt/fixed_c5x.h
libcelt/rangedec.c
libcelt/rangeenc.c

index 0e41cce..9a3569e 100644 (file)
@@ -47,6 +47,7 @@
 #define celt_assert2(cond, message)
 #endif
 
+#define IMUL32(a,b) ((a)*(b))
 
 #define ABS(x) ((x) < 0 ? (-(x)) : (x))      /**< Absolute integer value. */
 #define ABS16(x) ((x) < 0 ? (-(x)) : (x))    /**< Absolute 16-bit value.  */
index 87bdc77..de7a217 100644 (file)
 
 #include "dsplib.h"
 
+#undef IMUL32
+static inline long IMUL32(long i, long j)
+{
+   long ac0, ac1;
+   ac0 = _lmpy(i>>16,j);
+   ac1 = ac0 + _lmpy(i,j>>16);
+   return _lmpyu(i,j) + (ac1<<16);
+}
+
 #undef MAX16
 #define MAX16(a,b) _max(a,b)
 
index 067f7dc..3fd5bd5 100644 (file)
@@ -2,6 +2,7 @@
 #include "config.h"
 #endif
 
+#include "arch.h"
 #include "entdec.h"
 #include "mfrngcod.h"
 
@@ -179,9 +180,9 @@ unsigned ec_decode_bin(ec_dec *_this,unsigned bits){
 
 void ec_dec_update(ec_dec *_this,unsigned _fl,unsigned _fh,unsigned _ft){
   ec_uint32 s;
-  s=_this->nrm*(_ft-_fh);
+  s=IMUL32(_this->nrm,(_ft-_fh));
   _this->dif-=s;
-  _this->rng=_fl>0?_this->nrm*(_fh-_fl):_this->rng-s;
+  _this->rng=_fl>0?IMUL32(_this->nrm,(_fh-_fl)):_this->rng-s;
   ec_dec_normalize(_this);
 }
 
index 13bddd6..51e1ffe 100644 (file)
@@ -2,6 +2,7 @@
 #include "config.h"
 #endif
 
+#include "arch.h"
 #include "entenc.h"
 #include "mfrngcod.h"
 
@@ -85,10 +86,10 @@ void ec_encode(ec_enc *_this,unsigned _fl,unsigned _fh,unsigned _ft){
   ec_uint32 r;
   r=_this->rng/_ft;
   if(_fl>0){
-    _this->low+=_this->rng-r*(_ft-_fl);
-    _this->rng=r*(_fh-_fl);
+    _this->low+=_this->rng-IMUL32(r,(_ft-_fl));
+    _this->rng=IMUL32(r,(_fh-_fl));
   }
-  else _this->rng-=r*(_ft-_fh);
+  else _this->rng-=IMUL32(r,(_ft-_fh));
   ec_enc_normalize(_this);
 }
 
@@ -97,10 +98,10 @@ void ec_encode_bin(ec_enc *_this,unsigned _fl,unsigned _fh,unsigned bits){
    r=_this->rng>>bits;
    ft = (ec_uint32)1<<bits;
    if(_fl>0){
-      _this->low+=_this->rng-r*(ft-_fl);
-      _this->rng=r*(_fh-_fl);
+     _this->low+=_this->rng-IMUL32(r,(ft-_fl));
+     _this->rng=IMUL32(r,(_fh-_fl));
    }
-   else _this->rng-=r*(ft-_fh);
+   else _this->rng-=IMUL32(r,(ft-_fh));
    ec_enc_normalize(_this);
 }