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