]> git.sesse.net Git - ffmpeg/blob - libswresample/x86/audio_convert.asm
Merge commit '6516632967da5e6bd7d6136e8678f826669ed26e'
[ffmpeg] / 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 %if mmsize == 8
199     emms
200     RET
201 %else
202     REP_RET
203 %endif
204 %endmacro
205
206 %macro PACK_6CH 5-7
207 cglobal pack_6ch_%2_to_%1_%3, 2,8,7, dst, src, src1, src2, src3, src4, src5, len
208 %if ARCH_X86_64
209     mov     lend, r2d
210 %else
211     %define lend dword r2m
212 %endif
213     mov    src1q, [srcq+1*gprsize]
214     mov    src2q, [srcq+2*gprsize]
215     mov    src3q, [srcq+3*gprsize]
216     mov    src4q, [srcq+4*gprsize]
217     mov    src5q, [srcq+5*gprsize]
218     mov     srcq, [srcq]
219     mov     dstq, [dstq]
220 %ifidn %3, a
221     test dstq, mmsize-1
222         jne pack_6ch_%2_to_%1_u_int %+ SUFFIX
223     test srcq, mmsize-1
224         jne pack_6ch_%2_to_%1_u_int %+ SUFFIX
225     test src2q, mmsize-1
226         jne pack_6ch_%2_to_%1_u_int %+ SUFFIX
227     test src3q, mmsize-1
228         jne pack_6ch_%2_to_%1_u_int %+ SUFFIX
229     test src4q, mmsize-1
230         jne pack_6ch_%2_to_%1_u_int %+ SUFFIX
231     test src5q, mmsize-1
232         jne pack_6ch_%2_to_%1_u_int %+ SUFFIX
233 %else
234 pack_6ch_%2_to_%1_u_int %+ SUFFIX
235 %endif
236     sub    src1q, srcq
237     sub    src2q, srcq
238     sub    src3q, srcq
239     sub    src4q, srcq
240     sub    src5q, srcq
241 .loop:
242     mov%3     m0, [srcq      ]
243     mov%3     m1, [srcq+src1q]
244     mov%3     m2, [srcq+src2q]
245     mov%3     m3, [srcq+src3q]
246     mov%3     m4, [srcq+src4q]
247     mov%3     m5, [srcq+src5q]
248     %7 x,x,x,x,m7,x
249 %if cpuflag(sse4)
250     SBUTTERFLYPS 0, 1, 6
251     SBUTTERFLYPS 2, 3, 6
252     SBUTTERFLYPS 4, 5, 6
253
254     blendps   m6, m4, m0, 1100b
255     movlhps   m0, m2
256     movhlps   m4, m2
257     blendps   m2, m5, m1, 1100b
258     movlhps   m1, m3
259     movhlps   m5, m3
260
261     %6 m0,m6,x,x,m7,m3
262     %6 m4,m1,x,x,m7,m3
263     %6 m2,m5,x,x,m7,m3
264
265     mov %+ %3 %+ ps [dstq   ], m0
266     mov %+ %3 %+ ps [dstq+16], m6
267     mov %+ %3 %+ ps [dstq+32], m4
268     mov %+ %3 %+ ps [dstq+48], m1
269     mov %+ %3 %+ ps [dstq+64], m2
270     mov %+ %3 %+ ps [dstq+80], m5
271 %else ; mmx
272     SBUTTERFLY dq, 0, 1, 6
273     SBUTTERFLY dq, 2, 3, 6
274     SBUTTERFLY dq, 4, 5, 6
275
276     movq   [dstq   ], m0
277     movq   [dstq+ 8], m2
278     movq   [dstq+16], m4
279     movq   [dstq+24], m1
280     movq   [dstq+32], m3
281     movq   [dstq+40], m5
282 %endif
283     add      srcq, mmsize
284     add      dstq, mmsize*6
285     sub      lend, mmsize/4
286     jg .loop
287 %if mmsize == 8
288     emms
289     RET
290 %else
291     REP_RET
292 %endif
293 %endmacro
294
295 %macro INT16_TO_INT32_N 6
296     pxor      m2, m2
297     pxor      m3, m3
298     punpcklwd m2, m1
299     punpckhwd m3, m1
300     SWAP 4,0
301     pxor      m0, m0
302     pxor      m1, m1
303     punpcklwd m0, m4
304     punpckhwd m1, m4
305 %endmacro
306
307 %macro INT32_TO_INT16_N 6
308     psrad     m0, 16
309     psrad     m1, 16
310     psrad     m2, 16
311     psrad     m3, 16
312     packssdw  m0, m1
313     packssdw  m2, m3
314     SWAP 1,2
315 %endmacro
316
317 %macro INT32_TO_FLOAT_INIT 6
318     mova      %5, [flt2pm31]
319 %endmacro
320 %macro INT32_TO_FLOAT_N 6
321     cvtdq2ps  %1, %1
322     cvtdq2ps  %2, %2
323     mulps %1, %1, %5
324     mulps %2, %2, %5
325 %endmacro
326
327 %macro FLOAT_TO_INT32_INIT 6
328     mova      %5, [flt2p31]
329 %endmacro
330 %macro FLOAT_TO_INT32_N 6
331     mulps %1, %5
332     mulps %2, %5
333     cvtps2dq  %6, %1
334     cmpnltps %1, %5
335     paddd %1, %6
336     cvtps2dq  %6, %2
337     cmpnltps %2, %5
338     paddd %2, %6
339 %endmacro
340
341 %macro INT16_TO_FLOAT_INIT 6
342     mova      m5, [flt2pm31]
343 %endmacro
344 %macro INT16_TO_FLOAT_N 6
345     INT16_TO_INT32_N %1,%2,%3,%4,%5,%6
346     cvtdq2ps  m0, m0
347     cvtdq2ps  m1, m1
348     cvtdq2ps  m2, m2
349     cvtdq2ps  m3, m3
350     mulps m0, m0, m5
351     mulps m1, m1, m5
352     mulps m2, m2, m5
353     mulps m3, m3, m5
354 %endmacro
355
356 %macro FLOAT_TO_INT16_INIT 6
357     mova      m5, [flt2p15]
358 %endmacro
359 %macro FLOAT_TO_INT16_N 6
360     mulps m0, m5
361     mulps m1, m5
362     mulps m2, m5
363     mulps m3, m5
364     cvtps2dq  m0, m0
365     cvtps2dq  m1, m1
366     packssdw  m0, m1
367     cvtps2dq  m1, m2
368     cvtps2dq  m3, m3
369     packssdw  m1, m3
370 %endmacro
371
372 %macro NOP_N 0-6
373 %endmacro
374
375 INIT_MMX mmx
376 CONV int32, int16, u, 2, 1, INT16_TO_INT32_N, NOP_N
377 CONV int32, int16, a, 2, 1, INT16_TO_INT32_N, NOP_N
378 CONV int16, int32, u, 1, 2, INT32_TO_INT16_N, NOP_N
379 CONV int16, int32, a, 1, 2, INT32_TO_INT16_N, NOP_N
380
381 PACK_6CH float, float, u, 2, 2, NOP_N, NOP_N
382 PACK_6CH float, float, a, 2, 2, NOP_N, NOP_N
383
384 INIT_XMM sse2
385 CONV int32, int16, u, 2, 1, INT16_TO_INT32_N, NOP_N
386 CONV int32, int16, a, 2, 1, INT16_TO_INT32_N, NOP_N
387 CONV int16, int32, u, 1, 2, INT32_TO_INT16_N, NOP_N
388 CONV int16, int32, a, 1, 2, INT32_TO_INT16_N, NOP_N
389
390 PACK_2CH int16, int16, u, 1, 1, NOP_N, NOP_N
391 PACK_2CH int16, int16, a, 1, 1, NOP_N, NOP_N
392 PACK_2CH int32, int32, u, 2, 2, NOP_N, NOP_N
393 PACK_2CH int32, int32, a, 2, 2, NOP_N, NOP_N
394 PACK_2CH int32, int16, u, 2, 1, INT16_TO_INT32_N, NOP_N
395 PACK_2CH int32, int16, a, 2, 1, INT16_TO_INT32_N, NOP_N
396 PACK_2CH int16, int32, u, 1, 2, INT32_TO_INT16_N, NOP_N
397 PACK_2CH int16, int32, a, 1, 2, INT32_TO_INT16_N, NOP_N
398
399 UNPACK_2CH int16, int16, u, 1, 1, NOP_N, NOP_N
400 UNPACK_2CH int16, int16, a, 1, 1, NOP_N, NOP_N
401 UNPACK_2CH int32, int32, u, 2, 2, NOP_N, NOP_N
402 UNPACK_2CH int32, int32, a, 2, 2, NOP_N, NOP_N
403 UNPACK_2CH int32, int16, u, 2, 1, INT16_TO_INT32_N, NOP_N
404 UNPACK_2CH int32, int16, a, 2, 1, INT16_TO_INT32_N, NOP_N
405 UNPACK_2CH int16, int32, u, 1, 2, INT32_TO_INT16_N, NOP_N
406 UNPACK_2CH int16, int32, a, 1, 2, INT32_TO_INT16_N, NOP_N
407
408 CONV float, int32, u, 2, 2, INT32_TO_FLOAT_N, INT32_TO_FLOAT_INIT
409 CONV float, int32, a, 2, 2, INT32_TO_FLOAT_N, INT32_TO_FLOAT_INIT
410 CONV int32, float, u, 2, 2, FLOAT_TO_INT32_N, FLOAT_TO_INT32_INIT
411 CONV int32, float, a, 2, 2, FLOAT_TO_INT32_N, FLOAT_TO_INT32_INIT
412 CONV float, int16, u, 2, 1, INT16_TO_FLOAT_N, INT16_TO_FLOAT_INIT
413 CONV float, int16, a, 2, 1, INT16_TO_FLOAT_N, INT16_TO_FLOAT_INIT
414 CONV int16, float, u, 1, 2, FLOAT_TO_INT16_N, FLOAT_TO_INT16_INIT
415 CONV int16, float, a, 1, 2, FLOAT_TO_INT16_N, FLOAT_TO_INT16_INIT
416
417 PACK_2CH float, int32, u, 2, 2, INT32_TO_FLOAT_N, INT32_TO_FLOAT_INIT
418 PACK_2CH float, int32, a, 2, 2, INT32_TO_FLOAT_N, INT32_TO_FLOAT_INIT
419 PACK_2CH int32, float, u, 2, 2, FLOAT_TO_INT32_N, FLOAT_TO_INT32_INIT
420 PACK_2CH int32, float, a, 2, 2, FLOAT_TO_INT32_N, FLOAT_TO_INT32_INIT
421 PACK_2CH float, int16, u, 2, 1, INT16_TO_FLOAT_N, INT16_TO_FLOAT_INIT
422 PACK_2CH float, int16, a, 2, 1, INT16_TO_FLOAT_N, INT16_TO_FLOAT_INIT
423 PACK_2CH int16, float, u, 1, 2, FLOAT_TO_INT16_N, FLOAT_TO_INT16_INIT
424 PACK_2CH int16, float, a, 1, 2, FLOAT_TO_INT16_N, FLOAT_TO_INT16_INIT
425
426 UNPACK_2CH float, int32, u, 2, 2, INT32_TO_FLOAT_N, INT32_TO_FLOAT_INIT
427 UNPACK_2CH float, int32, a, 2, 2, INT32_TO_FLOAT_N, INT32_TO_FLOAT_INIT
428 UNPACK_2CH int32, float, u, 2, 2, FLOAT_TO_INT32_N, FLOAT_TO_INT32_INIT
429 UNPACK_2CH int32, float, a, 2, 2, FLOAT_TO_INT32_N, FLOAT_TO_INT32_INIT
430 UNPACK_2CH float, int16, u, 2, 1, INT16_TO_FLOAT_N, INT16_TO_FLOAT_INIT
431 UNPACK_2CH float, int16, a, 2, 1, INT16_TO_FLOAT_N, INT16_TO_FLOAT_INIT
432 UNPACK_2CH int16, float, u, 1, 2, FLOAT_TO_INT16_N, FLOAT_TO_INT16_INIT
433 UNPACK_2CH int16, float, a, 1, 2, FLOAT_TO_INT16_N, FLOAT_TO_INT16_INIT
434
435
436 INIT_XMM ssse3
437 UNPACK_2CH int16, int16, u, 1, 1, NOP_N, NOP_N
438 UNPACK_2CH int16, int16, a, 1, 1, NOP_N, NOP_N
439 UNPACK_2CH int32, int16, u, 2, 1, INT16_TO_INT32_N, NOP_N
440 UNPACK_2CH int32, int16, a, 2, 1, INT16_TO_INT32_N, NOP_N
441 UNPACK_2CH float, int16, u, 2, 1, INT16_TO_FLOAT_N, INT16_TO_FLOAT_INIT
442 UNPACK_2CH float, int16, a, 2, 1, INT16_TO_FLOAT_N, INT16_TO_FLOAT_INIT
443
444 INIT_XMM sse4
445 PACK_6CH float, float, u, 2, 2, NOP_N, NOP_N
446 PACK_6CH float, float, a, 2, 2, NOP_N, NOP_N
447
448 PACK_6CH float, int32, u, 2, 2, INT32_TO_FLOAT_N, INT32_TO_FLOAT_INIT
449 PACK_6CH float, int32, a, 2, 2, INT32_TO_FLOAT_N, INT32_TO_FLOAT_INIT
450 PACK_6CH int32, float, u, 2, 2, FLOAT_TO_INT32_N, FLOAT_TO_INT32_INIT
451 PACK_6CH int32, float, a, 2, 2, FLOAT_TO_INT32_N, FLOAT_TO_INT32_INIT
452
453 %if HAVE_AVX_EXTERNAL
454 INIT_XMM avx
455 PACK_6CH float, float, u, 2, 2, NOP_N, NOP_N
456 PACK_6CH float, float, a, 2, 2, NOP_N, NOP_N
457
458 PACK_6CH float, int32, u, 2, 2, INT32_TO_FLOAT_N, INT32_TO_FLOAT_INIT
459 PACK_6CH float, int32, a, 2, 2, INT32_TO_FLOAT_N, INT32_TO_FLOAT_INIT
460 PACK_6CH int32, float, u, 2, 2, FLOAT_TO_INT32_N, FLOAT_TO_INT32_INIT
461 PACK_6CH int32, float, a, 2, 2, FLOAT_TO_INT32_N, FLOAT_TO_INT32_INIT
462
463 INIT_YMM avx
464 CONV float, int32, u, 2, 2, INT32_TO_FLOAT_N, INT32_TO_FLOAT_INIT
465 CONV float, int32, a, 2, 2, INT32_TO_FLOAT_N, INT32_TO_FLOAT_INIT
466 %endif