]> git.sesse.net Git - x264/blob - common/x86/mc-a.asm
Update source file headers
[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 ;*          Min Chen <chenm001.163.com>
11 ;*
12 ;* This program is free software; you can redistribute it and/or modify
13 ;* it under the terms of the GNU General Public License as published by
14 ;* the Free Software Foundation; either version 2 of the License, or
15 ;* (at your option) any later version.
16 ;*
17 ;* This program is distributed in the hope that it will be useful,
18 ;* but WITHOUT ANY WARRANTY; without even the implied warranty of
19 ;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20 ;* GNU General Public License for more details.
21 ;*
22 ;* You should have received a copy of the GNU General Public License
23 ;* along with this program; if not, write to the Free Software
24 ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111, USA.
25 ;*
26 ;* This program is also available under a commercial proprietary license.
27 ;* For more information, contact us at licensing@x264.com.
28 ;*****************************************************************************
29
30 %include "x86inc.asm"
31
32 SECTION_RODATA 32
33
34 ch_shuf: db 0,2,2,4,4,6,6,8,1,3,3,5,5,7,7,9
35 ch_shuf_adj: times 8 db 0
36              times 8 db 2
37              times 8 db 4
38              times 8 db 6
39
40 SECTION .text
41
42 cextern pw_4
43 cextern pw_8
44 cextern pw_32
45 cextern pw_64
46 cextern pw_00ff
47 cextern sw_64
48
49 ;=============================================================================
50 ; implicit weighted biprediction
51 ;=============================================================================
52 ; assumes log2_denom = 5, offset = 0, weight1 + weight2 = 64
53 %ifdef ARCH_X86_64
54     DECLARE_REG_TMP 0,1,2,3,4,5,10,11
55     %macro AVG_START 0-1 0
56         PROLOGUE 6,7,%1
57 %ifdef WIN64
58         movsxd r5, r5d
59 %endif
60         .height_loop:
61     %endmacro
62 %else
63     DECLARE_REG_TMP 1,2,3,4,5,6,1,2
64     %macro AVG_START 0-1 0
65         PROLOGUE 0,7,%1
66         mov t0, r0m
67         mov t1, r1m
68         mov t2, r2m
69         mov t3, r3m
70         mov t4, r4m
71         mov t5, r5m
72         .height_loop:
73     %endmacro
74 %endif
75
76 %macro SPLATW 2-3 0
77 %if mmsize==16
78     pshuflw  %1, %2, %3*0x55
79     punpcklqdq %1, %1
80 %else
81     pshufw   %1, %2, %3*0x55
82 %endif
83 %endmacro
84
85 %macro BIWEIGHT_MMX 2
86     movh      m0, %1
87     movh      m1, %2
88     punpcklbw m0, m5
89     punpcklbw m1, m5
90     pmullw    m0, m2
91     pmullw    m1, m3
92     paddw     m0, m1
93     paddw     m0, m4
94     psraw     m0, 6
95 %endmacro
96
97 %macro BIWEIGHT_START_MMX 0
98     movd    m2, r6m
99     SPLATW  m2, m2   ; weight_dst
100     mova    m3, [pw_64]
101     psubw   m3, m2   ; weight_src
102     mova    m4, [pw_32] ; rounding
103     pxor    m5, m5
104 %endmacro
105
106 %macro BIWEIGHT_SSSE3 2
107     movh      m0, %1
108     movh      m1, %2
109     punpcklbw m0, m1
110     pmaddubsw m0, m3
111     paddw     m0, m4
112     psraw     m0, 6
113 %endmacro
114
115 %macro BIWEIGHT_START_SSSE3 0
116     movzx  t6d, byte r6m ; FIXME x86_64
117     mov    t7d, 64
118     sub    t7d, t6d
119     shl    t7d, 8
120     add    t6d, t7d
121     movd    m3, t6d
122     mova    m4, [pw_32]
123     SPLATW  m3, m3   ; weight_dst,src
124 %endmacro
125
126 %macro BIWEIGHT_ROW 4
127     BIWEIGHT [%2], [%3]
128 %if %4==mmsize/2
129     packuswb   m0, m0
130     movh     [%1], m0
131 %else
132     SWAP 0, 6
133     BIWEIGHT [%2+mmsize/2], [%3+mmsize/2]
134     packuswb   m6, m0
135     mova     [%1], m6
136 %endif
137 %endmacro
138
139 ;-----------------------------------------------------------------------------
140 ; int pixel_avg_weight_w16( uint8_t *dst, int, uint8_t *src1, int, uint8_t *src2, int, int i_weight )
141 ;-----------------------------------------------------------------------------
142 %macro AVG_WEIGHT 2-3 0
143 cglobal pixel_avg_weight_w%2_%1
144     BIWEIGHT_START
145     AVG_START %3
146 %if %2==8 && mmsize==16
147     BIWEIGHT [t2], [t4]
148     SWAP 0, 6
149     BIWEIGHT [t2+t3], [t4+t5]
150     packuswb m6, m0
151     movlps   [t0], m6
152     movhps   [t0+t1], m6
153 %else
154 %assign x 0
155 %rep 1+%2/(mmsize*2)
156     BIWEIGHT_ROW t0+x,    t2+x,    t4+x,    %2
157     BIWEIGHT_ROW t0+x+t1, t2+x+t3, t4+x+t5, %2
158 %assign x x+mmsize
159 %endrep
160 %endif
161     lea  t0, [t0+t1*2]
162     lea  t2, [t2+t3*2]
163     lea  t4, [t4+t5*2]
164     sub  eax, 2
165     jg   .height_loop
166     REP_RET
167 %endmacro
168
169 %define BIWEIGHT BIWEIGHT_MMX
170 %define BIWEIGHT_START BIWEIGHT_START_MMX
171 INIT_MMX
172 AVG_WEIGHT mmxext, 4
173 AVG_WEIGHT mmxext, 8
174 AVG_WEIGHT mmxext, 16
175 INIT_XMM
176 %define pixel_avg_weight_w4_sse2 pixel_avg_weight_w4_mmxext
177 AVG_WEIGHT sse2, 8,  7
178 AVG_WEIGHT sse2, 16, 7
179 %define BIWEIGHT BIWEIGHT_SSSE3
180 %define BIWEIGHT_START BIWEIGHT_START_SSSE3
181 INIT_MMX
182 AVG_WEIGHT ssse3, 4
183 INIT_XMM
184 AVG_WEIGHT ssse3, 8,  7
185 AVG_WEIGHT ssse3, 16, 7
186
187 ;=============================================================================
188 ; P frame explicit weighted prediction
189 ;=============================================================================
190
191 %macro WEIGHT_START 1
192     mova     m3, [r4]
193     mova     m6, [r4+16]
194     movd     m5, [r4+32]
195     pxor     m2, m2
196 %if (%1 == 20 || %1 == 12) && mmsize == 16
197     movdq2q mm3, xmm3
198     movdq2q mm4, xmm4
199     movdq2q mm5, xmm5
200     movdq2q mm6, xmm6
201     pxor    mm2, mm2
202 %endif
203 %endmacro
204
205 %macro WEIGHT_START_SSSE3 1
206     mova     m3, [r4]
207     mova     m4, [r4+16]
208     pxor     m2, m2
209 %if %1 == 20 || %1 == 12
210     movdq2q mm3, xmm3
211     movdq2q mm4, xmm4
212     pxor    mm2, mm2
213 %endif
214 %endmacro
215
216 ;; macro to weight mmsize bytes taking half from %1 and half from %2
217 %macro WEIGHT 2             ; (src1,src2)
218     movh      m0, [%1]
219     movh      m1, [%2]
220     punpcklbw m0, m2        ;setup
221     punpcklbw m1, m2        ;setup
222     pmullw    m0, m3        ;scale
223     pmullw    m1, m3        ;scale
224     paddsw    m0, m6        ;1<<(denom-1)+(offset<<denom)
225     paddsw    m1, m6        ;1<<(denom-1)+(offset<<denom)
226     psraw     m0, m5        ;denom
227     psraw     m1, m5        ;denom
228 %endmacro
229
230 %macro WEIGHT_SSSE3 2
231     movh      m0, [%1]
232     movh      m1, [%2]
233     punpcklbw m0, m2
234     punpcklbw m1, m2
235     psllw     m0, 7
236     psllw     m1, 7
237     pmulhrsw  m0, m3
238     pmulhrsw  m1, m3
239     paddw     m0, m4
240     paddw     m1, m4
241 %endmacro
242
243 %macro WEIGHT_SAVE_ROW 3        ;(src,dst,width)
244 %if %3 == 16
245     mova     [%2], %1
246 %elif %3 == 8
247     movq     [%2], %1
248 %else
249     movd     [%2], %1       ; width 2 can write garbage for last 2 bytes
250 %endif
251 %endmacro
252
253 %macro WEIGHT_ROW 3         ; (src,dst,width)
254     ;; load weights
255     WEIGHT           %1, (%1+(mmsize/2))
256     packuswb         m0, m1        ;put bytes into m0
257     WEIGHT_SAVE_ROW  m0, %2, %3
258 %endmacro
259
260 %macro WEIGHT_SAVE_COL 2        ;(dst,size)
261 %if %2 == 8
262     packuswb     m0, m1
263     movq       [%1], m0
264     movhps  [%1+r1], m0
265 %else
266     packuswb     m0, m0
267     packuswb     m1, m1
268     movd       [%1], m0    ; width 2 can write garbage for last 2 bytes
269     movd    [%1+r1], m1
270 %endif
271 %endmacro
272
273 %macro WEIGHT_COL 3     ; (src,dst,width)
274 %if %3 <= 4 && mmsize == 16
275     INIT_MMX
276     ;; load weights
277     WEIGHT           %1, (%1+r3)
278     WEIGHT_SAVE_COL  %2, %3
279     INIT_XMM
280 %else
281     WEIGHT           %1, (%1+r3)
282     WEIGHT_SAVE_COL  %2, %3
283 %endif
284
285 %endmacro
286
287 %macro WEIGHT_TWO_ROW 3 ; (src,dst,width)
288 %assign x 0
289 %rep %3
290 %if (%3-x) >= mmsize
291     WEIGHT_ROW    (%1+x),    (%2+x), mmsize     ; weight 1 mmsize
292     WEIGHT_ROW (%1+r3+x), (%2+r1+x), mmsize     ; weight 1 mmsize
293     %assign x (x+mmsize)
294 %else
295     WEIGHT_COL (%1+x),(%2+x),(%3-x)
296     %exitrep
297 %endif
298 %if x >= %3
299     %exitrep
300 %endif
301 %endrep
302 %endmacro
303
304 ;-----------------------------------------------------------------------------
305 ;void mc_weight_wX( uint8_t *dst, int i_dst_stride, uint8_t *src, int i_src_stride, weight_t *weight, int h )
306 ;-----------------------------------------------------------------------------
307
308 %ifdef ARCH_X86_64
309 %define NUMREGS 6
310 %define LOAD_HEIGHT
311 %define HEIGHT_REG r5d
312 %else
313 %define NUMREGS 5
314 %define LOAD_HEIGHT mov r4d, r5m
315 %define HEIGHT_REG r4d
316 %endif
317
318 %macro WEIGHTER 2
319     cglobal mc_weight_w%1_%2, NUMREGS, NUMREGS, 7
320     WEIGHT_START %1
321     LOAD_HEIGHT
322 .loop:
323     WEIGHT_TWO_ROW r2, r0, %1
324     lea  r0, [r0+r1*2]
325     lea  r2, [r2+r3*2]
326     sub HEIGHT_REG, 2
327     jg .loop
328     REP_RET
329 %endmacro
330
331 INIT_MMX
332 WEIGHTER  4, mmxext
333 WEIGHTER  8, mmxext
334 WEIGHTER 12, mmxext
335 WEIGHTER 16, mmxext
336 WEIGHTER 20, mmxext
337 INIT_XMM
338 WEIGHTER  8, sse2
339 WEIGHTER 16, sse2
340 WEIGHTER 20, sse2
341 %define WEIGHT WEIGHT_SSSE3
342 %define WEIGHT_START WEIGHT_START_SSSE3
343 INIT_MMX
344 WEIGHTER  4, ssse3
345 INIT_XMM
346 WEIGHTER  8, ssse3
347 WEIGHTER 16, ssse3
348 WEIGHTER 20, ssse3
349
350 %macro OFFSET_OP 7
351     mov%6        m0, [%1]
352     mov%6        m1, [%2]
353     p%5usb       m0, m2
354     p%5usb       m1, m2
355     mov%7      [%3], m0
356     mov%7      [%4], m1
357 %endmacro
358
359 %macro OFFSET_TWO_ROW 4
360 %assign x 0
361 %rep %3
362 %if (%3-x) >= mmsize
363     OFFSET_OP (%1+x), (%1+x+r3), (%2+x), (%2+x+r1), %4, u, a
364     %assign x (x+mmsize)
365 %else
366     OFFSET_OP (%1+x),(%1+x+r3), (%2+x), (%2+x+r1), %4, d, d
367     %exitrep
368 %endif
369 %if x >= %3
370     %exitrep
371 %endif
372 %endrep
373 %endmacro
374
375 ;-----------------------------------------------------------------------------
376 ;void mc_offset_wX( uint8_t *src, int i_src_stride, uint8_t *dst, int i_dst_stride, weight_t *w, int h )
377 ;-----------------------------------------------------------------------------
378 %macro OFFSET 3
379     cglobal mc_offset%3_w%1_%2, NUMREGS, NUMREGS
380     mova m2, [r4]
381     LOAD_HEIGHT
382 .loop:
383     OFFSET_TWO_ROW r2, r0, %1, %3
384     lea  r0, [r0+r1*2]
385     lea  r2, [r2+r3*2]
386     sub HEIGHT_REG, 2
387     jg .loop
388     REP_RET
389 %endmacro
390
391 %macro OFFSETPN 2
392        OFFSET %1, %2, add
393        OFFSET %1, %2, sub
394 %endmacro
395 INIT_MMX
396 OFFSETPN  4, mmxext
397 OFFSETPN  8, mmxext
398 OFFSETPN 12, mmxext
399 OFFSETPN 16, mmxext
400 OFFSETPN 20, mmxext
401 INIT_XMM
402 OFFSETPN 12, sse2
403 OFFSETPN 16, sse2
404 OFFSETPN 20, sse2
405 %undef LOAD_HEIGHT
406 %undef HEIGHT_REG
407 %undef NUMREGS
408
409
410
411 ;=============================================================================
412 ; pixel avg
413 ;=============================================================================
414
415 ;-----------------------------------------------------------------------------
416 ; void pixel_avg_4x4( uint8_t *dst, int dst_stride,
417 ;                     uint8_t *src1, int src1_stride, uint8_t *src2, int src2_stride, int weight );
418 ;-----------------------------------------------------------------------------
419 %macro AVGH 3
420 cglobal pixel_avg_%1x%2_%3
421     mov eax, %2
422     cmp dword r6m, 32
423     jne pixel_avg_weight_w%1_%3
424 %if mmsize == 16 && %1 == 16
425     test dword r4m, 15
426     jz pixel_avg_w%1_sse2
427 %endif
428     jmp pixel_avg_w%1_mmxext
429 %endmacro
430
431 ;-----------------------------------------------------------------------------
432 ; void pixel_avg_w4( uint8_t *dst, int dst_stride,
433 ;                    uint8_t *src1, int src1_stride, uint8_t *src2, int src2_stride,
434 ;                    int height, int weight );
435 ;-----------------------------------------------------------------------------
436
437 %macro AVG_END 0
438     sub    eax, 2
439     lea    t4, [t4+t5*2]
440     lea    t2, [t2+t3*2]
441     lea    t0, [t0+t1*2]
442     jg     .height_loop
443     REP_RET
444 %endmacro
445
446 %macro AVG_FUNC 3
447 cglobal %1
448     AVG_START
449     %2     m0, [t2]
450     %2     m1, [t2+t3]
451     pavgb  m0, [t4]
452     pavgb  m1, [t4+t5]
453     %3     [t0], m0
454     %3     [t0+t1], m1
455     AVG_END
456 %endmacro
457
458 INIT_MMX
459 AVG_FUNC pixel_avg_w4_mmxext, movd, movd
460 AVGH 4, 8, mmxext
461 AVGH 4, 4, mmxext
462 AVGH 4, 2, mmxext
463
464 AVG_FUNC pixel_avg_w8_mmxext, movq, movq
465 AVGH 8, 16, mmxext
466 AVGH 8, 8,  mmxext
467 AVGH 8, 4,  mmxext
468
469 cglobal pixel_avg_w16_mmxext
470     AVG_START
471     movq   mm0, [t2  ]
472     movq   mm1, [t2+8]
473     movq   mm2, [t2+t3  ]
474     movq   mm3, [t2+t3+8]
475     pavgb  mm0, [t4  ]
476     pavgb  mm1, [t4+8]
477     pavgb  mm2, [t4+t5  ]
478     pavgb  mm3, [t4+t5+8]
479     movq   [t0  ], mm0
480     movq   [t0+8], mm1
481     movq   [t0+t1  ], mm2
482     movq   [t0+t1+8], mm3
483     AVG_END
484
485 AVGH 16, 16, mmxext
486 AVGH 16, 8,  mmxext
487
488 INIT_XMM
489 AVG_FUNC pixel_avg_w16_sse2, movdqu, movdqa
490 AVGH 16, 16, sse2
491 AVGH 16,  8, sse2
492 AVGH  8, 16, sse2
493 AVGH  8,  8, sse2
494 AVGH  8,  4, sse2
495 AVGH 16, 16, ssse3
496 AVGH 16,  8, ssse3
497 AVGH  8, 16, ssse3
498 AVGH  8,  8, ssse3
499 AVGH  8,  4, ssse3
500 INIT_MMX
501 AVGH  4,  8, ssse3
502 AVGH  4,  4, ssse3
503 AVGH  4,  2, ssse3
504
505
506
507 ;=============================================================================
508 ; pixel avg2
509 ;=============================================================================
510
511 ;-----------------------------------------------------------------------------
512 ; void pixel_avg2_w4( uint8_t *dst, int dst_stride,
513 ;                     uint8_t *src1, int src_stride,
514 ;                     uint8_t *src2, int height );
515 ;-----------------------------------------------------------------------------
516 %macro AVG2_W8 2
517 cglobal pixel_avg2_w%1_mmxext, 6,7
518     sub    r4, r2
519     lea    r6, [r4+r3]
520 .height_loop:
521     %2     mm0, [r2]
522     %2     mm1, [r2+r3]
523     pavgb  mm0, [r2+r4]
524     pavgb  mm1, [r2+r6]
525     %2     [r0], mm0
526     %2     [r0+r1], mm1
527     sub    r5d, 2
528     lea    r2, [r2+r3*2]
529     lea    r0, [r0+r1*2]
530     jg     .height_loop
531     REP_RET
532 %endmacro
533
534 AVG2_W8 4, movd
535 AVG2_W8 8, movq
536
537 %macro AVG2_W16 2
538 cglobal pixel_avg2_w%1_mmxext, 6,7
539     sub    r4, r2
540     lea    r6, [r4+r3]
541 .height_loop:
542     movq   mm0, [r2]
543     %2     mm1, [r2+8]
544     movq   mm2, [r2+r3]
545     %2     mm3, [r2+r3+8]
546     pavgb  mm0, [r2+r4]
547     pavgb  mm1, [r2+r4+8]
548     pavgb  mm2, [r2+r6]
549     pavgb  mm3, [r2+r6+8]
550     movq   [r0], mm0
551     %2     [r0+8], mm1
552     movq   [r0+r1], mm2
553     %2     [r0+r1+8], mm3
554     lea    r2, [r2+r3*2]
555     lea    r0, [r0+r1*2]
556     sub    r5d, 2
557     jg     .height_loop
558     REP_RET
559 %endmacro
560
561 AVG2_W16 12, movd
562 AVG2_W16 16, movq
563
564 cglobal pixel_avg2_w20_mmxext, 6,7
565     sub    r4, r2
566     lea    r6, [r4+r3]
567 .height_loop:
568     movq   mm0, [r2]
569     movq   mm1, [r2+8]
570     movd   mm2, [r2+16]
571     movq   mm3, [r2+r3]
572     movq   mm4, [r2+r3+8]
573     movd   mm5, [r2+r3+16]
574     pavgb  mm0, [r2+r4]
575     pavgb  mm1, [r2+r4+8]
576     pavgb  mm2, [r2+r4+16]
577     pavgb  mm3, [r2+r6]
578     pavgb  mm4, [r2+r6+8]
579     pavgb  mm5, [r2+r6+16]
580     movq   [r0], mm0
581     movq   [r0+8], mm1
582     movd   [r0+16], mm2
583     movq   [r0+r1], mm3
584     movq   [r0+r1+8], mm4
585     movd   [r0+r1+16], mm5
586     lea    r2, [r2+r3*2]
587     lea    r0, [r0+r1*2]
588     sub    r5d, 2
589     jg     .height_loop
590     REP_RET
591
592 cglobal pixel_avg2_w16_sse2, 6,7
593     sub    r4, r2
594     lea    r6, [r4+r3]
595 .height_loop:
596     movdqu xmm0, [r2]
597     movdqu xmm2, [r2+r3]
598     movdqu xmm1, [r2+r4]
599     movdqu xmm3, [r2+r6]
600     pavgb  xmm0, xmm1
601     pavgb  xmm2, xmm3
602     movdqa [r0], xmm0
603     movdqa [r0+r1], xmm2
604     lea    r2, [r2+r3*2]
605     lea    r0, [r0+r1*2]
606     sub    r5d, 2
607     jg     .height_loop
608     REP_RET
609
610 %macro AVG2_W20 1
611 cglobal pixel_avg2_w20_%1, 6,7
612     sub    r4, r2
613     lea    r6, [r4+r3]
614 .height_loop:
615     movdqu xmm0, [r2]
616     movdqu xmm2, [r2+r3]
617     movd   mm4,  [r2+16]
618     movd   mm5,  [r2+r3+16]
619 %ifidn %1, sse2_misalign
620     pavgb  xmm0, [r2+r4]
621     pavgb  xmm2, [r2+r6]
622 %else
623     movdqu xmm1, [r2+r4]
624     movdqu xmm3, [r2+r6]
625     pavgb  xmm0, xmm1
626     pavgb  xmm2, xmm3
627 %endif
628     pavgb  mm4,  [r2+r4+16]
629     pavgb  mm5,  [r2+r6+16]
630     movdqa [r0], xmm0
631     movd   [r0+16], mm4
632     movdqa [r0+r1], xmm2
633     movd   [r0+r1+16], mm5
634     lea    r2, [r2+r3*2]
635     lea    r0, [r0+r1*2]
636     sub    r5d, 2
637     jg     .height_loop
638     REP_RET
639 %endmacro
640
641 AVG2_W20 sse2
642 AVG2_W20 sse2_misalign
643
644 ; Cacheline split code for processors with high latencies for loads
645 ; split over cache lines.  See sad-a.asm for a more detailed explanation.
646 ; This particular instance is complicated by the fact that src1 and src2
647 ; can have different alignments.  For simplicity and code size, only the
648 ; MMX cacheline workaround is used.  As a result, in the case of SSE2
649 ; pixel_avg, the cacheline check functions calls the SSE2 version if there
650 ; is no cacheline split, and the MMX workaround if there is.
651
652 %macro INIT_SHIFT 2
653     and    eax, 7
654     shl    eax, 3
655     movd   %1, [sw_64]
656     movd   %2, eax
657     psubw  %1, %2
658 %endmacro
659
660 %macro AVG_CACHELINE_CHECK 3 ; width, cacheline, instruction set
661 cglobal pixel_avg2_w%1_cache%2_%3
662     mov    eax, r2m
663     and    eax, 0x1f|(%2>>1)
664     cmp    eax, (32-%1)|(%2>>1)
665     jle pixel_avg2_w%1_%3
666 ;w12 isn't needed because w16 is just as fast if there's no cacheline split
667 %if %1 == 12
668     jmp pixel_avg2_w16_cache_mmxext
669 %else
670     jmp pixel_avg2_w%1_cache_mmxext
671 %endif
672 %endmacro
673
674 %macro AVG_CACHELINE_START 0
675     %assign stack_offset 0
676     INIT_SHIFT mm6, mm7
677     mov    eax, r4m
678     INIT_SHIFT mm4, mm5
679     PROLOGUE 6,6
680     and    r2, ~7
681     and    r4, ~7
682     sub    r4, r2
683 .height_loop:
684 %endmacro
685
686 %macro AVG_CACHELINE_LOOP 2
687     movq   mm0, [r2+8+%1]
688     movq   mm1, [r2+%1]
689     movq   mm2, [r2+r4+8+%1]
690     movq   mm3, [r2+r4+%1]
691     psllq  mm0, mm6
692     psrlq  mm1, mm7
693     psllq  mm2, mm4
694     psrlq  mm3, mm5
695     por    mm0, mm1
696     por    mm2, mm3
697     pavgb  mm0, mm2
698     %2 [r0+%1], mm0
699 %endmacro
700
701 pixel_avg2_w8_cache_mmxext:
702     AVG_CACHELINE_START
703     AVG_CACHELINE_LOOP 0, movq
704     add    r2, r3
705     add    r0, r1
706     dec    r5d
707     jg     .height_loop
708     REP_RET
709
710 pixel_avg2_w16_cache_mmxext:
711     AVG_CACHELINE_START
712     AVG_CACHELINE_LOOP 0, movq
713     AVG_CACHELINE_LOOP 8, movq
714     add    r2, r3
715     add    r0, r1
716     dec    r5d
717     jg .height_loop
718     REP_RET
719
720 pixel_avg2_w20_cache_mmxext:
721     AVG_CACHELINE_START
722     AVG_CACHELINE_LOOP 0, movq
723     AVG_CACHELINE_LOOP 8, movq
724     AVG_CACHELINE_LOOP 16, movd
725     add    r2, r3
726     add    r0, r1
727     dec    r5d
728     jg .height_loop
729     REP_RET
730
731 %ifndef ARCH_X86_64
732 AVG_CACHELINE_CHECK  8, 32, mmxext
733 AVG_CACHELINE_CHECK 12, 32, mmxext
734 AVG_CACHELINE_CHECK 16, 32, mmxext
735 AVG_CACHELINE_CHECK 20, 32, mmxext
736 AVG_CACHELINE_CHECK 16, 64, mmxext
737 AVG_CACHELINE_CHECK 20, 64, mmxext
738 %endif
739
740 AVG_CACHELINE_CHECK  8, 64, mmxext
741 AVG_CACHELINE_CHECK 12, 64, mmxext
742 AVG_CACHELINE_CHECK 16, 64, sse2
743 AVG_CACHELINE_CHECK 20, 64, sse2
744
745 ; computed jump assumes this loop is exactly 48 bytes
746 %macro AVG16_CACHELINE_LOOP_SSSE3 2 ; alignment
747 ALIGN 16
748 avg_w16_align%1_%2_ssse3:
749 %if %2&15==0
750     movdqa  xmm1, [r2+16]
751     palignr xmm1, [r2], %1
752     pavgb   xmm1, [r2+r4]
753 %else
754     movdqa  xmm1, [r2+16]
755     movdqa  xmm2, [r2+r4+16]
756     palignr xmm1, [r2], %1
757     palignr xmm2, [r2+r4], %2
758     pavgb   xmm1, xmm2
759 %endif
760     movdqa  [r0], xmm1
761     add    r2, r3
762     add    r0, r1
763     dec    r5d
764     jg     avg_w16_align%1_%2_ssse3
765     rep ret
766 %endmacro
767
768 cglobal pixel_avg2_w16_cache64_ssse3
769     mov    eax, r2m
770     and    eax, 0x3f
771     cmp    eax, 0x30
772     jle pixel_avg2_w16_sse2
773     PROLOGUE 6,7
774     lea    r6, [r4+r2]
775     and    r4, ~0xf
776     and    r6, 0x1f
777     and    r2, ~0xf
778     lea    r6, [r6*3]    ;(offset + align*2)*3
779     sub    r4, r2
780     shl    r6, 4         ;jump = (offset + align*2)*48
781 %define avg_w16_addr avg_w16_align1_1_ssse3-(avg_w16_align2_2_ssse3-avg_w16_align1_1_ssse3)
782 %ifdef PIC
783     lea   r11, [avg_w16_addr]
784     add    r6, r11
785 %else
786     lea    r6, [avg_w16_addr + r6]
787 %endif
788 %ifdef UNIX64
789     jmp    r6
790 %else
791     call   r6
792     RET
793 %endif
794
795 %assign j 1
796 %assign k 2
797 %rep 15
798 AVG16_CACHELINE_LOOP_SSSE3 j, j
799 AVG16_CACHELINE_LOOP_SSSE3 j, k
800 %assign j j+1
801 %assign k k+1
802 %endrep
803
804 ;=============================================================================
805 ; pixel copy
806 ;=============================================================================
807
808 %macro COPY4 4
809     %2  m0, [r2]
810     %2  m1, [r2+r3]
811     %2  m2, [r2+r3*2]
812     %2  m3, [r2+%4]
813     %1  [r0],      m0
814     %1  [r0+r1],   m1
815     %1  [r0+r1*2], m2
816     %1  [r0+%3],   m3
817 %endmacro
818
819 INIT_MMX
820 ;-----------------------------------------------------------------------------
821 ; void mc_copy_w4( uint8_t *dst, int i_dst_stride,
822 ;                  uint8_t *src, int i_src_stride, int i_height )
823 ;-----------------------------------------------------------------------------
824 cglobal mc_copy_w4_mmx, 4,6
825     cmp     dword r4m, 4
826     lea     r5, [r3*3]
827     lea     r4, [r1*3]
828     je .end
829     COPY4 movd, movd, r4, r5
830     lea     r2, [r2+r3*4]
831     lea     r0, [r0+r1*4]
832 .end:
833     COPY4 movd, movd, r4, r5
834     RET
835
836 cglobal mc_copy_w8_mmx, 5,7
837     lea     r6, [r3*3]
838     lea     r5, [r1*3]
839 .height_loop:
840     COPY4 movq, movq, r5, r6
841     lea     r2, [r2+r3*4]
842     lea     r0, [r0+r1*4]
843     sub     r4d, 4
844     jg      .height_loop
845     REP_RET
846
847 cglobal mc_copy_w16_mmx, 5,7
848     lea     r6, [r3*3]
849     lea     r5, [r1*3]
850 .height_loop:
851     movq    mm0, [r2]
852     movq    mm1, [r2+8]
853     movq    mm2, [r2+r3]
854     movq    mm3, [r2+r3+8]
855     movq    mm4, [r2+r3*2]
856     movq    mm5, [r2+r3*2+8]
857     movq    mm6, [r2+r6]
858     movq    mm7, [r2+r6+8]
859     movq    [r0], mm0
860     movq    [r0+8], mm1
861     movq    [r0+r1], mm2
862     movq    [r0+r1+8], mm3
863     movq    [r0+r1*2], mm4
864     movq    [r0+r1*2+8], mm5
865     movq    [r0+r5], mm6
866     movq    [r0+r5+8], mm7
867     lea     r2, [r2+r3*4]
868     lea     r0, [r0+r1*4]
869     sub     r4d, 4
870     jg      .height_loop
871     REP_RET
872
873 INIT_XMM
874 %macro COPY_W16_SSE2 2
875 cglobal %1, 5,7
876     lea     r6, [r3*3]
877     lea     r5, [r1*3]
878 .height_loop:
879     COPY4 movdqa, %2, r5, r6
880     lea     r2, [r2+r3*4]
881     lea     r0, [r0+r1*4]
882     sub     r4d, 4
883     jg      .height_loop
884     REP_RET
885 %endmacro
886
887 COPY_W16_SSE2 mc_copy_w16_sse2, movdqu
888 ; cacheline split with mmx has too much overhead; the speed benefit is near-zero.
889 ; but with SSE3 the overhead is zero, so there's no reason not to include it.
890 COPY_W16_SSE2 mc_copy_w16_sse3, lddqu
891 COPY_W16_SSE2 mc_copy_w16_aligned_sse2, movdqa
892
893
894
895 ;=============================================================================
896 ; prefetch
897 ;=============================================================================
898 ; FIXME assumes 64 byte cachelines
899
900 ;-----------------------------------------------------------------------------
901 ; void prefetch_fenc( uint8_t *pix_y, int stride_y,
902 ;                     uint8_t *pix_uv, int stride_uv, int mb_x )
903 ;-----------------------------------------------------------------------------
904 %ifdef ARCH_X86_64
905 cglobal prefetch_fenc_mmxext, 5,5
906     and    r4d, 3
907     mov    eax, r4d
908     imul   r4d, r1d
909     lea    r0,  [r0+r4*4+64]
910     prefetcht0  [r0]
911     prefetcht0  [r0+r1]
912     lea    r0,  [r0+r1*2]
913     prefetcht0  [r0]
914     prefetcht0  [r0+r1]
915
916     imul   eax, r3d
917     lea    r2,  [r2+rax*2+64]
918     prefetcht0  [r2]
919     prefetcht0  [r2+r3]
920     RET
921
922 %else
923 cglobal prefetch_fenc_mmxext, 0,3
924     mov    r2, r4m
925     mov    r1, r1m
926     mov    r0, r0m
927     and    r2, 3
928     imul   r2, r1
929     lea    r0, [r0+r2*4+64]
930     prefetcht0 [r0]
931     prefetcht0 [r0+r1]
932     lea    r0, [r0+r1*2]
933     prefetcht0 [r0]
934     prefetcht0 [r0+r1]
935
936     mov    r2, r4m
937     mov    r1, r3m
938     mov    r0, r2m
939     and    r2, 3
940     imul   r2, r1
941     lea    r0, [r0+r2*2+64]
942     prefetcht0 [r0]
943     prefetcht0 [r0+r1]
944     ret
945 %endif ; ARCH_X86_64
946
947 ;-----------------------------------------------------------------------------
948 ; void prefetch_ref( uint8_t *pix, int stride, int parity )
949 ;-----------------------------------------------------------------------------
950 cglobal prefetch_ref_mmxext, 3,3
951     dec    r2d
952     and    r2d, r1d
953     lea    r0,  [r0+r2*8+64]
954     lea    r2,  [r1*3]
955     prefetcht0  [r0]
956     prefetcht0  [r0+r1]
957     prefetcht0  [r0+r1*2]
958     prefetcht0  [r0+r2]
959     lea    r0,  [r0+r1*4]
960     prefetcht0  [r0]
961     prefetcht0  [r0+r1]
962     prefetcht0  [r0+r1*2]
963     prefetcht0  [r0+r2]
964     RET
965
966
967
968 ;=============================================================================
969 ; chroma MC
970 ;=============================================================================
971
972 %ifdef ARCH_X86_64
973     DECLARE_REG_TMP 10,11,6
974 %else
975     DECLARE_REG_TMP 0,1,2
976 %endif
977
978 %macro MC_CHROMA_START 0
979     movifnidn r3,  r3mp
980     movifnidn r4d, r4m
981     movifnidn r5d, r5m
982     movifnidn t2d, r6m
983     mov       t0d, t2d
984     mov       t1d, r5d
985     sar       t0d, 3
986     sar       t1d, 3
987     imul      t0d, r4d
988     lea       t0d, [t0+t1*2]
989     movsxdifnidn t0, t0d
990     add       r3,  t0            ; src += (dx>>3) + (dy>>3) * src_stride
991 %endmacro
992
993 %macro UNPACK_UNALIGNED_MEM 3
994     punpcklwd  %1, %3
995 %endmacro
996
997 %macro UNPACK_UNALIGNED_LOAD 3
998     movh       %2, %3
999     punpcklwd  %1, %2
1000 %endmacro
1001
1002 ;-----------------------------------------------------------------------------
1003 ; void mc_chroma( uint8_t *dstu, uint8_t *dstv, int dst_stride,
1004 ;                 uint8_t *src, int src_stride,
1005 ;                 int dx, int dy,
1006 ;                 int width, int height )
1007 ;-----------------------------------------------------------------------------
1008 %macro MC_CHROMA 1
1009 cglobal mc_chroma_%1, 0,6
1010     MC_CHROMA_START
1011     and       r5d, 7
1012 %ifdef ARCH_X86_64
1013     jz .mc1dy
1014 %endif
1015     and       t2d, 7
1016 %ifdef ARCH_X86_64
1017     jz .mc1dx
1018 %endif
1019     shl       r5d, 16
1020     add       t2d, r5d
1021     mov       t0d, t2d
1022     shl       t2d, 8
1023     sub       t2d, t0d
1024     add       t2d, 0x80008 ; (x<<24) + ((8-x)<<16) + (y<<8) + (8-y)
1025     cmp dword r7m, 4
1026 %if mmsize==8
1027 .skip_prologue:
1028 %else
1029     jl mc_chroma_mmxext %+ .skip_prologue
1030     WIN64_SPILL_XMM 9
1031 %endif
1032     movd       m5, t2d
1033     movifnidn  r0, r0mp
1034     movifnidn  r1, r1mp
1035     movifnidn r2d, r2m
1036     movifnidn r5d, r8m
1037     pxor       m6, m6
1038     punpcklbw  m5, m6
1039 %if mmsize==8
1040     pshufw     m7, m5, 0xee
1041     pshufw     m6, m5, 0x00
1042     pshufw     m5, m5, 0x55
1043     jge .width4
1044 %else
1045 %ifdef WIN64
1046     cmp dword r7m, 4 ; flags were clobbered by WIN64_SPILL_XMM
1047 %endif
1048     pshufd     m7, m5, 0x55
1049     punpcklwd  m5, m5
1050     pshufd     m6, m5, 0x00
1051     pshufd     m5, m5, 0x55
1052     jg .width8
1053 %endif
1054     movu       m0, [r3]
1055     UNPACK_UNALIGNED m0, m1, [r3+2]
1056     mova       m1, m0
1057     pand       m0, [pw_00ff]
1058     psrlw      m1, 8
1059     pmaddwd    m0, m7
1060     pmaddwd    m1, m7
1061     packssdw   m0, m1
1062     SWAP       m3, m0
1063 ALIGN 4
1064 .loop2:
1065     movu       m0, [r3+r4]
1066     UNPACK_UNALIGNED m0, m1, [r3+r4+2]
1067     pmullw     m3, m6
1068     mova       m1, m0
1069     pand       m0, [pw_00ff]
1070     psrlw      m1, 8
1071     pmaddwd    m0, m7
1072     pmaddwd    m1, m7
1073     mova       m2, [pw_32]
1074     packssdw   m0, m1
1075     paddw      m2, m3
1076     mova       m3, m0
1077     pmullw     m0, m5
1078     paddw      m0, m2
1079     psrlw      m0, 6
1080     packuswb   m0, m0
1081     movd     [r0], m0
1082 %if mmsize==8
1083     psrlq      m0, 16
1084 %else
1085     psrldq     m0, 4
1086 %endif
1087     movd     [r1], m0
1088     add        r3, r4
1089     add        r0, r2
1090     add        r1, r2
1091     dec       r5d
1092     jg .loop2
1093     REP_RET
1094
1095 %if mmsize==8
1096 .width4:
1097 %ifdef ARCH_X86_64
1098     mov        t0, r0
1099     mov        t1, r1
1100     mov        t2, r3
1101     %define multy0 [rsp-8]
1102     mova    multy0, m5
1103 %else
1104     mov       r3m, r3
1105     %define multy0 r4m
1106     mova    multy0, m5
1107 %endif
1108 %else
1109 .width8:
1110 %ifdef ARCH_X86_64
1111     %define multy0 m8
1112     SWAP       m8, m5
1113 %else
1114     %define multy0 r0m
1115     mova    multy0, m5
1116 %endif
1117 %endif
1118 .loopx:
1119     movu       m0, [r3]
1120     movu       m1, [r3+mmsize/2]
1121     UNPACK_UNALIGNED m0, m2, [r3+2]
1122     UNPACK_UNALIGNED m1, m3, [r3+2+mmsize/2]
1123     mova       m2, m0
1124     mova       m3, m1
1125     pand       m0, [pw_00ff]
1126     pand       m1, [pw_00ff]
1127     psrlw      m2, 8
1128     psrlw      m3, 8
1129     pmaddwd    m0, m7
1130     pmaddwd    m2, m7
1131     pmaddwd    m1, m7
1132     pmaddwd    m3, m7
1133     packssdw   m0, m2
1134     packssdw   m1, m3
1135     SWAP       m4, m0
1136     SWAP       m5, m1
1137     add        r3, r4
1138 ALIGN 4
1139 .loop4:
1140     movu       m0, [r3]
1141     movu       m1, [r3+mmsize/2]
1142     UNPACK_UNALIGNED m0, m2, [r3+2]
1143     UNPACK_UNALIGNED m1, m3, [r3+2+mmsize/2]
1144     mova       m2, m0
1145     mova       m3, m1
1146     pand       m0, [pw_00ff]
1147     pand       m1, [pw_00ff]
1148     psrlw      m2, 8
1149     psrlw      m3, 8
1150     pmaddwd    m0, m7
1151     pmaddwd    m2, m7
1152     pmaddwd    m1, m7
1153     pmaddwd    m3, m7
1154     packssdw   m0, m2
1155     packssdw   m1, m3
1156     pmullw     m4, m6
1157     pmullw     m5, m6
1158     mova       m2, [pw_32]
1159     mova       m3, m2
1160     paddw      m2, m4
1161     paddw      m3, m5
1162     mova       m4, m0
1163     mova       m5, m1
1164     pmullw     m0, multy0
1165     pmullw     m1, multy0
1166     paddw      m0, m2
1167     paddw      m1, m3
1168     psrlw      m0, 6
1169     psrlw      m1, 6
1170     packuswb   m0, m1
1171 %if mmsize==8
1172     pshufw     m1, m0, 0x8
1173     pshufw     m0, m0, 0xd
1174     movd     [r0], m1
1175     movd     [r1], m0
1176 %else
1177     pshufd     m0, m0, 0xd8
1178     movq     [r0], m0
1179     movhps   [r1], m0
1180 %endif
1181     add        r3, r4
1182     add        r0, r2
1183     add        r1, r2
1184     dec       r5d
1185     jg .loop4
1186 %if mmsize!=8
1187     REP_RET
1188 %else
1189     sub dword r7m, 4
1190     jg .width8
1191     REP_RET
1192 .width8:
1193 %ifdef ARCH_X86_64
1194     lea        r3, [t2+8]
1195     lea        r0, [t0+4]
1196     lea        r1, [t1+4]
1197 %else
1198     mov        r3, r3m
1199     mov        r0, r0m
1200     mov        r1, r1m
1201     add        r3, 8
1202     add        r0, 4
1203     add        r1, 4
1204 %endif
1205     mov       r5d, r8m
1206     jmp .loopx
1207 %endif
1208
1209 %ifdef ARCH_X86_64 ; too many regs for x86_32
1210     RESET_MM_PERMUTATION
1211 %ifdef WIN64
1212 %if xmm_regs_used > 6
1213     %assign stack_offset stack_offset-(xmm_regs_used-6)*16-16
1214     %assign xmm_regs_used 6
1215 %endif
1216 %endif
1217 .mc1dy:
1218     and       t2d, 7
1219     movd       m5, t2d
1220     mov       r6d, r4d ; pel_offset = dx ? 2 : src_stride
1221     jmp .mc1d
1222 .mc1dx:
1223     movd       m5, r5d
1224     mov       r6d, 2
1225 .mc1d:
1226     mova       m4, [pw_8]
1227     SPLATW     m5, m5
1228     psubw      m4, m5
1229     movifnidn  r0, r0mp
1230     movifnidn  r1, r1mp
1231     movifnidn r2d, r2m
1232     movifnidn r5d, r8m
1233     cmp dword r7m, 4
1234     jg .mc1d_w8
1235     mov       r10, r2
1236     mov       r11, r4
1237 %if mmsize!=8
1238     shr       r5d, 1
1239 %endif
1240 .loop1d_w4:
1241     movq       m0, [r3]
1242     movq       m1, [r3+r6]
1243 %if mmsize!=8
1244     add        r3, r11
1245     movhps     m0, [r3]
1246     movhps     m1, [r3+r6]
1247 %endif
1248     mova       m2, m0
1249     mova       m3, m1
1250     pand       m0, [pw_00ff]
1251     pand       m1, [pw_00ff]
1252     psrlw      m2, 8
1253     psrlw      m3, 8
1254     pmullw     m0, m4
1255     pmullw     m1, m5
1256     pmullw     m2, m4
1257     pmullw     m3, m5
1258     paddw      m0, [pw_4]
1259     paddw      m2, [pw_4]
1260     paddw      m0, m1
1261     paddw      m2, m3
1262     psrlw      m0, 3
1263     psrlw      m2, 3
1264     packuswb   m0, m2
1265 %if mmsize==8
1266     xchg       r4, r11
1267     xchg       r2, r10
1268     movd     [r0], m0
1269     psrlq      m0, 32
1270     movd     [r1], m0
1271 %else
1272     movhlps    m1, m0
1273     movd     [r0], m0
1274     movd     [r1], m1
1275     add        r0, r10
1276     add        r1, r10
1277     psrldq     m0, 4
1278     psrldq     m1, 4
1279     movd     [r0], m0
1280     movd     [r1], m1
1281 %endif
1282     add        r3, r4
1283     add        r0, r2
1284     add        r1, r2
1285     dec       r5d
1286     jg .loop1d_w4
1287     REP_RET
1288 .mc1d_w8:
1289     sub       r2, 4
1290     sub       r4, 8
1291     mov      r10, 4
1292     mov      r11, 8
1293 %if mmsize==8
1294     shl       r5d, 1
1295 %endif
1296     jmp .loop1d_w4
1297 %endif ; ARCH_X86_64
1298 %endmacro ; MC_CHROMA
1299
1300
1301 %macro MC_CHROMA_SSSE3 0-1
1302 INIT_XMM
1303 cglobal mc_chroma_ssse3%1, 0,6,9
1304     MC_CHROMA_START
1305     and       r5d, 7
1306     and       t2d, 7
1307     mov       t0d, r5d
1308     shl       t0d, 8
1309     sub       t0d, r5d
1310     mov       r5d, 8
1311     add       t0d, 8
1312     sub       r5d, t2d
1313     imul      t2d, t0d ; (x*255+8)*y
1314     imul      r5d, t0d ; (x*255+8)*(8-y)
1315     movd       m6, t2d
1316     movd       m7, r5d
1317 %ifidn %1, _cache64
1318     mov       t0d, r3d
1319     and       t0d, 7
1320 %ifdef PIC
1321     lea        t1, [ch_shuf_adj]
1322     movddup    m5, [t1 + t0*4]
1323 %else
1324     movddup    m5, [ch_shuf_adj + t0*4]
1325 %endif
1326     paddb      m5, [ch_shuf]
1327     and        r3, ~7
1328 %else
1329     mova       m5, [ch_shuf]
1330 %endif
1331     movifnidn  r0, r0mp
1332     movifnidn  r1, r1mp
1333     movifnidn r2d, r2m
1334     movifnidn r5d, r8m
1335     SPLATW     m6, m6
1336     SPLATW     m7, m7
1337     cmp dword r7m, 4
1338     jg .width8
1339     movu       m0, [r3]
1340     pshufb     m0, m5
1341 .loop4:
1342     movu       m1, [r3+r4]
1343     pshufb     m1, m5
1344     movu       m3, [r3+r4*2]
1345     pshufb     m3, m5
1346     mova       m2, m1
1347     mova       m4, m3
1348     pmaddubsw  m0, m7
1349     pmaddubsw  m1, m6
1350     pmaddubsw  m2, m7
1351     pmaddubsw  m3, m6
1352     paddw      m0, [pw_32]
1353     paddw      m2, [pw_32]
1354     paddw      m1, m0
1355     paddw      m3, m2
1356     mova       m0, m4
1357     psrlw      m1, 6
1358     psrlw      m3, 6
1359     packuswb   m1, m3
1360     movhlps    m3, m1
1361     movd     [r0], m1
1362     movd  [r0+r2], m3
1363     psrldq     m1, 4
1364     psrldq     m3, 4
1365     movd     [r1], m1
1366     movd  [r1+r2], m3
1367     lea        r3, [r3+r4*2]
1368     lea        r0, [r0+r2*2]
1369     lea        r1, [r1+r2*2]
1370     sub       r5d, 2
1371     jg .loop4
1372     REP_RET
1373
1374 .width8:
1375     movu       m0, [r3]
1376     pshufb     m0, m5
1377     movu       m1, [r3+8]
1378     pshufb     m1, m5
1379 %ifdef ARCH_X86_64
1380     SWAP       m8, m6
1381     %define  mult1 m8
1382 %else
1383     mova      r0m, m6
1384     %define  mult1 r0m
1385 %endif
1386 .loop8:
1387     movu       m2, [r3+r4]
1388     pshufb     m2, m5
1389     movu       m3, [r3+r4+8]
1390     pshufb     m3, m5
1391     mova       m4, m2
1392     mova       m6, m3
1393     pmaddubsw  m0, m7
1394     pmaddubsw  m1, m7
1395     pmaddubsw  m2, mult1
1396     pmaddubsw  m3, mult1
1397     paddw      m0, [pw_32]
1398     paddw      m1, [pw_32]
1399     paddw      m0, m2
1400     paddw      m1, m3
1401     psrlw      m0, 6
1402     psrlw      m1, 6
1403     packuswb   m0, m1
1404     pshufd     m0, m0, 0xd8
1405     movq     [r0], m0
1406     movhps   [r1], m0
1407
1408     movu       m2, [r3+r4*2]
1409     pshufb     m2, m5
1410     movu       m3, [r3+r4*2+8]
1411     pshufb     m3, m5
1412     mova       m0, m2
1413     mova       m1, m3
1414     pmaddubsw  m4, m7
1415     pmaddubsw  m6, m7
1416     pmaddubsw  m2, mult1
1417     pmaddubsw  m3, mult1
1418     paddw      m4, [pw_32]
1419     paddw      m6, [pw_32]
1420     paddw      m2, m4
1421     paddw      m3, m6
1422     psrlw      m2, 6
1423     psrlw      m3, 6
1424     packuswb   m2, m3
1425     pshufd     m2, m2, 0xd8
1426     movq   [r0+r2], m2
1427     movhps [r1+r2], m2
1428     lea        r3, [r3+r4*2]
1429     lea        r0, [r0+r2*2]
1430     lea        r1, [r1+r2*2]
1431     sub       r5d, 2
1432     jg .loop8
1433     REP_RET
1434 %endmacro
1435
1436 INIT_MMX
1437 %define UNPACK_UNALIGNED UNPACK_UNALIGNED_MEM
1438 MC_CHROMA mmxext
1439 INIT_XMM
1440 MC_CHROMA sse2_misalign
1441 %define UNPACK_UNALIGNED UNPACK_UNALIGNED_LOAD
1442 MC_CHROMA sse2
1443 MC_CHROMA_SSSE3
1444 MC_CHROMA_SSSE3 _cache64