annotate src/opus-1.3/celt/fixed_debug.h @ 83:ae30d91d2ffe

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