• 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    opus_int32 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 = (opus_int32)((opus_uint32)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", (long long)a, shift, file, line);
218 #ifdef FIXED_DEBUG_ASSERT
219       celt_assert(0);
220 #endif
221    }
222    res = (opus_int64)((opus_uint64)a<<shift);
223    if (!VERIFY_INT(res))
224    {
225       fprintf (stderr, "SHL32: output is not int: %lld<<%d = %lld in %s: line %d\n", (long long)a, shift, (long long)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", (unsigned long long)a, (unsigned long long)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", (unsigned long long)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", (unsigned long long)a, (unsigned long long)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", (unsigned long long)a, (unsigned long long)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", (unsigned long long)a, (unsigned long long)b, (unsigned long long)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 /* result fits in 32 bits */
MULT32_32_32(opus_int64 a,opus_int64 b)414 static OPUS_INLINE int MULT32_32_32(opus_int64 a, opus_int64 b)
415 {
416    opus_int64 res;
417    if (!VERIFY_INT(a) || !VERIFY_INT(b))
418    {
419       fprintf (stderr, "MULT32_32_32: inputs are not int: %lld %lld\n", (long long)a, (long long)b);
420 #ifdef FIXED_DEBUG_ASSERT
421       celt_assert(0);
422 #endif
423    }
424    res = a*b;
425    if (!VERIFY_INT(res))
426    {
427       fprintf (stderr, "MULT32_32_32: output is not int: %lld\n", (long long)res);
428 #ifdef FIXED_DEBUG_ASSERT
429       celt_assert(0);
430 #endif
431    }
432    celt_mips+=5;
433    return res;
434 }
435 
MULT32_32_Q16(opus_int64 a,opus_int64 b)436 static OPUS_INLINE int MULT32_32_Q16(opus_int64 a, opus_int64 b)
437 {
438    opus_int64 res;
439    if (!VERIFY_INT(a) || !VERIFY_INT(b))
440    {
441       fprintf (stderr, "MULT32_32_Q16: inputs are not int: %lld %lld\n", (long long)a, (long long)b);
442 #ifdef FIXED_DEBUG_ASSERT
443       celt_assert(0);
444 #endif
445    }
446    res = ((opus_int64)(a)*(opus_int64)(b)) >> 16;
447    if (!VERIFY_INT(res))
448    {
449       fprintf (stderr, "MULT32_32_Q16: output is not int: %lld*%lld=%lld\n", (long long)a, (long long)b, (long long)res);
450 #ifdef FIXED_DEBUG_ASSERT
451       celt_assert(0);
452 #endif
453    }
454    celt_mips+=5;
455    return res;
456 }
457 
458 #define MULT16_16(a, b) MULT16_16_(a, b, __FILE__, __LINE__)
MULT16_16_(int a,int b,char * file,int line)459 static OPUS_INLINE int MULT16_16_(int a, int b, char *file, int line)
460 {
461    opus_int64 res;
462    if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
463    {
464       fprintf (stderr, "MULT16_16: inputs are not short: %d %d in %s: line %d\n", a, b, file, line);
465 #ifdef FIXED_DEBUG_ASSERT
466       celt_assert(0);
467 #endif
468    }
469    res = ((opus_int64)a)*b;
470    if (!VERIFY_INT(res))
471    {
472       fprintf (stderr, "MULT16_16: output is not int: %d in %s: line %d\n", (int)res, file, line);
473 #ifdef FIXED_DEBUG_ASSERT
474       celt_assert(0);
475 #endif
476    }
477    celt_mips++;
478    return res;
479 }
480 
481 #define MAC16_16(c,a,b)     (celt_mips-=2,ADD32((c),MULT16_16((a),(b))))
482 
483 #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)484 static OPUS_INLINE int MULT16_32_QX_(int a, opus_int64 b, int Q, char *file, int line)
485 {
486    opus_int64 res;
487    if (!VERIFY_SHORT(a) || !VERIFY_INT(b))
488    {
489       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);
490 #ifdef FIXED_DEBUG_ASSERT
491       celt_assert(0);
492 #endif
493    }
494    if (ABS32(b)>=((opus_int64)(1)<<(16+Q)))
495    {
496       fprintf (stderr, "MULT16_32_Q%d: second operand too large: %d %d in %s: line %d\n", Q, (int)a, (int)b, file, line);
497 #ifdef FIXED_DEBUG_ASSERT
498       celt_assert(0);
499 #endif
500    }
501    res = (((opus_int64)a)*(opus_int64)b) >> Q;
502    if (!VERIFY_INT(res))
503    {
504       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);
505 #ifdef FIXED_DEBUG_ASSERT
506       celt_assert(0);
507 #endif
508    }
509    if (Q==15)
510       celt_mips+=3;
511    else
512       celt_mips+=4;
513    return res;
514 }
515 
516 #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)517 static OPUS_INLINE int MULT16_32_PX_(int a, opus_int64 b, int Q, char *file, int line)
518 {
519    opus_int64 res;
520    if (!VERIFY_SHORT(a) || !VERIFY_INT(b))
521    {
522       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);
523 #ifdef FIXED_DEBUG_ASSERT
524       celt_assert(0);
525 #endif
526    }
527    if (ABS32(b)>=((opus_int64)(1)<<(16+Q)))
528    {
529       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);
530 #ifdef FIXED_DEBUG_ASSERT
531       celt_assert(0);
532 #endif
533    }
534    res = ((((opus_int64)a)*(opus_int64)b) + (((opus_val32)(1)<<Q)>>1))>> Q;
535    if (!VERIFY_INT(res))
536    {
537       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);
538 #ifdef FIXED_DEBUG_ASSERT
539       celt_assert(0);
540 #endif
541    }
542    if (Q==15)
543       celt_mips+=4;
544    else
545       celt_mips+=5;
546    return res;
547 }
548 
549 #define MULT16_32_Q15(a,b) MULT16_32_QX(a,b,15)
550 #define MAC16_32_Q15(c,a,b) (celt_mips-=2,ADD32((c),MULT16_32_Q15((a),(b))))
551 #define MAC16_32_Q16(c,a,b) (celt_mips-=2,ADD32((c),MULT16_32_Q16((a),(b))))
552 
SATURATE(int a,int b)553 static OPUS_INLINE int SATURATE(int a, int b)
554 {
555    if (a>b)
556       a=b;
557    if (a<-b)
558       a = -b;
559    celt_mips+=3;
560    return a;
561 }
562 
SATURATE16(opus_int32 a)563 static OPUS_INLINE opus_int16 SATURATE16(opus_int32 a)
564 {
565    celt_mips+=3;
566    if (a>32767)
567       return 32767;
568    else if (a<-32768)
569       return -32768;
570    else return a;
571 }
572 
MULT16_16_Q11_32(int a,int b)573 static OPUS_INLINE int MULT16_16_Q11_32(int a, int b)
574 {
575    opus_int64 res;
576    if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
577    {
578       fprintf (stderr, "MULT16_16_Q11: inputs are not short: %d %d\n", a, b);
579 #ifdef FIXED_DEBUG_ASSERT
580       celt_assert(0);
581 #endif
582    }
583    res = ((opus_int64)a)*b;
584    res >>= 11;
585    if (!VERIFY_INT(res))
586    {
587       fprintf (stderr, "MULT16_16_Q11: output is not short: %d*%d=%d\n", (int)a, (int)b, (int)res);
588 #ifdef FIXED_DEBUG_ASSERT
589       celt_assert(0);
590 #endif
591    }
592    celt_mips+=3;
593    return res;
594 }
MULT16_16_Q13(int a,int b)595 static OPUS_INLINE short MULT16_16_Q13(int a, int b)
596 {
597    opus_int64 res;
598    if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
599    {
600       fprintf (stderr, "MULT16_16_Q13: inputs are not short: %d %d\n", a, b);
601 #ifdef FIXED_DEBUG_ASSERT
602       celt_assert(0);
603 #endif
604    }
605    res = ((opus_int64)a)*b;
606    res >>= 13;
607    if (!VERIFY_SHORT(res))
608    {
609       fprintf (stderr, "MULT16_16_Q13: output is not short: %d*%d=%d\n", a, b, (int)res);
610 #ifdef FIXED_DEBUG_ASSERT
611       celt_assert(0);
612 #endif
613    }
614    celt_mips+=3;
615    return res;
616 }
MULT16_16_Q14(int a,int b)617 static OPUS_INLINE short MULT16_16_Q14(int a, int b)
618 {
619    opus_int64 res;
620    if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
621    {
622       fprintf (stderr, "MULT16_16_Q14: inputs are not short: %d %d\n", a, b);
623 #ifdef FIXED_DEBUG_ASSERT
624       celt_assert(0);
625 #endif
626    }
627    res = ((opus_int64)a)*b;
628    res >>= 14;
629    if (!VERIFY_SHORT(res))
630    {
631       fprintf (stderr, "MULT16_16_Q14: output is not short: %d\n", (int)res);
632 #ifdef FIXED_DEBUG_ASSERT
633       celt_assert(0);
634 #endif
635    }
636    celt_mips+=3;
637    return res;
638 }
639 
640 #define MULT16_16_Q15(a, b) MULT16_16_Q15_(a, b, __FILE__, __LINE__)
MULT16_16_Q15_(int a,int b,char * file,int line)641 static OPUS_INLINE short MULT16_16_Q15_(int a, int b, char *file, int line)
642 {
643    opus_int64 res;
644    if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
645    {
646       fprintf (stderr, "MULT16_16_Q15: inputs are not short: %d %d in %s: line %d\n", a, b, file, line);
647 #ifdef FIXED_DEBUG_ASSERT
648       celt_assert(0);
649 #endif
650    }
651    res = ((opus_int64)a)*b;
652    res >>= 15;
653    if (!VERIFY_SHORT(res))
654    {
655       fprintf (stderr, "MULT16_16_Q15: output is not short: %d in %s: line %d\n", (int)res, file, line);
656 #ifdef FIXED_DEBUG_ASSERT
657       celt_assert(0);
658 #endif
659    }
660    celt_mips+=1;
661    return res;
662 }
663 
MULT16_16_P13(int a,int b)664 static OPUS_INLINE short MULT16_16_P13(int a, int b)
665 {
666    opus_int64 res;
667    if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
668    {
669       fprintf (stderr, "MULT16_16_P13: inputs are not short: %d %d\n", a, b);
670 #ifdef FIXED_DEBUG_ASSERT
671       celt_assert(0);
672 #endif
673    }
674    res = ((opus_int64)a)*b;
675    res += 4096;
676    if (!VERIFY_INT(res))
677    {
678       fprintf (stderr, "MULT16_16_P13: overflow: %d*%d=%d\n", a, b, (int)res);
679 #ifdef FIXED_DEBUG_ASSERT
680       celt_assert(0);
681 #endif
682    }
683    res >>= 13;
684    if (!VERIFY_SHORT(res))
685    {
686       fprintf (stderr, "MULT16_16_P13: output is not short: %d*%d=%d\n", a, b, (int)res);
687 #ifdef FIXED_DEBUG_ASSERT
688       celt_assert(0);
689 #endif
690    }
691    celt_mips+=4;
692    return res;
693 }
MULT16_16_P14(int a,int b)694 static OPUS_INLINE short MULT16_16_P14(int a, int b)
695 {
696    opus_int64 res;
697    if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
698    {
699       fprintf (stderr, "MULT16_16_P14: inputs are not short: %d %d\n", a, b);
700 #ifdef FIXED_DEBUG_ASSERT
701       celt_assert(0);
702 #endif
703    }
704    res = ((opus_int64)a)*b;
705    res += 8192;
706    if (!VERIFY_INT(res))
707    {
708       fprintf (stderr, "MULT16_16_P14: overflow: %d*%d=%d\n", a, b, (int)res);
709 #ifdef FIXED_DEBUG_ASSERT
710       celt_assert(0);
711 #endif
712    }
713    res >>= 14;
714    if (!VERIFY_SHORT(res))
715    {
716       fprintf (stderr, "MULT16_16_P14: output is not short: %d*%d=%d\n", a, b, (int)res);
717 #ifdef FIXED_DEBUG_ASSERT
718       celt_assert(0);
719 #endif
720    }
721    celt_mips+=4;
722    return res;
723 }
MULT16_16_P15(int a,int b)724 static OPUS_INLINE short MULT16_16_P15(int a, int b)
725 {
726    opus_int64 res;
727    if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
728    {
729       fprintf (stderr, "MULT16_16_P15: inputs are not short: %d %d\n", a, b);
730 #ifdef FIXED_DEBUG_ASSERT
731       celt_assert(0);
732 #endif
733    }
734    res = ((opus_int64)a)*b;
735    res += 16384;
736    if (!VERIFY_INT(res))
737    {
738       fprintf (stderr, "MULT16_16_P15: overflow: %d*%d=%d\n", a, b, (int)res);
739 #ifdef FIXED_DEBUG_ASSERT
740       celt_assert(0);
741 #endif
742    }
743    res >>= 15;
744    if (!VERIFY_SHORT(res))
745    {
746       fprintf (stderr, "MULT16_16_P15: output is not short: %d*%d=%d\n", a, b, (int)res);
747 #ifdef FIXED_DEBUG_ASSERT
748       celt_assert(0);
749 #endif
750    }
751    celt_mips+=2;
752    return res;
753 }
754 
755 #define DIV32_16(a, b) DIV32_16_(a, b, __FILE__, __LINE__)
756 
DIV32_16_(opus_int64 a,opus_int64 b,char * file,int line)757 static OPUS_INLINE int DIV32_16_(opus_int64 a, opus_int64 b, char *file, int line)
758 {
759    opus_int64 res;
760    if (b==0)
761    {
762       fprintf(stderr, "DIV32_16: divide by zero: %d/%d in %s: line %d\n", (int)a, (int)b, file, line);
763 #ifdef FIXED_DEBUG_ASSERT
764       celt_assert(0);
765 #endif
766       return 0;
767    }
768    if (!VERIFY_INT(a) || !VERIFY_SHORT(b))
769    {
770       fprintf (stderr, "DIV32_16: inputs are not int/short: %d %d in %s: line %d\n", (int)a, (int)b, file, line);
771 #ifdef FIXED_DEBUG_ASSERT
772       celt_assert(0);
773 #endif
774    }
775    res = a/b;
776    if (!VERIFY_SHORT(res))
777    {
778       fprintf (stderr, "DIV32_16: output is not short: %d / %d = %d in %s: line %d\n", (int)a,(int)b,(int)res, file, line);
779       if (res>32767)
780          res = 32767;
781       if (res<-32768)
782          res = -32768;
783 #ifdef FIXED_DEBUG_ASSERT
784       celt_assert(0);
785 #endif
786    }
787    celt_mips+=35;
788    return res;
789 }
790 
791 #define DIV32(a, b) DIV32_(a, b, __FILE__, __LINE__)
DIV32_(opus_int64 a,opus_int64 b,char * file,int line)792 static OPUS_INLINE int DIV32_(opus_int64 a, opus_int64 b, char *file, int line)
793 {
794    opus_int64 res;
795    if (b==0)
796    {
797       fprintf(stderr, "DIV32: divide by zero: %d/%d in %s: line %d\n", (int)a, (int)b, file, line);
798 #ifdef FIXED_DEBUG_ASSERT
799       celt_assert(0);
800 #endif
801       return 0;
802    }
803 
804    if (!VERIFY_INT(a) || !VERIFY_INT(b))
805    {
806       fprintf (stderr, "DIV32: inputs are not int/short: %d %d in %s: line %d\n", (int)a, (int)b, file, line);
807 #ifdef FIXED_DEBUG_ASSERT
808       celt_assert(0);
809 #endif
810    }
811    res = a/b;
812    if (!VERIFY_INT(res))
813    {
814       fprintf (stderr, "DIV32: output is not int: %d in %s: line %d\n", (int)res, file, line);
815 #ifdef FIXED_DEBUG_ASSERT
816       celt_assert(0);
817 #endif
818    }
819    celt_mips+=70;
820    return res;
821 }
822 
SIG2WORD16_generic(celt_sig x)823 static OPUS_INLINE opus_val16 SIG2WORD16_generic(celt_sig x)
824 {
825    x = PSHR32(x, SIG_SHIFT);
826    x = MAX32(x, -32768);
827    x = MIN32(x, 32767);
828    return EXTRACT16(x);
829 }
830 #define SIG2WORD16(x) (SIG2WORD16_generic(x))
831 
832 
833 #undef PRINT_MIPS
834 #define PRINT_MIPS(file) do {fprintf (file, "total complexity = %llu MIPS\n", (unsigned long long)celt_mips);} while (0);
835 
836 #endif
837