1
/* Copyright (C) 2003 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 spx_mips;
41
#define MIPS_INC spx_mips++,
43
#define VERIFY_SHORT(x) ((x)<=32767&&(x)>=-32768)
44
#define VERIFY_INT(x) ((x)<=2147483647LL&&(x)>=-2147483648LL)
46
#define SHR(a,shift) ((a) >> (shift))
47
#define SHL(a,shift) ((a) << (shift))
49
static inline short ADD16(int a, int b)
52
if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
54
fprintf (stderr, "ADD16: inputs are not short: %d %d\n", a, b);
57
if (!VERIFY_SHORT(res))
58
fprintf (stderr, "ADD16: output is not short: %d\n", res);
62
static inline short SUB16(int a, int b)
65
if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
67
fprintf (stderr, "SUB16: inputs are not short: %d %d\n", a, b);
70
if (!VERIFY_SHORT(res))
71
fprintf (stderr, "SUB16: output is not short: %d\n", res);
76
static inline int ADD32(long long a, long long b)
79
if (!VERIFY_INT(a) || !VERIFY_INT(b))
81
fprintf (stderr, "ADD32: inputs are not int: %d %d\n", (int)a, (int)b);
85
fprintf (stderr, "ADD32: output is not int: %d\n", (int)res);
90
static inline int SUB32(long long a, long long b)
93
if (!VERIFY_INT(a) || !VERIFY_INT(b))
95
fprintf (stderr, "SUB32: inputs are not int: %d %d\n", (int)a, (int)b);
99
fprintf (stderr, "SUB32: output is not int: %d\n", (int)res);
104
#define ADD64(a,b) (MIPS_INC(a)+(b))
106
#define PSHR(a,shift) (SHR((a)+(1<<((shift)-1)),shift))
108
/* result fits in 16 bits */
109
static inline short MULT16_16_16(int a, int b)
112
if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
114
fprintf (stderr, "MULT16_16_16: inputs are not short: %d %d\n", a, b);
117
if (!VERIFY_SHORT(res))
118
fprintf (stderr, "MULT16_16_16: output is not short: %d\n", res);
123
static inline int MULT16_16(int a, int b)
126
if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
128
fprintf (stderr, "MULT16_16: inputs are not short: %d %d\n", a, b);
130
res = ((long long)a)*b;
131
if (!VERIFY_INT(res))
132
fprintf (stderr, "MULT16_16: output is not int: %d\n", (int)res);
136
#define MULT16_16B(a,b) (((short)(a))*((short)(b)))
138
#define MAC16_16(c,a,b) (ADD32((c),MULT16_16((a),(b))))
139
#define MAC16_16_Q11(c,a,b) (ADD32((c),SHR(MULT16_16((a),(b)),11)))
141
#define MULT16_32_Q12(a,b) ADD32(MULT16_16((a),SHR((b),12)), SHR(MULT16_16((a),((b)&0x00000fff)),12))
142
#define MULT16_32_Q13(a,b) ADD32(MULT16_16((a),SHR((b),13)), SHR(MULT16_16((a),((b)&0x00001fff)),13))
143
#define MULT16_32_Q14(a,b) ADD32(MULT16_16((a),SHR((b),14)), SHR(MULT16_16((a),((b)&0x00003fff)),14))
145
#define MULT16_32_Q11(a,b) ADD32(MULT16_16((a),SHR((b),11)), SHR(MULT16_16((a),((b)&0x000007ff)),11))
146
#define MAC16_32_Q11(c,a,b) ADD32(c,ADD32(MULT16_16((a),SHR((b),11)), SHR(MULT16_16((a),((b)&0x000007ff)),11)))
148
#define MULT16_32_Q15(a,b) ADD32(MULT16_16((a),SHR((b),15)), SHR(MULT16_16((a),((b)&0x00007fff)),15))
149
#define MAC16_32_Q15(c,a,b) ADD32(c,ADD32(MULT16_16((a),SHR((b),15)), SHR(MULT16_16((a),((b)&0x00007fff)),15)))
151
static inline int SATURATE(int a, int b)
160
static inline short MULT16_16_Q11(int a, int b)
163
if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
165
fprintf (stderr, "MULT16_16_Q11: inputs are not short: %d %d\n", a, b);
167
res = ((long long)a)*b;
169
if (!VERIFY_SHORT(res))
170
fprintf (stderr, "MULT16_16_Q11: output is not short: %d*%d=%d\n", (int)a, (int)b, (int)res);
174
static inline short MULT16_16_Q13(int a, int b)
177
if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
179
fprintf (stderr, "MULT16_16_Q13: inputs are not short: %d %d\n", a, b);
181
res = ((long long)a)*b;
183
if (!VERIFY_SHORT(res))
184
fprintf (stderr, "MULT16_16_Q13: output is not short: %d*%d=%d\n", a, b, (int)res);
188
static inline short MULT16_16_Q14(int a, int b)
191
if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
193
fprintf (stderr, "MULT16_16_Q14: inputs are not short: %d %d\n", a, b);
195
res = ((long long)a)*b;
197
if (!VERIFY_SHORT(res))
198
fprintf (stderr, "MULT16_16_Q14: output is not short: %d\n", (int)res);
202
static inline short MULT16_16_Q15(int a, int b)
205
if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
207
fprintf (stderr, "MULT16_16_Q15: inputs are not short: %d %d\n", a, b);
209
res = ((long long)a)*b;
211
if (!VERIFY_SHORT(res))
212
fprintf (stderr, "MULT16_16_Q15: output is not short: %d\n", (int)res);
217
static inline short MULT16_16_P13(int a, int b)
220
if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
222
fprintf (stderr, "MULT16_16_P13: inputs are not short: %d %d\n", a, b);
224
res = ((long long)a)*b;
226
if (!VERIFY_INT(res))
227
fprintf (stderr, "MULT16_16_P13: overflow: %d*%d=%d\n", a, b, (int)res);
229
if (!VERIFY_SHORT(res))
230
fprintf (stderr, "MULT16_16_P13: output is not short: %d*%d=%d\n", a, b, (int)res);
234
static inline short MULT16_16_P14(int a, int b)
237
if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
239
fprintf (stderr, "MULT16_16_P14: inputs are not short: %d %d\n", a, b);
241
res = ((long long)a)*b;
243
if (!VERIFY_INT(res))
244
fprintf (stderr, "MULT16_16_P14: overflow: %d*%d=%d\n", a, b, (int)res);
246
if (!VERIFY_SHORT(res))
247
fprintf (stderr, "MULT16_16_P14: output is not short: %d*%d=%d\n", a, b, (int)res);
251
static inline short MULT16_16_P15(int a, int b)
254
if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
256
fprintf (stderr, "MULT16_16_P15: inputs are not short: %d %d\n", a, b);
258
res = ((long long)a)*b;
260
if (!VERIFY_INT(res))
261
fprintf (stderr, "MULT16_16_P15: overflow: %d*%d=%d\n", a, b, (int)res);
263
if (!VERIFY_SHORT(res))
264
fprintf (stderr, "MULT16_16_P15: output is not short: %d*%d=%d\n", a, b, (int)res);
269
#define MUL_16_32_R15(a,bh,bl) ADD32(MULT16_16((a),(bh)), SHR(MULT16_16((a),(bl)),15))
272
static inline int DIV32_16(long long a, long long b)
277
fprintf(stderr, "DIV32_16: divide by zero: %d/%d\n", (int)a, (int)b);
280
if (!VERIFY_INT(a) || !VERIFY_SHORT(b))
282
fprintf (stderr, "DIV32_16: inputs are not int/short: %d %d\n", (int)a, (int)b);
285
if (!VERIFY_SHORT(res))
287
fprintf (stderr, "DIV32_16: output is not short: %d / %d = %d\n", (int)a,(int)b,(int)res);
296
static inline int DIV32(long long a, long long b)
301
fprintf(stderr, "DIV32: divide by zero: %d/%d\n", (int)a, (int)b);
305
if (!VERIFY_INT(a) || !VERIFY_INT(b))
307
fprintf (stderr, "DIV32: inputs are not int/short: %d %d\n", (int)a, (int)b);
310
if (!VERIFY_INT(res))
311
fprintf (stderr, "DIV32: output is not int: %d\n", (int)res);