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