15e93ea6cb0bc5eff1047f39d7c3696f0d3a3ea6
[ffmpeg.git] / libavcodec / x86 / vp9mc.asm
1 ;******************************************************************************
2 ;* VP9 motion compensation SIMD optimizations
3 ;*
4 ;* Copyright (c) 2013 Ronald S. Bultje <rsbultje gmail com>
5 ;*
6 ;* This file is part of Libav.
7 ;*
8 ;* Libav 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 ;* Libav 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 Libav; 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 cextern pw_256
28 cextern pw_64
29
30 %macro F8_SSSE3_TAPS 8
31 times 16 db %1, %2
32 times 16 db %3, %4
33 times 16 db %5, %6
34 times 16 db %7, %8
35 %endmacro
36
37 %macro F8_SSE2_TAPS 8
38 times 8 dw %1
39 times 8 dw %2
40 times 8 dw %3
41 times 8 dw %4
42 times 8 dw %5
43 times 8 dw %6
44 times 8 dw %7
45 times 8 dw %8
46 %endmacro
47
48 %macro FILTER 1
49 const filters_%1 ; smooth
50                     F8_TAPS -3, -1,  32,  64,  38,   1, -3,  0
51                     F8_TAPS -2, -2,  29,  63,  41,   2, -3,  0
52                     F8_TAPS -2, -2,  26,  63,  43,   4, -4,  0
53                     F8_TAPS -2, -3,  24,  62,  46,   5, -4,  0
54                     F8_TAPS -2, -3,  21,  60,  49,   7, -4,  0
55                     F8_TAPS -1, -4,  18,  59,  51,   9, -4,  0
56                     F8_TAPS -1, -4,  16,  57,  53,  12, -4, -1
57                     F8_TAPS -1, -4,  14,  55,  55,  14, -4, -1
58                     F8_TAPS -1, -4,  12,  53,  57,  16, -4, -1
59                     F8_TAPS  0, -4,   9,  51,  59,  18, -4, -1
60                     F8_TAPS  0, -4,   7,  49,  60,  21, -3, -2
61                     F8_TAPS  0, -4,   5,  46,  62,  24, -3, -2
62                     F8_TAPS  0, -4,   4,  43,  63,  26, -2, -2
63                     F8_TAPS  0, -3,   2,  41,  63,  29, -2, -2
64                     F8_TAPS  0, -3,   1,  38,  64,  32, -1, -3
65                     ; regular
66                     F8_TAPS  0,  1,  -5, 126,   8,  -3,  1,  0
67                     F8_TAPS -1,  3, -10, 122,  18,  -6,  2,  0
68                     F8_TAPS -1,  4, -13, 118,  27,  -9,  3, -1
69                     F8_TAPS -1,  4, -16, 112,  37, -11,  4, -1
70                     F8_TAPS -1,  5, -18, 105,  48, -14,  4, -1
71                     F8_TAPS -1,  5, -19,  97,  58, -16,  5, -1
72                     F8_TAPS -1,  6, -19,  88,  68, -18,  5, -1
73                     F8_TAPS -1,  6, -19,  78,  78, -19,  6, -1
74                     F8_TAPS -1,  5, -18,  68,  88, -19,  6, -1
75                     F8_TAPS -1,  5, -16,  58,  97, -19,  5, -1
76                     F8_TAPS -1,  4, -14,  48, 105, -18,  5, -1
77                     F8_TAPS -1,  4, -11,  37, 112, -16,  4, -1
78                     F8_TAPS -1,  3,  -9,  27, 118, -13,  4, -1
79                     F8_TAPS  0,  2,  -6,  18, 122, -10,  3, -1
80                     F8_TAPS  0,  1,  -3,   8, 126,  -5,  1,  0
81                     ; sharp
82                     F8_TAPS -1,  3,  -7, 127,   8,  -3,  1,  0
83                     F8_TAPS -2,  5, -13, 125,  17,  -6,  3, -1
84                     F8_TAPS -3,  7, -17, 121,  27, -10,  5, -2
85                     F8_TAPS -4,  9, -20, 115,  37, -13,  6, -2
86                     F8_TAPS -4, 10, -23, 108,  48, -16,  8, -3
87                     F8_TAPS -4, 10, -24, 100,  59, -19,  9, -3
88                     F8_TAPS -4, 11, -24,  90,  70, -21, 10, -4
89                     F8_TAPS -4, 11, -23,  80,  80, -23, 11, -4
90                     F8_TAPS -4, 10, -21,  70,  90, -24, 11, -4
91                     F8_TAPS -3,  9, -19,  59, 100, -24, 10, -4
92                     F8_TAPS -3,  8, -16,  48, 108, -23, 10, -4
93                     F8_TAPS -2,  6, -13,  37, 115, -20,  9, -4
94                     F8_TAPS -2,  5, -10,  27, 121, -17,  7, -3
95                     F8_TAPS -1,  3,  -6,  17, 125, -13,  5, -2
96                     F8_TAPS  0,  1,  -3,   8, 127,  -7,  3, -1
97 %endmacro
98
99 %define F8_TAPS F8_SSSE3_TAPS
100 ; int8_t ff_filters_ssse3[3][15][4][32]
101 FILTER ssse3
102 %define F8_TAPS F8_SSE2_TAPS
103 ; int16_t ff_filters_sse2[3][15][8][8]
104 FILTER sse2
105
106 SECTION .text
107
108 %macro filter_sse2_h_fn 1
109 %assign %%px mmsize/2
110 cglobal vp9_%1_8tap_1d_h_ %+ %%px, 6, 6, 15, dst, src, dstride, sstride, h, filtery
111     pxor        m5, m5
112     mova        m6, [pw_64]
113     mova        m7, [filteryq+  0]
114 %if ARCH_X86_64 && mmsize > 8
115     mova        m8, [filteryq+ 16]
116     mova        m9, [filteryq+ 32]
117     mova       m10, [filteryq+ 48]
118     mova       m11, [filteryq+ 64]
119     mova       m12, [filteryq+ 80]
120     mova       m13, [filteryq+ 96]
121     mova       m14, [filteryq+112]
122 %endif
123 .loop:
124     movh        m0, [srcq-3]
125     movh        m1, [srcq-2]
126     movh        m2, [srcq-1]
127     movh        m3, [srcq+0]
128     movh        m4, [srcq+1]
129     punpcklbw   m0, m5
130     punpcklbw   m1, m5
131     punpcklbw   m2, m5
132     punpcklbw   m3, m5
133     punpcklbw   m4, m5
134     pmullw      m0, m7
135 %if ARCH_X86_64 && mmsize > 8
136     pmullw      m1, m8
137     pmullw      m2, m9
138     pmullw      m3, m10
139     pmullw      m4, m11
140 %else
141     pmullw      m1, [filteryq+ 16]
142     pmullw      m2, [filteryq+ 32]
143     pmullw      m3, [filteryq+ 48]
144     pmullw      m4, [filteryq+ 64]
145 %endif
146     paddw       m0, m1
147     paddw       m2, m3
148     paddw       m0, m4
149     movh        m1, [srcq+2]
150     movh        m3, [srcq+3]
151     movh        m4, [srcq+4]
152     add       srcq, sstrideq
153     punpcklbw   m1, m5
154     punpcklbw   m3, m5
155     punpcklbw   m4, m5
156 %if ARCH_X86_64 && mmsize > 8
157     pmullw      m1, m12
158     pmullw      m3, m13
159     pmullw      m4, m14
160 %else
161     pmullw      m1, [filteryq+ 80]
162     pmullw      m3, [filteryq+ 96]
163     pmullw      m4, [filteryq+112]
164 %endif
165     paddw       m0, m1
166     paddw       m3, m4
167     paddw       m0, m6
168     paddw       m2, m3
169     paddsw      m0, m2
170     psraw       m0, 7
171 %ifidn %1, avg
172     movh        m1, [dstq]
173 %endif
174     packuswb    m0, m0
175 %ifidn %1, avg
176     pavgb       m0, m1
177 %endif
178     movh    [dstq], m0
179     add       dstq, dstrideq
180     dec         hd
181     jg .loop
182     RET
183 %endmacro
184
185 INIT_MMX mmxext
186 filter_sse2_h_fn put
187 filter_sse2_h_fn avg
188
189 INIT_XMM sse2
190 filter_sse2_h_fn put
191 filter_sse2_h_fn avg
192
193 %macro filter_h_fn 1
194 %assign %%px mmsize/2
195 cglobal vp9_%1_8tap_1d_h_ %+ %%px, 6, 6, 11, dst, src, dstride, sstride, h, filtery
196     mova        m6, [pw_256]
197     mova        m7, [filteryq+ 0]
198 %if ARCH_X86_64 && mmsize > 8
199     mova        m8, [filteryq+32]
200     mova        m9, [filteryq+64]
201     mova       m10, [filteryq+96]
202 %endif
203 .loop:
204     movh        m0, [srcq-3]
205     movh        m1, [srcq-2]
206     movh        m2, [srcq-1]
207     movh        m3, [srcq+0]
208     movh        m4, [srcq+1]
209     movh        m5, [srcq+2]
210     punpcklbw   m0, m1
211     punpcklbw   m2, m3
212     movh        m1, [srcq+3]
213     movh        m3, [srcq+4]
214     add       srcq, sstrideq
215     punpcklbw   m4, m5
216     punpcklbw   m1, m3
217     pmaddubsw   m0, m7
218 %if ARCH_X86_64 && mmsize > 8
219     pmaddubsw   m2, m8
220     pmaddubsw   m4, m9
221     pmaddubsw   m1, m10
222 %else
223     pmaddubsw   m2, [filteryq+32]
224     pmaddubsw   m4, [filteryq+64]
225     pmaddubsw   m1, [filteryq+96]
226 %endif
227     paddw       m0, m4
228     paddw       m2, m1
229     paddsw      m0, m2
230     pmulhrsw    m0, m6
231 %ifidn %1, avg
232     movh        m1, [dstq]
233 %endif
234     packuswb    m0, m0
235 %ifidn %1, avg
236     pavgb       m0, m1
237 %endif
238     movh    [dstq], m0
239     add       dstq, dstrideq
240     dec         hd
241     jg .loop
242     RET
243 %endmacro
244
245 INIT_MMX ssse3
246 filter_h_fn put
247 filter_h_fn avg
248
249 INIT_XMM ssse3
250 filter_h_fn put
251 filter_h_fn avg
252
253 %if ARCH_X86_64
254 %macro filter_hx2_fn 1
255 %assign %%px mmsize
256 cglobal vp9_%1_8tap_1d_h_ %+ %%px, 6, 6, 14, dst, src, dstride, sstride, h, filtery
257     mova       m13, [pw_256]
258     mova        m8, [filteryq+ 0]
259     mova        m9, [filteryq+32]
260     mova       m10, [filteryq+64]
261     mova       m11, [filteryq+96]
262 .loop:
263     movu        m0, [srcq-3]
264     movu        m1, [srcq-2]
265     movu        m2, [srcq-1]
266     movu        m3, [srcq+0]
267     movu        m4, [srcq+1]
268     movu        m5, [srcq+2]
269     movu        m6, [srcq+3]
270     movu        m7, [srcq+4]
271     add       srcq, sstrideq
272     SBUTTERFLY  bw, 0, 1, 12
273     SBUTTERFLY  bw, 2, 3, 12
274     SBUTTERFLY  bw, 4, 5, 12
275     SBUTTERFLY  bw, 6, 7, 12
276     pmaddubsw   m0, m8
277     pmaddubsw   m1, m8
278     pmaddubsw   m2, m9
279     pmaddubsw   m3, m9
280     pmaddubsw   m4, m10
281     pmaddubsw   m5, m10
282     pmaddubsw   m6, m11
283     pmaddubsw   m7, m11
284     paddw       m0, m4
285     paddw       m1, m5
286     paddw       m2, m6
287     paddw       m3, m7
288     paddsw      m0, m2
289     paddsw      m1, m3
290     pmulhrsw    m0, m13
291     pmulhrsw    m1, m13
292     packuswb    m0, m1
293 %ifidn %1, avg
294     pavgb       m0, [dstq]
295 %endif
296     mova    [dstq], m0
297     add       dstq, dstrideq
298     dec         hd
299     jg .loop
300     RET
301 %endmacro
302
303 INIT_XMM ssse3
304 filter_hx2_fn put
305 filter_hx2_fn avg
306
307 %if HAVE_AVX2_EXTERNAL
308 INIT_YMM avx2
309 filter_hx2_fn put
310 filter_hx2_fn avg
311 %endif
312
313 %endif ; ARCH_X86_64
314
315 %macro filter_sse2_v_fn 1
316 %assign %%px mmsize/2
317 %if ARCH_X86_64
318 cglobal vp9_%1_8tap_1d_v_ %+ %%px, 6, 8, 15, dst, src, dstride, sstride, h, filtery, src4, sstride3
319 %else
320 cglobal vp9_%1_8tap_1d_v_ %+ %%px, 4, 7, 15, dst, src, dstride, sstride, filtery, src4, sstride3
321     mov   filteryq, r5mp
322 %define hd r4mp
323 %endif
324     pxor        m5, m5
325     mova        m6, [pw_64]
326     lea  sstride3q, [sstrideq*3]
327     lea      src4q, [srcq+sstrideq]
328     sub       srcq, sstride3q
329     mova        m7, [filteryq+  0]
330 %if ARCH_X86_64 && mmsize > 8
331     mova        m8, [filteryq+ 16]
332     mova        m9, [filteryq+ 32]
333     mova       m10, [filteryq+ 48]
334     mova       m11, [filteryq+ 64]
335     mova       m12, [filteryq+ 80]
336     mova       m13, [filteryq+ 96]
337     mova       m14, [filteryq+112]
338 %endif
339 .loop:
340     ; FIXME maybe reuse loads from previous rows, or just
341     ; more generally unroll this to prevent multiple loads of
342     ; the same data?
343     movh        m0, [srcq]
344     movh        m1, [srcq+sstrideq]
345     movh        m2, [srcq+sstrideq*2]
346     movh        m3, [srcq+sstride3q]
347     add       srcq, sstrideq
348     movh        m4, [src4q]
349     punpcklbw   m0, m5
350     punpcklbw   m1, m5
351     punpcklbw   m2, m5
352     punpcklbw   m3, m5
353     punpcklbw   m4, m5
354     pmullw      m0, m7
355 %if ARCH_X86_64 && mmsize > 8
356     pmullw      m1, m8
357     pmullw      m2, m9
358     pmullw      m3, m10
359     pmullw      m4, m11
360 %else
361     pmullw      m1, [filteryq+ 16]
362     pmullw      m2, [filteryq+ 32]
363     pmullw      m3, [filteryq+ 48]
364     pmullw      m4, [filteryq+ 64]
365 %endif
366     paddw       m0, m1
367     paddw       m2, m3
368     paddw       m0, m4
369     movh        m1, [src4q+sstrideq]
370     movh        m3, [src4q+sstrideq*2]
371     movh        m4, [src4q+sstride3q]
372     add      src4q, sstrideq
373     punpcklbw   m1, m5
374     punpcklbw   m3, m5
375     punpcklbw   m4, m5
376 %if ARCH_X86_64 && mmsize > 8
377     pmullw      m1, m12
378     pmullw      m3, m13
379     pmullw      m4, m14
380 %else
381     pmullw      m1, [filteryq+ 80]
382     pmullw      m3, [filteryq+ 96]
383     pmullw      m4, [filteryq+112]
384 %endif
385     paddw       m0, m1
386     paddw       m3, m4
387     paddw       m0, m6
388     paddw       m2, m3
389     paddsw      m0, m2
390     psraw       m0, 7
391 %ifidn %1, avg
392     movh        m1, [dstq]
393 %endif
394     packuswb    m0, m0
395 %ifidn %1, avg
396     pavgb       m0, m1
397 %endif
398     movh    [dstq], m0
399     add       dstq, dstrideq
400     dec         hd
401     jg .loop
402     RET
403 %endmacro
404
405 INIT_MMX mmxext
406 filter_sse2_v_fn put
407 filter_sse2_v_fn avg
408
409 INIT_XMM sse2
410 filter_sse2_v_fn put
411 filter_sse2_v_fn avg
412
413 %macro filter_v_fn 1
414 %assign %%px mmsize/2
415 %if ARCH_X86_64
416 cglobal vp9_%1_8tap_1d_v_ %+ %%px, 6, 8, 11, dst, src, dstride, sstride, h, filtery, src4, sstride3
417 %else
418 cglobal vp9_%1_8tap_1d_v_ %+ %%px, 4, 7, 11, dst, src, dstride, sstride, filtery, src4, sstride3
419     mov   filteryq, r5mp
420 %define hd r4mp
421 %endif
422     mova        m6, [pw_256]
423     lea  sstride3q, [sstrideq*3]
424     lea      src4q, [srcq+sstrideq]
425     sub       srcq, sstride3q
426     mova        m7, [filteryq+ 0]
427 %if ARCH_X86_64 && mmsize > 8
428     mova        m8, [filteryq+32]
429     mova        m9, [filteryq+64]
430     mova       m10, [filteryq+96]
431 %endif
432 .loop:
433     ; FIXME maybe reuse loads from previous rows, or just more generally
434     ; unroll this to prevent multiple loads of the same data?
435     movh        m0, [srcq]
436     movh        m1, [srcq+sstrideq]
437     movh        m2, [srcq+sstrideq*2]
438     movh        m3, [srcq+sstride3q]
439     movh        m4, [src4q]
440     movh        m5, [src4q+sstrideq]
441     punpcklbw   m0, m1
442     punpcklbw   m2, m3
443     movh        m1, [src4q+sstrideq*2]
444     movh        m3, [src4q+sstride3q]
445     add       srcq, sstrideq
446     add      src4q, sstrideq
447     punpcklbw   m4, m5
448     punpcklbw   m1, m3
449     pmaddubsw   m0, m7
450 %if ARCH_X86_64 && mmsize > 8
451     pmaddubsw   m2, m8
452     pmaddubsw   m4, m9
453     pmaddubsw   m1, m10
454 %else
455     pmaddubsw   m2, [filteryq+32]
456     pmaddubsw   m4, [filteryq+64]
457     pmaddubsw   m1, [filteryq+96]
458 %endif
459     paddw       m0, m4
460     paddw       m2, m1
461     paddsw      m0, m2
462     pmulhrsw    m0, m6
463 %ifidn %1, avg
464     movh        m1, [dstq]
465 %endif
466     packuswb    m0, m0
467 %ifidn %1, avg
468     pavgb       m0, m1
469 %endif
470     movh    [dstq], m0
471     add       dstq, dstrideq
472     dec         hd
473     jg .loop
474     RET
475 %endmacro
476
477 INIT_MMX ssse3
478 filter_v_fn put
479 filter_v_fn avg
480
481 INIT_XMM ssse3
482 filter_v_fn put
483 filter_v_fn avg
484
485 %if ARCH_X86_64
486
487 %macro filter_vx2_fn 1
488 %assign %%px mmsize
489 cglobal vp9_%1_8tap_1d_v_ %+ %%px, 6, 8, 14, dst, src, dstride, sstride, h, filtery, src4, sstride3
490     mova       m13, [pw_256]
491     lea  sstride3q, [sstrideq*3]
492     lea      src4q, [srcq+sstrideq]
493     sub       srcq, sstride3q
494     mova        m8, [filteryq+ 0]
495     mova        m9, [filteryq+32]
496     mova       m10, [filteryq+64]
497     mova       m11, [filteryq+96]
498 .loop:
499     ; FIXME maybe reuse loads from previous rows, or just
500     ; more generally unroll this to prevent multiple loads of
501     ; the same data?
502     movu        m0, [srcq]
503     movu        m1, [srcq+sstrideq]
504     movu        m2, [srcq+sstrideq*2]
505     movu        m3, [srcq+sstride3q]
506     movu        m4, [src4q]
507     movu        m5, [src4q+sstrideq]
508     movu        m6, [src4q+sstrideq*2]
509     movu        m7, [src4q+sstride3q]
510     add       srcq, sstrideq
511     add      src4q, sstrideq
512     SBUTTERFLY  bw, 0, 1, 12
513     SBUTTERFLY  bw, 2, 3, 12
514     SBUTTERFLY  bw, 4, 5, 12
515     SBUTTERFLY  bw, 6, 7, 12
516     pmaddubsw   m0, m8
517     pmaddubsw   m1, m8
518     pmaddubsw   m2, m9
519     pmaddubsw   m3, m9
520     pmaddubsw   m4, m10
521     pmaddubsw   m5, m10
522     pmaddubsw   m6, m11
523     pmaddubsw   m7, m11
524     paddw       m0, m4
525     paddw       m1, m5
526     paddw       m2, m6
527     paddw       m3, m7
528     paddsw      m0, m2
529     paddsw      m1, m3
530     pmulhrsw    m0, m13
531     pmulhrsw    m1, m13
532     packuswb    m0, m1
533 %ifidn %1, avg
534     pavgb       m0, [dstq]
535 %endif
536     mova    [dstq], m0
537     add       dstq, dstrideq
538     dec         hd
539     jg .loop
540     RET
541 %endmacro
542
543 INIT_XMM ssse3
544 filter_vx2_fn put
545 filter_vx2_fn avg
546
547 %if HAVE_AVX2_EXTERNAL
548 INIT_YMM avx2
549 filter_vx2_fn put
550 filter_vx2_fn avg
551 %endif
552
553 %endif ; ARCH_X86_64
554
555 %macro fpel_fn 6
556 %if %2 == 4
557 %define %%srcfn movh
558 %define %%dstfn movh
559 %else
560 %define %%srcfn movu
561 %define %%dstfn mova
562 %endif
563
564 %if %2 <= mmsize
565 cglobal vp9_%1%2, 5, 7, 4, dst, src, dstride, sstride, h, dstride3, sstride3
566     lea  sstride3q, [sstrideq*3]
567     lea  dstride3q, [dstrideq*3]
568 %else
569 cglobal vp9_%1%2, 5, 5, 4, dst, src, dstride, sstride, h
570 %endif
571 .loop:
572     %%srcfn     m0, [srcq]
573     %%srcfn     m1, [srcq+s%3]
574     %%srcfn     m2, [srcq+s%4]
575     %%srcfn     m3, [srcq+s%5]
576     lea       srcq, [srcq+sstrideq*%6]
577 %ifidn %1, avg
578     pavgb       m0, [dstq]
579     pavgb       m1, [dstq+d%3]
580     pavgb       m2, [dstq+d%4]
581     pavgb       m3, [dstq+d%5]
582 %endif
583     %%dstfn [dstq], m0
584     %%dstfn [dstq+d%3], m1
585     %%dstfn [dstq+d%4], m2
586     %%dstfn [dstq+d%5], m3
587     lea       dstq, [dstq+dstrideq*%6]
588     sub         hd, %6
589     jnz .loop
590     RET
591 %endmacro
592
593 %define d16 16
594 %define s16 16
595 %define d32 32
596 %define s32 32
597 INIT_MMX mmx
598 fpel_fn put, 4,  strideq, strideq*2, stride3q, 4
599 fpel_fn put, 8,  strideq, strideq*2, stride3q, 4
600 INIT_MMX mmxext
601 fpel_fn avg, 4,  strideq, strideq*2, stride3q, 4
602 fpel_fn avg, 8,  strideq, strideq*2, stride3q, 4
603 INIT_XMM sse
604 fpel_fn put, 16, strideq, strideq*2, stride3q, 4
605 fpel_fn put, 32, mmsize,  strideq,   strideq+mmsize, 2
606 fpel_fn put, 64, mmsize,  mmsize*2,  mmsize*3, 1
607 INIT_XMM sse2
608 fpel_fn avg, 16, strideq, strideq*2, stride3q, 4
609 fpel_fn avg, 32, mmsize,  strideq,   strideq+mmsize, 2
610 fpel_fn avg, 64, mmsize,  mmsize*2,  mmsize*3, 1
611 INIT_YMM avx
612 fpel_fn put, 32, strideq, strideq*2, stride3q, 4
613 fpel_fn put, 64, mmsize,  strideq,   strideq+mmsize, 2
614 %if HAVE_AVX2_EXTERNAL
615 INIT_YMM avx2
616 fpel_fn avg, 32, strideq, strideq*2, stride3q, 4
617 fpel_fn avg, 64, mmsize,  strideq,   strideq+mmsize, 2
618 %endif
619 %undef s16
620 %undef d16
621 %undef s32
622 %undef d32