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