flacdsp.asm 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326
  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_RODATA
  25. vector: db 0,1,4,5,8,9,12,13,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,1,4,5,8,9,12,13,
  26. SECTION .text
  27. %macro PMACSDQL 5
  28. %if cpuflag(xop)
  29. pmacsdql %1, %2, %3, %1
  30. %else
  31. pmuldq %2, %3
  32. paddq %1, %2
  33. %endif
  34. %endmacro
  35. %macro LPC_32 1
  36. INIT_XMM %1
  37. cglobal flac_lpc_32, 5,6,5, decoded, coeffs, pred_order, qlevel, len, j
  38. sub lend, pred_orderd
  39. jle .ret
  40. lea decodedq, [decodedq+pred_orderq*4-8]
  41. lea coeffsq, [coeffsq+pred_orderq*4]
  42. neg pred_orderq
  43. movd m4, qlevelm
  44. ALIGN 16
  45. .loop_sample:
  46. movd m0, [decodedq+pred_orderq*4+8]
  47. add decodedq, 8
  48. movd m1, [coeffsq+pred_orderq*4]
  49. pxor m2, m2
  50. pxor m3, m3
  51. lea jq, [pred_orderq+1]
  52. test jq, jq
  53. jz .end_order
  54. .loop_order:
  55. PMACSDQL m2, m0, m1, m2, m0
  56. movd m0, [decodedq+jq*4]
  57. PMACSDQL m3, m1, m0, m3, m1
  58. movd m1, [coeffsq+jq*4]
  59. inc jq
  60. jl .loop_order
  61. .end_order:
  62. PMACSDQL m2, m0, m1, m2, m0
  63. psrlq m2, m4
  64. movd m0, [decodedq]
  65. paddd m0, m2
  66. movd [decodedq], m0
  67. sub lend, 2
  68. jl .ret
  69. PMACSDQL m3, m1, m0, m3, m1
  70. psrlq m3, m4
  71. movd m1, [decodedq+4]
  72. paddd m1, m3
  73. movd [decodedq+4], m1
  74. jg .loop_sample
  75. .ret:
  76. RET
  77. %endmacro
  78. %if HAVE_XOP_EXTERNAL
  79. LPC_32 xop
  80. %endif
  81. LPC_32 sse4
  82. ;----------------------------------------------------------------------------------
  83. ;void ff_flac_decorrelate_[lrm]s_16_sse2(uint8_t **out, int32_t **in, int channels,
  84. ; int len, int shift);
  85. ;----------------------------------------------------------------------------------
  86. %macro FLAC_DECORRELATE_16 3-4
  87. cglobal flac_decorrelate_%1_16, 2, 4, 4, out, in0, in1, len
  88. %ifidn %1, indep2
  89. VBROADCASTI128 m2, [vector]
  90. %endif
  91. %if ARCH_X86_32
  92. mov lend, lenm
  93. %endif
  94. movd m3, r4m
  95. shl lend, 2
  96. mov in1q, [in0q + gprsize]
  97. mov in0q, [in0q]
  98. mov outq, [outq]
  99. add in1q, lenq
  100. add in0q, lenq
  101. add outq, lenq
  102. neg lenq
  103. align 16
  104. .loop:
  105. mova m0, [in0q + lenq]
  106. mova m1, [in1q + lenq]
  107. %ifidn %1, ms
  108. psrad m2, m1, 1
  109. psubd m0, m2
  110. %endif
  111. %ifnidn %1, indep2
  112. p%4d m2, m0, m1
  113. packssdw m%2, m%2
  114. packssdw m%3, m%3
  115. punpcklwd m%2, m%3
  116. psllw m%2, m3
  117. %else
  118. pslld m%2, m3
  119. pslld m%3, m3
  120. pshufb m%2, m%2, m2
  121. pshufb m%3, m%3, m2
  122. punpcklwd m%2, m%3
  123. %endif
  124. mova [outq + lenq], m%2
  125. add lenq, 16
  126. jl .loop
  127. RET
  128. %endmacro
  129. INIT_XMM sse2
  130. FLAC_DECORRELATE_16 ls, 0, 2, sub
  131. FLAC_DECORRELATE_16 rs, 2, 1, add
  132. FLAC_DECORRELATE_16 ms, 2, 0, add
  133. ;----------------------------------------------------------------------------------
  134. ;void ff_flac_decorrelate_[lrm]s_32_sse2(uint8_t **out, int32_t **in, int channels,
  135. ; int len, int shift);
  136. ;----------------------------------------------------------------------------------
  137. %macro FLAC_DECORRELATE_32 5
  138. cglobal flac_decorrelate_%1_32, 2, 4, 4, out, in0, in1, len
  139. %if ARCH_X86_32
  140. mov lend, lenm
  141. %endif
  142. movd m3, r4m
  143. mov in1q, [in0q + gprsize]
  144. mov in0q, [in0q]
  145. mov outq, [outq]
  146. sub in1q, in0q
  147. align 16
  148. .loop:
  149. mova m0, [in0q]
  150. mova m1, [in0q + in1q]
  151. %ifidn %1, ms
  152. psrad m2, m1, 1
  153. psubd m0, m2
  154. %endif
  155. p%5d m2, m0, m1
  156. pslld m%2, m3
  157. pslld m%3, m3
  158. SBUTTERFLY dq, %2, %3, %4
  159. mova [outq ], m%2
  160. mova [outq + mmsize], m%3
  161. add in0q, mmsize
  162. add outq, mmsize*2
  163. sub lend, mmsize/4
  164. jg .loop
  165. RET
  166. %endmacro
  167. INIT_XMM sse2
  168. FLAC_DECORRELATE_32 ls, 0, 2, 1, sub
  169. FLAC_DECORRELATE_32 rs, 2, 1, 0, add
  170. FLAC_DECORRELATE_32 ms, 2, 0, 1, add
  171. ;-----------------------------------------------------------------------------------------
  172. ;void ff_flac_decorrelate_indep<ch>_<bps>_<opt>(uint8_t **out, int32_t **in, int channels,
  173. ; int len, int shift);
  174. ;-----------------------------------------------------------------------------------------
  175. ;%1 = bps
  176. ;%2 = channels
  177. ;%3 = last xmm reg used
  178. ;%4 = word/dword (shift instruction)
  179. %macro FLAC_DECORRELATE_INDEP 4
  180. %define REPCOUNT %2/(32/%1) ; 16bits = channels / 2; 32bits = channels
  181. cglobal flac_decorrelate_indep%2_%1, 2, %2+2, %3+1, out, in0, in1, len, in2, in3, in4, in5, in6, in7
  182. %if ARCH_X86_32
  183. %if %2 == 6
  184. DEFINE_ARGS out, in0, in1, in2, in3, in4, in5
  185. %define lend dword r3m
  186. %else
  187. mov lend, lenm
  188. %endif
  189. %endif
  190. movd m%3, r4m
  191. %assign %%i 1
  192. %rep %2-1
  193. mov in %+ %%i %+ q, [in0q+%%i*gprsize]
  194. %assign %%i %%i+1
  195. %endrep
  196. mov in0q, [in0q]
  197. mov outq, [outq]
  198. %assign %%i 1
  199. %rep %2-1
  200. sub in %+ %%i %+ q, in0q
  201. %assign %%i %%i+1
  202. %endrep
  203. align 16
  204. .loop:
  205. mova m0, [in0q]
  206. %assign %%i 1
  207. %rep REPCOUNT-1
  208. mova m %+ %%i, [in0q + in %+ %%i %+ q]
  209. %assign %%i %%i+1
  210. %endrep
  211. %if %1 == 32
  212. %if %2 == 8
  213. TRANSPOSE8x4D 0, 1, 2, 3, 4, 5, 6, 7, 8
  214. %elif %2 == 6
  215. SBUTTERFLY dq, 0, 1, 6
  216. SBUTTERFLY dq, 2, 3, 6
  217. SBUTTERFLY dq, 4, 5, 6
  218. punpcklqdq m6, m0, m2
  219. punpckhqdq m2, m4
  220. shufps m4, m0, 0xe4
  221. punpcklqdq m0, m1, m3
  222. punpckhqdq m3, m5
  223. shufps m5, m1, 0xe4
  224. SWAP 0,6,1,4,5,3
  225. %elif %2 == 4
  226. TRANSPOSE4x4D 0, 1, 2, 3, 4
  227. %else ; %2 == 2
  228. SBUTTERFLY dq, 0, 1, 2
  229. %endif
  230. %else ; %1 == 16
  231. %if %2 == 8
  232. packssdw m0, [in0q + in4q]
  233. packssdw m1, [in0q + in5q]
  234. packssdw m2, [in0q + in6q]
  235. packssdw m3, [in0q + in7q]
  236. TRANSPOSE2x4x4W 0, 1, 2, 3, 4
  237. %elif %2 == 6
  238. packssdw m0, [in0q + in3q]
  239. packssdw m1, [in0q + in4q]
  240. packssdw m2, [in0q + in5q]
  241. pshufd m3, m0, q1032
  242. punpcklwd m0, m1
  243. punpckhwd m1, m2
  244. punpcklwd m2, m3
  245. shufps m3, m0, m2, q2020
  246. shufps m0, m1, q2031
  247. shufps m2, m1, q3131
  248. shufps m1, m2, m3, q3120
  249. shufps m3, m0, q0220
  250. shufps m0, m2, q3113
  251. SWAP 2, 0, 3
  252. %else ; %2 == 4
  253. packssdw m0, [in0q + in2q]
  254. packssdw m1, [in0q + in3q]
  255. SBUTTERFLY wd, 0, 1, 2
  256. SBUTTERFLY dq, 0, 1, 2
  257. %endif
  258. %endif
  259. %assign %%i 0
  260. %rep REPCOUNT
  261. psll%4 m %+ %%i, m%3
  262. %assign %%i %%i+1
  263. %endrep
  264. %assign %%i 0
  265. %rep REPCOUNT
  266. mova [outq + %%i*mmsize], m %+ %%i
  267. %assign %%i %%i+1
  268. %endrep
  269. add in0q, mmsize
  270. add outq, mmsize*REPCOUNT
  271. sub lend, mmsize/4
  272. jg .loop
  273. RET
  274. %endmacro
  275. INIT_XMM ssse3
  276. FLAC_DECORRELATE_16 indep2, 0, 1 ; Reuse stereo 16bits macro
  277. FLAC_DECORRELATE_INDEP 32, 2, 3, d
  278. FLAC_DECORRELATE_INDEP 16, 4, 3, w
  279. FLAC_DECORRELATE_INDEP 32, 4, 5, d
  280. FLAC_DECORRELATE_INDEP 16, 6, 4, w
  281. FLAC_DECORRELATE_INDEP 32, 6, 7, d
  282. %if ARCH_X86_64
  283. FLAC_DECORRELATE_INDEP 16, 8, 5, w
  284. FLAC_DECORRELATE_INDEP 32, 8, 9, d
  285. %endif
  286. INIT_XMM avx
  287. FLAC_DECORRELATE_INDEP 32, 4, 5, d
  288. FLAC_DECORRELATE_INDEP 32, 6, 7, d
  289. %if ARCH_X86_64
  290. FLAC_DECORRELATE_INDEP 16, 8, 5, w
  291. FLAC_DECORRELATE_INDEP 32, 8, 9, d
  292. %endif