fixed_debug.h 21 KB

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