1 /* Copyright (C) 2003-2008 Jean-Marc Valin */
4 @brief Fixed-point operations with debugging
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions
11 - Redistributions of source code must retain the above copyright
12 notice, this list of conditions and the following disclaimer.
14 - Redistributions in binary form must reproduce the above copyright
15 notice, this list of conditions and the following disclaimer in the
16 documentation and/or other materials provided with the distribution.
18 - Neither the name of the Xiph.org Foundation nor the names of its
19 contributors may be used to endorse or promote products derived from
20 this software without specific prior written permission.
22 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
26 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
27 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40 //extern long long celt_mips;
41 static long long celt_mips = 0;
42 #define MIPS_INC celt_mips++,
44 #define QCONST16(x,bits) ((celt_word16_t)(.5+(x)*(((celt_word32_t)1)<<(bits))))
45 #define QCONST32(x,bits) ((celt_word32_t)(.5+(x)*(((celt_word32_t)1)<<(bits))))
48 #define VERIFY_SHORT(x) ((x)<=32767&&(x)>=-32768)
49 #define VERIFY_INT(x) ((x)<=2147483647LL&&(x)>=-2147483648LL)
51 #define SHR(a,b) SHR32(a,b)
52 #define PSHR(a,b) PSHR32(a,b)
54 static inline short NEG16(int x)
59 fprintf (stderr, "NEG16: input is not short: %d\n", (int)x);
62 if (!VERIFY_SHORT(res))
63 fprintf (stderr, "NEG16: output is not short: %d\n", (int)res);
67 static inline int NEG32(long long x)
72 fprintf (stderr, "NEG16: input is not int: %d\n", (int)x);
76 fprintf (stderr, "NEG16: output is not int: %d\n", (int)res);
81 #define EXTRACT16(x) _EXTRACT16(x, __FILE__, __LINE__)
82 static inline short _EXTRACT16(int x, char *file, int line)
87 fprintf (stderr, "EXTRACT16: input is not short: %d in %s: line %d\n", x, file, line);
94 #define EXTEND32(x) _EXTEND32(x, __FILE__, __LINE__)
95 static inline int _EXTEND32(int x, char *file, int line)
100 fprintf (stderr, "EXTEND32: input is not short: %d in %s: line %d\n", x, file, line);
107 #define SHR16(a, shift) _SHR16(a, shift, __FILE__, __LINE__)
108 static inline short _SHR16(int a, int shift, char *file, int line)
111 if (!VERIFY_SHORT(a) || !VERIFY_SHORT(shift))
113 fprintf (stderr, "SHR16: inputs are not short: %d >> %d in %s: line %d\n", a, shift, file, line);
116 if (!VERIFY_SHORT(res))
117 fprintf (stderr, "SHR16: output is not short: %d in %s: line %d\n", res, file, line);
121 #define SHL16(a, shift) _SHL16(a, shift, __FILE__, __LINE__)
122 static inline short _SHL16(int a, int shift, char *file, int line)
125 if (!VERIFY_SHORT(a) || !VERIFY_SHORT(shift))
127 fprintf (stderr, "SHL16: inputs are not short: %d %d in %s: line %d\n", a, shift, file, line);
130 if (!VERIFY_SHORT(res))
131 fprintf (stderr, "SHL16: output is not short: %d in %s: line %d\n", res, file, line);
136 static inline int SHR32(long long a, int shift)
139 if (!VERIFY_INT(a) || !VERIFY_SHORT(shift))
141 fprintf (stderr, "SHR32: inputs are not int: %d %d\n", (int)a, shift);
144 if (!VERIFY_INT(res))
146 fprintf (stderr, "SHR32: output is not int: %d\n", (int)res);
151 static inline int SHL32(long long a, int shift)
154 if (!VERIFY_INT(a) || !VERIFY_SHORT(shift))
156 fprintf (stderr, "SHL32: inputs are not int: %d %d\n", (int)a, shift);
159 if (!VERIFY_INT(res))
161 fprintf (stderr, "SHL32: output is not int: %d\n", (int)res);
167 #define PSHR16(a,shift) (SHR16(ADD16((a),((1<<((shift))>>1))),shift))
168 #define PSHR32(a,shift) (SHR32(ADD32((a),((EXTEND32(1)<<((shift))>>1))),shift))
169 #define VSHR32(a, shift) (((shift)>0) ? SHR32(a, shift) : SHL32(a, -(shift)))
171 #define SATURATE16(x,a) (((x)>(a) ? (a) : (x)<-(a) ? -(a) : (x)))
172 #define SATURATE32(x,a) (((x)>(a) ? (a) : (x)<-(a) ? -(a) : (x)))
174 #define ROUND(x,a) (EXTRACT16(PSHR32((x),(a))))
175 #define HALF32(x) (SHR32(x,1))
177 //#define SHR(a,shift) ((a) >> (shift))
178 //#define SHL(a,shift) ((a) << (shift))
180 #define ADD16(a, b) _ADD16(a, b, __FILE__, __LINE__)
181 static inline short _ADD16(int a, int b, char *file, int line)
184 if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
186 fprintf (stderr, "ADD16: inputs are not short: %d %d in %s: line %d\n", a, b, file, line);
189 if (!VERIFY_SHORT(res))
191 fprintf (stderr, "ADD16: output is not short: %d+%d=%d in %s: line %d\n", a,b,res, file, line);
197 #define SUB16(a, b) _SUB16(a, b, __FILE__, __LINE__)
198 static inline short _SUB16(int a, int b, char *file, int line)
201 if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
203 fprintf (stderr, "SUB16: inputs are not short: %d %d in %s: line %d\n", a, b, file, line);
206 if (!VERIFY_SHORT(res))
207 fprintf (stderr, "SUB16: output is not short: %d in %s: line %d\n", res, file, line);
212 #define ADD32(a, b) _ADD32(a, b, __FILE__, __LINE__)
213 static inline int _ADD32(long long a, long long b, char *file, int line)
216 if (!VERIFY_INT(a) || !VERIFY_INT(b))
218 fprintf (stderr, "ADD32: inputs are not int: %d %d in %s: line %d\n", (int)a, (int)b, file, line);
221 if (!VERIFY_INT(res))
223 fprintf (stderr, "ADD32: output is not int: %d in %s: line %d\n", (int)res, file, line);
229 static inline int SUB32(long long a, long long b)
232 if (!VERIFY_INT(a) || !VERIFY_INT(b))
234 fprintf (stderr, "SUB32: inputs are not int: %d %d\n", (int)a, (int)b);
237 if (!VERIFY_INT(res))
238 fprintf (stderr, "SUB32: output is not int: %d\n", (int)res);
243 #define ADD64(a,b) (MIPS_INC(a)+(b))
245 /* result fits in 16 bits */
246 static inline short MULT16_16_16(int a, int b)
249 if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
251 fprintf (stderr, "MULT16_16_16: inputs are not short: %d %d\n", a, b);
254 if (!VERIFY_SHORT(res))
255 fprintf (stderr, "MULT16_16_16: output is not short: %d\n", res);
260 #define MULT16_16(a, b) _MULT16_16(a, b, __FILE__, __LINE__)
261 static inline int _MULT16_16(int a, int b, char *file, int line)
264 if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
266 fprintf (stderr, "MULT16_16: inputs are not short: %d %d in %s: line %d\n", a, b, file, line);
268 res = ((long long)a)*b;
269 if (!VERIFY_INT(res))
270 fprintf (stderr, "MULT16_16: output is not int: %d in %s: line %d\n", (int)res, file, line);
275 #define MAC16_16(c,a,b) (celt_mips--,ADD32((c),MULT16_16((a),(b))))
276 #define MAC16_16_Q11(c,a,b) (EXTRACT16(ADD16((c),EXTRACT16(SHR32(MULT16_16((a),(b)),11)))))
277 #define MAC16_16_Q13(c,a,b) (EXTRACT16(ADD16((c),EXTRACT16(SHR32(MULT16_16((a),(b)),13)))))
278 #define MAC16_16_P13(c,a,b) (EXTRACT16(ADD32((c),SHR32(ADD32(4096,MULT16_16((a),(b))),13))))
281 #define MULT16_32_QX(a, b, Q) _MULT16_32_QX(a, b, Q, __FILE__, __LINE__)
282 static inline int _MULT16_32_QX(int a, long long b, int Q, char *file, int line)
285 if (!VERIFY_SHORT(a) || !VERIFY_INT(b))
287 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);
289 if (ABS32(b)>=(EXTEND32(1)<<(15+Q)))
290 fprintf (stderr, "MULT16_32_Q%d: second operand too large: %d %d in %s: line %d\n", Q, (int)a, (int)b, file, line);
291 res = (((long long)a)*(long long)b) >> Q;
292 if (!VERIFY_INT(res))
293 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);
298 static inline int MULT16_32_PX(int a, long long b, int Q)
301 if (!VERIFY_SHORT(a) || !VERIFY_INT(b))
303 fprintf (stderr, "MULT16_32_P%d: inputs are not short+int: %d %d\n", Q, (int)a, (int)b);
305 if (ABS32(b)>=(EXTEND32(1)<<(15+Q)))
306 fprintf (stderr, "MULT16_32_Q%d: second operand too large: %d %d\n", Q, (int)a, (int)b);
307 res = ((((long long)a)*(long long)b) + ((EXTEND32(1)<<Q)>>1))>> Q;
308 if (!VERIFY_INT(res))
309 fprintf (stderr, "MULT16_32_P%d: output is not int: %d*%d=%d\n", Q, (int)a, (int)b,(int)res);
315 #define MULT16_32_Q11(a,b) MULT16_32_QX(a,b,11)
316 #define MAC16_32_Q11(c,a,b) ADD32((c),MULT16_32_Q11((a),(b)))
317 #define MULT16_32_Q12(a,b) MULT16_32_QX(a,b,12)
318 #define MULT16_32_Q13(a,b) MULT16_32_QX(a,b,13)
319 #define MULT16_32_Q14(a,b) MULT16_32_QX(a,b,14)
320 #define MULT16_32_Q15(a,b) MULT16_32_QX(a,b,15)
321 #define MULT16_32_P15(a,b) MULT16_32_PX(a,b,15)
322 #define MAC16_32_Q15(c,a,b) ADD32((c),MULT16_32_Q15((a),(b)))
324 static inline int SATURATE(int a, int b)
333 static inline int MULT16_16_Q11_32(int a, int b)
336 if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
338 fprintf (stderr, "MULT16_16_Q11: inputs are not short: %d %d\n", a, b);
340 res = ((long long)a)*b;
342 if (!VERIFY_INT(res))
343 fprintf (stderr, "MULT16_16_Q11: output is not short: %d*%d=%d\n", (int)a, (int)b, (int)res);
347 static inline short MULT16_16_Q13(int a, int b)
350 if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
352 fprintf (stderr, "MULT16_16_Q13: inputs are not short: %d %d\n", a, b);
354 res = ((long long)a)*b;
356 if (!VERIFY_SHORT(res))
357 fprintf (stderr, "MULT16_16_Q13: output is not short: %d*%d=%d\n", a, b, (int)res);
361 static inline short MULT16_16_Q14(int a, int b)
364 if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
366 fprintf (stderr, "MULT16_16_Q14: inputs are not short: %d %d\n", a, b);
368 res = ((long long)a)*b;
370 if (!VERIFY_SHORT(res))
371 fprintf (stderr, "MULT16_16_Q14: output is not short: %d\n", (int)res);
375 static inline short MULT16_16_Q15(int a, int b)
378 if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
380 fprintf (stderr, "MULT16_16_Q15: inputs are not short: %d %d\n", a, b);
382 res = ((long long)a)*b;
384 if (!VERIFY_SHORT(res))
386 fprintf (stderr, "MULT16_16_Q15: output is not short: %d\n", (int)res);
392 static inline short MULT16_16_P13(int a, int b)
395 if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
397 fprintf (stderr, "MULT16_16_P13: inputs are not short: %d %d\n", a, b);
399 res = ((long long)a)*b;
401 if (!VERIFY_INT(res))
402 fprintf (stderr, "MULT16_16_P13: overflow: %d*%d=%d\n", a, b, (int)res);
404 if (!VERIFY_SHORT(res))
405 fprintf (stderr, "MULT16_16_P13: output is not short: %d*%d=%d\n", a, b, (int)res);
409 static inline short MULT16_16_P14(int a, int b)
412 if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
414 fprintf (stderr, "MULT16_16_P14: inputs are not short: %d %d\n", a, b);
416 res = ((long long)a)*b;
418 if (!VERIFY_INT(res))
419 fprintf (stderr, "MULT16_16_P14: overflow: %d*%d=%d\n", a, b, (int)res);
421 if (!VERIFY_SHORT(res))
422 fprintf (stderr, "MULT16_16_P14: output is not short: %d*%d=%d\n", a, b, (int)res);
426 static inline short MULT16_16_P15(int a, int b)
429 if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
431 fprintf (stderr, "MULT16_16_P15: inputs are not short: %d %d\n", a, b);
433 res = ((long long)a)*b;
435 if (!VERIFY_INT(res))
436 fprintf (stderr, "MULT16_16_P15: overflow: %d*%d=%d\n", a, b, (int)res);
438 if (!VERIFY_SHORT(res))
439 fprintf (stderr, "MULT16_16_P15: output is not short: %d*%d=%d\n", a, b, (int)res);
444 #define DIV32_16(a, b) _DIV32_16(a, b, __FILE__, __LINE__)
446 static inline int _DIV32_16(long long a, long long b, char *file, int line)
451 fprintf(stderr, "DIV32_16: divide by zero: %d/%d in %s: line %d\n", (int)a, (int)b, file, line);
454 if (!VERIFY_INT(a) || !VERIFY_SHORT(b))
456 fprintf (stderr, "DIV32_16: inputs are not int/short: %d %d in %s: line %d\n", (int)a, (int)b, file, line);
459 if (!VERIFY_SHORT(res))
461 fprintf (stderr, "DIV32_16: output is not short: %d / %d = %d in %s: line %d\n", (int)a,(int)b,(int)res, file, line);
471 #define DIV32(a, b) _DIV32(a, b, __FILE__, __LINE__)
472 static inline int _DIV32(long long a, long long b, char *file, int line)
477 fprintf(stderr, "DIV32: divide by zero: %d/%d in %s: line %d\n", (int)a, (int)b, file, line);
481 if (!VERIFY_INT(a) || !VERIFY_INT(b))
483 fprintf (stderr, "DIV32: inputs are not int/short: %d %d in %s: line %d\n", (int)a, (int)b, file, line);
486 if (!VERIFY_INT(res))
487 fprintf (stderr, "DIV32: output is not int: %d in %s: line %d\n", (int)res, file, line);
491 #define PDIV32(a,b) DIV32(ADD32((a),(b)>>1),b)
492 #define PDIV32_16(a,b) DIV32_16(ADD32((a),(b)>>1),b)