fixed_debug.h 20 KB

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