You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

492 lines
11KB

  1. ;******************************************************************************
  2. ;* 32 point SSE-optimized DCT transform
  3. ;* Copyright (c) 2010 Vitor Sessak
  4. ;*
  5. ;* This file is part of Libav.
  6. ;*
  7. ;* Libav is free software; you can redistribute it and/or
  8. ;* modify it under the terms of the GNU Lesser General Public
  9. ;* License as published by the Free Software Foundation; either
  10. ;* version 2.1 of the License, or (at your option) any later version.
  11. ;*
  12. ;* Libav is distributed in the hope that it will be useful,
  13. ;* but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. ;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. ;* Lesser General Public License for more details.
  16. ;*
  17. ;* You should have received a copy of the GNU Lesser General Public
  18. ;* License along with Libav; if not, write to the Free Software
  19. ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  20. ;******************************************************************************
  21. %include "x86inc.asm"
  22. %include "x86util.asm"
  23. SECTION_RODATA 32
  24. align 32
  25. ps_cos_vec: dd 0.500603, 0.505471, 0.515447, 0.531043
  26. dd 0.553104, 0.582935, 0.622504, 0.674808
  27. dd -10.190008, -3.407609, -2.057781, -1.484165
  28. dd -1.169440, -0.972568, -0.839350, -0.744536
  29. dd 0.502419, 0.522499, 0.566944, 0.646822
  30. dd 0.788155, 1.060678, 1.722447, 5.101149
  31. dd 0.509796, 0.601345, 0.899976, 2.562916
  32. dd 0.509796, 0.601345, 0.899976, 2.562916
  33. dd 1.000000, 1.000000, 1.306563, 0.541196
  34. dd 1.000000, 1.000000, 1.306563, 0.541196
  35. dd 1.000000, 0.707107, 1.000000, -0.707107
  36. dd 1.000000, 0.707107, 1.000000, -0.707107
  37. dd 0.707107, 0.707107, 0.707107, 0.707107
  38. align 32
  39. ps_p1p1m1m1: dd 0, 0, 0x80000000, 0x80000000, 0, 0, 0x80000000, 0x80000000
  40. %macro BUTTERFLY 4
  41. subps %4, %1, %2
  42. addps %2, %2, %1
  43. mulps %1, %4, %3
  44. %endmacro
  45. %macro BUTTERFLY0 5
  46. %if cpuflag(sse2) && notcpuflag(avx)
  47. pshufd %4, %1, %5
  48. xorps %1, %2
  49. addps %1, %4
  50. mulps %1, %3
  51. %else
  52. shufps %4, %1, %1, %5
  53. xorps %1, %1, %2
  54. addps %4, %4, %1
  55. mulps %1, %4, %3
  56. %endif
  57. %endmacro
  58. %macro BUTTERFLY2 4
  59. BUTTERFLY0 %1, %2, %3, %4, 0x1b
  60. %endmacro
  61. %macro BUTTERFLY3 4
  62. BUTTERFLY0 %1, %2, %3, %4, 0xb1
  63. %endmacro
  64. %macro BUTTERFLY3V 5
  65. movaps m%5, m%1
  66. addps m%1, m%2
  67. subps m%5, m%2
  68. SWAP %2, %5
  69. mulps m%2, [ps_cos_vec+192]
  70. movaps m%5, m%3
  71. addps m%3, m%4
  72. subps m%4, m%5
  73. mulps m%4, [ps_cos_vec+192]
  74. %endmacro
  75. %macro PASS6_AND_PERMUTE 0
  76. mov tmpd, [outq+4]
  77. movss m7, [outq+72]
  78. addss m7, [outq+76]
  79. movss m3, [outq+56]
  80. addss m3, [outq+60]
  81. addss m4, m3
  82. movss m2, [outq+52]
  83. addss m2, m3
  84. movss m3, [outq+104]
  85. addss m3, [outq+108]
  86. addss m1, m3
  87. addss m5, m4
  88. movss [outq+ 16], m1
  89. movss m1, [outq+100]
  90. addss m1, m3
  91. movss m3, [outq+40]
  92. movss [outq+ 48], m1
  93. addss m3, [outq+44]
  94. movss m1, [outq+100]
  95. addss m4, m3
  96. addss m3, m2
  97. addss m1, [outq+108]
  98. movss [outq+ 40], m3
  99. addss m2, [outq+36]
  100. movss m3, [outq+8]
  101. movss [outq+ 56], m2
  102. addss m3, [outq+12]
  103. movss [outq+ 32], m3
  104. movss m3, [outq+80]
  105. movss [outq+ 8], m5
  106. movss [outq+ 80], m1
  107. movss m2, [outq+52]
  108. movss m5, [outq+120]
  109. addss m5, [outq+124]
  110. movss m1, [outq+64]
  111. addss m2, [outq+60]
  112. addss m0, m5
  113. addss m5, [outq+116]
  114. mov [outq+64], tmpd
  115. addss m6, m0
  116. addss m1, m6
  117. mov tmpd, [outq+12]
  118. mov [outq+ 96], tmpd
  119. movss [outq+ 4], m1
  120. movss m1, [outq+24]
  121. movss [outq+ 24], m4
  122. movss m4, [outq+88]
  123. addss m4, [outq+92]
  124. addss m3, m4
  125. addss m4, [outq+84]
  126. mov tmpd, [outq+108]
  127. addss m1, [outq+28]
  128. addss m0, m1
  129. addss m1, m5
  130. addss m6, m3
  131. addss m3, m0
  132. addss m0, m7
  133. addss m5, [outq+20]
  134. addss m7, m1
  135. movss [outq+ 12], m6
  136. mov [outq+112], tmpd
  137. movss m6, [outq+28]
  138. movss [outq+ 28], m0
  139. movss m0, [outq+36]
  140. movss [outq+ 36], m7
  141. addss m1, m4
  142. movss m7, [outq+116]
  143. addss m0, m2
  144. addss m7, [outq+124]
  145. movss [outq+ 72], m0
  146. movss m0, [outq+44]
  147. addss m2, m0
  148. movss [outq+ 44], m1
  149. movss [outq+ 88], m2
  150. addss m0, [outq+60]
  151. mov tmpd, [outq+60]
  152. mov [outq+120], tmpd
  153. movss [outq+104], m0
  154. addss m4, m5
  155. addss m5, [outq+68]
  156. movss [outq+52], m4
  157. movss [outq+60], m5
  158. movss m4, [outq+68]
  159. movss m5, [outq+20]
  160. movss [outq+ 20], m3
  161. addss m5, m7
  162. addss m7, m6
  163. addss m4, m5
  164. movss m2, [outq+84]
  165. addss m2, [outq+92]
  166. addss m5, m2
  167. movss [outq+ 68], m4
  168. addss m2, m7
  169. movss m4, [outq+76]
  170. movss [outq+ 84], m2
  171. movss [outq+ 76], m5
  172. addss m7, m4
  173. addss m6, [outq+124]
  174. addss m4, m6
  175. addss m6, [outq+92]
  176. movss [outq+100], m4
  177. movss [outq+108], m6
  178. movss m6, [outq+92]
  179. movss [outq+92], m7
  180. addss m6, [outq+124]
  181. movss [outq+116], m6
  182. %endmacro
  183. INIT_YMM avx
  184. SECTION_TEXT
  185. %if HAVE_AVX_EXTERNAL
  186. ; void ff_dct32_float_avx(FFTSample *out, const FFTSample *in)
  187. cglobal dct32_float, 2,3,8, out, in, tmp
  188. ; pass 1
  189. vmovaps m4, [inq+0]
  190. vinsertf128 m5, m5, [inq+96], 1
  191. vinsertf128 m5, m5, [inq+112], 0
  192. vshufps m5, m5, m5, 0x1b
  193. BUTTERFLY m4, m5, [ps_cos_vec], m6
  194. vmovaps m2, [inq+64]
  195. vinsertf128 m6, m6, [inq+32], 1
  196. vinsertf128 m6, m6, [inq+48], 0
  197. vshufps m6, m6, m6, 0x1b
  198. BUTTERFLY m2, m6, [ps_cos_vec+32], m0
  199. ; pass 2
  200. BUTTERFLY m5, m6, [ps_cos_vec+64], m0
  201. BUTTERFLY m4, m2, [ps_cos_vec+64], m7
  202. ; pass 3
  203. vperm2f128 m3, m6, m4, 0x31
  204. vperm2f128 m1, m6, m4, 0x20
  205. vshufps m3, m3, m3, 0x1b
  206. BUTTERFLY m1, m3, [ps_cos_vec+96], m6
  207. vperm2f128 m4, m5, m2, 0x20
  208. vperm2f128 m5, m5, m2, 0x31
  209. vshufps m5, m5, m5, 0x1b
  210. BUTTERFLY m4, m5, [ps_cos_vec+96], m6
  211. ; pass 4
  212. vmovaps m6, [ps_p1p1m1m1+0]
  213. vmovaps m2, [ps_cos_vec+128]
  214. BUTTERFLY2 m5, m6, m2, m7
  215. BUTTERFLY2 m4, m6, m2, m7
  216. BUTTERFLY2 m1, m6, m2, m7
  217. BUTTERFLY2 m3, m6, m2, m7
  218. ; pass 5
  219. vshufps m6, m6, m6, 0xcc
  220. vmovaps m2, [ps_cos_vec+160]
  221. BUTTERFLY3 m5, m6, m2, m7
  222. BUTTERFLY3 m4, m6, m2, m7
  223. BUTTERFLY3 m1, m6, m2, m7
  224. BUTTERFLY3 m3, m6, m2, m7
  225. vperm2f128 m6, m3, m3, 0x31
  226. vmovaps [outq], m3
  227. vextractf128 [outq+64], m5, 1
  228. vextractf128 [outq+32], m5, 0
  229. vextractf128 [outq+80], m4, 1
  230. vextractf128 [outq+48], m4, 0
  231. vperm2f128 m0, m1, m1, 0x31
  232. vmovaps [outq+96], m1
  233. vzeroupper
  234. ; pass 6, no SIMD...
  235. INIT_XMM
  236. PASS6_AND_PERMUTE
  237. RET
  238. %endif
  239. %if ARCH_X86_64
  240. %define SPILL SWAP
  241. %define UNSPILL SWAP
  242. %macro PASS5 0
  243. nop ; FIXME code alignment
  244. SWAP 5, 8
  245. SWAP 4, 12
  246. SWAP 6, 14
  247. SWAP 7, 13
  248. SWAP 0, 15
  249. PERMUTE 9,10, 10,12, 11,14, 12,9, 13,11, 14,13
  250. TRANSPOSE4x4PS 8, 9, 10, 11, 0
  251. BUTTERFLY3V 8, 9, 10, 11, 0
  252. addps m10, m11
  253. TRANSPOSE4x4PS 12, 13, 14, 15, 0
  254. BUTTERFLY3V 12, 13, 14, 15, 0
  255. addps m14, m15
  256. addps m12, m14
  257. addps m14, m13
  258. addps m13, m15
  259. %endmacro
  260. %macro PASS6 0
  261. SWAP 9, 12
  262. SWAP 11, 14
  263. movss [outq+0x00], m8
  264. pshuflw m0, m8, 0xe
  265. movss [outq+0x10], m9
  266. pshuflw m1, m9, 0xe
  267. movss [outq+0x20], m10
  268. pshuflw m2, m10, 0xe
  269. movss [outq+0x30], m11
  270. pshuflw m3, m11, 0xe
  271. movss [outq+0x40], m12
  272. pshuflw m4, m12, 0xe
  273. movss [outq+0x50], m13
  274. pshuflw m5, m13, 0xe
  275. movss [outq+0x60], m14
  276. pshuflw m6, m14, 0xe
  277. movaps [outq+0x70], m15
  278. pshuflw m7, m15, 0xe
  279. addss m0, m1
  280. addss m1, m2
  281. movss [outq+0x08], m0
  282. addss m2, m3
  283. movss [outq+0x18], m1
  284. addss m3, m4
  285. movss [outq+0x28], m2
  286. addss m4, m5
  287. movss [outq+0x38], m3
  288. addss m5, m6
  289. movss [outq+0x48], m4
  290. addss m6, m7
  291. movss [outq+0x58], m5
  292. movss [outq+0x68], m6
  293. movss [outq+0x78], m7
  294. PERMUTE 1,8, 3,9, 5,10, 7,11, 9,12, 11,13, 13,14, 8,1, 10,3, 12,5, 14,7
  295. movhlps m0, m1
  296. pshufd m1, m1, 3
  297. SWAP 0, 2, 4, 6, 8, 10, 12, 14
  298. SWAP 1, 3, 5, 7, 9, 11, 13, 15
  299. %rep 7
  300. movhlps m0, m1
  301. pshufd m1, m1, 3
  302. addss m15, m1
  303. SWAP 0, 2, 4, 6, 8, 10, 12, 14
  304. SWAP 1, 3, 5, 7, 9, 11, 13, 15
  305. %endrep
  306. %assign i 4
  307. %rep 15
  308. addss m0, m1
  309. movss [outq+i], m0
  310. SWAP 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
  311. %assign i i+8
  312. %endrep
  313. %endmacro
  314. %else ; ARCH_X86_32
  315. %macro SPILL 2 ; xmm#, mempos
  316. movaps [outq+(%2-8)*16], m%1
  317. %endmacro
  318. %macro UNSPILL 2
  319. movaps m%1, [outq+(%2-8)*16]
  320. %endmacro
  321. %define PASS6 PASS6_AND_PERMUTE
  322. %macro PASS5 0
  323. movaps m2, [ps_cos_vec+160]
  324. shufps m3, m3, 0xcc
  325. BUTTERFLY3 m5, m3, m2, m1
  326. SPILL 5, 8
  327. UNSPILL 1, 9
  328. BUTTERFLY3 m1, m3, m2, m5
  329. SPILL 1, 14
  330. BUTTERFLY3 m4, m3, m2, m5
  331. SPILL 4, 12
  332. BUTTERFLY3 m7, m3, m2, m5
  333. SPILL 7, 13
  334. UNSPILL 5, 10
  335. BUTTERFLY3 m5, m3, m2, m7
  336. SPILL 5, 10
  337. UNSPILL 4, 11
  338. BUTTERFLY3 m4, m3, m2, m7
  339. SPILL 4, 11
  340. BUTTERFLY3 m6, m3, m2, m7
  341. SPILL 6, 9
  342. BUTTERFLY3 m0, m3, m2, m7
  343. SPILL 0, 15
  344. %endmacro
  345. %endif
  346. ; void ff_dct32_float_sse(FFTSample *out, const FFTSample *in)
  347. %macro DCT32_FUNC 0
  348. cglobal dct32_float, 2, 3, 16, out, in, tmp
  349. ; pass 1
  350. movaps m0, [inq+0]
  351. LOAD_INV m1, [inq+112]
  352. BUTTERFLY m0, m1, [ps_cos_vec], m3
  353. movaps m7, [inq+64]
  354. LOAD_INV m4, [inq+48]
  355. BUTTERFLY m7, m4, [ps_cos_vec+32], m3
  356. ; pass 2
  357. movaps m2, [ps_cos_vec+64]
  358. BUTTERFLY m1, m4, m2, m3
  359. SPILL 1, 11
  360. SPILL 4, 8
  361. ; pass 1
  362. movaps m1, [inq+16]
  363. LOAD_INV m6, [inq+96]
  364. BUTTERFLY m1, m6, [ps_cos_vec+16], m3
  365. movaps m4, [inq+80]
  366. LOAD_INV m5, [inq+32]
  367. BUTTERFLY m4, m5, [ps_cos_vec+48], m3
  368. ; pass 2
  369. BUTTERFLY m0, m7, m2, m3
  370. movaps m2, [ps_cos_vec+80]
  371. BUTTERFLY m6, m5, m2, m3
  372. BUTTERFLY m1, m4, m2, m3
  373. ; pass 3
  374. movaps m2, [ps_cos_vec+96]
  375. shufps m1, m1, 0x1b
  376. BUTTERFLY m0, m1, m2, m3
  377. SPILL 0, 15
  378. SPILL 1, 14
  379. UNSPILL 0, 8
  380. shufps m5, m5, 0x1b
  381. BUTTERFLY m0, m5, m2, m3
  382. UNSPILL 1, 11
  383. shufps m6, m6, 0x1b
  384. BUTTERFLY m1, m6, m2, m3
  385. SPILL 1, 11
  386. shufps m4, m4, 0x1b
  387. BUTTERFLY m7, m4, m2, m3
  388. ; pass 4
  389. movaps m3, [ps_p1p1m1m1+0]
  390. movaps m2, [ps_cos_vec+128]
  391. BUTTERFLY2 m5, m3, m2, m1
  392. BUTTERFLY2 m0, m3, m2, m1
  393. SPILL 0, 9
  394. BUTTERFLY2 m6, m3, m2, m1
  395. SPILL 6, 10
  396. UNSPILL 0, 11
  397. BUTTERFLY2 m0, m3, m2, m1
  398. SPILL 0, 11
  399. BUTTERFLY2 m4, m3, m2, m1
  400. BUTTERFLY2 m7, m3, m2, m1
  401. UNSPILL 6, 14
  402. BUTTERFLY2 m6, m3, m2, m1
  403. UNSPILL 0, 15
  404. BUTTERFLY2 m0, m3, m2, m1
  405. PASS5
  406. PASS6
  407. RET
  408. %endmacro
  409. %macro LOAD_INV 2
  410. %if cpuflag(sse2)
  411. pshufd %1, %2, 0x1b
  412. %elif cpuflag(sse)
  413. movaps %1, %2
  414. shufps %1, %1, 0x1b
  415. %endif
  416. %endmacro
  417. INIT_XMM sse
  418. DCT32_FUNC
  419. INIT_XMM sse2
  420. DCT32_FUNC