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