]> git.sesse.net Git - x264/blob - common/x86/mc-a.asm
x86: more AVX2 framework, AVX2 functions, plus some existing asm tweaks
[x264] / 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 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
824 INIT_MMX
825 cglobal pixel_avg2_w10_mmx2, 6,7
826     sub     r4, r2
827     lea     r6, [r4+r3*2]
828 .height_loop:
829     movu    m0, [r2+ 0]
830     movu    m1, [r2+ 8]
831     movh    m2, [r2+16]
832     movu    m3, [r2+r3*2+ 0]
833     movu    m4, [r2+r3*2+ 8]
834     movh    m5, [r2+r3*2+16]
835     pavgw   m0, [r2+r4+ 0]
836     pavgw   m1, [r2+r4+ 8]
837     pavgw   m2, [r2+r4+16]
838     pavgw   m3, [r2+r6+ 0]
839     pavgw   m4, [r2+r6+ 8]
840     pavgw   m5, [r2+r6+16]
841     mova   [r0+ 0], m0
842     mova   [r0+ 8], m1
843     movh   [r0+16], m2
844     mova   [r0+r1*2+ 0], m3
845     mova   [r0+r1*2+ 8], m4
846     movh   [r0+r1*2+16], m5
847     lea     r2, [r2+r3*2*2]
848     lea     r0, [r0+r1*2*2]
849     sub    r5d, 2
850     jg .height_loop
851     RET
852
853 cglobal pixel_avg2_w16_mmx2, 6,7
854     sub     r4, r2
855     lea     r6, [r4+r3*2]
856 .height_loop:
857     movu    m0, [r2+ 0]
858     movu    m1, [r2+ 8]
859     movu    m2, [r2+16]
860     movu    m3, [r2+24]
861     movu    m4, [r2+r3*2+ 0]
862     movu    m5, [r2+r3*2+ 8]
863     movu    m6, [r2+r3*2+16]
864     movu    m7, [r2+r3*2+24]
865     pavgw   m0, [r2+r4+ 0]
866     pavgw   m1, [r2+r4+ 8]
867     pavgw   m2, [r2+r4+16]
868     pavgw   m3, [r2+r4+24]
869     pavgw   m4, [r2+r6+ 0]
870     pavgw   m5, [r2+r6+ 8]
871     pavgw   m6, [r2+r6+16]
872     pavgw   m7, [r2+r6+24]
873     mova   [r0+ 0], m0
874     mova   [r0+ 8], m1
875     mova   [r0+16], m2
876     mova   [r0+24], m3
877     mova   [r0+r1*2+ 0], m4
878     mova   [r0+r1*2+ 8], m5
879     mova   [r0+r1*2+16], m6
880     mova   [r0+r1*2+24], m7
881     lea     r2, [r2+r3*2*2]
882     lea     r0, [r0+r1*2*2]
883     sub    r5d, 2
884     jg .height_loop
885     RET
886
887 cglobal pixel_avg2_w18_mmx2, 6,7
888     sub     r4, r2
889 .height_loop:
890     movu    m0, [r2+ 0]
891     movu    m1, [r2+ 8]
892     movu    m2, [r2+16]
893     movu    m3, [r2+24]
894     movh    m4, [r2+32]
895     pavgw   m0, [r2+r4+ 0]
896     pavgw   m1, [r2+r4+ 8]
897     pavgw   m2, [r2+r4+16]
898     pavgw   m3, [r2+r4+24]
899     pavgw   m4, [r2+r4+32]
900     mova   [r0+ 0], m0
901     mova   [r0+ 8], m1
902     mova   [r0+16], m2
903     mova   [r0+24], m3
904     movh   [r0+32], m4
905     lea     r2, [r2+r3*2]
906     lea     r0, [r0+r1*2]
907     dec    r5d
908     jg .height_loop
909     RET
910
911 INIT_XMM
912 cglobal pixel_avg2_w18_sse2, 6,7,6
913     sub     r4, r2
914 .height_loop:
915     movu    m0, [r2+ 0]
916     movu    m1, [r2+16]
917     movh    m2, [r2+32]
918     movu    m3, [r2+r4+ 0]
919     movu    m4, [r2+r4+16]
920     movh    m5, [r2+r4+32]
921     pavgw   m0, m3
922     pavgw   m1, m4
923     pavgw   m2, m5
924     mova   [r0+ 0], m0
925     mova   [r0+16], m1
926     movh   [r0+32], m2
927     lea     r2, [r2+r3*2]
928     lea     r0, [r0+r1*2]
929     dec    r5d
930     jg .height_loop
931     RET
932 %endif ; HIGH_BIT_DEPTH
933
934 %if HIGH_BIT_DEPTH == 0
935 ;-----------------------------------------------------------------------------
936 ; void pixel_avg2_w4( uint8_t *dst,  intptr_t dst_stride,
937 ;                     uint8_t *src1, intptr_t src_stride,
938 ;                     uint8_t *src2, int height );
939 ;-----------------------------------------------------------------------------
940 %macro AVG2_W8 2
941 cglobal pixel_avg2_w%1_mmx2, 6,7
942     sub    r4, r2
943     lea    r6, [r4+r3]
944 .height_loop:
945     %2     mm0, [r2]
946     %2     mm1, [r2+r3]
947     pavgb  mm0, [r2+r4]
948     pavgb  mm1, [r2+r6]
949     lea    r2, [r2+r3*2]
950     %2     [r0], mm0
951     %2     [r0+r1], mm1
952     lea    r0, [r0+r1*2]
953     sub    r5d, 2
954     jg     .height_loop
955     RET
956 %endmacro
957
958 INIT_MMX
959 AVG2_W8 4, movd
960 AVG2_W8 8, movq
961
962 %macro AVG2_W16 2
963 cglobal pixel_avg2_w%1_mmx2, 6,7
964     sub    r2, r4
965     lea    r6, [r2+r3]
966 .height_loop:
967     movq   mm0, [r4]
968     %2     mm1, [r4+8]
969     movq   mm2, [r4+r3]
970     %2     mm3, [r4+r3+8]
971     pavgb  mm0, [r4+r2]
972     pavgb  mm1, [r4+r2+8]
973     pavgb  mm2, [r4+r6]
974     pavgb  mm3, [r4+r6+8]
975     lea    r4, [r4+r3*2]
976     movq   [r0], mm0
977     %2     [r0+8], mm1
978     movq   [r0+r1], mm2
979     %2     [r0+r1+8], mm3
980     lea    r0, [r0+r1*2]
981     sub    r5d, 2
982     jg     .height_loop
983     RET
984 %endmacro
985
986 AVG2_W16 12, movd
987 AVG2_W16 16, movq
988
989 cglobal pixel_avg2_w20_mmx2, 6,7
990     sub    r2, r4
991     lea    r6, [r2+r3]
992 .height_loop:
993     movq   mm0, [r4]
994     movq   mm1, [r4+8]
995     movd   mm2, [r4+16]
996     movq   mm3, [r4+r3]
997     movq   mm4, [r4+r3+8]
998     movd   mm5, [r4+r3+16]
999     pavgb  mm0, [r4+r2]
1000     pavgb  mm1, [r4+r2+8]
1001     pavgb  mm2, [r4+r2+16]
1002     pavgb  mm3, [r4+r6]
1003     pavgb  mm4, [r4+r6+8]
1004     pavgb  mm5, [r4+r6+16]
1005     lea    r4, [r4+r3*2]
1006     movq   [r0], mm0
1007     movq   [r0+8], mm1
1008     movd   [r0+16], mm2
1009     movq   [r0+r1], mm3
1010     movq   [r0+r1+8], mm4
1011     movd   [r0+r1+16], mm5
1012     lea    r0, [r0+r1*2]
1013     sub    r5d, 2
1014     jg     .height_loop
1015     RET
1016
1017 cglobal pixel_avg2_w16_sse2, 6,7
1018     sub    r4, r2
1019     lea    r6, [r4+r3]
1020 .height_loop:
1021     movdqu xmm0, [r2]
1022     movdqu xmm2, [r2+r3]
1023     movdqu xmm1, [r2+r4]
1024     movdqu xmm3, [r2+r6]
1025     lea    r2, [r2+r3*2]
1026     pavgb  xmm0, xmm1
1027     pavgb  xmm2, xmm3
1028     movdqa [r0], xmm0
1029     movdqa [r0+r1], xmm2
1030     lea    r0, [r0+r1*2]
1031     sub    r5d, 2
1032     jg     .height_loop
1033     RET
1034
1035 %macro AVG2_W20 1
1036 cglobal pixel_avg2_w20_%1, 6,7
1037     sub    r2, r4
1038     lea    r6, [r2+r3]
1039 .height_loop:
1040     movdqu xmm0, [r4]
1041     movdqu xmm2, [r4+r3]
1042 %ifidn %1, sse2_misalign
1043     movd   mm4,  [r4+16]
1044     movd   mm5,  [r4+r3+16]
1045     pavgb  xmm0, [r4+r2]
1046     pavgb  xmm2, [r4+r6]
1047 %else
1048     movdqu xmm1, [r4+r2]
1049     movdqu xmm3, [r4+r6]
1050     movd   mm4,  [r4+16]
1051     movd   mm5,  [r4+r3+16]
1052     pavgb  xmm0, xmm1
1053     pavgb  xmm2, xmm3
1054 %endif
1055     pavgb  mm4,  [r4+r2+16]
1056     pavgb  mm5,  [r4+r6+16]
1057     lea    r4, [r4+r3*2]
1058     movdqa [r0], xmm0
1059     movd   [r0+16], mm4
1060     movdqa [r0+r1], xmm2
1061     movd   [r0+r1+16], mm5
1062     lea    r0, [r0+r1*2]
1063     sub    r5d, 2
1064     jg     .height_loop
1065     RET
1066 %endmacro
1067
1068 AVG2_W20 sse2
1069 AVG2_W20 sse2_misalign
1070
1071 INIT_YMM avx2
1072 cglobal pixel_avg2_w20, 6,7
1073     sub    r2, r4
1074     lea    r6, [r2+r3]
1075 .height_loop:
1076     movu   m0, [r4]
1077     movu   m1, [r4+r3]
1078     pavgb  m0, [r4+r2]
1079     pavgb  m1, [r4+r6]
1080     lea    r4, [r4+r3*2]
1081     mova [r0], m0
1082     mova [r0+r1], m1
1083     lea    r0, [r0+r1*2]
1084     sub    r5d, 2
1085     jg     .height_loop
1086     RET
1087
1088 ; Cacheline split code for processors with high latencies for loads
1089 ; split over cache lines.  See sad-a.asm for a more detailed explanation.
1090 ; This particular instance is complicated by the fact that src1 and src2
1091 ; can have different alignments.  For simplicity and code size, only the
1092 ; MMX cacheline workaround is used.  As a result, in the case of SSE2
1093 ; pixel_avg, the cacheline check functions calls the SSE2 version if there
1094 ; is no cacheline split, and the MMX workaround if there is.
1095
1096 %macro INIT_SHIFT 2
1097     and    eax, 7
1098     shl    eax, 3
1099     movd   %1, [sw_64]
1100     movd   %2, eax
1101     psubw  %1, %2
1102 %endmacro
1103
1104 %macro AVG_CACHELINE_START 0
1105     %assign stack_offset 0
1106     INIT_SHIFT mm6, mm7
1107     mov    eax, r4m
1108     INIT_SHIFT mm4, mm5
1109     PROLOGUE 6,6
1110     and    r2, ~7
1111     and    r4, ~7
1112     sub    r4, r2
1113 .height_loop:
1114 %endmacro
1115
1116 %macro AVG_CACHELINE_LOOP 2
1117     movq   mm1, [r2+%1]
1118     movq   mm0, [r2+8+%1]
1119     movq   mm3, [r2+r4+%1]
1120     movq   mm2, [r2+r4+8+%1]
1121     psrlq  mm1, mm7
1122     psllq  mm0, mm6
1123     psrlq  mm3, mm5
1124     psllq  mm2, mm4
1125     por    mm0, mm1
1126     por    mm2, mm3
1127     pavgb  mm2, mm0
1128     %2 [r0+%1], mm2
1129 %endmacro
1130
1131 %macro AVG_CACHELINE_FUNC 2
1132 pixel_avg2_w%1_cache_mmx2:
1133     AVG_CACHELINE_START
1134     AVG_CACHELINE_LOOP 0, movq
1135 %if %1>8
1136     AVG_CACHELINE_LOOP 8, movq
1137 %if %1>16
1138     AVG_CACHELINE_LOOP 16, movd
1139 %endif
1140 %endif
1141     add    r2, r3
1142     add    r0, r1
1143     dec    r5d
1144     jg .height_loop
1145     RET
1146 %endmacro
1147
1148 %macro AVG_CACHELINE_CHECK 3 ; width, cacheline, instruction set
1149 %if %1 == 12
1150 ;w12 isn't needed because w16 is just as fast if there's no cacheline split
1151 %define cachesplit pixel_avg2_w16_cache_mmx2
1152 %else
1153 %define cachesplit pixel_avg2_w%1_cache_mmx2
1154 %endif
1155 cglobal pixel_avg2_w%1_cache%2_%3
1156     mov    eax, r2m
1157     and    eax, %2-1
1158     cmp    eax, (%2-%1-(%1 % 8))
1159 %if %1==12||%1==20
1160     jbe pixel_avg2_w%1_%3
1161 %else
1162     jb pixel_avg2_w%1_%3
1163 %endif
1164 %if 0 ; or %1==8 - but the extra branch seems too expensive
1165     ja cachesplit
1166 %if ARCH_X86_64
1167     test      r4b, 1
1168 %else
1169     test byte r4m, 1
1170 %endif
1171     jz pixel_avg2_w%1_%3
1172 %else
1173     or     eax, r4m
1174     and    eax, 7
1175     jz pixel_avg2_w%1_%3
1176     mov    eax, r2m
1177 %endif
1178 %if mmsize==16 || (%1==8 && %2==64)
1179     AVG_CACHELINE_FUNC %1, %2
1180 %else
1181     jmp cachesplit
1182 %endif
1183 %endmacro
1184
1185 INIT_MMX
1186 AVG_CACHELINE_CHECK  8, 64, mmx2
1187 AVG_CACHELINE_CHECK 12, 64, mmx2
1188 %if ARCH_X86_64 == 0
1189 AVG_CACHELINE_CHECK 16, 64, mmx2
1190 AVG_CACHELINE_CHECK 20, 64, mmx2
1191 AVG_CACHELINE_CHECK  8, 32, mmx2
1192 AVG_CACHELINE_CHECK 12, 32, mmx2
1193 AVG_CACHELINE_CHECK 16, 32, mmx2
1194 AVG_CACHELINE_CHECK 20, 32, mmx2
1195 %endif
1196 INIT_XMM
1197 AVG_CACHELINE_CHECK 16, 64, sse2
1198 AVG_CACHELINE_CHECK 20, 64, sse2
1199
1200 ; computed jump assumes this loop is exactly 48 bytes
1201 %macro AVG16_CACHELINE_LOOP_SSSE3 2 ; alignment
1202 ALIGN 16
1203 avg_w16_align%1_%2_ssse3:
1204 %if %1==0 && %2==0
1205     movdqa  xmm1, [r2]
1206     pavgb   xmm1, [r2+r4]
1207     add    r2, r3
1208 %elif %1==0
1209     movdqa  xmm1, [r2+r4+16]
1210     palignr xmm1, [r2+r4], %2
1211     pavgb   xmm1, [r2]
1212     add    r2, r3
1213 %elif %2&15==0
1214     movdqa  xmm1, [r2+16]
1215     palignr xmm1, [r2], %1
1216     pavgb   xmm1, [r2+r4]
1217     add    r2, r3
1218 %else
1219     movdqa  xmm1, [r2+16]
1220     movdqa  xmm2, [r2+r4+16]
1221     palignr xmm1, [r2], %1
1222     palignr xmm2, [r2+r4], %2&15
1223     add    r2, r3
1224     pavgb   xmm1, xmm2
1225 %endif
1226     movdqa  [r0], xmm1
1227     add    r0, r1
1228     dec    r5d
1229     jg     avg_w16_align%1_%2_ssse3
1230     ret
1231 %if %1==0
1232     ; make sure the first ones don't end up short
1233     ALIGN 16
1234     times (48-($-avg_w16_align%1_%2_ssse3))>>4 nop
1235 %endif
1236 %endmacro
1237
1238 cglobal pixel_avg2_w16_cache64_ssse3
1239 %if 0 ; seems both tests aren't worth it if src1%16==0 is optimized
1240     mov   eax, r2m
1241     and   eax, 0x3f
1242     cmp   eax, 0x30
1243     jb x264_pixel_avg2_w16_sse2
1244     or    eax, r4m
1245     and   eax, 7
1246     jz x264_pixel_avg2_w16_sse2
1247 %endif
1248     PROLOGUE 6, 8
1249     lea    r6, [r4+r2]
1250     and    r4, ~0xf
1251     and    r6, 0x1f
1252     and    r2, ~0xf
1253     lea    r6, [r6*3]    ;(offset + align*2)*3
1254     sub    r4, r2
1255     shl    r6, 4         ;jump = (offset + align*2)*48
1256 %define avg_w16_addr avg_w16_align1_1_ssse3-(avg_w16_align2_2_ssse3-avg_w16_align1_1_ssse3)
1257 %ifdef PIC
1258     lea    r7, [avg_w16_addr]
1259     add    r6, r7
1260 %else
1261     lea    r6, [avg_w16_addr + r6]
1262 %endif
1263     TAIL_CALL r6, 1
1264
1265 %assign j 0
1266 %assign k 1
1267 %rep 16
1268 AVG16_CACHELINE_LOOP_SSSE3 j, j
1269 AVG16_CACHELINE_LOOP_SSSE3 j, k
1270 %assign j j+1
1271 %assign k k+1
1272 %endrep
1273 %endif ; !HIGH_BIT_DEPTH
1274
1275 ;=============================================================================
1276 ; pixel copy
1277 ;=============================================================================
1278
1279 %macro COPY1 2
1280     movu  m0, [r2]
1281     movu  m1, [r2+r3]
1282     movu  m2, [r2+r3*2]
1283     movu  m3, [r2+%2]
1284     mova  [r0],      m0
1285     mova  [r0+r1],   m1
1286     mova  [r0+r1*2], m2
1287     mova  [r0+%1],   m3
1288 %endmacro
1289
1290 %macro COPY2 2-4 0, 1
1291     movu  m0, [r2+%3*mmsize]
1292     movu  m1, [r2+%4*mmsize]
1293     movu  m2, [r2+r3+%3*mmsize]
1294     movu  m3, [r2+r3+%4*mmsize]
1295     movu  m4, [r2+r3*2+%3*mmsize]
1296     movu  m5, [r2+r3*2+%4*mmsize]
1297     movu  m6, [r2+%2+%3*mmsize]
1298     movu  m7, [r2+%2+%4*mmsize]
1299     mova  [r0+%3*mmsize],      m0
1300     mova  [r0+%4*mmsize],      m1
1301     mova  [r0+r1+%3*mmsize],   m2
1302     mova  [r0+r1+%4*mmsize],   m3
1303     mova  [r0+r1*2+%3*mmsize], m4
1304     mova  [r0+r1*2+%4*mmsize], m5
1305     mova  [r0+%1+%3*mmsize],   m6
1306     mova  [r0+%1+%4*mmsize],   m7
1307 %endmacro
1308
1309 %macro COPY4 2
1310     COPY2 %1, %2, 0, 1
1311     COPY2 %1, %2, 2, 3
1312 %endmacro
1313
1314 ;-----------------------------------------------------------------------------
1315 ; void mc_copy_w4( uint8_t *dst, intptr_t i_dst_stride,
1316 ;                  uint8_t *src, intptr_t i_src_stride, int i_height )
1317 ;-----------------------------------------------------------------------------
1318 INIT_MMX
1319 cglobal mc_copy_w4_mmx, 4,6
1320     FIX_STRIDES r1, r3
1321     cmp dword r4m, 4
1322     lea     r5, [r3*3]
1323     lea     r4, [r1*3]
1324     je .end
1325 %if HIGH_BIT_DEPTH == 0
1326     %define mova movd
1327     %define movu movd
1328 %endif
1329     COPY1   r4, r5
1330     lea     r2, [r2+r3*4]
1331     lea     r0, [r0+r1*4]
1332 .end:
1333     COPY1   r4, r5
1334     RET
1335
1336 %macro MC_COPY 1
1337 %assign %%w %1*SIZEOF_PIXEL/mmsize
1338 %if %%w > 0
1339 cglobal mc_copy_w%1, 5,7,8*(%%w/2)
1340     FIX_STRIDES r1, r3
1341     lea     r6, [r3*3]
1342     lea     r5, [r1*3]
1343 .height_loop:
1344     COPY %+ %%w r5, r6
1345     lea     r2, [r2+r3*4]
1346     lea     r0, [r0+r1*4]
1347     sub    r4d, 4
1348     jg .height_loop
1349     RET
1350 %endif
1351 %endmacro
1352
1353 INIT_MMX mmx
1354 MC_COPY  8
1355 MC_COPY 16
1356 INIT_XMM sse
1357 MC_COPY  8
1358 MC_COPY 16
1359 INIT_XMM aligned, sse
1360 MC_COPY 16
1361
1362
1363
1364 ;=============================================================================
1365 ; prefetch
1366 ;=============================================================================
1367 ; assumes 64 byte cachelines
1368 ; FIXME doesn't cover all pixels in high depth and/or 4:4:4
1369
1370 ;-----------------------------------------------------------------------------
1371 ; void prefetch_fenc( pixel *pix_y,  intptr_t stride_y,
1372 ;                     pixel *pix_uv, intptr_t stride_uv, int mb_x )
1373 ;-----------------------------------------------------------------------------
1374
1375 %macro PREFETCH_FENC 1
1376 %if ARCH_X86_64
1377 cglobal prefetch_fenc_%1, 5,5
1378     FIX_STRIDES r1, r3
1379     and    r4d, 3
1380     mov    eax, r4d
1381     imul   r4d, r1d
1382     lea    r0,  [r0+r4*4+64*SIZEOF_PIXEL]
1383     prefetcht0  [r0]
1384     prefetcht0  [r0+r1]
1385     lea    r0,  [r0+r1*2]
1386     prefetcht0  [r0]
1387     prefetcht0  [r0+r1]
1388
1389     imul   eax, r3d
1390     lea    r2,  [r2+rax*2+64*SIZEOF_PIXEL]
1391     prefetcht0  [r2]
1392     prefetcht0  [r2+r3]
1393 %ifidn %1, 422
1394     lea    r2,  [r2+r3*2]
1395     prefetcht0  [r2]
1396     prefetcht0  [r2+r3]
1397 %endif
1398     RET
1399
1400 %else
1401 cglobal prefetch_fenc_%1, 0,3
1402     mov    r2, r4m
1403     mov    r1, r1m
1404     mov    r0, r0m
1405     FIX_STRIDES r1
1406     and    r2, 3
1407     imul   r2, r1
1408     lea    r0, [r0+r2*4+64*SIZEOF_PIXEL]
1409     prefetcht0 [r0]
1410     prefetcht0 [r0+r1]
1411     lea    r0, [r0+r1*2]
1412     prefetcht0 [r0]
1413     prefetcht0 [r0+r1]
1414
1415     mov    r2, r4m
1416     mov    r1, r3m
1417     mov    r0, r2m
1418     FIX_STRIDES r1
1419     and    r2, 3
1420     imul   r2, r1
1421     lea    r0, [r0+r2*2+64*SIZEOF_PIXEL]
1422     prefetcht0 [r0]
1423     prefetcht0 [r0+r1]
1424 %ifidn %1, 422
1425     lea    r0,  [r0+r1*2]
1426     prefetcht0  [r0]
1427     prefetcht0  [r0+r1]
1428 %endif
1429     ret
1430 %endif ; ARCH_X86_64
1431 %endmacro
1432
1433 INIT_MMX mmx2
1434 PREFETCH_FENC 420
1435 PREFETCH_FENC 422
1436
1437 ;-----------------------------------------------------------------------------
1438 ; void prefetch_ref( pixel *pix, intptr_t stride, int parity )
1439 ;-----------------------------------------------------------------------------
1440 INIT_MMX mmx2
1441 cglobal prefetch_ref, 3,3
1442     FIX_STRIDES r1
1443     dec    r2d
1444     and    r2d, r1d
1445     lea    r0,  [r0+r2*8+64*SIZEOF_PIXEL]
1446     lea    r2,  [r1*3]
1447     prefetcht0  [r0]
1448     prefetcht0  [r0+r1]
1449     prefetcht0  [r0+r1*2]
1450     prefetcht0  [r0+r2]
1451     lea    r0,  [r0+r1*4]
1452     prefetcht0  [r0]
1453     prefetcht0  [r0+r1]
1454     prefetcht0  [r0+r1*2]
1455     prefetcht0  [r0+r2]
1456     RET
1457
1458
1459
1460 ;=============================================================================
1461 ; chroma MC
1462 ;=============================================================================
1463
1464 %if ARCH_X86_64
1465     DECLARE_REG_TMP 6,7,8
1466 %else
1467     DECLARE_REG_TMP 0,1,2
1468 %endif
1469
1470 %macro MC_CHROMA_START 1
1471 %if ARCH_X86_64
1472     PROLOGUE 0,9,%1
1473 %else
1474     PROLOGUE 0,6,%1
1475 %endif
1476     movifnidn r3,  r3mp
1477     movifnidn r4d, r4m
1478     movifnidn r5d, r5m
1479     movifnidn t0d, r6m
1480     mov       t2d, t0d
1481     mov       t1d, r5d
1482     sar       t0d, 3
1483     sar       t1d, 3
1484     imul      t0d, r4d
1485     lea       t0d, [t0+t1*2]
1486     FIX_STRIDES t0d
1487     movsxdifnidn t0, t0d
1488     add       r3,  t0            ; src += (dx>>3) + (dy>>3) * src_stride
1489 %endmacro
1490
1491 %if HIGH_BIT_DEPTH
1492 %macro UNPACK_UNALIGNED 4
1493     movu       %1, [%4+0]
1494     movu       %2, [%4+4]
1495     punpckhwd  %3, %1, %2
1496     punpcklwd  %1, %2
1497 %if mmsize == 8
1498     mova       %2, %1
1499     punpcklwd  %1, %3
1500     punpckhwd  %2, %3
1501 %else
1502     shufps     %2, %1, %3, q3131
1503     shufps     %1, %3, q2020
1504 %endif
1505 %endmacro
1506 %else ; !HIGH_BIT_DEPTH
1507 %macro UNPACK_UNALIGNED 3
1508 %if mmsize == 8 || cpuflag(misalign)
1509     punpcklwd  %1, %3
1510 %else
1511     movh       %2, %3
1512     punpcklwd  %1, %2
1513 %endif
1514 %endmacro
1515 %endif ; HIGH_BIT_DEPTH
1516
1517 ;-----------------------------------------------------------------------------
1518 ; void mc_chroma( uint8_t *dstu, uint8_t *dstv, intptr_t dst_stride,
1519 ;                 uint8_t *src, intptr_t src_stride,
1520 ;                 int dx, int dy,
1521 ;                 int width, int height )
1522 ;-----------------------------------------------------------------------------
1523 %macro MC_CHROMA 0
1524 cglobal mc_chroma
1525     MC_CHROMA_START 0
1526     FIX_STRIDES r4
1527     and       r5d, 7
1528 %if ARCH_X86_64
1529     jz .mc1dy
1530 %endif
1531     and       t2d, 7
1532 %if ARCH_X86_64
1533     jz .mc1dx
1534 %endif
1535     shl       r5d, 16
1536     add       t2d, r5d
1537     mov       t0d, t2d
1538     shl       t2d, 8
1539     sub       t2d, t0d
1540     add       t2d, 0x80008 ; (x<<24) + ((8-x)<<16) + (y<<8) + (8-y)
1541     cmp dword r7m, 4
1542 %if mmsize==8
1543 .skip_prologue:
1544 %else
1545     jl mc_chroma_mmx2 %+ .skip_prologue
1546     WIN64_SPILL_XMM 9
1547 %endif
1548     movd       m5, t2d
1549     movifnidn  r0, r0mp
1550     movifnidn  r1, r1mp
1551     movifnidn r2d, r2m
1552     movifnidn r5d, r8m
1553     pxor       m6, m6
1554     punpcklbw  m5, m6
1555 %if mmsize==8
1556     pshufw     m7, m5, q3232
1557     pshufw     m6, m5, q0000
1558     pshufw     m5, m5, q1111
1559     jge .width4
1560 %else
1561 %if WIN64
1562     cmp dword r7m, 4 ; flags were clobbered by WIN64_SPILL_XMM
1563 %endif
1564     pshufd     m7, m5, q1111
1565     punpcklwd  m5, m5
1566     pshufd     m6, m5, q0000
1567     pshufd     m5, m5, q1111
1568     jg .width8
1569 %endif
1570 %if HIGH_BIT_DEPTH
1571     add        r2, r2
1572     UNPACK_UNALIGNED m0, m1, m2, r3
1573 %else
1574     movu       m0, [r3]
1575     UNPACK_UNALIGNED m0, m1, [r3+2]
1576     mova       m1, m0
1577     pand       m0, [pw_00ff]
1578     psrlw      m1, 8
1579 %endif ; HIGH_BIT_DEPTH
1580     pmaddwd    m0, m7
1581     pmaddwd    m1, m7
1582     packssdw   m0, m1
1583     SWAP        3, 0
1584 ALIGN 4
1585 .loop2:
1586 %if HIGH_BIT_DEPTH
1587     UNPACK_UNALIGNED m0, m1, m2, r3+r4
1588     pmullw     m3, m6
1589 %else ; !HIGH_BIT_DEPTH
1590     movu       m0, [r3+r4]
1591     UNPACK_UNALIGNED m0, m1, [r3+r4+2]
1592     pmullw     m3, m6
1593     mova       m1, m0
1594     pand       m0, [pw_00ff]
1595     psrlw      m1, 8
1596 %endif ; HIGH_BIT_DEPTH
1597     pmaddwd    m0, m7
1598     pmaddwd    m1, m7
1599     mova       m2, [pw_32]
1600     packssdw   m0, m1
1601     paddw      m2, m3
1602     mova       m3, m0
1603     pmullw     m0, m5
1604     paddw      m0, m2
1605     psrlw      m0, 6
1606 %if HIGH_BIT_DEPTH
1607     movh     [r0], m0
1608 %if mmsize == 8
1609     psrlq      m0, 32
1610     movh     [r1], m0
1611 %else
1612     movhps   [r1], m0
1613 %endif
1614 %else ; !HIGH_BIT_DEPTH
1615     packuswb   m0, m0
1616     movd     [r0], m0
1617 %if mmsize==8
1618     psrlq      m0, 16
1619 %else
1620     psrldq     m0, 4
1621 %endif
1622     movd     [r1], m0
1623 %endif ; HIGH_BIT_DEPTH
1624     add        r3, r4
1625     add        r0, r2
1626     add        r1, r2
1627     dec       r5d
1628     jg .loop2
1629     RET
1630
1631 %if mmsize==8
1632 .width4:
1633 %if ARCH_X86_64
1634     mov        t0, r0
1635     mov        t1, r1
1636     mov        t2, r3
1637 %if WIN64
1638     %define multy0 r4m
1639 %else
1640     %define multy0 [rsp-8]
1641 %endif
1642     mova    multy0, m5
1643 %else
1644     mov       r3m, r3
1645     %define multy0 r4m
1646     mova    multy0, m5
1647 %endif
1648 %else
1649 .width8:
1650 %if ARCH_X86_64
1651     %define multy0 m8
1652     SWAP        8, 5
1653 %else
1654     %define multy0 r0m
1655     mova    multy0, m5
1656 %endif
1657 %endif
1658     FIX_STRIDES r2
1659 .loopx:
1660 %if HIGH_BIT_DEPTH
1661     UNPACK_UNALIGNED m0, m2, m4, r3
1662     UNPACK_UNALIGNED m1, m3, m5, r3+mmsize
1663 %else
1664     movu       m0, [r3]
1665     movu       m1, [r3+mmsize/2]
1666     UNPACK_UNALIGNED m0, m2, [r3+2]
1667     UNPACK_UNALIGNED m1, m3, [r3+2+mmsize/2]
1668     psrlw      m2, m0, 8
1669     psrlw      m3, m1, 8
1670     pand       m0, [pw_00ff]
1671     pand       m1, [pw_00ff]
1672 %endif
1673     pmaddwd    m0, m7
1674     pmaddwd    m2, m7
1675     pmaddwd    m1, m7
1676     pmaddwd    m3, m7
1677     packssdw   m0, m2
1678     packssdw   m1, m3
1679     SWAP        4, 0
1680     SWAP        5, 1
1681     add        r3, r4
1682 ALIGN 4
1683 .loop4:
1684 %if HIGH_BIT_DEPTH
1685     UNPACK_UNALIGNED m0, m1, m2, r3
1686     pmaddwd    m0, m7
1687     pmaddwd    m1, m7
1688     packssdw   m0, m1
1689     UNPACK_UNALIGNED m1, m2, m3, r3+mmsize
1690     pmaddwd    m1, m7
1691     pmaddwd    m2, m7
1692     packssdw   m1, m2
1693 %else ; !HIGH_BIT_DEPTH
1694     movu       m0, [r3]
1695     movu       m1, [r3+mmsize/2]
1696     UNPACK_UNALIGNED m0, m2, [r3+2]
1697     UNPACK_UNALIGNED m1, m3, [r3+2+mmsize/2]
1698     psrlw      m2, m0, 8
1699     psrlw      m3, m1, 8
1700     pand       m0, [pw_00ff]
1701     pand       m1, [pw_00ff]
1702     pmaddwd    m0, m7
1703     pmaddwd    m2, m7
1704     pmaddwd    m1, m7
1705     pmaddwd    m3, m7
1706     packssdw   m0, m2
1707     packssdw   m1, m3
1708 %endif ; HIGH_BIT_DEPTH
1709     pmullw     m4, m6
1710     pmullw     m5, m6
1711     mova       m2, [pw_32]
1712     paddw      m3, m2, m5
1713     paddw      m2, m4
1714     mova       m4, m0
1715     mova       m5, m1
1716     pmullw     m0, multy0
1717     pmullw     m1, multy0
1718     paddw      m0, m2
1719     paddw      m1, m3
1720     psrlw      m0, 6
1721     psrlw      m1, 6
1722 %if HIGH_BIT_DEPTH
1723     movh     [r0], m0
1724     movh     [r0+mmsize/2], m1
1725 %if mmsize==8
1726     psrlq      m0, 32
1727     psrlq      m1, 32
1728     movh     [r1], m0
1729     movh     [r1+mmsize/2], m1
1730 %else
1731     movhps   [r1], m0
1732     movhps   [r1+mmsize/2], m1
1733 %endif
1734 %else ; !HIGH_BIT_DEPTH
1735     packuswb   m0, m1
1736 %if mmsize==8
1737     pshufw     m1, m0, q0020
1738     pshufw     m0, m0, q0031
1739     movd     [r0], m1
1740     movd     [r1], m0
1741 %else
1742     pshufd     m0, m0, q3120
1743     movq     [r0], m0
1744     movhps   [r1], m0
1745 %endif
1746 %endif ; HIGH_BIT_DEPTH
1747     add        r3, r4
1748     add        r0, r2
1749     add        r1, r2
1750     dec       r5d
1751     jg .loop4
1752 %if mmsize!=8
1753     RET
1754 %else
1755     sub dword r7m, 4
1756     jg .width8
1757     RET
1758 .width8:
1759 %if ARCH_X86_64
1760     lea        r3, [t2+8*SIZEOF_PIXEL]
1761     lea        r0, [t0+4*SIZEOF_PIXEL]
1762     lea        r1, [t1+4*SIZEOF_PIXEL]
1763 %else
1764     mov        r3, r3m
1765     mov        r0, r0m
1766     mov        r1, r1m
1767     add        r3, 8*SIZEOF_PIXEL
1768     add        r0, 4*SIZEOF_PIXEL
1769     add        r1, 4*SIZEOF_PIXEL
1770 %endif
1771     mov       r5d, r8m
1772     jmp .loopx
1773 %endif
1774
1775 %if ARCH_X86_64 ; too many regs for x86_32
1776     RESET_MM_PERMUTATION
1777 %if WIN64
1778 %if xmm_regs_used > 6
1779     %assign stack_offset stack_offset-(xmm_regs_used-6)*16-16
1780     %assign xmm_regs_used 6
1781 %endif
1782 %endif
1783 .mc1dy:
1784     and       t2d, 7
1785     movd       m5, t2d
1786     mov       r6d, r4d ; pel_offset = dx ? 2 : src_stride
1787     jmp .mc1d
1788 .mc1dx:
1789     movd       m5, r5d
1790     mov       r6d, 2*SIZEOF_PIXEL
1791 .mc1d:
1792 %if HIGH_BIT_DEPTH && mmsize == 16
1793     WIN64_SPILL_XMM 8
1794 %endif
1795     mova       m4, [pw_8]
1796     SPLATW     m5, m5
1797     psubw      m4, m5
1798     movifnidn  r0, r0mp
1799     movifnidn  r1, r1mp
1800     movifnidn r2d, r2m
1801     FIX_STRIDES r2
1802     movifnidn r5d, r8m
1803     cmp dword r7m, 4
1804     jg .mc1d_w8
1805     mov        r7, r2
1806     mov        r8, r4
1807 %if mmsize!=8
1808     shr       r5d, 1
1809 %endif
1810 .loop1d_w4:
1811 %if HIGH_BIT_DEPTH
1812 %if mmsize == 8
1813     movq       m0, [r3+0]
1814     movq       m2, [r3+8]
1815     movq       m1, [r3+r6+0]
1816     movq       m3, [r3+r6+8]
1817 %else
1818     movu       m0, [r3]
1819     movu       m1, [r3+r6]
1820     add        r3, r8
1821     movu       m2, [r3]
1822     movu       m3, [r3+r6]
1823 %endif
1824     SBUTTERFLY wd, 0, 2, 6
1825     SBUTTERFLY wd, 1, 3, 7
1826     SBUTTERFLY wd, 0, 2, 6
1827     SBUTTERFLY wd, 1, 3, 7
1828 %if mmsize == 16
1829     SBUTTERFLY wd, 0, 2, 6
1830     SBUTTERFLY wd, 1, 3, 7
1831 %endif
1832 %else ; !HIGH_BIT_DEPTH
1833     movq       m0, [r3]
1834     movq       m1, [r3+r6]
1835 %if mmsize!=8
1836     add        r3, r8
1837     movhps     m0, [r3]
1838     movhps     m1, [r3+r6]
1839 %endif
1840     psrlw      m2, m0, 8
1841     psrlw      m3, m1, 8
1842     pand       m0, [pw_00ff]
1843     pand       m1, [pw_00ff]
1844 %endif ; HIGH_BIT_DEPTH
1845     pmullw     m0, m4
1846     pmullw     m1, m5
1847     pmullw     m2, m4
1848     pmullw     m3, m5
1849     paddw      m0, [pw_4]
1850     paddw      m2, [pw_4]
1851     paddw      m0, m1
1852     paddw      m2, m3
1853     psrlw      m0, 3
1854     psrlw      m2, 3
1855 %if HIGH_BIT_DEPTH
1856 %if mmsize == 8
1857     xchg       r4, r8
1858     xchg       r2, r7
1859 %endif
1860     movq     [r0], m0
1861     movq     [r1], m2
1862 %if mmsize == 16
1863     add        r0, r7
1864     add        r1, r7
1865     movhps   [r0], m0
1866     movhps   [r1], m2
1867 %endif
1868 %else ; !HIGH_BIT_DEPTH
1869     packuswb   m0, m2
1870 %if mmsize==8
1871     xchg       r4, r8
1872     xchg       r2, r7
1873     movd     [r0], m0
1874     psrlq      m0, 32
1875     movd     [r1], m0
1876 %else
1877     movhlps    m1, m0
1878     movd     [r0], m0
1879     movd     [r1], m1
1880     add        r0, r7
1881     add        r1, r7
1882     psrldq     m0, 4
1883     psrldq     m1, 4
1884     movd     [r0], m0
1885     movd     [r1], m1
1886 %endif
1887 %endif ; HIGH_BIT_DEPTH
1888     add        r3, r4
1889     add        r0, r2
1890     add        r1, r2
1891     dec       r5d
1892     jg .loop1d_w4
1893     RET
1894 .mc1d_w8:
1895     sub       r2, 4*SIZEOF_PIXEL
1896     sub       r4, 8*SIZEOF_PIXEL
1897     mov       r7, 4*SIZEOF_PIXEL
1898     mov       r8, 8*SIZEOF_PIXEL
1899 %if mmsize==8
1900     shl       r5d, 1
1901 %endif
1902     jmp .loop1d_w4
1903 %endif ; ARCH_X86_64
1904 %endmacro ; MC_CHROMA
1905
1906 %macro MC_CHROMA_SSSE3 0
1907 cglobal mc_chroma
1908 %if cpuflag(avx2)
1909     MC_CHROMA_START 9
1910 %else
1911     MC_CHROMA_START 10
1912 %endif
1913     and       r5d, 7
1914     and       t2d, 7
1915     mov       t0d, r5d
1916     shl       t0d, 8
1917     sub       t0d, r5d
1918     mov       r5d, 8
1919     add       t0d, 8
1920     sub       r5d, t2d
1921     imul      t2d, t0d ; (x*255+8)*y
1922     imul      r5d, t0d ; (x*255+8)*(8-y)
1923     movd      xm6, t2d
1924     movd      xm7, r5d
1925 %if cpuflag(cache64)
1926     mov       t0d, r3d
1927     and       t0d, 7
1928 %ifdef PIC
1929     lea        t1, [ch_shuf_adj]
1930     movddup   xm5, [t1 + t0*4]
1931 %else
1932     movddup   xm5, [ch_shuf_adj + t0*4]
1933 %endif
1934     paddb     xm5, [ch_shuf]
1935     and        r3, ~7
1936 %else
1937     mova       m5, [ch_shuf]
1938 %endif
1939     movifnidn  r0, r0mp
1940     movifnidn  r1, r1mp
1941     movifnidn r2d, r2m
1942     movifnidn r5d, r8m
1943 %if cpuflag(avx2)
1944     vpbroadcastw m6, xm6
1945     vpbroadcastw m7, xm7
1946 %else
1947     SPLATW     m6, m6
1948     SPLATW     m7, m7
1949 %endif
1950 %if ARCH_X86_64
1951     %define shiftround m8
1952     mova       m8, [pw_512]
1953 %else
1954     %define shiftround [pw_512]
1955 %endif
1956     cmp dword r7m, 4
1957     jg .width8
1958
1959 %if cpuflag(avx2)
1960 .loop4:
1961     movu      xm0, [r3]
1962     movu      xm1, [r3+r4]
1963     vinserti128 m0, m0, [r3+r4], 1
1964     vinserti128 m1, m1, [r3+r4*2], 1
1965     pshufb     m0, m5
1966     pshufb     m1, m5
1967     pmaddubsw  m0, m7
1968     pmaddubsw  m1, m6
1969     paddw      m0, m1
1970     pmulhrsw   m0, shiftround
1971     packuswb   m0, m0
1972     vextracti128 xm1, m0, 1
1973     movd     [r0], xm0
1974     movd  [r0+r2], xm1
1975     psrldq    xm0, 4
1976     psrldq    xm1, 4
1977     movd     [r1], xm0
1978     movd  [r1+r2], xm1
1979     lea        r3, [r3+r4*2]
1980     lea        r0, [r0+r2*2]
1981     lea        r1, [r1+r2*2]
1982     sub       r5d, 2
1983     jg .loop4
1984     RET
1985 .width8:
1986     movu      xm0, [r3]
1987     vinserti128 m0, m0, [r3+8], 1
1988     pshufb     m0, m5
1989 .loop8:
1990     movu      xm3, [r3+r4]
1991     vinserti128 m3, m3, [r3+r4+8], 1
1992     pshufb     m3, m5
1993     pmaddubsw  m1, m0, m7
1994     pmaddubsw  m2, m3, m6
1995     pmaddubsw  m3, m3, m7
1996
1997     movu      xm0, [r3+r4*2]
1998     vinserti128 m0, m0, [r3+r4*2+8], 1
1999     pshufb     m0, m5
2000     pmaddubsw  m4, m0, m6
2001
2002     paddw      m1, m2
2003     paddw      m3, m4
2004     pmulhrsw   m1, shiftround
2005     pmulhrsw   m3, shiftround
2006     packuswb   m1, m3
2007     mova       m2, [deinterleave_shufd]
2008     vpermd     m1, m2, m1
2009     vextracti128 xm2, m1, 1
2010     movq      [r0], xm1
2011     movhps    [r1], xm1
2012     movq   [r0+r2], xm2
2013     movhps [r1+r2], xm2
2014 %else
2015     movu       m0, [r3]
2016     pshufb     m0, xm5
2017 .loop4:
2018     movu       m1, [r3+r4]
2019     pshufb     m1, m5
2020     movu       m3, [r3+r4*2]
2021     pshufb     m3, m5
2022     mova       m4, m3
2023     pmaddubsw  m0, m7
2024     pmaddubsw  m2, m1, m7
2025     pmaddubsw  m1, m6
2026     pmaddubsw  m3, m6
2027     paddw      m1, m0
2028     paddw      m3, m2
2029     pmulhrsw   m1, shiftround
2030     pmulhrsw   m3, shiftround
2031     mova       m0, m4
2032     packuswb   m1, m3
2033     movhlps    m3, m1
2034     movd     [r0], xm1
2035     movd  [r0+r2], m3
2036     psrldq     m1, 4
2037     psrldq     m3, 4
2038     movd     [r1], m1
2039     movd  [r1+r2], m3
2040     lea        r3, [r3+r4*2]
2041     lea        r0, [r0+r2*2]
2042     lea        r1, [r1+r2*2]
2043     sub       r5d, 2
2044     jg .loop4
2045     RET
2046 .width8:
2047     movu       m0, [r3]
2048     pshufb     m0, m5
2049     movu       m1, [r3+8]
2050     pshufb     m1, m5
2051 %if ARCH_X86_64
2052     SWAP        9, 6
2053     %define  mult1 m9
2054 %else
2055     mova      r0m, m6
2056     %define  mult1 r0m
2057 %endif
2058 .loop8:
2059     movu       m2, [r3+r4]
2060     pshufb     m2, m5
2061     movu       m3, [r3+r4+8]
2062     pshufb     m3, m5
2063     mova       m4, m2
2064     mova       m6, m3
2065     pmaddubsw  m0, m7
2066     pmaddubsw  m1, m7
2067     pmaddubsw  m2, mult1
2068     pmaddubsw  m3, mult1
2069     paddw      m0, m2
2070     paddw      m1, m3
2071     pmulhrsw   m0, shiftround ; x + 32 >> 6
2072     pmulhrsw   m1, shiftround
2073     packuswb   m0, m1
2074     pshufd     m0, m0, q3120
2075     movq     [r0], m0
2076     movhps   [r1], m0
2077
2078     movu       m2, [r3+r4*2]
2079     pshufb     m2, m5
2080     movu       m3, [r3+r4*2+8]
2081     pshufb     m3, m5
2082     mova       m0, m2
2083     mova       m1, m3
2084     pmaddubsw  m4, m7
2085     pmaddubsw  m6, m7
2086     pmaddubsw  m2, mult1
2087     pmaddubsw  m3, mult1
2088     paddw      m2, m4
2089     paddw      m3, m6
2090     pmulhrsw   m2, shiftround
2091     pmulhrsw   m3, shiftround
2092     packuswb   m2, m3
2093     pshufd     m2, m2, q3120
2094     movq   [r0+r2], m2
2095     movhps [r1+r2], m2
2096 %endif
2097     lea        r3, [r3+r4*2]
2098     lea        r0, [r0+r2*2]
2099     lea        r1, [r1+r2*2]
2100     sub       r5d, 2
2101     jg .loop8
2102     RET
2103 %endmacro
2104
2105 %if HIGH_BIT_DEPTH
2106 INIT_MMX mmx2
2107 MC_CHROMA
2108 INIT_XMM sse2
2109 MC_CHROMA
2110 INIT_XMM avx
2111 MC_CHROMA
2112 %else ; !HIGH_BIT_DEPTH
2113 INIT_MMX mmx2
2114 MC_CHROMA
2115 INIT_XMM sse2, misalign
2116 MC_CHROMA
2117 INIT_XMM sse2
2118 MC_CHROMA
2119 INIT_XMM ssse3
2120 MC_CHROMA_SSSE3
2121 INIT_XMM ssse3, cache64
2122 MC_CHROMA_SSSE3
2123 INIT_XMM avx
2124 MC_CHROMA_SSSE3 ; No known AVX CPU will trigger CPU_CACHELINE_64
2125 INIT_YMM avx2
2126 MC_CHROMA_SSSE3
2127 %endif ; HIGH_BIT_DEPTH