Merge remote-tracking branch 'qatar/master'
[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/x86inc.asm"
23 %include "libavutil/x86/x86util.asm"
24
25 SECTION_TEXT
26
27 ;---------------------------------------------------------------------------------
28 ; void int32_to_float_fmul_scalar(float *dst, const int *src, float mul, int len);
29 ;---------------------------------------------------------------------------------
30 %macro INT32_TO_FLOAT_FMUL_SCALAR 2
31 %ifdef ARCH_X86_64
32 cglobal int32_to_float_fmul_scalar_%1, 3,3,%2, dst, src, len
33 %else
34 cglobal int32_to_float_fmul_scalar_%1, 4,4,%2, dst, src, mul, len
35     movss   m0, mulm
36 %endif
37     SPLATD  m0
38     shl     lenq, 2
39     add     srcq, lenq
40     add     dstq, lenq
41     neg     lenq
42 .loop:
43 %ifidn %1, sse2
44     cvtdq2ps  m1, [srcq+lenq   ]
45     cvtdq2ps  m2, [srcq+lenq+16]
46 %else
47     cvtpi2ps  m1, [srcq+lenq   ]
48     cvtpi2ps  m3, [srcq+lenq+ 8]
49     cvtpi2ps  m2, [srcq+lenq+16]
50     cvtpi2ps  m4, [srcq+lenq+24]
51     movlhps   m1, m3
52     movlhps   m2, m4
53 %endif
54     mulps     m1, m0
55     mulps     m2, m0
56     mova  [dstq+lenq   ], m1
57     mova  [dstq+lenq+16], m2
58     add     lenq, 32
59     jl .loop
60     REP_RET
61 %endmacro
62
63 INIT_XMM
64 %define SPLATD SPLATD_SSE
65 %define movdqa movaps
66 INT32_TO_FLOAT_FMUL_SCALAR sse, 5
67 %undef movdqa
68 %define SPLATD SPLATD_SSE2
69 INT32_TO_FLOAT_FMUL_SCALAR sse2, 3
70 %undef SPLATD
71
72
73 ;------------------------------------------------------------------------------
74 ; void ff_float_to_int16(int16_t *dst, const float *src, long len);
75 ;------------------------------------------------------------------------------
76 %macro FLOAT_TO_INT16 2
77 cglobal float_to_int16_%1, 3,3,%2, dst, src, len
78     add       lenq, lenq
79     lea       srcq, [srcq+2*lenq]
80     add       dstq, lenq
81     neg       lenq
82 .loop:
83 %ifidn %1, sse2
84     cvtps2dq    m0, [srcq+2*lenq   ]
85     cvtps2dq    m1, [srcq+2*lenq+16]
86     packssdw    m0, m1
87     mova  [dstq+lenq], m0
88 %else
89     cvtps2pi    m0, [srcq+2*lenq   ]
90     cvtps2pi    m1, [srcq+2*lenq+ 8]
91     cvtps2pi    m2, [srcq+2*lenq+16]
92     cvtps2pi    m3, [srcq+2*lenq+24]
93     packssdw    m0, m1
94     packssdw    m2, m3
95     mova  [dstq+lenq  ], m0
96     mova  [dstq+lenq+8], m2
97 %endif
98     add       lenq, 16
99     js .loop
100 %ifnidn %1, sse2
101     emms
102 %endif
103     REP_RET
104 %endmacro
105
106 INIT_XMM
107 FLOAT_TO_INT16 sse2, 2
108 INIT_MMX
109 FLOAT_TO_INT16 sse, 0
110 %define cvtps2pi pf2id
111 FLOAT_TO_INT16 3dnow, 0
112 %undef cvtps2pi
113
114
115 ;-------------------------------------------------------------------------------
116 ; void ff_float_to_int16_interleave2(int16_t *dst, const float **src, long len);
117 ;-------------------------------------------------------------------------------
118 %macro FLOAT_TO_INT16_INTERLEAVE2 1
119 cglobal float_to_int16_interleave2_%1, 3,4,2, dst, src0, src1, len
120     lea      lenq, [4*r2q]
121     mov     src1q, [src0q+gprsize]
122     mov     src0q, [src0q]
123     add      dstq, lenq
124     add     src0q, lenq
125     add     src1q, lenq
126     neg      lenq
127 .loop:
128 %ifidn %1, sse2
129     cvtps2dq   m0, [src0q+lenq]
130     cvtps2dq   m1, [src1q+lenq]
131     packssdw   m0, m1
132     movhlps    m1, m0
133     punpcklwd  m0, m1
134     mova  [dstq+lenq], m0
135 %else
136     cvtps2pi   m0, [src0q+lenq  ]
137     cvtps2pi   m1, [src0q+lenq+8]
138     cvtps2pi   m2, [src1q+lenq  ]
139     cvtps2pi   m3, [src1q+lenq+8]
140     packssdw   m0, m1
141     packssdw   m2, m3
142     mova       m1, m0
143     punpcklwd  m0, m2
144     punpckhwd  m1, m2
145     mova  [dstq+lenq  ], m0
146     mova  [dstq+lenq+8], m1
147 %endif
148     add      lenq, 16
149     js .loop
150 %ifnidn %1, sse2
151     emms
152 %endif
153     REP_RET
154 %endmacro
155
156 INIT_MMX
157 %define cvtps2pi pf2id
158 FLOAT_TO_INT16_INTERLEAVE2 3dnow
159 %undef cvtps2pi
160 %define movdqa movaps
161 FLOAT_TO_INT16_INTERLEAVE2 sse
162 %undef movdqa
163 INIT_XMM
164 FLOAT_TO_INT16_INTERLEAVE2 sse2
165
166
167 %macro PSWAPD_SSE 2
168     pshufw %1, %2, 0x4e
169 %endmacro
170 %macro PSWAPD_3DN1 2
171     movq  %1, %2
172     psrlq %1, 32
173     punpckldq %1, %2
174 %endmacro
175
176 %macro FLOAT_TO_INT16_INTERLEAVE6 1
177 ; void float_to_int16_interleave6_sse(int16_t *dst, const float **src, int len)
178 cglobal float_to_int16_interleave6_%1, 2,7,0, dst, src, src1, src2, src3, src4, src5
179 %ifdef ARCH_X86_64
180     %define lend r10d
181     mov     lend, r2d
182 %else
183     %define lend dword r2m
184 %endif
185     mov src1q, [srcq+1*gprsize]
186     mov src2q, [srcq+2*gprsize]
187     mov src3q, [srcq+3*gprsize]
188     mov src4q, [srcq+4*gprsize]
189     mov src5q, [srcq+5*gprsize]
190     mov srcq,  [srcq]
191     sub src1q, srcq
192     sub src2q, srcq
193     sub src3q, srcq
194     sub src4q, srcq
195     sub src5q, srcq
196 .loop:
197     cvtps2pi   mm0, [srcq]
198     cvtps2pi   mm1, [srcq+src1q]
199     cvtps2pi   mm2, [srcq+src2q]
200     cvtps2pi   mm3, [srcq+src3q]
201     cvtps2pi   mm4, [srcq+src4q]
202     cvtps2pi   mm5, [srcq+src5q]
203     packssdw   mm0, mm3
204     packssdw   mm1, mm4
205     packssdw   mm2, mm5
206     pswapd     mm3, mm0
207     punpcklwd  mm0, mm1
208     punpckhwd  mm1, mm2
209     punpcklwd  mm2, mm3
210     pswapd     mm3, mm0
211     punpckldq  mm0, mm2
212     punpckhdq  mm2, mm1
213     punpckldq  mm1, mm3
214     movq [dstq   ], mm0
215     movq [dstq+16], mm2
216     movq [dstq+ 8], mm1
217     add srcq, 8
218     add dstq, 24
219     sub lend, 2
220     jg .loop
221     emms
222     RET
223 %endmacro ; FLOAT_TO_INT16_INTERLEAVE6
224
225 %define pswapd PSWAPD_SSE
226 FLOAT_TO_INT16_INTERLEAVE6 sse
227 %define cvtps2pi pf2id
228 %define pswapd PSWAPD_3DN1
229 FLOAT_TO_INT16_INTERLEAVE6 3dnow
230 %undef pswapd
231 FLOAT_TO_INT16_INTERLEAVE6 3dn2
232 %undef cvtps2pi
233
234 ;-----------------------------------------------------------------------------
235 ; void ff_float_interleave6(float *dst, const float **src, unsigned int len);
236 ;-----------------------------------------------------------------------------
237
238 %macro FLOAT_INTERLEAVE6 2
239 cglobal float_interleave6_%1, 2,7,%2, dst, src, src1, src2, src3, src4, src5
240 %ifdef ARCH_X86_64
241     %define lend r10d
242     mov     lend, r2d
243 %else
244     %define lend dword r2m
245 %endif
246     mov    src1q, [srcq+1*gprsize]
247     mov    src2q, [srcq+2*gprsize]
248     mov    src3q, [srcq+3*gprsize]
249     mov    src4q, [srcq+4*gprsize]
250     mov    src5q, [srcq+5*gprsize]
251     mov     srcq, [srcq]
252     sub    src1q, srcq
253     sub    src2q, srcq
254     sub    src3q, srcq
255     sub    src4q, srcq
256     sub    src5q, srcq
257 .loop:
258 %ifidn %1, sse
259     movaps    m0, [srcq]
260     movaps    m1, [srcq+src1q]
261     movaps    m2, [srcq+src2q]
262     movaps    m3, [srcq+src3q]
263     movaps    m4, [srcq+src4q]
264     movaps    m5, [srcq+src5q]
265
266     SBUTTERFLYPS 0, 1, 6
267     SBUTTERFLYPS 2, 3, 6
268     SBUTTERFLYPS 4, 5, 6
269
270     movaps    m6, m4
271     shufps    m4, m0, 0xe4
272     movlhps   m0, m2
273     movhlps   m6, m2
274     movaps [dstq   ], m0
275     movaps [dstq+16], m4
276     movaps [dstq+32], m6
277
278     movaps    m6, m5
279     shufps    m5, m1, 0xe4
280     movlhps   m1, m3
281     movhlps   m6, m3
282     movaps [dstq+48], m1
283     movaps [dstq+64], m5
284     movaps [dstq+80], m6
285 %else ; mmx
286     movq       m0, [srcq]
287     movq       m1, [srcq+src1q]
288     movq       m2, [srcq+src2q]
289     movq       m3, [srcq+src3q]
290     movq       m4, [srcq+src4q]
291     movq       m5, [srcq+src5q]
292
293     SBUTTERFLY dq, 0, 1, 6
294     SBUTTERFLY dq, 2, 3, 6
295     SBUTTERFLY dq, 4, 5, 6
296     movq [dstq   ], m0
297     movq [dstq+ 8], m2
298     movq [dstq+16], m4
299     movq [dstq+24], m1
300     movq [dstq+32], m3
301     movq [dstq+40], m5
302 %endif
303     add      srcq, mmsize
304     add      dstq, mmsize*6
305     sub      lend, mmsize/4
306     jg .loop
307 %ifidn %1, mmx
308     emms
309 %endif
310     REP_RET
311 %endmacro
312
313 INIT_MMX
314 FLOAT_INTERLEAVE6 mmx, 0
315 INIT_XMM
316 FLOAT_INTERLEAVE6 sse, 7
317
318 ;-----------------------------------------------------------------------------
319 ; void ff_float_interleave2(float *dst, const float **src, unsigned int len);
320 ;-----------------------------------------------------------------------------
321
322 %macro FLOAT_INTERLEAVE2 2
323 cglobal float_interleave2_%1, 3,4,%2, dst, src, len, src1
324     mov     src1q, [srcq+gprsize]
325     mov      srcq, [srcq        ]
326     sub     src1q, srcq
327 .loop
328     MOVPS      m0, [srcq             ]
329     MOVPS      m1, [srcq+src1q       ]
330     MOVPS      m3, [srcq      +mmsize]
331     MOVPS      m4, [srcq+src1q+mmsize]
332
333     MOVPS      m2, m0
334     PUNPCKLDQ  m0, m1
335     PUNPCKHDQ  m2, m1
336
337     MOVPS      m1, m3
338     PUNPCKLDQ  m3, m4
339     PUNPCKHDQ  m1, m4
340
341     MOVPS [dstq         ], m0
342     MOVPS [dstq+1*mmsize], m2
343     MOVPS [dstq+2*mmsize], m3
344     MOVPS [dstq+3*mmsize], m1
345
346     add      srcq, mmsize*2
347     add      dstq, mmsize*4
348     sub      lend, mmsize/2
349     jg .loop
350 %ifidn %1, mmx
351     emms
352 %endif
353     REP_RET
354 %endmacro
355
356 INIT_MMX
357 %define MOVPS     movq
358 %define PUNPCKLDQ punpckldq
359 %define PUNPCKHDQ punpckhdq
360 FLOAT_INTERLEAVE2 mmx, 0
361 INIT_XMM
362 %define MOVPS     movaps
363 %define PUNPCKLDQ unpcklps
364 %define PUNPCKHDQ unpckhps
365 FLOAT_INTERLEAVE2 sse, 5