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