Merge commit '6860b4081d046558c44b1b42f22022ea341a2a73'
[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 FFmpeg.
6 ;*
7 ;* FFmpeg 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 ;* FFmpeg 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 FFmpeg; 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 2
30 %if UNIX64
31 cglobal int32_to_float_fmul_scalar_%1, 3,3,%2, dst, src, len
32 %else
33 cglobal int32_to_float_fmul_scalar_%1, 4,4,%2, 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 %ifidn %1, 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
67 %define SPLATD SPLATD_SSE
68 %define movdqa movaps
69 INT32_TO_FLOAT_FMUL_SCALAR sse, 5
70 %undef movdqa
71 %define SPLATD SPLATD_SSE2
72 INT32_TO_FLOAT_FMUL_SCALAR sse2, 3
73 %undef SPLATD
74
75
76 ;------------------------------------------------------------------------------
77 ; void ff_float_to_int16(int16_t *dst, const float *src, long len);
78 ;------------------------------------------------------------------------------
79 %macro FLOAT_TO_INT16 2
80 cglobal float_to_int16_%1, 3,3,%2, dst, src, len
81     add       lenq, lenq
82     lea       srcq, [srcq+2*lenq]
83     add       dstq, lenq
84     neg       lenq
85 .loop:
86 %ifidn %1, sse2
87     cvtps2dq    m0, [srcq+2*lenq   ]
88     cvtps2dq    m1, [srcq+2*lenq+16]
89     packssdw    m0, m1
90     mova  [dstq+lenq], m0
91 %else
92     cvtps2pi    m0, [srcq+2*lenq   ]
93     cvtps2pi    m1, [srcq+2*lenq+ 8]
94     cvtps2pi    m2, [srcq+2*lenq+16]
95     cvtps2pi    m3, [srcq+2*lenq+24]
96     packssdw    m0, m1
97     packssdw    m2, m3
98     mova  [dstq+lenq  ], m0
99     mova  [dstq+lenq+8], m2
100 %endif
101     add       lenq, 16
102     js .loop
103 %ifnidn %1, sse2
104     emms
105 %endif
106     REP_RET
107 %endmacro
108
109 INIT_XMM
110 FLOAT_TO_INT16 sse2, 2
111 INIT_MMX
112 FLOAT_TO_INT16 sse, 0
113 %define cvtps2pi pf2id
114 FLOAT_TO_INT16 3dnow, 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 2
121 cglobal float_to_int16_step_%1, 4,7,%2, 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 %ifidn %1, 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 %ifnidn %1, sse2
183     emms
184 %endif
185     REP_RET
186 %endmacro
187
188 INIT_XMM
189 FLOAT_TO_INT16_STEP sse2, 2
190 INIT_MMX
191 FLOAT_TO_INT16_STEP sse, 0
192 %define cvtps2pi pf2id
193 FLOAT_TO_INT16_STEP 3dnow, 0
194 %undef cvtps2pi
195
196 ;-------------------------------------------------------------------------------
197 ; void ff_float_to_int16_interleave2(int16_t *dst, const float **src, long len);
198 ;-------------------------------------------------------------------------------
199 %macro FLOAT_TO_INT16_INTERLEAVE2 1
200 cglobal float_to_int16_interleave2_%1, 3,4,2, dst, src0, src1, len
201     lea      lenq, [4*r2q]
202     mov     src1q, [src0q+gprsize]
203     mov     src0q, [src0q]
204     add      dstq, lenq
205     add     src0q, lenq
206     add     src1q, lenq
207     neg      lenq
208 .loop:
209 %ifidn %1, sse2
210     cvtps2dq   m0, [src0q+lenq]
211     cvtps2dq   m1, [src1q+lenq]
212     packssdw   m0, m1
213     movhlps    m1, m0
214     punpcklwd  m0, m1
215     mova  [dstq+lenq], m0
216 %else
217     cvtps2pi   m0, [src0q+lenq  ]
218     cvtps2pi   m1, [src0q+lenq+8]
219     cvtps2pi   m2, [src1q+lenq  ]
220     cvtps2pi   m3, [src1q+lenq+8]
221     packssdw   m0, m1
222     packssdw   m2, m3
223     mova       m1, m0
224     punpcklwd  m0, m2
225     punpckhwd  m1, m2
226     mova  [dstq+lenq  ], m0
227     mova  [dstq+lenq+8], m1
228 %endif
229     add      lenq, 16
230     js .loop
231 %ifnidn %1, sse2
232     emms
233 %endif
234     REP_RET
235 %endmacro
236
237 INIT_MMX
238 %define cvtps2pi pf2id
239 FLOAT_TO_INT16_INTERLEAVE2 3dnow
240 %undef cvtps2pi
241 %define movdqa movaps
242 FLOAT_TO_INT16_INTERLEAVE2 sse
243 %undef movdqa
244 INIT_XMM
245 FLOAT_TO_INT16_INTERLEAVE2 sse2
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 1
258 ; void float_to_int16_interleave6_sse(int16_t *dst, const float **src, int len)
259 cglobal float_to_int16_interleave6_%1, 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 %define pswapd PSWAPD_SSE
306 FLOAT_TO_INT16_INTERLEAVE6 sse
307 %define cvtps2pi pf2id
308 %define pswapd PSWAPD_3DNOW
309 FLOAT_TO_INT16_INTERLEAVE6 3dnow
310 %undef pswapd
311 FLOAT_TO_INT16_INTERLEAVE6 3dnowext
312 %undef cvtps2pi
313
314 ;-----------------------------------------------------------------------------
315 ; void ff_float_interleave6(float *dst, const float **src, unsigned int len);
316 ;-----------------------------------------------------------------------------
317
318 %macro FLOAT_INTERLEAVE6 2
319 cglobal float_interleave6_%1, 2,8,%2, dst, src, src1, src2, src3, src4, src5, len
320 %if ARCH_X86_64
321     mov     lend, r2d
322 %else
323     %define lend dword r2m
324 %endif
325     mov    src1q, [srcq+1*gprsize]
326     mov    src2q, [srcq+2*gprsize]
327     mov    src3q, [srcq+3*gprsize]
328     mov    src4q, [srcq+4*gprsize]
329     mov    src5q, [srcq+5*gprsize]
330     mov     srcq, [srcq]
331     sub    src1q, srcq
332     sub    src2q, srcq
333     sub    src3q, srcq
334     sub    src4q, srcq
335     sub    src5q, srcq
336 .loop:
337 %ifidn %1, sse
338     movaps    m0, [srcq]
339     movaps    m1, [srcq+src1q]
340     movaps    m2, [srcq+src2q]
341     movaps    m3, [srcq+src3q]
342     movaps    m4, [srcq+src4q]
343     movaps    m5, [srcq+src5q]
344
345     SBUTTERFLYPS 0, 1, 6
346     SBUTTERFLYPS 2, 3, 6
347     SBUTTERFLYPS 4, 5, 6
348
349     movaps    m6, m4
350     shufps    m4, m0, 0xe4
351     movlhps   m0, m2
352     movhlps   m6, m2
353     movaps [dstq   ], m0
354     movaps [dstq+16], m4
355     movaps [dstq+32], m6
356
357     movaps    m6, m5
358     shufps    m5, m1, 0xe4
359     movlhps   m1, m3
360     movhlps   m6, m3
361     movaps [dstq+48], m1
362     movaps [dstq+64], m5
363     movaps [dstq+80], m6
364 %else ; mmx
365     movq       m0, [srcq]
366     movq       m1, [srcq+src1q]
367     movq       m2, [srcq+src2q]
368     movq       m3, [srcq+src3q]
369     movq       m4, [srcq+src4q]
370     movq       m5, [srcq+src5q]
371
372     SBUTTERFLY dq, 0, 1, 6
373     SBUTTERFLY dq, 2, 3, 6
374     SBUTTERFLY dq, 4, 5, 6
375     movq [dstq   ], m0
376     movq [dstq+ 8], m2
377     movq [dstq+16], m4
378     movq [dstq+24], m1
379     movq [dstq+32], m3
380     movq [dstq+40], m5
381 %endif
382     add      srcq, mmsize
383     add      dstq, mmsize*6
384     sub      lend, mmsize/4
385     jg .loop
386 %ifidn %1, mmx
387     emms
388 %endif
389     REP_RET
390 %endmacro
391
392 INIT_MMX
393 FLOAT_INTERLEAVE6 mmx, 0
394 INIT_XMM
395 FLOAT_INTERLEAVE6 sse, 7
396
397 ;-----------------------------------------------------------------------------
398 ; void ff_float_interleave2(float *dst, const float **src, unsigned int len);
399 ;-----------------------------------------------------------------------------
400
401 %macro FLOAT_INTERLEAVE2 2
402 cglobal float_interleave2_%1, 3,4,%2, dst, src, len, src1
403     mov     src1q, [srcq+gprsize]
404     mov      srcq, [srcq        ]
405     sub     src1q, srcq
406 .loop:
407     MOVPS      m0, [srcq             ]
408     MOVPS      m1, [srcq+src1q       ]
409     MOVPS      m3, [srcq      +mmsize]
410     MOVPS      m4, [srcq+src1q+mmsize]
411
412     MOVPS      m2, m0
413     PUNPCKLDQ  m0, m1
414     PUNPCKHDQ  m2, m1
415
416     MOVPS      m1, m3
417     PUNPCKLDQ  m3, m4
418     PUNPCKHDQ  m1, m4
419
420     MOVPS [dstq         ], m0
421     MOVPS [dstq+1*mmsize], m2
422     MOVPS [dstq+2*mmsize], m3
423     MOVPS [dstq+3*mmsize], m1
424
425     add      srcq, mmsize*2
426     add      dstq, mmsize*4
427     sub      lend, mmsize/2
428     jg .loop
429 %ifidn %1, mmx
430     emms
431 %endif
432     REP_RET
433 %endmacro
434
435 INIT_MMX
436 %define MOVPS     movq
437 %define PUNPCKLDQ punpckldq
438 %define PUNPCKHDQ punpckhdq
439 FLOAT_INTERLEAVE2 mmx, 0
440 INIT_XMM
441 %define MOVPS     movaps
442 %define PUNPCKLDQ unpcklps
443 %define PUNPCKHDQ unpckhps
444 FLOAT_INTERLEAVE2 sse, 5