tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

fixed_debug.h (23609B)


      1 /* Copyright (C) 2003-2008 Jean-Marc Valin
      2   Copyright (C) 2007-2012 Xiph.Org Foundation */
      3 /**
      4   @file fixed_debug.h
      5   @brief Fixed-point operations with debugging
      6 */
      7 /*
      8   Redistribution and use in source and binary forms, with or without
      9   modification, are permitted provided that the following conditions
     10   are met:
     11 
     12   - Redistributions of source code must retain the above copyright
     13   notice, this list of conditions and the following disclaimer.
     14 
     15   - Redistributions in binary form must reproduce the above copyright
     16   notice, this list of conditions and the following disclaimer in the
     17   documentation and/or other materials provided with the distribution.
     18 
     19   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     20   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     21   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     22   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
     23   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     24   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     25   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
     26   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
     27   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
     28   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
     29   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     30 */
     31 
     32 #ifndef FIXED_DEBUG_H
     33 #define FIXED_DEBUG_H
     34 
     35 #include <stdio.h>
     36 #include "opus_defines.h"
     37 
     38 #ifdef CELT_C
     39 OPUS_EXPORT opus_int64 celt_mips=0;
     40 #else
     41 extern opus_int64 celt_mips;
     42 #endif
     43 
     44 #define MULT16_16U(a,b) ((opus_uint32)(a)*(opus_uint32)(b))
     45 #define MULT16_16SU(a,b) ((opus_val32)(opus_val16)(a)*(opus_val32)(opus_uint16)(b))
     46 #define MULT32_32_Q31(a,b) ADD32(ADD32(SHL32(MULT16_16(SHR32((a),16),SHR((b),16)),1), SHR32(MULT16_16SU(SHR32((a),16),((b)&0x0000ffff)),15)), SHR32(MULT16_16SU(SHR32((b),16),((a)&0x0000ffff)),15))
     47 #define MULT32_32_P31(a,b) ADD32(SHL32(MULT16_16(SHR((a),16),SHR((b),16)),1), SHR32(128+(opus_int32)(MULT16_16U(((a)&0x0000ffff),((b)&0x0000ffff))>>(16+7)) + SHR32(MULT16_16SU(SHR((a),16),((b)&0x0000ffff)),7) + SHR32(MULT16_16SU(SHR((b),16),((a)&0x0000ffff)),7), 8) )
     48 #define MULT32_32_Q32(a,b) ADD32(ADD32(MULT16_16(SHR((a),16),SHR((b),16)), SHR(MULT16_16SU(SHR((a),16),((b)&0x0000ffff)),16)), SHR(MULT16_16SU(SHR((b),16),((a)&0x0000ffff)),16))
     49 
     50 /** 16x32 multiplication, followed by a 16-bit shift right. Results fits in 32 bits */
     51 #define MULT16_32_Q16(a,b) ADD32(MULT16_16((a),SHR32((b),16)), SHR32(MULT16_16SU((a),((b)&0x0000ffff)),16))
     52 
     53 #define MULT16_32_P16(a,b) MULT16_32_PX(a,b,16)
     54 
     55 #define QCONST16(x,bits) ((opus_val16)(.5+(x)*(((opus_val32)1)<<(bits))))
     56 #define QCONST32(x,bits) ((opus_val32)(.5+(x)*(((opus_val64)1)<<(bits))))
     57 #define GCONST2(x,bits) ((celt_glog)(.5+(x)*(((celt_glog)1)<<(bits))))
     58 #define GCONST(x) GCONST2((x),DB_SHIFT)
     59 
     60 #define VERIFY_SHORT(x) ((x)<=32767&&(x)>=-32768)
     61 #define VERIFY_INT(x) ((x)<=2147483647LL&&(x)>=-2147483648LL)
     62 #define VERIFY_UINT(x) ((x)<=(2147483647LLU<<1))
     63 
     64 #define SHR(a,b) SHR32(a,b)
     65 #define PSHR(a,b) PSHR32(a,b)
     66 
     67 /** Add two 32-bit values, ignore any overflows */
     68 #define ADD32_ovflw(a,b) (celt_mips+=2,(opus_val32)((opus_uint32)(a)+(opus_uint32)(b)))
     69 /** Subtract two 32-bit values, ignore any overflows */
     70 #define SUB32_ovflw(a,b) (celt_mips+=2,(opus_val32)((opus_uint32)(a)-(opus_uint32)(b)))
     71 /* Avoid MSVC warning C4146: unary minus operator applied to unsigned type */
     72 /** Negate 32-bit value, ignore any overflows */
     73 #define NEG32_ovflw(a) (celt_mips+=2,(opus_val32)(0-(opus_uint32)(a)))
     74 /** 32-bit shift left, ignoring overflows */
     75 #define SHL32_ovflw(a,shift) ((opus_int32)((opus_uint32)(a)<<(shift)))
     76 /** 32-bit arithmetic shift right with rounding-to-nearest, ignoring overflows */
     77 #define PSHR32_ovflw(a,shift) (SHR32(ADD32_ovflw(a, (EXTEND32(1)<<(shift)>>1)),shift))
     78 
     79 static OPUS_INLINE short NEG16(int x)
     80 {
     81   int res;
     82   if (!VERIFY_SHORT(x))
     83   {
     84      fprintf (stderr, "NEG16: input is not short: %d\n", (int)x);
     85 #ifdef FIXED_DEBUG_ASSERT
     86      celt_assert(0);
     87 #endif
     88   }
     89   res = -x;
     90   if (!VERIFY_SHORT(res))
     91   {
     92      fprintf (stderr, "NEG16: output is not short: %d\n", (int)res);
     93 #ifdef FIXED_DEBUG_ASSERT
     94      celt_assert(0);
     95 #endif
     96   }
     97   celt_mips++;
     98   return res;
     99 }
    100 static OPUS_INLINE int NEG32(opus_int64 x)
    101 {
    102   opus_int64 res;
    103   if (!VERIFY_INT(x))
    104   {
    105      fprintf (stderr, "NEG16: input is not int: %d\n", (int)x);
    106 #ifdef FIXED_DEBUG_ASSERT
    107      celt_assert(0);
    108 #endif
    109   }
    110   res = -x;
    111   if (!VERIFY_INT(res))
    112   {
    113      fprintf (stderr, "NEG16: output is not int: %d\n", (int)res);
    114 #ifdef FIXED_DEBUG_ASSERT
    115      celt_assert(0);
    116 #endif
    117   }
    118   celt_mips+=2;
    119   return res;
    120 }
    121 
    122 #define EXTRACT16(x) EXTRACT16_(x, __FILE__, __LINE__)
    123 static OPUS_INLINE short EXTRACT16_(int x, char *file, int line)
    124 {
    125   int res;
    126   if (!VERIFY_SHORT(x))
    127   {
    128      fprintf (stderr, "EXTRACT16: input is not short: %d in %s: line %d\n", x, file, line);
    129 #ifdef FIXED_DEBUG_ASSERT
    130      celt_assert(0);
    131 #endif
    132   }
    133   res = x;
    134   celt_mips++;
    135   return res;
    136 }
    137 
    138 #define EXTEND32(x) EXTEND32_(x, __FILE__, __LINE__)
    139 static OPUS_INLINE int EXTEND32_(int x, char *file, int line)
    140 {
    141   int res;
    142   if (!VERIFY_SHORT(x))
    143   {
    144      fprintf (stderr, "EXTEND32: input is not short: %d in %s: line %d\n", x, file, line);
    145 #ifdef FIXED_DEBUG_ASSERT
    146      celt_assert(0);
    147 #endif
    148   }
    149   res = x;
    150   celt_mips++;
    151   return res;
    152 }
    153 
    154 #define SHR16(a, shift) SHR16_(a, shift, __FILE__, __LINE__)
    155 static OPUS_INLINE short SHR16_(int a, int shift, char *file, int line)
    156 {
    157   int res;
    158   if (!VERIFY_SHORT(a) || !VERIFY_SHORT(shift))
    159   {
    160      fprintf (stderr, "SHR16: inputs are not short: %d >> %d in %s: line %d\n", a, shift, file, line);
    161 #ifdef FIXED_DEBUG_ASSERT
    162      celt_assert(0);
    163 #endif
    164   }
    165   res = a>>shift;
    166   if (!VERIFY_SHORT(res))
    167   {
    168      fprintf (stderr, "SHR16: output is not short: %d in %s: line %d\n", res, file, line);
    169 #ifdef FIXED_DEBUG_ASSERT
    170      celt_assert(0);
    171 #endif
    172   }
    173   celt_mips++;
    174   return res;
    175 }
    176 #define SHL16(a, shift) SHL16_(a, shift, __FILE__, __LINE__)
    177 static OPUS_INLINE short SHL16_(int a, int shift, char *file, int line)
    178 {
    179   opus_int32 res;
    180   if (!VERIFY_SHORT(a) || !VERIFY_SHORT(shift))
    181   {
    182      fprintf (stderr, "SHL16: inputs are not short: %d %d in %s: line %d\n", a, shift, file, line);
    183 #ifdef FIXED_DEBUG_ASSERT
    184      celt_assert(0);
    185 #endif
    186   }
    187   res = (opus_int32)((opus_uint32)a<<shift);
    188   if (!VERIFY_SHORT(res))
    189   {
    190      fprintf (stderr, "SHL16: output is not short: %d in %s: line %d\n", res, file, line);
    191 #ifdef FIXED_DEBUG_ASSERT
    192      celt_assert(0);
    193 #endif
    194   }
    195   celt_mips++;
    196   return res;
    197 }
    198 
    199 static OPUS_INLINE int SHR32(opus_int64 a, int shift)
    200 {
    201   opus_int64  res;
    202   if (!VERIFY_INT(a) || !VERIFY_SHORT(shift))
    203   {
    204      fprintf (stderr, "SHR32: inputs are not int: %d %d\n", (int)a, shift);
    205 #ifdef FIXED_DEBUG_ASSERT
    206      celt_assert(0);
    207 #endif
    208   }
    209   res = a>>shift;
    210   if (!VERIFY_INT(res))
    211   {
    212      fprintf (stderr, "SHR32: output is not int: %d\n", (int)res);
    213 #ifdef FIXED_DEBUG_ASSERT
    214      celt_assert(0);
    215 #endif
    216   }
    217   celt_mips+=2;
    218   return res;
    219 }
    220 #define SHL32(a, shift) SHL32_(a, shift, __FILE__, __LINE__)
    221 static OPUS_INLINE int SHL32_(opus_int64 a, int shift, char *file, int line)
    222 {
    223   opus_int64  res;
    224   if (!VERIFY_INT(a) || !VERIFY_SHORT(shift))
    225   {
    226      fprintf (stderr, "SHL32: inputs are not int: %lld %d in %s: line %d\n", (long long)a, shift, file, line);
    227 #ifdef FIXED_DEBUG_ASSERT
    228      celt_assert(0);
    229 #endif
    230   }
    231   res = (opus_int64)((opus_uint64)a<<shift);
    232   if (!VERIFY_INT(res))
    233   {
    234      fprintf (stderr, "SHL32: output is not int: %lld<<%d = %lld in %s: line %d\n", (long long)a, shift, (long long)res, file, line);
    235 #ifdef FIXED_DEBUG_ASSERT
    236      celt_assert(0);
    237 #endif
    238   }
    239   celt_mips+=2;
    240   return res;
    241 }
    242 
    243 #define PSHR32(a,shift) (celt_mips--,SHR32(ADD32((a),(((opus_val32)(1)<<((shift))>>1))),shift))
    244 #define VSHR32(a, shift) (((shift)>0) ? SHR32(a, shift) : SHL32(a, -(shift)))
    245 
    246 #define SHR64(a,shift) (celt_mips++,(a) >> (shift))
    247 
    248 #define ROUND16(x,a) (celt_mips--,EXTRACT16(PSHR32((x),(a))))
    249 #define SROUND16(x,a) (celt_mips--,EXTRACT16(SATURATE(PSHR32(x,a), 32767)));
    250 
    251 #define HALF16(x)  (SHR16(x,1))
    252 #define HALF32(x)  (SHR32(x,1))
    253 
    254 #define ADD16(a, b) ADD16_(a, b, __FILE__, __LINE__)
    255 static OPUS_INLINE short ADD16_(int a, int b, char *file, int line)
    256 {
    257   int res;
    258   if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
    259   {
    260      fprintf (stderr, "ADD16: inputs are not short: %d %d in %s: line %d\n", a, b, file, line);
    261 #ifdef FIXED_DEBUG_ASSERT
    262      celt_assert(0);
    263 #endif
    264   }
    265   res = a+b;
    266   if (!VERIFY_SHORT(res))
    267   {
    268      fprintf (stderr, "ADD16: output is not short: %d+%d=%d in %s: line %d\n", a,b,res, file, line);
    269 #ifdef FIXED_DEBUG_ASSERT
    270      celt_assert(0);
    271 #endif
    272   }
    273   celt_mips++;
    274   return res;
    275 }
    276 
    277 #define SUB16(a, b) SUB16_(a, b, __FILE__, __LINE__)
    278 static OPUS_INLINE short SUB16_(int a, int b, char *file, int line)
    279 {
    280   int res;
    281   if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
    282   {
    283      fprintf (stderr, "SUB16: inputs are not short: %d %d in %s: line %d\n", a, b, file, line);
    284 #ifdef FIXED_DEBUG_ASSERT
    285      celt_assert(0);
    286 #endif
    287   }
    288   res = a-b;
    289   if (!VERIFY_SHORT(res))
    290   {
    291      fprintf (stderr, "SUB16: output is not short: %d in %s: line %d\n", res, file, line);
    292 #ifdef FIXED_DEBUG_ASSERT
    293      celt_assert(0);
    294 #endif
    295   }
    296   celt_mips++;
    297   return res;
    298 }
    299 
    300 #define ADD32(a, b) ADD32_(a, b, __FILE__, __LINE__)
    301 static OPUS_INLINE int ADD32_(opus_int64 a, opus_int64 b, char *file, int line)
    302 {
    303   opus_int64 res;
    304   if (!VERIFY_INT(a) || !VERIFY_INT(b))
    305   {
    306      fprintf (stderr, "ADD32: inputs are not int: %d %d in %s: line %d\n", (int)a, (int)b, file, line);
    307 #ifdef FIXED_DEBUG_ASSERT
    308      celt_assert(0);
    309 #endif
    310   }
    311   res = a+b;
    312   if (!VERIFY_INT(res))
    313   {
    314      fprintf (stderr, "ADD32: output is not int: %d in %s: line %d\n", (int)res, file, line);
    315 #ifdef FIXED_DEBUG_ASSERT
    316      celt_assert(0);
    317 #endif
    318   }
    319   celt_mips+=2;
    320   return res;
    321 }
    322 
    323 #define SUB32(a, b) SUB32_(a, b, __FILE__, __LINE__)
    324 static OPUS_INLINE int SUB32_(opus_int64 a, opus_int64 b, char *file, int line)
    325 {
    326   opus_int64 res;
    327   if (!VERIFY_INT(a) || !VERIFY_INT(b))
    328   {
    329      fprintf (stderr, "SUB32: inputs are not int: %d %d in %s: line %d\n", (int)a, (int)b, file, line);
    330 #ifdef FIXED_DEBUG_ASSERT
    331      celt_assert(0);
    332 #endif
    333   }
    334   res = a-b;
    335   if (!VERIFY_INT(res))
    336   {
    337      fprintf (stderr, "SUB32: output is not int: %d in %s: line %d\n", (int)res, file, line);
    338 #ifdef FIXED_DEBUG_ASSERT
    339      celt_assert(0);
    340 #endif
    341   }
    342   celt_mips+=2;
    343   return res;
    344 }
    345 
    346 #undef UADD32
    347 #define UADD32(a, b) UADD32_(a, b, __FILE__, __LINE__)
    348 static OPUS_INLINE unsigned int UADD32_(opus_uint64 a, opus_uint64 b, char *file, int line)
    349 {
    350   opus_uint64 res;
    351   if (!VERIFY_UINT(a) || !VERIFY_UINT(b))
    352   {
    353      fprintf (stderr, "UADD32: inputs are not uint32: %llu %llu in %s: line %d\n", (unsigned long long)a, (unsigned long long)b, file, line);
    354 #ifdef FIXED_DEBUG_ASSERT
    355      celt_assert(0);
    356 #endif
    357   }
    358   res = a+b;
    359   if (!VERIFY_UINT(res))
    360   {
    361      fprintf (stderr, "UADD32: output is not uint32: %llu in %s: line %d\n", (unsigned long long)res, file, line);
    362 #ifdef FIXED_DEBUG_ASSERT
    363      celt_assert(0);
    364 #endif
    365   }
    366   celt_mips+=2;
    367   return res;
    368 }
    369 
    370 #undef USUB32
    371 #define USUB32(a, b) USUB32_(a, b, __FILE__, __LINE__)
    372 static OPUS_INLINE unsigned int USUB32_(opus_uint64 a, opus_uint64 b, char *file, int line)
    373 {
    374   opus_uint64 res;
    375   if (!VERIFY_UINT(a) || !VERIFY_UINT(b))
    376   {
    377      fprintf (stderr, "USUB32: inputs are not uint32: %llu %llu in %s: line %d\n", (unsigned long long)a, (unsigned long long)b, file, line);
    378 #ifdef FIXED_DEBUG_ASSERT
    379      celt_assert(0);
    380 #endif
    381   }
    382   if (a<b)
    383   {
    384      fprintf (stderr, "USUB32: inputs underflow: %llu < %llu in %s: line %d\n", (unsigned long long)a, (unsigned long long)b, file, line);
    385 #ifdef FIXED_DEBUG_ASSERT
    386      celt_assert(0);
    387 #endif
    388   }
    389   res = a-b;
    390   if (!VERIFY_UINT(res))
    391   {
    392      fprintf (stderr, "USUB32: output is not uint32: %llu - %llu = %llu in %s: line %d\n", (unsigned long long)a, (unsigned long long)b, (unsigned long long)res, file, line);
    393 #ifdef FIXED_DEBUG_ASSERT
    394      celt_assert(0);
    395 #endif
    396   }
    397   celt_mips+=2;
    398   return res;
    399 }
    400 
    401 /* result fits in 16 bits */
    402 static OPUS_INLINE short MULT16_16_16(int a, int b)
    403 {
    404   int res;
    405   if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
    406   {
    407      fprintf (stderr, "MULT16_16_16: inputs are not short: %d %d\n", a, b);
    408 #ifdef FIXED_DEBUG_ASSERT
    409      celt_assert(0);
    410 #endif
    411   }
    412   res = a*b;
    413   if (!VERIFY_SHORT(res))
    414   {
    415      fprintf (stderr, "MULT16_16_16: output is not short: %d\n", res);
    416 #ifdef FIXED_DEBUG_ASSERT
    417      celt_assert(0);
    418 #endif
    419   }
    420   celt_mips++;
    421   return res;
    422 }
    423 
    424 /* result fits in 32 bits */
    425 static OPUS_INLINE int MULT32_32_32(opus_int64 a, opus_int64 b)
    426 {
    427   opus_int64 res;
    428   if (!VERIFY_INT(a) || !VERIFY_INT(b))
    429   {
    430      fprintf (stderr, "MULT32_32_32: inputs are not int: %lld %lld\n", (long long)a, (long long)b);
    431 #ifdef FIXED_DEBUG_ASSERT
    432      celt_assert(0);
    433 #endif
    434   }
    435   res = a*b;
    436   if (!VERIFY_INT(res))
    437   {
    438      fprintf (stderr, "MULT32_32_32: output is not int: %lld\n", (long long)res);
    439 #ifdef FIXED_DEBUG_ASSERT
    440      celt_assert(0);
    441 #endif
    442   }
    443   celt_mips+=5;
    444   return res;
    445 }
    446 
    447 static OPUS_INLINE int MULT32_32_Q16(opus_int64 a, opus_int64 b)
    448 {
    449   opus_int64 res;
    450   if (!VERIFY_INT(a) || !VERIFY_INT(b))
    451   {
    452      fprintf (stderr, "MULT32_32_Q16: inputs are not int: %lld %lld\n", (long long)a, (long long)b);
    453 #ifdef FIXED_DEBUG_ASSERT
    454      celt_assert(0);
    455 #endif
    456   }
    457   res = ((opus_int64)(a)*(opus_int64)(b)) >> 16;
    458   if (!VERIFY_INT(res))
    459   {
    460      fprintf (stderr, "MULT32_32_Q16: output is not int: %lld*%lld=%lld\n", (long long)a, (long long)b, (long long)res);
    461 #ifdef FIXED_DEBUG_ASSERT
    462      celt_assert(0);
    463 #endif
    464   }
    465   celt_mips+=5;
    466   return res;
    467 }
    468 
    469 #define MULT16_16(a, b) MULT16_16_(a, b, __FILE__, __LINE__)
    470 static OPUS_INLINE int MULT16_16_(int a, int b, char *file, int line)
    471 {
    472   opus_int64 res;
    473   if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
    474   {
    475      fprintf (stderr, "MULT16_16: inputs are not short: %d %d in %s: line %d\n", a, b, file, line);
    476 #ifdef FIXED_DEBUG_ASSERT
    477      celt_assert(0);
    478 #endif
    479   }
    480   res = ((opus_int64)a)*b;
    481   if (!VERIFY_INT(res))
    482   {
    483      fprintf (stderr, "MULT16_16: output is not int: %d in %s: line %d\n", (int)res, file, line);
    484 #ifdef FIXED_DEBUG_ASSERT
    485      celt_assert(0);
    486 #endif
    487   }
    488   celt_mips++;
    489   return res;
    490 }
    491 
    492 #define MAC16_16(c,a,b)     (celt_mips-=2,ADD32((c),MULT16_16((a),(b))))
    493 
    494 #define MULT16_32_QX(a, b, Q) MULT16_32_QX_(a, b, Q, __FILE__, __LINE__)
    495 static OPUS_INLINE int MULT16_32_QX_(int a, opus_int64 b, int Q, char *file, int line)
    496 {
    497   opus_int64 res;
    498   if (!VERIFY_SHORT(a) || !VERIFY_INT(b))
    499   {
    500      fprintf (stderr, "MULT16_32_Q%d: inputs are not short+int: %d %d in %s: line %d\n", Q, (int)a, (int)b, file, line);
    501 #ifdef FIXED_DEBUG_ASSERT
    502      celt_assert(0);
    503 #endif
    504   }
    505   if (ABS32(b)>=((opus_int64)(1)<<(16+Q)))
    506   {
    507      fprintf (stderr, "MULT16_32_Q%d: second operand too large: %d %d in %s: line %d\n", Q, (int)a, (int)b, file, line);
    508 #ifdef FIXED_DEBUG_ASSERT
    509      celt_assert(0);
    510 #endif
    511   }
    512   res = (((opus_int64)a)*(opus_int64)b) >> Q;
    513   if (!VERIFY_INT(res))
    514   {
    515      fprintf (stderr, "MULT16_32_Q%d: output is not int: %d*%d=%d in %s: line %d\n", Q, (int)a, (int)b,(int)res, file, line);
    516 #ifdef FIXED_DEBUG_ASSERT
    517      celt_assert(0);
    518 #endif
    519   }
    520   if (Q==15)
    521      celt_mips+=3;
    522   else
    523      celt_mips+=4;
    524   return res;
    525 }
    526 
    527 #define MULT16_32_PX(a, b, Q) MULT16_32_PX_(a, b, Q, __FILE__, __LINE__)
    528 static OPUS_INLINE int MULT16_32_PX_(int a, opus_int64 b, int Q, char *file, int line)
    529 {
    530   opus_int64 res;
    531   if (!VERIFY_SHORT(a) || !VERIFY_INT(b))
    532   {
    533      fprintf (stderr, "MULT16_32_P%d: inputs are not short+int: %d %d in %s: line %d\n\n", Q, (int)a, (int)b, file, line);
    534 #ifdef FIXED_DEBUG_ASSERT
    535      celt_assert(0);
    536 #endif
    537   }
    538   if (ABS32(b)>=((opus_int64)(1)<<(16+Q)))
    539   {
    540      fprintf (stderr, "MULT16_32_Q%d: second operand too large: %d %d in %s: line %d\n\n", Q, (int)a, (int)b,file, line);
    541 #ifdef FIXED_DEBUG_ASSERT
    542      celt_assert(0);
    543 #endif
    544   }
    545   res = ((((opus_int64)a)*(opus_int64)b) + (((opus_val32)(1)<<Q)>>1))>> Q;
    546   if (!VERIFY_INT(res))
    547   {
    548      fprintf (stderr, "MULT16_32_P%d: output is not int: %d*%d=%d in %s: line %d\n\n", Q, (int)a, (int)b,(int)res, file, line);
    549 #ifdef FIXED_DEBUG_ASSERT
    550      celt_assert(0);
    551 #endif
    552   }
    553   if (Q==15)
    554      celt_mips+=4;
    555   else
    556      celt_mips+=5;
    557   return res;
    558 }
    559 
    560 #define MULT16_32_Q15(a,b) MULT16_32_QX(a,b,15)
    561 #define MAC16_32_Q15(c,a,b) (celt_mips-=2,ADD32((c),MULT16_32_Q15((a),(b))))
    562 #define MAC16_32_Q16(c,a,b) (celt_mips-=2,ADD32((c),MULT16_32_Q16((a),(b))))
    563 
    564 static OPUS_INLINE int SATURATE(int a, int b)
    565 {
    566   if (a>b)
    567      a=b;
    568   if (a<-b)
    569      a = -b;
    570   celt_mips+=3;
    571   return a;
    572 }
    573 
    574 static OPUS_INLINE opus_int16 SATURATE16(opus_int32 a)
    575 {
    576   celt_mips+=3;
    577   if (a>32767)
    578      return 32767;
    579   else if (a<-32768)
    580      return -32768;
    581   else return a;
    582 }
    583 
    584 static OPUS_INLINE int MULT16_16_Q11_32(int a, int b)
    585 {
    586   opus_int64 res;
    587   if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
    588   {
    589      fprintf (stderr, "MULT16_16_Q11: inputs are not short: %d %d\n", a, b);
    590 #ifdef FIXED_DEBUG_ASSERT
    591      celt_assert(0);
    592 #endif
    593   }
    594   res = ((opus_int64)a)*b;
    595   res >>= 11;
    596   if (!VERIFY_INT(res))
    597   {
    598      fprintf (stderr, "MULT16_16_Q11: output is not short: %d*%d=%d\n", (int)a, (int)b, (int)res);
    599 #ifdef FIXED_DEBUG_ASSERT
    600      celt_assert(0);
    601 #endif
    602   }
    603   celt_mips+=3;
    604   return res;
    605 }
    606 static OPUS_INLINE short MULT16_16_Q13(int a, int b)
    607 {
    608   opus_int64 res;
    609   if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
    610   {
    611      fprintf (stderr, "MULT16_16_Q13: inputs are not short: %d %d\n", a, b);
    612 #ifdef FIXED_DEBUG_ASSERT
    613      celt_assert(0);
    614 #endif
    615   }
    616   res = ((opus_int64)a)*b;
    617   res >>= 13;
    618   if (!VERIFY_SHORT(res))
    619   {
    620      fprintf (stderr, "MULT16_16_Q13: output is not short: %d*%d=%d\n", a, b, (int)res);
    621 #ifdef FIXED_DEBUG_ASSERT
    622      celt_assert(0);
    623 #endif
    624   }
    625   celt_mips+=3;
    626   return res;
    627 }
    628 static OPUS_INLINE short MULT16_16_Q14(int a, int b)
    629 {
    630   opus_int64 res;
    631   if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
    632   {
    633      fprintf (stderr, "MULT16_16_Q14: inputs are not short: %d %d\n", a, b);
    634 #ifdef FIXED_DEBUG_ASSERT
    635      celt_assert(0);
    636 #endif
    637   }
    638   res = ((opus_int64)a)*b;
    639   res >>= 14;
    640   if (!VERIFY_SHORT(res))
    641   {
    642      fprintf (stderr, "MULT16_16_Q14: output is not short: %d\n", (int)res);
    643 #ifdef FIXED_DEBUG_ASSERT
    644      celt_assert(0);
    645 #endif
    646   }
    647   celt_mips+=3;
    648   return res;
    649 }
    650 
    651 #define MULT16_16_Q15(a, b) MULT16_16_Q15_(a, b, __FILE__, __LINE__)
    652 static OPUS_INLINE short MULT16_16_Q15_(int a, int b, char *file, int line)
    653 {
    654   opus_int64 res;
    655   if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
    656   {
    657      fprintf (stderr, "MULT16_16_Q15: inputs are not short: %d %d in %s: line %d\n", a, b, file, line);
    658 #ifdef FIXED_DEBUG_ASSERT
    659      celt_assert(0);
    660 #endif
    661   }
    662   res = ((opus_int64)a)*b;
    663   res >>= 15;
    664   if (!VERIFY_SHORT(res))
    665   {
    666      fprintf (stderr, "MULT16_16_Q15: output is not short: %d in %s: line %d\n", (int)res, file, line);
    667 #ifdef FIXED_DEBUG_ASSERT
    668      celt_assert(0);
    669 #endif
    670   }
    671   celt_mips+=1;
    672   return res;
    673 }
    674 
    675 static OPUS_INLINE short MULT16_16_P13(int a, int b)
    676 {
    677   opus_int64 res;
    678   if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
    679   {
    680      fprintf (stderr, "MULT16_16_P13: inputs are not short: %d %d\n", a, b);
    681 #ifdef FIXED_DEBUG_ASSERT
    682      celt_assert(0);
    683 #endif
    684   }
    685   res = ((opus_int64)a)*b;
    686   res += 4096;
    687   if (!VERIFY_INT(res))
    688   {
    689      fprintf (stderr, "MULT16_16_P13: overflow: %d*%d=%d\n", a, b, (int)res);
    690 #ifdef FIXED_DEBUG_ASSERT
    691      celt_assert(0);
    692 #endif
    693   }
    694   res >>= 13;
    695   if (!VERIFY_SHORT(res))
    696   {
    697      fprintf (stderr, "MULT16_16_P13: output is not short: %d*%d=%d\n", a, b, (int)res);
    698 #ifdef FIXED_DEBUG_ASSERT
    699      celt_assert(0);
    700 #endif
    701   }
    702   celt_mips+=4;
    703   return res;
    704 }
    705 static OPUS_INLINE short MULT16_16_P14(int a, int b)
    706 {
    707   opus_int64 res;
    708   if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
    709   {
    710      fprintf (stderr, "MULT16_16_P14: inputs are not short: %d %d\n", a, b);
    711 #ifdef FIXED_DEBUG_ASSERT
    712      celt_assert(0);
    713 #endif
    714   }
    715   res = ((opus_int64)a)*b;
    716   res += 8192;
    717   if (!VERIFY_INT(res))
    718   {
    719      fprintf (stderr, "MULT16_16_P14: overflow: %d*%d=%d\n", a, b, (int)res);
    720 #ifdef FIXED_DEBUG_ASSERT
    721      celt_assert(0);
    722 #endif
    723   }
    724   res >>= 14;
    725   if (!VERIFY_SHORT(res))
    726   {
    727      fprintf (stderr, "MULT16_16_P14: output is not short: %d*%d=%d\n", a, b, (int)res);
    728 #ifdef FIXED_DEBUG_ASSERT
    729      celt_assert(0);
    730 #endif
    731   }
    732   celt_mips+=4;
    733   return res;
    734 }
    735 static OPUS_INLINE short MULT16_16_P15(int a, int b)
    736 {
    737   opus_int64 res;
    738   if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
    739   {
    740      fprintf (stderr, "MULT16_16_P15: inputs are not short: %d %d\n", a, b);
    741 #ifdef FIXED_DEBUG_ASSERT
    742      celt_assert(0);
    743 #endif
    744   }
    745   res = ((opus_int64)a)*b;
    746   res += 16384;
    747   if (!VERIFY_INT(res))
    748   {
    749      fprintf (stderr, "MULT16_16_P15: overflow: %d*%d=%d\n", a, b, (int)res);
    750 #ifdef FIXED_DEBUG_ASSERT
    751      celt_assert(0);
    752 #endif
    753   }
    754   res >>= 15;
    755   if (!VERIFY_SHORT(res))
    756   {
    757      fprintf (stderr, "MULT16_16_P15: output is not short: %d*%d=%d\n", a, b, (int)res);
    758 #ifdef FIXED_DEBUG_ASSERT
    759      celt_assert(0);
    760 #endif
    761   }
    762   celt_mips+=2;
    763   return res;
    764 }
    765 
    766 #define DIV32_16(a, b) DIV32_16_(a, b, __FILE__, __LINE__)
    767 
    768 static OPUS_INLINE int DIV32_16_(opus_int64 a, opus_int64 b, char *file, int line)
    769 {
    770   opus_int64 res;
    771   if (b==0)
    772   {
    773      fprintf(stderr, "DIV32_16: divide by zero: %d/%d in %s: line %d\n", (int)a, (int)b, file, line);
    774 #ifdef FIXED_DEBUG_ASSERT
    775      celt_assert(0);
    776 #endif
    777      return 0;
    778   }
    779   if (!VERIFY_INT(a) || !VERIFY_SHORT(b))
    780   {
    781      fprintf (stderr, "DIV32_16: inputs are not int/short: %d %d in %s: line %d\n", (int)a, (int)b, file, line);
    782 #ifdef FIXED_DEBUG_ASSERT
    783      celt_assert(0);
    784 #endif
    785   }
    786   res = a/b;
    787   if (!VERIFY_SHORT(res))
    788   {
    789      fprintf (stderr, "DIV32_16: output is not short: %d / %d = %d in %s: line %d\n", (int)a,(int)b,(int)res, file, line);
    790      if (res>32767)
    791         res = 32767;
    792      if (res<-32768)
    793         res = -32768;
    794 #ifdef FIXED_DEBUG_ASSERT
    795      celt_assert(0);
    796 #endif
    797   }
    798   celt_mips+=35;
    799   return res;
    800 }
    801 
    802 #define DIV32(a, b) DIV32_(a, b, __FILE__, __LINE__)
    803 static OPUS_INLINE int DIV32_(opus_int64 a, opus_int64 b, char *file, int line)
    804 {
    805   opus_int64 res;
    806   if (b==0)
    807   {
    808      fprintf(stderr, "DIV32: divide by zero: %d/%d in %s: line %d\n", (int)a, (int)b, file, line);
    809 #ifdef FIXED_DEBUG_ASSERT
    810      celt_assert(0);
    811 #endif
    812      return 0;
    813   }
    814 
    815   if (!VERIFY_INT(a) || !VERIFY_INT(b))
    816   {
    817      fprintf (stderr, "DIV32: inputs are not int/short: %d %d in %s: line %d\n", (int)a, (int)b, file, line);
    818 #ifdef FIXED_DEBUG_ASSERT
    819      celt_assert(0);
    820 #endif
    821   }
    822   res = a/b;
    823   if (!VERIFY_INT(res))
    824   {
    825      fprintf (stderr, "DIV32: output is not int: %d in %s: line %d\n", (int)res, file, line);
    826 #ifdef FIXED_DEBUG_ASSERT
    827      celt_assert(0);
    828 #endif
    829   }
    830   celt_mips+=70;
    831   return res;
    832 }
    833 
    834 static OPUS_INLINE opus_val16 SIG2WORD16_generic(celt_sig x)
    835 {
    836   x = PSHR32(x, SIG_SHIFT);
    837   x = MAX32(x, -32768);
    838   x = MIN32(x, 32767);
    839   return EXTRACT16(x);
    840 }
    841 #define SIG2WORD16(x) (SIG2WORD16_generic(x))
    842 
    843 
    844 #undef PRINT_MIPS
    845 #define PRINT_MIPS(file) do {fprintf (file, "total complexity = %llu MIPS\n", (unsigned long long)celt_mips);} while (0);
    846 
    847 #endif