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 37 #ifdef CELT_C 38 #include "opus_defines.h" 39 OPUS_EXPORT opus_int64 celt_mips=0; 40 #else 41 extern opus_int64 celt_mips; 42 #endif 43 44 #define MULT16_16SU(a,b) ((opus_val32)(opus_val16)(a)*(opus_val32)(opus_uint16)(b)) 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)) 46 47 /** 16x32 multiplication, followed by a 16-bit shift right. Results fits in 32 bits */ 48 #define MULT16_32_Q16(a,b) ADD32(MULT16_16((a),SHR32((b),16)), SHR32(MULT16_16SU((a),((b)&0x0000ffff)),16)) 49 50 #define MULT16_32_P16(a,b) MULT16_32_PX(a,b,16) 51 52 #define QCONST16(x,bits) ((opus_val16)(.5+(x)*(((opus_val32)1)<<(bits)))) 53 #define QCONST32(x,bits) ((opus_val32)(.5+(x)*(((opus_val32)1)<<(bits)))) 54 55 #define VERIFY_SHORT(x) ((x)<=32767&&(x)>=-32768) 56 #define VERIFY_INT(x) ((x)<=2147483647LL&&(x)>=-2147483648LL) 57 #define VERIFY_UINT(x) ((x)<=(2147483647LLU<<1)) 58 59 #define SHR(a,b) SHR32(a,b) 60 #define PSHR(a,b) PSHR32(a,b) 61 62 static inline short NEG16(int x) 63 { 64 int res; 65 if (!VERIFY_SHORT(x)) 66 { 67 fprintf (stderr, "NEG16: input is not short: %d\n", (int)x); 68 #ifdef FIXED_DEBUG_ASSERT 69 celt_assert(0); 70 #endif 71 } 72 res = -x; 73 if (!VERIFY_SHORT(res)) 74 { 75 fprintf (stderr, "NEG16: output is not short: %d\n", (int)res); 76 #ifdef FIXED_DEBUG_ASSERT 77 celt_assert(0); 78 #endif 79 } 80 celt_mips++; 81 return res; 82 } 83 static inline int NEG32(opus_int64 x) 84 { 85 opus_int64 res; 86 if (!VERIFY_INT(x)) 87 { 88 fprintf (stderr, "NEG16: input is not int: %d\n", (int)x); 89 #ifdef FIXED_DEBUG_ASSERT 90 celt_assert(0); 91 #endif 92 } 93 res = -x; 94 if (!VERIFY_INT(res)) 95 { 96 fprintf (stderr, "NEG16: output is not int: %d\n", (int)res); 97 #ifdef FIXED_DEBUG_ASSERT 98 celt_assert(0); 99 #endif 100 } 101 celt_mips+=2; 102 return res; 103 } 104 105 #define EXTRACT16(x) EXTRACT16_(x, __FILE__, __LINE__) 106 static inline short EXTRACT16_(int x, char *file, int line) 107 { 108 int res; 109 if (!VERIFY_SHORT(x)) 110 { 111 fprintf (stderr, "EXTRACT16: input is not short: %d in %s: line %d\n", x, file, line); 112 #ifdef FIXED_DEBUG_ASSERT 113 celt_assert(0); 114 #endif 115 } 116 res = x; 117 celt_mips++; 118 return res; 119 } 120 121 #define EXTEND32(x) EXTEND32_(x, __FILE__, __LINE__) 122 static inline int EXTEND32_(int x, char *file, int line) 123 { 124 int res; 125 if (!VERIFY_SHORT(x)) 126 { 127 fprintf (stderr, "EXTEND32: input is not short: %d in %s: line %d\n", x, file, line); 128 #ifdef FIXED_DEBUG_ASSERT 129 celt_assert(0); 130 #endif 131 } 132 res = x; 133 celt_mips++; 134 return res; 135 } 136 137 #define SHR16(a, shift) SHR16_(a, shift, __FILE__, __LINE__) 138 static inline short SHR16_(int a, int shift, char *file, int line) 139 { 140 int res; 141 if (!VERIFY_SHORT(a) || !VERIFY_SHORT(shift)) 142 { 143 fprintf (stderr, "SHR16: inputs are not short: %d >> %d in %s: line %d\n", a, shift, file, line); 144 #ifdef FIXED_DEBUG_ASSERT 145 celt_assert(0); 146 #endif 147 } 148 res = a>>shift; 149 if (!VERIFY_SHORT(res)) 150 { 151 fprintf (stderr, "SHR16: output is not short: %d in %s: line %d\n", res, file, line); 152 #ifdef FIXED_DEBUG_ASSERT 153 celt_assert(0); 154 #endif 155 } 156 celt_mips++; 157 return res; 158 } 159 #define SHL16(a, shift) SHL16_(a, shift, __FILE__, __LINE__) 160 static inline short SHL16_(int a, int shift, char *file, int line) 161 { 162 int res; 163 if (!VERIFY_SHORT(a) || !VERIFY_SHORT(shift)) 164 { 165 fprintf (stderr, "SHL16: inputs are not short: %d %d in %s: line %d\n", a, shift, file, line); 166 #ifdef FIXED_DEBUG_ASSERT 167 celt_assert(0); 168 #endif 169 } 170 res = a<<shift; 171 if (!VERIFY_SHORT(res)) 172 { 173 fprintf (stderr, "SHL16: output is not short: %d in %s: line %d\n", res, file, line); 174 #ifdef FIXED_DEBUG_ASSERT 175 celt_assert(0); 176 #endif 177 } 178 celt_mips++; 179 return res; 180 } 181 182 static inline int SHR32(opus_int64 a, int shift) 183 { 184 opus_int64 res; 185 if (!VERIFY_INT(a) || !VERIFY_SHORT(shift)) 186 { 187 fprintf (stderr, "SHR32: inputs are not int: %d %d\n", (int)a, shift); 188 #ifdef FIXED_DEBUG_ASSERT 189 celt_assert(0); 190 #endif 191 } 192 res = a>>shift; 193 if (!VERIFY_INT(res)) 194 { 195 fprintf (stderr, "SHR32: output is not int: %d\n", (int)res); 196 #ifdef FIXED_DEBUG_ASSERT 197 celt_assert(0); 198 #endif 199 } 200 celt_mips+=2; 201 return res; 202 } 203 #define SHL32(a, shift) SHL32_(a, shift, __FILE__, __LINE__) 204 static inline int SHL32_(opus_int64 a, int shift, char *file, int line) 205 { 206 opus_int64 res; 207 if (!VERIFY_INT(a) || !VERIFY_SHORT(shift)) 208 { 209 fprintf (stderr, "SHL32: inputs are not int: %lld %d in %s: line %d\n", a, shift, file, line); 210 #ifdef FIXED_DEBUG_ASSERT 211 celt_assert(0); 212 #endif 213 } 214 res = a<<shift; 215 if (!VERIFY_INT(res)) 216 { 217 fprintf (stderr, "SHL32: output is not int: %lld<<%d = %lld in %s: line %d\n", a, shift, res, file, line); 218 #ifdef FIXED_DEBUG_ASSERT 219 celt_assert(0); 220 #endif 221 } 222 celt_mips+=2; 223 return res; 224 } 225 226 #define PSHR32(a,shift) (celt_mips--,SHR32(ADD32((a),(((opus_val32)(1)<<((shift))>>1))),shift)) 227 #define VSHR32(a, shift) (((shift)>0) ? SHR32(a, shift) : SHL32(a, -(shift))) 228 229 #define ROUND16(x,a) (celt_mips--,EXTRACT16(PSHR32((x),(a)))) 230 #define HALF16(x) (SHR16(x,1)) 231 #define HALF32(x) (SHR32(x,1)) 232 233 //#define SHR(a,shift) ((a) >> (shift)) 234 //#define SHL(a,shift) ((a) << (shift)) 235 236 #define ADD16(a, b) ADD16_(a, b, __FILE__, __LINE__) 237 static inline short ADD16_(int a, int b, char *file, int line) 238 { 239 int res; 240 if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b)) 241 { 242 fprintf (stderr, "ADD16: inputs are not short: %d %d in %s: line %d\n", a, b, file, line); 243 #ifdef FIXED_DEBUG_ASSERT 244 celt_assert(0); 245 #endif 246 } 247 res = a+b; 248 if (!VERIFY_SHORT(res)) 249 { 250 fprintf (stderr, "ADD16: output is not short: %d+%d=%d in %s: line %d\n", a,b,res, file, line); 251 #ifdef FIXED_DEBUG_ASSERT 252 celt_assert(0); 253 #endif 254 } 255 celt_mips++; 256 return res; 257 } 258 259 #define SUB16(a, b) SUB16_(a, b, __FILE__, __LINE__) 260 static inline short SUB16_(int a, int b, char *file, int line) 261 { 262 int res; 263 if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b)) 264 { 265 fprintf (stderr, "SUB16: inputs are not short: %d %d in %s: line %d\n", a, b, file, line); 266 #ifdef FIXED_DEBUG_ASSERT 267 celt_assert(0); 268 #endif 269 } 270 res = a-b; 271 if (!VERIFY_SHORT(res)) 272 { 273 fprintf (stderr, "SUB16: output is not short: %d in %s: line %d\n", res, file, line); 274 #ifdef FIXED_DEBUG_ASSERT 275 celt_assert(0); 276 #endif 277 } 278 celt_mips++; 279 return res; 280 } 281 282 #define ADD32(a, b) ADD32_(a, b, __FILE__, __LINE__) 283 static inline int ADD32_(opus_int64 a, opus_int64 b, char *file, int line) 284 { 285 opus_int64 res; 286 if (!VERIFY_INT(a) || !VERIFY_INT(b)) 287 { 288 fprintf (stderr, "ADD32: inputs are not int: %d %d in %s: line %d\n", (int)a, (int)b, file, line); 289 #ifdef FIXED_DEBUG_ASSERT 290 celt_assert(0); 291 #endif 292 } 293 res = a+b; 294 if (!VERIFY_INT(res)) 295 { 296 fprintf (stderr, "ADD32: output is not int: %d in %s: line %d\n", (int)res, file, line); 297 #ifdef FIXED_DEBUG_ASSERT 298 celt_assert(0); 299 #endif 300 } 301 celt_mips+=2; 302 return res; 303 } 304 305 #define SUB32(a, b) SUB32_(a, b, __FILE__, __LINE__) 306 static inline int SUB32_(opus_int64 a, opus_int64 b, char *file, int line) 307 { 308 opus_int64 res; 309 if (!VERIFY_INT(a) || !VERIFY_INT(b)) 310 { 311 fprintf (stderr, "SUB32: inputs are not int: %d %d in %s: line %d\n", (int)a, (int)b, file, line); 312 #ifdef FIXED_DEBUG_ASSERT 313 celt_assert(0); 314 #endif 315 } 316 res = a-b; 317 if (!VERIFY_INT(res)) 318 { 319 fprintf (stderr, "SUB32: output is not int: %d in %s: line %d\n", (int)res, file, line); 320 #ifdef FIXED_DEBUG_ASSERT 321 celt_assert(0); 322 #endif 323 } 324 celt_mips+=2; 325 return res; 326 } 327 328 #undef UADD32 329 #define UADD32(a, b) UADD32_(a, b, __FILE__, __LINE__) 330 static inline unsigned int UADD32_(opus_uint64 a, opus_uint64 b, char *file, int line) 331 { 332 opus_uint64 res; 333 if (!VERIFY_UINT(a) || !VERIFY_UINT(b)) 334 { 335 fprintf (stderr, "UADD32: inputs are not uint32: %llu %llu in %s: line %d\n", a, b, file, line); 336 #ifdef FIXED_DEBUG_ASSERT 337 celt_assert(0); 338 #endif 339 } 340 res = a+b; 341 if (!VERIFY_UINT(res)) 342 { 343 fprintf (stderr, "UADD32: output is not uint32: %llu in %s: line %d\n", res, file, line); 344 #ifdef FIXED_DEBUG_ASSERT 345 celt_assert(0); 346 #endif 347 } 348 celt_mips+=2; 349 return res; 350 } 351 352 #undef USUB32 353 #define USUB32(a, b) USUB32_(a, b, __FILE__, __LINE__) 354 static inline unsigned int USUB32_(opus_uint64 a, opus_uint64 b, char *file, int line) 355 { 356 opus_uint64 res; 357 if (!VERIFY_UINT(a) || !VERIFY_UINT(b)) 358 { 359 fprintf (stderr, "USUB32: inputs are not uint32: %llu %llu in %s: line %d\n", a, b, file, line); 360 #ifdef FIXED_DEBUG_ASSERT 361 celt_assert(0); 362 #endif 363 } 364 if (a<b) 365 { 366 fprintf (stderr, "USUB32: inputs underflow: %llu < %llu in %s: line %d\n", a, b, file, line); 367 #ifdef FIXED_DEBUG_ASSERT 368 celt_assert(0); 369 #endif 370 } 371 res = a-b; 372 if (!VERIFY_UINT(res)) 373 { 374 fprintf (stderr, "USUB32: output is not uint32: %llu - %llu = %llu in %s: line %d\n", a, b, res, file, line); 375 #ifdef FIXED_DEBUG_ASSERT 376 celt_assert(0); 377 #endif 378 } 379 celt_mips+=2; 380 return res; 381 } 382 383 /* result fits in 16 bits */ 384 static inline short MULT16_16_16(int a, int b) 385 { 386 int res; 387 if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b)) 388 { 389 fprintf (stderr, "MULT16_16_16: inputs are not short: %d %d\n", a, b); 390 #ifdef FIXED_DEBUG_ASSERT 391 celt_assert(0); 392 #endif 393 } 394 res = a*b; 395 if (!VERIFY_SHORT(res)) 396 { 397 fprintf (stderr, "MULT16_16_16: output is not short: %d\n", res); 398 #ifdef FIXED_DEBUG_ASSERT 399 celt_assert(0); 400 #endif 401 } 402 celt_mips++; 403 return res; 404 } 405 406 #define MULT16_16(a, b) MULT16_16_(a, b, __FILE__, __LINE__) 407 static inline int MULT16_16_(int a, int b, char *file, int line) 408 { 409 opus_int64 res; 410 if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b)) 411 { 412 fprintf (stderr, "MULT16_16: inputs are not short: %d %d in %s: line %d\n", a, b, file, line); 413 #ifdef FIXED_DEBUG_ASSERT 414 celt_assert(0); 415 #endif 416 } 417 res = ((opus_int64)a)*b; 418 if (!VERIFY_INT(res)) 419 { 420 fprintf (stderr, "MULT16_16: output is not int: %d in %s: line %d\n", (int)res, file, line); 421 #ifdef FIXED_DEBUG_ASSERT 422 celt_assert(0); 423 #endif 424 } 425 celt_mips++; 426 return res; 427 } 428 429 #define MAC16_16(c,a,b) (celt_mips-=2,ADD32((c),MULT16_16((a),(b)))) 430 431 #define MULT16_32_QX(a, b, Q) MULT16_32_QX_(a, b, Q, __FILE__, __LINE__) 432 static inline int MULT16_32_QX_(int a, opus_int64 b, int Q, char *file, int line) 433 { 434 opus_int64 res; 435 if (!VERIFY_SHORT(a) || !VERIFY_INT(b)) 436 { 437 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); 438 #ifdef FIXED_DEBUG_ASSERT 439 celt_assert(0); 440 #endif 441 } 442 if (ABS32(b)>=((opus_val32)(1)<<(15+Q))) 443 { 444 fprintf (stderr, "MULT16_32_Q%d: second operand too large: %d %d in %s: line %d\n", Q, (int)a, (int)b, file, line); 445 #ifdef FIXED_DEBUG_ASSERT 446 celt_assert(0); 447 #endif 448 } 449 res = (((opus_int64)a)*(opus_int64)b) >> Q; 450 if (!VERIFY_INT(res)) 451 { 452 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); 453 #ifdef FIXED_DEBUG_ASSERT 454 celt_assert(0); 455 #endif 456 } 457 if (Q==15) 458 celt_mips+=3; 459 else 460 celt_mips+=4; 461 return res; 462 } 463 464 #define MULT16_32_PX(a, b, Q) MULT16_32_PX_(a, b, Q, __FILE__, __LINE__) 465 static inline int MULT16_32_PX_(int a, opus_int64 b, int Q, char *file, int line) 466 { 467 opus_int64 res; 468 if (!VERIFY_SHORT(a) || !VERIFY_INT(b)) 469 { 470 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); 471 #ifdef FIXED_DEBUG_ASSERT 472 celt_assert(0); 473 #endif 474 } 475 if (ABS32(b)>=((opus_int64)(1)<<(15+Q))) 476 { 477 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); 478 #ifdef FIXED_DEBUG_ASSERT 479 celt_assert(0); 480 #endif 481 } 482 res = ((((opus_int64)a)*(opus_int64)b) + (((opus_val32)(1)<<Q)>>1))>> Q; 483 if (!VERIFY_INT(res)) 484 { 485 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); 486 #ifdef FIXED_DEBUG_ASSERT 487 celt_assert(0); 488 #endif 489 } 490 if (Q==15) 491 celt_mips+=4; 492 else 493 celt_mips+=5; 494 return res; 495 } 496 497 #define MULT16_32_Q15(a,b) MULT16_32_QX(a,b,15) 498 #define MAC16_32_Q15(c,a,b) (celt_mips-=2,ADD32((c),MULT16_32_Q15((a),(b)))) 499 500 static inline int SATURATE(int a, int b) 501 { 502 if (a>b) 503 a=b; 504 if (a<-b) 505 a = -b; 506 celt_mips+=3; 507 return a; 508 } 509 510 static inline int MULT16_16_Q11_32(int a, int b) 511 { 512 opus_int64 res; 513 if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b)) 514 { 515 fprintf (stderr, "MULT16_16_Q11: inputs are not short: %d %d\n", a, b); 516 #ifdef FIXED_DEBUG_ASSERT 517 celt_assert(0); 518 #endif 519 } 520 res = ((opus_int64)a)*b; 521 res >>= 11; 522 if (!VERIFY_INT(res)) 523 { 524 fprintf (stderr, "MULT16_16_Q11: output is not short: %d*%d=%d\n", (int)a, (int)b, (int)res); 525 #ifdef FIXED_DEBUG_ASSERT 526 celt_assert(0); 527 #endif 528 } 529 celt_mips+=3; 530 return res; 531 } 532 static inline short MULT16_16_Q13(int a, int b) 533 { 534 opus_int64 res; 535 if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b)) 536 { 537 fprintf (stderr, "MULT16_16_Q13: inputs are not short: %d %d\n", a, b); 538 #ifdef FIXED_DEBUG_ASSERT 539 celt_assert(0); 540 #endif 541 } 542 res = ((opus_int64)a)*b; 543 res >>= 13; 544 if (!VERIFY_SHORT(res)) 545 { 546 fprintf (stderr, "MULT16_16_Q13: output is not short: %d*%d=%d\n", a, b, (int)res); 547 #ifdef FIXED_DEBUG_ASSERT 548 celt_assert(0); 549 #endif 550 } 551 celt_mips+=3; 552 return res; 553 } 554 static inline short MULT16_16_Q14(int a, int b) 555 { 556 opus_int64 res; 557 if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b)) 558 { 559 fprintf (stderr, "MULT16_16_Q14: inputs are not short: %d %d\n", a, b); 560 #ifdef FIXED_DEBUG_ASSERT 561 celt_assert(0); 562 #endif 563 } 564 res = ((opus_int64)a)*b; 565 res >>= 14; 566 if (!VERIFY_SHORT(res)) 567 { 568 fprintf (stderr, "MULT16_16_Q14: output is not short: %d\n", (int)res); 569 #ifdef FIXED_DEBUG_ASSERT 570 celt_assert(0); 571 #endif 572 } 573 celt_mips+=3; 574 return res; 575 } 576 577 #define MULT16_16_Q15(a, b) MULT16_16_Q15_(a, b, __FILE__, __LINE__) 578 static inline short MULT16_16_Q15_(int a, int b, char *file, int line) 579 { 580 opus_int64 res; 581 if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b)) 582 { 583 fprintf (stderr, "MULT16_16_Q15: inputs are not short: %d %d in %s: line %d\n", a, b, file, line); 584 #ifdef FIXED_DEBUG_ASSERT 585 celt_assert(0); 586 #endif 587 } 588 res = ((opus_int64)a)*b; 589 res >>= 15; 590 if (!VERIFY_SHORT(res)) 591 { 592 fprintf (stderr, "MULT16_16_Q15: output is not short: %d in %s: line %d\n", (int)res, file, line); 593 #ifdef FIXED_DEBUG_ASSERT 594 celt_assert(0); 595 #endif 596 } 597 celt_mips+=1; 598 return res; 599 } 600 601 static inline short MULT16_16_P13(int a, int b) 602 { 603 opus_int64 res; 604 if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b)) 605 { 606 fprintf (stderr, "MULT16_16_P13: inputs are not short: %d %d\n", a, b); 607 #ifdef FIXED_DEBUG_ASSERT 608 celt_assert(0); 609 #endif 610 } 611 res = ((opus_int64)a)*b; 612 res += 4096; 613 if (!VERIFY_INT(res)) 614 { 615 fprintf (stderr, "MULT16_16_P13: overflow: %d*%d=%d\n", a, b, (int)res); 616 #ifdef FIXED_DEBUG_ASSERT 617 celt_assert(0); 618 #endif 619 } 620 res >>= 13; 621 if (!VERIFY_SHORT(res)) 622 { 623 fprintf (stderr, "MULT16_16_P13: output is not short: %d*%d=%d\n", a, b, (int)res); 624 #ifdef FIXED_DEBUG_ASSERT 625 celt_assert(0); 626 #endif 627 } 628 celt_mips+=4; 629 return res; 630 } 631 static inline short MULT16_16_P14(int a, int b) 632 { 633 opus_int64 res; 634 if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b)) 635 { 636 fprintf (stderr, "MULT16_16_P14: inputs are not short: %d %d\n", a, b); 637 #ifdef FIXED_DEBUG_ASSERT 638 celt_assert(0); 639 #endif 640 } 641 res = ((opus_int64)a)*b; 642 res += 8192; 643 if (!VERIFY_INT(res)) 644 { 645 fprintf (stderr, "MULT16_16_P14: overflow: %d*%d=%d\n", a, b, (int)res); 646 #ifdef FIXED_DEBUG_ASSERT 647 celt_assert(0); 648 #endif 649 } 650 res >>= 14; 651 if (!VERIFY_SHORT(res)) 652 { 653 fprintf (stderr, "MULT16_16_P14: output is not short: %d*%d=%d\n", a, b, (int)res); 654 #ifdef FIXED_DEBUG_ASSERT 655 celt_assert(0); 656 #endif 657 } 658 celt_mips+=4; 659 return res; 660 } 661 static inline short MULT16_16_P15(int a, int b) 662 { 663 opus_int64 res; 664 if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b)) 665 { 666 fprintf (stderr, "MULT16_16_P15: inputs are not short: %d %d\n", a, b); 667 #ifdef FIXED_DEBUG_ASSERT 668 celt_assert(0); 669 #endif 670 } 671 res = ((opus_int64)a)*b; 672 res += 16384; 673 if (!VERIFY_INT(res)) 674 { 675 fprintf (stderr, "MULT16_16_P15: overflow: %d*%d=%d\n", a, b, (int)res); 676 #ifdef FIXED_DEBUG_ASSERT 677 celt_assert(0); 678 #endif 679 } 680 res >>= 15; 681 if (!VERIFY_SHORT(res)) 682 { 683 fprintf (stderr, "MULT16_16_P15: output is not short: %d*%d=%d\n", a, b, (int)res); 684 #ifdef FIXED_DEBUG_ASSERT 685 celt_assert(0); 686 #endif 687 } 688 celt_mips+=2; 689 return res; 690 } 691 692 #define DIV32_16(a, b) DIV32_16_(a, b, __FILE__, __LINE__) 693 694 static inline int DIV32_16_(opus_int64 a, opus_int64 b, char *file, int line) 695 { 696 opus_int64 res; 697 if (b==0) 698 { 699 fprintf(stderr, "DIV32_16: divide by zero: %d/%d in %s: line %d\n", (int)a, (int)b, file, line); 700 #ifdef FIXED_DEBUG_ASSERT 701 celt_assert(0); 702 #endif 703 return 0; 704 } 705 if (!VERIFY_INT(a) || !VERIFY_SHORT(b)) 706 { 707 fprintf (stderr, "DIV32_16: inputs are not int/short: %d %d in %s: line %d\n", (int)a, (int)b, file, line); 708 #ifdef FIXED_DEBUG_ASSERT 709 celt_assert(0); 710 #endif 711 } 712 res = a/b; 713 if (!VERIFY_SHORT(res)) 714 { 715 fprintf (stderr, "DIV32_16: output is not short: %d / %d = %d in %s: line %d\n", (int)a,(int)b,(int)res, file, line); 716 if (res>32767) 717 res = 32767; 718 if (res<-32768) 719 res = -32768; 720 #ifdef FIXED_DEBUG_ASSERT 721 celt_assert(0); 722 #endif 723 } 724 celt_mips+=35; 725 return res; 726 } 727 728 #define DIV32(a, b) DIV32_(a, b, __FILE__, __LINE__) 729 static inline int DIV32_(opus_int64 a, opus_int64 b, char *file, int line) 730 { 731 opus_int64 res; 732 if (b==0) 733 { 734 fprintf(stderr, "DIV32: divide by zero: %d/%d in %s: line %d\n", (int)a, (int)b, file, line); 735 #ifdef FIXED_DEBUG_ASSERT 736 celt_assert(0); 737 #endif 738 return 0; 739 } 740 741 if (!VERIFY_INT(a) || !VERIFY_INT(b)) 742 { 743 fprintf (stderr, "DIV32: inputs are not int/short: %d %d in %s: line %d\n", (int)a, (int)b, file, line); 744 #ifdef FIXED_DEBUG_ASSERT 745 celt_assert(0); 746 #endif 747 } 748 res = a/b; 749 if (!VERIFY_INT(res)) 750 { 751 fprintf (stderr, "DIV32: output is not int: %d in %s: line %d\n", (int)res, file, line); 752 #ifdef FIXED_DEBUG_ASSERT 753 celt_assert(0); 754 #endif 755 } 756 celt_mips+=70; 757 return res; 758 } 759 760 #undef PRINT_MIPS 761 #define PRINT_MIPS(file) do {fprintf (file, "total complexity = %llu MIPS\n", celt_mips);} while (0); 762 763 #endif 764