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.

313 lines
7.7KB

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