1*a58d3d2aSXin Li /* Copyright (C) 2003-2008 Jean-Marc Valin
2*a58d3d2aSXin Li Copyright (C) 2007-2012 Xiph.Org Foundation */
3*a58d3d2aSXin Li /**
4*a58d3d2aSXin Li @file fixed_debug.h
5*a58d3d2aSXin Li @brief Fixed-point operations with debugging
6*a58d3d2aSXin Li */
7*a58d3d2aSXin Li /*
8*a58d3d2aSXin Li Redistribution and use in source and binary forms, with or without
9*a58d3d2aSXin Li modification, are permitted provided that the following conditions
10*a58d3d2aSXin Li are met:
11*a58d3d2aSXin Li
12*a58d3d2aSXin Li - Redistributions of source code must retain the above copyright
13*a58d3d2aSXin Li notice, this list of conditions and the following disclaimer.
14*a58d3d2aSXin Li
15*a58d3d2aSXin Li - Redistributions in binary form must reproduce the above copyright
16*a58d3d2aSXin Li notice, this list of conditions and the following disclaimer in the
17*a58d3d2aSXin Li documentation and/or other materials provided with the distribution.
18*a58d3d2aSXin Li
19*a58d3d2aSXin Li THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20*a58d3d2aSXin Li ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21*a58d3d2aSXin Li LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22*a58d3d2aSXin Li A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
23*a58d3d2aSXin Li OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24*a58d3d2aSXin Li EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25*a58d3d2aSXin Li PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26*a58d3d2aSXin Li PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27*a58d3d2aSXin Li LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28*a58d3d2aSXin Li NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29*a58d3d2aSXin Li SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30*a58d3d2aSXin Li */
31*a58d3d2aSXin Li
32*a58d3d2aSXin Li #ifndef FIXED_DEBUG_H
33*a58d3d2aSXin Li #define FIXED_DEBUG_H
34*a58d3d2aSXin Li
35*a58d3d2aSXin Li #include <stdio.h>
36*a58d3d2aSXin Li #include "opus_defines.h"
37*a58d3d2aSXin Li
38*a58d3d2aSXin Li #ifdef CELT_C
39*a58d3d2aSXin Li OPUS_EXPORT opus_int64 celt_mips=0;
40*a58d3d2aSXin Li #else
41*a58d3d2aSXin Li extern opus_int64 celt_mips;
42*a58d3d2aSXin Li #endif
43*a58d3d2aSXin Li
44*a58d3d2aSXin Li #define MULT16_16SU(a,b) ((opus_val32)(opus_val16)(a)*(opus_val32)(opus_uint16)(b))
45*a58d3d2aSXin Li #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*a58d3d2aSXin Li
47*a58d3d2aSXin Li /** 16x32 multiplication, followed by a 16-bit shift right. Results fits in 32 bits */
48*a58d3d2aSXin Li #define MULT16_32_Q16(a,b) ADD32(MULT16_16((a),SHR32((b),16)), SHR32(MULT16_16SU((a),((b)&0x0000ffff)),16))
49*a58d3d2aSXin Li
50*a58d3d2aSXin Li #define MULT16_32_P16(a,b) MULT16_32_PX(a,b,16)
51*a58d3d2aSXin Li
52*a58d3d2aSXin Li #define QCONST16(x,bits) ((opus_val16)(.5+(x)*(((opus_val32)1)<<(bits))))
53*a58d3d2aSXin Li #define QCONST32(x,bits) ((opus_val32)(.5+(x)*(((opus_val32)1)<<(bits))))
54*a58d3d2aSXin Li
55*a58d3d2aSXin Li #define VERIFY_SHORT(x) ((x)<=32767&&(x)>=-32768)
56*a58d3d2aSXin Li #define VERIFY_INT(x) ((x)<=2147483647LL&&(x)>=-2147483648LL)
57*a58d3d2aSXin Li #define VERIFY_UINT(x) ((x)<=(2147483647LLU<<1))
58*a58d3d2aSXin Li
59*a58d3d2aSXin Li #define SHR(a,b) SHR32(a,b)
60*a58d3d2aSXin Li #define PSHR(a,b) PSHR32(a,b)
61*a58d3d2aSXin Li
62*a58d3d2aSXin Li /** Add two 32-bit values, ignore any overflows */
63*a58d3d2aSXin Li #define ADD32_ovflw(a,b) (celt_mips+=2,(opus_val32)((opus_uint32)(a)+(opus_uint32)(b)))
64*a58d3d2aSXin Li /** Subtract two 32-bit values, ignore any overflows */
65*a58d3d2aSXin Li #define SUB32_ovflw(a,b) (celt_mips+=2,(opus_val32)((opus_uint32)(a)-(opus_uint32)(b)))
66*a58d3d2aSXin Li /* Avoid MSVC warning C4146: unary minus operator applied to unsigned type */
67*a58d3d2aSXin Li /** Negate 32-bit value, ignore any overflows */
68*a58d3d2aSXin Li #define NEG32_ovflw(a) (celt_mips+=2,(opus_val32)(0-(opus_uint32)(a)))
69*a58d3d2aSXin Li
NEG16(int x)70*a58d3d2aSXin Li static OPUS_INLINE short NEG16(int x)
71*a58d3d2aSXin Li {
72*a58d3d2aSXin Li int res;
73*a58d3d2aSXin Li if (!VERIFY_SHORT(x))
74*a58d3d2aSXin Li {
75*a58d3d2aSXin Li fprintf (stderr, "NEG16: input is not short: %d\n", (int)x);
76*a58d3d2aSXin Li #ifdef FIXED_DEBUG_ASSERT
77*a58d3d2aSXin Li celt_assert(0);
78*a58d3d2aSXin Li #endif
79*a58d3d2aSXin Li }
80*a58d3d2aSXin Li res = -x;
81*a58d3d2aSXin Li if (!VERIFY_SHORT(res))
82*a58d3d2aSXin Li {
83*a58d3d2aSXin Li fprintf (stderr, "NEG16: output is not short: %d\n", (int)res);
84*a58d3d2aSXin Li #ifdef FIXED_DEBUG_ASSERT
85*a58d3d2aSXin Li celt_assert(0);
86*a58d3d2aSXin Li #endif
87*a58d3d2aSXin Li }
88*a58d3d2aSXin Li celt_mips++;
89*a58d3d2aSXin Li return res;
90*a58d3d2aSXin Li }
NEG32(opus_int64 x)91*a58d3d2aSXin Li static OPUS_INLINE int NEG32(opus_int64 x)
92*a58d3d2aSXin Li {
93*a58d3d2aSXin Li opus_int64 res;
94*a58d3d2aSXin Li if (!VERIFY_INT(x))
95*a58d3d2aSXin Li {
96*a58d3d2aSXin Li fprintf (stderr, "NEG16: input is not int: %d\n", (int)x);
97*a58d3d2aSXin Li #ifdef FIXED_DEBUG_ASSERT
98*a58d3d2aSXin Li celt_assert(0);
99*a58d3d2aSXin Li #endif
100*a58d3d2aSXin Li }
101*a58d3d2aSXin Li res = -x;
102*a58d3d2aSXin Li if (!VERIFY_INT(res))
103*a58d3d2aSXin Li {
104*a58d3d2aSXin Li fprintf (stderr, "NEG16: output is not int: %d\n", (int)res);
105*a58d3d2aSXin Li #ifdef FIXED_DEBUG_ASSERT
106*a58d3d2aSXin Li celt_assert(0);
107*a58d3d2aSXin Li #endif
108*a58d3d2aSXin Li }
109*a58d3d2aSXin Li celt_mips+=2;
110*a58d3d2aSXin Li return res;
111*a58d3d2aSXin Li }
112*a58d3d2aSXin Li
113*a58d3d2aSXin Li #define EXTRACT16(x) EXTRACT16_(x, __FILE__, __LINE__)
EXTRACT16_(int x,char * file,int line)114*a58d3d2aSXin Li static OPUS_INLINE short EXTRACT16_(int x, char *file, int line)
115*a58d3d2aSXin Li {
116*a58d3d2aSXin Li int res;
117*a58d3d2aSXin Li if (!VERIFY_SHORT(x))
118*a58d3d2aSXin Li {
119*a58d3d2aSXin Li fprintf (stderr, "EXTRACT16: input is not short: %d in %s: line %d\n", x, file, line);
120*a58d3d2aSXin Li #ifdef FIXED_DEBUG_ASSERT
121*a58d3d2aSXin Li celt_assert(0);
122*a58d3d2aSXin Li #endif
123*a58d3d2aSXin Li }
124*a58d3d2aSXin Li res = x;
125*a58d3d2aSXin Li celt_mips++;
126*a58d3d2aSXin Li return res;
127*a58d3d2aSXin Li }
128*a58d3d2aSXin Li
129*a58d3d2aSXin Li #define EXTEND32(x) EXTEND32_(x, __FILE__, __LINE__)
EXTEND32_(int x,char * file,int line)130*a58d3d2aSXin Li static OPUS_INLINE int EXTEND32_(int x, char *file, int line)
131*a58d3d2aSXin Li {
132*a58d3d2aSXin Li int res;
133*a58d3d2aSXin Li if (!VERIFY_SHORT(x))
134*a58d3d2aSXin Li {
135*a58d3d2aSXin Li fprintf (stderr, "EXTEND32: input is not short: %d in %s: line %d\n", x, file, line);
136*a58d3d2aSXin Li #ifdef FIXED_DEBUG_ASSERT
137*a58d3d2aSXin Li celt_assert(0);
138*a58d3d2aSXin Li #endif
139*a58d3d2aSXin Li }
140*a58d3d2aSXin Li res = x;
141*a58d3d2aSXin Li celt_mips++;
142*a58d3d2aSXin Li return res;
143*a58d3d2aSXin Li }
144*a58d3d2aSXin Li
145*a58d3d2aSXin Li #define SHR16(a, shift) SHR16_(a, shift, __FILE__, __LINE__)
SHR16_(int a,int shift,char * file,int line)146*a58d3d2aSXin Li static OPUS_INLINE short SHR16_(int a, int shift, char *file, int line)
147*a58d3d2aSXin Li {
148*a58d3d2aSXin Li int res;
149*a58d3d2aSXin Li if (!VERIFY_SHORT(a) || !VERIFY_SHORT(shift))
150*a58d3d2aSXin Li {
151*a58d3d2aSXin Li fprintf (stderr, "SHR16: inputs are not short: %d >> %d in %s: line %d\n", a, shift, file, line);
152*a58d3d2aSXin Li #ifdef FIXED_DEBUG_ASSERT
153*a58d3d2aSXin Li celt_assert(0);
154*a58d3d2aSXin Li #endif
155*a58d3d2aSXin Li }
156*a58d3d2aSXin Li res = a>>shift;
157*a58d3d2aSXin Li if (!VERIFY_SHORT(res))
158*a58d3d2aSXin Li {
159*a58d3d2aSXin Li fprintf (stderr, "SHR16: output is not short: %d in %s: line %d\n", res, file, line);
160*a58d3d2aSXin Li #ifdef FIXED_DEBUG_ASSERT
161*a58d3d2aSXin Li celt_assert(0);
162*a58d3d2aSXin Li #endif
163*a58d3d2aSXin Li }
164*a58d3d2aSXin Li celt_mips++;
165*a58d3d2aSXin Li return res;
166*a58d3d2aSXin Li }
167*a58d3d2aSXin Li #define SHL16(a, shift) SHL16_(a, shift, __FILE__, __LINE__)
SHL16_(int a,int shift,char * file,int line)168*a58d3d2aSXin Li static OPUS_INLINE short SHL16_(int a, int shift, char *file, int line)
169*a58d3d2aSXin Li {
170*a58d3d2aSXin Li opus_int32 res;
171*a58d3d2aSXin Li if (!VERIFY_SHORT(a) || !VERIFY_SHORT(shift))
172*a58d3d2aSXin Li {
173*a58d3d2aSXin Li fprintf (stderr, "SHL16: inputs are not short: %d %d in %s: line %d\n", a, shift, file, line);
174*a58d3d2aSXin Li #ifdef FIXED_DEBUG_ASSERT
175*a58d3d2aSXin Li celt_assert(0);
176*a58d3d2aSXin Li #endif
177*a58d3d2aSXin Li }
178*a58d3d2aSXin Li res = (opus_int32)((opus_uint32)a<<shift);
179*a58d3d2aSXin Li if (!VERIFY_SHORT(res))
180*a58d3d2aSXin Li {
181*a58d3d2aSXin Li fprintf (stderr, "SHL16: output is not short: %d in %s: line %d\n", res, file, line);
182*a58d3d2aSXin Li #ifdef FIXED_DEBUG_ASSERT
183*a58d3d2aSXin Li celt_assert(0);
184*a58d3d2aSXin Li #endif
185*a58d3d2aSXin Li }
186*a58d3d2aSXin Li celt_mips++;
187*a58d3d2aSXin Li return res;
188*a58d3d2aSXin Li }
189*a58d3d2aSXin Li
SHR32(opus_int64 a,int shift)190*a58d3d2aSXin Li static OPUS_INLINE int SHR32(opus_int64 a, int shift)
191*a58d3d2aSXin Li {
192*a58d3d2aSXin Li opus_int64 res;
193*a58d3d2aSXin Li if (!VERIFY_INT(a) || !VERIFY_SHORT(shift))
194*a58d3d2aSXin Li {
195*a58d3d2aSXin Li fprintf (stderr, "SHR32: inputs are not int: %d %d\n", (int)a, shift);
196*a58d3d2aSXin Li #ifdef FIXED_DEBUG_ASSERT
197*a58d3d2aSXin Li celt_assert(0);
198*a58d3d2aSXin Li #endif
199*a58d3d2aSXin Li }
200*a58d3d2aSXin Li res = a>>shift;
201*a58d3d2aSXin Li if (!VERIFY_INT(res))
202*a58d3d2aSXin Li {
203*a58d3d2aSXin Li fprintf (stderr, "SHR32: output is not int: %d\n", (int)res);
204*a58d3d2aSXin Li #ifdef FIXED_DEBUG_ASSERT
205*a58d3d2aSXin Li celt_assert(0);
206*a58d3d2aSXin Li #endif
207*a58d3d2aSXin Li }
208*a58d3d2aSXin Li celt_mips+=2;
209*a58d3d2aSXin Li return res;
210*a58d3d2aSXin Li }
211*a58d3d2aSXin Li #define SHL32(a, shift) SHL32_(a, shift, __FILE__, __LINE__)
SHL32_(opus_int64 a,int shift,char * file,int line)212*a58d3d2aSXin Li static OPUS_INLINE int SHL32_(opus_int64 a, int shift, char *file, int line)
213*a58d3d2aSXin Li {
214*a58d3d2aSXin Li opus_int64 res;
215*a58d3d2aSXin Li if (!VERIFY_INT(a) || !VERIFY_SHORT(shift))
216*a58d3d2aSXin Li {
217*a58d3d2aSXin Li fprintf (stderr, "SHL32: inputs are not int: %lld %d in %s: line %d\n", (long long)a, shift, file, line);
218*a58d3d2aSXin Li #ifdef FIXED_DEBUG_ASSERT
219*a58d3d2aSXin Li celt_assert(0);
220*a58d3d2aSXin Li #endif
221*a58d3d2aSXin Li }
222*a58d3d2aSXin Li res = (opus_int64)((opus_uint64)a<<shift);
223*a58d3d2aSXin Li if (!VERIFY_INT(res))
224*a58d3d2aSXin Li {
225*a58d3d2aSXin Li 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*a58d3d2aSXin Li #ifdef FIXED_DEBUG_ASSERT
227*a58d3d2aSXin Li celt_assert(0);
228*a58d3d2aSXin Li #endif
229*a58d3d2aSXin Li }
230*a58d3d2aSXin Li celt_mips+=2;
231*a58d3d2aSXin Li return res;
232*a58d3d2aSXin Li }
233*a58d3d2aSXin Li
234*a58d3d2aSXin Li #define PSHR32(a,shift) (celt_mips--,SHR32(ADD32((a),(((opus_val32)(1)<<((shift))>>1))),shift))
235*a58d3d2aSXin Li #define VSHR32(a, shift) (((shift)>0) ? SHR32(a, shift) : SHL32(a, -(shift)))
236*a58d3d2aSXin Li
237*a58d3d2aSXin Li #define ROUND16(x,a) (celt_mips--,EXTRACT16(PSHR32((x),(a))))
238*a58d3d2aSXin Li #define SROUND16(x,a) (celt_mips--,EXTRACT16(SATURATE(PSHR32(x,a), 32767)));
239*a58d3d2aSXin Li
240*a58d3d2aSXin Li #define HALF16(x) (SHR16(x,1))
241*a58d3d2aSXin Li #define HALF32(x) (SHR32(x,1))
242*a58d3d2aSXin Li
243*a58d3d2aSXin Li #define ADD16(a, b) ADD16_(a, b, __FILE__, __LINE__)
ADD16_(int a,int b,char * file,int line)244*a58d3d2aSXin Li static OPUS_INLINE short ADD16_(int a, int b, char *file, int line)
245*a58d3d2aSXin Li {
246*a58d3d2aSXin Li int res;
247*a58d3d2aSXin Li if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
248*a58d3d2aSXin Li {
249*a58d3d2aSXin Li fprintf (stderr, "ADD16: inputs are not short: %d %d in %s: line %d\n", a, b, file, line);
250*a58d3d2aSXin Li #ifdef FIXED_DEBUG_ASSERT
251*a58d3d2aSXin Li celt_assert(0);
252*a58d3d2aSXin Li #endif
253*a58d3d2aSXin Li }
254*a58d3d2aSXin Li res = a+b;
255*a58d3d2aSXin Li if (!VERIFY_SHORT(res))
256*a58d3d2aSXin Li {
257*a58d3d2aSXin Li fprintf (stderr, "ADD16: output is not short: %d+%d=%d in %s: line %d\n", a,b,res, file, line);
258*a58d3d2aSXin Li #ifdef FIXED_DEBUG_ASSERT
259*a58d3d2aSXin Li celt_assert(0);
260*a58d3d2aSXin Li #endif
261*a58d3d2aSXin Li }
262*a58d3d2aSXin Li celt_mips++;
263*a58d3d2aSXin Li return res;
264*a58d3d2aSXin Li }
265*a58d3d2aSXin Li
266*a58d3d2aSXin Li #define SUB16(a, b) SUB16_(a, b, __FILE__, __LINE__)
SUB16_(int a,int b,char * file,int line)267*a58d3d2aSXin Li static OPUS_INLINE short SUB16_(int a, int b, char *file, int line)
268*a58d3d2aSXin Li {
269*a58d3d2aSXin Li int res;
270*a58d3d2aSXin Li if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
271*a58d3d2aSXin Li {
272*a58d3d2aSXin Li fprintf (stderr, "SUB16: inputs are not short: %d %d in %s: line %d\n", a, b, file, line);
273*a58d3d2aSXin Li #ifdef FIXED_DEBUG_ASSERT
274*a58d3d2aSXin Li celt_assert(0);
275*a58d3d2aSXin Li #endif
276*a58d3d2aSXin Li }
277*a58d3d2aSXin Li res = a-b;
278*a58d3d2aSXin Li if (!VERIFY_SHORT(res))
279*a58d3d2aSXin Li {
280*a58d3d2aSXin Li fprintf (stderr, "SUB16: output is not short: %d in %s: line %d\n", res, file, line);
281*a58d3d2aSXin Li #ifdef FIXED_DEBUG_ASSERT
282*a58d3d2aSXin Li celt_assert(0);
283*a58d3d2aSXin Li #endif
284*a58d3d2aSXin Li }
285*a58d3d2aSXin Li celt_mips++;
286*a58d3d2aSXin Li return res;
287*a58d3d2aSXin Li }
288*a58d3d2aSXin Li
289*a58d3d2aSXin Li #define ADD32(a, b) ADD32_(a, b, __FILE__, __LINE__)
ADD32_(opus_int64 a,opus_int64 b,char * file,int line)290*a58d3d2aSXin Li static OPUS_INLINE int ADD32_(opus_int64 a, opus_int64 b, char *file, int line)
291*a58d3d2aSXin Li {
292*a58d3d2aSXin Li opus_int64 res;
293*a58d3d2aSXin Li if (!VERIFY_INT(a) || !VERIFY_INT(b))
294*a58d3d2aSXin Li {
295*a58d3d2aSXin Li fprintf (stderr, "ADD32: inputs are not int: %d %d in %s: line %d\n", (int)a, (int)b, file, line);
296*a58d3d2aSXin Li #ifdef FIXED_DEBUG_ASSERT
297*a58d3d2aSXin Li celt_assert(0);
298*a58d3d2aSXin Li #endif
299*a58d3d2aSXin Li }
300*a58d3d2aSXin Li res = a+b;
301*a58d3d2aSXin Li if (!VERIFY_INT(res))
302*a58d3d2aSXin Li {
303*a58d3d2aSXin Li fprintf (stderr, "ADD32: output is not int: %d in %s: line %d\n", (int)res, file, line);
304*a58d3d2aSXin Li #ifdef FIXED_DEBUG_ASSERT
305*a58d3d2aSXin Li celt_assert(0);
306*a58d3d2aSXin Li #endif
307*a58d3d2aSXin Li }
308*a58d3d2aSXin Li celt_mips+=2;
309*a58d3d2aSXin Li return res;
310*a58d3d2aSXin Li }
311*a58d3d2aSXin Li
312*a58d3d2aSXin Li #define SUB32(a, b) SUB32_(a, b, __FILE__, __LINE__)
SUB32_(opus_int64 a,opus_int64 b,char * file,int line)313*a58d3d2aSXin Li static OPUS_INLINE int SUB32_(opus_int64 a, opus_int64 b, char *file, int line)
314*a58d3d2aSXin Li {
315*a58d3d2aSXin Li opus_int64 res;
316*a58d3d2aSXin Li if (!VERIFY_INT(a) || !VERIFY_INT(b))
317*a58d3d2aSXin Li {
318*a58d3d2aSXin Li fprintf (stderr, "SUB32: inputs are not int: %d %d in %s: line %d\n", (int)a, (int)b, file, line);
319*a58d3d2aSXin Li #ifdef FIXED_DEBUG_ASSERT
320*a58d3d2aSXin Li celt_assert(0);
321*a58d3d2aSXin Li #endif
322*a58d3d2aSXin Li }
323*a58d3d2aSXin Li res = a-b;
324*a58d3d2aSXin Li if (!VERIFY_INT(res))
325*a58d3d2aSXin Li {
326*a58d3d2aSXin Li fprintf (stderr, "SUB32: output is not int: %d in %s: line %d\n", (int)res, file, line);
327*a58d3d2aSXin Li #ifdef FIXED_DEBUG_ASSERT
328*a58d3d2aSXin Li celt_assert(0);
329*a58d3d2aSXin Li #endif
330*a58d3d2aSXin Li }
331*a58d3d2aSXin Li celt_mips+=2;
332*a58d3d2aSXin Li return res;
333*a58d3d2aSXin Li }
334*a58d3d2aSXin Li
335*a58d3d2aSXin Li #undef UADD32
336*a58d3d2aSXin Li #define UADD32(a, b) UADD32_(a, b, __FILE__, __LINE__)
UADD32_(opus_uint64 a,opus_uint64 b,char * file,int line)337*a58d3d2aSXin Li static OPUS_INLINE unsigned int UADD32_(opus_uint64 a, opus_uint64 b, char *file, int line)
338*a58d3d2aSXin Li {
339*a58d3d2aSXin Li opus_uint64 res;
340*a58d3d2aSXin Li if (!VERIFY_UINT(a) || !VERIFY_UINT(b))
341*a58d3d2aSXin Li {
342*a58d3d2aSXin Li 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*a58d3d2aSXin Li #ifdef FIXED_DEBUG_ASSERT
344*a58d3d2aSXin Li celt_assert(0);
345*a58d3d2aSXin Li #endif
346*a58d3d2aSXin Li }
347*a58d3d2aSXin Li res = a+b;
348*a58d3d2aSXin Li if (!VERIFY_UINT(res))
349*a58d3d2aSXin Li {
350*a58d3d2aSXin Li fprintf (stderr, "UADD32: output is not uint32: %llu in %s: line %d\n", (unsigned long long)res, file, line);
351*a58d3d2aSXin Li #ifdef FIXED_DEBUG_ASSERT
352*a58d3d2aSXin Li celt_assert(0);
353*a58d3d2aSXin Li #endif
354*a58d3d2aSXin Li }
355*a58d3d2aSXin Li celt_mips+=2;
356*a58d3d2aSXin Li return res;
357*a58d3d2aSXin Li }
358*a58d3d2aSXin Li
359*a58d3d2aSXin Li #undef USUB32
360*a58d3d2aSXin Li #define USUB32(a, b) USUB32_(a, b, __FILE__, __LINE__)
USUB32_(opus_uint64 a,opus_uint64 b,char * file,int line)361*a58d3d2aSXin Li static OPUS_INLINE unsigned int USUB32_(opus_uint64 a, opus_uint64 b, char *file, int line)
362*a58d3d2aSXin Li {
363*a58d3d2aSXin Li opus_uint64 res;
364*a58d3d2aSXin Li if (!VERIFY_UINT(a) || !VERIFY_UINT(b))
365*a58d3d2aSXin Li {
366*a58d3d2aSXin Li 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*a58d3d2aSXin Li #ifdef FIXED_DEBUG_ASSERT
368*a58d3d2aSXin Li celt_assert(0);
369*a58d3d2aSXin Li #endif
370*a58d3d2aSXin Li }
371*a58d3d2aSXin Li if (a<b)
372*a58d3d2aSXin Li {
373*a58d3d2aSXin Li fprintf (stderr, "USUB32: inputs underflow: %llu < %llu in %s: line %d\n", (unsigned long long)a, (unsigned long long)b, file, line);
374*a58d3d2aSXin Li #ifdef FIXED_DEBUG_ASSERT
375*a58d3d2aSXin Li celt_assert(0);
376*a58d3d2aSXin Li #endif
377*a58d3d2aSXin Li }
378*a58d3d2aSXin Li res = a-b;
379*a58d3d2aSXin Li if (!VERIFY_UINT(res))
380*a58d3d2aSXin Li {
381*a58d3d2aSXin Li 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*a58d3d2aSXin Li #ifdef FIXED_DEBUG_ASSERT
383*a58d3d2aSXin Li celt_assert(0);
384*a58d3d2aSXin Li #endif
385*a58d3d2aSXin Li }
386*a58d3d2aSXin Li celt_mips+=2;
387*a58d3d2aSXin Li return res;
388*a58d3d2aSXin Li }
389*a58d3d2aSXin Li
390*a58d3d2aSXin Li /* result fits in 16 bits */
MULT16_16_16(int a,int b)391*a58d3d2aSXin Li static OPUS_INLINE short MULT16_16_16(int a, int b)
392*a58d3d2aSXin Li {
393*a58d3d2aSXin Li int res;
394*a58d3d2aSXin Li if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
395*a58d3d2aSXin Li {
396*a58d3d2aSXin Li fprintf (stderr, "MULT16_16_16: inputs are not short: %d %d\n", a, b);
397*a58d3d2aSXin Li #ifdef FIXED_DEBUG_ASSERT
398*a58d3d2aSXin Li celt_assert(0);
399*a58d3d2aSXin Li #endif
400*a58d3d2aSXin Li }
401*a58d3d2aSXin Li res = a*b;
402*a58d3d2aSXin Li if (!VERIFY_SHORT(res))
403*a58d3d2aSXin Li {
404*a58d3d2aSXin Li fprintf (stderr, "MULT16_16_16: output is not short: %d\n", res);
405*a58d3d2aSXin Li #ifdef FIXED_DEBUG_ASSERT
406*a58d3d2aSXin Li celt_assert(0);
407*a58d3d2aSXin Li #endif
408*a58d3d2aSXin Li }
409*a58d3d2aSXin Li celt_mips++;
410*a58d3d2aSXin Li return res;
411*a58d3d2aSXin Li }
412*a58d3d2aSXin Li
413*a58d3d2aSXin Li /* result fits in 32 bits */
MULT32_32_32(opus_int64 a,opus_int64 b)414*a58d3d2aSXin Li static OPUS_INLINE int MULT32_32_32(opus_int64 a, opus_int64 b)
415*a58d3d2aSXin Li {
416*a58d3d2aSXin Li opus_int64 res;
417*a58d3d2aSXin Li if (!VERIFY_INT(a) || !VERIFY_INT(b))
418*a58d3d2aSXin Li {
419*a58d3d2aSXin Li fprintf (stderr, "MULT32_32_32: inputs are not int: %lld %lld\n", (long long)a, (long long)b);
420*a58d3d2aSXin Li #ifdef FIXED_DEBUG_ASSERT
421*a58d3d2aSXin Li celt_assert(0);
422*a58d3d2aSXin Li #endif
423*a58d3d2aSXin Li }
424*a58d3d2aSXin Li res = a*b;
425*a58d3d2aSXin Li if (!VERIFY_INT(res))
426*a58d3d2aSXin Li {
427*a58d3d2aSXin Li fprintf (stderr, "MULT32_32_32: output is not int: %lld\n", (long long)res);
428*a58d3d2aSXin Li #ifdef FIXED_DEBUG_ASSERT
429*a58d3d2aSXin Li celt_assert(0);
430*a58d3d2aSXin Li #endif
431*a58d3d2aSXin Li }
432*a58d3d2aSXin Li celt_mips+=5;
433*a58d3d2aSXin Li return res;
434*a58d3d2aSXin Li }
435*a58d3d2aSXin Li
MULT32_32_Q16(opus_int64 a,opus_int64 b)436*a58d3d2aSXin Li static OPUS_INLINE int MULT32_32_Q16(opus_int64 a, opus_int64 b)
437*a58d3d2aSXin Li {
438*a58d3d2aSXin Li opus_int64 res;
439*a58d3d2aSXin Li if (!VERIFY_INT(a) || !VERIFY_INT(b))
440*a58d3d2aSXin Li {
441*a58d3d2aSXin Li fprintf (stderr, "MULT32_32_Q16: inputs are not int: %lld %lld\n", (long long)a, (long long)b);
442*a58d3d2aSXin Li #ifdef FIXED_DEBUG_ASSERT
443*a58d3d2aSXin Li celt_assert(0);
444*a58d3d2aSXin Li #endif
445*a58d3d2aSXin Li }
446*a58d3d2aSXin Li res = ((opus_int64)(a)*(opus_int64)(b)) >> 16;
447*a58d3d2aSXin Li if (!VERIFY_INT(res))
448*a58d3d2aSXin Li {
449*a58d3d2aSXin Li fprintf (stderr, "MULT32_32_Q16: output is not int: %lld*%lld=%lld\n", (long long)a, (long long)b, (long long)res);
450*a58d3d2aSXin Li #ifdef FIXED_DEBUG_ASSERT
451*a58d3d2aSXin Li celt_assert(0);
452*a58d3d2aSXin Li #endif
453*a58d3d2aSXin Li }
454*a58d3d2aSXin Li celt_mips+=5;
455*a58d3d2aSXin Li return res;
456*a58d3d2aSXin Li }
457*a58d3d2aSXin Li
458*a58d3d2aSXin Li #define MULT16_16(a, b) MULT16_16_(a, b, __FILE__, __LINE__)
MULT16_16_(int a,int b,char * file,int line)459*a58d3d2aSXin Li static OPUS_INLINE int MULT16_16_(int a, int b, char *file, int line)
460*a58d3d2aSXin Li {
461*a58d3d2aSXin Li opus_int64 res;
462*a58d3d2aSXin Li if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
463*a58d3d2aSXin Li {
464*a58d3d2aSXin Li fprintf (stderr, "MULT16_16: inputs are not short: %d %d in %s: line %d\n", a, b, file, line);
465*a58d3d2aSXin Li #ifdef FIXED_DEBUG_ASSERT
466*a58d3d2aSXin Li celt_assert(0);
467*a58d3d2aSXin Li #endif
468*a58d3d2aSXin Li }
469*a58d3d2aSXin Li res = ((opus_int64)a)*b;
470*a58d3d2aSXin Li if (!VERIFY_INT(res))
471*a58d3d2aSXin Li {
472*a58d3d2aSXin Li fprintf (stderr, "MULT16_16: output is not int: %d in %s: line %d\n", (int)res, file, line);
473*a58d3d2aSXin Li #ifdef FIXED_DEBUG_ASSERT
474*a58d3d2aSXin Li celt_assert(0);
475*a58d3d2aSXin Li #endif
476*a58d3d2aSXin Li }
477*a58d3d2aSXin Li celt_mips++;
478*a58d3d2aSXin Li return res;
479*a58d3d2aSXin Li }
480*a58d3d2aSXin Li
481*a58d3d2aSXin Li #define MAC16_16(c,a,b) (celt_mips-=2,ADD32((c),MULT16_16((a),(b))))
482*a58d3d2aSXin Li
483*a58d3d2aSXin Li #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*a58d3d2aSXin Li static OPUS_INLINE int MULT16_32_QX_(int a, opus_int64 b, int Q, char *file, int line)
485*a58d3d2aSXin Li {
486*a58d3d2aSXin Li opus_int64 res;
487*a58d3d2aSXin Li if (!VERIFY_SHORT(a) || !VERIFY_INT(b))
488*a58d3d2aSXin Li {
489*a58d3d2aSXin Li 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*a58d3d2aSXin Li #ifdef FIXED_DEBUG_ASSERT
491*a58d3d2aSXin Li celt_assert(0);
492*a58d3d2aSXin Li #endif
493*a58d3d2aSXin Li }
494*a58d3d2aSXin Li if (ABS32(b)>=((opus_int64)(1)<<(16+Q)))
495*a58d3d2aSXin Li {
496*a58d3d2aSXin Li 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*a58d3d2aSXin Li #ifdef FIXED_DEBUG_ASSERT
498*a58d3d2aSXin Li celt_assert(0);
499*a58d3d2aSXin Li #endif
500*a58d3d2aSXin Li }
501*a58d3d2aSXin Li res = (((opus_int64)a)*(opus_int64)b) >> Q;
502*a58d3d2aSXin Li if (!VERIFY_INT(res))
503*a58d3d2aSXin Li {
504*a58d3d2aSXin Li 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*a58d3d2aSXin Li #ifdef FIXED_DEBUG_ASSERT
506*a58d3d2aSXin Li celt_assert(0);
507*a58d3d2aSXin Li #endif
508*a58d3d2aSXin Li }
509*a58d3d2aSXin Li if (Q==15)
510*a58d3d2aSXin Li celt_mips+=3;
511*a58d3d2aSXin Li else
512*a58d3d2aSXin Li celt_mips+=4;
513*a58d3d2aSXin Li return res;
514*a58d3d2aSXin Li }
515*a58d3d2aSXin Li
516*a58d3d2aSXin Li #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*a58d3d2aSXin Li static OPUS_INLINE int MULT16_32_PX_(int a, opus_int64 b, int Q, char *file, int line)
518*a58d3d2aSXin Li {
519*a58d3d2aSXin Li opus_int64 res;
520*a58d3d2aSXin Li if (!VERIFY_SHORT(a) || !VERIFY_INT(b))
521*a58d3d2aSXin Li {
522*a58d3d2aSXin Li 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*a58d3d2aSXin Li #ifdef FIXED_DEBUG_ASSERT
524*a58d3d2aSXin Li celt_assert(0);
525*a58d3d2aSXin Li #endif
526*a58d3d2aSXin Li }
527*a58d3d2aSXin Li if (ABS32(b)>=((opus_int64)(1)<<(16+Q)))
528*a58d3d2aSXin Li {
529*a58d3d2aSXin Li 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*a58d3d2aSXin Li #ifdef FIXED_DEBUG_ASSERT
531*a58d3d2aSXin Li celt_assert(0);
532*a58d3d2aSXin Li #endif
533*a58d3d2aSXin Li }
534*a58d3d2aSXin Li res = ((((opus_int64)a)*(opus_int64)b) + (((opus_val32)(1)<<Q)>>1))>> Q;
535*a58d3d2aSXin Li if (!VERIFY_INT(res))
536*a58d3d2aSXin Li {
537*a58d3d2aSXin Li 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*a58d3d2aSXin Li #ifdef FIXED_DEBUG_ASSERT
539*a58d3d2aSXin Li celt_assert(0);
540*a58d3d2aSXin Li #endif
541*a58d3d2aSXin Li }
542*a58d3d2aSXin Li if (Q==15)
543*a58d3d2aSXin Li celt_mips+=4;
544*a58d3d2aSXin Li else
545*a58d3d2aSXin Li celt_mips+=5;
546*a58d3d2aSXin Li return res;
547*a58d3d2aSXin Li }
548*a58d3d2aSXin Li
549*a58d3d2aSXin Li #define MULT16_32_Q15(a,b) MULT16_32_QX(a,b,15)
550*a58d3d2aSXin Li #define MAC16_32_Q15(c,a,b) (celt_mips-=2,ADD32((c),MULT16_32_Q15((a),(b))))
551*a58d3d2aSXin Li #define MAC16_32_Q16(c,a,b) (celt_mips-=2,ADD32((c),MULT16_32_Q16((a),(b))))
552*a58d3d2aSXin Li
SATURATE(int a,int b)553*a58d3d2aSXin Li static OPUS_INLINE int SATURATE(int a, int b)
554*a58d3d2aSXin Li {
555*a58d3d2aSXin Li if (a>b)
556*a58d3d2aSXin Li a=b;
557*a58d3d2aSXin Li if (a<-b)
558*a58d3d2aSXin Li a = -b;
559*a58d3d2aSXin Li celt_mips+=3;
560*a58d3d2aSXin Li return a;
561*a58d3d2aSXin Li }
562*a58d3d2aSXin Li
SATURATE16(opus_int32 a)563*a58d3d2aSXin Li static OPUS_INLINE opus_int16 SATURATE16(opus_int32 a)
564*a58d3d2aSXin Li {
565*a58d3d2aSXin Li celt_mips+=3;
566*a58d3d2aSXin Li if (a>32767)
567*a58d3d2aSXin Li return 32767;
568*a58d3d2aSXin Li else if (a<-32768)
569*a58d3d2aSXin Li return -32768;
570*a58d3d2aSXin Li else return a;
571*a58d3d2aSXin Li }
572*a58d3d2aSXin Li
MULT16_16_Q11_32(int a,int b)573*a58d3d2aSXin Li static OPUS_INLINE int MULT16_16_Q11_32(int a, int b)
574*a58d3d2aSXin Li {
575*a58d3d2aSXin Li opus_int64 res;
576*a58d3d2aSXin Li if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
577*a58d3d2aSXin Li {
578*a58d3d2aSXin Li fprintf (stderr, "MULT16_16_Q11: inputs are not short: %d %d\n", a, b);
579*a58d3d2aSXin Li #ifdef FIXED_DEBUG_ASSERT
580*a58d3d2aSXin Li celt_assert(0);
581*a58d3d2aSXin Li #endif
582*a58d3d2aSXin Li }
583*a58d3d2aSXin Li res = ((opus_int64)a)*b;
584*a58d3d2aSXin Li res >>= 11;
585*a58d3d2aSXin Li if (!VERIFY_INT(res))
586*a58d3d2aSXin Li {
587*a58d3d2aSXin Li fprintf (stderr, "MULT16_16_Q11: output is not short: %d*%d=%d\n", (int)a, (int)b, (int)res);
588*a58d3d2aSXin Li #ifdef FIXED_DEBUG_ASSERT
589*a58d3d2aSXin Li celt_assert(0);
590*a58d3d2aSXin Li #endif
591*a58d3d2aSXin Li }
592*a58d3d2aSXin Li celt_mips+=3;
593*a58d3d2aSXin Li return res;
594*a58d3d2aSXin Li }
MULT16_16_Q13(int a,int b)595*a58d3d2aSXin Li static OPUS_INLINE short MULT16_16_Q13(int a, int b)
596*a58d3d2aSXin Li {
597*a58d3d2aSXin Li opus_int64 res;
598*a58d3d2aSXin Li if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
599*a58d3d2aSXin Li {
600*a58d3d2aSXin Li fprintf (stderr, "MULT16_16_Q13: inputs are not short: %d %d\n", a, b);
601*a58d3d2aSXin Li #ifdef FIXED_DEBUG_ASSERT
602*a58d3d2aSXin Li celt_assert(0);
603*a58d3d2aSXin Li #endif
604*a58d3d2aSXin Li }
605*a58d3d2aSXin Li res = ((opus_int64)a)*b;
606*a58d3d2aSXin Li res >>= 13;
607*a58d3d2aSXin Li if (!VERIFY_SHORT(res))
608*a58d3d2aSXin Li {
609*a58d3d2aSXin Li fprintf (stderr, "MULT16_16_Q13: output is not short: %d*%d=%d\n", a, b, (int)res);
610*a58d3d2aSXin Li #ifdef FIXED_DEBUG_ASSERT
611*a58d3d2aSXin Li celt_assert(0);
612*a58d3d2aSXin Li #endif
613*a58d3d2aSXin Li }
614*a58d3d2aSXin Li celt_mips+=3;
615*a58d3d2aSXin Li return res;
616*a58d3d2aSXin Li }
MULT16_16_Q14(int a,int b)617*a58d3d2aSXin Li static OPUS_INLINE short MULT16_16_Q14(int a, int b)
618*a58d3d2aSXin Li {
619*a58d3d2aSXin Li opus_int64 res;
620*a58d3d2aSXin Li if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
621*a58d3d2aSXin Li {
622*a58d3d2aSXin Li fprintf (stderr, "MULT16_16_Q14: inputs are not short: %d %d\n", a, b);
623*a58d3d2aSXin Li #ifdef FIXED_DEBUG_ASSERT
624*a58d3d2aSXin Li celt_assert(0);
625*a58d3d2aSXin Li #endif
626*a58d3d2aSXin Li }
627*a58d3d2aSXin Li res = ((opus_int64)a)*b;
628*a58d3d2aSXin Li res >>= 14;
629*a58d3d2aSXin Li if (!VERIFY_SHORT(res))
630*a58d3d2aSXin Li {
631*a58d3d2aSXin Li fprintf (stderr, "MULT16_16_Q14: output is not short: %d\n", (int)res);
632*a58d3d2aSXin Li #ifdef FIXED_DEBUG_ASSERT
633*a58d3d2aSXin Li celt_assert(0);
634*a58d3d2aSXin Li #endif
635*a58d3d2aSXin Li }
636*a58d3d2aSXin Li celt_mips+=3;
637*a58d3d2aSXin Li return res;
638*a58d3d2aSXin Li }
639*a58d3d2aSXin Li
640*a58d3d2aSXin Li #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*a58d3d2aSXin Li static OPUS_INLINE short MULT16_16_Q15_(int a, int b, char *file, int line)
642*a58d3d2aSXin Li {
643*a58d3d2aSXin Li opus_int64 res;
644*a58d3d2aSXin Li if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
645*a58d3d2aSXin Li {
646*a58d3d2aSXin Li fprintf (stderr, "MULT16_16_Q15: inputs are not short: %d %d in %s: line %d\n", a, b, file, line);
647*a58d3d2aSXin Li #ifdef FIXED_DEBUG_ASSERT
648*a58d3d2aSXin Li celt_assert(0);
649*a58d3d2aSXin Li #endif
650*a58d3d2aSXin Li }
651*a58d3d2aSXin Li res = ((opus_int64)a)*b;
652*a58d3d2aSXin Li res >>= 15;
653*a58d3d2aSXin Li if (!VERIFY_SHORT(res))
654*a58d3d2aSXin Li {
655*a58d3d2aSXin Li fprintf (stderr, "MULT16_16_Q15: output is not short: %d in %s: line %d\n", (int)res, file, line);
656*a58d3d2aSXin Li #ifdef FIXED_DEBUG_ASSERT
657*a58d3d2aSXin Li celt_assert(0);
658*a58d3d2aSXin Li #endif
659*a58d3d2aSXin Li }
660*a58d3d2aSXin Li celt_mips+=1;
661*a58d3d2aSXin Li return res;
662*a58d3d2aSXin Li }
663*a58d3d2aSXin Li
MULT16_16_P13(int a,int b)664*a58d3d2aSXin Li static OPUS_INLINE short MULT16_16_P13(int a, int b)
665*a58d3d2aSXin Li {
666*a58d3d2aSXin Li opus_int64 res;
667*a58d3d2aSXin Li if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
668*a58d3d2aSXin Li {
669*a58d3d2aSXin Li fprintf (stderr, "MULT16_16_P13: inputs are not short: %d %d\n", a, b);
670*a58d3d2aSXin Li #ifdef FIXED_DEBUG_ASSERT
671*a58d3d2aSXin Li celt_assert(0);
672*a58d3d2aSXin Li #endif
673*a58d3d2aSXin Li }
674*a58d3d2aSXin Li res = ((opus_int64)a)*b;
675*a58d3d2aSXin Li res += 4096;
676*a58d3d2aSXin Li if (!VERIFY_INT(res))
677*a58d3d2aSXin Li {
678*a58d3d2aSXin Li fprintf (stderr, "MULT16_16_P13: overflow: %d*%d=%d\n", a, b, (int)res);
679*a58d3d2aSXin Li #ifdef FIXED_DEBUG_ASSERT
680*a58d3d2aSXin Li celt_assert(0);
681*a58d3d2aSXin Li #endif
682*a58d3d2aSXin Li }
683*a58d3d2aSXin Li res >>= 13;
684*a58d3d2aSXin Li if (!VERIFY_SHORT(res))
685*a58d3d2aSXin Li {
686*a58d3d2aSXin Li fprintf (stderr, "MULT16_16_P13: output is not short: %d*%d=%d\n", a, b, (int)res);
687*a58d3d2aSXin Li #ifdef FIXED_DEBUG_ASSERT
688*a58d3d2aSXin Li celt_assert(0);
689*a58d3d2aSXin Li #endif
690*a58d3d2aSXin Li }
691*a58d3d2aSXin Li celt_mips+=4;
692*a58d3d2aSXin Li return res;
693*a58d3d2aSXin Li }
MULT16_16_P14(int a,int b)694*a58d3d2aSXin Li static OPUS_INLINE short MULT16_16_P14(int a, int b)
695*a58d3d2aSXin Li {
696*a58d3d2aSXin Li opus_int64 res;
697*a58d3d2aSXin Li if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
698*a58d3d2aSXin Li {
699*a58d3d2aSXin Li fprintf (stderr, "MULT16_16_P14: inputs are not short: %d %d\n", a, b);
700*a58d3d2aSXin Li #ifdef FIXED_DEBUG_ASSERT
701*a58d3d2aSXin Li celt_assert(0);
702*a58d3d2aSXin Li #endif
703*a58d3d2aSXin Li }
704*a58d3d2aSXin Li res = ((opus_int64)a)*b;
705*a58d3d2aSXin Li res += 8192;
706*a58d3d2aSXin Li if (!VERIFY_INT(res))
707*a58d3d2aSXin Li {
708*a58d3d2aSXin Li fprintf (stderr, "MULT16_16_P14: overflow: %d*%d=%d\n", a, b, (int)res);
709*a58d3d2aSXin Li #ifdef FIXED_DEBUG_ASSERT
710*a58d3d2aSXin Li celt_assert(0);
711*a58d3d2aSXin Li #endif
712*a58d3d2aSXin Li }
713*a58d3d2aSXin Li res >>= 14;
714*a58d3d2aSXin Li if (!VERIFY_SHORT(res))
715*a58d3d2aSXin Li {
716*a58d3d2aSXin Li fprintf (stderr, "MULT16_16_P14: output is not short: %d*%d=%d\n", a, b, (int)res);
717*a58d3d2aSXin Li #ifdef FIXED_DEBUG_ASSERT
718*a58d3d2aSXin Li celt_assert(0);
719*a58d3d2aSXin Li #endif
720*a58d3d2aSXin Li }
721*a58d3d2aSXin Li celt_mips+=4;
722*a58d3d2aSXin Li return res;
723*a58d3d2aSXin Li }
MULT16_16_P15(int a,int b)724*a58d3d2aSXin Li static OPUS_INLINE short MULT16_16_P15(int a, int b)
725*a58d3d2aSXin Li {
726*a58d3d2aSXin Li opus_int64 res;
727*a58d3d2aSXin Li if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
728*a58d3d2aSXin Li {
729*a58d3d2aSXin Li fprintf (stderr, "MULT16_16_P15: inputs are not short: %d %d\n", a, b);
730*a58d3d2aSXin Li #ifdef FIXED_DEBUG_ASSERT
731*a58d3d2aSXin Li celt_assert(0);
732*a58d3d2aSXin Li #endif
733*a58d3d2aSXin Li }
734*a58d3d2aSXin Li res = ((opus_int64)a)*b;
735*a58d3d2aSXin Li res += 16384;
736*a58d3d2aSXin Li if (!VERIFY_INT(res))
737*a58d3d2aSXin Li {
738*a58d3d2aSXin Li fprintf (stderr, "MULT16_16_P15: overflow: %d*%d=%d\n", a, b, (int)res);
739*a58d3d2aSXin Li #ifdef FIXED_DEBUG_ASSERT
740*a58d3d2aSXin Li celt_assert(0);
741*a58d3d2aSXin Li #endif
742*a58d3d2aSXin Li }
743*a58d3d2aSXin Li res >>= 15;
744*a58d3d2aSXin Li if (!VERIFY_SHORT(res))
745*a58d3d2aSXin Li {
746*a58d3d2aSXin Li fprintf (stderr, "MULT16_16_P15: output is not short: %d*%d=%d\n", a, b, (int)res);
747*a58d3d2aSXin Li #ifdef FIXED_DEBUG_ASSERT
748*a58d3d2aSXin Li celt_assert(0);
749*a58d3d2aSXin Li #endif
750*a58d3d2aSXin Li }
751*a58d3d2aSXin Li celt_mips+=2;
752*a58d3d2aSXin Li return res;
753*a58d3d2aSXin Li }
754*a58d3d2aSXin Li
755*a58d3d2aSXin Li #define DIV32_16(a, b) DIV32_16_(a, b, __FILE__, __LINE__)
756*a58d3d2aSXin Li
DIV32_16_(opus_int64 a,opus_int64 b,char * file,int line)757*a58d3d2aSXin Li static OPUS_INLINE int DIV32_16_(opus_int64 a, opus_int64 b, char *file, int line)
758*a58d3d2aSXin Li {
759*a58d3d2aSXin Li opus_int64 res;
760*a58d3d2aSXin Li if (b==0)
761*a58d3d2aSXin Li {
762*a58d3d2aSXin Li fprintf(stderr, "DIV32_16: divide by zero: %d/%d in %s: line %d\n", (int)a, (int)b, file, line);
763*a58d3d2aSXin Li #ifdef FIXED_DEBUG_ASSERT
764*a58d3d2aSXin Li celt_assert(0);
765*a58d3d2aSXin Li #endif
766*a58d3d2aSXin Li return 0;
767*a58d3d2aSXin Li }
768*a58d3d2aSXin Li if (!VERIFY_INT(a) || !VERIFY_SHORT(b))
769*a58d3d2aSXin Li {
770*a58d3d2aSXin Li fprintf (stderr, "DIV32_16: inputs are not int/short: %d %d in %s: line %d\n", (int)a, (int)b, file, line);
771*a58d3d2aSXin Li #ifdef FIXED_DEBUG_ASSERT
772*a58d3d2aSXin Li celt_assert(0);
773*a58d3d2aSXin Li #endif
774*a58d3d2aSXin Li }
775*a58d3d2aSXin Li res = a/b;
776*a58d3d2aSXin Li if (!VERIFY_SHORT(res))
777*a58d3d2aSXin Li {
778*a58d3d2aSXin Li 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*a58d3d2aSXin Li if (res>32767)
780*a58d3d2aSXin Li res = 32767;
781*a58d3d2aSXin Li if (res<-32768)
782*a58d3d2aSXin Li res = -32768;
783*a58d3d2aSXin Li #ifdef FIXED_DEBUG_ASSERT
784*a58d3d2aSXin Li celt_assert(0);
785*a58d3d2aSXin Li #endif
786*a58d3d2aSXin Li }
787*a58d3d2aSXin Li celt_mips+=35;
788*a58d3d2aSXin Li return res;
789*a58d3d2aSXin Li }
790*a58d3d2aSXin Li
791*a58d3d2aSXin Li #define DIV32(a, b) DIV32_(a, b, __FILE__, __LINE__)
DIV32_(opus_int64 a,opus_int64 b,char * file,int line)792*a58d3d2aSXin Li static OPUS_INLINE int DIV32_(opus_int64 a, opus_int64 b, char *file, int line)
793*a58d3d2aSXin Li {
794*a58d3d2aSXin Li opus_int64 res;
795*a58d3d2aSXin Li if (b==0)
796*a58d3d2aSXin Li {
797*a58d3d2aSXin Li fprintf(stderr, "DIV32: divide by zero: %d/%d in %s: line %d\n", (int)a, (int)b, file, line);
798*a58d3d2aSXin Li #ifdef FIXED_DEBUG_ASSERT
799*a58d3d2aSXin Li celt_assert(0);
800*a58d3d2aSXin Li #endif
801*a58d3d2aSXin Li return 0;
802*a58d3d2aSXin Li }
803*a58d3d2aSXin Li
804*a58d3d2aSXin Li if (!VERIFY_INT(a) || !VERIFY_INT(b))
805*a58d3d2aSXin Li {
806*a58d3d2aSXin Li fprintf (stderr, "DIV32: inputs are not int/short: %d %d in %s: line %d\n", (int)a, (int)b, file, line);
807*a58d3d2aSXin Li #ifdef FIXED_DEBUG_ASSERT
808*a58d3d2aSXin Li celt_assert(0);
809*a58d3d2aSXin Li #endif
810*a58d3d2aSXin Li }
811*a58d3d2aSXin Li res = a/b;
812*a58d3d2aSXin Li if (!VERIFY_INT(res))
813*a58d3d2aSXin Li {
814*a58d3d2aSXin Li fprintf (stderr, "DIV32: output is not int: %d in %s: line %d\n", (int)res, file, line);
815*a58d3d2aSXin Li #ifdef FIXED_DEBUG_ASSERT
816*a58d3d2aSXin Li celt_assert(0);
817*a58d3d2aSXin Li #endif
818*a58d3d2aSXin Li }
819*a58d3d2aSXin Li celt_mips+=70;
820*a58d3d2aSXin Li return res;
821*a58d3d2aSXin Li }
822*a58d3d2aSXin Li
SIG2WORD16_generic(celt_sig x)823*a58d3d2aSXin Li static OPUS_INLINE opus_val16 SIG2WORD16_generic(celt_sig x)
824*a58d3d2aSXin Li {
825*a58d3d2aSXin Li x = PSHR32(x, SIG_SHIFT);
826*a58d3d2aSXin Li x = MAX32(x, -32768);
827*a58d3d2aSXin Li x = MIN32(x, 32767);
828*a58d3d2aSXin Li return EXTRACT16(x);
829*a58d3d2aSXin Li }
830*a58d3d2aSXin Li #define SIG2WORD16(x) (SIG2WORD16_generic(x))
831*a58d3d2aSXin Li
832*a58d3d2aSXin Li
833*a58d3d2aSXin Li #undef PRINT_MIPS
834*a58d3d2aSXin Li #define PRINT_MIPS(file) do {fprintf (file, "total complexity = %llu MIPS\n", (unsigned long long)celt_mips);} while (0);
835*a58d3d2aSXin Li
836*a58d3d2aSXin Li #endif
837