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