Revert "Adds 3rd clause to CELT license"
[opus.git] / celt / fixed_debug.h
1 /* Copyright (C) 2003-2008 Jean-Marc Valin
2    Copyright (C) 2007-2009 Xiph.Org Foundation */
3 /**
4    @file fixed_debug.h
5    @brief Fixed-point operations with debugging
6 */
7 /*
8    Redistribution and use in source and binary forms, with or without
9    modification, are permitted provided that the following conditions
10    are met:
11
12    - Redistributions of source code must retain the above copyright
13    notice, this list of conditions and the following disclaimer.
14
15    - Redistributions in binary form must reproduce the above copyright
16    notice, this list of conditions and the following disclaimer in the
17    documentation and/or other materials provided with the distribution.
18
19    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20    ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22    A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
23    OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24    EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25    PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26    PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27    LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28    NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31
32 #ifndef FIXED_DEBUG_H
33 #define FIXED_DEBUG_H
34
35 #include <stdio.h>
36
37 #ifdef CELT_C
38 long long celt_mips=0;
39 #else
40 extern long long celt_mips;
41 #endif
42
43 #define MULT16_16SU(a,b) ((opus_val32)(opus_val16)(a)*(opus_val32)(opus_uint16)(b))
44 #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))
45
46 /** 16x32 multiplication, followed by a 16-bit shift right. Results fits in 32 bits */
47 #define MULT16_32_Q16(a,b) ADD32(MULT16_16((a),SHR32((b),16)), SHR32(MULT16_16SU((a),((b)&0x0000ffff)),16))
48
49 #define QCONST16(x,bits) ((opus_val16)(.5+(x)*(((opus_val32)1)<<(bits))))
50 #define QCONST32(x,bits) ((opus_val32)(.5+(x)*(((opus_val32)1)<<(bits))))
51
52 #define VERIFY_SHORT(x) ((x)<=32767&&(x)>=-32768)
53 #define VERIFY_INT(x) ((x)<=2147483647LL&&(x)>=-2147483648LL)
54 #define VERIFY_UINT(x) ((x)<=(2147483647LLU<<1))
55
56 #define SHR(a,b) SHR32(a,b)
57 #define PSHR(a,b) PSHR32(a,b)
58
59 static inline short NEG16(int x)
60 {
61    int res;
62    if (!VERIFY_SHORT(x))
63    {
64       fprintf (stderr, "NEG16: input is not short: %d\n", (int)x);
65    }
66    res = -x;
67    if (!VERIFY_SHORT(res))
68       fprintf (stderr, "NEG16: output is not short: %d\n", (int)res);
69    celt_mips++;
70    return res;
71 }
72 static inline int NEG32(long long x)
73 {
74    long long res;
75    if (!VERIFY_INT(x))
76    {
77       fprintf (stderr, "NEG16: input is not int: %d\n", (int)x);
78    }
79    res = -x;
80    if (!VERIFY_INT(res))
81       fprintf (stderr, "NEG16: output is not int: %d\n", (int)res);
82    celt_mips+=2;
83    return res;
84 }
85
86 #define EXTRACT16(x) EXTRACT16_(x, __FILE__, __LINE__)
87 static inline short EXTRACT16_(int x, char *file, int line)
88 {
89    int res;
90    if (!VERIFY_SHORT(x))
91    {
92       fprintf (stderr, "EXTRACT16: input is not short: %d in %s: line %d\n", x, file, line);
93    }
94    res = x;
95    celt_mips++;
96    return res;
97 }
98
99 #define EXTEND32(x) EXTEND32_(x, __FILE__, __LINE__)
100 static inline int EXTEND32_(int x, char *file, int line)
101 {
102    int res;
103    if (!VERIFY_SHORT(x))
104    {
105       fprintf (stderr, "EXTEND32: input is not short: %d in %s: line %d\n", x, file, line);
106    }
107    res = x;
108    celt_mips++;
109    return res;
110 }
111
112 #define SHR16(a, shift) SHR16_(a, shift, __FILE__, __LINE__)
113 static inline short SHR16_(int a, int shift, char *file, int line)
114 {
115    int res;
116    if (!VERIFY_SHORT(a) || !VERIFY_SHORT(shift))
117    {
118       fprintf (stderr, "SHR16: inputs are not short: %d >> %d in %s: line %d\n", a, shift, file, line);
119    }
120    res = a>>shift;
121    if (!VERIFY_SHORT(res))
122       fprintf (stderr, "SHR16: output is not short: %d in %s: line %d\n", res, file, line);
123    celt_mips++;
124    return res;
125 }
126 #define SHL16(a, shift) SHL16_(a, shift, __FILE__, __LINE__)
127 static inline short SHL16_(int a, int shift, char *file, int line)
128 {
129    int res;
130    if (!VERIFY_SHORT(a) || !VERIFY_SHORT(shift))
131    {
132       fprintf (stderr, "SHL16: inputs are not short: %d %d in %s: line %d\n", a, shift, file, line);
133    }
134    res = a<<shift;
135    if (!VERIFY_SHORT(res))
136       fprintf (stderr, "SHL16: output is not short: %d in %s: line %d\n", res, file, line);
137    celt_mips++;
138    return res;
139 }
140
141 static inline int SHR32(long long a, int shift)
142 {
143    long long  res;
144    if (!VERIFY_INT(a) || !VERIFY_SHORT(shift))
145    {
146       fprintf (stderr, "SHR32: inputs are not int: %d %d\n", (int)a, shift);
147    }
148    res = a>>shift;
149    if (!VERIFY_INT(res))
150    {
151       fprintf (stderr, "SHR32: output is not int: %d\n", (int)res);
152    }
153    celt_mips+=2;
154    return res;
155 }
156 static inline int SHL32(long long a, int shift)
157 {
158    long long  res;
159    if (!VERIFY_INT(a) || !VERIFY_SHORT(shift))
160    {
161       fprintf (stderr, "SHL32: inputs are not int: %d %d\n", (int)a, shift);
162    }
163    res = a<<shift;
164    if (!VERIFY_INT(res))
165    {
166       fprintf (stderr, "SHL32: output is not int: %d\n", (int)res);
167    }
168    celt_mips+=2;
169    return res;
170 }
171
172 #define PSHR32(a,shift) (celt_mips--,SHR32(ADD32((a),(((opus_val32)(1)<<((shift))>>1))),shift))
173 #define VSHR32(a, shift) (((shift)>0) ? SHR32(a, shift) : SHL32(a, -(shift)))
174
175 #define ROUND16(x,a) (celt_mips--,EXTRACT16(PSHR32((x),(a))))
176 #define HALF16(x)  (SHR16(x,1))
177 #define HALF32(x)  (SHR32(x,1))
178
179 //#define SHR(a,shift) ((a) >> (shift))
180 //#define SHL(a,shift) ((a) << (shift))
181
182 #define ADD16(a, b) ADD16_(a, b, __FILE__, __LINE__)
183 static inline short ADD16_(int a, int b, char *file, int line)
184 {
185    int res;
186    if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
187    {
188       fprintf (stderr, "ADD16: inputs are not short: %d %d in %s: line %d\n", a, b, file, line);
189    }
190    res = a+b;
191    if (!VERIFY_SHORT(res))
192    {
193       fprintf (stderr, "ADD16: output is not short: %d+%d=%d in %s: line %d\n", a,b,res, file, line);
194    }
195    celt_mips++;
196    return res;
197 }
198
199 #define SUB16(a, b) SUB16_(a, b, __FILE__, __LINE__)
200 static inline short SUB16_(int a, int b, char *file, int line)
201 {
202    int res;
203    if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
204    {
205       fprintf (stderr, "SUB16: inputs are not short: %d %d in %s: line %d\n", a, b, file, line);
206    }
207    res = a-b;
208    if (!VERIFY_SHORT(res))
209       fprintf (stderr, "SUB16: output is not short: %d in %s: line %d\n", res, file, line);
210    celt_mips++;
211    return res;
212 }
213
214 #define ADD32(a, b) ADD32_(a, b, __FILE__, __LINE__)
215 static inline int ADD32_(long long a, long long b, char *file, int line)
216 {
217    long long res;
218    if (!VERIFY_INT(a) || !VERIFY_INT(b))
219    {
220       fprintf (stderr, "ADD32: inputs are not int: %d %d in %s: line %d\n", (int)a, (int)b, file, line);
221    }
222    res = a+b;
223    if (!VERIFY_INT(res))
224    {
225       fprintf (stderr, "ADD32: output is not int: %d in %s: line %d\n", (int)res, file, line);
226    }
227    celt_mips+=2;
228    return res;
229 }
230
231 #define SUB32(a, b) SUB32_(a, b, __FILE__, __LINE__)
232 static inline int SUB32_(long long a, long long b, char *file, int line)
233 {
234    long long res;
235    if (!VERIFY_INT(a) || !VERIFY_INT(b))
236    {
237       fprintf (stderr, "SUB32: inputs are not int: %d %d in %s: line %d\n", (int)a, (int)b, file, line);
238    }
239    res = a-b;
240    if (!VERIFY_INT(res))
241       fprintf (stderr, "SUB32: output is not int: %d in %s: line %d\n", (int)res, file, line);
242    celt_mips+=2;
243    return res;
244 }
245
246 #undef UADD32
247 #define UADD32(a, b) UADD32_(a, b, __FILE__, __LINE__)
248 static inline unsigned int UADD32_(unsigned long long a, unsigned long long b, char *file, int line)
249 {
250    long long res;
251    if (!VERIFY_UINT(a) || !VERIFY_UINT(b))
252    {
253       fprintf (stderr, "UADD32: inputs are not int: %u %u in %s: line %d\n", (unsigned)a, (unsigned)b, file, line);
254    }
255    res = a+b;
256    if (!VERIFY_UINT(res))
257    {
258       fprintf (stderr, "UADD32: output is not int: %u in %s: line %d\n", (unsigned)res, file, line);
259    }
260    celt_mips+=2;
261    return res;
262 }
263
264 #undef USUB32
265 #define USUB32(a, b) USUB32_(a, b, __FILE__, __LINE__)
266 static inline unsigned int USUB32_(unsigned long long a, unsigned long long b, char *file, int line)
267 {
268    long long res;
269    if (!VERIFY_UINT(a) || !VERIFY_UINT(b))
270    {
271       /*fprintf (stderr, "USUB32: inputs are not int: %llu %llu in %s: line %d\n", (unsigned)a, (unsigned)b, file, line);*/
272    }
273    res = a-b;
274    if (!VERIFY_UINT(res))
275    {
276       /*fprintf (stderr, "USUB32: output is not int: %llu - %llu = %llu in %s: line %d\n", a, b, res, file, line);*/
277    }
278    celt_mips+=2;
279    return res;
280 }
281
282 /* result fits in 16 bits */
283 static inline short MULT16_16_16(int a, int b)
284 {
285    int res;
286    if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
287    {
288       fprintf (stderr, "MULT16_16_16: inputs are not short: %d %d\n", a, b);
289    }
290    res = a*b;
291    if (!VERIFY_SHORT(res))
292       fprintf (stderr, "MULT16_16_16: output is not short: %d\n", res);
293    celt_mips++;
294    return res;
295 }
296
297 #define MULT16_16(a, b) MULT16_16_(a, b, __FILE__, __LINE__)
298 static inline int MULT16_16_(int a, int b, char *file, int line)
299 {
300    long long res;
301    if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
302    {
303       fprintf (stderr, "MULT16_16: inputs are not short: %d %d in %s: line %d\n", a, b, file, line);
304    }
305    res = ((long long)a)*b;
306    if (!VERIFY_INT(res))
307       fprintf (stderr, "MULT16_16: output is not int: %d in %s: line %d\n", (int)res, file, line);
308    celt_mips++;
309    return res;
310 }
311
312 #define MAC16_16(c,a,b)     (celt_mips-=2,ADD32((c),MULT16_16((a),(b))))
313
314 #define MULT16_32_QX(a, b, Q) MULT16_32_QX_(a, b, Q, __FILE__, __LINE__)
315 static inline int MULT16_32_QX_(int a, long long b, int Q, char *file, int line)
316 {
317    long long res;
318    if (!VERIFY_SHORT(a) || !VERIFY_INT(b))
319    {
320       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);
321    }
322    if (ABS32(b)>=((opus_val32)(1)<<(15+Q)))
323       fprintf (stderr, "MULT16_32_Q%d: second operand too large: %d %d in %s: line %d\n", Q, (int)a, (int)b, file, line);
324    res = (((long long)a)*(long long)b) >> Q;
325    if (!VERIFY_INT(res))
326       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);
327    if (Q==15)
328       celt_mips+=3;
329    else
330       celt_mips+=4;
331    return res;
332 }
333
334 #define MULT16_32_Q15(a,b) MULT16_32_QX(a,b,15)
335 #define MAC16_32_Q15(c,a,b) (celt_mips-=2,ADD32((c),MULT16_32_Q15((a),(b))))
336
337 static inline int SATURATE(int a, int b)
338 {
339    if (a>b)
340       a=b;
341    if (a<-b)
342       a = -b;
343    celt_mips+=3;
344    return a;
345 }
346
347 static inline int MULT16_16_Q11_32(int a, int b)
348 {
349    long long res;
350    if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
351    {
352       fprintf (stderr, "MULT16_16_Q11: inputs are not short: %d %d\n", a, b);
353    }
354    res = ((long long)a)*b;
355    res >>= 11;
356    if (!VERIFY_INT(res))
357       fprintf (stderr, "MULT16_16_Q11: output is not short: %d*%d=%d\n", (int)a, (int)b, (int)res);
358    celt_mips+=3;
359    return res;
360 }
361 static inline short MULT16_16_Q13(int a, int b)
362 {
363    long long res;
364    if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
365    {
366       fprintf (stderr, "MULT16_16_Q13: inputs are not short: %d %d\n", a, b);
367    }
368    res = ((long long)a)*b;
369    res >>= 13;
370    if (!VERIFY_SHORT(res))
371       fprintf (stderr, "MULT16_16_Q13: output is not short: %d*%d=%d\n", a, b, (int)res);
372    celt_mips+=3;
373    return res;
374 }
375 static inline short MULT16_16_Q14(int a, int b)
376 {
377    long long res;
378    if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
379    {
380       fprintf (stderr, "MULT16_16_Q14: inputs are not short: %d %d\n", a, b);
381    }
382    res = ((long long)a)*b;
383    res >>= 14;
384    if (!VERIFY_SHORT(res))
385       fprintf (stderr, "MULT16_16_Q14: output is not short: %d\n", (int)res);
386    celt_mips+=3;
387    return res;
388 }
389
390 #define MULT16_16_Q15(a, b) MULT16_16_Q15_(a, b, __FILE__, __LINE__)
391 static inline short MULT16_16_Q15_(int a, int b, char *file, int line)
392 {
393    long long res;
394    if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
395    {
396       fprintf (stderr, "MULT16_16_Q15: inputs are not short: %d %d in %s: line %d\n", a, b, file, line);
397    }
398    res = ((long long)a)*b;
399    res >>= 15;
400    if (!VERIFY_SHORT(res))
401    {
402       fprintf (stderr, "MULT16_16_Q15: output is not short: %d in %s: line %d\n", (int)res, file, line);
403    }
404    celt_mips+=1;
405    return res;
406 }
407
408 static inline short MULT16_16_P13(int a, int b)
409 {
410    long long res;
411    if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
412    {
413       fprintf (stderr, "MULT16_16_P13: inputs are not short: %d %d\n", a, b);
414    }
415    res = ((long long)a)*b;
416    res += 4096;
417    if (!VERIFY_INT(res))
418       fprintf (stderr, "MULT16_16_P13: overflow: %d*%d=%d\n", a, b, (int)res);
419    res >>= 13;
420    if (!VERIFY_SHORT(res))
421       fprintf (stderr, "MULT16_16_P13: output is not short: %d*%d=%d\n", a, b, (int)res);
422    celt_mips+=4;
423    return res;
424 }
425 static inline short MULT16_16_P14(int a, int b)
426 {
427    long long res;
428    if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
429    {
430       fprintf (stderr, "MULT16_16_P14: inputs are not short: %d %d\n", a, b);
431    }
432    res = ((long long)a)*b;
433    res += 8192;
434    if (!VERIFY_INT(res))
435       fprintf (stderr, "MULT16_16_P14: overflow: %d*%d=%d\n", a, b, (int)res);
436    res >>= 14;
437    if (!VERIFY_SHORT(res))
438       fprintf (stderr, "MULT16_16_P14: output is not short: %d*%d=%d\n", a, b, (int)res);
439    celt_mips+=4;
440    return res;
441 }
442 static inline short MULT16_16_P15(int a, int b)
443 {
444    long long res;
445    if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
446    {
447       fprintf (stderr, "MULT16_16_P15: inputs are not short: %d %d\n", a, b);
448    }
449    res = ((long long)a)*b;
450    res += 16384;
451    if (!VERIFY_INT(res))
452       fprintf (stderr, "MULT16_16_P15: overflow: %d*%d=%d\n", a, b, (int)res);
453    res >>= 15;
454    if (!VERIFY_SHORT(res))
455       fprintf (stderr, "MULT16_16_P15: output is not short: %d*%d=%d\n", a, b, (int)res);
456    celt_mips+=2;
457    return res;
458 }
459
460 #define DIV32_16(a, b) DIV32_16_(a, b, __FILE__, __LINE__)
461
462 static inline int DIV32_16_(long long a, long long b, char *file, int line)
463 {
464    long long res;
465    if (b==0)
466    {
467       fprintf(stderr, "DIV32_16: divide by zero: %d/%d in %s: line %d\n", (int)a, (int)b, file, line);
468       return 0;
469    }
470    if (!VERIFY_INT(a) || !VERIFY_SHORT(b))
471    {
472       fprintf (stderr, "DIV32_16: inputs are not int/short: %d %d in %s: line %d\n", (int)a, (int)b, file, line);
473    }
474    res = a/b;
475    if (!VERIFY_SHORT(res))
476    {
477       fprintf (stderr, "DIV32_16: output is not short: %d / %d = %d in %s: line %d\n", (int)a,(int)b,(int)res, file, line);
478       if (res>32767)
479          res = 32767;
480       if (res<-32768)
481          res = -32768;
482    }
483    celt_mips+=35;
484    return res;
485 }
486
487 #define DIV32(a, b) DIV32_(a, b, __FILE__, __LINE__)
488 static inline int DIV32_(long long a, long long b, char *file, int line)
489 {
490    long long res;
491    if (b==0)
492    {
493       fprintf(stderr, "DIV32: divide by zero: %d/%d in %s: line %d\n", (int)a, (int)b, file, line);
494       return 0;
495    }
496
497    if (!VERIFY_INT(a) || !VERIFY_INT(b))
498    {
499       fprintf (stderr, "DIV32: inputs are not int/short: %d %d in %s: line %d\n", (int)a, (int)b, file, line);
500    }
501    res = a/b;
502    if (!VERIFY_INT(res))
503       fprintf (stderr, "DIV32: output is not int: %d in %s: line %d\n", (int)res, file, line);
504    celt_mips+=70;
505    return res;
506 }
507
508 #undef PRINT_MIPS
509 #define PRINT_MIPS(file) do {fprintf (file, "total complexity = %llu MIPS\n", celt_mips);} while (0);
510
511 #endif