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