fixed_debug.h 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785
  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. #include "opus_defines.h"
  32. #ifdef CELT_C
  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 OPUS_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 OPUS_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 OPUS_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 OPUS_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 OPUS_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 OPUS_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 OPUS_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 OPUS_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 OPUS_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 OPUS_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 OPUS_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 OPUS_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 OPUS_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 OPUS_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 OPUS_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 OPUS_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 OPUS_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 OPUS_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. #define MAC16_32_Q16(c,a,b) (celt_mips-=2,ADD32((c),MULT16_32_Q16((a),(b))))
  468. static OPUS_INLINE int SATURATE(int a, int b)
  469. {
  470. if (a>b)
  471. a=b;
  472. if (a<-b)
  473. a = -b;
  474. celt_mips+=3;
  475. return a;
  476. }
  477. static OPUS_INLINE opus_int16 SATURATE16(opus_int32 a)
  478. {
  479. celt_mips+=3;
  480. if (a>32767)
  481. return 32767;
  482. else if (a<-32768)
  483. return -32768;
  484. else return a;
  485. }
  486. static OPUS_INLINE int MULT16_16_Q11_32(int a, int b)
  487. {
  488. opus_int64 res;
  489. if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
  490. {
  491. fprintf (stderr, "MULT16_16_Q11: inputs are not short: %d %d\n", a, b);
  492. #ifdef FIXED_DEBUG_ASSERT
  493. celt_assert(0);
  494. #endif
  495. }
  496. res = ((opus_int64)a)*b;
  497. res >>= 11;
  498. if (!VERIFY_INT(res))
  499. {
  500. fprintf (stderr, "MULT16_16_Q11: output is not short: %d*%d=%d\n", (int)a, (int)b, (int)res);
  501. #ifdef FIXED_DEBUG_ASSERT
  502. celt_assert(0);
  503. #endif
  504. }
  505. celt_mips+=3;
  506. return res;
  507. }
  508. static OPUS_INLINE short MULT16_16_Q13(int a, int b)
  509. {
  510. opus_int64 res;
  511. if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
  512. {
  513. fprintf (stderr, "MULT16_16_Q13: inputs are not short: %d %d\n", a, b);
  514. #ifdef FIXED_DEBUG_ASSERT
  515. celt_assert(0);
  516. #endif
  517. }
  518. res = ((opus_int64)a)*b;
  519. res >>= 13;
  520. if (!VERIFY_SHORT(res))
  521. {
  522. fprintf (stderr, "MULT16_16_Q13: output is not short: %d*%d=%d\n", a, b, (int)res);
  523. #ifdef FIXED_DEBUG_ASSERT
  524. celt_assert(0);
  525. #endif
  526. }
  527. celt_mips+=3;
  528. return res;
  529. }
  530. static OPUS_INLINE short MULT16_16_Q14(int a, int b)
  531. {
  532. opus_int64 res;
  533. if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
  534. {
  535. fprintf (stderr, "MULT16_16_Q14: inputs are not short: %d %d\n", a, b);
  536. #ifdef FIXED_DEBUG_ASSERT
  537. celt_assert(0);
  538. #endif
  539. }
  540. res = ((opus_int64)a)*b;
  541. res >>= 14;
  542. if (!VERIFY_SHORT(res))
  543. {
  544. fprintf (stderr, "MULT16_16_Q14: output is not short: %d\n", (int)res);
  545. #ifdef FIXED_DEBUG_ASSERT
  546. celt_assert(0);
  547. #endif
  548. }
  549. celt_mips+=3;
  550. return res;
  551. }
  552. #define MULT16_16_Q15(a, b) MULT16_16_Q15_(a, b, __FILE__, __LINE__)
  553. static OPUS_INLINE short MULT16_16_Q15_(int a, int b, char *file, int line)
  554. {
  555. opus_int64 res;
  556. if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
  557. {
  558. fprintf (stderr, "MULT16_16_Q15: inputs are not short: %d %d in %s: line %d\n", a, b, file, line);
  559. #ifdef FIXED_DEBUG_ASSERT
  560. celt_assert(0);
  561. #endif
  562. }
  563. res = ((opus_int64)a)*b;
  564. res >>= 15;
  565. if (!VERIFY_SHORT(res))
  566. {
  567. fprintf (stderr, "MULT16_16_Q15: output is not short: %d in %s: line %d\n", (int)res, file, line);
  568. #ifdef FIXED_DEBUG_ASSERT
  569. celt_assert(0);
  570. #endif
  571. }
  572. celt_mips+=1;
  573. return res;
  574. }
  575. static OPUS_INLINE short MULT16_16_P13(int a, int b)
  576. {
  577. opus_int64 res;
  578. if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
  579. {
  580. fprintf (stderr, "MULT16_16_P13: inputs are not short: %d %d\n", a, b);
  581. #ifdef FIXED_DEBUG_ASSERT
  582. celt_assert(0);
  583. #endif
  584. }
  585. res = ((opus_int64)a)*b;
  586. res += 4096;
  587. if (!VERIFY_INT(res))
  588. {
  589. fprintf (stderr, "MULT16_16_P13: overflow: %d*%d=%d\n", a, b, (int)res);
  590. #ifdef FIXED_DEBUG_ASSERT
  591. celt_assert(0);
  592. #endif
  593. }
  594. res >>= 13;
  595. if (!VERIFY_SHORT(res))
  596. {
  597. fprintf (stderr, "MULT16_16_P13: output is not short: %d*%d=%d\n", a, b, (int)res);
  598. #ifdef FIXED_DEBUG_ASSERT
  599. celt_assert(0);
  600. #endif
  601. }
  602. celt_mips+=4;
  603. return res;
  604. }
  605. static OPUS_INLINE short MULT16_16_P14(int a, int b)
  606. {
  607. opus_int64 res;
  608. if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
  609. {
  610. fprintf (stderr, "MULT16_16_P14: inputs are not short: %d %d\n", a, b);
  611. #ifdef FIXED_DEBUG_ASSERT
  612. celt_assert(0);
  613. #endif
  614. }
  615. res = ((opus_int64)a)*b;
  616. res += 8192;
  617. if (!VERIFY_INT(res))
  618. {
  619. fprintf (stderr, "MULT16_16_P14: overflow: %d*%d=%d\n", a, b, (int)res);
  620. #ifdef FIXED_DEBUG_ASSERT
  621. celt_assert(0);
  622. #endif
  623. }
  624. res >>= 14;
  625. if (!VERIFY_SHORT(res))
  626. {
  627. fprintf (stderr, "MULT16_16_P14: output is not short: %d*%d=%d\n", a, b, (int)res);
  628. #ifdef FIXED_DEBUG_ASSERT
  629. celt_assert(0);
  630. #endif
  631. }
  632. celt_mips+=4;
  633. return res;
  634. }
  635. static OPUS_INLINE short MULT16_16_P15(int a, int b)
  636. {
  637. opus_int64 res;
  638. if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
  639. {
  640. fprintf (stderr, "MULT16_16_P15: inputs are not short: %d %d\n", a, b);
  641. #ifdef FIXED_DEBUG_ASSERT
  642. celt_assert(0);
  643. #endif
  644. }
  645. res = ((opus_int64)a)*b;
  646. res += 16384;
  647. if (!VERIFY_INT(res))
  648. {
  649. fprintf (stderr, "MULT16_16_P15: overflow: %d*%d=%d\n", a, b, (int)res);
  650. #ifdef FIXED_DEBUG_ASSERT
  651. celt_assert(0);
  652. #endif
  653. }
  654. res >>= 15;
  655. if (!VERIFY_SHORT(res))
  656. {
  657. fprintf (stderr, "MULT16_16_P15: output is not short: %d*%d=%d\n", a, b, (int)res);
  658. #ifdef FIXED_DEBUG_ASSERT
  659. celt_assert(0);
  660. #endif
  661. }
  662. celt_mips+=2;
  663. return res;
  664. }
  665. #define DIV32_16(a, b) DIV32_16_(a, b, __FILE__, __LINE__)
  666. static OPUS_INLINE int DIV32_16_(opus_int64 a, opus_int64 b, char *file, int line)
  667. {
  668. opus_int64 res;
  669. if (b==0)
  670. {
  671. fprintf(stderr, "DIV32_16: divide by zero: %d/%d in %s: line %d\n", (int)a, (int)b, file, line);
  672. #ifdef FIXED_DEBUG_ASSERT
  673. celt_assert(0);
  674. #endif
  675. return 0;
  676. }
  677. if (!VERIFY_INT(a) || !VERIFY_SHORT(b))
  678. {
  679. fprintf (stderr, "DIV32_16: inputs are not int/short: %d %d in %s: line %d\n", (int)a, (int)b, file, line);
  680. #ifdef FIXED_DEBUG_ASSERT
  681. celt_assert(0);
  682. #endif
  683. }
  684. res = a/b;
  685. if (!VERIFY_SHORT(res))
  686. {
  687. fprintf (stderr, "DIV32_16: output is not short: %d / %d = %d in %s: line %d\n", (int)a,(int)b,(int)res, file, line);
  688. if (res>32767)
  689. res = 32767;
  690. if (res<-32768)
  691. res = -32768;
  692. #ifdef FIXED_DEBUG_ASSERT
  693. celt_assert(0);
  694. #endif
  695. }
  696. celt_mips+=35;
  697. return res;
  698. }
  699. #define DIV32(a, b) DIV32_(a, b, __FILE__, __LINE__)
  700. static OPUS_INLINE int DIV32_(opus_int64 a, opus_int64 b, char *file, int line)
  701. {
  702. opus_int64 res;
  703. if (b==0)
  704. {
  705. fprintf(stderr, "DIV32: divide by zero: %d/%d in %s: line %d\n", (int)a, (int)b, file, line);
  706. #ifdef FIXED_DEBUG_ASSERT
  707. celt_assert(0);
  708. #endif
  709. return 0;
  710. }
  711. if (!VERIFY_INT(a) || !VERIFY_INT(b))
  712. {
  713. fprintf (stderr, "DIV32: inputs are not int/short: %d %d in %s: line %d\n", (int)a, (int)b, file, line);
  714. #ifdef FIXED_DEBUG_ASSERT
  715. celt_assert(0);
  716. #endif
  717. }
  718. res = a/b;
  719. if (!VERIFY_INT(res))
  720. {
  721. fprintf (stderr, "DIV32: output is not int: %d in %s: line %d\n", (int)res, file, line);
  722. #ifdef FIXED_DEBUG_ASSERT
  723. celt_assert(0);
  724. #endif
  725. }
  726. celt_mips+=70;
  727. return res;
  728. }
  729. static OPUS_INLINE opus_val16 SIG2WORD16_generic(celt_sig x)
  730. {
  731. x = PSHR32(x, SIG_SHIFT);
  732. x = MAX32(x, -32768);
  733. x = MIN32(x, 32767);
  734. return EXTRACT16(x);
  735. }
  736. #define SIG2WORD16(x) (SIG2WORD16_generic(x))
  737. #undef PRINT_MIPS
  738. #define PRINT_MIPS(file) do {fprintf (file, "total complexity = %llu MIPS\n", celt_mips);} while (0);
  739. #endif