x86/vp9: add avx2 subpel MC SIMD for 10/12bpp
[ffmpeg.git] / libavcodec / x86 / vp9mc_16bpp.asm
1 ;******************************************************************************
2 ;* VP9 MC SIMD optimizations
3 ;*
4 ;* Copyright (c) 2015 Ronald S. Bultje <rsbultje gmail com>
5 ;*
6 ;* This file is part of FFmpeg.
7 ;*
8 ;* FFmpeg is free software; you can redistribute it and/or
9 ;* modify it under the terms of the GNU Lesser General Public
10 ;* License as published by the Free Software Foundation; either
11 ;* version 2.1 of the License, or (at your option) any later version.
12 ;*
13 ;* FFmpeg is distributed in the hope that it will be useful,
14 ;* but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16 ;* Lesser General Public License for more details.
17 ;*
18 ;* You should have received a copy of the GNU Lesser General Public
19 ;* License along with FFmpeg; if not, write to the Free Software
20 ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 ;******************************************************************************
22
23 %include "libavutil/x86/x86util.asm"
24
25 SECTION_RODATA 32
26
27 pw_4095: times 16 dw 0xfff
28 pd_64: times 8 dd 64
29
30 cextern pw_1023
31
32 SECTION .text
33
34 %macro filter_h4_fn 1-2 12
35 cglobal vp9_%1_8tap_1d_h_4_10, 6, 6, %2, dst, dstride, src, sstride, h, filtery
36     mova        m5, [pw_1023]
37 .body:
38 %if notcpuflag(sse4) && ARCH_X86_64
39     pxor       m11, m11
40 %endif
41     mova        m6, [pd_64]
42     mova        m7, [filteryq+ 0]
43 %if ARCH_X86_64 && mmsize > 8
44     mova        m8, [filteryq+32]
45     mova        m9, [filteryq+64]
46     mova       m10, [filteryq+96]
47 %endif
48 .loop:
49     movh        m0, [srcq-6]
50     movh        m1, [srcq-4]
51     movh        m2, [srcq-2]
52     movh        m3, [srcq+0]
53     movh        m4, [srcq+2]
54     punpcklwd   m0, m1
55     punpcklwd   m2, m3
56     pmaddwd     m0, m7
57 %if ARCH_X86_64 && mmsize > 8
58     pmaddwd     m2, m8
59 %else
60     pmaddwd     m2, [filteryq+32]
61 %endif
62     movu        m1, [srcq+4]
63     movu        m3, [srcq+6]
64     paddd       m0, m2
65     movu        m2, [srcq+8]
66     add       srcq, sstrideq
67     punpcklwd   m4, m1
68     punpcklwd   m3, m2
69 %if ARCH_X86_64 && mmsize > 8
70     pmaddwd     m4, m9
71     pmaddwd     m3, m10
72 %else
73     pmaddwd     m4, [filteryq+64]
74     pmaddwd     m3, [filteryq+96]
75 %endif
76     paddd       m0, m4
77     paddd       m0, m3
78     paddd       m0, m6
79     psrad       m0, 7
80 %if cpuflag(sse4)
81     packusdw    m0, m0
82 %else
83     packssdw    m0, m0
84 %endif
85 %ifidn %1, avg
86     movh        m1, [dstq]
87 %endif
88     pminsw      m0, m5
89 %if notcpuflag(sse4)
90 %if ARCH_X86_64
91     pmaxsw      m0, m11
92 %else
93     pxor        m2, m2
94     pmaxsw      m0, m2
95 %endif
96 %endif
97 %ifidn %1, avg
98     pavgw       m0, m1
99 %endif
100     movh    [dstq], m0
101     add       dstq, dstrideq
102     dec         hd
103     jg .loop
104     RET
105
106 cglobal vp9_%1_8tap_1d_h_4_12, 6, 6, %2, dst, dstride, src, sstride, h, filtery
107     mova        m5, [pw_4095]
108     jmp mangle(private_prefix %+ _ %+ vp9_%1_8tap_1d_h_4_10 %+ SUFFIX).body
109 %endmacro
110
111 INIT_XMM sse2
112 filter_h4_fn put
113 filter_h4_fn avg
114
115 %macro filter_h_fn 1-2 12
116 %assign %%px mmsize/2
117 cglobal vp9_%1_8tap_1d_h_ %+ %%px %+ _10, 6, 6, %2, dst, dstride, src, sstride, h, filtery
118     mova        m5, [pw_1023]
119 .body:
120 %if notcpuflag(sse4) && ARCH_X86_64
121     pxor       m11, m11
122 %endif
123     mova        m6, [pd_64]
124     mova        m7, [filteryq+ 0]
125 %if ARCH_X86_64 && mmsize > 8
126     mova        m8, [filteryq+32]
127     mova        m9, [filteryq+64]
128     mova       m10, [filteryq+96]
129 %endif
130 .loop:
131     movu        m0, [srcq-6]
132     movu        m1, [srcq-4]
133     movu        m2, [srcq-2]
134     movu        m3, [srcq+0]
135     movu        m4, [srcq+2]
136     pmaddwd     m0, m7
137     pmaddwd     m1, m7
138 %if ARCH_X86_64 && mmsize > 8
139     pmaddwd     m2, m8
140     pmaddwd     m3, m8
141     pmaddwd     m4, m9
142 %else
143     pmaddwd     m2, [filteryq+32]
144     pmaddwd     m3, [filteryq+32]
145     pmaddwd     m4, [filteryq+64]
146 %endif
147     paddd       m0, m2
148     paddd       m1, m3
149     paddd       m0, m4
150     movu        m2, [srcq+4]
151     movu        m3, [srcq+6]
152     movu        m4, [srcq+8]
153     add       srcq, sstrideq
154 %if ARCH_X86_64 && mmsize > 8
155     pmaddwd     m2, m9
156     pmaddwd     m3, m10
157     pmaddwd     m4, m10
158 %else
159     pmaddwd     m2, [filteryq+64]
160     pmaddwd     m3, [filteryq+96]
161     pmaddwd     m4, [filteryq+96]
162 %endif
163     paddd       m1, m2
164     paddd       m0, m3
165     paddd       m1, m4
166     paddd       m0, m6
167     paddd       m1, m6
168     psrad       m0, 7
169     psrad       m1, 7
170 %if cpuflag(sse4)
171     packusdw    m0, m0
172     packusdw    m1, m1
173 %else
174     packssdw    m0, m0
175     packssdw    m1, m1
176 %endif
177     punpcklwd   m0, m1
178     pminsw      m0, m5
179 %if notcpuflag(sse4)
180 %if ARCH_X86_64
181     pmaxsw      m0, m11
182 %else
183     pxor        m2, m2
184     pmaxsw      m0, m2
185 %endif
186 %endif
187 %ifidn %1, avg
188     pavgw       m0, [dstq]
189 %endif
190     mova    [dstq], m0
191     add       dstq, dstrideq
192     dec         hd
193     jg .loop
194     RET
195
196 cglobal vp9_%1_8tap_1d_h_ %+ %%px %+ _12, 6, 6, %2, dst, dstride, src, sstride, h, filtery
197     mova        m5, [pw_4095]
198     jmp mangle(private_prefix %+ _ %+ vp9_%1_8tap_1d_h_ %+ %%px %+ _10 %+ SUFFIX).body
199 %endmacro
200
201 INIT_XMM sse2
202 filter_h_fn put
203 filter_h_fn avg
204 INIT_YMM avx2
205 filter_h_fn put
206 filter_h_fn avg
207
208 %macro filter_v4_fn 1-2 12
209 %if ARCH_X86_64
210 cglobal vp9_%1_8tap_1d_v_4_10, 6, 8, %2, dst, dstride, src, sstride, h, filtery, src4, sstride3
211 %else
212 cglobal vp9_%1_8tap_1d_v_4_10, 4, 7, %2, dst, dstride, src, sstride, filtery, src4, sstride3
213     mov   filteryq, r5mp
214 %define hd r4mp
215 %endif
216     mova        m5, [pw_1023]
217 .body:
218 %if notcpuflag(sse4) && ARCH_X86_64
219     pxor       m11, m11
220 %endif
221     mova        m6, [pd_64]
222     lea  sstride3q, [sstrideq*3]
223     lea      src4q, [srcq+sstrideq]
224     sub       srcq, sstride3q
225     mova        m7, [filteryq+  0]
226 %if ARCH_X86_64 && mmsize > 8
227     mova        m8, [filteryq+ 32]
228     mova        m9, [filteryq+ 64]
229     mova       m10, [filteryq+ 96]
230 %endif
231 .loop:
232     ; FIXME maybe reuse loads from previous rows, or just
233     ; more generally unroll this to prevent multiple loads of
234     ; the same data?
235     movh        m0, [srcq]
236     movh        m1, [srcq+sstrideq]
237     movh        m2, [srcq+sstrideq*2]
238     movh        m3, [srcq+sstride3q]
239     add       srcq, sstrideq
240     movh        m4, [src4q]
241     punpcklwd   m0, m1
242     punpcklwd   m2, m3
243     pmaddwd     m0, m7
244 %if ARCH_X86_64 && mmsize > 8
245     pmaddwd     m2, m8
246 %else
247     pmaddwd     m2, [filteryq+ 32]
248 %endif
249     movh        m1, [src4q+sstrideq]
250     movh        m3, [src4q+sstrideq*2]
251     paddd       m0, m2
252     movh        m2, [src4q+sstride3q]
253     add      src4q, sstrideq
254     punpcklwd   m4, m1
255     punpcklwd   m3, m2
256 %if ARCH_X86_64 && mmsize > 8
257     pmaddwd     m4, m9
258     pmaddwd     m3, m10
259 %else
260     pmaddwd     m4, [filteryq+ 64]
261     pmaddwd     m3, [filteryq+ 96]
262 %endif
263     paddd       m0, m4
264     paddd       m0, m3
265     paddd       m0, m6
266     psrad       m0, 7
267 %if cpuflag(sse4)
268     packusdw    m0, m0
269 %else
270     packssdw    m0, m0
271 %endif
272 %ifidn %1, avg
273     movh        m1, [dstq]
274 %endif
275     pminsw      m0, m5
276 %if notcpuflag(sse4)
277 %if ARCH_X86_64
278     pmaxsw      m0, m11
279 %else
280     pxor        m2, m2
281     pmaxsw      m0, m2
282 %endif
283 %endif
284 %ifidn %1, avg
285     pavgw       m0, m1
286 %endif
287     movh    [dstq], m0
288     add       dstq, dstrideq
289     dec         hd
290     jg .loop
291     RET
292
293 %if ARCH_X86_64
294 cglobal vp9_%1_8tap_1d_v_4_12, 6, 8, %2, dst, dstride, src, sstride, h, filtery, src4, sstride3
295 %else
296 cglobal vp9_%1_8tap_1d_v_4_12, 4, 7, %2, dst, dstride, src, sstride, filtery, src4, sstride3
297     mov   filteryq, r5mp
298 %endif
299     mova        m5, [pw_4095]
300     jmp mangle(private_prefix %+ _ %+ vp9_%1_8tap_1d_v_4_10 %+ SUFFIX).body
301 %endmacro
302
303 INIT_XMM sse2
304 filter_v4_fn put
305 filter_v4_fn avg
306
307 %macro filter_v_fn 1-2 13
308 %assign %%px mmsize/2
309 %if ARCH_X86_64
310 cglobal vp9_%1_8tap_1d_v_ %+ %%px %+ _10, 6, 8, %2, dst, dstride, src, sstride, h, filtery, src4, sstride3
311 %else
312 cglobal vp9_%1_8tap_1d_v_ %+ %%px %+ _10, 4, 7, %2, dst, dstride, src, sstride, filtery, src4, sstride3
313     mov   filteryq, r5mp
314 %define hd r4mp
315 %endif
316     mova        m5, [pw_1023]
317 .body:
318 %if notcpuflag(sse4) && ARCH_X86_64
319     pxor       m12, m12
320 %endif
321 %if ARCH_X86_64
322     mova       m11, [pd_64]
323 %endif
324     lea  sstride3q, [sstrideq*3]
325     lea      src4q, [srcq+sstrideq]
326     sub       srcq, sstride3q
327     mova        m7, [filteryq+  0]
328 %if ARCH_X86_64 && mmsize > 8
329     mova        m8, [filteryq+ 32]
330     mova        m9, [filteryq+ 64]
331     mova       m10, [filteryq+ 96]
332 %endif
333 .loop:
334     ; FIXME maybe reuse loads from previous rows, or just
335     ; more generally unroll this to prevent multiple loads of
336     ; the same data?
337     movu        m0, [srcq]
338     movu        m1, [srcq+sstrideq]
339     movu        m2, [srcq+sstrideq*2]
340     movu        m3, [srcq+sstride3q]
341     add       srcq, sstrideq
342     movu        m4, [src4q]
343     SBUTTERFLY  wd, 0, 1, 6
344     SBUTTERFLY  wd, 2, 3, 6
345     pmaddwd     m0, m7
346     pmaddwd     m1, m7
347 %if ARCH_X86_64 && mmsize > 8
348     pmaddwd     m2, m8
349     pmaddwd     m3, m8
350 %else
351     pmaddwd     m2, [filteryq+ 32]
352     pmaddwd     m3, [filteryq+ 32]
353 %endif
354     paddd       m0, m2
355     paddd       m1, m3
356     movu        m2, [src4q+sstrideq]
357     movu        m3, [src4q+sstrideq*2]
358     SBUTTERFLY  wd, 4, 2, 6
359 %if ARCH_X86_64 && mmsize > 8
360     pmaddwd     m4, m9
361     pmaddwd     m2, m9
362 %else
363     pmaddwd     m4, [filteryq+ 64]
364     pmaddwd     m2, [filteryq+ 64]
365 %endif
366     paddd       m0, m4
367     paddd       m1, m2
368     movu        m4, [src4q+sstride3q]
369     add      src4q, sstrideq
370     SBUTTERFLY  wd, 3, 4, 6
371 %if ARCH_X86_64 && mmsize > 8
372     pmaddwd     m3, m10
373     pmaddwd     m4, m10
374 %else
375     pmaddwd     m3, [filteryq+ 96]
376     pmaddwd     m4, [filteryq+ 96]
377 %endif
378     paddd       m0, m3
379     paddd       m1, m4
380 %if ARCH_X86_64
381     paddd       m0, m11
382     paddd       m1, m11
383 %else
384     paddd       m0, [pd_64]
385     paddd       m1, [pd_64]
386 %endif
387     psrad       m0, 7
388     psrad       m1, 7
389 %if cpuflag(sse4)
390     packusdw    m0, m1
391 %else
392     packssdw    m0, m1
393 %endif
394     pminsw      m0, m5
395 %if notcpuflag(sse4)
396 %if ARCH_X86_64
397     pmaxsw      m0, m12
398 %else
399     pxor        m2, m2
400     pmaxsw      m0, m2
401 %endif
402 %endif
403 %ifidn %1, avg
404     pavgw       m0, [dstq]
405 %endif
406     mova    [dstq], m0
407     add       dstq, dstrideq
408     dec         hd
409     jg .loop
410     RET
411
412 %if ARCH_X86_64
413 cglobal vp9_%1_8tap_1d_v_ %+ %%px %+ _12, 6, 8, %2, dst, dstride, src, sstride, h, filtery, src4, sstride3
414 %else
415 cglobal vp9_%1_8tap_1d_v_ %+ %%px %+ _12, 4, 7, %2, dst, dstride, src, sstride, filtery, src4, sstride3
416     mov   filteryq, r5mp
417 %endif
418     mova        m5, [pw_4095]
419     jmp mangle(private_prefix %+ _ %+ vp9_%1_8tap_1d_v_ %+ %%px %+ _10 %+ SUFFIX).body
420 %endmacro
421
422 INIT_XMM sse2
423 filter_v_fn put
424 filter_v_fn avg
425 INIT_YMM avx2
426 filter_v_fn put
427 filter_v_fn avg