]> git.sesse.net Git - x264/blob - common/x86/mc-a2.asm
Remove unnecessary PIC support macros
[x264] / common / x86 / mc-a2.asm
1 ;*****************************************************************************
2 ;* mc-a2.asm: h264 encoder library
3 ;*****************************************************************************
4 ;* Copyright (C) 2005-2008 x264 project
5 ;*
6 ;* Authors: Loren Merritt <lorenm@u.washington.edu>
7 ;*          Fiona Glaser <fiona@x264.com>
8 ;*          Holger Lubitz <hal@duncan.ol.sub.de>
9 ;*          Mathieu Monnier <manao@melix.net>
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 %include "x86util.asm"
28
29 SECTION_RODATA
30
31 filt_mul20: times 16 db 20
32 filt_mul51: times 8 db 1, -5
33
34 pw_1:  times 8 dw 1
35 pw_16: times 8 dw 16
36 pw_32: times 8 dw 32
37 pd_128: times 4 dd 128
38
39 SECTION .text
40
41 %macro LOAD_ADD 4
42     movh       %4, %3
43     movh       %1, %2
44     punpcklbw  %4, m0
45     punpcklbw  %1, m0
46     paddw      %1, %4
47 %endmacro
48
49 %macro LOAD_ADD_2 6
50     mova       %5, %3
51     mova       %1, %4
52     mova       %6, %5
53     mova       %2, %1
54     punpcklbw  %5, m0
55     punpcklbw  %1, m0
56     punpckhbw  %6, m0
57     punpckhbw  %2, m0
58     paddw      %1, %5
59     paddw      %2, %6
60 %endmacro
61
62 %macro FILT_V2 0
63     psubw  m1, m2  ; a-b
64     psubw  m4, m5
65     psubw  m2, m3  ; b-c
66     psubw  m5, m6
67     psllw  m2, 2
68     psllw  m5, 2
69     psubw  m1, m2  ; a-5*b+4*c
70     psubw  m4, m5
71     psllw  m3, 4
72     psllw  m6, 4
73     paddw  m1, m3  ; a-5*b+20*c
74     paddw  m4, m6
75 %endmacro
76
77 %macro FILT_H 3
78     psubw  %1, %2  ; a-b
79     psraw  %1, 2   ; (a-b)/4
80     psubw  %1, %2  ; (a-b)/4-b
81     paddw  %1, %3  ; (a-b)/4-b+c
82     psraw  %1, 2   ; ((a-b)/4-b+c)/4
83     paddw  %1, %3  ; ((a-b)/4-b+c)/4+c = (a-5*b+20*c)/16
84 %endmacro
85
86 %macro FILT_H2 6
87     psubw  %1, %2
88     psubw  %4, %5
89     psraw  %1, 2
90     psraw  %4, 2
91     psubw  %1, %2
92     psubw  %4, %5
93     paddw  %1, %3
94     paddw  %4, %6
95     psraw  %1, 2
96     psraw  %4, 2
97     paddw  %1, %3
98     paddw  %4, %6
99 %endmacro
100
101 %macro FILT_PACK 3
102     paddw     %1, m7
103     paddw     %2, m7
104     psraw     %1, %3
105     psraw     %2, %3
106     packuswb  %1, %2
107 %endmacro
108
109 INIT_MMX
110
111 %macro HPEL_V 1-2 0
112 ;-----------------------------------------------------------------------------
113 ; void x264_hpel_filter_v_mmxext( uint8_t *dst, uint8_t *src, int16_t *buf, int stride, int width );
114 ;-----------------------------------------------------------------------------
115 cglobal x264_hpel_filter_v_%1, 5,6,%2
116 %ifdef WIN64
117     movsxd   r4, r4d
118 %endif
119     lea r5, [r1+r3]
120     sub r1, r3
121     sub r1, r3
122     add r0, r4
123     lea r2, [r2+r4*2]
124     neg r4
125 %ifnidn %1, ssse3
126     pxor m0, m0
127 %else
128     mova m0, [filt_mul51]
129 %endif
130 .loop:
131 %ifidn %1, ssse3
132     mova m1, [r1]
133     mova m4, [r1+r3]
134     mova m2, [r5+r3*2]
135     mova m5, [r5+r3]
136     mova m3, [r1+r3*2]
137     mova m6, [r5]
138     SBUTTERFLY bw, 1, 4, 7
139     SBUTTERFLY bw, 2, 5, 7
140     SBUTTERFLY bw, 3, 6, 7
141     pmaddubsw m1, m0
142     pmaddubsw m4, m0
143     pmaddubsw m2, m0
144     pmaddubsw m5, m0
145     pmaddubsw m3, [filt_mul20]
146     pmaddubsw m6, [filt_mul20]
147     paddw  m1, m2
148     paddw  m4, m5
149     paddw  m1, m3
150     paddw  m4, m6
151 %else
152     LOAD_ADD_2 m1, m4, [r1     ], [r5+r3*2], m6, m7            ; a0 / a1
153     LOAD_ADD_2 m2, m5, [r1+r3  ], [r5+r3  ], m6, m7            ; b0 / b1
154     LOAD_ADD   m3,     [r1+r3*2], [r5     ], m7                ; c0
155     LOAD_ADD   m6,     [r1+r3*2+mmsize/2], [r5+mmsize/2], m7 ; c1
156     FILT_V2
157 %endif
158     mova      m7, [pw_16]
159     mova      [r2+r4*2], m1
160     mova      [r2+r4*2+mmsize], m4
161     paddw     m1, m7
162     paddw     m4, m7
163     psraw     m1, 5
164     psraw     m4, 5
165     packuswb  m1, m4
166     mova     [r0+r4], m1
167     add r1, mmsize
168     add r5, mmsize
169     add r4, mmsize
170     jl .loop
171     REP_RET
172 %endmacro
173 HPEL_V mmxext
174
175 ;-----------------------------------------------------------------------------
176 ; void x264_hpel_filter_c_mmxext( uint8_t *dst, int16_t *buf, int width );
177 ;-----------------------------------------------------------------------------
178 cglobal x264_hpel_filter_c_mmxext, 3,3
179     add r0, r2
180     lea r1, [r1+r2*2]
181     neg r2
182     %define src r1+r2*2
183     movq m7, [pw_32]
184 .loop:
185     movq   m1, [src-4]
186     movq   m2, [src-2]
187     movq   m3, [src  ]
188     movq   m4, [src+4]
189     movq   m5, [src+6]
190     paddw  m3, [src+2]  ; c0
191     paddw  m2, m4       ; b0
192     paddw  m1, m5       ; a0
193     movq   m6, [src+8]
194     paddw  m4, [src+14] ; a1
195     paddw  m5, [src+12] ; b1
196     paddw  m6, [src+10] ; c1
197     FILT_H2 m1, m2, m3, m4, m5, m6
198     FILT_PACK m1, m4, 6
199     movntq [r0+r2], m1
200     add r2, 8
201     jl .loop
202     REP_RET
203
204 ;-----------------------------------------------------------------------------
205 ; void x264_hpel_filter_h_mmxext( uint8_t *dst, uint8_t *src, int width );
206 ;-----------------------------------------------------------------------------
207 cglobal x264_hpel_filter_h_mmxext, 3,3
208     add r0, r2
209     add r1, r2
210     neg r2
211     %define src r1+r2
212     pxor m0, m0
213 .loop:
214     movd       m1, [src-2]
215     movd       m2, [src-1]
216     movd       m3, [src  ]
217     movd       m6, [src+1]
218     movd       m4, [src+2]
219     movd       m5, [src+3]
220     punpcklbw  m1, m0
221     punpcklbw  m2, m0
222     punpcklbw  m3, m0
223     punpcklbw  m6, m0
224     punpcklbw  m4, m0
225     punpcklbw  m5, m0
226     paddw      m3, m6 ; c0
227     paddw      m2, m4 ; b0
228     paddw      m1, m5 ; a0
229     movd       m7, [src+7]
230     movd       m6, [src+6]
231     punpcklbw  m7, m0
232     punpcklbw  m6, m0
233     paddw      m4, m7 ; c1
234     paddw      m5, m6 ; b1
235     movd       m7, [src+5]
236     movd       m6, [src+4]
237     punpcklbw  m7, m0
238     punpcklbw  m6, m0
239     paddw      m6, m7 ; a1
240     movq       m7, [pw_1]
241     FILT_H2 m1, m2, m3, m4, m5, m6
242     FILT_PACK m1, m4, 1
243     movntq     [r0+r2], m1
244     add r2, 8
245     jl .loop
246     REP_RET
247
248 INIT_XMM
249
250 %macro HPEL_C 1
251 ;-----------------------------------------------------------------------------
252 ; void x264_hpel_filter_c_sse2( uint8_t *dst, int16_t *buf, int width );
253 ;-----------------------------------------------------------------------------
254 cglobal x264_hpel_filter_c_%1, 3,3,9
255     add r0, r2
256     lea r1, [r1+r2*2]
257     neg r2
258     %define src r1+r2*2
259 %ifidn %1, ssse3
260     mova    m7, [pw_32]
261     %define tpw_32 m7
262 %elifdef ARCH_X86_64
263     mova    m8, [pw_32]
264     %define tpw_32 m8
265 %else
266     %define tpw_32 [pw_32]
267 %endif
268 .loop:
269 %ifidn %1,sse2_misalign
270     movu    m0, [src-4]
271     movu    m1, [src-2]
272     mova    m2, [src]
273     paddw   m0, [src+6]
274     paddw   m1, [src+4]
275     paddw   m2, [src+2]
276 %else
277     mova    m6, [src-16]
278     mova    m2, [src]
279     mova    m3, [src+16]
280     mova    m0, m2
281     mova    m1, m2
282     mova    m4, m3
283     mova    m5, m3
284     PALIGNR m3, m2, 2, m7
285     PALIGNR m4, m2, 4, m7
286     PALIGNR m5, m2, 6, m7
287     PALIGNR m0, m6, 12, m7
288     PALIGNR m1, m6, 14, m7
289     paddw   m2, m3
290     paddw   m1, m4
291     paddw   m0, m5
292 %endif
293     FILT_H  m0, m1, m2
294     paddw   m0, tpw_32
295     psraw   m0, 6
296     packuswb m0, m0
297     movq [r0+r2], m0
298     add r2, 8
299     jl .loop
300     REP_RET
301 %endmacro
302
303 ;-----------------------------------------------------------------------------
304 ; void x264_hpel_filter_h_sse2( uint8_t *dst, uint8_t *src, int width );
305 ;-----------------------------------------------------------------------------
306 cglobal x264_hpel_filter_h_sse2, 3,3,8
307     add r0, r2
308     add r1, r2
309     neg r2
310     %define src r1+r2
311     pxor m0, m0
312 .loop:
313     movh       m1, [src-2]
314     movh       m2, [src-1]
315     movh       m3, [src  ]
316     movh       m4, [src+1]
317     movh       m5, [src+2]
318     movh       m6, [src+3]
319     punpcklbw  m1, m0
320     punpcklbw  m2, m0
321     punpcklbw  m3, m0
322     punpcklbw  m4, m0
323     punpcklbw  m5, m0
324     punpcklbw  m6, m0
325     paddw      m3, m4 ; c0
326     paddw      m2, m5 ; b0
327     paddw      m1, m6 ; a0
328     movh       m4, [src+6]
329     movh       m5, [src+7]
330     movh       m6, [src+10]
331     movh       m7, [src+11]
332     punpcklbw  m4, m0
333     punpcklbw  m5, m0
334     punpcklbw  m6, m0
335     punpcklbw  m7, m0
336     paddw      m5, m6 ; b1
337     paddw      m4, m7 ; a1
338     movh       m6, [src+8]
339     movh       m7, [src+9]
340     punpcklbw  m6, m0
341     punpcklbw  m7, m0
342     paddw      m6, m7 ; c1
343     mova       m7, [pw_1] ; FIXME xmm8
344     FILT_H2 m1, m2, m3, m4, m5, m6
345     FILT_PACK m1, m4, 1
346     movntdq    [r0+r2], m1
347     add r2, 16
348     jl .loop
349     REP_RET
350
351 %ifndef ARCH_X86_64
352 ;-----------------------------------------------------------------------------
353 ; void x264_hpel_filter_h_ssse3( uint8_t *dst, uint8_t *src, int width );
354 ;-----------------------------------------------------------------------------
355 cglobal x264_hpel_filter_h_ssse3, 3,3
356     add r0, r2
357     add r1, r2
358     neg r2
359     %define src r1+r2
360     pxor m0, m0
361     movh m1, [src-8]
362     punpcklbw m1, m0         ; 00 -1 00 -2 00 -3 00 -4 00 -5 00 -6 00 -7 00 -8
363     movh m2, [src]
364     punpcklbw m2, m0
365     mova       m7, [pw_1]
366 .loop:
367     movh       m3, [src+8]
368     punpcklbw  m3, m0
369
370     mova       m4, m2
371     palignr    m2, m1, 14
372     mova       m5, m3
373     palignr    m3, m4, 4
374     paddw      m3, m2
375
376     mova       m2, m4
377     palignr    m4, m1, 12
378     mova       m1, m5
379     palignr    m5, m2, 6
380     paddw      m5, m4
381
382     mova       m4, m1
383     palignr    m1, m2, 2
384     paddw      m1, m2
385
386     FILT_H     m5, m3, m1
387
388     movh       m1, [src+16]
389     punpcklbw  m1, m0
390
391     mova       m3, m4
392     palignr    m4, m2, 14
393     mova       m6, m1
394     palignr    m1, m3, 4
395     paddw      m1, m4
396
397     mova       m4, m3
398     palignr    m3, m2, 12
399     mova       m2, m6
400     palignr    m6, m4, 6
401     paddw      m6, m3
402
403     mova       m3, m2
404     palignr    m2, m4, 2
405     paddw      m2, m4
406
407     FILT_H m6, m1, m2
408     FILT_PACK m5, m6, 1
409     movdqa    [r0+r2], m5
410
411     add r2, 16
412     mova      m2, m3
413     mova      m1, m4
414
415     jl .loop
416     REP_RET
417 %endif
418
419 %define PALIGNR PALIGNR_MMX
420 %ifndef ARCH_X86_64
421 HPEL_C sse2
422 %endif
423 HPEL_V sse2, 8
424 HPEL_C sse2_misalign
425 %define PALIGNR PALIGNR_SSSE3
426 HPEL_C ssse3
427 HPEL_V ssse3
428
429 %ifdef ARCH_X86_64
430
431 %macro DO_FILT_V 6
432 %ifidn %6, ssse3
433     mova m1, [r3]
434     mova m2, [r3+r2]
435     mova %3, [r3+r2*2]
436     mova m3, [r1]
437     mova %4, [r1+r2]
438     mova m0, [r1+r2*2]
439     mova %2, [filt_mul51]
440     mova m4, m1
441     punpcklbw m1, m2
442     punpckhbw m4, m2
443     mova m2, m0
444     punpcklbw m0, %4
445     punpckhbw m2, %4
446     mova %1, m3
447     punpcklbw m3, %3
448     punpckhbw %1, %3
449     mova %3, m3
450     mova %4, %1
451     pmaddubsw m1, %2
452     pmaddubsw m4, %2
453     pmaddubsw m0, %2
454     pmaddubsw m2, %2
455     pmaddubsw m3, [filt_mul20]
456     pmaddubsw %1, [filt_mul20]
457     psrlw     %3, 8
458     psrlw     %4, 8
459     paddw m1, m0
460     paddw m4, m2
461     paddw m1, m3
462     paddw m4, %1
463 %else
464     LOAD_ADD_2 m1, m4, [r3     ], [r1+r2*2], m2, m5            ; a0 / a1
465     LOAD_ADD_2 m2, m5, [r3+r2  ], [r1+r2  ], m3, m6            ; b0 / b1
466     LOAD_ADD_2 m3, m6, [r3+r2*2], [r1     ], %3, %4            ; c0 / c1
467     FILT_V2
468 %endif
469     mova      %1, m1
470     mova      %2, m4
471     paddw     m1, m15
472     paddw     m4, m15
473     add       r3, 16
474     add       r1, 16
475     psraw     m1, 5
476     psraw     m4, 5
477     packuswb  m1, m4
478     movntps  [r11+r4+%5], m1
479 %endmacro
480
481 %macro DO_FILT_H 4
482     mova      m1, %2
483     PALIGNR   m1, %1, 12, m4
484     mova      m2, %2
485     PALIGNR   m2, %1, 14, m4
486     mova      %1, %3
487     PALIGNR   %3, %2, 6, m4
488     mova      m3, %1
489     PALIGNR   m3, %2, 4, m4
490     mova      m4, %1
491     paddw     %3, m1
492     PALIGNR   m4, %2, 2, m1
493     paddw     m3, m2
494     paddw     m4, %2
495     FILT_H    %3, m3, m4
496     paddw     %3, m15
497     psraw     %3, %4
498 %endmacro
499
500 %macro DO_FILT_CC 4
501     DO_FILT_H %1, %2, %3, 6
502     DO_FILT_H %2, %1, %4, 6
503     packuswb  %3, %4
504     movntps   [r5+r4], %3
505 %endmacro
506
507 %macro DO_FILT_HH 4
508     DO_FILT_H %1, %2, %3, 1
509     DO_FILT_H %2, %1, %4, 1
510     packuswb  %3, %4
511     movntps   [r0+r4], %3
512 %endmacro
513
514 %macro DO_FILT_H2 6
515     DO_FILT_H %1, %2, %3, 6
516     psrlw    m15, 5
517     DO_FILT_H %4, %5, %6, 1
518     packuswb  %6, %3
519 %endmacro
520
521 %macro HPEL 1
522 ;-----------------------------------------------------------------------------
523 ; void x264_hpel_filter_sse2( uint8_t *dsth, uint8_t *dstv, uint8_t *dstc,
524 ;                             uint8_t *src, int stride, int width, int height)
525 ;-----------------------------------------------------------------------------
526 cglobal x264_hpel_filter_%1, 7,7,16
527 %ifdef WIN64
528     movsxd   r4, r4d
529     movsxd   r5, r5d
530 %endif
531     mov      r10, r3
532     sub       r5, 16
533     mov      r11, r1
534     and      r10, 15
535     sub       r3, r10
536     add       r0, r5
537     add      r11, r5
538     add      r10, r5
539     add       r5, r2
540     mov       r2, r4
541     neg      r10
542     lea       r1, [r3+r2]
543     sub       r3, r2
544     sub       r3, r2
545     mov       r4, r10
546 %ifidn %1, sse2
547     pxor      m0, m0
548 %endif
549     pcmpeqw  m15, m15
550     psrlw    m15, 15 ; pw_1
551     psllw    m15, 4
552 ;ALIGN 16
553 .loopy:
554 ; first filter_v
555 ; prefetching does not help here! lots of variants tested, all slower
556     DO_FILT_V m8, m7, m13, m12, 0, %1
557 ;ALIGN 16
558 .loopx:
559     DO_FILT_V m6, m5, m11, m10, 16, %1
560 .lastx:
561     paddw    m15, m15
562     DO_FILT_CC m9, m8, m7, m6
563     movdqa   m7, m12        ; not really necessary, but seems free and
564     movdqa   m6, m11         ; gives far shorter code
565     psrlw    m15, 5
566     DO_FILT_HH m14, m13, m7, m6
567     psllw    m15, 4 ; pw_16
568     movdqa   m7, m5
569     movdqa  m12, m10
570     add      r4, 16
571     jl .loopx
572     cmp      r4, 16
573     jl .lastx
574 ; setup regs for next y
575     sub      r4, r10
576     sub      r4, r2
577     sub      r1, r4
578     sub      r3, r4
579     add      r0, r2
580     add     r11, r2
581     add      r5, r2
582     mov      r4, r10
583     sub     r6d, 1
584     jg .loopy
585     sfence
586     RET
587 %endmacro
588
589 %define PALIGNR PALIGNR_MMX
590 HPEL sse2
591 %define PALIGNR PALIGNR_SSSE3
592 HPEL ssse3
593
594 %endif
595
596 cglobal x264_sfence
597     sfence
598     ret
599
600 ;-----------------------------------------------------------------------------
601 ; void x264_plane_copy_mmxext( uint8_t *dst, int i_dst,
602 ;                              uint8_t *src, int i_src, int w, int h)
603 ;-----------------------------------------------------------------------------
604 cglobal x264_plane_copy_mmxext, 6,7
605     movsxdifnidn r1, r1d
606     movsxdifnidn r3, r3d
607     add    r4d, 3
608     and    r4d, ~3
609     mov    r6d, r4d
610     and    r6d, ~15
611     sub    r1,  r6
612     sub    r3,  r6
613 .loopy:
614     mov    r6d, r4d
615     sub    r6d, 64
616     jl     .endx
617 .loopx:
618     prefetchnta [r2+256]
619     movq   mm0, [r2   ]
620     movq   mm1, [r2+ 8]
621     movq   mm2, [r2+16]
622     movq   mm3, [r2+24]
623     movq   mm4, [r2+32]
624     movq   mm5, [r2+40]
625     movq   mm6, [r2+48]
626     movq   mm7, [r2+56]
627     movntq [r0   ], mm0
628     movntq [r0+ 8], mm1
629     movntq [r0+16], mm2
630     movntq [r0+24], mm3
631     movntq [r0+32], mm4
632     movntq [r0+40], mm5
633     movntq [r0+48], mm6
634     movntq [r0+56], mm7
635     add    r2,  64
636     add    r0,  64
637     sub    r6d, 64
638     jge    .loopx
639 .endx:
640     prefetchnta [r2+256]
641     add    r6d, 48
642     jl .end16
643 .loop16:
644     movq   mm0, [r2  ]
645     movq   mm1, [r2+8]
646     movntq [r0  ], mm0
647     movntq [r0+8], mm1
648     add    r2,  16
649     add    r0,  16
650     sub    r6d, 16
651     jge    .loop16
652 .end16:
653     add    r6d, 12
654     jl .end4
655 .loop4:
656     movd   mm2, [r2+r6]
657     movd   [r0+r6], mm2
658     sub    r6d, 4
659     jge .loop4
660 .end4:
661     add    r2, r3
662     add    r0, r1
663     dec    r5d
664     jg     .loopy
665     sfence
666     emms
667     RET
668
669
670
671 ; These functions are not general-use; not only do the SSE ones require aligned input,
672 ; but they also will fail if given a non-mod16 size or a size less than 64.
673 ; memzero SSE will fail for non-mod128.
674
675 ;-----------------------------------------------------------------------------
676 ; void *x264_memcpy_aligned_mmx( void *dst, const void *src, size_t n );
677 ;-----------------------------------------------------------------------------
678 cglobal x264_memcpy_aligned_mmx, 3,3
679     test r2d, 16
680     jz .copy32
681     sub r2d, 16
682     movq mm0, [r1 + r2 + 0]
683     movq mm1, [r1 + r2 + 8]
684     movq [r0 + r2 + 0], mm0
685     movq [r0 + r2 + 8], mm1
686 .copy32:
687     sub r2d, 32
688     movq mm0, [r1 + r2 +  0]
689     movq mm1, [r1 + r2 +  8]
690     movq mm2, [r1 + r2 + 16]
691     movq mm3, [r1 + r2 + 24]
692     movq [r0 + r2 +  0], mm0
693     movq [r0 + r2 +  8], mm1
694     movq [r0 + r2 + 16], mm2
695     movq [r0 + r2 + 24], mm3
696     jg .copy32
697     REP_RET
698
699 ;-----------------------------------------------------------------------------
700 ; void *x264_memcpy_aligned_sse2( void *dst, const void *src, size_t n );
701 ;-----------------------------------------------------------------------------
702 cglobal x264_memcpy_aligned_sse2, 3,3
703     test r2d, 16
704     jz .copy32
705     sub r2d, 16
706     movdqa xmm0, [r1 + r2]
707     movdqa [r0 + r2], xmm0
708 .copy32:
709     test r2d, 32
710     jz .copy64
711     sub r2d, 32
712     movdqa xmm0, [r1 + r2 +  0]
713     movdqa [r0 + r2 +  0], xmm0
714     movdqa xmm1, [r1 + r2 + 16]
715     movdqa [r0 + r2 + 16], xmm1
716 .copy64:
717     sub r2d, 64
718     movdqa xmm0, [r1 + r2 +  0]
719     movdqa [r0 + r2 +  0], xmm0
720     movdqa xmm1, [r1 + r2 + 16]
721     movdqa [r0 + r2 + 16], xmm1
722     movdqa xmm2, [r1 + r2 + 32]
723     movdqa [r0 + r2 + 32], xmm2
724     movdqa xmm3, [r1 + r2 + 48]
725     movdqa [r0 + r2 + 48], xmm3
726     jg .copy64
727     REP_RET
728
729 ;-----------------------------------------------------------------------------
730 ; void *x264_memzero_aligned( void *dst, size_t n );
731 ;-----------------------------------------------------------------------------
732 %macro MEMZERO 1
733 cglobal x264_memzero_aligned_%1, 2,2
734     pxor m0, m0
735 .loop:
736     sub r1d, mmsize*8
737 %assign i 0
738 %rep 8
739     mova [r0 + r1 + i], m0
740 %assign i i+mmsize
741 %endrep
742     jg .loop
743     REP_RET
744 %endmacro
745
746 INIT_MMX
747 MEMZERO mmx
748 INIT_XMM
749 MEMZERO sse2
750
751
752
753 ;-----------------------------------------------------------------------------
754 ; void x264_integral_init4h_sse4( uint16_t *sum, uint8_t *pix, int stride )
755 ;-----------------------------------------------------------------------------
756 cglobal x264_integral_init4h_sse4, 3,4
757     lea     r3, [r0+r2*2]
758     add     r1, r2
759     neg     r2
760     pxor    m4, m4
761 .loop:
762     movdqa  m0, [r1+r2]
763     movdqa  m1, [r1+r2+16]
764     palignr m1, m0, 8
765     mpsadbw m0, m4, 0
766     mpsadbw m1, m4, 0
767     paddw   m0, [r0+r2*2]
768     paddw   m1, [r0+r2*2+16]
769     movdqa  [r3+r2*2   ], m0
770     movdqa  [r3+r2*2+16], m1
771     add     r2, 16
772     jl .loop
773     REP_RET
774
775 cglobal x264_integral_init8h_sse4, 3,4
776     lea     r3, [r0+r2*2]
777     add     r1, r2
778     neg     r2
779     pxor    m4, m4
780 .loop:
781     movdqa  m0, [r1+r2]
782     movdqa  m1, [r1+r2+16]
783     palignr m1, m0, 8
784     movdqa  m2, m0
785     movdqa  m3, m1
786     mpsadbw m0, m4, 0
787     mpsadbw m1, m4, 0
788     mpsadbw m2, m4, 4
789     mpsadbw m3, m4, 4
790     paddw   m0, [r0+r2*2]
791     paddw   m1, [r0+r2*2+16]
792     paddw   m0, m2
793     paddw   m1, m3
794     movdqa  [r3+r2*2   ], m0
795     movdqa  [r3+r2*2+16], m1
796     add     r2, 16
797     jl .loop
798     REP_RET
799
800 %macro INTEGRAL_INIT_8V 1
801 ;-----------------------------------------------------------------------------
802 ; void x264_integral_init8v_mmx( uint16_t *sum8, int stride )
803 ;-----------------------------------------------------------------------------
804 cglobal x264_integral_init8v_%1, 3,3
805     shl   r1, 1
806     add   r0, r1
807     lea   r2, [r0+r1*8]
808     neg   r1
809 .loop:
810     mova  m0, [r2+r1]
811     mova  m1, [r2+r1+mmsize]
812     psubw m0, [r0+r1]
813     psubw m1, [r0+r1+mmsize]
814     mova  [r0+r1], m0
815     mova  [r0+r1+mmsize], m1
816     add   r1, 2*mmsize
817     jl .loop
818     REP_RET
819 %endmacro
820
821 INIT_MMX
822 INTEGRAL_INIT_8V mmx
823 INIT_XMM
824 INTEGRAL_INIT_8V sse2
825
826 ;-----------------------------------------------------------------------------
827 ; void x264_integral_init4v_mmx( uint16_t *sum8, uint16_t *sum4, int stride )
828 ;-----------------------------------------------------------------------------
829 INIT_MMX
830 cglobal x264_integral_init4v_mmx, 3,5
831     shl   r2, 1
832     lea   r3, [r0+r2*4]
833     lea   r4, [r0+r2*8]
834     mova  m0, [r0+r2]
835     mova  m4, [r4+r2]
836 .loop:
837     sub   r2, 8
838     mova  m1, m4
839     psubw m1, m0
840     mova  m4, [r4+r2]
841     mova  m0, [r0+r2]
842     paddw m1, m4
843     mova  m3, [r3+r2]
844     psubw m1, m0
845     psubw m3, m0
846     mova  [r0+r2], m1
847     mova  [r1+r2], m3
848     jge .loop
849     REP_RET
850
851 INIT_XMM
852 cglobal x264_integral_init4v_sse2, 3,5
853     shl     r2, 1
854     add     r0, r2
855     add     r1, r2
856     lea     r3, [r0+r2*4]
857     lea     r4, [r0+r2*8]
858     neg     r2
859 .loop:
860     mova    m0, [r0+r2]
861     mova    m1, [r4+r2]
862     mova    m2, m0
863     mova    m4, m1
864     shufpd  m0, [r0+r2+16], 1
865     shufpd  m1, [r4+r2+16], 1
866     paddw   m0, m2
867     paddw   m1, m4
868     mova    m3, [r3+r2]
869     psubw   m1, m0
870     psubw   m3, m2
871     mova  [r0+r2], m1
872     mova  [r1+r2], m3
873     add     r2, 16
874     jl .loop
875     REP_RET
876
877 cglobal x264_integral_init4v_ssse3, 3,5
878     shl     r2, 1
879     add     r0, r2
880     add     r1, r2
881     lea     r3, [r0+r2*4]
882     lea     r4, [r0+r2*8]
883     neg     r2
884 .loop:
885     mova    m2, [r0+r2]
886     mova    m0, [r0+r2+16]
887     mova    m4, [r4+r2]
888     mova    m1, [r4+r2+16]
889     palignr m0, m2, 8
890     palignr m1, m4, 8
891     paddw   m0, m2
892     paddw   m1, m4
893     mova    m3, [r3+r2]
894     psubw   m1, m0
895     psubw   m3, m2
896     mova  [r0+r2], m1
897     mova  [r1+r2], m3
898     add     r2, 16
899     jl .loop
900     REP_RET
901
902 %macro FILT8x4 7
903     mova      %3, [r0+%7]
904     mova      %4, [r0+r5+%7]
905     pavgb     %3, %4
906     pavgb     %4, [r0+r5*2+%7]
907     PALIGNR   %1, %3, 1, m6
908     PALIGNR   %2, %4, 1, m6
909     pavgb     %1, %3
910     pavgb     %2, %4
911     mova      %5, %1
912     mova      %6, %2
913     pand      %1, m7
914     pand      %2, m7
915     psrlw     %5, 8
916     psrlw     %6, 8
917 %endmacro
918
919 %macro FILT16x2 4
920     mova      m3, [r0+%4+mmsize]
921     mova      m2, [r0+%4]
922     pavgb     m3, [r0+%4+r5+mmsize]
923     pavgb     m2, [r0+%4+r5]
924     PALIGNR   %1, m3, 1, m6
925     pavgb     %1, m3
926     PALIGNR   m3, m2, 1, m6
927     pavgb     m3, m2
928     mova      m5, m3
929     mova      m4, %1
930     pand      m3, m7
931     pand      %1, m7
932     psrlw     m5, 8
933     psrlw     m4, 8
934     packuswb  m3, %1
935     packuswb  m5, m4
936     mova    [%2], m3
937     mova    [%3], m5
938     mova      %1, m2
939 %endmacro
940
941 %macro FILT8x2U 3
942     mova      m3, [r0+%3+8]
943     mova      m2, [r0+%3]
944     pavgb     m3, [r0+%3+r5+8]
945     pavgb     m2, [r0+%3+r5]
946     mova      m1, [r0+%3+9]
947     mova      m0, [r0+%3+1]
948     pavgb     m1, [r0+%3+r5+9]
949     pavgb     m0, [r0+%3+r5+1]
950     pavgb     m1, m3
951     pavgb     m0, m2
952     mova      m3, m1
953     mova      m2, m0
954     pand      m1, m7
955     pand      m0, m7
956     psrlw     m3, 8
957     psrlw     m2, 8
958     packuswb  m0, m1
959     packuswb  m2, m3
960     mova    [%1], m0
961     mova    [%2], m2
962 %endmacro
963
964 ;-----------------------------------------------------------------------------
965 ; void frame_init_lowres_core( uint8_t *src0, uint8_t *dst0, uint8_t *dsth, uint8_t *dstv, uint8_t *dstc,
966 ;                              int src_stride, int dst_stride, int width, int height )
967 ;-----------------------------------------------------------------------------
968 %macro FRAME_INIT_LOWRES 1-2 0 ; FIXME
969 cglobal x264_frame_init_lowres_core_%1, 6,7,%2
970 %ifdef WIN64
971     movsxd   r5, r5d
972 %endif
973     ; src += 2*(height-1)*stride + 2*width
974     mov      r6d, r8m
975     dec      r6d
976     imul     r6d, r5d
977     add      r6d, r7m
978     lea       r0, [r0+r6*2]
979     ; dst += (height-1)*stride + width
980     mov      r6d, r8m
981     dec      r6d
982     imul     r6d, r6m
983     add      r6d, r7m
984     add       r1, r6
985     add       r2, r6
986     add       r3, r6
987     add       r4, r6
988     ; gap = stride - width
989     mov      r6d, r6m
990     sub      r6d, r7m
991     PUSH      r6
992     %define dst_gap [rsp+gprsize]
993     mov      r6d, r5d
994     sub      r6d, r7m
995     shl      r6d, 1
996     PUSH      r6
997     %define src_gap [rsp]
998 %if mmsize == 16
999     ; adjust for the odd end case
1000     mov      r6d, r7m
1001     and      r6d, 8
1002     sub       r1, r6
1003     sub       r2, r6
1004     sub       r3, r6
1005     sub       r4, r6
1006     add  dst_gap, r6d
1007 %endif ; mmsize
1008     pcmpeqb   m7, m7
1009     psrlw     m7, 8
1010 .vloop:
1011     mov      r6d, r7m
1012 %ifnidn %1, mmxext
1013     mova      m0, [r0]
1014     mova      m1, [r0+r5]
1015     pavgb     m0, m1
1016     pavgb     m1, [r0+r5*2]
1017 %endif
1018 %if mmsize == 16
1019     test     r6d, 8
1020     jz .hloop
1021     sub       r0, 16
1022     FILT8x4   m0, m1, m2, m3, m4, m5, 0
1023     packuswb  m0, m4
1024     packuswb  m1, m5
1025     movq    [r1], m0
1026     movhps  [r2], m0
1027     movq    [r3], m1
1028     movhps  [r4], m1
1029     mova      m0, m2
1030     mova      m1, m3
1031     sub      r6d, 8
1032 %endif ; mmsize
1033 .hloop:
1034     sub       r0, mmsize*2
1035     sub       r1, mmsize
1036     sub       r2, mmsize
1037     sub       r3, mmsize
1038     sub       r4, mmsize
1039 %ifdef m8
1040     FILT8x4   m0, m1, m2, m3, m10, m11, mmsize
1041     mova      m8, m0
1042     mova      m9, m1
1043     FILT8x4   m2, m3, m0, m1, m4, m5, 0
1044     packuswb  m2, m8
1045     packuswb  m3, m9
1046     packuswb  m4, m10
1047     packuswb  m5, m11
1048     mova    [r1], m2
1049     mova    [r2], m4
1050     mova    [r3], m3
1051     mova    [r4], m5
1052 %elifidn %1, mmxext
1053     FILT8x2U  r1, r2, 0
1054     FILT8x2U  r3, r4, r5
1055 %else
1056     FILT16x2  m0, r1, r2, 0
1057     FILT16x2  m1, r3, r4, r5
1058 %endif
1059     sub      r6d, mmsize
1060     jg .hloop
1061 .skip:
1062     mov       r6, dst_gap
1063     sub       r0, src_gap
1064     sub       r1, r6
1065     sub       r2, r6
1066     sub       r3, r6
1067     sub       r4, r6
1068     dec    dword r8m
1069     jg .vloop
1070     ADD      rsp, 2*gprsize
1071     emms
1072     RET
1073 %endmacro ; FRAME_INIT_LOWRES
1074
1075 INIT_MMX
1076 %define PALIGNR PALIGNR_MMX
1077 FRAME_INIT_LOWRES mmxext
1078 %ifndef ARCH_X86_64
1079 FRAME_INIT_LOWRES cache32_mmxext
1080 %endif
1081 INIT_XMM
1082 FRAME_INIT_LOWRES sse2, 12
1083 %define PALIGNR PALIGNR_SSSE3
1084 FRAME_INIT_LOWRES ssse3, 12
1085
1086 ;-----------------------------------------------------------------------------
1087 ; void mbtree_propagate_cost( int *dst, uint16_t *propagate_in, uint16_t *intra_costs,
1088 ;                             uint16_t *inter_costs, uint16_t *inv_qscales, int len )
1089 ;-----------------------------------------------------------------------------
1090 cglobal x264_mbtree_propagate_cost_sse2, 6,6
1091     shl r5d, 1
1092     lea r0, [r0+r5*2]
1093     add r1, r5
1094     add r2, r5
1095     add r3, r5
1096     add r4, r5
1097     neg r5
1098     pxor      xmm5, xmm5
1099     movdqa    xmm4, [pd_128]
1100 .loop:
1101     movq      xmm2, [r2+r5] ; intra
1102     movq      xmm0, [r4+r5] ; invq
1103     punpcklwd xmm2, xmm5
1104     punpcklwd xmm0, xmm5
1105     pmaddwd   xmm0, xmm2
1106     paddd     xmm0, xmm4
1107     psrld     xmm0, 8       ; intra*invq>>8
1108     movq      xmm1, [r1+r5] ; prop
1109     movq      xmm3, [r3+r5] ; inter
1110     punpcklwd xmm1, xmm5
1111     punpcklwd xmm3, xmm5
1112     paddd     xmm0, xmm1    ; prop + (intra*invq>>8)
1113     cvtdq2ps  xmm1, xmm2    ; intra
1114     psubd     xmm2, xmm3    ; intra - inter
1115     cvtdq2ps  xmm0, xmm0
1116     cvtdq2ps  xmm2, xmm2
1117     mulps     xmm0, xmm2    ; (prop + (intra*invq>>8)) * (intra - inter)
1118     divps     xmm0, xmm1    ; / intra
1119     cvttps2dq xmm0, xmm0    ; truncation isn't really desired, but matches the integer implementation
1120     movdqa [r0+r5*2], xmm0
1121     add r5, 8
1122     jl .loop
1123     REP_RET
1124