]> git.sesse.net Git - x264/blob - common/x86/mc-a.asm
Faster 8x8dct+CAVLC interleave
[x264] / common / x86 / mc-a.asm
1 ;*****************************************************************************
2 ;* mc-a.asm: h264 encoder library
3 ;*****************************************************************************
4 ;* Copyright (C) 2003-2008 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 ;*          Min Chen <chenm001.163.com>
10 ;*
11 ;* This program is free software; you can redistribute it and/or modify
12 ;* it under the terms of the GNU General Public License as published by
13 ;* the Free Software Foundation; either version 2 of the License, or
14 ;* (at your option) any later version.
15 ;*
16 ;* This program is distributed in the hope that it will be useful,
17 ;* but WITHOUT ANY WARRANTY; without even the implied warranty of
18 ;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19 ;* GNU General Public License for more details.
20 ;*
21 ;* You should have received a copy of the GNU General Public License
22 ;* along with this program; if not, write to the Free Software
23 ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111, USA.
24 ;*****************************************************************************
25
26 %include "x86inc.asm"
27
28 SECTION_RODATA
29
30 pw_4:  times 8 dw  4
31 pw_8:  times 8 dw  8
32 pw_32: times 8 dw 32
33 pw_64: times 8 dw 64
34 sw_64: dd 64
35
36 SECTION .text
37
38 ;=============================================================================
39 ; weighted prediction
40 ;=============================================================================
41 ; implicit bipred only:
42 ; assumes log2_denom = 5, offset = 0, weight1 + weight2 = 64
43 %ifdef ARCH_X86_64
44     DECLARE_REG_TMP 0,1,2,3,4,5,10,11
45     %macro AVG_START 0
46         PROLOGUE 6,7
47         .height_loop:
48     %endmacro
49 %else
50     DECLARE_REG_TMP 1,2,3,4,5,6,1,2
51     %macro AVG_START 0
52         PROLOGUE 0,7
53         mov t0, r0m
54         mov t1, r1m
55         mov t2, r2m
56         mov t3, r3m
57         mov t4, r4m
58         mov t5, r5m
59         .height_loop:
60     %endmacro
61 %endif
62
63 %macro SPLATW 2
64 %if mmsize==16
65     pshuflw  %1, %2, 0
66     punpcklqdq %1, %1
67 %else
68     pshufw   %1, %2, 0
69 %endif
70 %endmacro
71
72 %macro BIWEIGHT_MMX 2
73     movh      m0, %1
74     movh      m1, %2
75     punpcklbw m0, m7
76     punpcklbw m1, m7
77     pmullw    m0, m4
78     pmullw    m1, m5
79     paddw     m0, m1
80     paddw     m0, m6
81     psraw     m0, 6
82 %endmacro
83
84 %macro BIWEIGHT_START_MMX 0
85     movd    m4, r6m
86     SPLATW  m4, m4   ; weight_dst
87     mova    m5, [pw_64 GLOBAL]
88     psubw   m5, m4   ; weight_src
89     mova    m6, [pw_32 GLOBAL] ; rounding
90     pxor    m7, m7
91 %endmacro
92
93 %macro BIWEIGHT_SSSE3 2
94     movh      m0, %1
95     movh      m1, %2
96     punpcklbw m0, m1
97     pmaddubsw m0, m5
98     paddw     m0, m6
99     psraw     m0, 6
100 %endmacro
101
102 %macro BIWEIGHT_START_SSSE3 0
103     movzx  t6d, byte r6m ; FIXME x86_64
104     mov    t7d, 64
105     sub    t7d, t6d
106     shl    t7d, 8
107     add    t6d, t7d
108     movd    m5, t6d
109     mova    m6, [pw_32 GLOBAL]
110     SPLATW  m5, m5   ; weight_dst,src
111 %endmacro
112
113 %macro BIWEIGHT_ROW 4
114     BIWEIGHT [%2], [%3]
115 %if %4==mmsize/2
116     packuswb   m0, m0
117     movh     [%1], m0
118 %else
119     SWAP 0, 2
120     BIWEIGHT [%2+mmsize/2], [%3+mmsize/2]
121     packuswb   m2, m0
122     mova     [%1], m2
123 %endif
124 %endmacro
125
126 ;-----------------------------------------------------------------------------
127 ; int x264_pixel_avg_weight_w16_mmxext( uint8_t *dst, int, uint8_t *src1, int, uint8_t *src2, int, int i_weight )
128 ;-----------------------------------------------------------------------------
129 %macro AVG_WEIGHT 2
130 cglobal x264_pixel_avg_weight_w%2_%1, 0,0
131     BIWEIGHT_START
132     AVG_START
133 %if %2==8 && mmsize==16
134     BIWEIGHT [t2], [t4]
135     SWAP 0, 2
136     BIWEIGHT [t2+t3], [t4+t5]
137     packuswb m2, m0
138     movlps   [t0], m2
139     movhps   [t0+t1], m2
140 %else
141 %assign x 0
142 %rep 1+%2/(mmsize*2)
143     BIWEIGHT_ROW t0+x,    t2+x,    t4+x,    %2
144     BIWEIGHT_ROW t0+x+t1, t2+x+t3, t4+x+t5, %2
145 %assign x x+mmsize
146 %endrep
147 %endif
148     lea  t0, [t0+t1*2]
149     lea  t2, [t2+t3*2]
150     lea  t4, [t4+t5*2]
151     sub  eax, 2
152     jg   .height_loop
153     REP_RET
154 %endmacro
155
156 %define BIWEIGHT BIWEIGHT_MMX
157 %define BIWEIGHT_START BIWEIGHT_START_MMX
158 INIT_MMX
159 AVG_WEIGHT mmxext, 4
160 AVG_WEIGHT mmxext, 8
161 AVG_WEIGHT mmxext, 16
162 INIT_XMM
163 %define x264_pixel_avg_weight_w4_sse2 x264_pixel_avg_weight_w4_mmxext
164 AVG_WEIGHT sse2, 8
165 AVG_WEIGHT sse2, 16
166 %define BIWEIGHT BIWEIGHT_SSSE3
167 %define BIWEIGHT_START BIWEIGHT_START_SSSE3
168 INIT_MMX
169 AVG_WEIGHT ssse3, 4
170 INIT_XMM
171 AVG_WEIGHT ssse3, 8
172 AVG_WEIGHT ssse3, 16
173
174
175
176 ;=============================================================================
177 ; pixel avg
178 ;=============================================================================
179
180 ;-----------------------------------------------------------------------------
181 ; void x264_pixel_avg_4x4_mmxext( uint8_t *dst, int dst_stride,
182 ;                                 uint8_t *src1, int src1_stride, uint8_t *src2, int src2_stride, int weight );
183 ;-----------------------------------------------------------------------------
184 %macro AVGH 3
185 cglobal x264_pixel_avg_%1x%2_%3,0,0
186     mov eax, %2
187     cmp dword r6m, 32
188     jne x264_pixel_avg_weight_w%1_%3
189 %if mmsize == 16 && %1 == 16
190     test dword r4m, 15
191     jz x264_pixel_avg_w%1_sse2
192 %endif
193     jmp x264_pixel_avg_w%1_mmxext
194 %endmacro
195
196 ;-----------------------------------------------------------------------------
197 ; void x264_pixel_avg_w4_mmxext( uint8_t *dst, int dst_stride,
198 ;                                uint8_t *src1, int src1_stride, uint8_t *src2, int src2_stride,
199 ;                                int height, int weight );
200 ;-----------------------------------------------------------------------------
201
202 %macro AVG_END 0
203     sub    eax, 2
204     lea    t4, [t4+t5*2]
205     lea    t2, [t2+t3*2]
206     lea    t0, [t0+t1*2]
207     jg     .height_loop
208     REP_RET
209 %endmacro
210
211 %macro AVG_FUNC 3
212 cglobal %1
213     AVG_START
214     %2     m0, [t2]
215     %2     m1, [t2+t3]
216     pavgb  m0, [t4]
217     pavgb  m1, [t4+t5]
218     %3     [t0], m0
219     %3     [t0+t1], m1
220     AVG_END
221 %endmacro
222
223 INIT_MMX
224 AVG_FUNC x264_pixel_avg_w4_mmxext, movd, movd
225 AVGH 4, 8, mmxext
226 AVGH 4, 4, mmxext
227 AVGH 4, 2, mmxext
228
229 AVG_FUNC x264_pixel_avg_w8_mmxext, movq, movq
230 AVGH 8, 16, mmxext
231 AVGH 8, 8,  mmxext
232 AVGH 8, 4,  mmxext
233
234 cglobal x264_pixel_avg_w16_mmxext
235     AVG_START
236     movq   mm0, [t2  ]
237     movq   mm1, [t2+8]
238     movq   mm2, [t2+t3  ]
239     movq   mm3, [t2+t3+8]
240     pavgb  mm0, [t4  ]
241     pavgb  mm1, [t4+8]
242     pavgb  mm2, [t4+t5  ]
243     pavgb  mm3, [t4+t5+8]
244     movq   [t0  ], mm0
245     movq   [t0+8], mm1
246     movq   [t0+t1  ], mm2
247     movq   [t0+t1+8], mm3
248     AVG_END
249
250 AVGH 16, 16, mmxext
251 AVGH 16, 8,  mmxext
252
253 INIT_XMM
254 AVG_FUNC x264_pixel_avg_w16_sse2, movdqu, movdqa
255 AVGH 16, 16, sse2
256 AVGH 16,  8, sse2
257 AVGH  8, 16, sse2
258 AVGH  8,  8, sse2
259 AVGH  8,  4, sse2
260 AVGH 16, 16, ssse3
261 AVGH 16,  8, ssse3
262 AVGH  8, 16, ssse3
263 AVGH  8,  8, ssse3
264 AVGH  8,  4, ssse3
265 INIT_MMX
266 AVGH  4,  8, ssse3
267 AVGH  4,  4, ssse3
268 AVGH  4,  2, ssse3
269
270
271
272 ;=============================================================================
273 ; pixel avg2
274 ;=============================================================================
275
276 ;-----------------------------------------------------------------------------
277 ; void x264_pixel_avg2_w4_mmxext( uint8_t *dst, int dst_stride,
278 ;                                 uint8_t *src1, int src_stride,
279 ;                                 uint8_t *src2, int height );
280 ;-----------------------------------------------------------------------------
281 %macro AVG2_W8 2
282 cglobal x264_pixel_avg2_w%1_mmxext, 6,7
283     sub    r4, r2
284     lea    r6, [r4+r3]
285 .height_loop:
286     %2     mm0, [r2]
287     %2     mm1, [r2+r3]
288     pavgb  mm0, [r2+r4]
289     pavgb  mm1, [r2+r6]
290     %2     [r0], mm0
291     %2     [r0+r1], mm1
292     sub    r5d, 2
293     lea    r2, [r2+r3*2]
294     lea    r0, [r0+r1*2]
295     jg     .height_loop
296     REP_RET
297 %endmacro
298
299 AVG2_W8 4, movd
300 AVG2_W8 8, movq
301
302 %macro AVG2_W16 2
303 cglobal x264_pixel_avg2_w%1_mmxext, 6,7
304     sub    r4, r2
305     lea    r6, [r4+r3]
306 .height_loop:
307     movq   mm0, [r2]
308     %2     mm1, [r2+8]
309     movq   mm2, [r2+r3]
310     %2     mm3, [r2+r3+8]
311     pavgb  mm0, [r2+r4]
312     pavgb  mm1, [r2+r4+8]
313     pavgb  mm2, [r2+r6]
314     pavgb  mm3, [r2+r6+8]
315     movq   [r0], mm0
316     %2     [r0+8], mm1
317     movq   [r0+r1], mm2
318     %2     [r0+r1+8], mm3
319     lea    r2, [r2+r3*2]
320     lea    r0, [r0+r1*2]
321     sub    r5d, 2
322     jg     .height_loop
323     REP_RET
324 %endmacro
325
326 AVG2_W16 12, movd
327 AVG2_W16 16, movq
328
329 cglobal x264_pixel_avg2_w20_mmxext, 6,7
330     sub    r4, r2
331     lea    r6, [r4+r3]
332 .height_loop:
333     movq   mm0, [r2]
334     movq   mm1, [r2+8]
335     movd   mm2, [r2+16]
336     movq   mm3, [r2+r3]
337     movq   mm4, [r2+r3+8]
338     movd   mm5, [r2+r3+16]
339     pavgb  mm0, [r2+r4]
340     pavgb  mm1, [r2+r4+8]
341     pavgb  mm2, [r2+r4+16]
342     pavgb  mm3, [r2+r6]
343     pavgb  mm4, [r2+r6+8]
344     pavgb  mm5, [r2+r6+16]
345     movq   [r0], mm0
346     movq   [r0+8], mm1
347     movd   [r0+16], mm2
348     movq   [r0+r1], mm3
349     movq   [r0+r1+8], mm4
350     movd   [r0+r1+16], mm5
351     lea    r2, [r2+r3*2]
352     lea    r0, [r0+r1*2]
353     sub    r5d, 2
354     jg     .height_loop
355     REP_RET
356
357 cglobal x264_pixel_avg2_w16_sse2, 6,7
358     sub    r4, r2
359     lea    r6, [r4+r3]
360 .height_loop:
361     movdqu xmm0, [r2]
362     movdqu xmm2, [r2+r3]
363     movdqu xmm1, [r2+r4]
364     movdqu xmm3, [r2+r6]
365     pavgb  xmm0, xmm1
366     pavgb  xmm2, xmm3
367     movdqa [r0], xmm0
368     movdqa [r0+r1], xmm2
369     lea    r2, [r2+r3*2]
370     lea    r0, [r0+r1*2]
371     sub    r5d, 2
372     jg     .height_loop
373     REP_RET
374
375 %macro AVG2_W20 1
376 cglobal x264_pixel_avg2_w20_%1, 6,7
377     sub    r4, r2
378     lea    r6, [r4+r3]
379 .height_loop:
380     movdqu xmm0, [r2]
381     movdqu xmm2, [r2+r3]
382     movd   mm4,  [r2+16]
383     movd   mm5,  [r2+r3+16]
384 %ifidn %1, sse2_misalign
385     pavgb  xmm0, [r2+r4]
386     pavgb  xmm2, [r2+r6]
387 %else
388     movdqu xmm1, [r2+r4]
389     movdqu xmm3, [r2+r6]
390     pavgb  xmm0, xmm1
391     pavgb  xmm2, xmm3
392 %endif
393     pavgb  mm4,  [r2+r4+16]
394     pavgb  mm5,  [r2+r6+16]
395     movdqa [r0], xmm0
396     movd   [r0+16], mm4
397     movdqa [r0+r1], xmm2
398     movd   [r0+r1+16], mm5
399     lea    r2, [r2+r3*2]
400     lea    r0, [r0+r1*2]
401     sub    r5d, 2
402     jg     .height_loop
403     REP_RET
404 %endmacro
405
406 AVG2_W20 sse2
407 AVG2_W20 sse2_misalign
408
409 ; Cacheline split code for processors with high latencies for loads
410 ; split over cache lines.  See sad-a.asm for a more detailed explanation.
411 ; This particular instance is complicated by the fact that src1 and src2
412 ; can have different alignments.  For simplicity and code size, only the
413 ; MMX cacheline workaround is used.  As a result, in the case of SSE2
414 ; pixel_avg, the cacheline check functions calls the SSE2 version if there
415 ; is no cacheline split, and the MMX workaround if there is.
416
417 %macro INIT_SHIFT 2
418     and    eax, 7
419     shl    eax, 3
420     movd   %1, [sw_64 GLOBAL]
421     movd   %2, eax
422     psubw  %1, %2
423 %endmacro
424
425 %macro AVG_CACHELINE_CHECK 3 ; width, cacheline, instruction set
426 cglobal x264_pixel_avg2_w%1_cache%2_%3, 0,0
427     mov    eax, r2m
428     and    eax, 0x1f|(%2>>1)
429     cmp    eax, (32-%1)|(%2>>1)
430     jle x264_pixel_avg2_w%1_%3
431 ;w12 isn't needed because w16 is just as fast if there's no cacheline split
432 %if %1 == 12
433     jmp x264_pixel_avg2_w16_cache_mmxext
434 %else
435     jmp x264_pixel_avg2_w%1_cache_mmxext
436 %endif
437 %endmacro
438
439 %macro AVG_CACHELINE_START 0
440     %assign stack_offset 0
441     INIT_SHIFT mm6, mm7
442     mov    eax, r4m
443     INIT_SHIFT mm4, mm5
444     PROLOGUE 6,6
445     and    r2, ~7
446     and    r4, ~7
447     sub    r4, r2
448 .height_loop:
449 %endmacro
450
451 %macro AVG_CACHELINE_LOOP 2
452     movq   mm0, [r2+8+%1]
453     movq   mm1, [r2+%1]
454     movq   mm2, [r2+r4+8+%1]
455     movq   mm3, [r2+r4+%1]
456     psllq  mm0, mm6
457     psrlq  mm1, mm7
458     psllq  mm2, mm4
459     psrlq  mm3, mm5
460     por    mm0, mm1
461     por    mm2, mm3
462     pavgb  mm0, mm2
463     %2 [r0+%1], mm0
464 %endmacro
465
466 x264_pixel_avg2_w8_cache_mmxext:
467     AVG_CACHELINE_START
468     AVG_CACHELINE_LOOP 0, movq
469     add    r2, r3
470     add    r0, r1
471     dec    r5d
472     jg     .height_loop
473     RET
474
475 x264_pixel_avg2_w16_cache_mmxext:
476     AVG_CACHELINE_START
477     AVG_CACHELINE_LOOP 0, movq
478     AVG_CACHELINE_LOOP 8, movq
479     add    r2, r3
480     add    r0, r1
481     dec    r5d
482     jg .height_loop
483     RET
484
485 x264_pixel_avg2_w20_cache_mmxext:
486     AVG_CACHELINE_START
487     AVG_CACHELINE_LOOP 0, movq
488     AVG_CACHELINE_LOOP 8, movq
489     AVG_CACHELINE_LOOP 16, movd
490     add    r2, r3
491     add    r0, r1
492     dec    r5d
493     jg .height_loop
494     RET
495
496 %ifndef ARCH_X86_64
497 AVG_CACHELINE_CHECK  8, 32, mmxext
498 AVG_CACHELINE_CHECK 12, 32, mmxext
499 AVG_CACHELINE_CHECK 16, 32, mmxext
500 AVG_CACHELINE_CHECK 20, 32, mmxext
501 AVG_CACHELINE_CHECK 16, 64, mmxext
502 AVG_CACHELINE_CHECK 20, 64, mmxext
503 %endif
504
505 AVG_CACHELINE_CHECK  8, 64, mmxext
506 AVG_CACHELINE_CHECK 12, 64, mmxext
507 AVG_CACHELINE_CHECK 16, 64, sse2
508 AVG_CACHELINE_CHECK 20, 64, sse2
509
510 ;=============================================================================
511 ; pixel copy
512 ;=============================================================================
513
514 %macro COPY4 4
515     %2  m0, [r2]
516     %2  m1, [r2+r3]
517     %2  m2, [r2+r3*2]
518     %2  m3, [r2+%4]
519     %1  [r0],      m0
520     %1  [r0+r1],   m1
521     %1  [r0+r1*2], m2
522     %1  [r0+%3],   m3
523 %endmacro
524
525 INIT_MMX
526 ;-----------------------------------------------------------------------------
527 ; void x264_mc_copy_w4_mmx( uint8_t *dst, int i_dst_stride,
528 ;                           uint8_t *src, int i_src_stride, int i_height )
529 ;-----------------------------------------------------------------------------
530 cglobal x264_mc_copy_w4_mmx, 4,6
531     cmp     dword r4m, 4
532     lea     r5, [r3*3]
533     lea     r4, [r1*3]
534     je .end
535     COPY4 movd, movd, r4, r5
536     lea     r2, [r2+r3*4]
537     lea     r0, [r0+r1*4]
538 .end:
539     COPY4 movd, movd, r4, r5
540     RET
541
542 cglobal x264_mc_copy_w8_mmx, 5,7
543     lea     r6, [r3*3]
544     lea     r5, [r1*3]
545 .height_loop:
546     COPY4 movq, movq, r5, r6
547     lea     r2, [r2+r3*4]
548     lea     r0, [r0+r1*4]
549     sub     r4d, 4
550     jg      .height_loop
551     REP_RET
552
553 cglobal x264_mc_copy_w16_mmx, 5,7
554     lea     r6, [r3*3]
555     lea     r5, [r1*3]
556 .height_loop:
557     movq    mm0, [r2]
558     movq    mm1, [r2+8]
559     movq    mm2, [r2+r3]
560     movq    mm3, [r2+r3+8]
561     movq    mm4, [r2+r3*2]
562     movq    mm5, [r2+r3*2+8]
563     movq    mm6, [r2+r6]
564     movq    mm7, [r2+r6+8]
565     movq    [r0], mm0
566     movq    [r0+8], mm1
567     movq    [r0+r1], mm2
568     movq    [r0+r1+8], mm3
569     movq    [r0+r1*2], mm4
570     movq    [r0+r1*2+8], mm5
571     movq    [r0+r5], mm6
572     movq    [r0+r5+8], mm7
573     lea     r2, [r2+r3*4]
574     lea     r0, [r0+r1*4]
575     sub     r4d, 4
576     jg      .height_loop
577     REP_RET
578
579 INIT_XMM
580 %macro COPY_W16_SSE2 2
581 cglobal %1, 5,7
582     lea     r6, [r3*3]
583     lea     r5, [r1*3]
584 .height_loop:
585     COPY4 movdqa, %2, r5, r6
586     lea     r2, [r2+r3*4]
587     lea     r0, [r0+r1*4]
588     sub     r4d, 4
589     jg      .height_loop
590     REP_RET
591 %endmacro
592
593 COPY_W16_SSE2 x264_mc_copy_w16_sse2, movdqu
594 ; cacheline split with mmx has too much overhead; the speed benefit is near-zero.
595 ; but with SSE3 the overhead is zero, so there's no reason not to include it.
596 COPY_W16_SSE2 x264_mc_copy_w16_sse3, lddqu
597 COPY_W16_SSE2 x264_mc_copy_w16_aligned_sse2, movdqa
598
599
600
601 ;=============================================================================
602 ; prefetch
603 ;=============================================================================
604 ; FIXME assumes 64 byte cachelines
605
606 ;-----------------------------------------------------------------------------
607 ; void x264_prefetch_fenc_mmxext( uint8_t *pix_y, int stride_y,
608 ;                                 uint8_t *pix_uv, int stride_uv, int mb_x )
609 ;-----------------------------------------------------------------------------
610 %ifdef ARCH_X86_64
611 cglobal x264_prefetch_fenc_mmxext, 5,5
612     mov    eax, r4d
613     and    eax, 3
614     imul   eax, r1d
615     lea    r0,  [r0+rax*4+64]
616     prefetcht0  [r0]
617     prefetcht0  [r0+r1]
618     lea    r0,  [r0+r1*2]
619     prefetcht0  [r0]
620     prefetcht0  [r0+r1]
621
622     and    r4d, 6
623     imul   r4d, r3d
624     lea    r2,  [r2+r4+64]
625     prefetcht0  [r2]
626     prefetcht0  [r2+r3]
627     ret
628
629 %else
630 cglobal x264_prefetch_fenc_mmxext
631     mov    r2, [esp+20]
632     mov    r1, [esp+8]
633     mov    r0, [esp+4]
634     and    r2, 3
635     imul   r2, r1
636     lea    r0, [r0+r2*4+64]
637     prefetcht0 [r0]
638     prefetcht0 [r0+r1]
639     lea    r0, [r0+r1*2]
640     prefetcht0 [r0]
641     prefetcht0 [r0+r1]
642
643     mov    r2, [esp+20]
644     mov    r1, [esp+16]
645     mov    r0, [esp+12]
646     and    r2, 6
647     imul   r2, r1
648     lea    r0, [r0+r2+64]
649     prefetcht0 [r0]
650     prefetcht0 [r0+r1]
651     ret
652 %endif ; ARCH_X86_64
653
654 ;-----------------------------------------------------------------------------
655 ; void x264_prefetch_ref_mmxext( uint8_t *pix, int stride, int parity )
656 ;-----------------------------------------------------------------------------
657 cglobal x264_prefetch_ref_mmxext, 3,3
658     dec    r2d
659     and    r2d, r1d
660     lea    r0,  [r0+r2*8+64]
661     lea    r2,  [r1*3]
662     prefetcht0  [r0]
663     prefetcht0  [r0+r1]
664     prefetcht0  [r0+r1*2]
665     prefetcht0  [r0+r2]
666     lea    r0,  [r0+r1*4]
667     prefetcht0  [r0]
668     prefetcht0  [r0+r1]
669     prefetcht0  [r0+r1*2]
670     prefetcht0  [r0+r2]
671     ret
672
673
674
675 ;=============================================================================
676 ; chroma MC
677 ;=============================================================================
678
679     %define t0 rax
680 %ifdef ARCH_X86_64
681     %define t1 r10
682 %else
683     %define t1 r1
684 %endif
685
686 %macro MC_CHROMA_START 0
687     movifnidn r2d, r2m
688     movifnidn r3d, r3m
689     movifnidn r4d, r4m
690     movifnidn r5d, r5m
691     mov       t0d, r5d
692     mov       t1d, r4d
693     sar       t0d, 3
694     sar       t1d, 3
695     imul      t0d, r3d
696     add       t0d, t1d
697     movsxdifnidn t0, t0d
698     add       r2,  t0            ; src += (dx>>3) + (dy>>3) * src_stride
699 %endmacro
700
701 ;-----------------------------------------------------------------------------
702 ; void x264_mc_chroma_mmxext( uint8_t *dst, int dst_stride,
703 ;                             uint8_t *src, int src_stride,
704 ;                             int dx, int dy,
705 ;                             int width, int height )
706 ;-----------------------------------------------------------------------------
707 %macro MC_CHROMA 1
708 cglobal x264_mc_chroma_%1, 0,6
709 %if mmsize == 16
710     cmp dword r6m, 4
711     jle x264_mc_chroma_mmxext %+ .skip_prologue
712 %endif
713 .skip_prologue:
714     MC_CHROMA_START
715     pxor       m3, m3
716     and       r4d, 7         ; dx &= 7
717     jz .mc1dy
718     and       r5d, 7         ; dy &= 7
719     jz .mc1dx
720
721     movd       m5, r4d
722     movd       m6, r5d
723     SPLATW     m5, m5        ; m5 = dx
724     SPLATW     m6, m6        ; m6 = dy
725
726     mova       m4, [pw_8 GLOBAL]
727     mova       m0, m4
728     psubw      m4, m5        ; m4 = 8-dx
729     psubw      m0, m6        ; m0 = 8-dy
730
731     mova       m7, m5
732     pmullw     m5, m0        ; m5 = dx*(8-dy) =     cB
733     pmullw     m7, m6        ; m7 = dx*dy =         cD
734     pmullw     m6, m4        ; m6 = (8-dx)*dy =     cC
735     pmullw     m4, m0        ; m4 = (8-dx)*(8-dy) = cA
736
737     mov       r4d, r7m
738 %ifdef ARCH_X86_64
739     mov       r10, r0
740     mov       r11, r2
741 %else
742     mov        r0, r0m
743     mov        r1, r1m
744     mov        r5, r2
745 %endif
746
747 .loop2d:
748     movh       m1, [r2+r3]
749     movh       m0, [r2]
750     punpcklbw  m1, m3        ; 00 px1 | 00 px2 | 00 px3 | 00 px4
751     punpcklbw  m0, m3
752     pmullw     m1, m6        ; 2nd line * cC
753     pmullw     m0, m4        ; 1st line * cA
754     paddw      m0, m1        ; m0 <- result
755
756     movh       m2, [r2+1]
757     movh       m1, [r2+r3+1]
758     punpcklbw  m2, m3
759     punpcklbw  m1, m3
760
761     paddw      m0, [pw_32 GLOBAL]
762
763     pmullw     m2, m5        ; line * cB
764     pmullw     m1, m7        ; line * cD
765     paddw      m0, m2
766     paddw      m0, m1
767     psrlw      m0, 6
768
769     packuswb m0, m3          ; 00 00 00 00 px1 px2 px3 px4
770     movh       [r0], m0
771
772     add        r2,  r3
773     add        r0,  r1       ; dst_stride
774     dec        r4d
775     jnz .loop2d
776
777 %if mmsize == 8
778     sub dword r6m, 8
779     jnz .finish              ; width != 8 so assume 4
780 %ifdef ARCH_X86_64
781     lea        r0, [r10+4]   ; dst
782     lea        r2, [r11+4]   ; src
783 %else
784     mov        r0,  r0m
785     lea        r2, [r5+4]
786     add        r0,  4
787 %endif
788     mov       r4d, r7m       ; height
789     jmp .loop2d
790 %else
791     REP_RET
792 %endif ; mmsize
793
794 .mc1dy:
795     and       r5d, 7
796     movd       m6, r5d
797     mov        r5, r3        ; pel_offset = dx ? 1 : src_stride
798     jmp .mc1d
799 .mc1dx:
800     movd       m6, r4d
801     mov       r5d, 1
802 .mc1d:
803     mova       m5, [pw_8 GLOBAL]
804     SPLATW     m6, m6
805     mova       m7, [pw_4 GLOBAL]
806     psubw      m5, m6
807     movifnidn r0d, r0m
808     movifnidn r1d, r1m
809     mov       r4d, r7m
810 %if mmsize == 8
811     cmp dword r6m, 8
812     je .loop1d_w8
813 %endif
814
815 .loop1d_w4:
816     movh       m0, [r2+r5]
817     movh       m1, [r2]
818     punpcklbw  m0, m3
819     punpcklbw  m1, m3
820     pmullw     m0, m6
821     pmullw     m1, m5
822     paddw      m0, m7
823     paddw      m0, m1
824     psrlw      m0, 3
825     packuswb   m0, m3
826     movh     [r0], m0
827     add        r2, r3
828     add        r0, r1
829     dec        r4d
830     jnz .loop1d_w4
831 .finish:
832     REP_RET
833
834 %if mmsize == 8
835 .loop1d_w8:
836     movu       m0, [r2+r5]
837     mova       m1, [r2]
838     mova       m2, m0
839     mova       m4, m1
840     punpcklbw  m0, m3
841     punpcklbw  m1, m3
842     punpckhbw  m2, m3
843     punpckhbw  m4, m3
844     pmullw     m0, m6
845     pmullw     m1, m5
846     pmullw     m2, m6
847     pmullw     m4, m5
848     paddw      m0, m7
849     paddw      m2, m7
850     paddw      m0, m1
851     paddw      m2, m4
852     psrlw      m0, 3
853     psrlw      m2, 3
854     packuswb   m0, m2
855     mova     [r0], m0
856     add        r2, r3
857     add        r0, r1
858     dec        r4d
859     jnz .loop1d_w8
860     REP_RET
861 %endif ; mmsize
862 %endmacro ; MC_CHROMA
863
864 INIT_MMX
865 MC_CHROMA mmxext
866 INIT_XMM
867 MC_CHROMA sse2
868
869 INIT_MMX
870 cglobal x264_mc_chroma_ssse3, 0,6
871     MC_CHROMA_START
872     and       r4d, 7
873     and       r5d, 7
874     mov       t0d, r4d
875     shl       t0d, 8
876     sub       t0d, r4d
877     mov       r4d, 8
878     add       t0d, 8
879     sub       r4d, r5d
880     imul      r5d, t0d ; (x*255+8)*y
881     imul      r4d, t0d ; (x*255+8)*(8-y)
882     cmp dword r6m, 4
883     jg .width8
884     mova       m5, [pw_32 GLOBAL]
885     movd       m6, r5d
886     movd       m7, r4d
887     movifnidn r0d, r0m
888     movifnidn r1d, r1m
889     movifnidn r4d, r7m
890     SPLATW     m6, m6
891     SPLATW     m7, m7
892     movh       m0, [r2]
893     punpcklbw  m0, [r2+1]
894     add r2, r3
895 .loop4:
896     movh       m1, [r2]
897     movh       m3, [r2+r3]
898     punpcklbw  m1, [r2+1]
899     punpcklbw  m3, [r2+r3+1]
900     lea        r2, [r2+2*r3]
901     mova       m2, m1
902     mova       m4, m3
903     pmaddubsw  m0, m7
904     pmaddubsw  m1, m6
905     pmaddubsw  m2, m7
906     pmaddubsw  m3, m6
907     paddw      m0, m5
908     paddw      m2, m5
909     paddw      m1, m0
910     paddw      m3, m2
911     mova       m0, m4
912     psrlw      m1, 6
913     psrlw      m3, 6
914     packuswb   m1, m1
915     packuswb   m3, m3
916     movh     [r0], m1
917     movh  [r0+r1], m3
918     sub       r4d, 2
919     lea        r0, [r0+2*r1]
920     jg .loop4
921     REP_RET
922
923 INIT_XMM
924 .width8:
925     mova       m5, [pw_32 GLOBAL]
926     movd       m6, r5d
927     movd       m7, r4d
928     movifnidn r0d, r0m
929     movifnidn r1d, r1m
930     movifnidn r4d, r7m
931     SPLATW     m6, m6
932     SPLATW     m7, m7
933     movh       m0, [r2]
934     movh       m1, [r2+1]
935     punpcklbw  m0, m1
936     add r2, r3
937 .loop8:
938     movh       m1, [r2]
939     movh       m2, [r2+1]
940     movh       m3, [r2+r3]
941     movh       m4, [r2+r3+1]
942     punpcklbw  m1, m2
943     punpcklbw  m3, m4
944     lea        r2, [r2+2*r3]
945     mova       m2, m1
946     mova       m4, m3
947     pmaddubsw  m0, m7
948     pmaddubsw  m1, m6
949     pmaddubsw  m2, m7
950     pmaddubsw  m3, m6
951     paddw      m0, m5
952     paddw      m2, m5
953     paddw      m1, m0
954     paddw      m3, m2
955     mova       m0, m4
956     psrlw      m1, 6
957     psrlw      m3, 6
958     packuswb   m1, m3
959     movh     [r0], m1
960     movhps [r0+r1], m1
961     sub       r4d, 2
962     lea        r0, [r0+2*r1]
963     jg .loop8
964     REP_RET
965
966 ; mc_chroma 1d ssse3 is negligibly faster, and definitely not worth the extra code size
967