swresample/x86/audio_convert: add emms to CONV
[ffmpeg.git] / libswresample / x86 / audio_convert.asm
1 ;******************************************************************************
2 ;* Copyright (c) 2012 Michael Niedermayer
3 ;*
4 ;* This file is part of FFmpeg.
5 ;*
6 ;* FFmpeg is free software; you can redistribute it and/or
7 ;* modify it under the terms of the GNU Lesser General Public
8 ;* License as published by the Free Software Foundation; either
9 ;* version 2.1 of the License, or (at your option) any later version.
10 ;*
11 ;* FFmpeg is distributed in the hope that it will be useful,
12 ;* but WITHOUT ANY WARRANTY; without even the implied warranty of
13 ;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 ;* Lesser General Public License for more details.
15 ;*
16 ;* You should have received a copy of the GNU Lesser General Public
17 ;* License along with FFmpeg; if not, write to the Free Software
18 ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 ;******************************************************************************
20
21 %include "libavutil/x86/x86inc.asm"
22 %include "libavutil/x86/x86util.asm"
23
24 SECTION_RODATA
25 align 32
26 flt2pm31: times 8 dd 4.6566129e-10
27 flt2p31 : times 8 dd 2147483648.0
28 flt2p15 : times 8 dd 32768.0
29
30 word_unpack_shuf : db  0, 1, 4, 5, 8, 9,12,13, 2, 3, 6, 7,10,11,14,15
31
32 SECTION .text
33
34
35 ;to, from, a/u, log2_outsize, log_intsize, const
36 %macro PACK_2CH 5-7
37 cglobal pack_2ch_%2_to_%1_%3, 3, 4, 6, dst, src, len, src2
38     mov src2q   , [srcq+gprsize]
39     mov srcq    , [srcq]
40     mov dstq    , [dstq]
41 %ifidn %3, a
42     test dstq, mmsize-1
43         jne pack_2ch_%2_to_%1_u_int %+ SUFFIX
44     test srcq, mmsize-1
45         jne pack_2ch_%2_to_%1_u_int %+ SUFFIX
46     test src2q, mmsize-1
47         jne pack_2ch_%2_to_%1_u_int %+ SUFFIX
48 %else
49 pack_2ch_%2_to_%1_u_int %+ SUFFIX
50 %endif
51     lea     srcq , [srcq  + (1<<%5)*lenq]
52     lea     src2q, [src2q + (1<<%5)*lenq]
53     lea     dstq , [dstq  + (2<<%4)*lenq]
54     neg     lenq
55     %7 m0,m1,m2,m3,m4,m5
56 .next:
57 %if %4 >= %5
58     mov%3     m0, [         srcq +(1<<%5)*lenq]
59     mova      m1, m0
60     mov%3     m2, [         src2q+(1<<%5)*lenq]
61 %if %5 == 1
62     punpcklwd m0, m2
63     punpckhwd m1, m2
64 %else
65     punpckldq m0, m2
66     punpckhdq m1, m2
67 %endif
68     %6 m0,m1,m2,m3,m4,m5
69 %else
70     mov%3     m0, [         srcq +(1<<%5)*lenq]
71     mov%3     m1, [mmsize + srcq +(1<<%5)*lenq]
72     mov%3     m2, [         src2q+(1<<%5)*lenq]
73     mov%3     m3, [mmsize + src2q+(1<<%5)*lenq]
74     %6 m0,m1,m2,m3,m4,m5
75     mova      m2, m0
76     punpcklwd m0, m1
77     punpckhwd m2, m1
78     SWAP 1,2
79 %endif
80     mov%3 [           dstq+(2<<%4)*lenq], m0
81     mov%3 [  mmsize + dstq+(2<<%4)*lenq], m1
82 %if %4 > %5
83     mov%3 [2*mmsize + dstq+(2<<%4)*lenq], m2
84     mov%3 [3*mmsize + dstq+(2<<%4)*lenq], m3
85     add lenq, 4*mmsize/(2<<%4)
86 %else
87     add lenq, 2*mmsize/(2<<%4)
88 %endif
89         jl .next
90     REP_RET
91 %endmacro
92
93 %macro UNPACK_2CH 5-7
94 cglobal unpack_2ch_%2_to_%1_%3, 3, 4, 7, dst, src, len, dst2
95     mov dst2q   , [dstq+gprsize]
96     mov srcq    , [srcq]
97     mov dstq    , [dstq]
98 %ifidn %3, a
99     test dstq, mmsize-1
100         jne unpack_2ch_%2_to_%1_u_int %+ SUFFIX
101     test srcq, mmsize-1
102         jne unpack_2ch_%2_to_%1_u_int %+ SUFFIX
103     test dst2q, mmsize-1
104         jne unpack_2ch_%2_to_%1_u_int %+ SUFFIX
105 %else
106 unpack_2ch_%2_to_%1_u_int %+ SUFFIX
107 %endif
108     lea     srcq , [srcq  + (2<<%5)*lenq]
109     lea     dstq , [dstq  + (1<<%4)*lenq]
110     lea     dst2q, [dst2q + (1<<%4)*lenq]
111     neg     lenq
112     %7 m0,m1,m2,m3,m4,m5
113     mova      m6, [word_unpack_shuf]
114 .next:
115     mov%3     m0, [           srcq +(2<<%5)*lenq]
116     mov%3     m2, [  mmsize + srcq +(2<<%5)*lenq]
117 %if %5 == 1
118 %ifidn SUFFIX, _ssse3
119     pshufb    m0, m6
120     mova      m1, m0
121     pshufb    m2, m6
122     punpcklqdq m0,m2
123     punpckhqdq m1,m2
124 %else
125     mova      m1, m0
126     punpcklwd m0,m2
127     punpckhwd m1,m2
128
129     mova      m2, m0
130     punpcklwd m0,m1
131     punpckhwd m2,m1
132
133     mova      m1, m0
134     punpcklwd m0,m2
135     punpckhwd m1,m2
136 %endif
137 %else
138     mova      m1, m0
139     shufps    m0, m2, 10001000b
140     shufps    m1, m2, 11011101b
141 %endif
142 %if %4 < %5
143     mov%3     m2, [2*mmsize + srcq +(2<<%5)*lenq]
144     mova      m3, m2
145     mov%3     m4, [3*mmsize + srcq +(2<<%5)*lenq]
146     shufps    m2, m4, 10001000b
147     shufps    m3, m4, 11011101b
148     SWAP 1,2
149 %endif
150     %6 m0,m1,m2,m3,m4,m5
151     mov%3 [           dstq+(1<<%4)*lenq], m0
152 %if %4 > %5
153     mov%3 [          dst2q+(1<<%4)*lenq], m2
154     mov%3 [ mmsize +  dstq+(1<<%4)*lenq], m1
155     mov%3 [ mmsize + dst2q+(1<<%4)*lenq], m3
156     add lenq, 2*mmsize/(1<<%4)
157 %else
158     mov%3 [          dst2q+(1<<%4)*lenq], m1
159     add lenq, mmsize/(1<<%4)
160 %endif
161         jl .next
162     REP_RET
163 %endmacro
164
165 %macro CONV 5-7
166 cglobal %2_to_%1_%3, 3, 3, 6, dst, src, len
167     mov srcq    , [srcq]
168     mov dstq    , [dstq]
169 %ifidn %3, a
170     test dstq, mmsize-1
171         jne %2_to_%1_u_int %+ SUFFIX
172     test srcq, mmsize-1
173         jne %2_to_%1_u_int %+ SUFFIX
174 %else
175 %2_to_%1_u_int %+ SUFFIX
176 %endif
177     lea     srcq , [srcq  + (1<<%5)*lenq]
178     lea     dstq , [dstq  + (1<<%4)*lenq]
179     neg     lenq
180     %7 m0,m1,m2,m3,m4,m5
181 .next:
182     mov%3     m0, [           srcq +(1<<%5)*lenq]
183     mov%3     m1, [  mmsize + srcq +(1<<%5)*lenq]
184 %if %4 < %5
185     mov%3     m2, [2*mmsize + srcq +(1<<%5)*lenq]
186     mov%3     m3, [3*mmsize + srcq +(1<<%5)*lenq]
187 %endif
188     %6 m0,m1,m2,m3,m4,m5
189     mov%3 [           dstq+(1<<%4)*lenq], m0
190     mov%3 [  mmsize + dstq+(1<<%4)*lenq], m1
191 %if %4 > %5
192     mov%3 [2*mmsize + dstq+(1<<%4)*lenq], m2
193     mov%3 [3*mmsize + dstq+(1<<%4)*lenq], m3
194     add lenq, 4*mmsize/(1<<%4)
195 %else
196     add lenq, 2*mmsize/(1<<%4)
197 %endif
198         jl .next
199 %if mmsize == 8
200     emms
201     RET
202 %else
203     REP_RET
204 %endif
205 %endmacro
206
207 %macro PACK_6CH 5-7
208 cglobal pack_6ch_%2_to_%1_%3, 2,8,7, dst, src, src1, src2, src3, src4, src5, len
209 %if ARCH_X86_64
210     mov     lend, r2d
211 %else
212     %define lend dword r2m
213 %endif
214     mov    src1q, [srcq+1*gprsize]
215     mov    src2q, [srcq+2*gprsize]
216     mov    src3q, [srcq+3*gprsize]
217     mov    src4q, [srcq+4*gprsize]
218     mov    src5q, [srcq+5*gprsize]
219     mov     srcq, [srcq]
220     mov     dstq, [dstq]
221 %ifidn %3, a
222     test dstq, mmsize-1
223         jne pack_6ch_%2_to_%1_u_int %+ SUFFIX
224     test srcq, mmsize-1
225         jne pack_6ch_%2_to_%1_u_int %+ SUFFIX
226     test src2q, mmsize-1
227         jne pack_6ch_%2_to_%1_u_int %+ SUFFIX
228     test src3q, mmsize-1
229         jne pack_6ch_%2_to_%1_u_int %+ SUFFIX
230     test src4q, mmsize-1
231         jne pack_6ch_%2_to_%1_u_int %+ SUFFIX
232     test src5q, mmsize-1
233         jne pack_6ch_%2_to_%1_u_int %+ SUFFIX
234 %else
235 pack_6ch_%2_to_%1_u_int %+ SUFFIX
236 %endif
237     sub    src1q, srcq
238     sub    src2q, srcq
239     sub    src3q, srcq
240     sub    src4q, srcq
241     sub    src5q, srcq
242 .loop:
243     mov%3     m0, [srcq      ]
244     mov%3     m1, [srcq+src1q]
245     mov%3     m2, [srcq+src2q]
246     mov%3     m3, [srcq+src3q]
247     mov%3     m4, [srcq+src4q]
248     mov%3     m5, [srcq+src5q]
249     %7 x,x,x,x,m7,x
250 %if cpuflag(sse4)
251     SBUTTERFLYPS 0, 1, 6
252     SBUTTERFLYPS 2, 3, 6
253     SBUTTERFLYPS 4, 5, 6
254
255     blendps   m6, m4, m0, 1100b
256     movlhps   m0, m2
257     movhlps   m4, m2
258     blendps   m2, m5, m1, 1100b
259     movlhps   m1, m3
260     movhlps   m5, m3
261
262     %6 m0,m6,x,x,m7,m3
263     %6 m4,m1,x,x,m7,m3
264     %6 m2,m5,x,x,m7,m3
265
266     mov %+ %3 %+ ps [dstq   ], m0
267     mov %+ %3 %+ ps [dstq+16], m6
268     mov %+ %3 %+ ps [dstq+32], m4
269     mov %+ %3 %+ ps [dstq+48], m1
270     mov %+ %3 %+ ps [dstq+64], m2
271     mov %+ %3 %+ ps [dstq+80], m5
272 %else ; mmx
273     SBUTTERFLY dq, 0, 1, 6
274     SBUTTERFLY dq, 2, 3, 6
275     SBUTTERFLY dq, 4, 5, 6
276
277     movq   [dstq   ], m0
278     movq   [dstq+ 8], m2
279     movq   [dstq+16], m4
280     movq   [dstq+24], m1
281     movq   [dstq+32], m3
282     movq   [dstq+40], m5
283 %endif
284     add      srcq, mmsize
285     add      dstq, mmsize*6
286     sub      lend, mmsize/4
287     jg .loop
288 %if mmsize == 8
289     emms
290     RET
291 %else
292     REP_RET
293 %endif
294 %endmacro
295
296 %macro INT16_TO_INT32_N 6
297     pxor      m2, m2
298     pxor      m3, m3
299     punpcklwd m2, m1
300     punpckhwd m3, m1
301     SWAP 4,0
302     pxor      m0, m0
303     pxor      m1, m1
304     punpcklwd m0, m4
305     punpckhwd m1, m4
306 %endmacro
307
308 %macro INT32_TO_INT16_N 6
309     psrad     m0, 16
310     psrad     m1, 16
311     psrad     m2, 16
312     psrad     m3, 16
313     packssdw  m0, m1
314     packssdw  m2, m3
315     SWAP 1,2
316 %endmacro
317
318 %macro INT32_TO_FLOAT_INIT 6
319     mova      %5, [flt2pm31]
320 %endmacro
321 %macro INT32_TO_FLOAT_N 6
322     cvtdq2ps  %1, %1
323     cvtdq2ps  %2, %2
324     mulps %1, %1, %5
325     mulps %2, %2, %5
326 %endmacro
327
328 %macro FLOAT_TO_INT32_INIT 6
329     mova      %5, [flt2p31]
330 %endmacro
331 %macro FLOAT_TO_INT32_N 6
332     mulps %1, %5
333     mulps %2, %5
334     cvtps2dq  %6, %1
335     cmpnltps %1, %5
336     paddd %1, %6
337     cvtps2dq  %6, %2
338     cmpnltps %2, %5
339     paddd %2, %6
340 %endmacro
341
342 %macro INT16_TO_FLOAT_INIT 6
343     mova      m5, [flt2pm31]
344 %endmacro
345 %macro INT16_TO_FLOAT_N 6
346     INT16_TO_INT32_N %1,%2,%3,%4,%5,%6
347     cvtdq2ps  m0, m0
348     cvtdq2ps  m1, m1
349     cvtdq2ps  m2, m2
350     cvtdq2ps  m3, m3
351     mulps m0, m0, m5
352     mulps m1, m1, m5
353     mulps m2, m2, m5
354     mulps m3, m3, m5
355 %endmacro
356
357 %macro FLOAT_TO_INT16_INIT 6
358     mova      m5, [flt2p15]
359 %endmacro
360 %macro FLOAT_TO_INT16_N 6
361     mulps m0, m5
362     mulps m1, m5
363     mulps m2, m5
364     mulps m3, m5
365     cvtps2dq  m0, m0
366     cvtps2dq  m1, m1
367     packssdw  m0, m1
368     cvtps2dq  m1, m2
369     cvtps2dq  m3, m3
370     packssdw  m1, m3
371 %endmacro
372
373 %macro NOP_N 0-6
374 %endmacro
375
376 INIT_MMX mmx
377 CONV int32, int16, u, 2, 1, INT16_TO_INT32_N, NOP_N
378 CONV int32, int16, a, 2, 1, INT16_TO_INT32_N, NOP_N
379 CONV int16, int32, u, 1, 2, INT32_TO_INT16_N, NOP_N
380 CONV int16, int32, a, 1, 2, INT32_TO_INT16_N, NOP_N
381
382 PACK_6CH float, float, u, 2, 2, NOP_N, NOP_N
383 PACK_6CH float, float, a, 2, 2, NOP_N, NOP_N
384
385 INIT_XMM sse2
386 CONV int32, int16, u, 2, 1, INT16_TO_INT32_N, NOP_N
387 CONV int32, int16, a, 2, 1, INT16_TO_INT32_N, NOP_N
388 CONV int16, int32, u, 1, 2, INT32_TO_INT16_N, NOP_N
389 CONV int16, int32, a, 1, 2, INT32_TO_INT16_N, NOP_N
390
391 PACK_2CH int16, int16, u, 1, 1, NOP_N, NOP_N
392 PACK_2CH int16, int16, a, 1, 1, NOP_N, NOP_N
393 PACK_2CH int32, int32, u, 2, 2, NOP_N, NOP_N
394 PACK_2CH int32, int32, a, 2, 2, NOP_N, NOP_N
395 PACK_2CH int32, int16, u, 2, 1, INT16_TO_INT32_N, NOP_N
396 PACK_2CH int32, int16, a, 2, 1, INT16_TO_INT32_N, NOP_N
397 PACK_2CH int16, int32, u, 1, 2, INT32_TO_INT16_N, NOP_N
398 PACK_2CH int16, int32, a, 1, 2, INT32_TO_INT16_N, NOP_N
399
400 UNPACK_2CH int16, int16, u, 1, 1, NOP_N, NOP_N
401 UNPACK_2CH int16, int16, a, 1, 1, NOP_N, NOP_N
402 UNPACK_2CH int32, int32, u, 2, 2, NOP_N, NOP_N
403 UNPACK_2CH int32, int32, a, 2, 2, NOP_N, NOP_N
404 UNPACK_2CH int32, int16, u, 2, 1, INT16_TO_INT32_N, NOP_N
405 UNPACK_2CH int32, int16, a, 2, 1, INT16_TO_INT32_N, NOP_N
406 UNPACK_2CH int16, int32, u, 1, 2, INT32_TO_INT16_N, NOP_N
407 UNPACK_2CH int16, int32, a, 1, 2, INT32_TO_INT16_N, NOP_N
408
409 CONV float, int32, u, 2, 2, INT32_TO_FLOAT_N, INT32_TO_FLOAT_INIT
410 CONV float, int32, a, 2, 2, INT32_TO_FLOAT_N, INT32_TO_FLOAT_INIT
411 CONV int32, float, u, 2, 2, FLOAT_TO_INT32_N, FLOAT_TO_INT32_INIT
412 CONV int32, float, a, 2, 2, FLOAT_TO_INT32_N, FLOAT_TO_INT32_INIT
413 CONV float, int16, u, 2, 1, INT16_TO_FLOAT_N, INT16_TO_FLOAT_INIT
414 CONV float, int16, a, 2, 1, INT16_TO_FLOAT_N, INT16_TO_FLOAT_INIT
415 CONV int16, float, u, 1, 2, FLOAT_TO_INT16_N, FLOAT_TO_INT16_INIT
416 CONV int16, float, a, 1, 2, FLOAT_TO_INT16_N, FLOAT_TO_INT16_INIT
417
418 PACK_2CH float, int32, u, 2, 2, INT32_TO_FLOAT_N, INT32_TO_FLOAT_INIT
419 PACK_2CH float, int32, a, 2, 2, INT32_TO_FLOAT_N, INT32_TO_FLOAT_INIT
420 PACK_2CH int32, float, u, 2, 2, FLOAT_TO_INT32_N, FLOAT_TO_INT32_INIT
421 PACK_2CH int32, float, a, 2, 2, FLOAT_TO_INT32_N, FLOAT_TO_INT32_INIT
422 PACK_2CH float, int16, u, 2, 1, INT16_TO_FLOAT_N, INT16_TO_FLOAT_INIT
423 PACK_2CH float, int16, a, 2, 1, INT16_TO_FLOAT_N, INT16_TO_FLOAT_INIT
424 PACK_2CH int16, float, u, 1, 2, FLOAT_TO_INT16_N, FLOAT_TO_INT16_INIT
425 PACK_2CH int16, float, a, 1, 2, FLOAT_TO_INT16_N, FLOAT_TO_INT16_INIT
426
427 UNPACK_2CH float, int32, u, 2, 2, INT32_TO_FLOAT_N, INT32_TO_FLOAT_INIT
428 UNPACK_2CH float, int32, a, 2, 2, INT32_TO_FLOAT_N, INT32_TO_FLOAT_INIT
429 UNPACK_2CH int32, float, u, 2, 2, FLOAT_TO_INT32_N, FLOAT_TO_INT32_INIT
430 UNPACK_2CH int32, float, a, 2, 2, FLOAT_TO_INT32_N, FLOAT_TO_INT32_INIT
431 UNPACK_2CH float, int16, u, 2, 1, INT16_TO_FLOAT_N, INT16_TO_FLOAT_INIT
432 UNPACK_2CH float, int16, a, 2, 1, INT16_TO_FLOAT_N, INT16_TO_FLOAT_INIT
433 UNPACK_2CH int16, float, u, 1, 2, FLOAT_TO_INT16_N, FLOAT_TO_INT16_INIT
434 UNPACK_2CH int16, float, a, 1, 2, FLOAT_TO_INT16_N, FLOAT_TO_INT16_INIT
435
436
437 INIT_XMM ssse3
438 UNPACK_2CH int16, int16, u, 1, 1, NOP_N, NOP_N
439 UNPACK_2CH int16, int16, a, 1, 1, NOP_N, NOP_N
440 UNPACK_2CH int32, int16, u, 2, 1, INT16_TO_INT32_N, NOP_N
441 UNPACK_2CH int32, int16, a, 2, 1, INT16_TO_INT32_N, NOP_N
442 UNPACK_2CH float, int16, u, 2, 1, INT16_TO_FLOAT_N, INT16_TO_FLOAT_INIT
443 UNPACK_2CH float, int16, a, 2, 1, INT16_TO_FLOAT_N, INT16_TO_FLOAT_INIT
444
445 INIT_XMM sse4
446 PACK_6CH float, float, u, 2, 2, NOP_N, NOP_N
447 PACK_6CH float, float, a, 2, 2, NOP_N, NOP_N
448
449 PACK_6CH float, int32, u, 2, 2, INT32_TO_FLOAT_N, INT32_TO_FLOAT_INIT
450 PACK_6CH float, int32, a, 2, 2, INT32_TO_FLOAT_N, INT32_TO_FLOAT_INIT
451 PACK_6CH int32, float, u, 2, 2, FLOAT_TO_INT32_N, FLOAT_TO_INT32_INIT
452 PACK_6CH int32, float, a, 2, 2, FLOAT_TO_INT32_N, FLOAT_TO_INT32_INIT
453
454 %if HAVE_AVX_EXTERNAL
455 INIT_XMM avx
456 PACK_6CH float, float, u, 2, 2, NOP_N, NOP_N
457 PACK_6CH float, float, a, 2, 2, NOP_N, NOP_N
458
459 PACK_6CH float, int32, u, 2, 2, INT32_TO_FLOAT_N, INT32_TO_FLOAT_INIT
460 PACK_6CH float, int32, a, 2, 2, INT32_TO_FLOAT_N, INT32_TO_FLOAT_INIT
461 PACK_6CH int32, float, u, 2, 2, FLOAT_TO_INT32_N, FLOAT_TO_INT32_INIT
462 PACK_6CH int32, float, a, 2, 2, FLOAT_TO_INT32_N, FLOAT_TO_INT32_INIT
463
464 INIT_YMM avx
465 CONV float, int32, u, 2, 2, INT32_TO_FLOAT_N, INT32_TO_FLOAT_INIT
466 CONV float, int32, a, 2, 2, INT32_TO_FLOAT_N, INT32_TO_FLOAT_INIT
467 %endif