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