Merge branch 'tmp_draft'
[opus.git] / celt / fixed_debug.h
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
37 #ifdef CELT_C
38 #include "opus_defines.h"
39 OPUS_EXPORT long long celt_mips=0;
40 #else
41 extern long long celt_mips;
42 #endif
43
44 #define MULT16_16SU(a,b) ((opus_val32)(opus_val16)(a)*(opus_val32)(opus_uint16)(b))
45 #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))
46
47 /** 16x32 multiplication, followed by a 16-bit shift right. Results fits in 32 bits */
48 #define MULT16_32_Q16(a,b) ADD32(MULT16_16((a),SHR32((b),16)), SHR32(MULT16_16SU((a),((b)&0x0000ffff)),16))
49
50 #define QCONST16(x,bits) ((opus_val16)(.5+(x)*(((opus_val32)1)<<(bits))))
51 #define QCONST32(x,bits) ((opus_val32)(.5+(x)*(((opus_val32)1)<<(bits))))
52
53 #define VERIFY_SHORT(x) ((x)<=32767&&(x)>=-32768)
54 #define VERIFY_INT(x) ((x)<=2147483647LL&&(x)>=-2147483648LL)
55 #define VERIFY_UINT(x) ((x)<=(2147483647LLU<<1))
56
57 #define SHR(a,b) SHR32(a,b)
58 #define PSHR(a,b) PSHR32(a,b)
59
60 static inline short NEG16(int x)
61 {
62    int res;
63    if (!VERIFY_SHORT(x))
64    {
65       fprintf (stderr, "NEG16: input is not short: %d\n", (int)x);
66 #ifdef FIXED_DEBUG_ASSERT
67       celt_assert(0);
68 #endif
69    }
70    res = -x;
71    if (!VERIFY_SHORT(res))
72    {
73       fprintf (stderr, "NEG16: output is not short: %d\n", (int)res);
74 #ifdef FIXED_DEBUG_ASSERT
75       celt_assert(0);
76 #endif
77    }
78    celt_mips++;
79    return res;
80 }
81 static inline int NEG32(long long x)
82 {
83    long long res;
84    if (!VERIFY_INT(x))
85    {
86       fprintf (stderr, "NEG16: input is not int: %d\n", (int)x);
87 #ifdef FIXED_DEBUG_ASSERT
88       celt_assert(0);
89 #endif
90    }
91    res = -x;
92    if (!VERIFY_INT(res))
93    {
94       fprintf (stderr, "NEG16: output is not int: %d\n", (int)res);
95 #ifdef FIXED_DEBUG_ASSERT
96       celt_assert(0);
97 #endif
98    }
99    celt_mips+=2;
100    return res;
101 }
102
103 #define EXTRACT16(x) EXTRACT16_(x, __FILE__, __LINE__)
104 static inline short EXTRACT16_(int x, char *file, int line)
105 {
106    int res;
107    if (!VERIFY_SHORT(x))
108    {
109       fprintf (stderr, "EXTRACT16: input is not short: %d in %s: line %d\n", x, file, line);
110 #ifdef FIXED_DEBUG_ASSERT
111       celt_assert(0);
112 #endif
113    }
114    res = x;
115    celt_mips++;
116    return res;
117 }
118
119 #define EXTEND32(x) EXTEND32_(x, __FILE__, __LINE__)
120 static inline int EXTEND32_(int x, char *file, int line)
121 {
122    int res;
123    if (!VERIFY_SHORT(x))
124    {
125       fprintf (stderr, "EXTEND32: input is not short: %d in %s: line %d\n", x, file, line);
126 #ifdef FIXED_DEBUG_ASSERT
127       celt_assert(0);
128 #endif
129    }
130    res = x;
131    celt_mips++;
132    return res;
133 }
134
135 #define SHR16(a, shift) SHR16_(a, shift, __FILE__, __LINE__)
136 static inline short SHR16_(int a, int shift, char *file, int line)
137 {
138    int res;
139    if (!VERIFY_SHORT(a) || !VERIFY_SHORT(shift))
140    {
141       fprintf (stderr, "SHR16: inputs are not short: %d >> %d in %s: line %d\n", a, shift, file, line);
142 #ifdef FIXED_DEBUG_ASSERT
143       celt_assert(0);
144 #endif
145    }
146    res = a>>shift;
147    if (!VERIFY_SHORT(res))
148    {
149       fprintf (stderr, "SHR16: output is not short: %d in %s: line %d\n", res, file, line);
150 #ifdef FIXED_DEBUG_ASSERT
151       celt_assert(0);
152 #endif
153    }
154    celt_mips++;
155    return res;
156 }
157 #define SHL16(a, shift) SHL16_(a, shift, __FILE__, __LINE__)
158 static inline short SHL16_(int a, int shift, char *file, int line)
159 {
160    int res;
161    if (!VERIFY_SHORT(a) || !VERIFY_SHORT(shift))
162    {
163       fprintf (stderr, "SHL16: inputs are not short: %d %d in %s: line %d\n", a, shift, file, line);
164 #ifdef FIXED_DEBUG_ASSERT
165       celt_assert(0);
166 #endif
167    }
168    res = a<<shift;
169    if (!VERIFY_SHORT(res))
170    {
171       fprintf (stderr, "SHL16: output is not short: %d in %s: line %d\n", res, file, line);
172 #ifdef FIXED_DEBUG_ASSERT
173       celt_assert(0);
174 #endif
175    }
176    celt_mips++;
177    return res;
178 }
179
180 static inline int SHR32(long long a, int shift)
181 {
182    long long  res;
183    if (!VERIFY_INT(a) || !VERIFY_SHORT(shift))
184    {
185       fprintf (stderr, "SHR32: inputs are not int: %d %d\n", (int)a, shift);
186 #ifdef FIXED_DEBUG_ASSERT
187       celt_assert(0);
188 #endif
189    }
190    res = a>>shift;
191    if (!VERIFY_INT(res))
192    {
193       fprintf (stderr, "SHR32: output is not int: %d\n", (int)res);
194 #ifdef FIXED_DEBUG_ASSERT
195       celt_assert(0);
196 #endif
197    }
198    celt_mips+=2;
199    return res;
200 }
201 #define SHL32(a, shift) SHL32_(a, shift, __FILE__, __LINE__)
202 static inline int SHL32_(long long a, int shift, char *file, int line)
203 {
204    long long  res;
205    if (!VERIFY_INT(a) || !VERIFY_SHORT(shift))
206    {
207       fprintf (stderr, "SHL32: inputs are not int: %lld %d in %s: line %d\n", a, shift, file, line);
208 #ifdef FIXED_DEBUG_ASSERT
209       celt_assert(0);
210 #endif
211    }
212    res = a<<shift;
213    if (!VERIFY_INT(res))
214    {
215       fprintf (stderr, "SHL32: output is not int: %lld<<%d = %lld in %s: line %d\n", a, shift, res, file, line);
216 #ifdef FIXED_DEBUG_ASSERT
217       celt_assert(0);
218 #endif
219    }
220    celt_mips+=2;
221    return res;
222 }
223
224 #define PSHR32(a,shift) (celt_mips--,SHR32(ADD32((a),(((opus_val32)(1)<<((shift))>>1))),shift))
225 #define VSHR32(a, shift) (((shift)>0) ? SHR32(a, shift) : SHL32(a, -(shift)))
226
227 #define ROUND16(x,a) (celt_mips--,EXTRACT16(PSHR32((x),(a))))
228 #define HALF16(x)  (SHR16(x,1))
229 #define HALF32(x)  (SHR32(x,1))
230
231 //#define SHR(a,shift) ((a) >> (shift))
232 //#define SHL(a,shift) ((a) << (shift))
233
234 #define ADD16(a, b) ADD16_(a, b, __FILE__, __LINE__)
235 static inline short ADD16_(int a, int b, char *file, int line)
236 {
237    int res;
238    if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
239    {
240       fprintf (stderr, "ADD16: inputs are not short: %d %d in %s: line %d\n", a, b, file, line);
241 #ifdef FIXED_DEBUG_ASSERT
242       celt_assert(0);
243 #endif
244    }
245    res = a+b;
246    if (!VERIFY_SHORT(res))
247    {
248       fprintf (stderr, "ADD16: output is not short: %d+%d=%d in %s: line %d\n", a,b,res, file, line);
249 #ifdef FIXED_DEBUG_ASSERT
250       celt_assert(0);
251 #endif
252    }
253    celt_mips++;
254    return res;
255 }
256
257 #define SUB16(a, b) SUB16_(a, b, __FILE__, __LINE__)
258 static inline short SUB16_(int a, int b, char *file, int line)
259 {
260    int res;
261    if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
262    {
263       fprintf (stderr, "SUB16: inputs are not short: %d %d in %s: line %d\n", a, b, file, line);
264 #ifdef FIXED_DEBUG_ASSERT
265       celt_assert(0);
266 #endif
267    }
268    res = a-b;
269    if (!VERIFY_SHORT(res))
270    {
271       fprintf (stderr, "SUB16: output is not short: %d in %s: line %d\n", res, file, line);
272 #ifdef FIXED_DEBUG_ASSERT
273       celt_assert(0);
274 #endif
275    }
276    celt_mips++;
277    return res;
278 }
279
280 #define ADD32(a, b) ADD32_(a, b, __FILE__, __LINE__)
281 static inline int ADD32_(long long a, long long b, char *file, int line)
282 {
283    long long res;
284    if (!VERIFY_INT(a) || !VERIFY_INT(b))
285    {
286       fprintf (stderr, "ADD32: inputs are not int: %d %d in %s: line %d\n", (int)a, (int)b, file, line);
287 #ifdef FIXED_DEBUG_ASSERT
288       celt_assert(0);
289 #endif
290    }
291    res = a+b;
292    if (!VERIFY_INT(res))
293    {
294       fprintf (stderr, "ADD32: output is not int: %d in %s: line %d\n", (int)res, file, line);
295 #ifdef FIXED_DEBUG_ASSERT
296       celt_assert(0);
297 #endif
298    }
299    celt_mips+=2;
300    return res;
301 }
302
303 #define SUB32(a, b) SUB32_(a, b, __FILE__, __LINE__)
304 static inline int SUB32_(long long a, long long b, char *file, int line)
305 {
306    long long res;
307    if (!VERIFY_INT(a) || !VERIFY_INT(b))
308    {
309       fprintf (stderr, "SUB32: inputs are not int: %d %d in %s: line %d\n", (int)a, (int)b, file, line);
310 #ifdef FIXED_DEBUG_ASSERT
311       celt_assert(0);
312 #endif
313    }
314    res = a-b;
315    if (!VERIFY_INT(res))
316    {
317       fprintf (stderr, "SUB32: output is not int: %d in %s: line %d\n", (int)res, file, line);
318 #ifdef FIXED_DEBUG_ASSERT
319       celt_assert(0);
320 #endif
321    }
322    celt_mips+=2;
323    return res;
324 }
325
326 #undef UADD32
327 #define UADD32(a, b) UADD32_(a, b, __FILE__, __LINE__)
328 static inline unsigned int UADD32_(unsigned long long a, unsigned long long b, char *file, int line)
329 {
330    unsigned long long res;
331    if (!VERIFY_UINT(a) || !VERIFY_UINT(b))
332    {
333       fprintf (stderr, "UADD32: inputs are not uint32: %llu %llu in %s: line %d\n", a, b, file, line);
334 #ifdef FIXED_DEBUG_ASSERT
335       celt_assert(0);
336 #endif
337    }
338    res = a+b;
339    if (!VERIFY_UINT(res))
340    {
341       fprintf (stderr, "UADD32: output is not uint32: %llu in %s: line %d\n", res, file, line);
342 #ifdef FIXED_DEBUG_ASSERT
343       celt_assert(0);
344 #endif
345    }
346    celt_mips+=2;
347    return res;
348 }
349
350 #undef USUB32
351 #define USUB32(a, b) USUB32_(a, b, __FILE__, __LINE__)
352 static inline unsigned int USUB32_(unsigned long long a, unsigned long long b, char *file, int line)
353 {
354    unsigned long long res;
355    if (!VERIFY_UINT(a) || !VERIFY_UINT(b))
356    {
357       fprintf (stderr, "USUB32: inputs are not uint32: %llu %llu in %s: line %d\n", a, b, file, line);
358 #ifdef FIXED_DEBUG_ASSERT
359       celt_assert(0);
360 #endif
361    }
362    if (a<b)
363    {
364       fprintf (stderr, "USUB32: inputs underflow: %llu < %llu in %s: line %d\n", a, b, file, line);
365 #ifdef FIXED_DEBUG_ASSERT
366       celt_assert(0);
367 #endif
368    }
369    res = a-b;
370    if (!VERIFY_UINT(res))
371    {
372       fprintf (stderr, "USUB32: output is not uint32: %llu - %llu = %llu in %s: line %d\n", a, b, res, file, line);
373 #ifdef FIXED_DEBUG_ASSERT
374       celt_assert(0);
375 #endif
376    }
377    celt_mips+=2;
378    return res;
379 }
380
381 /* result fits in 16 bits */
382 static inline short MULT16_16_16(int a, int b)
383 {
384    int res;
385    if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
386    {
387       fprintf (stderr, "MULT16_16_16: inputs are not short: %d %d\n", a, b);
388 #ifdef FIXED_DEBUG_ASSERT
389       celt_assert(0);
390 #endif
391    }
392    res = a*b;
393    if (!VERIFY_SHORT(res))
394    {
395       fprintf (stderr, "MULT16_16_16: output is not short: %d\n", res);
396 #ifdef FIXED_DEBUG_ASSERT
397       celt_assert(0);
398 #endif
399    }
400    celt_mips++;
401    return res;
402 }
403
404 #define MULT16_16(a, b) MULT16_16_(a, b, __FILE__, __LINE__)
405 static inline int MULT16_16_(int a, int b, char *file, int line)
406 {
407    long long res;
408    if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
409    {
410       fprintf (stderr, "MULT16_16: inputs are not short: %d %d in %s: line %d\n", a, b, file, line);
411 #ifdef FIXED_DEBUG_ASSERT
412       celt_assert(0);
413 #endif
414    }
415    res = ((long long)a)*b;
416    if (!VERIFY_INT(res))
417    {
418       fprintf (stderr, "MULT16_16: output is not int: %d in %s: line %d\n", (int)res, file, line);
419 #ifdef FIXED_DEBUG_ASSERT
420       celt_assert(0);
421 #endif
422    }
423    celt_mips++;
424    return res;
425 }
426
427 #define MAC16_16(c,a,b)     (celt_mips-=2,ADD32((c),MULT16_16((a),(b))))
428
429 #define MULT16_32_QX(a, b, Q) MULT16_32_QX_(a, b, Q, __FILE__, __LINE__)
430 static inline int MULT16_32_QX_(int a, long long b, int Q, char *file, int line)
431 {
432    long long res;
433    if (!VERIFY_SHORT(a) || !VERIFY_INT(b))
434    {
435       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);
436 #ifdef FIXED_DEBUG_ASSERT
437       celt_assert(0);
438 #endif
439    }
440    if (ABS32(b)>=((opus_val32)(1)<<(15+Q)))
441    {
442       fprintf (stderr, "MULT16_32_Q%d: second operand too large: %d %d in %s: line %d\n", Q, (int)a, (int)b, file, line);
443 #ifdef FIXED_DEBUG_ASSERT
444       celt_assert(0);
445 #endif
446    }
447    res = (((long long)a)*(long long)b) >> Q;
448    if (!VERIFY_INT(res))
449    {
450       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);
451 #ifdef FIXED_DEBUG_ASSERT
452       celt_assert(0);
453 #endif
454    }
455    if (Q==15)
456       celt_mips+=3;
457    else
458       celt_mips+=4;
459    return res;
460 }
461
462 #define MULT16_32_Q15(a,b) MULT16_32_QX(a,b,15)
463 #define MAC16_32_Q15(c,a,b) (celt_mips-=2,ADD32((c),MULT16_32_Q15((a),(b))))
464
465 static inline int SATURATE(int a, int b)
466 {
467    if (a>b)
468       a=b;
469    if (a<-b)
470       a = -b;
471    celt_mips+=3;
472    return a;
473 }
474
475 static inline int MULT16_16_Q11_32(int a, int b)
476 {
477    long long res;
478    if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
479    {
480       fprintf (stderr, "MULT16_16_Q11: inputs are not short: %d %d\n", a, b);
481 #ifdef FIXED_DEBUG_ASSERT
482       celt_assert(0);
483 #endif
484    }
485    res = ((long long)a)*b;
486    res >>= 11;
487    if (!VERIFY_INT(res))
488    {
489       fprintf (stderr, "MULT16_16_Q11: output is not short: %d*%d=%d\n", (int)a, (int)b, (int)res);
490 #ifdef FIXED_DEBUG_ASSERT
491       celt_assert(0);
492 #endif
493    }
494    celt_mips+=3;
495    return res;
496 }
497 static inline short MULT16_16_Q13(int a, int b)
498 {
499    long long res;
500    if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
501    {
502       fprintf (stderr, "MULT16_16_Q13: inputs are not short: %d %d\n", a, b);
503 #ifdef FIXED_DEBUG_ASSERT
504       celt_assert(0);
505 #endif
506    }
507    res = ((long long)a)*b;
508    res >>= 13;
509    if (!VERIFY_SHORT(res))
510    {
511       fprintf (stderr, "MULT16_16_Q13: output is not short: %d*%d=%d\n", a, b, (int)res);
512 #ifdef FIXED_DEBUG_ASSERT
513       celt_assert(0);
514 #endif
515    }
516    celt_mips+=3;
517    return res;
518 }
519 static inline short MULT16_16_Q14(int a, int b)
520 {
521    long long res;
522    if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
523    {
524       fprintf (stderr, "MULT16_16_Q14: inputs are not short: %d %d\n", a, b);
525 #ifdef FIXED_DEBUG_ASSERT
526       celt_assert(0);
527 #endif
528    }
529    res = ((long long)a)*b;
530    res >>= 14;
531    if (!VERIFY_SHORT(res))
532    {
533       fprintf (stderr, "MULT16_16_Q14: output is not short: %d\n", (int)res);
534 #ifdef FIXED_DEBUG_ASSERT
535       celt_assert(0);
536 #endif
537    }
538    celt_mips+=3;
539    return res;
540 }
541
542 #define MULT16_16_Q15(a, b) MULT16_16_Q15_(a, b, __FILE__, __LINE__)
543 static inline short MULT16_16_Q15_(int a, int b, char *file, int line)
544 {
545    long long res;
546    if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
547    {
548       fprintf (stderr, "MULT16_16_Q15: inputs are not short: %d %d in %s: line %d\n", a, b, file, line);
549 #ifdef FIXED_DEBUG_ASSERT
550       celt_assert(0);
551 #endif
552    }
553    res = ((long long)a)*b;
554    res >>= 15;
555    if (!VERIFY_SHORT(res))
556    {
557       fprintf (stderr, "MULT16_16_Q15: output is not short: %d in %s: line %d\n", (int)res, file, line);
558 #ifdef FIXED_DEBUG_ASSERT
559       celt_assert(0);
560 #endif
561    }
562    celt_mips+=1;
563    return res;
564 }
565
566 static inline short MULT16_16_P13(int a, int b)
567 {
568    long long res;
569    if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
570    {
571       fprintf (stderr, "MULT16_16_P13: inputs are not short: %d %d\n", a, b);
572 #ifdef FIXED_DEBUG_ASSERT
573       celt_assert(0);
574 #endif
575    }
576    res = ((long long)a)*b;
577    res += 4096;
578    if (!VERIFY_INT(res))
579    {
580       fprintf (stderr, "MULT16_16_P13: overflow: %d*%d=%d\n", a, b, (int)res);
581 #ifdef FIXED_DEBUG_ASSERT
582       celt_assert(0);
583 #endif
584    }
585    res >>= 13;
586    if (!VERIFY_SHORT(res))
587    {
588       fprintf (stderr, "MULT16_16_P13: output is not short: %d*%d=%d\n", a, b, (int)res);
589 #ifdef FIXED_DEBUG_ASSERT
590       celt_assert(0);
591 #endif
592    }
593    celt_mips+=4;
594    return res;
595 }
596 static inline short MULT16_16_P14(int a, int b)
597 {
598    long long res;
599    if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
600    {
601       fprintf (stderr, "MULT16_16_P14: inputs are not short: %d %d\n", a, b);
602 #ifdef FIXED_DEBUG_ASSERT
603       celt_assert(0);
604 #endif
605    }
606    res = ((long long)a)*b;
607    res += 8192;
608    if (!VERIFY_INT(res))
609    {
610       fprintf (stderr, "MULT16_16_P14: overflow: %d*%d=%d\n", a, b, (int)res);
611 #ifdef FIXED_DEBUG_ASSERT
612       celt_assert(0);
613 #endif
614    }
615    res >>= 14;
616    if (!VERIFY_SHORT(res))
617    {
618       fprintf (stderr, "MULT16_16_P14: output is not short: %d*%d=%d\n", a, b, (int)res);
619 #ifdef FIXED_DEBUG_ASSERT
620       celt_assert(0);
621 #endif
622    }
623    celt_mips+=4;
624    return res;
625 }
626 static inline short MULT16_16_P15(int a, int b)
627 {
628    long long res;
629    if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
630    {
631       fprintf (stderr, "MULT16_16_P15: inputs are not short: %d %d\n", a, b);
632 #ifdef FIXED_DEBUG_ASSERT
633       celt_assert(0);
634 #endif
635    }
636    res = ((long long)a)*b;
637    res += 16384;
638    if (!VERIFY_INT(res))
639    {
640       fprintf (stderr, "MULT16_16_P15: overflow: %d*%d=%d\n", a, b, (int)res);
641 #ifdef FIXED_DEBUG_ASSERT
642       celt_assert(0);
643 #endif
644    }
645    res >>= 15;
646    if (!VERIFY_SHORT(res))
647    {
648       fprintf (stderr, "MULT16_16_P15: output is not short: %d*%d=%d\n", a, b, (int)res);
649 #ifdef FIXED_DEBUG_ASSERT
650       celt_assert(0);
651 #endif
652    }
653    celt_mips+=2;
654    return res;
655 }
656
657 #define DIV32_16(a, b) DIV32_16_(a, b, __FILE__, __LINE__)
658
659 static inline int DIV32_16_(long long a, long long b, char *file, int line)
660 {
661    long long res;
662    if (b==0)
663    {
664       fprintf(stderr, "DIV32_16: divide by zero: %d/%d in %s: line %d\n", (int)a, (int)b, file, line);
665 #ifdef FIXED_DEBUG_ASSERT
666       celt_assert(0);
667 #endif
668       return 0;
669    }
670    if (!VERIFY_INT(a) || !VERIFY_SHORT(b))
671    {
672       fprintf (stderr, "DIV32_16: inputs are not int/short: %d %d in %s: line %d\n", (int)a, (int)b, file, line);
673 #ifdef FIXED_DEBUG_ASSERT
674       celt_assert(0);
675 #endif
676    }
677    res = a/b;
678    if (!VERIFY_SHORT(res))
679    {
680       fprintf (stderr, "DIV32_16: output is not short: %d / %d = %d in %s: line %d\n", (int)a,(int)b,(int)res, file, line);
681       if (res>32767)
682          res = 32767;
683       if (res<-32768)
684          res = -32768;
685 #ifdef FIXED_DEBUG_ASSERT
686       celt_assert(0);
687 #endif
688    }
689    celt_mips+=35;
690    return res;
691 }
692
693 #define DIV32(a, b) DIV32_(a, b, __FILE__, __LINE__)
694 static inline int DIV32_(long long a, long long b, char *file, int line)
695 {
696    long long res;
697    if (b==0)
698    {
699       fprintf(stderr, "DIV32: divide by zero: %d/%d in %s: line %d\n", (int)a, (int)b, file, line);
700 #ifdef FIXED_DEBUG_ASSERT
701       celt_assert(0);
702 #endif
703       return 0;
704    }
705
706    if (!VERIFY_INT(a) || !VERIFY_INT(b))
707    {
708       fprintf (stderr, "DIV32: inputs are not int/short: %d %d in %s: line %d\n", (int)a, (int)b, file, line);
709 #ifdef FIXED_DEBUG_ASSERT
710       celt_assert(0);
711 #endif
712    }
713    res = a/b;
714    if (!VERIFY_INT(res))
715    {
716       fprintf (stderr, "DIV32: output is not int: %d in %s: line %d\n", (int)res, file, line);
717 #ifdef FIXED_DEBUG_ASSERT
718       celt_assert(0);
719 #endif
720    }
721    celt_mips+=70;
722    return res;
723 }
724
725 #undef PRINT_MIPS
726 #define PRINT_MIPS(file) do {fprintf (file, "total complexity = %llu MIPS\n", celt_mips);} while (0);
727
728 #endif