x86: fmtconvert: port to cpuflags
[ffmpeg.git] / libavcodec / x86 / fmtconvert.asm
1 ;******************************************************************************
2 ;* x86 optimized Format Conversion Utils
3 ;* Copyright (c) 2008 Loren Merritt
4 ;*
5 ;* This file is part of Libav.
6 ;*
7 ;* Libav is free software; you can redistribute it and/or
8 ;* modify it under the terms of the GNU Lesser General Public
9 ;* License as published by the Free Software Foundation; either
10 ;* version 2.1 of the License, or (at your option) any later version.
11 ;*
12 ;* Libav is distributed in the hope that it will be useful,
13 ;* but WITHOUT ANY WARRANTY; without even the implied warranty of
14 ;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 ;* Lesser General Public License for more details.
16 ;*
17 ;* You should have received a copy of the GNU Lesser General Public
18 ;* License along with Libav; if not, write to the Free Software
19 ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 ;******************************************************************************
21
22 %include "libavutil/x86/x86util.asm"
23
24 SECTION_TEXT
25
26 ;---------------------------------------------------------------------------------
27 ; void int32_to_float_fmul_scalar(float *dst, const int *src, float mul, int len);
28 ;---------------------------------------------------------------------------------
29 %macro INT32_TO_FLOAT_FMUL_SCALAR 1
30 %if UNIX64
31 cglobal int32_to_float_fmul_scalar, 3, 3, %1, dst, src, len
32 %else
33 cglobal int32_to_float_fmul_scalar, 4, 4, %1, dst, src, mul, len
34 %endif
35 %if WIN64
36     SWAP 0, 2
37 %elif ARCH_X86_32
38     movss   m0, mulm
39 %endif
40     SPLATD  m0
41     shl     lenq, 2
42     add     srcq, lenq
43     add     dstq, lenq
44     neg     lenq
45 .loop:
46 %if cpuflag(sse2)
47     cvtdq2ps  m1, [srcq+lenq   ]
48     cvtdq2ps  m2, [srcq+lenq+16]
49 %else
50     cvtpi2ps  m1, [srcq+lenq   ]
51     cvtpi2ps  m3, [srcq+lenq+ 8]
52     cvtpi2ps  m2, [srcq+lenq+16]
53     cvtpi2ps  m4, [srcq+lenq+24]
54     movlhps   m1, m3
55     movlhps   m2, m4
56 %endif
57     mulps     m1, m0
58     mulps     m2, m0
59     mova  [dstq+lenq   ], m1
60     mova  [dstq+lenq+16], m2
61     add     lenq, 32
62     jl .loop
63     REP_RET
64 %endmacro
65
66 INIT_XMM sse
67 %define SPLATD SPLATD_SSE
68 INT32_TO_FLOAT_FMUL_SCALAR 5
69 INIT_XMM sse2
70 %define SPLATD SPLATD_SSE2
71 INT32_TO_FLOAT_FMUL_SCALAR 3
72 %undef SPLATD
73
74
75 ;------------------------------------------------------------------------------
76 ; void ff_float_to_int16(int16_t *dst, const float *src, long len);
77 ;------------------------------------------------------------------------------
78 %macro FLOAT_TO_INT16 1
79 cglobal float_to_int16, 3, 3, %1, dst, src, len
80     add       lenq, lenq
81     lea       srcq, [srcq+2*lenq]
82     add       dstq, lenq
83     neg       lenq
84 .loop:
85 %if cpuflag(sse2)
86     cvtps2dq    m0, [srcq+2*lenq   ]
87     cvtps2dq    m1, [srcq+2*lenq+16]
88     packssdw    m0, m1
89     mova  [dstq+lenq], m0
90 %else
91     cvtps2pi    m0, [srcq+2*lenq   ]
92     cvtps2pi    m1, [srcq+2*lenq+ 8]
93     cvtps2pi    m2, [srcq+2*lenq+16]
94     cvtps2pi    m3, [srcq+2*lenq+24]
95     packssdw    m0, m1
96     packssdw    m2, m3
97     mova  [dstq+lenq  ], m0
98     mova  [dstq+lenq+8], m2
99 %endif
100     add       lenq, 16
101     js .loop
102 %if mmsize == 8
103     emms
104 %endif
105     REP_RET
106 %endmacro
107
108 INIT_XMM sse2
109 FLOAT_TO_INT16 2
110 INIT_MMX sse
111 FLOAT_TO_INT16 0
112 %define cvtps2pi pf2id
113 INIT_MMX 3dnow
114 FLOAT_TO_INT16 0
115 %undef cvtps2pi
116
117 ;------------------------------------------------------------------------------
118 ; void ff_float_to_int16_step(int16_t *dst, const float *src, long len, long step);
119 ;------------------------------------------------------------------------------
120 %macro FLOAT_TO_INT16_STEP 1
121 cglobal float_to_int16_step, 4, 7, %1, dst, src, len, step, step3, v1, v2
122     add       lenq, lenq
123     lea       srcq, [srcq+2*lenq]
124     lea     step3q, [stepq*3]
125     neg       lenq
126 .loop:
127 %if cpuflag(sse2)
128     cvtps2dq    m0, [srcq+2*lenq   ]
129     cvtps2dq    m1, [srcq+2*lenq+16]
130     packssdw    m0, m1
131     movd       v1d, m0
132     psrldq      m0, 4
133     movd       v2d, m0
134     psrldq      m0, 4
135     mov     [dstq], v1w
136     mov  [dstq+stepq*4], v2w
137     shr        v1d, 16
138     shr        v2d, 16
139     mov  [dstq+stepq*2], v1w
140     mov  [dstq+step3q*2], v2w
141     lea       dstq, [dstq+stepq*8]
142     movd       v1d, m0
143     psrldq      m0, 4
144     movd       v2d, m0
145     mov     [dstq], v1w
146     mov  [dstq+stepq*4], v2w
147     shr        v1d, 16
148     shr        v2d, 16
149     mov  [dstq+stepq*2], v1w
150     mov  [dstq+step3q*2], v2w
151     lea       dstq, [dstq+stepq*8]
152 %else
153     cvtps2pi    m0, [srcq+2*lenq   ]
154     cvtps2pi    m1, [srcq+2*lenq+ 8]
155     cvtps2pi    m2, [srcq+2*lenq+16]
156     cvtps2pi    m3, [srcq+2*lenq+24]
157     packssdw    m0, m1
158     packssdw    m2, m3
159     movd       v1d, m0
160     psrlq       m0, 32
161     movd       v2d, m0
162     mov     [dstq], v1w
163     mov  [dstq+stepq*4], v2w
164     shr        v1d, 16
165     shr        v2d, 16
166     mov  [dstq+stepq*2], v1w
167     mov  [dstq+step3q*2], v2w
168     lea       dstq, [dstq+stepq*8]
169     movd       v1d, m2
170     psrlq       m2, 32
171     movd       v2d, m2
172     mov     [dstq], v1w
173     mov  [dstq+stepq*4], v2w
174     shr        v1d, 16
175     shr        v2d, 16
176     mov  [dstq+stepq*2], v1w
177     mov  [dstq+step3q*2], v2w
178     lea       dstq, [dstq+stepq*8]
179 %endif
180     add       lenq, 16
181     js .loop
182 %if mmsize == 8
183     emms
184 %endif
185     REP_RET
186 %endmacro
187
188 INIT_XMM sse2
189 FLOAT_TO_INT16_STEP 2
190 INIT_MMX sse
191 FLOAT_TO_INT16_STEP 0
192 %define cvtps2pi pf2id
193 INIT_MMX 3dnow
194 FLOAT_TO_INT16_STEP 0
195 %undef cvtps2pi
196
197 ;-------------------------------------------------------------------------------
198 ; void ff_float_to_int16_interleave2(int16_t *dst, const float **src, long len);
199 ;-------------------------------------------------------------------------------
200 %macro FLOAT_TO_INT16_INTERLEAVE2 0
201 cglobal float_to_int16_interleave2, 3, 4, 2, dst, src0, src1, len
202     lea      lenq, [4*r2q]
203     mov     src1q, [src0q+gprsize]
204     mov     src0q, [src0q]
205     add      dstq, lenq
206     add     src0q, lenq
207     add     src1q, lenq
208     neg      lenq
209 .loop:
210 %if cpuflag(sse2)
211     cvtps2dq   m0, [src0q+lenq]
212     cvtps2dq   m1, [src1q+lenq]
213     packssdw   m0, m1
214     movhlps    m1, m0
215     punpcklwd  m0, m1
216     mova  [dstq+lenq], m0
217 %else
218     cvtps2pi   m0, [src0q+lenq  ]
219     cvtps2pi   m1, [src0q+lenq+8]
220     cvtps2pi   m2, [src1q+lenq  ]
221     cvtps2pi   m3, [src1q+lenq+8]
222     packssdw   m0, m1
223     packssdw   m2, m3
224     mova       m1, m0
225     punpcklwd  m0, m2
226     punpckhwd  m1, m2
227     mova  [dstq+lenq  ], m0
228     mova  [dstq+lenq+8], m1
229 %endif
230     add      lenq, 16
231     js .loop
232 %if mmsize == 8
233     emms
234 %endif
235     REP_RET
236 %endmacro
237
238 INIT_MMX 3dnow
239 %define cvtps2pi pf2id
240 FLOAT_TO_INT16_INTERLEAVE2
241 %undef cvtps2pi
242 INIT_MMX sse
243 FLOAT_TO_INT16_INTERLEAVE2
244 INIT_XMM sse2
245 FLOAT_TO_INT16_INTERLEAVE2
246
247
248 %macro PSWAPD_SSE 2
249     pshufw %1, %2, 0x4e
250 %endmacro
251 %macro PSWAPD_3DNOW 2
252     movq  %1, %2
253     psrlq %1, 32
254     punpckldq %1, %2
255 %endmacro
256
257 %macro FLOAT_TO_INT16_INTERLEAVE6 0
258 ; void float_to_int16_interleave6_sse(int16_t *dst, const float **src, int len)
259 cglobal float_to_int16_interleave6, 2, 8, 0, dst, src, src1, src2, src3, src4, src5, len
260 %if ARCH_X86_64
261     mov     lend, r2d
262 %else
263     %define lend dword r2m
264 %endif
265     mov src1q, [srcq+1*gprsize]
266     mov src2q, [srcq+2*gprsize]
267     mov src3q, [srcq+3*gprsize]
268     mov src4q, [srcq+4*gprsize]
269     mov src5q, [srcq+5*gprsize]
270     mov srcq,  [srcq]
271     sub src1q, srcq
272     sub src2q, srcq
273     sub src3q, srcq
274     sub src4q, srcq
275     sub src5q, srcq
276 .loop:
277     cvtps2pi   mm0, [srcq]
278     cvtps2pi   mm1, [srcq+src1q]
279     cvtps2pi   mm2, [srcq+src2q]
280     cvtps2pi   mm3, [srcq+src3q]
281     cvtps2pi   mm4, [srcq+src4q]
282     cvtps2pi   mm5, [srcq+src5q]
283     packssdw   mm0, mm3
284     packssdw   mm1, mm4
285     packssdw   mm2, mm5
286     pswapd     mm3, mm0
287     punpcklwd  mm0, mm1
288     punpckhwd  mm1, mm2
289     punpcklwd  mm2, mm3
290     pswapd     mm3, mm0
291     punpckldq  mm0, mm2
292     punpckhdq  mm2, mm1
293     punpckldq  mm1, mm3
294     movq [dstq   ], mm0
295     movq [dstq+16], mm2
296     movq [dstq+ 8], mm1
297     add srcq, 8
298     add dstq, 24
299     sub lend, 2
300     jg .loop
301     emms
302     RET
303 %endmacro ; FLOAT_TO_INT16_INTERLEAVE6
304
305 INIT_MMX sse
306 %define pswapd PSWAPD_SSE
307 FLOAT_TO_INT16_INTERLEAVE6
308 INIT_MMX 3dnow
309 %define cvtps2pi pf2id
310 %define pswapd PSWAPD_3DNOW
311 FLOAT_TO_INT16_INTERLEAVE6
312 %undef pswapd
313 INIT_MMX 3dnowext
314 FLOAT_TO_INT16_INTERLEAVE6
315 %undef cvtps2pi
316
317 ;-----------------------------------------------------------------------------
318 ; void ff_float_interleave6(float *dst, const float **src, unsigned int len);
319 ;-----------------------------------------------------------------------------
320
321 %macro FLOAT_INTERLEAVE6 1
322 cglobal float_interleave6, 2, 8, %1, dst, src, src1, src2, src3, src4, src5, len
323 %if ARCH_X86_64
324     mov     lend, r2d
325 %else
326     %define lend dword r2m
327 %endif
328     mov    src1q, [srcq+1*gprsize]
329     mov    src2q, [srcq+2*gprsize]
330     mov    src3q, [srcq+3*gprsize]
331     mov    src4q, [srcq+4*gprsize]
332     mov    src5q, [srcq+5*gprsize]
333     mov     srcq, [srcq]
334     sub    src1q, srcq
335     sub    src2q, srcq
336     sub    src3q, srcq
337     sub    src4q, srcq
338     sub    src5q, srcq
339 .loop:
340 %if cpuflag(sse)
341     movaps    m0, [srcq]
342     movaps    m1, [srcq+src1q]
343     movaps    m2, [srcq+src2q]
344     movaps    m3, [srcq+src3q]
345     movaps    m4, [srcq+src4q]
346     movaps    m5, [srcq+src5q]
347
348     SBUTTERFLYPS 0, 1, 6
349     SBUTTERFLYPS 2, 3, 6
350     SBUTTERFLYPS 4, 5, 6
351
352     movaps    m6, m4
353     shufps    m4, m0, 0xe4
354     movlhps   m0, m2
355     movhlps   m6, m2
356     movaps [dstq   ], m0
357     movaps [dstq+16], m4
358     movaps [dstq+32], m6
359
360     movaps    m6, m5
361     shufps    m5, m1, 0xe4
362     movlhps   m1, m3
363     movhlps   m6, m3
364     movaps [dstq+48], m1
365     movaps [dstq+64], m5
366     movaps [dstq+80], m6
367 %else ; mmx
368     movq       m0, [srcq]
369     movq       m1, [srcq+src1q]
370     movq       m2, [srcq+src2q]
371     movq       m3, [srcq+src3q]
372     movq       m4, [srcq+src4q]
373     movq       m5, [srcq+src5q]
374
375     SBUTTERFLY dq, 0, 1, 6
376     SBUTTERFLY dq, 2, 3, 6
377     SBUTTERFLY dq, 4, 5, 6
378     movq [dstq   ], m0
379     movq [dstq+ 8], m2
380     movq [dstq+16], m4
381     movq [dstq+24], m1
382     movq [dstq+32], m3
383     movq [dstq+40], m5
384 %endif
385     add      srcq, mmsize
386     add      dstq, mmsize*6
387     sub      lend, mmsize/4
388     jg .loop
389 %if mmsize == 8
390     emms
391 %endif
392     REP_RET
393 %endmacro
394
395 INIT_MMX mmx
396 FLOAT_INTERLEAVE6 0
397 INIT_XMM sse
398 FLOAT_INTERLEAVE6 7
399
400 ;-----------------------------------------------------------------------------
401 ; void ff_float_interleave2(float *dst, const float **src, unsigned int len);
402 ;-----------------------------------------------------------------------------
403
404 %macro FLOAT_INTERLEAVE2 1
405 cglobal float_interleave2, 3, 4, %1, dst, src, len, src1
406     mov     src1q, [srcq+gprsize]
407     mov      srcq, [srcq        ]
408     sub     src1q, srcq
409 .loop:
410     mova       m0, [srcq             ]
411     mova       m1, [srcq+src1q       ]
412     mova       m3, [srcq      +mmsize]
413     mova       m4, [srcq+src1q+mmsize]
414
415     mova       m2, m0
416     PUNPCKLDQ  m0, m1
417     PUNPCKHDQ  m2, m1
418
419     mova       m1, m3
420     PUNPCKLDQ  m3, m4
421     PUNPCKHDQ  m1, m4
422
423     mova  [dstq         ], m0
424     mova  [dstq+1*mmsize], m2
425     mova  [dstq+2*mmsize], m3
426     mova  [dstq+3*mmsize], m1
427
428     add      srcq, mmsize*2
429     add      dstq, mmsize*4
430     sub      lend, mmsize/2
431     jg .loop
432 %if mmsize == 8
433     emms
434 %endif
435     REP_RET
436 %endmacro
437
438 INIT_MMX mmx
439 %define PUNPCKLDQ punpckldq
440 %define PUNPCKHDQ punpckhdq
441 FLOAT_INTERLEAVE2 0
442 INIT_XMM sse
443 %define PUNPCKLDQ unpcklps
444 %define PUNPCKHDQ unpckhps
445 FLOAT_INTERLEAVE2 5