]> git.sesse.net Git - x264/blob - common/x86/mc-a2.asm
cosmetics
[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 ;*          Mathieu Monnier <manao@melix.net>
8 ;*
9 ;* This program is free software; you can redistribute it and/or modify
10 ;* it under the terms of the GNU General Public License as published by
11 ;* the Free Software Foundation; either version 2 of the License, or
12 ;* (at your option) any later version.
13 ;*
14 ;* This program is distributed in the hope that it will be useful,
15 ;* but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 ;* GNU General Public License for more details.
18 ;*
19 ;* You should have received a copy of the GNU General Public License
20 ;* along with this program; if not, write to the Free Software
21 ;* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
22 ;*****************************************************************************
23
24 %include "x86inc.asm"
25
26 SECTION_RODATA
27
28 pw_1:  times 8 dw 1
29 pw_16: times 8 dw 16
30 pw_32: times 8 dw 32
31
32 SECTION .text
33
34 %macro LOAD_ADD 3
35     movh       %1, %2
36     movh       m7, %3
37     punpcklbw  %1, m0
38     punpcklbw  m7, m0
39     paddw      %1, m7
40 %endmacro
41
42 %macro FILT_V2 0
43     psubw  m1, m2  ; a-b
44     psubw  m4, m5
45     psubw  m2, m3  ; b-c
46     psubw  m5, m6
47     psllw  m2, 2
48     psllw  m5, 2
49     psubw  m1, m2  ; a-5*b+4*c
50     psubw  m4, m5
51     psllw  m3, 4
52     psllw  m6, 4
53     paddw  m1, m3  ; a-5*b+20*c
54     paddw  m4, m6
55 %endmacro
56
57 %macro FILT_H 3
58     psubw  %1, %2  ; a-b
59     psraw  %1, 2   ; (a-b)/4
60     psubw  %1, %2  ; (a-b)/4-b
61     paddw  %1, %3  ; (a-b)/4-b+c
62     psraw  %1, 2   ; ((a-b)/4-b+c)/4
63     paddw  %1, %3  ; ((a-b)/4-b+c)/4+c = (a-5*b+20*c)/16
64 %endmacro
65
66 %macro FILT_H2 0
67     psubw  m1, m2
68     psubw  m4, m5
69     psraw  m1, 2
70     psraw  m4, 2
71     psubw  m1, m2
72     psubw  m4, m5
73     paddw  m1, m3
74     paddw  m4, m6
75     psraw  m1, 2
76     psraw  m4, 2
77     paddw  m1, m3
78     paddw  m4, m6
79 %endmacro
80
81 %macro FILT_PACK 1
82     paddw     m1, m7
83     paddw     m4, m7
84     psraw     m1, %1
85     psraw     m4, %1
86     packuswb  m1, m4
87 %endmacro
88
89 %macro PALIGNR_SSE2 4
90     %ifnidn %2, %4
91     movdqa %4, %2
92     %endif
93     pslldq %1, 16-%3
94     psrldq %4, %3
95     por    %1, %4
96 %endmacro
97
98 %macro PALIGNR_SSSE3 4
99     palignr %1, %2, %3
100 %endmacro
101
102 INIT_MMX
103
104 %macro HPEL_V 1
105 ;-----------------------------------------------------------------------------
106 ; void x264_hpel_filter_v_mmxext( uint8_t *dst, uint8_t *src, int16_t *buf, int stride, int width );
107 ;-----------------------------------------------------------------------------
108 cglobal x264_hpel_filter_v_%1, 5,6,1
109     lea r5, [r1+r3]
110     sub r1, r3
111     sub r1, r3
112     add r0, r4
113     lea r2, [r2+r4*2]
114     neg r4
115     pxor m0, m0
116 .loop:
117     prefetcht0 [r5+r3*2+64]
118     LOAD_ADD  m1, [r1     ], [r5+r3*2] ; a0
119     LOAD_ADD  m2, [r1+r3  ], [r5+r3  ] ; b0
120     LOAD_ADD  m3, [r1+r3*2], [r5     ] ; c0
121     LOAD_ADD  m4, [r1     +regsize/2], [r5+r3*2+regsize/2] ; a1
122     LOAD_ADD  m5, [r1+r3  +regsize/2], [r5+r3  +regsize/2] ; b1
123     LOAD_ADD  m6, [r1+r3*2+regsize/2], [r5     +regsize/2] ; c1
124     FILT_V2
125     mova      m7, [pw_16 GLOBAL]
126     mova      [r2+r4*2], m1
127     mova      [r2+r4*2+regsize], m4
128     paddw     m1, m7
129     paddw     m4, m7
130     psraw     m1, 5
131     psraw     m4, 5
132     packuswb  m1, m4
133     movnt     [r0+r4], m1
134     add r1, regsize
135     add r5, regsize
136     add r4, regsize
137     jl .loop
138     REP_RET
139 %endmacro
140 HPEL_V mmxext
141
142 ;-----------------------------------------------------------------------------
143 ; void x264_hpel_filter_c_mmxext( uint8_t *dst, int16_t *buf, int width );
144 ;-----------------------------------------------------------------------------
145 cglobal x264_hpel_filter_c_mmxext, 3,3,1
146     add r0, r2
147     lea r1, [r1+r2*2]
148     neg r2
149     %define src r1+r2*2
150     movq m7, [pw_32 GLOBAL]
151 .loop:
152     movq   m1, [src-4]
153     movq   m2, [src-2]
154     movq   m3, [src  ]
155     movq   m4, [src+4]
156     movq   m5, [src+6]
157     paddw  m3, [src+2]  ; c0
158     paddw  m2, m4       ; b0
159     paddw  m1, m5       ; a0
160     movq   m6, [src+8]
161     paddw  m4, [src+14] ; a1
162     paddw  m5, [src+12] ; b1
163     paddw  m6, [src+10] ; c1
164     FILT_H2
165     FILT_PACK 6
166     movntq [r0+r2], m1
167     add r2, 8
168     jl .loop
169     REP_RET
170
171 ;-----------------------------------------------------------------------------
172 ; void x264_hpel_filter_h_mmxext( uint8_t *dst, uint8_t *src, int width );
173 ;-----------------------------------------------------------------------------
174 cglobal x264_hpel_filter_h_mmxext, 3,3,1
175     add r0, r2
176     add r1, r2
177     neg r2
178     %define src r1+r2
179     pxor m0, m0
180 .loop:
181     movd       m1, [src-2]
182     movd       m2, [src-1]
183     movd       m3, [src  ]
184     movd       m6, [src+1]
185     movd       m4, [src+2]
186     movd       m5, [src+3]
187     punpcklbw  m1, m0
188     punpcklbw  m2, m0
189     punpcklbw  m3, m0
190     punpcklbw  m6, m0
191     punpcklbw  m4, m0
192     punpcklbw  m5, m0
193     paddw      m3, m6 ; c0
194     paddw      m2, m4 ; b0
195     paddw      m1, m5 ; a0
196     movd       m7, [src+7]
197     movd       m6, [src+6]
198     punpcklbw  m7, m0
199     punpcklbw  m6, m0
200     paddw      m4, m7 ; c1
201     paddw      m5, m6 ; b1
202     movd       m7, [src+5]
203     movd       m6, [src+4]
204     punpcklbw  m7, m0
205     punpcklbw  m6, m0
206     paddw      m6, m7 ; a1
207     movq       m7, [pw_1 GLOBAL]
208     FILT_H2
209     FILT_PACK 1
210     movntq     [r0+r2], m1
211     add r2, 8
212     jl .loop
213     REP_RET
214
215 INIT_XMM
216
217 %macro HPEL_C 1
218 ;-----------------------------------------------------------------------------
219 ; void x264_hpel_filter_c_sse2( uint8_t *dst, int16_t *buf, int width );
220 ;-----------------------------------------------------------------------------
221 cglobal x264_hpel_filter_c_%1, 3,3,1
222     add r0, r2
223     lea r1, [r1+r2*2]
224     neg r2
225     %define src r1+r2*2
226 %ifidn %1, ssse3
227     mova    m7, [pw_32 GLOBAL]
228     %define tpw_32 m7
229 %elifdef ARCH_X86_64
230     mova    m8, [pw_32 GLOBAL]
231     %define tpw_32 m8
232 %else
233     %define tpw_32 [pw_32 GLOBAL]
234 %endif
235 .loop:
236     mova    m6, [src-16]
237     mova    m2, [src]
238     mova    m3, [src+16]
239     mova    m0, m2
240     mova    m1, m2
241     mova    m4, m3
242     mova    m5, m3
243     PALIGNR m3, m2, 2, m7
244     PALIGNR m4, m2, 4, m7
245     PALIGNR m5, m2, 6, m7
246     PALIGNR m0, m6, 12, m7
247     PALIGNR m1, m6, 14, m7
248     paddw   m2, m3
249     paddw   m1, m4
250     paddw   m0, m5
251     FILT_H  m0, m1, m2
252     paddw   m0, tpw_32
253     psraw   m0, 6
254     packuswb m0, m0
255     movq [r0+r2], m0
256     add r2, 8
257     jl .loop
258     REP_RET
259 %endmacro
260
261 ;-----------------------------------------------------------------------------
262 ; void x264_hpel_filter_h_sse2( uint8_t *dst, uint8_t *src, int width );
263 ;-----------------------------------------------------------------------------
264 cglobal x264_hpel_filter_h_sse2, 3,3,1
265     add r0, r2
266     add r1, r2
267     neg r2
268     %define src r1+r2
269     pxor m0, m0
270 .loop:
271     movh       m1, [src-2]
272     movh       m2, [src-1]
273     movh       m3, [src  ]
274     movh       m4, [src+1]
275     movh       m5, [src+2]
276     movh       m6, [src+3]
277     punpcklbw  m1, m0
278     punpcklbw  m2, m0
279     punpcklbw  m3, m0
280     punpcklbw  m4, m0
281     punpcklbw  m5, m0
282     punpcklbw  m6, m0
283     paddw      m3, m4 ; c0
284     paddw      m2, m5 ; b0
285     paddw      m1, m6 ; a0
286     movh       m4, [src+6]
287     movh       m5, [src+7]
288     movh       m6, [src+10]
289     movh       m7, [src+11]
290     punpcklbw  m4, m0
291     punpcklbw  m5, m0
292     punpcklbw  m6, m0
293     punpcklbw  m7, m0
294     paddw      m5, m6 ; b1
295     paddw      m4, m7 ; a1
296     movh       m6, [src+8]
297     movh       m7, [src+9]
298     punpcklbw  m6, m0
299     punpcklbw  m7, m0
300     paddw      m6, m7 ; c1
301     mova       m7, [pw_1 GLOBAL] ; FIXME xmm8
302     FILT_H2
303     FILT_PACK 1
304     movntdq    [r0+r2], m1
305     add r2, 16
306     jl .loop
307     REP_RET
308
309 %define PALIGNR PALIGNR_SSE2
310 HPEL_V sse2
311 HPEL_C sse2
312 %define PALIGNR PALIGNR_SSSE3
313 HPEL_C ssse3
314
315 cglobal x264_sfence
316     sfence
317     ret
318
319
320
321 ;-----------------------------------------------------------------------------
322 ; void x264_plane_copy_mmxext( uint8_t *dst, int i_dst,
323 ;                              uint8_t *src, int i_src, int w, int h)
324 ;-----------------------------------------------------------------------------
325 cglobal x264_plane_copy_mmxext, 6,7
326     movsxdifnidn r1, r1d
327     movsxdifnidn r3, r3d
328     add    r4d, 3
329     and    r4d, ~3
330     mov    r6d, r4d
331     and    r6d, ~15
332     sub    r1,  r6
333     sub    r3,  r6
334 .loopy:
335     mov    r6d, r4d
336     sub    r6d, 64
337     jl     .endx
338 .loopx:
339     prefetchnta [r2+256]
340     movq   mm0, [r2   ]
341     movq   mm1, [r2+ 8]
342     movq   mm2, [r2+16]
343     movq   mm3, [r2+24]
344     movq   mm4, [r2+32]
345     movq   mm5, [r2+40]
346     movq   mm6, [r2+48]
347     movq   mm7, [r2+56]
348     movntq [r0   ], mm0
349     movntq [r0+ 8], mm1
350     movntq [r0+16], mm2
351     movntq [r0+24], mm3
352     movntq [r0+32], mm4
353     movntq [r0+40], mm5
354     movntq [r0+48], mm6
355     movntq [r0+56], mm7
356     add    r2,  64
357     add    r0,  64
358     sub    r6d, 64
359     jge    .loopx
360 .endx:
361     prefetchnta [r2+256]
362     add    r6d, 48
363     jl .end16
364 .loop16:
365     movq   mm0, [r2  ]
366     movq   mm1, [r2+8]
367     movntq [r0  ], mm0
368     movntq [r0+8], mm1
369     add    r2,  16
370     add    r0,  16
371     sub    r6d, 16
372     jge    .loop16
373 .end16:
374     add    r6d, 12
375     jl .end4
376 .loop4:
377     movd   mm2, [r2+r6]
378     movd   [r0+r6], mm2
379     sub    r6d, 4
380     jge .loop4
381 .end4:
382     add    r2, r3
383     add    r0, r1
384     dec    r5d
385     jg     .loopy
386     sfence
387     emms
388     RET
389
390
391
392 ; These functions are not general-use; not only do the SSE ones require aligned input,
393 ; but they also will fail if given a non-mod16 size or a size less than 64.
394 ; memzero SSE will fail for non-mod128.
395
396 ;-----------------------------------------------------------------------------
397 ; void *x264_memcpy_aligned_mmx( void *dst, const void *src, size_t n );
398 ;-----------------------------------------------------------------------------
399 cglobal x264_memcpy_aligned_mmx, 3,3
400     test r2d, 16
401     jz .copy32
402     sub r2d, 16
403     movq mm0, [r1 + r2 + 0]
404     movq mm1, [r1 + r2 + 8]
405     movq [r0 + r2 + 0], mm0
406     movq [r0 + r2 + 8], mm1
407 .copy32:
408     sub r2d, 32
409     movq mm0, [r1 + r2 +  0]
410     movq mm1, [r1 + r2 +  8]
411     movq mm2, [r1 + r2 + 16]
412     movq mm3, [r1 + r2 + 24]
413     movq [r0 + r2 +  0], mm0
414     movq [r0 + r2 +  8], mm1
415     movq [r0 + r2 + 16], mm2
416     movq [r0 + r2 + 24], mm3
417     jg .copy32
418     REP_RET
419
420 ;-----------------------------------------------------------------------------
421 ; void *x264_memcpy_aligned_sse2( void *dst, const void *src, size_t n );
422 ;-----------------------------------------------------------------------------
423 cglobal x264_memcpy_aligned_sse2, 3,3
424     test r2d, 16
425     jz .copy32
426     sub r2d, 16
427     movdqa xmm0, [r1 + r2]
428     movdqa [r0 + r2], xmm0
429 .copy32:
430     test r2d, 32
431     jz .copy64
432     sub r2d, 32
433     movdqa xmm0, [r1 + r2 +  0]
434     movdqa [r0 + r2 +  0], xmm0
435     movdqa xmm1, [r1 + r2 + 16]
436     movdqa [r0 + r2 + 16], xmm1
437 .copy64:
438     sub r2d, 64
439     movdqa xmm0, [r1 + r2 +  0]
440     movdqa [r0 + r2 +  0], xmm0
441     movdqa xmm1, [r1 + r2 + 16]
442     movdqa [r0 + r2 + 16], xmm1
443     movdqa xmm2, [r1 + r2 + 32]
444     movdqa [r0 + r2 + 32], xmm2
445     movdqa xmm3, [r1 + r2 + 48]
446     movdqa [r0 + r2 + 48], xmm3
447     jg .copy64
448     REP_RET
449
450 ;-----------------------------------------------------------------------------
451 ; void *x264_memzero_aligned( void *dst, size_t n );
452 ;-----------------------------------------------------------------------------
453 %macro MEMZERO 1
454 cglobal x264_memzero_aligned_%1, 2,2
455     pxor m0, m0
456 .loop:
457     sub r1d, regsize*8
458 %assign i 0
459 %rep 8
460     mova [r0 + r1 + i], m0
461 %assign i i+regsize
462 %endrep
463     jg .loop
464     REP_RET
465 %endmacro
466
467 INIT_MMX
468 MEMZERO mmx
469 INIT_XMM
470 MEMZERO sse2