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.

307 lines
7.4KB

  1. ;******************************************************************************
  2. ;* MMX optimized discrete wavelet trasnform
  3. ;* Copyright (c) 2010 David Conrad
  4. ;*
  5. ;* This file is part of FFmpeg.
  6. ;*
  7. ;* FFmpeg 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. ;* FFmpeg 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 FFmpeg; if not, write to the Free Software
  19. ;* 51, Inc., Foundation Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  20. ;******************************************************************************
  21. %include "libavutil/x86/x86util.asm"
  22. SECTION_RODATA
  23. pw_1: times 8 dw 1
  24. pw_2: times 8 dw 2
  25. pw_8: times 8 dw 8
  26. pw_16: times 8 dw 16
  27. pw_1991: times 4 dw 9,-1
  28. section .text
  29. ; %1 -= (%2 + %3 + 2)>>2 %4 is pw_2
  30. %macro COMPOSE_53iL0 4
  31. paddw %2, %3
  32. paddw %2, %4
  33. psraw %2, 2
  34. psubw %1, %2
  35. %endm
  36. ; m1 = %1 + (-m0 + 9*m1 + 9*%2 -%3 + 8)>>4
  37. ; if %4 is supplied, %1 is loaded unaligned from there
  38. ; m2: clobbered m3: pw_8 m4: pw_1991
  39. %macro COMPOSE_DD97iH0 3-4
  40. paddw m0, %3
  41. paddw m1, %2
  42. psubw m0, m3
  43. mova m2, m1
  44. punpcklwd m1, m0
  45. punpckhwd m2, m0
  46. pmaddwd m1, m4
  47. pmaddwd m2, m4
  48. %if %0 > 3
  49. movu %1, %4
  50. %endif
  51. psrad m1, 4
  52. psrad m2, 4
  53. packssdw m1, m2
  54. paddw m1, %1
  55. %endm
  56. %macro COMPOSE_VERTICAL 1
  57. ; void vertical_compose53iL0(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2,
  58. ; int width)
  59. cglobal vertical_compose53iL0_%1, 4,4,1, b0, b1, b2, width
  60. mova m2, [pw_2]
  61. %if ARCH_X86_64
  62. mov widthd, widthd
  63. %endif
  64. .loop:
  65. sub widthq, mmsize/2
  66. mova m1, [b0q+2*widthq]
  67. mova m0, [b1q+2*widthq]
  68. COMPOSE_53iL0 m0, m1, [b2q+2*widthq], m2
  69. mova [b1q+2*widthq], m0
  70. jg .loop
  71. REP_RET
  72. ; void vertical_compose_dirac53iH0(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2,
  73. ; int width)
  74. cglobal vertical_compose_dirac53iH0_%1, 4,4,1, b0, b1, b2, width
  75. mova m1, [pw_1]
  76. %if ARCH_X86_64
  77. mov widthd, widthd
  78. %endif
  79. .loop:
  80. sub widthq, mmsize/2
  81. mova m0, [b0q+2*widthq]
  82. paddw m0, [b2q+2*widthq]
  83. paddw m0, m1
  84. psraw m0, 1
  85. paddw m0, [b1q+2*widthq]
  86. mova [b1q+2*widthq], m0
  87. jg .loop
  88. REP_RET
  89. ; void vertical_compose_dd97iH0(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2,
  90. ; IDWTELEM *b3, IDWTELEM *b4, int width)
  91. cglobal vertical_compose_dd97iH0_%1, 6,6,5, b0, b1, b2, b3, b4, width
  92. mova m3, [pw_8]
  93. mova m4, [pw_1991]
  94. %if ARCH_X86_64
  95. mov widthd, widthd
  96. %endif
  97. .loop:
  98. sub widthq, mmsize/2
  99. mova m0, [b0q+2*widthq]
  100. mova m1, [b1q+2*widthq]
  101. COMPOSE_DD97iH0 [b2q+2*widthq], [b3q+2*widthq], [b4q+2*widthq]
  102. mova [b2q+2*widthq], m1
  103. jg .loop
  104. REP_RET
  105. ; void vertical_compose_dd137iL0(IDWTELEM *b0, IDWTELEM *b1, IDWTELEM *b2,
  106. ; IDWTELEM *b3, IDWTELEM *b4, int width)
  107. cglobal vertical_compose_dd137iL0_%1, 6,6,6, b0, b1, b2, b3, b4, width
  108. mova m3, [pw_16]
  109. mova m4, [pw_1991]
  110. %if ARCH_X86_64
  111. mov widthd, widthd
  112. %endif
  113. .loop:
  114. sub widthq, mmsize/2
  115. mova m0, [b0q+2*widthq]
  116. mova m1, [b1q+2*widthq]
  117. mova m5, [b2q+2*widthq]
  118. paddw m0, [b4q+2*widthq]
  119. paddw m1, [b3q+2*widthq]
  120. psubw m0, m3
  121. mova m2, m1
  122. punpcklwd m1, m0
  123. punpckhwd m2, m0
  124. pmaddwd m1, m4
  125. pmaddwd m2, m4
  126. psrad m1, 5
  127. psrad m2, 5
  128. packssdw m1, m2
  129. psubw m5, m1
  130. mova [b2q+2*widthq], m5
  131. jg .loop
  132. REP_RET
  133. ; void vertical_compose_haar(IDWTELEM *b0, IDWTELEM *b1, int width)
  134. cglobal vertical_compose_haar_%1, 3,4,3, b0, b1, width
  135. mova m3, [pw_1]
  136. %if ARCH_X86_64
  137. mov widthd, widthd
  138. %endif
  139. .loop:
  140. sub widthq, mmsize/2
  141. mova m1, [b1q+2*widthq]
  142. mova m0, [b0q+2*widthq]
  143. mova m2, m1
  144. paddw m1, m3
  145. psraw m1, 1
  146. psubw m0, m1
  147. mova [b0q+2*widthq], m0
  148. paddw m2, m0
  149. mova [b1q+2*widthq], m2
  150. jg .loop
  151. REP_RET
  152. %endmacro
  153. ; extend the left and right edges of the tmp array by %1 and %2 respectively
  154. %macro EDGE_EXTENSION 3
  155. mov %3, [tmpq]
  156. %assign %%i 1
  157. %rep %1
  158. mov [tmpq-2*%%i], %3
  159. %assign %%i %%i+1
  160. %endrep
  161. mov %3, [tmpq+2*w2q-2]
  162. %assign %%i 0
  163. %rep %2
  164. mov [tmpq+2*w2q+2*%%i], %3
  165. %assign %%i %%i+1
  166. %endrep
  167. %endmacro
  168. %macro HAAR_HORIZONTAL 2
  169. ; void horizontal_compose_haari(IDWTELEM *b, IDWTELEM *tmp, int width)
  170. cglobal horizontal_compose_haar%2i_%1, 3,6,4, b, tmp, w, x, w2, b_w2
  171. mov w2d, wd
  172. xor xq, xq
  173. shr w2d, 1
  174. lea b_w2q, [bq+wq]
  175. mova m3, [pw_1]
  176. .lowpass_loop:
  177. movu m1, [b_w2q + 2*xq]
  178. mova m0, [bq + 2*xq]
  179. paddw m1, m3
  180. psraw m1, 1
  181. psubw m0, m1
  182. mova [tmpq + 2*xq], m0
  183. add xq, mmsize/2
  184. cmp xq, w2q
  185. jl .lowpass_loop
  186. xor xq, xq
  187. and w2q, ~(mmsize/2 - 1)
  188. cmp w2q, mmsize/2
  189. jl .end
  190. .highpass_loop:
  191. movu m1, [b_w2q + 2*xq]
  192. mova m0, [tmpq + 2*xq]
  193. paddw m1, m0
  194. ; shift and interleave
  195. %if %2 == 1
  196. paddw m0, m3
  197. paddw m1, m3
  198. psraw m0, 1
  199. psraw m1, 1
  200. %endif
  201. mova m2, m0
  202. punpcklwd m0, m1
  203. punpckhwd m2, m1
  204. mova [bq+4*xq], m0
  205. mova [bq+4*xq+mmsize], m2
  206. add xq, mmsize/2
  207. cmp xq, w2q
  208. jl .highpass_loop
  209. .end:
  210. REP_RET
  211. %endmacro
  212. INIT_XMM
  213. ; void horizontal_compose_dd97i(IDWTELEM *b, IDWTELEM *tmp, int width)
  214. cglobal horizontal_compose_dd97i_ssse3, 3,6,8, b, tmp, w, x, w2, b_w2
  215. mov w2d, wd
  216. xor xd, xd
  217. shr w2d, 1
  218. lea b_w2q, [bq+wq]
  219. movu m4, [bq+wq]
  220. mova m7, [pw_2]
  221. pslldq m4, 14
  222. .lowpass_loop:
  223. movu m1, [b_w2q + 2*xq]
  224. mova m0, [bq + 2*xq]
  225. mova m2, m1
  226. palignr m1, m4, 14
  227. mova m4, m2
  228. COMPOSE_53iL0 m0, m1, m2, m7
  229. mova [tmpq + 2*xq], m0
  230. add xd, mmsize/2
  231. cmp xd, w2d
  232. jl .lowpass_loop
  233. EDGE_EXTENSION 1, 2, xw
  234. ; leave the last up to 7 (sse) or 3 (mmx) values for C
  235. xor xd, xd
  236. and w2d, ~(mmsize/2 - 1)
  237. cmp w2d, mmsize/2
  238. jl .end
  239. mova m7, [tmpq-mmsize]
  240. mova m0, [tmpq]
  241. mova m5, [pw_1]
  242. mova m3, [pw_8]
  243. mova m4, [pw_1991]
  244. .highpass_loop:
  245. mova m6, m0
  246. palignr m0, m7, 14
  247. mova m7, [tmpq + 2*xq + 16]
  248. mova m1, m7
  249. mova m2, m7
  250. palignr m1, m6, 2
  251. palignr m2, m6, 4
  252. COMPOSE_DD97iH0 m0, m6, m2, [b_w2q + 2*xq]
  253. mova m0, m7
  254. mova m7, m6
  255. ; shift and interleave
  256. paddw m6, m5
  257. paddw m1, m5
  258. psraw m6, 1
  259. psraw m1, 1
  260. mova m2, m6
  261. punpcklwd m6, m1
  262. punpckhwd m2, m1
  263. mova [bq+4*xq], m6
  264. mova [bq+4*xq+mmsize], m2
  265. add xd, mmsize/2
  266. cmp xd, w2d
  267. jl .highpass_loop
  268. .end:
  269. REP_RET
  270. %if ARCH_X86_64 == 0
  271. INIT_MMX
  272. COMPOSE_VERTICAL mmx
  273. HAAR_HORIZONTAL mmx, 0
  274. HAAR_HORIZONTAL mmx, 1
  275. %endif
  276. ;;INIT_XMM
  277. INIT_XMM
  278. COMPOSE_VERTICAL sse2
  279. HAAR_HORIZONTAL sse2, 0
  280. HAAR_HORIZONTAL sse2, 1