1af1429bae632f62d67613a9ae98eea278ab21d2
[ffmpeg.git] / libavresample / x86 / audio_convert.asm
1 ;******************************************************************************
2 ;* x86 optimized Format Conversion Utils
3 ;* Copyright (c) 2008 Loren Merritt
4 ;* Copyright (c) 2012 Justin Ruggles <justin.ruggles@gmail.com>
5 ;*
6 ;* This file is part of Libav.
7 ;*
8 ;* Libav is free software; you can redistribute it and/or
9 ;* modify it under the terms of the GNU Lesser General Public
10 ;* License as published by the Free Software Foundation; either
11 ;* version 2.1 of the License, or (at your option) any later version.
12 ;*
13 ;* Libav is distributed in the hope that it will be useful,
14 ;* but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16 ;* Lesser General Public License for more details.
17 ;*
18 ;* You should have received a copy of the GNU Lesser General Public
19 ;* License along with Libav; if not, write to the Free Software
20 ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 ;******************************************************************************
22
23 %include "libavutil/x86/x86util.asm"
24 %include "util.asm"
25
26 SECTION_RODATA 32
27
28 pf_s32_inv_scale: times 8 dd 0x30000000
29 pf_s32_scale:     times 8 dd 0x4f000000
30 pf_s32_clip:      times 8 dd 0x4effffff
31 pf_s16_inv_scale: times 4 dd 0x38000000
32 pf_s16_scale:     times 4 dd 0x47000000
33 pb_shuf_unpack_even:      db -1, -1,  0,  1, -1, -1,  2,  3, -1, -1,  8,  9, -1, -1, 10, 11
34 pb_shuf_unpack_odd:       db -1, -1,  4,  5, -1, -1,  6,  7, -1, -1, 12, 13, -1, -1, 14, 15
35 pb_interleave_words: SHUFFLE_MASK_W  0,  4,  1,  5,  2,  6,  3,  7
36 pb_deinterleave_words: SHUFFLE_MASK_W  0,  2,  4,  6,  1,  3,  5,  7
37 pw_zero_even:     times 4 dw 0x0000, 0xffff
38
39 SECTION_TEXT
40
41 ;------------------------------------------------------------------------------
42 ; void ff_conv_s16_to_s32(int32_t *dst, const int16_t *src, int len);
43 ;------------------------------------------------------------------------------
44
45 INIT_XMM sse2
46 cglobal conv_s16_to_s32, 3,3,3, dst, src, len
47     lea      lenq, [2*lend]
48     lea      dstq, [dstq+2*lenq]
49     add      srcq, lenq
50     neg      lenq
51 .loop:
52     mova       m2, [srcq+lenq]
53     pxor       m0, m0
54     pxor       m1, m1
55     punpcklwd  m0, m2
56     punpckhwd  m1, m2
57     mova  [dstq+2*lenq       ], m0
58     mova  [dstq+2*lenq+mmsize], m1
59     add      lenq, mmsize
60     jl .loop
61     REP_RET
62
63 ;------------------------------------------------------------------------------
64 ; void ff_conv_s16_to_flt(float *dst, const int16_t *src, int len);
65 ;------------------------------------------------------------------------------
66
67 %macro CONV_S16_TO_FLT 0
68 cglobal conv_s16_to_flt, 3,3,3, dst, src, len
69     lea      lenq, [2*lend]
70     add      srcq, lenq
71     lea      dstq, [dstq + 2*lenq]
72     neg      lenq
73     mova       m2, [pf_s16_inv_scale]
74     ALIGN 16
75 .loop:
76     mova       m0, [srcq+lenq]
77     S16_TO_S32_SX 0, 1
78     cvtdq2ps   m0, m0
79     cvtdq2ps   m1, m1
80     mulps      m0, m2
81     mulps      m1, m2
82     mova  [dstq+2*lenq       ], m0
83     mova  [dstq+2*lenq+mmsize], m1
84     add      lenq, mmsize
85     jl .loop
86     REP_RET
87 %endmacro
88
89 INIT_XMM sse2
90 CONV_S16_TO_FLT
91 INIT_XMM sse4
92 CONV_S16_TO_FLT
93
94 ;------------------------------------------------------------------------------
95 ; void ff_conv_s32_to_s16(int16_t *dst, const int32_t *src, int len);
96 ;------------------------------------------------------------------------------
97
98 %macro CONV_S32_TO_S16 0
99 cglobal conv_s32_to_s16, 3,3,4, dst, src, len
100     lea     lenq, [2*lend]
101     lea     srcq, [srcq+2*lenq]
102     add     dstq, lenq
103     neg     lenq
104 .loop:
105     mova      m0, [srcq+2*lenq         ]
106     mova      m1, [srcq+2*lenq+  mmsize]
107     mova      m2, [srcq+2*lenq+2*mmsize]
108     mova      m3, [srcq+2*lenq+3*mmsize]
109     psrad     m0, 16
110     psrad     m1, 16
111     psrad     m2, 16
112     psrad     m3, 16
113     packssdw  m0, m1
114     packssdw  m2, m3
115     mova  [dstq+lenq       ], m0
116     mova  [dstq+lenq+mmsize], m2
117     add     lenq, mmsize*2
118     jl .loop
119 %if mmsize == 8
120     emms
121     RET
122 %else
123     REP_RET
124 %endif
125 %endmacro
126
127 INIT_MMX mmx
128 CONV_S32_TO_S16
129 INIT_XMM sse2
130 CONV_S32_TO_S16
131
132 ;------------------------------------------------------------------------------
133 ; void ff_conv_s32_to_flt(float *dst, const int32_t *src, int len);
134 ;------------------------------------------------------------------------------
135
136 %macro CONV_S32_TO_FLT 0
137 cglobal conv_s32_to_flt, 3,3,3, dst, src, len
138     lea     lenq, [4*lend]
139     add     srcq, lenq
140     add     dstq, lenq
141     neg     lenq
142     mova      m0, [pf_s32_inv_scale]
143     ALIGN 16
144 .loop:
145     cvtdq2ps  m1, [srcq+lenq       ]
146     cvtdq2ps  m2, [srcq+lenq+mmsize]
147     mulps     m1, m1, m0
148     mulps     m2, m2, m0
149     mova  [dstq+lenq       ], m1
150     mova  [dstq+lenq+mmsize], m2
151     add     lenq, mmsize*2
152     jl .loop
153     REP_RET
154 %endmacro
155
156 INIT_XMM sse2
157 CONV_S32_TO_FLT
158 INIT_YMM avx
159 CONV_S32_TO_FLT
160
161 ;------------------------------------------------------------------------------
162 ; void ff_conv_flt_to_s16(int16_t *dst, const float *src, int len);
163 ;------------------------------------------------------------------------------
164
165 INIT_XMM sse2
166 cglobal conv_flt_to_s16, 3,3,5, dst, src, len
167     lea     lenq, [2*lend]
168     lea     srcq, [srcq+2*lenq]
169     add     dstq, lenq
170     neg     lenq
171     mova      m4, [pf_s16_scale]
172 .loop:
173     mova      m0, [srcq+2*lenq         ]
174     mova      m1, [srcq+2*lenq+1*mmsize]
175     mova      m2, [srcq+2*lenq+2*mmsize]
176     mova      m3, [srcq+2*lenq+3*mmsize]
177     mulps     m0, m4
178     mulps     m1, m4
179     mulps     m2, m4
180     mulps     m3, m4
181     cvtps2dq  m0, m0
182     cvtps2dq  m1, m1
183     cvtps2dq  m2, m2
184     cvtps2dq  m3, m3
185     packssdw  m0, m1
186     packssdw  m2, m3
187     mova  [dstq+lenq       ], m0
188     mova  [dstq+lenq+mmsize], m2
189     add     lenq, mmsize*2
190     jl .loop
191     REP_RET
192
193 ;------------------------------------------------------------------------------
194 ; void ff_conv_flt_to_s32(int32_t *dst, const float *src, int len);
195 ;------------------------------------------------------------------------------
196
197 %macro CONV_FLT_TO_S32 0
198 cglobal conv_flt_to_s32, 3,3,6, dst, src, len
199     lea     lenq, [lend*4]
200     add     srcq, lenq
201     add     dstq, lenq
202     neg     lenq
203     mova      m4, [pf_s32_scale]
204     mova      m5, [pf_s32_clip]
205 .loop:
206     mulps     m0, m4, [srcq+lenq         ]
207     mulps     m1, m4, [srcq+lenq+1*mmsize]
208     mulps     m2, m4, [srcq+lenq+2*mmsize]
209     mulps     m3, m4, [srcq+lenq+3*mmsize]
210     minps     m0, m0, m5
211     minps     m1, m1, m5
212     minps     m2, m2, m5
213     minps     m3, m3, m5
214     cvtps2dq  m0, m0
215     cvtps2dq  m1, m1
216     cvtps2dq  m2, m2
217     cvtps2dq  m3, m3
218     mova  [dstq+lenq         ], m0
219     mova  [dstq+lenq+1*mmsize], m1
220     mova  [dstq+lenq+2*mmsize], m2
221     mova  [dstq+lenq+3*mmsize], m3
222     add     lenq, mmsize*4
223     jl .loop
224     REP_RET
225 %endmacro
226
227 INIT_XMM sse2
228 CONV_FLT_TO_S32
229 INIT_YMM avx
230 CONV_FLT_TO_S32
231
232 ;------------------------------------------------------------------------------
233 ; void ff_conv_s16p_to_s16_2ch(int16_t *dst, int16_t *const *src, int len,
234 ;                              int channels);
235 ;------------------------------------------------------------------------------
236
237 %macro CONV_S16P_TO_S16_2CH 0
238 cglobal conv_s16p_to_s16_2ch, 3,4,5, dst, src0, len, src1
239     mov       src1q, [src0q+gprsize]
240     mov       src0q, [src0q        ]
241     lea        lenq, [2*lend]
242     add       src0q, lenq
243     add       src1q, lenq
244     lea        dstq, [dstq+2*lenq]
245     neg        lenq
246 .loop:
247     mova         m0, [src0q+lenq       ]
248     mova         m1, [src1q+lenq       ]
249     mova         m2, [src0q+lenq+mmsize]
250     mova         m3, [src1q+lenq+mmsize]
251     SBUTTERFLY2  wd, 0, 1, 4
252     SBUTTERFLY2  wd, 2, 3, 4
253     mova  [dstq+2*lenq+0*mmsize], m0
254     mova  [dstq+2*lenq+1*mmsize], m1
255     mova  [dstq+2*lenq+2*mmsize], m2
256     mova  [dstq+2*lenq+3*mmsize], m3
257     add        lenq, 2*mmsize
258     jl .loop
259     REP_RET
260 %endmacro
261
262 INIT_XMM sse2
263 CONV_S16P_TO_S16_2CH
264 INIT_XMM avx
265 CONV_S16P_TO_S16_2CH
266
267 ;------------------------------------------------------------------------------
268 ; void ff_conv_s16p_to_s16_6ch(int16_t *dst, int16_t *const *src, int len,
269 ;                              int channels);
270 ;------------------------------------------------------------------------------
271
272 ;------------------------------------------------------------------------------
273 ; NOTE: In the 6-channel functions, len could be used as an index on x86-64
274 ;       instead of just a counter, which would avoid incrementing the
275 ;       pointers, but the extra complexity and amount of code is not worth
276 ;       the small gain. On x86-32 there are not enough registers to use len
277 ;       as an index without keeping two of the pointers on the stack and
278 ;       loading them in each iteration.
279 ;------------------------------------------------------------------------------
280
281 %macro CONV_S16P_TO_S16_6CH 0
282 %if ARCH_X86_64
283 cglobal conv_s16p_to_s16_6ch, 3,8,7, dst, src0, len, src1, src2, src3, src4, src5
284 %else
285 cglobal conv_s16p_to_s16_6ch, 2,7,7, dst, src0, src1, src2, src3, src4, src5
286 %define lend dword r2m
287 %endif
288     mov      src1q, [src0q+1*gprsize]
289     mov      src2q, [src0q+2*gprsize]
290     mov      src3q, [src0q+3*gprsize]
291     mov      src4q, [src0q+4*gprsize]
292     mov      src5q, [src0q+5*gprsize]
293     mov      src0q, [src0q]
294     sub      src1q, src0q
295     sub      src2q, src0q
296     sub      src3q, src0q
297     sub      src4q, src0q
298     sub      src5q, src0q
299 .loop:
300 %if cpuflag(sse2slow)
301     movq        m0, [src0q      ]   ; m0 =  0,  6, 12, 18,  x,  x,  x,  x
302     movq        m1, [src0q+src1q]   ; m1 =  1,  7, 13, 19,  x,  x,  x,  x
303     movq        m2, [src0q+src2q]   ; m2 =  2,  8, 14, 20,  x,  x,  x,  x
304     movq        m3, [src0q+src3q]   ; m3 =  3,  9, 15, 21,  x,  x,  x,  x
305     movq        m4, [src0q+src4q]   ; m4 =  4, 10, 16, 22,  x,  x,  x,  x
306     movq        m5, [src0q+src5q]   ; m5 =  5, 11, 17, 23,  x,  x,  x,  x
307                                     ; unpack words:
308     punpcklwd   m0, m1              ; m0 =  0,  1,  6,  7, 12, 13, 18, 19
309     punpcklwd   m2, m3              ; m2 =  4,  5, 10, 11, 16, 17, 22, 23
310     punpcklwd   m4, m5              ; m4 =  2,  3,  8,  9, 14, 15, 20, 21
311                                     ; blend dwords
312     shufps      m1, m0, m2, q2020   ; m1 =  0,  1, 12, 13,  2,  3, 14, 15
313     shufps      m0, m4, q2031       ; m0 =  6,  7, 18, 19,  4,  5, 16, 17
314     shufps      m2, m4, q3131       ; m2 =  8,  9, 20, 21, 10, 11, 22, 23
315                                     ; shuffle dwords
316     pshufd      m0, m0, q1302       ; m0 =  4,  5,  6,  7, 16, 17, 18, 19
317     pshufd      m1, m1, q3120       ; m1 =  0,  1,  2,  3, 12, 13, 14, 15
318     pshufd      m2, m2, q3120       ; m2 =  8,  9, 10, 11, 20, 21, 22, 23
319     movq   [dstq+0*mmsize/2], m1
320     movq   [dstq+1*mmsize/2], m0
321     movq   [dstq+2*mmsize/2], m2
322     movhps [dstq+3*mmsize/2], m1
323     movhps [dstq+4*mmsize/2], m0
324     movhps [dstq+5*mmsize/2], m2
325     add      src0q, mmsize/2
326     add       dstq, mmsize*3
327     sub       lend, mmsize/4
328 %else
329     mova        m0, [src0q      ]   ; m0 =  0,  6, 12, 18, 24, 30, 36, 42
330     mova        m1, [src0q+src1q]   ; m1 =  1,  7, 13, 19, 25, 31, 37, 43
331     mova        m2, [src0q+src2q]   ; m2 =  2,  8, 14, 20, 26, 32, 38, 44
332     mova        m3, [src0q+src3q]   ; m3 =  3,  9, 15, 21, 27, 33, 39, 45
333     mova        m4, [src0q+src4q]   ; m4 =  4, 10, 16, 22, 28, 34, 40, 46
334     mova        m5, [src0q+src5q]   ; m5 =  5, 11, 17, 23, 29, 35, 41, 47
335                                     ; unpack words:
336     SBUTTERFLY2 wd, 0, 1, 6         ; m0 =  0,  1,  6,  7, 12, 13, 18, 19
337                                     ; m1 = 24, 25, 30, 31, 36, 37, 42, 43
338     SBUTTERFLY2 wd, 2, 3, 6         ; m2 =  2,  3,  8,  9, 14, 15, 20, 21
339                                     ; m3 = 26, 27, 32, 33, 38, 39, 44, 45
340     SBUTTERFLY2 wd, 4, 5, 6         ; m4 =  4,  5, 10, 11, 16, 17, 22, 23
341                                     ; m5 = 28, 29, 34, 35, 40, 41, 46, 47
342                                     ; blend dwords
343     shufps      m6, m0, m2, q2020   ; m6 =  0,  1, 12, 13,  2,  3, 14, 15
344     shufps      m0, m4, q2031       ; m0 =  6,  7, 18, 19,  4,  5, 16, 17
345     shufps      m2, m4, q3131       ; m2 =  8,  9, 20, 21, 10, 11, 22, 23
346     SWAP 4,6                        ; m4 =  0,  1, 12, 13,  2,  3, 14, 15
347     shufps      m6, m1, m3, q2020   ; m6 = 24, 25, 36, 37, 26, 27, 38, 39
348     shufps      m1, m5, q2031       ; m1 = 30, 31, 42, 43, 28, 29, 40, 41
349     shufps      m3, m5, q3131       ; m3 = 32, 33, 44, 45, 34, 35, 46, 47
350     SWAP 5,6                        ; m5 = 24, 25, 36, 37, 26, 27, 38, 39
351                                     ; shuffle dwords
352     pshufd      m0, m0, q1302       ; m0 =  4,  5,  6,  7, 16, 17, 18, 19
353     pshufd      m2, m2, q3120       ; m2 =  8,  9, 10, 11, 20, 21, 22, 23
354     pshufd      m4, m4, q3120       ; m4 =  0,  1,  2,  3, 12, 13, 14, 15
355     pshufd      m1, m1, q1302       ; m1 = 28, 29, 30, 31, 40, 41, 42, 43
356     pshufd      m3, m3, q3120       ; m3 = 32, 33, 34, 35, 44, 45, 46, 47
357     pshufd      m5, m5, q3120       ; m5 = 24, 25, 26, 27, 36, 37, 38, 39
358                                     ; shuffle qwords
359     punpcklqdq  m6, m4, m0          ; m6 =  0,  1,  2,  3,  4,  5,  6,  7
360     punpckhqdq  m0, m2              ; m0 = 16, 17, 18, 19, 20, 21, 22, 23
361     shufps      m2, m4, q3210       ; m2 =  8,  9, 10, 11, 12, 13, 14, 15
362     SWAP 4,6                        ; m4 =  0,  1,  2,  3,  4,  5,  6,  7
363     punpcklqdq  m6, m5, m1          ; m6 = 24, 25, 26, 27, 28, 29, 30, 31
364     punpckhqdq  m1, m3              ; m1 = 40, 41, 42, 43, 44, 45, 46, 47
365     shufps      m3, m5, q3210       ; m3 = 32, 33, 34, 35, 36, 37, 38, 39
366     SWAP 5,6                        ; m5 = 24, 25, 26, 27, 28, 29, 30, 31
367     mova   [dstq+0*mmsize], m4
368     mova   [dstq+1*mmsize], m2
369     mova   [dstq+2*mmsize], m0
370     mova   [dstq+3*mmsize], m5
371     mova   [dstq+4*mmsize], m3
372     mova   [dstq+5*mmsize], m1
373     add      src0q, mmsize
374     add       dstq, mmsize*6
375     sub       lend, mmsize/2
376 %endif
377     jg .loop
378     REP_RET
379 %endmacro
380
381 INIT_XMM sse2
382 CONV_S16P_TO_S16_6CH
383 INIT_XMM sse2slow
384 CONV_S16P_TO_S16_6CH
385 INIT_XMM avx
386 CONV_S16P_TO_S16_6CH
387
388 ;------------------------------------------------------------------------------
389 ; void ff_conv_s16p_to_flt_2ch(float *dst, int16_t *const *src, int len,
390 ;                              int channels);
391 ;------------------------------------------------------------------------------
392
393 %macro CONV_S16P_TO_FLT_2CH 0
394 cglobal conv_s16p_to_flt_2ch, 3,4,6, dst, src0, len, src1
395     lea       lenq, [2*lend]
396     mov      src1q, [src0q+gprsize]
397     mov      src0q, [src0q        ]
398     lea       dstq, [dstq+4*lenq]
399     add      src0q, lenq
400     add      src1q, lenq
401     neg       lenq
402     mova        m5, [pf_s32_inv_scale]
403 .loop:
404     mova        m2, [src0q+lenq]    ; m2 =  0,  2,  4,  6,  8, 10, 12, 14
405     mova        m4, [src1q+lenq]    ; m4 =  1,  3,  5,  7,  9, 11, 13, 15
406     SBUTTERFLY2 wd, 2, 4, 3         ; m2 =  0,  1,  2,  3,  4,  5,  6,  7
407                                     ; m4 =  8,  9, 10, 11, 12, 13, 14, 15
408     pxor        m3, m3
409     punpcklwd   m0, m3, m2          ; m0 =      0,      1,      2,      3
410     punpckhwd   m1, m3, m2          ; m1 =      4,      5,      6,      7
411     punpcklwd   m2, m3, m4          ; m2 =      8,      9,     10,     11
412     punpckhwd   m3, m4              ; m3 =     12,     13,     14,     15
413     cvtdq2ps    m0, m0
414     cvtdq2ps    m1, m1
415     cvtdq2ps    m2, m2
416     cvtdq2ps    m3, m3
417     mulps       m0, m5
418     mulps       m1, m5
419     mulps       m2, m5
420     mulps       m3, m5
421     mova  [dstq+4*lenq         ], m0
422     mova  [dstq+4*lenq+  mmsize], m1
423     mova  [dstq+4*lenq+2*mmsize], m2
424     mova  [dstq+4*lenq+3*mmsize], m3
425     add       lenq, mmsize
426     jl .loop
427     REP_RET
428 %endmacro
429
430 INIT_XMM sse2
431 CONV_S16P_TO_FLT_2CH
432 INIT_XMM avx
433 CONV_S16P_TO_FLT_2CH
434
435 ;------------------------------------------------------------------------------
436 ; void ff_conv_s16p_to_flt_6ch(float *dst, int16_t *const *src, int len,
437 ;                              int channels);
438 ;------------------------------------------------------------------------------
439
440 %macro CONV_S16P_TO_FLT_6CH 0
441 %if ARCH_X86_64
442 cglobal conv_s16p_to_flt_6ch, 3,8,8, dst, src, len, src1, src2, src3, src4, src5
443 %else
444 cglobal conv_s16p_to_flt_6ch, 2,7,8, dst, src, src1, src2, src3, src4, src5
445 %define lend dword r2m
446 %endif
447     mov     src1q, [srcq+1*gprsize]
448     mov     src2q, [srcq+2*gprsize]
449     mov     src3q, [srcq+3*gprsize]
450     mov     src4q, [srcq+4*gprsize]
451     mov     src5q, [srcq+5*gprsize]
452     mov      srcq, [srcq]
453     sub     src1q, srcq
454     sub     src2q, srcq
455     sub     src3q, srcq
456     sub     src4q, srcq
457     sub     src5q, srcq
458     mova       m7, [pf_s32_inv_scale]
459 %if cpuflag(ssse3)
460     %define unpack_even m6
461     mova       m6, [pb_shuf_unpack_even]
462 %if ARCH_X86_64
463     %define unpack_odd m8
464     mova       m8, [pb_shuf_unpack_odd]
465 %else
466     %define unpack_odd [pb_shuf_unpack_odd]
467 %endif
468 %endif
469 .loop:
470     movq       m0, [srcq      ]  ; m0 =  0,  6, 12, 18,  x,  x,  x,  x
471     movq       m1, [srcq+src1q]  ; m1 =  1,  7, 13, 19,  x,  x,  x,  x
472     movq       m2, [srcq+src2q]  ; m2 =  2,  8, 14, 20,  x,  x,  x,  x
473     movq       m3, [srcq+src3q]  ; m3 =  3,  9, 15, 21,  x,  x,  x,  x
474     movq       m4, [srcq+src4q]  ; m4 =  4, 10, 16, 22,  x,  x,  x,  x
475     movq       m5, [srcq+src5q]  ; m5 =  5, 11, 17, 23,  x,  x,  x,  x
476                                  ; unpack words:
477     punpcklwd  m0, m1            ; m0 =  0,  1,  6,  7, 12, 13, 18, 19
478     punpcklwd  m2, m3            ; m2 =  2,  3,  8,  9, 14, 15, 20, 21
479     punpcklwd  m4, m5            ; m4 =  4,  5, 10, 11, 16, 17, 22, 23
480                                  ; blend dwords
481     shufps     m1, m4, m0, q3120 ; m1 =  4,  5, 16, 17,  6,  7, 18, 19
482     shufps         m0, m2, q2020 ; m0 =  0,  1, 12, 13,  2,  3, 14, 15
483     shufps         m2, m4, q3131 ; m2 =  8,  9, 20, 21, 10, 11, 22, 23
484 %if cpuflag(ssse3)
485     pshufb     m3, m0, unpack_odd   ; m3 =  12,     13,     14,     15
486     pshufb         m0, unpack_even  ; m0 =   0,      1,      2,      3
487     pshufb     m4, m1, unpack_odd   ; m4 =  16,     17,     18,     19
488     pshufb         m1, unpack_even  ; m1 =   4,      5,      6,      7
489     pshufb     m5, m2, unpack_odd   ; m5 =  20,     21,     22,     23
490     pshufb         m2, unpack_even  ; m2 =   8,      9,     10,     11
491 %else
492                                  ; shuffle dwords
493     pshufd     m0, m0, q3120     ; m0 =  0,  1,  2,  3, 12, 13, 14, 15
494     pshufd     m1, m1, q3120     ; m1 =  4,  5,  6,  7, 16, 17, 18, 19
495     pshufd     m2, m2, q3120     ; m2 =  8,  9, 10, 11, 20, 21, 22, 23
496     pxor       m6, m6            ; convert s16 in m0-m2 to s32 in m0-m5
497     punpcklwd  m3, m6, m0        ; m3 =      0,      1,      2,      3
498     punpckhwd  m4, m6, m0        ; m4 =     12,     13,     14,     15
499     punpcklwd  m0, m6, m1        ; m0 =      4,      5,      6,      7
500     punpckhwd  m5, m6, m1        ; m5 =     16,     17,     18,     19
501     punpcklwd  m1, m6, m2        ; m1 =      8,      9,     10,     11
502     punpckhwd      m6, m2        ; m6 =     20,     21,     22,     23
503     SWAP 6,2,1,0,3,4,5           ; swap registers 3,0,1,4,5,6 to 0,1,2,3,4,5
504 %endif
505     cvtdq2ps   m0, m0            ; convert s32 to float
506     cvtdq2ps   m1, m1
507     cvtdq2ps   m2, m2
508     cvtdq2ps   m3, m3
509     cvtdq2ps   m4, m4
510     cvtdq2ps   m5, m5
511     mulps      m0, m7            ; scale float from s32 range to [-1.0,1.0]
512     mulps      m1, m7
513     mulps      m2, m7
514     mulps      m3, m7
515     mulps      m4, m7
516     mulps      m5, m7
517     mova  [dstq         ], m0
518     mova  [dstq+  mmsize], m1
519     mova  [dstq+2*mmsize], m2
520     mova  [dstq+3*mmsize], m3
521     mova  [dstq+4*mmsize], m4
522     mova  [dstq+5*mmsize], m5
523     add      srcq, mmsize/2
524     add      dstq, mmsize*6
525     sub      lend, mmsize/4
526     jg .loop
527     REP_RET
528 %endmacro
529
530 INIT_XMM sse2
531 CONV_S16P_TO_FLT_6CH
532 INIT_XMM ssse3
533 CONV_S16P_TO_FLT_6CH
534 INIT_XMM avx
535 CONV_S16P_TO_FLT_6CH
536
537 ;------------------------------------------------------------------------------
538 ; void ff_conv_fltp_to_s16_2ch(int16_t *dst, float *const *src, int len,
539 ;                              int channels);
540 ;------------------------------------------------------------------------------
541
542 %macro CONV_FLTP_TO_S16_2CH 0
543 cglobal conv_fltp_to_s16_2ch, 3,4,3, dst, src0, len, src1
544     lea      lenq, [4*lend]
545     mov     src1q, [src0q+gprsize]
546     mov     src0q, [src0q        ]
547     add      dstq, lenq
548     add     src0q, lenq
549     add     src1q, lenq
550     neg      lenq
551     mova       m2, [pf_s16_scale]
552 %if cpuflag(ssse3)
553     mova       m3, [pb_interleave_words]
554 %endif
555 .loop:
556     mulps      m0, m2, [src0q+lenq] ; m0 =    0,    2,    4,    6
557     mulps      m1, m2, [src1q+lenq] ; m1 =    1,    3,    5,    7
558     cvtps2dq   m0, m0
559     cvtps2dq   m1, m1
560 %if cpuflag(ssse3)
561     packssdw   m0, m1               ; m0 = 0, 2, 4, 6, 1, 3, 5, 7
562     pshufb     m0, m3               ; m0 = 0, 1, 2, 3, 4, 5, 6, 7
563 %else
564     packssdw   m0, m0               ; m0 = 0, 2, 4, 6, x, x, x, x
565     packssdw   m1, m1               ; m1 = 1, 3, 5, 7, x, x, x, x
566     punpcklwd  m0, m1               ; m0 = 0, 1, 2, 3, 4, 5, 6, 7
567 %endif
568     mova  [dstq+lenq], m0
569     add      lenq, mmsize
570     jl .loop
571     REP_RET
572 %endmacro
573
574 INIT_XMM sse2
575 CONV_FLTP_TO_S16_2CH
576 INIT_XMM ssse3
577 CONV_FLTP_TO_S16_2CH
578
579 ;------------------------------------------------------------------------------
580 ; void ff_conv_fltp_to_s16_6ch(int16_t *dst, float *const *src, int len,
581 ;                              int channels);
582 ;------------------------------------------------------------------------------
583
584 %macro CONV_FLTP_TO_S16_6CH 0
585 %if ARCH_X86_64
586 cglobal conv_fltp_to_s16_6ch, 3,8,7, dst, src, len, src1, src2, src3, src4, src5
587 %else
588 cglobal conv_fltp_to_s16_6ch, 2,7,7, dst, src, src1, src2, src3, src4, src5
589 %define lend dword r2m
590 %endif
591     mov        src1q, [srcq+1*gprsize]
592     mov        src2q, [srcq+2*gprsize]
593     mov        src3q, [srcq+3*gprsize]
594     mov        src4q, [srcq+4*gprsize]
595     mov        src5q, [srcq+5*gprsize]
596     mov         srcq, [srcq]
597     sub        src1q, srcq
598     sub        src2q, srcq
599     sub        src3q, srcq
600     sub        src4q, srcq
601     sub        src5q, srcq
602     movaps      xmm6, [pf_s16_scale]
603 .loop:
604 %if cpuflag(sse2)
605     mulps         m0, m6, [srcq      ]
606     mulps         m1, m6, [srcq+src1q]
607     mulps         m2, m6, [srcq+src2q]
608     mulps         m3, m6, [srcq+src3q]
609     mulps         m4, m6, [srcq+src4q]
610     mulps         m5, m6, [srcq+src5q]
611     cvtps2dq      m0, m0
612     cvtps2dq      m1, m1
613     cvtps2dq      m2, m2
614     cvtps2dq      m3, m3
615     cvtps2dq      m4, m4
616     cvtps2dq      m5, m5
617     packssdw      m0, m3            ; m0 =  0,  6, 12, 18,  3,  9, 15, 21
618     packssdw      m1, m4            ; m1 =  1,  7, 13, 19,  4, 10, 16, 22
619     packssdw      m2, m5            ; m2 =  2,  8, 14, 20,  5, 11, 17, 23
620                                     ; unpack words:
621     movhlps       m3, m0            ; m3 =  3,  9, 15, 21,  x,  x,  x,  x
622     punpcklwd     m0, m1            ; m0 =  0,  1,  6,  7, 12, 13, 18, 19
623     punpckhwd     m1, m2            ; m1 =  4,  5, 10, 11, 16, 17, 22, 23
624     punpcklwd     m2, m3            ; m2 =  2,  3,  8,  9, 14, 15, 20, 21
625                                     ; blend dwords:
626     shufps        m3, m0, m2, q2020 ; m3 =  0,  1, 12, 13,  2,  3, 14, 15
627     shufps        m0, m1, q2031     ; m0 =  6,  7, 18, 19,  4,  5, 16, 17
628     shufps        m2, m1, q3131     ; m2 =  8,  9, 20, 21, 10, 11, 22, 23
629                                     ; shuffle dwords:
630     shufps        m1, m2, m3, q3120 ; m1 =  8,  9, 10, 11, 12, 13, 14, 15
631     shufps        m3, m0,     q0220 ; m3 =  0,  1,  2,  3,  4,  5,  6,  7
632     shufps        m0, m2,     q3113 ; m0 = 16, 17, 18, 19, 20, 21, 22, 23
633     mova  [dstq+0*mmsize], m3
634     mova  [dstq+1*mmsize], m1
635     mova  [dstq+2*mmsize], m0
636 %else ; sse
637     movlps      xmm0, [srcq      ]
638     movlps      xmm1, [srcq+src1q]
639     movlps      xmm2, [srcq+src2q]
640     movlps      xmm3, [srcq+src3q]
641     movlps      xmm4, [srcq+src4q]
642     movlps      xmm5, [srcq+src5q]
643     mulps       xmm0, xmm6
644     mulps       xmm1, xmm6
645     mulps       xmm2, xmm6
646     mulps       xmm3, xmm6
647     mulps       xmm4, xmm6
648     mulps       xmm5, xmm6
649     cvtps2pi     mm0, xmm0
650     cvtps2pi     mm1, xmm1
651     cvtps2pi     mm2, xmm2
652     cvtps2pi     mm3, xmm3
653     cvtps2pi     mm4, xmm4
654     cvtps2pi     mm5, xmm5
655     packssdw     mm0, mm3           ; m0 =  0,  6,  3,  9
656     packssdw     mm1, mm4           ; m1 =  1,  7,  4, 10
657     packssdw     mm2, mm5           ; m2 =  2,  8,  5, 11
658                                     ; unpack words
659     pshufw       mm3, mm0, q1032    ; m3 =  3,  9,  0,  6
660     punpcklwd    mm0, mm1           ; m0 =  0,  1,  6,  7
661     punpckhwd    mm1, mm2           ; m1 =  4,  5, 10, 11
662     punpcklwd    mm2, mm3           ; m2 =  2,  3,  8,  9
663                                     ; unpack dwords
664     pshufw       mm3, mm0, q1032    ; m3 =  6,  7,  0,  1
665     punpckldq    mm0, mm2           ; m0 =  0,  1,  2,  3 (final)
666     punpckhdq    mm2, mm1           ; m2 =  8,  9, 10, 11 (final)
667     punpckldq    mm1, mm3           ; m1 =  4,  5,  6,  7 (final)
668     mova  [dstq+0*mmsize], mm0
669     mova  [dstq+1*mmsize], mm1
670     mova  [dstq+2*mmsize], mm2
671 %endif
672     add       srcq, mmsize
673     add       dstq, mmsize*3
674     sub       lend, mmsize/4
675     jg .loop
676 %if mmsize == 8
677     emms
678     RET
679 %else
680     REP_RET
681 %endif
682 %endmacro
683
684 INIT_MMX sse
685 CONV_FLTP_TO_S16_6CH
686 INIT_XMM sse2
687 CONV_FLTP_TO_S16_6CH
688 INIT_XMM avx
689 CONV_FLTP_TO_S16_6CH
690
691 ;------------------------------------------------------------------------------
692 ; void ff_conv_fltp_to_flt_2ch(float *dst, float *const *src, int len,
693 ;                              int channels);
694 ;------------------------------------------------------------------------------
695
696 %macro CONV_FLTP_TO_FLT_2CH 0
697 cglobal conv_fltp_to_flt_2ch, 3,4,5, dst, src0, len, src1
698     mov  src1q, [src0q+gprsize]
699     mov  src0q, [src0q]
700     lea   lenq, [4*lend]
701     add  src0q, lenq
702     add  src1q, lenq
703     lea   dstq, [dstq+2*lenq]
704     neg   lenq
705 .loop:
706     mova    m0, [src0q+lenq       ]
707     mova    m1, [src1q+lenq       ]
708     mova    m2, [src0q+lenq+mmsize]
709     mova    m3, [src1q+lenq+mmsize]
710     SBUTTERFLYPS 0, 1, 4
711     SBUTTERFLYPS 2, 3, 4
712     mova  [dstq+2*lenq+0*mmsize], m0
713     mova  [dstq+2*lenq+1*mmsize], m1
714     mova  [dstq+2*lenq+2*mmsize], m2
715     mova  [dstq+2*lenq+3*mmsize], m3
716     add   lenq, 2*mmsize
717     jl .loop
718     REP_RET
719 %endmacro
720
721 INIT_XMM sse
722 CONV_FLTP_TO_FLT_2CH
723 INIT_XMM avx
724 CONV_FLTP_TO_FLT_2CH
725
726 ;-----------------------------------------------------------------------------
727 ; void ff_conv_fltp_to_flt_6ch(float *dst, float *const *src, int len,
728 ;                              int channels);
729 ;-----------------------------------------------------------------------------
730
731 %macro CONV_FLTP_TO_FLT_6CH 0
732 cglobal conv_fltp_to_flt_6ch, 2,8,7, dst, src, src1, src2, src3, src4, src5, len
733 %if ARCH_X86_64
734     mov     lend, r2d
735 %else
736     %define lend dword r2m
737 %endif
738     mov    src1q, [srcq+1*gprsize]
739     mov    src2q, [srcq+2*gprsize]
740     mov    src3q, [srcq+3*gprsize]
741     mov    src4q, [srcq+4*gprsize]
742     mov    src5q, [srcq+5*gprsize]
743     mov     srcq, [srcq]
744     sub    src1q, srcq
745     sub    src2q, srcq
746     sub    src3q, srcq
747     sub    src4q, srcq
748     sub    src5q, srcq
749 .loop:
750     mova      m0, [srcq      ]
751     mova      m1, [srcq+src1q]
752     mova      m2, [srcq+src2q]
753     mova      m3, [srcq+src3q]
754     mova      m4, [srcq+src4q]
755     mova      m5, [srcq+src5q]
756 %if cpuflag(sse4)
757     SBUTTERFLYPS 0, 1, 6
758     SBUTTERFLYPS 2, 3, 6
759     SBUTTERFLYPS 4, 5, 6
760
761     blendps   m6, m4, m0, 1100b
762     movlhps   m0, m2
763     movhlps   m4, m2
764     blendps   m2, m5, m1, 1100b
765     movlhps   m1, m3
766     movhlps   m5, m3
767
768     movaps [dstq   ], m0
769     movaps [dstq+16], m6
770     movaps [dstq+32], m4
771     movaps [dstq+48], m1
772     movaps [dstq+64], m2
773     movaps [dstq+80], m5
774 %else ; mmx
775     SBUTTERFLY dq, 0, 1, 6
776     SBUTTERFLY dq, 2, 3, 6
777     SBUTTERFLY dq, 4, 5, 6
778
779     movq   [dstq   ], m0
780     movq   [dstq+ 8], m2
781     movq   [dstq+16], m4
782     movq   [dstq+24], m1
783     movq   [dstq+32], m3
784     movq   [dstq+40], m5
785 %endif
786     add      srcq, mmsize
787     add      dstq, mmsize*6
788     sub      lend, mmsize/4
789     jg .loop
790 %if mmsize == 8
791     emms
792     RET
793 %else
794     REP_RET
795 %endif
796 %endmacro
797
798 INIT_MMX mmx
799 CONV_FLTP_TO_FLT_6CH
800 INIT_XMM sse4
801 CONV_FLTP_TO_FLT_6CH
802 INIT_XMM avx
803 CONV_FLTP_TO_FLT_6CH
804
805 ;------------------------------------------------------------------------------
806 ; void ff_conv_s16_to_s16p_2ch(int16_t *const *dst, int16_t *src, int len,
807 ;                              int channels);
808 ;------------------------------------------------------------------------------
809
810 %macro CONV_S16_TO_S16P_2CH 0
811 cglobal conv_s16_to_s16p_2ch, 3,4,4, dst0, src, len, dst1
812     lea       lenq, [2*lend]
813     mov      dst1q, [dst0q+gprsize]
814     mov      dst0q, [dst0q        ]
815     lea       srcq, [srcq+2*lenq]
816     add      dst0q, lenq
817     add      dst1q, lenq
818     neg       lenq
819 %if cpuflag(ssse3)
820     mova        m3, [pb_deinterleave_words]
821 %endif
822 .loop:
823     mova        m0, [srcq+2*lenq       ]  ; m0 =  0,  1,  2,  3,  4,  5,  6,  7
824     mova        m1, [srcq+2*lenq+mmsize]  ; m1 =  8,  9, 10, 11, 12, 13, 14, 15
825 %if cpuflag(ssse3)
826     pshufb      m0, m3                    ; m0 =  0,  2,  4,  6,  1,  3,  5,  7
827     pshufb      m1, m3                    ; m1 =  8, 10, 12, 14,  9, 11, 13, 15
828     SBUTTERFLY2 qdq, 0, 1, 2              ; m0 =  0,  2,  4,  6,  8, 10, 12, 14
829                                           ; m1 =  1,  3,  5,  7,  9, 11, 13, 15
830 %else ; sse2
831     pshuflw     m0, m0, q3120             ; m0 =  0,  2,  1,  3,  4,  5,  6,  7
832     pshufhw     m0, m0, q3120             ; m0 =  0,  2,  1,  3,  4,  6,  5,  7
833     pshuflw     m1, m1, q3120             ; m1 =  8, 10,  9, 11, 12, 13, 14, 15
834     pshufhw     m1, m1, q3120             ; m1 =  8, 10,  9, 11, 12, 14, 13, 15
835     DEINT2_PS    0, 1, 2                  ; m0 =  0,  2,  4,  6,  8, 10, 12, 14
836                                           ; m1 =  1,  3,  5,  7,  9, 11, 13, 15
837 %endif
838     mova  [dst0q+lenq], m0
839     mova  [dst1q+lenq], m1
840     add       lenq, mmsize
841     jl .loop
842     REP_RET
843 %endmacro
844
845 INIT_XMM sse2
846 CONV_S16_TO_S16P_2CH
847 INIT_XMM ssse3
848 CONV_S16_TO_S16P_2CH
849 INIT_XMM avx
850 CONV_S16_TO_S16P_2CH
851
852 ;------------------------------------------------------------------------------
853 ; void ff_conv_s16_to_s16p_6ch(int16_t *const *dst, int16_t *src, int len,
854 ;                              int channels);
855 ;------------------------------------------------------------------------------
856
857 %macro CONV_S16_TO_S16P_6CH 0
858 %if ARCH_X86_64
859 cglobal conv_s16_to_s16p_6ch, 3,8,5, dst, src, len, dst1, dst2, dst3, dst4, dst5
860 %else
861 cglobal conv_s16_to_s16p_6ch, 2,7,5, dst, src, dst1, dst2, dst3, dst4, dst5
862 %define lend dword r2m
863 %endif
864     mov     dst1q, [dstq+  gprsize]
865     mov     dst2q, [dstq+2*gprsize]
866     mov     dst3q, [dstq+3*gprsize]
867     mov     dst4q, [dstq+4*gprsize]
868     mov     dst5q, [dstq+5*gprsize]
869     mov      dstq, [dstq          ]
870     sub     dst1q, dstq
871     sub     dst2q, dstq
872     sub     dst3q, dstq
873     sub     dst4q, dstq
874     sub     dst5q, dstq
875 .loop:
876     mova       m0, [srcq+0*mmsize]      ; m0 =  0,  1,  2,  3,  4,  5,  6,  7
877     mova       m3, [srcq+1*mmsize]      ; m3 =  8,  9, 10, 11, 12, 13, 14, 15
878     mova       m2, [srcq+2*mmsize]      ; m2 = 16, 17, 18, 19, 20, 21, 22, 23
879     PALIGNR    m1, m3, m0, 12, m4       ; m1 =  6,  7,  8,  9, 10, 11,  x,  x
880     shufps     m3, m2, q1032            ; m3 = 12, 13, 14, 15, 16, 17, 18, 19
881     psrldq     m2, 4                    ; m2 = 18, 19, 20, 21, 22, 23,  x,  x
882     SBUTTERFLY2 wd, 0, 1, 4             ; m0 =  0,  6,  1,  7,  2,  8,  3,  9
883                                         ; m1 =  4, 10,  5, 11,  x,  x,  x,  x
884     SBUTTERFLY2 wd, 3, 2, 4             ; m3 = 12, 18, 13, 19, 14, 20, 15, 21
885                                         ; m2 = 16, 22, 17, 23,  x,  x,  x,  x
886     SBUTTERFLY2 dq, 0, 3, 4             ; m0 =  0,  6, 12, 18,  1,  7, 13, 19
887                                         ; m3 =  2,  8, 14, 20,  3,  9, 15, 21
888     punpckldq  m1, m2                   ; m1 =  4, 10, 16, 22,  5, 11, 17, 23
889     movq    [dstq      ], m0
890     movhps  [dstq+dst1q], m0
891     movq    [dstq+dst2q], m3
892     movhps  [dstq+dst3q], m3
893     movq    [dstq+dst4q], m1
894     movhps  [dstq+dst5q], m1
895     add      srcq, mmsize*3
896     add      dstq, mmsize/2
897     sub      lend, mmsize/4
898     jg .loop
899     REP_RET
900 %endmacro
901
902 INIT_XMM sse2
903 CONV_S16_TO_S16P_6CH
904 INIT_XMM ssse3
905 CONV_S16_TO_S16P_6CH
906 INIT_XMM avx
907 CONV_S16_TO_S16P_6CH
908
909 ;------------------------------------------------------------------------------
910 ; void ff_conv_s16_to_fltp_2ch(float *const *dst, int16_t *src, int len,
911 ;                              int channels);
912 ;------------------------------------------------------------------------------
913
914 %macro CONV_S16_TO_FLTP_2CH 0
915 cglobal conv_s16_to_fltp_2ch, 3,4,5, dst0, src, len, dst1
916     lea       lenq, [4*lend]
917     mov      dst1q, [dst0q+gprsize]
918     mov      dst0q, [dst0q        ]
919     add       srcq, lenq
920     add      dst0q, lenq
921     add      dst1q, lenq
922     neg       lenq
923     mova        m3, [pf_s32_inv_scale]
924     mova        m4, [pw_zero_even]
925 .loop:
926     mova        m1, [srcq+lenq]
927     pslld       m0, m1, 16
928     pand        m1, m4
929     cvtdq2ps    m0, m0
930     cvtdq2ps    m1, m1
931     mulps       m0, m0, m3
932     mulps       m1, m1, m3
933     mova  [dst0q+lenq], m0
934     mova  [dst1q+lenq], m1
935     add       lenq, mmsize
936     jl .loop
937     REP_RET
938 %endmacro
939
940 INIT_XMM sse2
941 CONV_S16_TO_FLTP_2CH
942 INIT_XMM avx
943 CONV_S16_TO_FLTP_2CH
944
945 ;------------------------------------------------------------------------------
946 ; void ff_conv_s16_to_fltp_6ch(float *const *dst, int16_t *src, int len,
947 ;                              int channels);
948 ;------------------------------------------------------------------------------
949
950 %macro CONV_S16_TO_FLTP_6CH 0
951 %if ARCH_X86_64
952 cglobal conv_s16_to_fltp_6ch, 3,8,7, dst, src, len, dst1, dst2, dst3, dst4, dst5
953 %else
954 cglobal conv_s16_to_fltp_6ch, 2,7,7, dst, src, dst1, dst2, dst3, dst4, dst5
955 %define lend dword r2m
956 %endif
957     mov     dst1q, [dstq+  gprsize]
958     mov     dst2q, [dstq+2*gprsize]
959     mov     dst3q, [dstq+3*gprsize]
960     mov     dst4q, [dstq+4*gprsize]
961     mov     dst5q, [dstq+5*gprsize]
962     mov      dstq, [dstq          ]
963     sub     dst1q, dstq
964     sub     dst2q, dstq
965     sub     dst3q, dstq
966     sub     dst4q, dstq
967     sub     dst5q, dstq
968     mova       m6, [pf_s16_inv_scale]
969 .loop:
970     mova       m0, [srcq+0*mmsize]  ; m0 =  0,  1,  2,  3,  4,  5,  6,  7
971     mova       m3, [srcq+1*mmsize]  ; m3 =  8,  9, 10, 11, 12, 13, 14, 15
972     mova       m2, [srcq+2*mmsize]  ; m2 = 16, 17, 18, 19, 20, 21, 22, 23
973     PALIGNR    m1, m3, m0, 12, m4   ; m1 =  6,  7,  8,  9, 10, 11,  x,  x
974     shufps     m3, m2, q1032        ; m3 = 12, 13, 14, 15, 16, 17, 18, 19
975     psrldq     m2, 4                ; m2 = 18, 19, 20, 21, 22, 23,  x,  x
976     SBUTTERFLY2 wd, 0, 1, 4         ; m0 =  0,  6,  1,  7,  2,  8,  3,  9
977                                     ; m1 =  4, 10,  5, 11,  x,  x,  x,  x
978     SBUTTERFLY2 wd, 3, 2, 4         ; m3 = 12, 18, 13, 19, 14, 20, 15, 21
979                                     ; m2 = 16, 22, 17, 23,  x,  x,  x,  x
980     SBUTTERFLY2 dq, 0, 3, 4         ; m0 =  0,  6, 12, 18,  1,  7, 13, 19
981                                     ; m3 =  2,  8, 14, 20,  3,  9, 15, 21
982     punpckldq  m1, m2               ; m1 =  4, 10, 16, 22,  5, 11, 17, 23
983     S16_TO_S32_SX 0, 2              ; m0 =      0,      6,     12,     18
984                                     ; m2 =      1,      7,     13,     19
985     S16_TO_S32_SX 3, 4              ; m3 =      2,      8,     14,     20
986                                     ; m4 =      3,      9,     15,     21
987     S16_TO_S32_SX 1, 5              ; m1 =      4,     10,     16,     22
988                                     ; m5 =      5,     11,     17,     23
989     SWAP 1,2,3,4
990     cvtdq2ps   m0, m0
991     cvtdq2ps   m1, m1
992     cvtdq2ps   m2, m2
993     cvtdq2ps   m3, m3
994     cvtdq2ps   m4, m4
995     cvtdq2ps   m5, m5
996     mulps      m0, m6
997     mulps      m1, m6
998     mulps      m2, m6
999     mulps      m3, m6
1000     mulps      m4, m6
1001     mulps      m5, m6
1002     mova  [dstq      ], m0
1003     mova  [dstq+dst1q], m1
1004     mova  [dstq+dst2q], m2
1005     mova  [dstq+dst3q], m3
1006     mova  [dstq+dst4q], m4
1007     mova  [dstq+dst5q], m5
1008     add      srcq, mmsize*3
1009     add      dstq, mmsize
1010     sub      lend, mmsize/4
1011     jg .loop
1012     REP_RET
1013 %endmacro
1014
1015 INIT_XMM sse2
1016 CONV_S16_TO_FLTP_6CH
1017 INIT_XMM ssse3
1018 CONV_S16_TO_FLTP_6CH
1019 INIT_XMM sse4
1020 CONV_S16_TO_FLTP_6CH
1021 INIT_XMM avx
1022 CONV_S16_TO_FLTP_6CH
1023
1024 ;------------------------------------------------------------------------------
1025 ; void ff_conv_flt_to_s16p_2ch(int16_t *const *dst, float *src, int len,
1026 ;                              int channels);
1027 ;------------------------------------------------------------------------------
1028
1029 %macro CONV_FLT_TO_S16P_2CH 0
1030 cglobal conv_flt_to_s16p_2ch, 3,4,6, dst0, src, len, dst1
1031     lea       lenq, [2*lend]
1032     mov      dst1q, [dst0q+gprsize]
1033     mov      dst0q, [dst0q        ]
1034     lea       srcq, [srcq+4*lenq]
1035     add      dst0q, lenq
1036     add      dst1q, lenq
1037     neg       lenq
1038     mova        m5, [pf_s16_scale]
1039 .loop:
1040     mova       m0, [srcq+4*lenq         ]
1041     mova       m1, [srcq+4*lenq+  mmsize]
1042     mova       m2, [srcq+4*lenq+2*mmsize]
1043     mova       m3, [srcq+4*lenq+3*mmsize]
1044     DEINT2_PS   0, 1, 4
1045     DEINT2_PS   2, 3, 4
1046     mulps      m0, m0, m5
1047     mulps      m1, m1, m5
1048     mulps      m2, m2, m5
1049     mulps      m3, m3, m5
1050     cvtps2dq   m0, m0
1051     cvtps2dq   m1, m1
1052     cvtps2dq   m2, m2
1053     cvtps2dq   m3, m3
1054     packssdw   m0, m2
1055     packssdw   m1, m3
1056     mova  [dst0q+lenq], m0
1057     mova  [dst1q+lenq], m1
1058     add      lenq, mmsize
1059     jl .loop
1060     REP_RET
1061 %endmacro
1062
1063 INIT_XMM sse2
1064 CONV_FLT_TO_S16P_2CH
1065 INIT_XMM avx
1066 CONV_FLT_TO_S16P_2CH
1067
1068 ;------------------------------------------------------------------------------
1069 ; void ff_conv_flt_to_s16p_6ch(int16_t *const *dst, float *src, int len,
1070 ;                              int channels);
1071 ;------------------------------------------------------------------------------
1072
1073 %macro CONV_FLT_TO_S16P_6CH 0
1074 %if ARCH_X86_64
1075 cglobal conv_flt_to_s16p_6ch, 3,8,7, dst, src, len, dst1, dst2, dst3, dst4, dst5
1076 %else
1077 cglobal conv_flt_to_s16p_6ch, 2,7,7, dst, src, dst1, dst2, dst3, dst4, dst5
1078 %define lend dword r2m
1079 %endif
1080     mov     dst1q, [dstq+  gprsize]
1081     mov     dst2q, [dstq+2*gprsize]
1082     mov     dst3q, [dstq+3*gprsize]
1083     mov     dst4q, [dstq+4*gprsize]
1084     mov     dst5q, [dstq+5*gprsize]
1085     mov      dstq, [dstq          ]
1086     sub     dst1q, dstq
1087     sub     dst2q, dstq
1088     sub     dst3q, dstq
1089     sub     dst4q, dstq
1090     sub     dst5q, dstq
1091     mova       m6, [pf_s16_scale]
1092 .loop:
1093     mulps      m0, m6, [srcq+0*mmsize]
1094     mulps      m3, m6, [srcq+1*mmsize]
1095     mulps      m1, m6, [srcq+2*mmsize]
1096     mulps      m4, m6, [srcq+3*mmsize]
1097     mulps      m2, m6, [srcq+4*mmsize]
1098     mulps      m5, m6, [srcq+5*mmsize]
1099     cvtps2dq   m0, m0
1100     cvtps2dq   m1, m1
1101     cvtps2dq   m2, m2
1102     cvtps2dq   m3, m3
1103     cvtps2dq   m4, m4
1104     cvtps2dq   m5, m5
1105     packssdw   m0, m3               ; m0 =  0,  1,  2,  3,  4,  5,  6,  7
1106     packssdw   m1, m4               ; m1 =  8,  9, 10, 11, 12, 13, 14, 15
1107     packssdw   m2, m5               ; m2 = 16, 17, 18, 19, 20, 21, 22, 23
1108     PALIGNR    m3, m1, m0, 12, m4   ; m3 =  6,  7,  8,  9, 10, 11,  x,  x
1109     shufps     m1, m2, q1032        ; m1 = 12, 13, 14, 15, 16, 17, 18, 19
1110     psrldq     m2, 4                ; m2 = 18, 19, 20, 21, 22, 23,  x,  x
1111     SBUTTERFLY2 wd, 0, 3, 4         ; m0 =  0,  6,  1,  7,  2,  8,  3,  9
1112                                     ; m3 =  4, 10,  5, 11,  x,  x,  x,  x
1113     SBUTTERFLY2 wd, 1, 2, 4         ; m1 = 12, 18, 13, 19, 14, 20, 15, 21
1114                                     ; m2 = 16, 22, 17, 23,  x,  x,  x,  x
1115     SBUTTERFLY2 dq, 0, 1, 4         ; m0 =  0,  6, 12, 18,  1,  7, 13, 19
1116                                     ; m1 =  2,  8, 14, 20,  3,  9, 15, 21
1117     punpckldq  m3, m2               ; m3 =  4, 10, 16, 22,  5, 11, 17, 23
1118     movq    [dstq      ], m0
1119     movhps  [dstq+dst1q], m0
1120     movq    [dstq+dst2q], m1
1121     movhps  [dstq+dst3q], m1
1122     movq    [dstq+dst4q], m3
1123     movhps  [dstq+dst5q], m3
1124     add      srcq, mmsize*6
1125     add      dstq, mmsize/2
1126     sub      lend, mmsize/4
1127     jg .loop
1128     REP_RET
1129 %endmacro
1130
1131 INIT_XMM sse2
1132 CONV_FLT_TO_S16P_6CH
1133 INIT_XMM ssse3
1134 CONV_FLT_TO_S16P_6CH
1135 INIT_XMM avx
1136 CONV_FLT_TO_S16P_6CH
1137
1138 ;------------------------------------------------------------------------------
1139 ; void ff_conv_flt_to_fltp_2ch(float *const *dst, float *src, int len,
1140 ;                              int channels);
1141 ;------------------------------------------------------------------------------
1142
1143 %macro CONV_FLT_TO_FLTP_2CH 0
1144 cglobal conv_flt_to_fltp_2ch, 3,4,3, dst0, src, len, dst1
1145     lea    lenq, [4*lend]
1146     mov   dst1q, [dst0q+gprsize]
1147     mov   dst0q, [dst0q        ]
1148     lea    srcq, [srcq+2*lenq]
1149     add   dst0q, lenq
1150     add   dst1q, lenq
1151     neg    lenq
1152 .loop:
1153     mova     m0, [srcq+2*lenq       ]
1154     mova     m1, [srcq+2*lenq+mmsize]
1155     DEINT2_PS 0, 1, 2
1156     mova  [dst0q+lenq], m0
1157     mova  [dst1q+lenq], m1
1158     add    lenq, mmsize
1159     jl .loop
1160     REP_RET
1161 %endmacro
1162
1163 INIT_XMM sse
1164 CONV_FLT_TO_FLTP_2CH
1165 INIT_XMM avx
1166 CONV_FLT_TO_FLTP_2CH
1167
1168 ;------------------------------------------------------------------------------
1169 ; void ff_conv_flt_to_fltp_6ch(float *const *dst, float *src, int len,
1170 ;                              int channels);
1171 ;------------------------------------------------------------------------------
1172
1173 %macro CONV_FLT_TO_FLTP_6CH 0
1174 %if ARCH_X86_64
1175 cglobal conv_flt_to_fltp_6ch, 3,8,7, dst, src, len, dst1, dst2, dst3, dst4, dst5
1176 %else
1177 cglobal conv_flt_to_fltp_6ch, 2,7,7, dst, src, dst1, dst2, dst3, dst4, dst5
1178 %define lend dword r2m
1179 %endif
1180     mov     dst1q, [dstq+  gprsize]
1181     mov     dst2q, [dstq+2*gprsize]
1182     mov     dst3q, [dstq+3*gprsize]
1183     mov     dst4q, [dstq+4*gprsize]
1184     mov     dst5q, [dstq+5*gprsize]
1185     mov      dstq, [dstq          ]
1186     sub     dst1q, dstq
1187     sub     dst2q, dstq
1188     sub     dst3q, dstq
1189     sub     dst4q, dstq
1190     sub     dst5q, dstq
1191 .loop:
1192     mova       m0, [srcq+0*mmsize]  ; m0 =  0,  1,  2,  3
1193     mova       m1, [srcq+1*mmsize]  ; m1 =  4,  5,  6,  7
1194     mova       m2, [srcq+2*mmsize]  ; m2 =  8,  9, 10, 11
1195     mova       m3, [srcq+3*mmsize]  ; m3 = 12, 13, 14, 15
1196     mova       m4, [srcq+4*mmsize]  ; m4 = 16, 17, 18, 19
1197     mova       m5, [srcq+5*mmsize]  ; m5 = 20, 21, 22, 23
1198
1199     SBUTTERFLY2 dq, 0, 3, 6         ; m0 =  0, 12,  1, 13
1200                                     ; m3 =  2, 14,  3, 15
1201     SBUTTERFLY2 dq, 1, 4, 6         ; m1 =  4, 16,  5, 17
1202                                     ; m4 =  6, 18,  7, 19
1203     SBUTTERFLY2 dq, 2, 5, 6         ; m2 =  8, 20,  9, 21
1204                                     ; m5 = 10, 22, 11, 23
1205     SBUTTERFLY2 dq, 0, 4, 6         ; m0 =  0,  6, 12, 18
1206                                     ; m4 =  1,  7, 13, 19
1207     SBUTTERFLY2 dq, 3, 2, 6         ; m3 =  2,  8, 14, 20
1208                                     ; m2 =  3,  9, 15, 21
1209     SBUTTERFLY2 dq, 1, 5, 6         ; m1 =  4, 10, 16, 22
1210                                     ; m5 =  5, 11, 17, 23
1211     mova [dstq      ], m0
1212     mova [dstq+dst1q], m4
1213     mova [dstq+dst2q], m3
1214     mova [dstq+dst3q], m2
1215     mova [dstq+dst4q], m1
1216     mova [dstq+dst5q], m5
1217     add      srcq, mmsize*6
1218     add      dstq, mmsize
1219     sub      lend, mmsize/4
1220     jg .loop
1221     REP_RET
1222 %endmacro
1223
1224 INIT_XMM sse2
1225 CONV_FLT_TO_FLTP_6CH
1226 INIT_XMM avx
1227 CONV_FLT_TO_FLTP_6CH