x86: AVX-512 pixel_avg_weight_w8
[x264.git] / common / x86 / mc-a.asm
1 ;*****************************************************************************
2 ;* mc-a.asm: x86 motion compensation
3 ;*****************************************************************************
4 ;* Copyright (C) 2003-2017 x264 project
5 ;*
6 ;* Authors: Loren Merritt <lorenm@u.washington.edu>
7 ;*          Fiona Glaser <fiona@x264.com>
8 ;*          Laurent Aimar <fenrir@via.ecp.fr>
9 ;*          Dylan Yudaken <dyudaken@gmail.com>
10 ;*          Holger Lubitz <holger@lubitz.org>
11 ;*          Min Chen <chenm001.163.com>
12 ;*          Oskar Arvidsson <oskar@irock.se>
13 ;*
14 ;* This program is free software; you can redistribute it and/or modify
15 ;* it under the terms of the GNU General Public License as published by
16 ;* the Free Software Foundation; either version 2 of the License, or
17 ;* (at your option) any later version.
18 ;*
19 ;* This program is distributed in the hope that it will be useful,
20 ;* but WITHOUT ANY WARRANTY; without even the implied warranty of
21 ;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22 ;* GNU General Public License for more details.
23 ;*
24 ;* You should have received a copy of the GNU General Public License
25 ;* along with this program; if not, write to the Free Software
26 ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111, USA.
27 ;*
28 ;* This program is also available under a commercial proprietary license.
29 ;* For more information, contact us at licensing@x264.com.
30 ;*****************************************************************************
31
32 %include "x86inc.asm"
33 %include "x86util.asm"
34
35 SECTION_RODATA 32
36
37 ch_shuf: times 2 db 0,2,2,4,4,6,6,8,1,3,3,5,5,7,7,9
38 ch_shuf_adj: times 8 db 0
39              times 8 db 2
40              times 8 db 4
41              times 8 db 6
42 sq_1: times 1 dq 1
43
44 SECTION .text
45
46 cextern pb_0
47 cextern pw_1
48 cextern pw_4
49 cextern pw_8
50 cextern pw_32
51 cextern pw_64
52 cextern pw_512
53 cextern pw_00ff
54 cextern pw_pixel_max
55 cextern sw_64
56 cextern pd_32
57 cextern deinterleave_shufd
58
59 ;=============================================================================
60 ; implicit weighted biprediction
61 ;=============================================================================
62 ; assumes log2_denom = 5, offset = 0, weight1 + weight2 = 64
63 %if WIN64
64     DECLARE_REG_TMP 0,1,2,3,4,5,4,5
65     %macro AVG_START 0-1 0
66         PROLOGUE 6,7,%1
67     %endmacro
68 %elif UNIX64
69     DECLARE_REG_TMP 0,1,2,3,4,5,7,8
70     %macro AVG_START 0-1 0
71         PROLOGUE 6,9,%1
72     %endmacro
73 %else
74     DECLARE_REG_TMP 1,2,3,4,5,6,1,2
75     %macro AVG_START 0-1 0
76         PROLOGUE 0,7,%1
77         mov t0, r0m
78         mov t1, r1m
79         mov t2, r2m
80         mov t3, r3m
81         mov t4, r4m
82         mov t5, r5m
83     %endmacro
84 %endif
85
86 %macro AVG_END 0-1 2 ; rows
87     lea  t2, [t2+t3*2*SIZEOF_PIXEL]
88     lea  t4, [t4+t5*2*SIZEOF_PIXEL]
89     lea  t0, [t0+t1*2*SIZEOF_PIXEL]
90     sub eax, %1
91     jg .height_loop
92     RET
93 %endmacro
94
95 %if HIGH_BIT_DEPTH
96
97 %macro BIWEIGHT_MMX 2
98     movh      m0, %1
99     movh      m1, %2
100     punpcklwd m0, m1
101     pmaddwd   m0, m3
102     paddd     m0, m4
103     psrad     m0, 6
104 %endmacro
105
106 %macro BIWEIGHT_START_MMX 0
107     movzx  t6d, word r6m
108     mov    t7d, 64
109     sub    t7d, t6d
110     shl    t7d, 16
111     add    t6d, t7d
112     movd    m3, t6d
113     SPLATD  m3, m3
114     mova    m4, [pd_32]
115     pxor    m5, m5
116 %endmacro
117
118 %else ;!HIGH_BIT_DEPTH
119 %macro BIWEIGHT_MMX 2
120     movh      m0, %1
121     movh      m1, %2
122     punpcklbw m0, m5
123     punpcklbw m1, m5
124     pmullw    m0, m2
125     pmullw    m1, m3
126     paddw     m0, m1
127     paddw     m0, m4
128     psraw     m0, 6
129 %endmacro
130
131 %macro BIWEIGHT_START_MMX 0
132     movd    m2, r6m
133     SPLATW  m2, m2   ; weight_dst
134     mova    m3, [pw_64]
135     psubw   m3, m2   ; weight_src
136     mova    m4, [pw_32] ; rounding
137     pxor    m5, m5
138 %endmacro
139 %endif ;HIGH_BIT_DEPTH
140
141 %macro BIWEIGHT_SSSE3 2
142     movh      m0, %1
143     movh      m1, %2
144     punpcklbw m0, m1
145     pmaddubsw m0, m3
146     pmulhrsw  m0, m4
147 %endmacro
148
149 %macro BIWEIGHT_START_SSSE3 0
150     movzx         t6d, byte r6m ; FIXME x86_64
151 %if mmsize > 16
152     vbroadcasti128 m4, [pw_512]
153 %else
154     mova           m4, [pw_512]
155 %endif
156     lea           t7d, [t6+(64<<8)]
157     shl           t6d, 8
158     sub           t7d, t6d
159 %if cpuflag(avx512)
160     vpbroadcastw   m3, t7d
161 %else
162     movd          xm3, t7d
163 %if cpuflag(avx2)
164     vpbroadcastw   m3, xm3
165 %else
166     SPLATW         m3, m3   ; weight_dst,src
167 %endif
168 %endif
169 %endmacro
170
171 %if HIGH_BIT_DEPTH
172 %macro BIWEIGHT_ROW 4
173     BIWEIGHT   [%2], [%3]
174 %if %4==mmsize/4
175     packssdw     m0, m0
176     CLIPW        m0, m5, m7
177     movh       [%1], m0
178 %else
179     SWAP 0, 6
180     BIWEIGHT   [%2+mmsize/2], [%3+mmsize/2]
181     packssdw     m6, m0
182     CLIPW        m6, m5, m7
183     mova       [%1], m6
184 %endif
185 %endmacro
186
187 %else ;!HIGH_BIT_DEPTH
188 %macro BIWEIGHT_ROW 4
189     BIWEIGHT [%2], [%3]
190 %if %4==mmsize/2
191     packuswb   m0, m0
192     movh     [%1], m0
193 %else
194     SWAP 0, 6
195     BIWEIGHT [%2+mmsize/2], [%3+mmsize/2]
196     packuswb   m6, m0
197     mova     [%1], m6
198 %endif
199 %endmacro
200
201 %endif ;HIGH_BIT_DEPTH
202
203 ;-----------------------------------------------------------------------------
204 ; int pixel_avg_weight_w16( pixel *dst, intptr_t, pixel *src1, intptr_t, pixel *src2, intptr_t, int i_weight )
205 ;-----------------------------------------------------------------------------
206 %macro AVG_WEIGHT 1-2 0
207 cglobal pixel_avg_weight_w%1
208     BIWEIGHT_START
209     AVG_START %2
210 %if HIGH_BIT_DEPTH
211     mova    m7, [pw_pixel_max]
212 %endif
213 .height_loop:
214 %if mmsize==16 && %1==mmsize/(2*SIZEOF_PIXEL)
215     BIWEIGHT [t2], [t4]
216     SWAP 0, 6
217     BIWEIGHT [t2+SIZEOF_PIXEL*t3], [t4+SIZEOF_PIXEL*t5]
218 %if HIGH_BIT_DEPTH
219     packssdw m6, m0
220     CLIPW    m6, m5, m7
221 %else ;!HIGH_BIT_DEPTH
222     packuswb m6, m0
223 %endif ;HIGH_BIT_DEPTH
224     movlps   [t0], m6
225     movhps   [t0+SIZEOF_PIXEL*t1], m6
226 %else
227 %assign x 0
228 %rep (%1*SIZEOF_PIXEL+mmsize-1)/mmsize
229     BIWEIGHT_ROW   t0+x,                   t2+x,                   t4+x,                 %1
230     BIWEIGHT_ROW   t0+x+SIZEOF_PIXEL*t1,   t2+x+SIZEOF_PIXEL*t3,   t4+x+SIZEOF_PIXEL*t5, %1
231 %assign x x+mmsize
232 %endrep
233 %endif
234     AVG_END
235 %endmacro
236
237 %define BIWEIGHT BIWEIGHT_MMX
238 %define BIWEIGHT_START BIWEIGHT_START_MMX
239 INIT_MMX mmx2
240 AVG_WEIGHT 4
241 AVG_WEIGHT 8
242 AVG_WEIGHT 16
243 %if HIGH_BIT_DEPTH
244 INIT_XMM sse2
245 AVG_WEIGHT 4,  8
246 AVG_WEIGHT 8,  8
247 AVG_WEIGHT 16, 8
248 %else ;!HIGH_BIT_DEPTH
249 INIT_XMM sse2
250 AVG_WEIGHT 8,  7
251 AVG_WEIGHT 16, 7
252 %define BIWEIGHT BIWEIGHT_SSSE3
253 %define BIWEIGHT_START BIWEIGHT_START_SSSE3
254 INIT_MMX ssse3
255 AVG_WEIGHT 4
256 INIT_XMM ssse3
257 AVG_WEIGHT 8,  7
258 AVG_WEIGHT 16, 7
259
260 INIT_YMM avx2
261 cglobal pixel_avg_weight_w16
262     BIWEIGHT_START
263     AVG_START 5
264 .height_loop:
265     movu     xm0, [t2]
266     movu     xm1, [t4]
267     vinserti128 m0, m0, [t2+t3], 1
268     vinserti128 m1, m1, [t4+t5], 1
269     SBUTTERFLY bw, 0, 1, 2
270     pmaddubsw m0, m3
271     pmaddubsw m1, m3
272     pmulhrsw  m0, m4
273     pmulhrsw  m1, m4
274     packuswb  m0, m1
275     mova    [t0], xm0
276     vextracti128 [t0+t1], m0, 1
277     AVG_END
278
279 INIT_YMM avx512
280 cglobal pixel_avg_weight_w8
281     BIWEIGHT_START
282     kxnorb         k1, k1, k1
283     kaddb          k1, k1, k1
284     AVG_START 5
285 .height_loop:
286     movq          xm0, [t2]
287     movq          xm2, [t4]
288     movq          xm1, [t2+t3]
289     movq          xm5, [t4+t5]
290     lea            t2, [t2+t3*2]
291     lea            t4, [t4+t5*2]
292     vpbroadcastq   m0 {k1}, [t2]
293     vpbroadcastq   m2 {k1}, [t4]
294     vpbroadcastq   m1 {k1}, [t2+t3]
295     vpbroadcastq   m5 {k1}, [t4+t5]
296     punpcklbw      m0, m2
297     punpcklbw      m1, m5
298     pmaddubsw      m0, m3
299     pmaddubsw      m1, m3
300     pmulhrsw       m0, m4
301     pmulhrsw       m1, m4
302     packuswb       m0, m1
303     vextracti128 xmm1, m0, 1
304     movq         [t0], xm0
305     movhps    [t0+t1], xm0
306     lea            t0, [t0+t1*2]
307     movq         [t0], xmm1
308     movhps    [t0+t1], xmm1
309     AVG_END 4
310
311 INIT_ZMM avx512
312 cglobal pixel_avg_weight_w16
313     BIWEIGHT_START
314     AVG_START 5
315 .height_loop:
316     movu        xm0, [t2]
317     movu        xm1, [t4]
318     vinserti128 ym0, [t2+t3], 1
319     vinserti128 ym1, [t4+t5], 1
320     lea          t2, [t2+t3*2]
321     lea          t4, [t4+t5*2]
322     vinserti32x4 m0, [t2], 2
323     vinserti32x4 m1, [t4], 2
324     vinserti32x4 m0, [t2+t3], 3
325     vinserti32x4 m1, [t4+t5], 3
326     SBUTTERFLY   bw, 0, 1, 2
327     pmaddubsw    m0, m3
328     pmaddubsw    m1, m3
329     pmulhrsw     m0, m4
330     pmulhrsw     m1, m4
331     packuswb     m0, m1
332     mova       [t0], xm0
333     vextracti128 [t0+t1], ym0, 1
334     lea          t0, [t0+t1*2]
335     vextracti32x4 [t0], m0, 2
336     vextracti32x4 [t0+t1], m0, 3
337     AVG_END 4
338 %endif ;HIGH_BIT_DEPTH
339
340 ;=============================================================================
341 ; P frame explicit weighted prediction
342 ;=============================================================================
343
344 %if HIGH_BIT_DEPTH
345 ; width
346 %macro WEIGHT_START 1
347     mova        m0, [r4+ 0]         ; 1<<denom
348     mova        m3, [r4+16]
349     movd        m2, [r4+32]         ; denom
350     mova        m4, [pw_pixel_max]
351     paddw       m2, [sq_1]          ; denom+1
352 %endmacro
353
354 ; src1, src2
355 %macro WEIGHT 2
356     movh        m5, [%1]
357     movh        m6, [%2]
358     punpcklwd   m5, m0
359     punpcklwd   m6, m0
360     pmaddwd     m5, m3
361     pmaddwd     m6, m3
362     psrad       m5, m2
363     psrad       m6, m2
364     packssdw    m5, m6
365 %endmacro
366
367 ; src, dst, width
368 %macro WEIGHT_TWO_ROW 4
369     %assign x 0
370 %rep (%3+mmsize/2-1)/(mmsize/2)
371 %if %3-x/2 <= 4 && mmsize == 16
372     WEIGHT      %1+x, %1+r3+x
373     CLIPW         m5, [pb_0], m4
374     movh      [%2+x], m5
375     movhps [%2+r1+x], m5
376 %else
377     WEIGHT      %1+x, %1+x+mmsize/2
378     SWAP           5,  7
379     WEIGHT   %1+r3+x, %1+r3+x+mmsize/2
380     CLIPW         m5, [pb_0], m4
381     CLIPW         m7, [pb_0], m4
382     mova      [%2+x], m7
383     mova   [%2+r1+x], m5
384 %endif
385     %assign x x+mmsize
386 %endrep
387 %endmacro
388
389 %else ; !HIGH_BIT_DEPTH
390
391 %macro WEIGHT_START 1
392 %if cpuflag(avx2)
393     vbroadcasti128 m3, [r4]
394     vbroadcasti128 m4, [r4+16]
395 %else
396     mova     m3, [r4]
397     mova     m4, [r4+16]
398 %if notcpuflag(ssse3)
399     movd     m5, [r4+32]
400 %endif
401 %endif
402     pxor     m2, m2
403 %endmacro
404
405 ; src1, src2, dst1, dst2, fast
406 %macro WEIGHT_ROWx2 5
407     movh      m0, [%1         ]
408     movh      m1, [%1+mmsize/2]
409     movh      m6, [%2         ]
410     movh      m7, [%2+mmsize/2]
411     punpcklbw m0, m2
412     punpcklbw m1, m2
413     punpcklbw m6, m2
414     punpcklbw m7, m2
415 %if cpuflag(ssse3)
416 %if %5==0
417     psllw     m0, 7
418     psllw     m1, 7
419     psllw     m6, 7
420     psllw     m7, 7
421 %endif
422     pmulhrsw  m0, m3
423     pmulhrsw  m1, m3
424     pmulhrsw  m6, m3
425     pmulhrsw  m7, m3
426     paddw     m0, m4
427     paddw     m1, m4
428     paddw     m6, m4
429     paddw     m7, m4
430 %else
431     pmullw    m0, m3
432     pmullw    m1, m3
433     pmullw    m6, m3
434     pmullw    m7, m3
435     paddsw    m0, m4        ;1<<(denom-1)+(offset<<denom)
436     paddsw    m1, m4
437     paddsw    m6, m4
438     paddsw    m7, m4
439     psraw     m0, m5
440     psraw     m1, m5
441     psraw     m6, m5
442     psraw     m7, m5
443 %endif
444     packuswb  m0, m1
445     packuswb  m6, m7
446     mova    [%3], m0
447     mova    [%4], m6
448 %endmacro
449
450 ; src1, src2, dst1, dst2, width, fast
451 %macro WEIGHT_COL 6
452 %if cpuflag(avx2)
453 %if %5==16
454     movu     xm0, [%1]
455     vinserti128 m0, m0, [%2], 1
456     punpckhbw m1, m0, m2
457     punpcklbw m0, m0, m2
458 %if %6==0
459     psllw     m0, 7
460     psllw     m1, 7
461 %endif
462     pmulhrsw  m0, m3
463     pmulhrsw  m1, m3
464     paddw     m0, m4
465     paddw     m1, m4
466     packuswb  m0, m1
467     mova    [%3], xm0
468     vextracti128 [%4], m0, 1
469 %else
470     movq     xm0, [%1]
471     vinserti128 m0, m0, [%2], 1
472     punpcklbw m0, m2
473 %if %6==0
474     psllw     m0, 7
475 %endif
476     pmulhrsw  m0, m3
477     paddw     m0, m4
478     packuswb  m0, m0
479     vextracti128 xm1, m0, 1
480 %if %5 == 8
481     movq    [%3], xm0
482     movq    [%4], xm1
483 %else
484     movd    [%3], xm0
485     movd    [%4], xm1
486 %endif
487 %endif
488 %else
489     movh      m0, [%1]
490     movh      m1, [%2]
491     punpcklbw m0, m2
492     punpcklbw m1, m2
493 %if cpuflag(ssse3)
494 %if %6==0
495     psllw     m0, 7
496     psllw     m1, 7
497 %endif
498     pmulhrsw  m0, m3
499     pmulhrsw  m1, m3
500     paddw     m0, m4
501     paddw     m1, m4
502 %else
503     pmullw    m0, m3
504     pmullw    m1, m3
505     paddsw    m0, m4        ;1<<(denom-1)+(offset<<denom)
506     paddsw    m1, m4
507     psraw     m0, m5
508     psraw     m1, m5
509 %endif
510 %if %5 == 8
511     packuswb  m0, m1
512     movh    [%3], m0
513     movhps  [%4], m0
514 %else
515     packuswb  m0, m0
516     packuswb  m1, m1
517     movd    [%3], m0    ; width 2 can write garbage for the last 2 bytes
518     movd    [%4], m1
519 %endif
520 %endif
521 %endmacro
522 ; src, dst, width
523 %macro WEIGHT_TWO_ROW 4
524 %assign x 0
525 %rep %3
526 %if (%3-x) >= mmsize
527     WEIGHT_ROWx2 %1+x, %1+r3+x, %2+x, %2+r1+x, %4
528     %assign x (x+mmsize)
529 %else
530     %assign w %3-x
531 %if w == 20
532     %assign w 16
533 %endif
534     WEIGHT_COL %1+x, %1+r3+x, %2+x, %2+r1+x, w, %4
535     %assign x (x+w)
536 %endif
537 %if x >= %3
538     %exitrep
539 %endif
540 %endrep
541 %endmacro
542
543 %endif ; HIGH_BIT_DEPTH
544
545 ;-----------------------------------------------------------------------------
546 ;void mc_weight_wX( pixel *dst, intptr_t i_dst_stride, pixel *src, intptr_t i_src_stride, weight_t *weight, int h )
547 ;-----------------------------------------------------------------------------
548
549 %macro WEIGHTER 1
550 cglobal mc_weight_w%1, 6,6,8
551     FIX_STRIDES r1, r3
552     WEIGHT_START %1
553 %if cpuflag(ssse3) && HIGH_BIT_DEPTH == 0
554     ; we can merge the shift step into the scale factor
555     ; if (m3<<7) doesn't overflow an int16_t
556     cmp byte [r4+1], 0
557     jz .fast
558 %endif
559 .loop:
560     WEIGHT_TWO_ROW r2, r0, %1, 0
561     lea  r0, [r0+r1*2]
562     lea  r2, [r2+r3*2]
563     sub r5d, 2
564     jg .loop
565     RET
566 %if cpuflag(ssse3) && HIGH_BIT_DEPTH == 0
567 .fast:
568     psllw m3, 7
569 .fastloop:
570     WEIGHT_TWO_ROW r2, r0, %1, 1
571     lea  r0, [r0+r1*2]
572     lea  r2, [r2+r3*2]
573     sub r5d, 2
574     jg .fastloop
575     RET
576 %endif
577 %endmacro
578
579 INIT_MMX mmx2
580 WEIGHTER  4
581 WEIGHTER  8
582 WEIGHTER 12
583 WEIGHTER 16
584 WEIGHTER 20
585 INIT_XMM sse2
586 WEIGHTER  8
587 WEIGHTER 16
588 WEIGHTER 20
589 %if HIGH_BIT_DEPTH
590 WEIGHTER 12
591 %else
592 INIT_MMX ssse3
593 WEIGHTER  4
594 INIT_XMM ssse3
595 WEIGHTER  8
596 WEIGHTER 16
597 WEIGHTER 20
598 INIT_YMM avx2
599 WEIGHTER 8
600 WEIGHTER 16
601 WEIGHTER 20
602 %endif
603
604 %macro OFFSET_OP 7
605     mov%6        m0, [%1]
606     mov%6        m1, [%2]
607 %if HIGH_BIT_DEPTH
608     p%5usw       m0, m2
609     p%5usw       m1, m2
610 %ifidn %5,add
611     pminsw       m0, m3
612     pminsw       m1, m3
613 %endif
614 %else
615     p%5usb       m0, m2
616     p%5usb       m1, m2
617 %endif
618     mov%7      [%3], m0
619     mov%7      [%4], m1
620 %endmacro
621
622 %macro OFFSET_TWO_ROW 4
623 %assign x 0
624 %rep %3
625 %if (%3*SIZEOF_PIXEL-x) >= mmsize
626     OFFSET_OP (%1+x), (%1+x+r3), (%2+x), (%2+x+r1), %4, u, a
627     %assign x (x+mmsize)
628 %else
629 %if HIGH_BIT_DEPTH
630     OFFSET_OP (%1+x), (%1+x+r3), (%2+x), (%2+x+r1), %4, h, h
631 %else
632     OFFSET_OP (%1+x), (%1+x+r3), (%2+x), (%2+x+r1), %4, d, d
633 %endif
634     %exitrep
635 %endif
636 %if x >= %3*SIZEOF_PIXEL
637     %exitrep
638 %endif
639 %endrep
640 %endmacro
641
642 ;-----------------------------------------------------------------------------
643 ;void mc_offset_wX( pixel *src, intptr_t i_src_stride, pixel *dst, intptr_t i_dst_stride, weight_t *w, int h )
644 ;-----------------------------------------------------------------------------
645 %macro OFFSET 2
646 cglobal mc_offset%2_w%1, 6,6
647     FIX_STRIDES r1, r3
648     mova m2, [r4]
649 %if HIGH_BIT_DEPTH
650 %ifidn %2,add
651     mova m3, [pw_pixel_max]
652 %endif
653 %endif
654 .loop:
655     OFFSET_TWO_ROW r2, r0, %1, %2
656     lea  r0, [r0+r1*2]
657     lea  r2, [r2+r3*2]
658     sub r5d, 2
659     jg .loop
660     RET
661 %endmacro
662
663 %macro OFFSETPN 1
664        OFFSET %1, add
665        OFFSET %1, sub
666 %endmacro
667 INIT_MMX mmx2
668 OFFSETPN  4
669 OFFSETPN  8
670 OFFSETPN 12
671 OFFSETPN 16
672 OFFSETPN 20
673 INIT_XMM sse2
674 OFFSETPN 12
675 OFFSETPN 16
676 OFFSETPN 20
677 %if HIGH_BIT_DEPTH
678 INIT_XMM sse2
679 OFFSETPN  8
680 %endif
681
682
683 ;=============================================================================
684 ; pixel avg
685 ;=============================================================================
686
687 ;-----------------------------------------------------------------------------
688 ; void pixel_avg_4x4( pixel *dst, intptr_t dst_stride, pixel *src1, intptr_t src1_stride,
689 ;                     pixel *src2, intptr_t src2_stride, int weight );
690 ;-----------------------------------------------------------------------------
691 %macro AVGH 2
692 cglobal pixel_avg_%1x%2
693     mov eax, %2
694     cmp dword r6m, 32
695     jne pixel_avg_weight_w%1 %+ SUFFIX
696 %if cpuflag(avx2) && %1 == 16 ; all AVX2 machines can do fast 16-byte unaligned loads
697     jmp pixel_avg_w%1_avx2
698 %else
699 %if mmsize == 16 && %1 == 16
700     test dword r4m, 15
701     jz pixel_avg_w%1_sse2
702 %endif
703     jmp pixel_avg_w%1_mmx2
704 %endif
705 %endmacro
706
707 ;-----------------------------------------------------------------------------
708 ; void pixel_avg_w4( pixel *dst, intptr_t dst_stride, pixel *src1, intptr_t src1_stride,
709 ;                    pixel *src2, intptr_t src2_stride, int height, int weight );
710 ;-----------------------------------------------------------------------------
711
712 %macro AVG_FUNC 3
713 cglobal pixel_avg_w%1
714     AVG_START
715 .height_loop:
716 %assign x 0
717 %rep (%1*SIZEOF_PIXEL+mmsize-1)/mmsize
718     %2     m0, [t2+x]
719     %2     m1, [t2+x+SIZEOF_PIXEL*t3]
720 %if HIGH_BIT_DEPTH
721     pavgw  m0, [t4+x]
722     pavgw  m1, [t4+x+SIZEOF_PIXEL*t5]
723 %else ;!HIGH_BIT_DEPTH
724     pavgb  m0, [t4+x]
725     pavgb  m1, [t4+x+SIZEOF_PIXEL*t5]
726 %endif
727     %3     [t0+x], m0
728     %3     [t0+x+SIZEOF_PIXEL*t1], m1
729 %assign x x+mmsize
730 %endrep
731     AVG_END
732 %endmacro
733
734 %if HIGH_BIT_DEPTH
735
736 INIT_MMX mmx2
737 AVG_FUNC 4, movq, movq
738 AVGH 4, 16
739 AVGH 4, 8
740 AVGH 4, 4
741 AVGH 4, 2
742
743 AVG_FUNC 8, movq, movq
744 AVGH 8, 16
745 AVGH 8,  8
746 AVGH 8,  4
747
748 AVG_FUNC 16, movq, movq
749 AVGH 16, 16
750 AVGH 16,  8
751
752 INIT_XMM sse2
753 AVG_FUNC 4, movq, movq
754 AVGH  4, 16
755 AVGH  4, 8
756 AVGH  4, 4
757 AVGH  4, 2
758
759 AVG_FUNC 8, movdqu, movdqa
760 AVGH  8, 16
761 AVGH  8,  8
762 AVGH  8,  4
763
764 AVG_FUNC 16, movdqu, movdqa
765 AVGH  16, 16
766 AVGH  16,  8
767
768 %else ;!HIGH_BIT_DEPTH
769
770 INIT_MMX mmx2
771 AVG_FUNC 4, movd, movd
772 AVGH 4, 16
773 AVGH 4, 8
774 AVGH 4, 4
775 AVGH 4, 2
776
777 AVG_FUNC 8, movq, movq
778 AVGH 8, 16
779 AVGH 8,  8
780 AVGH 8,  4
781
782 AVG_FUNC 16, movq, movq
783 AVGH 16, 16
784 AVGH 16, 8
785
786 INIT_XMM sse2
787 AVG_FUNC 16, movdqu, movdqa
788 AVGH 16, 16
789 AVGH 16,  8
790 AVGH  8, 16
791 AVGH  8,  8
792 AVGH  8,  4
793 INIT_XMM ssse3
794 AVGH 16, 16
795 AVGH 16,  8
796 AVGH  8, 16
797 AVGH  8,  8
798 AVGH  8,  4
799 INIT_MMX ssse3
800 AVGH  4, 16
801 AVGH  4,  8
802 AVGH  4,  4
803 AVGH  4,  2
804 INIT_XMM avx2
805 AVG_FUNC 16, movdqu, movdqa
806 AVGH 16, 16
807 AVGH 16,  8
808 INIT_XMM avx512
809 AVGH 16, 16
810 AVGH 16,  8
811 AVGH  8, 16
812 AVGH  8,  8
813 AVGH  8,  4
814
815 %endif ;HIGH_BIT_DEPTH
816
817
818
819 ;=============================================================================
820 ; pixel avg2
821 ;=============================================================================
822
823 %if HIGH_BIT_DEPTH
824 ;-----------------------------------------------------------------------------
825 ; void pixel_avg2_wN( uint16_t *dst,  intptr_t dst_stride,
826 ;                     uint16_t *src1, intptr_t src_stride,
827 ;                     uint16_t *src2, int height );
828 ;-----------------------------------------------------------------------------
829 %macro AVG2_W_ONE 1
830 cglobal pixel_avg2_w%1, 6,7,4
831     sub     r4, r2
832     lea     r6, [r4+r3*2]
833 .height_loop:
834     movu    m0, [r2]
835     movu    m1, [r2+r3*2]
836 %if cpuflag(avx) || mmsize == 8
837     pavgw   m0, [r2+r4]
838     pavgw   m1, [r2+r6]
839 %else
840     movu    m2, [r2+r4]
841     movu    m3, [r2+r6]
842     pavgw   m0, m2
843     pavgw   m1, m3
844 %endif
845     mova   [r0], m0
846     mova   [r0+r1*2], m1
847     lea     r2, [r2+r3*4]
848     lea     r0, [r0+r1*4]
849     sub    r5d, 2
850     jg .height_loop
851     RET
852 %endmacro
853
854 %macro AVG2_W_TWO 3
855 cglobal pixel_avg2_w%1, 6,7,8
856     sub     r4, r2
857     lea     r6, [r4+r3*2]
858 .height_loop:
859     movu    m0, [r2]
860     %2      m1, [r2+mmsize]
861     movu    m2, [r2+r3*2]
862     %2      m3, [r2+r3*2+mmsize]
863 %if mmsize == 8
864     pavgw   m0, [r2+r4]
865     pavgw   m1, [r2+r4+mmsize]
866     pavgw   m2, [r2+r6]
867     pavgw   m3, [r2+r6+mmsize]
868 %else
869     movu    m4, [r2+r4]
870     %2      m5, [r2+r4+mmsize]
871     movu    m6, [r2+r6]
872     %2      m7, [r2+r6+mmsize]
873     pavgw   m0, m4
874     pavgw   m1, m5
875     pavgw   m2, m6
876     pavgw   m3, m7
877 %endif
878     mova   [r0], m0
879     %3     [r0+mmsize], m1
880     mova   [r0+r1*2], m2
881     %3     [r0+r1*2+mmsize], m3
882     lea     r2, [r2+r3*4]
883     lea     r0, [r0+r1*4]
884     sub    r5d, 2
885     jg .height_loop
886     RET
887 %endmacro
888
889 INIT_MMX mmx2
890 AVG2_W_ONE  4
891 AVG2_W_TWO  8, movu, mova
892 INIT_XMM sse2
893 AVG2_W_ONE  8
894 AVG2_W_TWO 10, movd, movd
895 AVG2_W_TWO 16, movu, mova
896 INIT_YMM avx2
897 AVG2_W_ONE 16
898
899 INIT_MMX
900 cglobal pixel_avg2_w10_mmx2, 6,7
901     sub     r4, r2
902     lea     r6, [r4+r3*2]
903 .height_loop:
904     movu    m0, [r2+ 0]
905     movu    m1, [r2+ 8]
906     movh    m2, [r2+16]
907     movu    m3, [r2+r3*2+ 0]
908     movu    m4, [r2+r3*2+ 8]
909     movh    m5, [r2+r3*2+16]
910     pavgw   m0, [r2+r4+ 0]
911     pavgw   m1, [r2+r4+ 8]
912     pavgw   m2, [r2+r4+16]
913     pavgw   m3, [r2+r6+ 0]
914     pavgw   m4, [r2+r6+ 8]
915     pavgw   m5, [r2+r6+16]
916     mova   [r0+ 0], m0
917     mova   [r0+ 8], m1
918     movh   [r0+16], m2
919     mova   [r0+r1*2+ 0], m3
920     mova   [r0+r1*2+ 8], m4
921     movh   [r0+r1*2+16], m5
922     lea     r2, [r2+r3*2*2]
923     lea     r0, [r0+r1*2*2]
924     sub    r5d, 2
925     jg .height_loop
926     RET
927
928 cglobal pixel_avg2_w16_mmx2, 6,7
929     sub     r4, r2
930     lea     r6, [r4+r3*2]
931 .height_loop:
932     movu    m0, [r2+ 0]
933     movu    m1, [r2+ 8]
934     movu    m2, [r2+16]
935     movu    m3, [r2+24]
936     movu    m4, [r2+r3*2+ 0]
937     movu    m5, [r2+r3*2+ 8]
938     movu    m6, [r2+r3*2+16]
939     movu    m7, [r2+r3*2+24]
940     pavgw   m0, [r2+r4+ 0]
941     pavgw   m1, [r2+r4+ 8]
942     pavgw   m2, [r2+r4+16]
943     pavgw   m3, [r2+r4+24]
944     pavgw   m4, [r2+r6+ 0]
945     pavgw   m5, [r2+r6+ 8]
946     pavgw   m6, [r2+r6+16]
947     pavgw   m7, [r2+r6+24]
948     mova   [r0+ 0], m0
949     mova   [r0+ 8], m1
950     mova   [r0+16], m2
951     mova   [r0+24], m3
952     mova   [r0+r1*2+ 0], m4
953     mova   [r0+r1*2+ 8], m5
954     mova   [r0+r1*2+16], m6
955     mova   [r0+r1*2+24], m7
956     lea     r2, [r2+r3*2*2]
957     lea     r0, [r0+r1*2*2]
958     sub    r5d, 2
959     jg .height_loop
960     RET
961
962 cglobal pixel_avg2_w18_mmx2, 6,7
963     sub     r4, r2
964 .height_loop:
965     movu    m0, [r2+ 0]
966     movu    m1, [r2+ 8]
967     movu    m2, [r2+16]
968     movu    m3, [r2+24]
969     movh    m4, [r2+32]
970     pavgw   m0, [r2+r4+ 0]
971     pavgw   m1, [r2+r4+ 8]
972     pavgw   m2, [r2+r4+16]
973     pavgw   m3, [r2+r4+24]
974     pavgw   m4, [r2+r4+32]
975     mova   [r0+ 0], m0
976     mova   [r0+ 8], m1
977     mova   [r0+16], m2
978     mova   [r0+24], m3
979     movh   [r0+32], m4
980     lea     r2, [r2+r3*2]
981     lea     r0, [r0+r1*2]
982     dec    r5d
983     jg .height_loop
984     RET
985
986 %macro PIXEL_AVG_W18 0
987 cglobal pixel_avg2_w18, 6,7
988     sub     r4, r2
989 .height_loop:
990     movu    m0, [r2+ 0]
991     movd   xm2, [r2+32]
992 %if mmsize == 32
993     pavgw   m0, [r2+r4+ 0]
994     movd   xm1, [r2+r4+32]
995     pavgw  xm2, xm1
996 %else
997     movu    m1, [r2+16]
998     movu    m3, [r2+r4+ 0]
999     movu    m4, [r2+r4+16]
1000     movd    m5, [r2+r4+32]
1001     pavgw   m0, m3
1002     pavgw   m1, m4
1003     pavgw   m2, m5
1004     mova   [r0+16], m1
1005 %endif
1006     mova   [r0+ 0], m0
1007     movd   [r0+32], xm2
1008     lea     r2, [r2+r3*2]
1009     lea     r0, [r0+r1*2]
1010     dec    r5d
1011     jg .height_loop
1012     RET
1013 %endmacro
1014
1015 INIT_XMM sse2
1016 PIXEL_AVG_W18
1017 INIT_YMM avx2
1018 PIXEL_AVG_W18
1019
1020 %endif ; HIGH_BIT_DEPTH
1021
1022 %if HIGH_BIT_DEPTH == 0
1023 ;-----------------------------------------------------------------------------
1024 ; void pixel_avg2_w4( uint8_t *dst,  intptr_t dst_stride,
1025 ;                     uint8_t *src1, intptr_t src_stride,
1026 ;                     uint8_t *src2, int height );
1027 ;-----------------------------------------------------------------------------
1028 %macro AVG2_W8 2
1029 cglobal pixel_avg2_w%1_mmx2, 6,7
1030     sub    r4, r2
1031     lea    r6, [r4+r3]
1032 .height_loop:
1033     %2     mm0, [r2]
1034     %2     mm1, [r2+r3]
1035     pavgb  mm0, [r2+r4]
1036     pavgb  mm1, [r2+r6]
1037     lea    r2, [r2+r3*2]
1038     %2     [r0], mm0
1039     %2     [r0+r1], mm1
1040     lea    r0, [r0+r1*2]
1041     sub    r5d, 2
1042     jg     .height_loop
1043     RET
1044 %endmacro
1045
1046 INIT_MMX
1047 AVG2_W8 4, movd
1048 AVG2_W8 8, movq
1049
1050 %macro AVG2_W16 2
1051 cglobal pixel_avg2_w%1_mmx2, 6,7
1052     sub    r2, r4
1053     lea    r6, [r2+r3]
1054 .height_loop:
1055     movq   mm0, [r4]
1056     %2     mm1, [r4+8]
1057     movq   mm2, [r4+r3]
1058     %2     mm3, [r4+r3+8]
1059     pavgb  mm0, [r4+r2]
1060     pavgb  mm1, [r4+r2+8]
1061     pavgb  mm2, [r4+r6]
1062     pavgb  mm3, [r4+r6+8]
1063     lea    r4, [r4+r3*2]
1064     movq   [r0], mm0
1065     %2     [r0+8], mm1
1066     movq   [r0+r1], mm2
1067     %2     [r0+r1+8], mm3
1068     lea    r0, [r0+r1*2]
1069     sub    r5d, 2
1070     jg     .height_loop
1071     RET
1072 %endmacro
1073
1074 AVG2_W16 12, movd
1075 AVG2_W16 16, movq
1076
1077 cglobal pixel_avg2_w20_mmx2, 6,7
1078     sub    r2, r4
1079     lea    r6, [r2+r3]
1080 .height_loop:
1081     movq   mm0, [r4]
1082     movq   mm1, [r4+8]
1083     movd   mm2, [r4+16]
1084     movq   mm3, [r4+r3]
1085     movq   mm4, [r4+r3+8]
1086     movd   mm5, [r4+r3+16]
1087     pavgb  mm0, [r4+r2]
1088     pavgb  mm1, [r4+r2+8]
1089     pavgb  mm2, [r4+r2+16]
1090     pavgb  mm3, [r4+r6]
1091     pavgb  mm4, [r4+r6+8]
1092     pavgb  mm5, [r4+r6+16]
1093     lea    r4, [r4+r3*2]
1094     movq   [r0], mm0
1095     movq   [r0+8], mm1
1096     movd   [r0+16], mm2
1097     movq   [r0+r1], mm3
1098     movq   [r0+r1+8], mm4
1099     movd   [r0+r1+16], mm5
1100     lea    r0, [r0+r1*2]
1101     sub    r5d, 2
1102     jg     .height_loop
1103     RET
1104
1105 INIT_XMM
1106 cglobal pixel_avg2_w16_sse2, 6,7
1107     sub    r4, r2
1108     lea    r6, [r4+r3]
1109 .height_loop:
1110     movu   m0, [r2]
1111     movu   m2, [r2+r3]
1112     movu   m1, [r2+r4]
1113     movu   m3, [r2+r6]
1114     lea    r2, [r2+r3*2]
1115     pavgb  m0, m1
1116     pavgb  m2, m3
1117     mova [r0], m0
1118     mova [r0+r1], m2
1119     lea    r0, [r0+r1*2]
1120     sub   r5d, 2
1121     jg .height_loop
1122     RET
1123
1124 cglobal pixel_avg2_w20_sse2, 6,7
1125     sub    r2, r4
1126     lea    r6, [r2+r3]
1127 .height_loop:
1128     movu   m0, [r4]
1129     movu   m2, [r4+r3]
1130     movu   m1, [r4+r2]
1131     movu   m3, [r4+r6]
1132     movd  mm4, [r4+16]
1133     movd  mm5, [r4+r3+16]
1134     pavgb  m0, m1
1135     pavgb  m2, m3
1136     pavgb mm4, [r4+r2+16]
1137     pavgb mm5, [r4+r6+16]
1138     lea    r4, [r4+r3*2]
1139     mova [r0], m0
1140     mova [r0+r1], m2
1141     movd [r0+16], mm4
1142     movd [r0+r1+16], mm5
1143     lea    r0, [r0+r1*2]
1144     sub   r5d, 2
1145     jg .height_loop
1146     RET
1147
1148 INIT_YMM avx2
1149 cglobal pixel_avg2_w20, 6,7
1150     sub    r2, r4
1151     lea    r6, [r2+r3]
1152 .height_loop:
1153     movu   m0, [r4]
1154     movu   m1, [r4+r3]
1155     pavgb  m0, [r4+r2]
1156     pavgb  m1, [r4+r6]
1157     lea    r4, [r4+r3*2]
1158     mova [r0], m0
1159     mova [r0+r1], m1
1160     lea    r0, [r0+r1*2]
1161     sub    r5d, 2
1162     jg     .height_loop
1163     RET
1164
1165 ; Cacheline split code for processors with high latencies for loads
1166 ; split over cache lines.  See sad-a.asm for a more detailed explanation.
1167 ; This particular instance is complicated by the fact that src1 and src2
1168 ; can have different alignments.  For simplicity and code size, only the
1169 ; MMX cacheline workaround is used.  As a result, in the case of SSE2
1170 ; pixel_avg, the cacheline check functions calls the SSE2 version if there
1171 ; is no cacheline split, and the MMX workaround if there is.
1172
1173 %macro INIT_SHIFT 2
1174     and    eax, 7
1175     shl    eax, 3
1176     movd   %1, [sw_64]
1177     movd   %2, eax
1178     psubw  %1, %2
1179 %endmacro
1180
1181 %macro AVG_CACHELINE_START 0
1182     %assign stack_offset 0
1183     INIT_SHIFT mm6, mm7
1184     mov    eax, r4m
1185     INIT_SHIFT mm4, mm5
1186     PROLOGUE 6,6
1187     and    r2, ~7
1188     and    r4, ~7
1189     sub    r4, r2
1190 .height_loop:
1191 %endmacro
1192
1193 %macro AVG_CACHELINE_LOOP 2
1194     movq   mm1, [r2+%1]
1195     movq   mm0, [r2+8+%1]
1196     movq   mm3, [r2+r4+%1]
1197     movq   mm2, [r2+r4+8+%1]
1198     psrlq  mm1, mm7
1199     psllq  mm0, mm6
1200     psrlq  mm3, mm5
1201     psllq  mm2, mm4
1202     por    mm0, mm1
1203     por    mm2, mm3
1204     pavgb  mm2, mm0
1205     %2 [r0+%1], mm2
1206 %endmacro
1207
1208 %macro AVG_CACHELINE_FUNC 2
1209 pixel_avg2_w%1_cache_mmx2:
1210     AVG_CACHELINE_START
1211     AVG_CACHELINE_LOOP 0, movq
1212 %if %1>8
1213     AVG_CACHELINE_LOOP 8, movq
1214 %if %1>16
1215     AVG_CACHELINE_LOOP 16, movd
1216 %endif
1217 %endif
1218     add    r2, r3
1219     add    r0, r1
1220     dec    r5d
1221     jg .height_loop
1222     RET
1223 %endmacro
1224
1225 %macro AVG_CACHELINE_CHECK 3 ; width, cacheline, instruction set
1226 %if %1 == 12
1227 ;w12 isn't needed because w16 is just as fast if there's no cacheline split
1228 %define cachesplit pixel_avg2_w16_cache_mmx2
1229 %else
1230 %define cachesplit pixel_avg2_w%1_cache_mmx2
1231 %endif
1232 cglobal pixel_avg2_w%1_cache%2_%3
1233     mov    eax, r2m
1234     and    eax, %2-1
1235     cmp    eax, (%2-%1-(%1 % 8))
1236 %if %1==12||%1==20
1237     jbe pixel_avg2_w%1_%3
1238 %else
1239     jb pixel_avg2_w%1_%3
1240 %endif
1241 %if 0 ; or %1==8 - but the extra branch seems too expensive
1242     ja cachesplit
1243 %if ARCH_X86_64
1244     test      r4b, 1
1245 %else
1246     test byte r4m, 1
1247 %endif
1248     jz pixel_avg2_w%1_%3
1249 %else
1250     or     eax, r4m
1251     and    eax, 7
1252     jz pixel_avg2_w%1_%3
1253     mov    eax, r2m
1254 %endif
1255 %if mmsize==16 || (%1==8 && %2==64)
1256     AVG_CACHELINE_FUNC %1, %2
1257 %else
1258     jmp cachesplit
1259 %endif
1260 %endmacro
1261
1262 INIT_MMX
1263 AVG_CACHELINE_CHECK  8, 64, mmx2
1264 AVG_CACHELINE_CHECK 12, 64, mmx2
1265 %if ARCH_X86_64 == 0
1266 AVG_CACHELINE_CHECK 16, 64, mmx2
1267 AVG_CACHELINE_CHECK 20, 64, mmx2
1268 AVG_CACHELINE_CHECK  8, 32, mmx2
1269 AVG_CACHELINE_CHECK 12, 32, mmx2
1270 AVG_CACHELINE_CHECK 16, 32, mmx2
1271 AVG_CACHELINE_CHECK 20, 32, mmx2
1272 %endif
1273 INIT_XMM
1274 AVG_CACHELINE_CHECK 16, 64, sse2
1275 AVG_CACHELINE_CHECK 20, 64, sse2
1276
1277 ; computed jump assumes this loop is exactly 48 bytes
1278 %macro AVG16_CACHELINE_LOOP_SSSE3 2 ; alignment
1279 ALIGN 16
1280 avg_w16_align%1_%2_ssse3:
1281 %if %1==0 && %2==0
1282     movdqa  xmm1, [r2]
1283     pavgb   xmm1, [r2+r4]
1284     add    r2, r3
1285 %elif %1==0
1286     movdqa  xmm1, [r2+r4+16]
1287     palignr xmm1, [r2+r4], %2
1288     pavgb   xmm1, [r2]
1289     add    r2, r3
1290 %elif %2&15==0
1291     movdqa  xmm1, [r2+16]
1292     palignr xmm1, [r2], %1
1293     pavgb   xmm1, [r2+r4]
1294     add    r2, r3
1295 %else
1296     movdqa  xmm1, [r2+16]
1297     movdqa  xmm2, [r2+r4+16]
1298     palignr xmm1, [r2], %1
1299     palignr xmm2, [r2+r4], %2&15
1300     add    r2, r3
1301     pavgb   xmm1, xmm2
1302 %endif
1303     movdqa  [r0], xmm1
1304     add    r0, r1
1305     dec    r5d
1306     jg     avg_w16_align%1_%2_ssse3
1307     ret
1308 %if %1==0
1309     ; make sure the first ones don't end up short
1310     ALIGN 16
1311     times (48-($-avg_w16_align%1_%2_ssse3))>>4 nop
1312 %endif
1313 %endmacro
1314
1315 cglobal pixel_avg2_w16_cache64_ssse3
1316 %if 0 ; seems both tests aren't worth it if src1%16==0 is optimized
1317     mov   eax, r2m
1318     and   eax, 0x3f
1319     cmp   eax, 0x30
1320     jb pixel_avg2_w16_sse2
1321     or    eax, r4m
1322     and   eax, 7
1323     jz pixel_avg2_w16_sse2
1324 %endif
1325     PROLOGUE 6, 8
1326     lea    r6, [r4+r2]
1327     and    r4, ~0xf
1328     and    r6, 0x1f
1329     and    r2, ~0xf
1330     lea    r6, [r6*3]    ;(offset + align*2)*3
1331     sub    r4, r2
1332     shl    r6, 4         ;jump = (offset + align*2)*48
1333 %define avg_w16_addr avg_w16_align1_1_ssse3-(avg_w16_align2_2_ssse3-avg_w16_align1_1_ssse3)
1334 %ifdef PIC
1335     lea    r7, [avg_w16_addr]
1336     add    r6, r7
1337 %else
1338     lea    r6, [avg_w16_addr + r6]
1339 %endif
1340     TAIL_CALL r6, 1
1341
1342 %assign j 0
1343 %assign k 1
1344 %rep 16
1345 AVG16_CACHELINE_LOOP_SSSE3 j, j
1346 AVG16_CACHELINE_LOOP_SSSE3 j, k
1347 %assign j j+1
1348 %assign k k+1
1349 %endrep
1350 %endif ; !HIGH_BIT_DEPTH
1351
1352 ;=============================================================================
1353 ; pixel copy
1354 ;=============================================================================
1355
1356 %macro COPY1 2
1357     movu  m0, [r2]
1358     movu  m1, [r2+r3]
1359     movu  m2, [r2+r3*2]
1360     movu  m3, [r2+%2]
1361     mova  [r0],      m0
1362     mova  [r0+r1],   m1
1363     mova  [r0+r1*2], m2
1364     mova  [r0+%1],   m3
1365 %endmacro
1366
1367 %macro COPY2 2-4 0, 1
1368     movu  m0, [r2+%3*mmsize]
1369     movu  m1, [r2+%4*mmsize]
1370     movu  m2, [r2+r3+%3*mmsize]
1371     movu  m3, [r2+r3+%4*mmsize]
1372     mova  [r0+%3*mmsize],      m0
1373     mova  [r0+%4*mmsize],      m1
1374     mova  [r0+r1+%3*mmsize],   m2
1375     mova  [r0+r1+%4*mmsize],   m3
1376     movu  m0, [r2+r3*2+%3*mmsize]
1377     movu  m1, [r2+r3*2+%4*mmsize]
1378     movu  m2, [r2+%2+%3*mmsize]
1379     movu  m3, [r2+%2+%4*mmsize]
1380     mova  [r0+r1*2+%3*mmsize], m0
1381     mova  [r0+r1*2+%4*mmsize], m1
1382     mova  [r0+%1+%3*mmsize],   m2
1383     mova  [r0+%1+%4*mmsize],   m3
1384 %endmacro
1385
1386 %macro COPY4 2
1387     COPY2 %1, %2, 0, 1
1388     COPY2 %1, %2, 2, 3
1389 %endmacro
1390
1391 ;-----------------------------------------------------------------------------
1392 ; void mc_copy_w4( uint8_t *dst, intptr_t i_dst_stride,
1393 ;                  uint8_t *src, intptr_t i_src_stride, int i_height )
1394 ;-----------------------------------------------------------------------------
1395 INIT_MMX
1396 cglobal mc_copy_w4_mmx, 4,6
1397     FIX_STRIDES r1, r3
1398     cmp dword r4m, 4
1399     lea     r5, [r3*3]
1400     lea     r4, [r1*3]
1401     je .end
1402 %if HIGH_BIT_DEPTH == 0
1403     %define mova movd
1404     %define movu movd
1405 %endif
1406     COPY1   r4, r5
1407     lea     r2, [r2+r3*4]
1408     lea     r0, [r0+r1*4]
1409 .end:
1410     COPY1   r4, r5
1411     RET
1412
1413 %macro MC_COPY 1
1414 %assign %%w %1*SIZEOF_PIXEL/mmsize
1415 %if %%w > 0
1416 cglobal mc_copy_w%1, 5,7
1417     FIX_STRIDES r1, r3
1418     lea     r6, [r3*3]
1419     lea     r5, [r1*3]
1420 .height_loop:
1421     COPY %+ %%w r5, r6
1422     lea     r2, [r2+r3*4]
1423     lea     r0, [r0+r1*4]
1424     sub    r4d, 4
1425     jg .height_loop
1426     RET
1427 %endif
1428 %endmacro
1429
1430 INIT_MMX mmx
1431 MC_COPY  8
1432 MC_COPY 16
1433 INIT_XMM sse
1434 MC_COPY  8
1435 MC_COPY 16
1436 INIT_XMM aligned, sse
1437 MC_COPY 16
1438 %if HIGH_BIT_DEPTH
1439 INIT_YMM avx
1440 MC_COPY 16
1441 INIT_YMM aligned, avx
1442 MC_COPY 16
1443 %endif
1444
1445 ;=============================================================================
1446 ; prefetch
1447 ;=============================================================================
1448 ; assumes 64 byte cachelines
1449 ; FIXME doesn't cover all pixels in high depth and/or 4:4:4
1450
1451 ;-----------------------------------------------------------------------------
1452 ; void prefetch_fenc( pixel *pix_y,  intptr_t stride_y,
1453 ;                     pixel *pix_uv, intptr_t stride_uv, int mb_x )
1454 ;-----------------------------------------------------------------------------
1455
1456 %macro PREFETCH_FENC 1
1457 %if ARCH_X86_64
1458 cglobal prefetch_fenc_%1, 5,5
1459     FIX_STRIDES r1, r3
1460     and    r4d, 3
1461     mov    eax, r4d
1462     imul   r4d, r1d
1463     lea    r0,  [r0+r4*4+64*SIZEOF_PIXEL]
1464     prefetcht0  [r0]
1465     prefetcht0  [r0+r1]
1466     lea    r0,  [r0+r1*2]
1467     prefetcht0  [r0]
1468     prefetcht0  [r0+r1]
1469
1470     imul   eax, r3d
1471     lea    r2,  [r2+rax*2+64*SIZEOF_PIXEL]
1472     prefetcht0  [r2]
1473     prefetcht0  [r2+r3]
1474 %ifidn %1, 422
1475     lea    r2,  [r2+r3*2]
1476     prefetcht0  [r2]
1477     prefetcht0  [r2+r3]
1478 %endif
1479     RET
1480
1481 %else
1482 cglobal prefetch_fenc_%1, 0,3
1483     mov    r2, r4m
1484     mov    r1, r1m
1485     mov    r0, r0m
1486     FIX_STRIDES r1
1487     and    r2, 3
1488     imul   r2, r1
1489     lea    r0, [r0+r2*4+64*SIZEOF_PIXEL]
1490     prefetcht0 [r0]
1491     prefetcht0 [r0+r1]
1492     lea    r0, [r0+r1*2]
1493     prefetcht0 [r0]
1494     prefetcht0 [r0+r1]
1495
1496     mov    r2, r4m
1497     mov    r1, r3m
1498     mov    r0, r2m
1499     FIX_STRIDES r1
1500     and    r2, 3
1501     imul   r2, r1
1502     lea    r0, [r0+r2*2+64*SIZEOF_PIXEL]
1503     prefetcht0 [r0]
1504     prefetcht0 [r0+r1]
1505 %ifidn %1, 422
1506     lea    r0,  [r0+r1*2]
1507     prefetcht0  [r0]
1508     prefetcht0  [r0+r1]
1509 %endif
1510     ret
1511 %endif ; ARCH_X86_64
1512 %endmacro
1513
1514 INIT_MMX mmx2
1515 PREFETCH_FENC 420
1516 PREFETCH_FENC 422
1517
1518 ;-----------------------------------------------------------------------------
1519 ; void prefetch_ref( pixel *pix, intptr_t stride, int parity )
1520 ;-----------------------------------------------------------------------------
1521 INIT_MMX mmx2
1522 cglobal prefetch_ref, 3,3
1523     FIX_STRIDES r1
1524     dec    r2d
1525     and    r2d, r1d
1526     lea    r0,  [r0+r2*8+64*SIZEOF_PIXEL]
1527     lea    r2,  [r1*3]
1528     prefetcht0  [r0]
1529     prefetcht0  [r0+r1]
1530     prefetcht0  [r0+r1*2]
1531     prefetcht0  [r0+r2]
1532     lea    r0,  [r0+r1*4]
1533     prefetcht0  [r0]
1534     prefetcht0  [r0+r1]
1535     prefetcht0  [r0+r1*2]
1536     prefetcht0  [r0+r2]
1537     RET
1538
1539
1540
1541 ;=============================================================================
1542 ; chroma MC
1543 ;=============================================================================
1544
1545 %if ARCH_X86_64
1546     DECLARE_REG_TMP 6,7,8
1547 %else
1548     DECLARE_REG_TMP 0,1,2
1549 %endif
1550
1551 %macro MC_CHROMA_START 1
1552 %if ARCH_X86_64
1553     PROLOGUE 0,9,%1
1554 %else
1555     PROLOGUE 0,6,%1
1556 %endif
1557     movifnidn r3,  r3mp
1558     movifnidn r4d, r4m
1559     movifnidn r5d, r5m
1560     movifnidn t0d, r6m
1561     mov       t2d, t0d
1562     mov       t1d, r5d
1563     sar       t0d, 3
1564     sar       t1d, 3
1565     imul      t0d, r4d
1566     lea       t0d, [t0+t1*2]
1567     FIX_STRIDES t0d
1568     movsxdifnidn t0, t0d
1569     add       r3,  t0            ; src += (dx>>3) + (dy>>3) * src_stride
1570 %endmacro
1571
1572 %if HIGH_BIT_DEPTH
1573 %macro UNPACK_UNALIGNED 4
1574     movu       %1, [%4+0]
1575     movu       %2, [%4+4]
1576     punpckhwd  %3, %1, %2
1577     punpcklwd  %1, %2
1578 %if mmsize == 8
1579     mova       %2, %1
1580     punpcklwd  %1, %3
1581     punpckhwd  %2, %3
1582 %else
1583     shufps     %2, %1, %3, q3131
1584     shufps     %1, %3, q2020
1585 %endif
1586 %endmacro
1587 %else ; !HIGH_BIT_DEPTH
1588 %macro UNPACK_UNALIGNED 3
1589 %if mmsize == 8
1590     punpcklwd  %1, %3
1591 %else
1592     movh       %2, %3
1593     punpcklwd  %1, %2
1594 %endif
1595 %endmacro
1596 %endif ; HIGH_BIT_DEPTH
1597
1598 ;-----------------------------------------------------------------------------
1599 ; void mc_chroma( uint8_t *dstu, uint8_t *dstv, intptr_t dst_stride,
1600 ;                 uint8_t *src, intptr_t src_stride,
1601 ;                 int dx, int dy,
1602 ;                 int width, int height )
1603 ;-----------------------------------------------------------------------------
1604 %macro MC_CHROMA 0
1605 cglobal mc_chroma
1606     MC_CHROMA_START 0
1607     FIX_STRIDES r4
1608     and       r5d, 7
1609 %if ARCH_X86_64
1610     jz .mc1dy
1611 %endif
1612     and       t2d, 7
1613 %if ARCH_X86_64
1614     jz .mc1dx
1615 %endif
1616     shl       r5d, 16
1617     add       t2d, r5d
1618     mov       t0d, t2d
1619     shl       t2d, 8
1620     sub       t2d, t0d
1621     add       t2d, 0x80008 ; (x<<24) + ((8-x)<<16) + (y<<8) + (8-y)
1622     cmp dword r7m, 4
1623 %if mmsize==8
1624 .skip_prologue:
1625 %else
1626     jl mc_chroma_mmx2 %+ .skip_prologue
1627     WIN64_SPILL_XMM 9
1628 %endif
1629     movd       m5, t2d
1630     movifnidn  r0, r0mp
1631     movifnidn  r1, r1mp
1632     movifnidn r2d, r2m
1633     movifnidn r5d, r8m
1634     pxor       m6, m6
1635     punpcklbw  m5, m6
1636 %if mmsize==8
1637     pshufw     m7, m5, q3232
1638     pshufw     m6, m5, q0000
1639     pshufw     m5, m5, q1111
1640     jge .width4
1641 %else
1642 %if WIN64
1643     cmp dword r7m, 4 ; flags were clobbered by WIN64_SPILL_XMM
1644 %endif
1645     pshufd     m7, m5, q1111
1646     punpcklwd  m5, m5
1647     pshufd     m6, m5, q0000
1648     pshufd     m5, m5, q1111
1649     jg .width8
1650 %endif
1651 %if HIGH_BIT_DEPTH
1652     add        r2, r2
1653     UNPACK_UNALIGNED m0, m1, m2, r3
1654 %else
1655     movu       m0, [r3]
1656     UNPACK_UNALIGNED m0, m1, [r3+2]
1657     mova       m1, m0
1658     pand       m0, [pw_00ff]
1659     psrlw      m1, 8
1660 %endif ; HIGH_BIT_DEPTH
1661     pmaddwd    m0, m7
1662     pmaddwd    m1, m7
1663     packssdw   m0, m1
1664     SWAP        3, 0
1665 ALIGN 4
1666 .loop2:
1667 %if HIGH_BIT_DEPTH
1668     UNPACK_UNALIGNED m0, m1, m2, r3+r4
1669     pmullw     m3, m6
1670 %else ; !HIGH_BIT_DEPTH
1671     movu       m0, [r3+r4]
1672     UNPACK_UNALIGNED m0, m1, [r3+r4+2]
1673     pmullw     m3, m6
1674     mova       m1, m0
1675     pand       m0, [pw_00ff]
1676     psrlw      m1, 8
1677 %endif ; HIGH_BIT_DEPTH
1678     pmaddwd    m0, m7
1679     pmaddwd    m1, m7
1680     mova       m2, [pw_32]
1681     packssdw   m0, m1
1682     paddw      m2, m3
1683     mova       m3, m0
1684     pmullw     m0, m5
1685     paddw      m0, m2
1686     psrlw      m0, 6
1687 %if HIGH_BIT_DEPTH
1688     movh     [r0], m0
1689 %if mmsize == 8
1690     psrlq      m0, 32
1691     movh     [r1], m0
1692 %else
1693     movhps   [r1], m0
1694 %endif
1695 %else ; !HIGH_BIT_DEPTH
1696     packuswb   m0, m0
1697     movd     [r0], m0
1698 %if mmsize==8
1699     psrlq      m0, 16
1700 %else
1701     psrldq     m0, 4
1702 %endif
1703     movd     [r1], m0
1704 %endif ; HIGH_BIT_DEPTH
1705     add        r3, r4
1706     add        r0, r2
1707     add        r1, r2
1708     dec       r5d
1709     jg .loop2
1710     RET
1711
1712 %if mmsize==8
1713 .width4:
1714 %if ARCH_X86_64
1715     mov        t0, r0
1716     mov        t1, r1
1717     mov        t2, r3
1718 %if WIN64
1719     %define multy0 r4m
1720 %else
1721     %define multy0 [rsp-8]
1722 %endif
1723     mova    multy0, m5
1724 %else
1725     mov       r3m, r3
1726     %define multy0 r4m
1727     mova    multy0, m5
1728 %endif
1729 %else
1730 .width8:
1731 %if ARCH_X86_64
1732     %define multy0 m8
1733     SWAP        8, 5
1734 %else
1735     %define multy0 r0m
1736     mova    multy0, m5
1737 %endif
1738 %endif
1739     FIX_STRIDES r2
1740 .loopx:
1741 %if HIGH_BIT_DEPTH
1742     UNPACK_UNALIGNED m0, m2, m4, r3
1743     UNPACK_UNALIGNED m1, m3, m5, r3+mmsize
1744 %else
1745     movu       m0, [r3]
1746     movu       m1, [r3+mmsize/2]
1747     UNPACK_UNALIGNED m0, m2, [r3+2]
1748     UNPACK_UNALIGNED m1, m3, [r3+2+mmsize/2]
1749     psrlw      m2, m0, 8
1750     psrlw      m3, m1, 8
1751     pand       m0, [pw_00ff]
1752     pand       m1, [pw_00ff]
1753 %endif
1754     pmaddwd    m0, m7
1755     pmaddwd    m2, m7
1756     pmaddwd    m1, m7
1757     pmaddwd    m3, m7
1758     packssdw   m0, m2
1759     packssdw   m1, m3
1760     SWAP        4, 0
1761     SWAP        5, 1
1762     add        r3, r4
1763 ALIGN 4
1764 .loop4:
1765 %if HIGH_BIT_DEPTH
1766     UNPACK_UNALIGNED m0, m1, m2, r3
1767     pmaddwd    m0, m7
1768     pmaddwd    m1, m7
1769     packssdw   m0, m1
1770     UNPACK_UNALIGNED m1, m2, m3, r3+mmsize
1771     pmaddwd    m1, m7
1772     pmaddwd    m2, m7
1773     packssdw   m1, m2
1774 %else ; !HIGH_BIT_DEPTH
1775     movu       m0, [r3]
1776     movu       m1, [r3+mmsize/2]
1777     UNPACK_UNALIGNED m0, m2, [r3+2]
1778     UNPACK_UNALIGNED m1, m3, [r3+2+mmsize/2]
1779     psrlw      m2, m0, 8
1780     psrlw      m3, m1, 8
1781     pand       m0, [pw_00ff]
1782     pand       m1, [pw_00ff]
1783     pmaddwd    m0, m7
1784     pmaddwd    m2, m7
1785     pmaddwd    m1, m7
1786     pmaddwd    m3, m7
1787     packssdw   m0, m2
1788     packssdw   m1, m3
1789 %endif ; HIGH_BIT_DEPTH
1790     pmullw     m4, m6
1791     pmullw     m5, m6
1792     mova       m2, [pw_32]
1793     paddw      m3, m2, m5
1794     paddw      m2, m4
1795     mova       m4, m0
1796     mova       m5, m1
1797     pmullw     m0, multy0
1798     pmullw     m1, multy0
1799     paddw      m0, m2
1800     paddw      m1, m3
1801     psrlw      m0, 6
1802     psrlw      m1, 6
1803 %if HIGH_BIT_DEPTH
1804     movh     [r0], m0
1805     movh     [r0+mmsize/2], m1
1806 %if mmsize==8
1807     psrlq      m0, 32
1808     psrlq      m1, 32
1809     movh     [r1], m0
1810     movh     [r1+mmsize/2], m1
1811 %else
1812     movhps   [r1], m0
1813     movhps   [r1+mmsize/2], m1
1814 %endif
1815 %else ; !HIGH_BIT_DEPTH
1816     packuswb   m0, m1
1817 %if mmsize==8
1818     pshufw     m1, m0, q0020
1819     pshufw     m0, m0, q0031
1820     movd     [r0], m1
1821     movd     [r1], m0
1822 %else
1823     pshufd     m0, m0, q3120
1824     movq     [r0], m0
1825     movhps   [r1], m0
1826 %endif
1827 %endif ; HIGH_BIT_DEPTH
1828     add        r3, r4
1829     add        r0, r2
1830     add        r1, r2
1831     dec       r5d
1832     jg .loop4
1833 %if mmsize!=8
1834     RET
1835 %else
1836     sub dword r7m, 4
1837     jg .width8
1838     RET
1839 .width8:
1840 %if ARCH_X86_64
1841     lea        r3, [t2+8*SIZEOF_PIXEL]
1842     lea        r0, [t0+4*SIZEOF_PIXEL]
1843     lea        r1, [t1+4*SIZEOF_PIXEL]
1844 %else
1845     mov        r3, r3m
1846     mov        r0, r0m
1847     mov        r1, r1m
1848     add        r3, 8*SIZEOF_PIXEL
1849     add        r0, 4*SIZEOF_PIXEL
1850     add        r1, 4*SIZEOF_PIXEL
1851 %endif
1852     mov       r5d, r8m
1853     jmp .loopx
1854 %endif
1855
1856 %if ARCH_X86_64 ; too many regs for x86_32
1857     RESET_MM_PERMUTATION
1858 %if WIN64
1859     %assign stack_offset stack_offset - stack_size_padded
1860     %assign stack_size_padded 0
1861     %assign xmm_regs_used 0
1862 %endif
1863 .mc1dy:
1864     and       t2d, 7
1865     movd       m5, t2d
1866     mov       r6d, r4d ; pel_offset = dx ? 2 : src_stride
1867     jmp .mc1d
1868 .mc1dx:
1869     movd       m5, r5d
1870     mov       r6d, 2*SIZEOF_PIXEL
1871 .mc1d:
1872 %if HIGH_BIT_DEPTH && mmsize == 16
1873     WIN64_SPILL_XMM 8
1874 %endif
1875     mova       m4, [pw_8]
1876     SPLATW     m5, m5
1877     psubw      m4, m5
1878     movifnidn  r0, r0mp
1879     movifnidn  r1, r1mp
1880     movifnidn r2d, r2m
1881     FIX_STRIDES r2
1882     movifnidn r5d, r8m
1883     cmp dword r7m, 4
1884     jg .mc1d_w8
1885     mov        r7, r2
1886     mov        r8, r4
1887 %if mmsize!=8
1888     shr       r5d, 1
1889 %endif
1890 .loop1d_w4:
1891 %if HIGH_BIT_DEPTH
1892 %if mmsize == 8
1893     movq       m0, [r3+0]
1894     movq       m2, [r3+8]
1895     movq       m1, [r3+r6+0]
1896     movq       m3, [r3+r6+8]
1897 %else
1898     movu       m0, [r3]
1899     movu       m1, [r3+r6]
1900     add        r3, r8
1901     movu       m2, [r3]
1902     movu       m3, [r3+r6]
1903 %endif
1904     SBUTTERFLY wd, 0, 2, 6
1905     SBUTTERFLY wd, 1, 3, 7
1906     SBUTTERFLY wd, 0, 2, 6
1907     SBUTTERFLY wd, 1, 3, 7
1908 %if mmsize == 16
1909     SBUTTERFLY wd, 0, 2, 6
1910     SBUTTERFLY wd, 1, 3, 7
1911 %endif
1912 %else ; !HIGH_BIT_DEPTH
1913     movq       m0, [r3]
1914     movq       m1, [r3+r6]
1915 %if mmsize!=8
1916     add        r3, r8
1917     movhps     m0, [r3]
1918     movhps     m1, [r3+r6]
1919 %endif
1920     psrlw      m2, m0, 8
1921     psrlw      m3, m1, 8
1922     pand       m0, [pw_00ff]
1923     pand       m1, [pw_00ff]
1924 %endif ; HIGH_BIT_DEPTH
1925     pmullw     m0, m4
1926     pmullw     m1, m5
1927     pmullw     m2, m4
1928     pmullw     m3, m5
1929     paddw      m0, [pw_4]
1930     paddw      m2, [pw_4]
1931     paddw      m0, m1
1932     paddw      m2, m3
1933     psrlw      m0, 3
1934     psrlw      m2, 3
1935 %if HIGH_BIT_DEPTH
1936 %if mmsize == 8
1937     xchg       r4, r8
1938     xchg       r2, r7
1939 %endif
1940     movq     [r0], m0
1941     movq     [r1], m2
1942 %if mmsize == 16
1943     add        r0, r7
1944     add        r1, r7
1945     movhps   [r0], m0
1946     movhps   [r1], m2
1947 %endif
1948 %else ; !HIGH_BIT_DEPTH
1949     packuswb   m0, m2
1950 %if mmsize==8
1951     xchg       r4, r8
1952     xchg       r2, r7
1953     movd     [r0], m0
1954     psrlq      m0, 32
1955     movd     [r1], m0
1956 %else
1957     movhlps    m1, m0
1958     movd     [r0], m0
1959     movd     [r1], m1
1960     add        r0, r7
1961     add        r1, r7
1962     psrldq     m0, 4
1963     psrldq     m1, 4
1964     movd     [r0], m0
1965     movd     [r1], m1
1966 %endif
1967 %endif ; HIGH_BIT_DEPTH
1968     add        r3, r4
1969     add        r0, r2
1970     add        r1, r2
1971     dec       r5d
1972     jg .loop1d_w4
1973     RET
1974 .mc1d_w8:
1975     sub       r2, 4*SIZEOF_PIXEL
1976     sub       r4, 8*SIZEOF_PIXEL
1977     mov       r7, 4*SIZEOF_PIXEL
1978     mov       r8, 8*SIZEOF_PIXEL
1979 %if mmsize==8
1980     shl       r5d, 1
1981 %endif
1982     jmp .loop1d_w4
1983 %endif ; ARCH_X86_64
1984 %endmacro ; MC_CHROMA
1985
1986 %macro MC_CHROMA_SSSE3 0
1987 cglobal mc_chroma
1988     MC_CHROMA_START 10-cpuflag(avx2)
1989     and       r5d, 7
1990     and       t2d, 7
1991     mov       t0d, r5d
1992     shl       t0d, 8
1993     sub       t0d, r5d
1994     mov       r5d, 8
1995     add       t0d, 8
1996     sub       r5d, t2d
1997     imul      t2d, t0d ; (x*255+8)*y
1998     imul      r5d, t0d ; (x*255+8)*(8-y)
1999     movd      xm6, t2d
2000     movd      xm7, r5d
2001 %if cpuflag(cache64)
2002     mov       t0d, r3d
2003     and       t0d, 7
2004 %ifdef PIC
2005     lea        t1, [ch_shuf_adj]
2006     movddup   xm5, [t1 + t0*4]
2007 %else
2008     movddup   xm5, [ch_shuf_adj + t0*4]
2009 %endif
2010     paddb     xm5, [ch_shuf]
2011     and        r3, ~7
2012 %else
2013     mova       m5, [ch_shuf]
2014 %endif
2015     movifnidn  r0, r0mp
2016     movifnidn  r1, r1mp
2017     movifnidn r2d, r2m
2018     movifnidn r5d, r8m
2019 %if cpuflag(avx2)
2020     vpbroadcastw m6, xm6
2021     vpbroadcastw m7, xm7
2022 %else
2023     SPLATW     m6, m6
2024     SPLATW     m7, m7
2025 %endif
2026 %if ARCH_X86_64
2027     %define shiftround m8
2028     mova       m8, [pw_512]
2029 %else
2030     %define shiftround [pw_512]
2031 %endif
2032     cmp dword r7m, 4
2033     jg .width8
2034
2035 %if cpuflag(avx2)
2036 .loop4:
2037     movu      xm0, [r3]
2038     movu      xm1, [r3+r4]
2039     vinserti128 m0, m0, [r3+r4], 1
2040     vinserti128 m1, m1, [r3+r4*2], 1
2041     pshufb     m0, m5
2042     pshufb     m1, m5
2043     pmaddubsw  m0, m7
2044     pmaddubsw  m1, m6
2045     paddw      m0, m1
2046     pmulhrsw   m0, shiftround
2047     packuswb   m0, m0
2048     vextracti128 xm1, m0, 1
2049     movd     [r0], xm0
2050     movd  [r0+r2], xm1
2051     psrldq    xm0, 4
2052     psrldq    xm1, 4
2053     movd     [r1], xm0
2054     movd  [r1+r2], xm1
2055     lea        r3, [r3+r4*2]
2056     lea        r0, [r0+r2*2]
2057     lea        r1, [r1+r2*2]
2058     sub       r5d, 2
2059     jg .loop4
2060     RET
2061 .width8:
2062     movu      xm0, [r3]
2063     vinserti128 m0, m0, [r3+8], 1
2064     pshufb     m0, m5
2065 .loop8:
2066     movu      xm3, [r3+r4]
2067     vinserti128 m3, m3, [r3+r4+8], 1
2068     pshufb     m3, m5
2069     pmaddubsw  m1, m0, m7
2070     pmaddubsw  m2, m3, m6
2071     pmaddubsw  m3, m3, m7
2072
2073     movu      xm0, [r3+r4*2]
2074     vinserti128 m0, m0, [r3+r4*2+8], 1
2075     pshufb     m0, m5
2076     pmaddubsw  m4, m0, m6
2077
2078     paddw      m1, m2
2079     paddw      m3, m4
2080     pmulhrsw   m1, shiftround
2081     pmulhrsw   m3, shiftround
2082     packuswb   m1, m3
2083     mova       m2, [deinterleave_shufd]
2084     vpermd     m1, m2, m1
2085     vextracti128 xm2, m1, 1
2086     movq      [r0], xm1
2087     movhps    [r1], xm1
2088     movq   [r0+r2], xm2
2089     movhps [r1+r2], xm2
2090 %else
2091     movu       m0, [r3]
2092     pshufb     m0, m5
2093 .loop4:
2094     movu       m1, [r3+r4]
2095     pshufb     m1, m5
2096     movu       m3, [r3+r4*2]
2097     pshufb     m3, m5
2098     mova       m4, m3
2099     pmaddubsw  m0, m7
2100     pmaddubsw  m2, m1, m7
2101     pmaddubsw  m1, m6
2102     pmaddubsw  m3, m6
2103     paddw      m1, m0
2104     paddw      m3, m2
2105     pmulhrsw   m1, shiftround
2106     pmulhrsw   m3, shiftround
2107     mova       m0, m4
2108     packuswb   m1, m3
2109     movd     [r0], m1
2110 %if cpuflag(sse4)
2111     pextrd    [r1], m1, 1
2112     pextrd [r0+r2], m1, 2
2113     pextrd [r1+r2], m1, 3
2114 %else
2115     movhlps    m3, m1
2116     movd  [r0+r2], m3
2117     psrldq     m1, 4
2118     psrldq     m3, 4
2119     movd     [r1], m1
2120     movd  [r1+r2], m3
2121 %endif
2122     lea        r3, [r3+r4*2]
2123     lea        r0, [r0+r2*2]
2124     lea        r1, [r1+r2*2]
2125     sub       r5d, 2
2126     jg .loop4
2127     RET
2128 .width8:
2129     movu       m0, [r3]
2130     pshufb     m0, m5
2131     movu       m1, [r3+8]
2132     pshufb     m1, m5
2133 %if ARCH_X86_64
2134     SWAP        9, 6
2135     %define  mult1 m9
2136 %else
2137     mova      r0m, m6
2138     %define  mult1 r0m
2139 %endif
2140 .loop8:
2141     movu       m2, [r3+r4]
2142     pshufb     m2, m5
2143     movu       m3, [r3+r4+8]
2144     pshufb     m3, m5
2145     mova       m4, m2
2146     mova       m6, m3
2147     pmaddubsw  m0, m7
2148     pmaddubsw  m1, m7
2149     pmaddubsw  m2, mult1
2150     pmaddubsw  m3, mult1
2151     paddw      m0, m2
2152     paddw      m1, m3
2153     pmulhrsw   m0, shiftround ; x + 32 >> 6
2154     pmulhrsw   m1, shiftround
2155     packuswb   m0, m1
2156     pshufd     m0, m0, q3120
2157     movq     [r0], m0
2158     movhps   [r1], m0
2159
2160     movu       m2, [r3+r4*2]
2161     pshufb     m2, m5
2162     movu       m3, [r3+r4*2+8]
2163     pshufb     m3, m5
2164     mova       m0, m2
2165     mova       m1, m3
2166     pmaddubsw  m4, m7
2167     pmaddubsw  m6, m7
2168     pmaddubsw  m2, mult1
2169     pmaddubsw  m3, mult1
2170     paddw      m2, m4
2171     paddw      m3, m6
2172     pmulhrsw   m2, shiftround
2173     pmulhrsw   m3, shiftround
2174     packuswb   m2, m3
2175     pshufd     m2, m2, q3120
2176     movq   [r0+r2], m2
2177     movhps [r1+r2], m2
2178 %endif
2179     lea        r3, [r3+r4*2]
2180     lea        r0, [r0+r2*2]
2181     lea        r1, [r1+r2*2]
2182     sub       r5d, 2
2183     jg .loop8
2184     RET
2185 %endmacro
2186
2187 %if HIGH_BIT_DEPTH
2188 INIT_MMX mmx2
2189 MC_CHROMA
2190 INIT_XMM sse2
2191 MC_CHROMA
2192 INIT_XMM avx
2193 MC_CHROMA
2194 %else ; !HIGH_BIT_DEPTH
2195 INIT_MMX mmx2
2196 MC_CHROMA
2197 INIT_XMM sse2
2198 MC_CHROMA
2199 INIT_XMM ssse3
2200 MC_CHROMA_SSSE3
2201 INIT_XMM cache64, ssse3
2202 MC_CHROMA_SSSE3
2203 INIT_XMM avx
2204 MC_CHROMA_SSSE3 ; No known AVX CPU will trigger CPU_CACHELINE_64
2205 INIT_YMM avx2
2206 MC_CHROMA_SSSE3
2207 %endif ; HIGH_BIT_DEPTH