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