aacpsdsp.asm 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487
  1. ;******************************************************************************
  2. ;* SIMD optimized MPEG-4 Parametric Stereo decoding functions
  3. ;*
  4. ;* Copyright (C) 2015 James Almer
  5. ;*
  6. ;* This file is part of FFmpeg.
  7. ;*
  8. ;* FFmpeg is free software; you can redistribute it and/or
  9. ;* modify it under the terms of the GNU Lesser General Public
  10. ;* License as published by the Free Software Foundation; either
  11. ;* version 2.1 of the License, or (at your option) any later version.
  12. ;*
  13. ;* FFmpeg is distributed in the hope that it will be useful,
  14. ;* but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. ;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  16. ;* Lesser General Public License for more details.
  17. ;*
  18. ;* You should have received a copy of the GNU Lesser General Public
  19. ;* License along with FFmpeg; if not, write to the Free Software
  20. ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  21. ;******************************************************************************
  22. %include "libavutil/x86/x86util.asm"
  23. SECTION_RODATA
  24. ps_p1m1p1m1: dd 0, 0x80000000, 0, 0x80000000
  25. SECTION .text
  26. ;*************************************************************************
  27. ;void ff_ps_add_squares_<opt>(float *dst, const float (*src)[2], int n);
  28. ;*************************************************************************
  29. %macro PS_ADD_SQUARES 1
  30. cglobal ps_add_squares, 3, 3, %1, dst, src, n
  31. shl nd, 3
  32. add srcq, nq
  33. neg nq
  34. align 16
  35. .loop:
  36. movaps m0, [srcq+nq]
  37. movaps m1, [srcq+nq+mmsize]
  38. mulps m0, m0
  39. mulps m1, m1
  40. HADDPS m0, m1, m2
  41. addps m0, [dstq]
  42. movaps [dstq], m0
  43. add dstq, mmsize
  44. add nq, mmsize*2
  45. jl .loop
  46. REP_RET
  47. %endmacro
  48. INIT_XMM sse
  49. PS_ADD_SQUARES 2
  50. INIT_XMM sse3
  51. PS_ADD_SQUARES 3
  52. ;*******************************************************************
  53. ;void ff_ps_mul_pair_single_sse(float (*dst)[2], float (*src0)[2],
  54. ; float *src1, int n);
  55. ;*******************************************************************
  56. INIT_XMM sse
  57. cglobal ps_mul_pair_single, 4, 4, 4, dst, src1, src2, n
  58. shl nd, 3
  59. add src1q, nq
  60. add dstq, nq
  61. neg nq
  62. align 16
  63. .loop:
  64. movu m0, [src1q+nq]
  65. movu m1, [src1q+nq+mmsize]
  66. mova m2, [src2q]
  67. mova m3, m2
  68. unpcklps m2, m2
  69. unpckhps m3, m3
  70. mulps m0, m2
  71. mulps m1, m3
  72. mova [dstq+nq], m0
  73. mova [dstq+nq+mmsize], m1
  74. add src2q, mmsize
  75. add nq, mmsize*2
  76. jl .loop
  77. REP_RET
  78. ;***********************************************************************
  79. ;void ff_ps_stereo_interpolate_sse3(float (*l)[2], float (*r)[2],
  80. ; float h[2][4], float h_step[2][4],
  81. ; int len);
  82. ;***********************************************************************
  83. INIT_XMM sse3
  84. cglobal ps_stereo_interpolate, 5, 5, 6, l, r, h, h_step, n
  85. movaps m0, [hq]
  86. movaps m1, [h_stepq]
  87. unpcklps m4, m0, m0
  88. unpckhps m0, m0
  89. unpcklps m5, m1, m1
  90. unpckhps m1, m1
  91. shl nd, 3
  92. add lq, nq
  93. add rq, nq
  94. neg nq
  95. align 16
  96. .loop:
  97. addps m4, m5
  98. addps m0, m1
  99. movddup m2, [lq+nq]
  100. movddup m3, [rq+nq]
  101. mulps m2, m4
  102. mulps m3, m0
  103. addps m2, m3
  104. movsd [lq+nq], m2
  105. movhps [rq+nq], m2
  106. add nq, 8
  107. jl .loop
  108. REP_RET
  109. ;***************************************************************************
  110. ;void ps_stereo_interpolate_ipdopd_sse3(float (*l)[2], float (*r)[2],
  111. ; float h[2][4], float h_step[2][4],
  112. ; int len);
  113. ;***************************************************************************
  114. INIT_XMM sse3
  115. cglobal ps_stereo_interpolate_ipdopd, 5, 5, 10, l, r, h, h_step, n
  116. movaps m0, [hq]
  117. movaps m1, [hq+mmsize]
  118. %if ARCH_X86_64
  119. movaps m8, [h_stepq]
  120. movaps m9, [h_stepq+mmsize]
  121. %define H_STEP0 m8
  122. %define H_STEP1 m9
  123. %else
  124. %define H_STEP0 [h_stepq]
  125. %define H_STEP1 [h_stepq+mmsize]
  126. %endif
  127. shl nd, 3
  128. add lq, nq
  129. add rq, nq
  130. neg nq
  131. align 16
  132. .loop:
  133. addps m0, H_STEP0
  134. addps m1, H_STEP1
  135. movddup m2, [lq+nq]
  136. movddup m3, [rq+nq]
  137. shufps m4, m2, m2, q2301
  138. shufps m5, m3, m3, q2301
  139. unpcklps m6, m0, m0
  140. unpckhps m7, m0, m0
  141. mulps m2, m6
  142. mulps m3, m7
  143. unpcklps m6, m1, m1
  144. unpckhps m7, m1, m1
  145. mulps m4, m6
  146. mulps m5, m7
  147. addps m2, m3
  148. addsubps m2, m4
  149. addsubps m2, m5
  150. movsd [lq+nq], m2
  151. movhps [rq+nq], m2
  152. add nq, 8
  153. jl .loop
  154. REP_RET
  155. ;**********************************************************
  156. ;void ps_hybrid_analysis_ileave_sse(float out[2][38][64],
  157. ; float (*in)[32][2],
  158. ; int i, int len)
  159. ;**********************************************************
  160. INIT_XMM sse
  161. cglobal ps_hybrid_analysis_ileave, 3, 7, 5, out, in, i, len, in0, in1, tmp
  162. movsxdifnidn iq, id
  163. mov lend, 32 << 3
  164. lea inq, [inq+iq*4]
  165. mov tmpd, id
  166. shl tmpd, 8
  167. add outq, tmpq
  168. mov tmpd, 64
  169. sub tmpd, id
  170. mov id, tmpd
  171. test id, 1
  172. jne .loop4
  173. test id, 2
  174. jne .loop8
  175. align 16
  176. .loop16:
  177. mov in0q, inq
  178. mov in1q, 38*64*4
  179. add in1q, in0q
  180. mov tmpd, lend
  181. .inner_loop16:
  182. movaps m0, [in0q]
  183. movaps m1, [in1q]
  184. movaps m2, [in0q+lenq]
  185. movaps m3, [in1q+lenq]
  186. TRANSPOSE4x4PS 0, 1, 2, 3, 4
  187. movaps [outq], m0
  188. movaps [outq+lenq], m1
  189. movaps [outq+lenq*2], m2
  190. movaps [outq+3*32*2*4], m3
  191. lea in0q, [in0q+lenq*2]
  192. lea in1q, [in1q+lenq*2]
  193. add outq, mmsize
  194. sub tmpd, mmsize
  195. jg .inner_loop16
  196. add inq, 16
  197. add outq, 3*32*2*4
  198. sub id, 4
  199. jg .loop16
  200. RET
  201. align 16
  202. .loop8:
  203. mov in0q, inq
  204. mov in1q, 38*64*4
  205. add in1q, in0q
  206. mov tmpd, lend
  207. .inner_loop8:
  208. movlps m0, [in0q]
  209. movlps m1, [in1q]
  210. movhps m0, [in0q+lenq]
  211. movhps m1, [in1q+lenq]
  212. SBUTTERFLYPS 0, 1, 2
  213. SBUTTERFLYPD 0, 1, 2
  214. movaps [outq], m0
  215. movaps [outq+lenq], m1
  216. lea in0q, [in0q+lenq*2]
  217. lea in1q, [in1q+lenq*2]
  218. add outq, mmsize
  219. sub tmpd, mmsize
  220. jg .inner_loop8
  221. add inq, 8
  222. add outq, lenq
  223. sub id, 2
  224. jg .loop16
  225. RET
  226. align 16
  227. .loop4:
  228. mov in0q, inq
  229. mov in1q, 38*64*4
  230. add in1q, in0q
  231. mov tmpd, lend
  232. .inner_loop4:
  233. movss m0, [in0q]
  234. movss m1, [in1q]
  235. movss m2, [in0q+lenq]
  236. movss m3, [in1q+lenq]
  237. movlhps m0, m1
  238. movlhps m2, m3
  239. shufps m0, m2, q2020
  240. movaps [outq], m0
  241. lea in0q, [in0q+lenq*2]
  242. lea in1q, [in1q+lenq*2]
  243. add outq, mmsize
  244. sub tmpd, mmsize
  245. jg .inner_loop4
  246. add inq, 4
  247. sub id, 1
  248. test id, 2
  249. jne .loop8
  250. cmp id, 4
  251. jge .loop16
  252. RET
  253. ;***********************************************************
  254. ;void ps_hybrid_synthesis_deint_sse4(float out[2][38][64],
  255. ; float (*in)[32][2],
  256. ; int i, int len)
  257. ;***********************************************************
  258. %macro HYBRID_SYNTHESIS_DEINT 0
  259. cglobal ps_hybrid_synthesis_deint, 3, 7, 5, out, in, i, len, out0, out1, tmp
  260. %if cpuflag(sse4)
  261. %define MOVH movsd
  262. %else
  263. %define MOVH movlps
  264. %endif
  265. movsxdifnidn iq, id
  266. mov lend, 32 << 3
  267. lea outq, [outq+iq*4]
  268. mov tmpd, id
  269. shl tmpd, 8
  270. add inq, tmpq
  271. mov tmpd, 64
  272. sub tmpd, id
  273. mov id, tmpd
  274. test id, 1
  275. jne .loop4
  276. test id, 2
  277. jne .loop8
  278. align 16
  279. .loop16:
  280. mov out0q, outq
  281. mov out1q, 38*64*4
  282. add out1q, out0q
  283. mov tmpd, lend
  284. .inner_loop16:
  285. movaps m0, [inq]
  286. movaps m1, [inq+lenq]
  287. movaps m2, [inq+lenq*2]
  288. movaps m3, [inq+3*32*2*4]
  289. TRANSPOSE4x4PS 0, 1, 2, 3, 4
  290. movaps [out0q], m0
  291. movaps [out1q], m1
  292. movaps [out0q+lenq], m2
  293. movaps [out1q+lenq], m3
  294. lea out0q, [out0q+lenq*2]
  295. lea out1q, [out1q+lenq*2]
  296. add inq, mmsize
  297. sub tmpd, mmsize
  298. jg .inner_loop16
  299. add outq, 16
  300. add inq, 3*32*2*4
  301. sub id, 4
  302. jg .loop16
  303. RET
  304. align 16
  305. .loop8:
  306. mov out0q, outq
  307. mov out1q, 38*64*4
  308. add out1q, out0q
  309. mov tmpd, lend
  310. .inner_loop8:
  311. movaps m0, [inq]
  312. movaps m1, [inq+lenq]
  313. SBUTTERFLYPS 0, 1, 2
  314. SBUTTERFLYPD 0, 1, 2
  315. MOVH [out0q], m0
  316. MOVH [out1q], m1
  317. movhps [out0q+lenq], m0
  318. movhps [out1q+lenq], m1
  319. lea out0q, [out0q+lenq*2]
  320. lea out1q, [out1q+lenq*2]
  321. add inq, mmsize
  322. sub tmpd, mmsize
  323. jg .inner_loop8
  324. add outq, 8
  325. add inq, lenq
  326. sub id, 2
  327. jg .loop16
  328. RET
  329. align 16
  330. .loop4:
  331. mov out0q, outq
  332. mov out1q, 38*64*4
  333. add out1q, out0q
  334. mov tmpd, lend
  335. .inner_loop4:
  336. movaps m0, [inq]
  337. movss [out0q], m0
  338. %if cpuflag(sse4)
  339. extractps [out1q], m0, 1
  340. extractps [out0q+lenq], m0, 2
  341. extractps [out1q+lenq], m0, 3
  342. %else
  343. movhlps m1, m0
  344. movss [out0q+lenq], m1
  345. shufps m0, m0, 0xb1
  346. movss [out1q], m0
  347. movhlps m1, m0
  348. movss [out1q+lenq], m1
  349. %endif
  350. lea out0q, [out0q+lenq*2]
  351. lea out1q, [out1q+lenq*2]
  352. add inq, mmsize
  353. sub tmpd, mmsize
  354. jg .inner_loop4
  355. add outq, 4
  356. sub id, 1
  357. test id, 2
  358. jne .loop8
  359. cmp id, 4
  360. jge .loop16
  361. RET
  362. %endmacro
  363. INIT_XMM sse
  364. HYBRID_SYNTHESIS_DEINT
  365. INIT_XMM sse4
  366. HYBRID_SYNTHESIS_DEINT
  367. ;*******************************************************************
  368. ;void ff_ps_hybrid_analysis_<opt>(float (*out)[2], float (*in)[2],
  369. ; const float (*filter)[8][2],
  370. ; ptrdiff_t stride, int n);
  371. ;*******************************************************************
  372. %macro PS_HYBRID_ANALYSIS_LOOP 3
  373. movu %1, [inq+mmsize*%3]
  374. movu m1, [inq+mmsize*(5-%3)+8]
  375. %if cpuflag(sse3)
  376. pshufd %2, %1, q2301
  377. pshufd m4, m1, q0123
  378. pshufd m1, m1, q1032
  379. pshufd m2, [filterq+nq+mmsize*%3], q2301
  380. addsubps %2, m4
  381. addsubps %1, m1
  382. %else
  383. mova m2, [filterq+nq+mmsize*%3]
  384. mova %2, %1
  385. mova m4, m1
  386. shufps %2, %2, q2301
  387. shufps m4, m4, q0123
  388. shufps m1, m1, q1032
  389. shufps m2, m2, q2301
  390. xorps m4, m7
  391. xorps m1, m7
  392. subps %2, m4
  393. subps %1, m1
  394. %endif
  395. mulps %2, m2
  396. mulps %1, m2
  397. %if %3
  398. addps m3, %2
  399. addps m0, %1
  400. %endif
  401. %endmacro
  402. %macro PS_HYBRID_ANALYSIS 0
  403. cglobal ps_hybrid_analysis, 5, 5, 8, out, in, filter, stride, n
  404. %if cpuflag(sse3)
  405. %define MOVH movsd
  406. %else
  407. %define MOVH movlps
  408. %endif
  409. shl strideq, 3
  410. shl nd, 6
  411. add filterq, nq
  412. neg nq
  413. mova m7, [ps_p1m1p1m1]
  414. align 16
  415. .loop:
  416. PS_HYBRID_ANALYSIS_LOOP m0, m3, 0
  417. PS_HYBRID_ANALYSIS_LOOP m5, m6, 1
  418. PS_HYBRID_ANALYSIS_LOOP m5, m6, 2
  419. %if cpuflag(sse3)
  420. pshufd m3, m3, q2301
  421. xorps m0, m7
  422. hsubps m3, m0
  423. pshufd m1, m3, q0020
  424. pshufd m3, m3, q0031
  425. addps m1, m3
  426. movsd m2, [inq+6*8]
  427. %else
  428. mova m1, m3
  429. mova m2, m0
  430. shufps m1, m1, q2301
  431. shufps m2, m2, q2301
  432. subps m1, m3
  433. addps m2, m0
  434. unpcklps m3, m1, m2
  435. unpckhps m1, m2
  436. addps m1, m3
  437. movu m2, [inq+6*8] ; faster than movlps and no risk of overread
  438. %endif
  439. movss m3, [filterq+nq+8*6]
  440. SPLATD m3
  441. mulps m2, m3
  442. addps m1, m2
  443. MOVH [outq], m1
  444. add outq, strideq
  445. add nq, 64
  446. jl .loop
  447. REP_RET
  448. %endmacro
  449. INIT_XMM sse
  450. PS_HYBRID_ANALYSIS
  451. INIT_XMM sse3
  452. PS_HYBRID_ANALYSIS