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