drop support for pre-SSE3 assemblers
[x262.git] / 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 ; void *x264_memcpy_aligned_mmx( void *dst, const void *src, size_t n );
392 ;-----------------------------------------------------------------------------
393 cglobal x264_memcpy_aligned_mmx, 3,3
394     test r2d, 16
395     jz .copy32
396     sub r2d, 16
397     movq mm0, [r1 + r2 + 0]
398     movq mm1, [r1 + r2 + 8]
399     movq [r0 + r2 + 0], mm0
400     movq [r0 + r2 + 8], mm1
401 .copy32:
402         sub r2d, 32
403         movq mm0, [r1 + r2 +  0]
404         movq mm1, [r1 + r2 +  8]
405         movq mm2, [r1 + r2 + 16]
406         movq mm3, [r1 + r2 + 24]
407         movq [r0 + r2 +  0], mm0
408         movq [r0 + r2 +  8], mm1
409         movq [r0 + r2 + 16], mm2
410         movq [r0 + r2 + 24], mm3
411     jg .copy32
412     REP_RET
413
414 ;-----------------------------------------------------------------------------
415 ; void *x264_memcpy_aligned_sse2( void *dst, const void *src, size_t n );
416 ;-----------------------------------------------------------------------------
417 cglobal x264_memcpy_aligned_sse2, 3,3
418     test r2d, 16
419     jz .copy32
420     sub r2d, 16
421     movdqa xmm0, [r1 + r2]
422     movdqa [r0 + r2], xmm0
423 .copy32:
424     test r2d, 32
425     jz .copy64
426     sub r2d, 32
427     movdqa xmm0, [r1 + r2 +  0]
428     movdqa [r0 + r2 +  0], xmm0
429     movdqa xmm1, [r1 + r2 + 16]
430     movdqa [r0 + r2 + 16], xmm1
431 .copy64:
432         sub r2d, 64
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         movdqa xmm2, [r1 + r2 + 32]
438         movdqa [r0 + r2 + 32], xmm2
439         movdqa xmm3, [r1 + r2 + 48]
440         movdqa [r0 + r2 + 48], xmm3
441     jg .copy64
442     REP_RET