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