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