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