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