flacdsp.asm 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313
  1. ;******************************************************************************
  2. ;* FLAC DSP SIMD optimizations
  3. ;*
  4. ;* Copyright (C) 2014 Loren Merritt
  5. ;* Copyright (C) 2014 James Almer
  6. ;*
  7. ;* This file is part of FFmpeg.
  8. ;*
  9. ;* FFmpeg is free software; you can redistribute it and/or
  10. ;* modify it under the terms of the GNU Lesser General Public
  11. ;* License as published by the Free Software Foundation; either
  12. ;* version 2.1 of the License, or (at your option) any later version.
  13. ;*
  14. ;* FFmpeg is distributed in the hope that it will be useful,
  15. ;* but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. ;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  17. ;* Lesser General Public License for more details.
  18. ;*
  19. ;* You should have received a copy of the GNU Lesser General Public
  20. ;* License along with FFmpeg; if not, write to the Free Software
  21. ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  22. ;******************************************************************************
  23. %include "libavutil/x86/x86util.asm"
  24. SECTION .text
  25. %macro PMACSDQL 5
  26. %if cpuflag(xop)
  27. pmacsdql %1, %2, %3, %1
  28. %else
  29. pmuldq %2, %3
  30. paddq %1, %2
  31. %endif
  32. %endmacro
  33. %macro LPC_32 1
  34. INIT_XMM %1
  35. cglobal flac_lpc_32, 5,6,5, decoded, coeffs, pred_order, qlevel, len, j
  36. sub lend, pred_orderd
  37. jle .ret
  38. lea decodedq, [decodedq+pred_orderq*4-8]
  39. lea coeffsq, [coeffsq+pred_orderq*4]
  40. neg pred_orderq
  41. movd m4, qlevelm
  42. ALIGN 16
  43. .loop_sample:
  44. movd m0, [decodedq+pred_orderq*4+8]
  45. add decodedq, 8
  46. movd m1, [coeffsq+pred_orderq*4]
  47. pxor m2, m2
  48. pxor m3, m3
  49. lea jq, [pred_orderq+1]
  50. test jq, jq
  51. jz .end_order
  52. .loop_order:
  53. PMACSDQL m2, m0, m1, m2, m0
  54. movd m0, [decodedq+jq*4]
  55. PMACSDQL m3, m1, m0, m3, m1
  56. movd m1, [coeffsq+jq*4]
  57. inc jq
  58. jl .loop_order
  59. .end_order:
  60. PMACSDQL m2, m0, m1, m2, m0
  61. psrlq m2, m4
  62. movd m0, [decodedq]
  63. paddd m0, m2
  64. movd [decodedq], m0
  65. sub lend, 2
  66. jl .ret
  67. PMACSDQL m3, m1, m0, m3, m1
  68. psrlq m3, m4
  69. movd m1, [decodedq+4]
  70. paddd m1, m3
  71. movd [decodedq+4], m1
  72. jg .loop_sample
  73. .ret:
  74. REP_RET
  75. %endmacro
  76. %if HAVE_XOP_EXTERNAL
  77. LPC_32 xop
  78. %endif
  79. LPC_32 sse4
  80. ;----------------------------------------------------------------------------------
  81. ;void ff_flac_decorrelate_[lrm]s_16_sse2(uint8_t **out, int32_t **in, int channels,
  82. ; int len, int shift);
  83. ;----------------------------------------------------------------------------------
  84. %macro FLAC_DECORRELATE_16 3-4
  85. cglobal flac_decorrelate_%1_16, 2, 4, 4, out, in0, in1, len
  86. %if ARCH_X86_32
  87. mov lend, lenm
  88. %endif
  89. movd m3, r4m
  90. shl lend, 2
  91. mov in1q, [in0q + gprsize]
  92. mov in0q, [in0q]
  93. mov outq, [outq]
  94. add in1q, lenq
  95. add in0q, lenq
  96. add outq, lenq
  97. neg lenq
  98. align 16
  99. .loop:
  100. mova m0, [in0q + lenq]
  101. mova m1, [in1q + lenq]
  102. %ifidn %1, ms
  103. psrad m2, m1, 1
  104. psubd m0, m2
  105. %endif
  106. %ifnidn %1, indep2
  107. p%4d m2, m0, m1
  108. %endif
  109. packssdw m%2, m%2
  110. packssdw m%3, m%3
  111. punpcklwd m%2, m%3
  112. psllw m%2, m3
  113. mova [outq + lenq], m%2
  114. add lenq, 16
  115. jl .loop
  116. REP_RET
  117. %endmacro
  118. INIT_XMM sse2
  119. FLAC_DECORRELATE_16 ls, 0, 2, sub
  120. FLAC_DECORRELATE_16 rs, 2, 1, add
  121. FLAC_DECORRELATE_16 ms, 2, 0, add
  122. ;----------------------------------------------------------------------------------
  123. ;void ff_flac_decorrelate_[lrm]s_32_sse2(uint8_t **out, int32_t **in, int channels,
  124. ; int len, int shift);
  125. ;----------------------------------------------------------------------------------
  126. %macro FLAC_DECORRELATE_32 5
  127. cglobal flac_decorrelate_%1_32, 2, 4, 4, out, in0, in1, len
  128. %if ARCH_X86_32
  129. mov lend, lenm
  130. %endif
  131. movd m3, r4m
  132. mov in1q, [in0q + gprsize]
  133. mov in0q, [in0q]
  134. mov outq, [outq]
  135. sub in1q, in0q
  136. align 16
  137. .loop:
  138. mova m0, [in0q]
  139. mova m1, [in0q + in1q]
  140. %ifidn %1, ms
  141. psrad m2, m1, 1
  142. psubd m0, m2
  143. %endif
  144. p%5d m2, m0, m1
  145. pslld m%2, m3
  146. pslld m%3, m3
  147. SBUTTERFLY dq, %2, %3, %4
  148. mova [outq ], m%2
  149. mova [outq + mmsize], m%3
  150. add in0q, mmsize
  151. add outq, mmsize*2
  152. sub lend, mmsize/4
  153. jg .loop
  154. REP_RET
  155. %endmacro
  156. INIT_XMM sse2
  157. FLAC_DECORRELATE_32 ls, 0, 2, 1, sub
  158. FLAC_DECORRELATE_32 rs, 2, 1, 0, add
  159. FLAC_DECORRELATE_32 ms, 2, 0, 1, add
  160. ;-----------------------------------------------------------------------------------------
  161. ;void ff_flac_decorrelate_indep<ch>_<bps>_<opt>(uint8_t **out, int32_t **in, int channels,
  162. ; int len, int shift);
  163. ;-----------------------------------------------------------------------------------------
  164. ;%1 = bps
  165. ;%2 = channels
  166. ;%3 = last xmm reg used
  167. ;%4 = word/dword (shift instruction)
  168. %macro FLAC_DECORRELATE_INDEP 4
  169. %define REPCOUNT %2/(32/%1) ; 16bits = channels / 2; 32bits = channels
  170. cglobal flac_decorrelate_indep%2_%1, 2, %2+2, %3+1, out, in0, in1, len, in2, in3, in4, in5, in6, in7
  171. %if ARCH_X86_32
  172. %if %2 == 6
  173. DEFINE_ARGS out, in0, in1, in2, in3, in4, in5
  174. %define lend dword r3m
  175. %else
  176. mov lend, lenm
  177. %endif
  178. %endif
  179. movd m%3, r4m
  180. %assign %%i 1
  181. %rep %2-1
  182. mov in %+ %%i %+ q, [in0q+%%i*gprsize]
  183. %assign %%i %%i+1
  184. %endrep
  185. mov in0q, [in0q]
  186. mov outq, [outq]
  187. %assign %%i 1
  188. %rep %2-1
  189. sub in %+ %%i %+ q, in0q
  190. %assign %%i %%i+1
  191. %endrep
  192. align 16
  193. .loop:
  194. mova m0, [in0q]
  195. %assign %%i 1
  196. %rep REPCOUNT-1
  197. mova m %+ %%i, [in0q + in %+ %%i %+ q]
  198. %assign %%i %%i+1
  199. %endrep
  200. %if %1 == 32
  201. %if %2 == 8
  202. TRANSPOSE8x4D 0, 1, 2, 3, 4, 5, 6, 7, 8
  203. %elif %2 == 6
  204. SBUTTERFLY dq, 0, 1, 6
  205. SBUTTERFLY dq, 2, 3, 6
  206. SBUTTERFLY dq, 4, 5, 6
  207. punpcklqdq m6, m0, m2
  208. punpckhqdq m2, m4
  209. shufps m4, m0, 0xe4
  210. punpcklqdq m0, m1, m3
  211. punpckhqdq m3, m5
  212. shufps m5, m1, 0xe4
  213. SWAP 0,6,1,4,5,3
  214. %elif %2 == 4
  215. TRANSPOSE4x4D 0, 1, 2, 3, 4
  216. %else ; %2 == 2
  217. SBUTTERFLY dq, 0, 1, 2
  218. %endif
  219. %else ; %1 == 16
  220. %if %2 == 8
  221. packssdw m0, [in0q + in4q]
  222. packssdw m1, [in0q + in5q]
  223. packssdw m2, [in0q + in6q]
  224. packssdw m3, [in0q + in7q]
  225. TRANSPOSE2x4x4W 0, 1, 2, 3, 4
  226. %elif %2 == 6
  227. packssdw m0, [in0q + in3q]
  228. packssdw m1, [in0q + in4q]
  229. packssdw m2, [in0q + in5q]
  230. pshufd m3, m0, q1032
  231. punpcklwd m0, m1
  232. punpckhwd m1, m2
  233. punpcklwd m2, m3
  234. shufps m3, m0, m2, q2020
  235. shufps m0, m1, q2031
  236. shufps m2, m1, q3131
  237. shufps m1, m2, m3, q3120
  238. shufps m3, m0, q0220
  239. shufps m0, m2, q3113
  240. SWAP 2, 0, 3
  241. %else ; %2 == 4
  242. packssdw m0, [in0q + in2q]
  243. packssdw m1, [in0q + in3q]
  244. SBUTTERFLY wd, 0, 1, 2
  245. SBUTTERFLY dq, 0, 1, 2
  246. %endif
  247. %endif
  248. %assign %%i 0
  249. %rep REPCOUNT
  250. psll%4 m %+ %%i, m%3
  251. %assign %%i %%i+1
  252. %endrep
  253. %assign %%i 0
  254. %rep REPCOUNT
  255. mova [outq + %%i*mmsize], m %+ %%i
  256. %assign %%i %%i+1
  257. %endrep
  258. add in0q, mmsize
  259. add outq, mmsize*REPCOUNT
  260. sub lend, mmsize/4
  261. jg .loop
  262. REP_RET
  263. %endmacro
  264. INIT_XMM sse2
  265. FLAC_DECORRELATE_16 indep2, 0, 1 ; Reuse stereo 16bits macro
  266. FLAC_DECORRELATE_INDEP 32, 2, 3, d
  267. FLAC_DECORRELATE_INDEP 16, 4, 3, w
  268. FLAC_DECORRELATE_INDEP 32, 4, 5, d
  269. FLAC_DECORRELATE_INDEP 16, 6, 4, w
  270. FLAC_DECORRELATE_INDEP 32, 6, 7, d
  271. %if ARCH_X86_64
  272. FLAC_DECORRELATE_INDEP 16, 8, 5, w
  273. FLAC_DECORRELATE_INDEP 32, 8, 9, d
  274. %endif
  275. INIT_XMM avx
  276. FLAC_DECORRELATE_INDEP 32, 4, 5, d
  277. FLAC_DECORRELATE_INDEP 32, 6, 7, d
  278. %if ARCH_X86_64
  279. FLAC_DECORRELATE_INDEP 16, 8, 5, w
  280. FLAC_DECORRELATE_INDEP 32, 8, 9, d
  281. %endif