lavr: Add x86-optimized functions for s32 to flt 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_s16_inv_scale: times 4 dd 0x38000000
31
32 SECTION_TEXT
33
34 ;------------------------------------------------------------------------------
35 ; void ff_conv_s16_to_s32(int32_t *dst, const int16_t *src, int len);
36 ;------------------------------------------------------------------------------
37
38 INIT_XMM sse2
39 cglobal conv_s16_to_s32, 3,3,3, dst, src, len
40     lea      lenq, [2*lend]
41     lea      dstq, [dstq+2*lenq]
42     add      srcq, lenq
43     neg      lenq
44 .loop:
45     mova       m2, [srcq+lenq]
46     pxor       m0, m0
47     pxor       m1, m1
48     punpcklwd  m0, m2
49     punpckhwd  m1, m2
50     mova  [dstq+2*lenq       ], m0
51     mova  [dstq+2*lenq+mmsize], m1
52     add      lenq, mmsize
53     jl .loop
54     REP_RET
55
56 ;------------------------------------------------------------------------------
57 ; void ff_conv_s16_to_flt(float *dst, const int16_t *src, int len);
58 ;------------------------------------------------------------------------------
59
60 %macro CONV_S16_TO_FLT 0
61 cglobal conv_s16_to_flt, 3,3,3, dst, src, len
62     lea      lenq, [2*lend]
63     add      srcq, lenq
64     lea      dstq, [dstq + 2*lenq]
65     neg      lenq
66     mova       m2, [pf_s16_inv_scale]
67     ALIGN 16
68 .loop:
69     mova       m0, [srcq+lenq]
70     S16_TO_S32_SX 0, 1
71     cvtdq2ps   m0, m0
72     cvtdq2ps   m1, m1
73     mulps      m0, m2
74     mulps      m1, m2
75     mova  [dstq+2*lenq       ], m0
76     mova  [dstq+2*lenq+mmsize], m1
77     add      lenq, mmsize
78     jl .loop
79     REP_RET
80 %endmacro
81
82 INIT_XMM sse2
83 CONV_S16_TO_FLT
84 INIT_XMM sse4
85 CONV_S16_TO_FLT
86
87 ;------------------------------------------------------------------------------
88 ; void ff_conv_s32_to_s16(int16_t *dst, const int32_t *src, int len);
89 ;------------------------------------------------------------------------------
90
91 %macro CONV_S32_TO_S16 0
92 cglobal conv_s32_to_s16, 3,3,4, dst, src, len
93     lea     lenq, [2*lend]
94     lea     srcq, [srcq+2*lenq]
95     add     dstq, lenq
96     neg     lenq
97 .loop:
98     mova      m0, [srcq+2*lenq         ]
99     mova      m1, [srcq+2*lenq+  mmsize]
100     mova      m2, [srcq+2*lenq+2*mmsize]
101     mova      m3, [srcq+2*lenq+3*mmsize]
102     psrad     m0, 16
103     psrad     m1, 16
104     psrad     m2, 16
105     psrad     m3, 16
106     packssdw  m0, m1
107     packssdw  m2, m3
108     mova  [dstq+lenq       ], m0
109     mova  [dstq+lenq+mmsize], m2
110     add     lenq, mmsize*2
111     jl .loop
112 %if mmsize == 8
113     emms
114     RET
115 %else
116     REP_RET
117 %endif
118 %endmacro
119
120 INIT_MMX mmx
121 CONV_S32_TO_S16
122 INIT_XMM sse2
123 CONV_S32_TO_S16
124
125 ;------------------------------------------------------------------------------
126 ; void ff_conv_s32_to_flt(float *dst, const int32_t *src, int len);
127 ;------------------------------------------------------------------------------
128
129 %macro CONV_S32_TO_FLT 0
130 cglobal conv_s32_to_flt, 3,3,3, dst, src, len
131     lea     lenq, [4*lend]
132     add     srcq, lenq
133     add     dstq, lenq
134     neg     lenq
135     mova      m0, [pf_s32_inv_scale]
136     ALIGN 16
137 .loop:
138     cvtdq2ps  m1, [srcq+lenq       ]
139     cvtdq2ps  m2, [srcq+lenq+mmsize]
140     mulps     m1, m1, m0
141     mulps     m2, m2, m0
142     mova  [dstq+lenq       ], m1
143     mova  [dstq+lenq+mmsize], m2
144     add     lenq, mmsize*2
145     jl .loop
146 %if mmsize == 32
147     vzeroupper
148     RET
149 %else
150     REP_RET
151 %endif
152 %endmacro
153
154 INIT_XMM sse2
155 CONV_S32_TO_FLT
156 %if HAVE_AVX
157 INIT_YMM avx
158 CONV_S32_TO_FLT
159 %endif
160
161 ;-----------------------------------------------------------------------------
162 ; void ff_conv_fltp_to_flt_6ch(float *dst, float *const *src, int len,
163 ;                              int channels);
164 ;-----------------------------------------------------------------------------
165
166 %macro CONV_FLTP_TO_FLT_6CH 0
167 cglobal conv_fltp_to_flt_6ch, 2,8,7, dst, src, src1, src2, src3, src4, src5, len
168 %if ARCH_X86_64
169     mov     lend, r2d
170 %else
171     %define lend dword r2m
172 %endif
173     mov    src1q, [srcq+1*gprsize]
174     mov    src2q, [srcq+2*gprsize]
175     mov    src3q, [srcq+3*gprsize]
176     mov    src4q, [srcq+4*gprsize]
177     mov    src5q, [srcq+5*gprsize]
178     mov     srcq, [srcq]
179     sub    src1q, srcq
180     sub    src2q, srcq
181     sub    src3q, srcq
182     sub    src4q, srcq
183     sub    src5q, srcq
184 .loop:
185     mova      m0, [srcq      ]
186     mova      m1, [srcq+src1q]
187     mova      m2, [srcq+src2q]
188     mova      m3, [srcq+src3q]
189     mova      m4, [srcq+src4q]
190     mova      m5, [srcq+src5q]
191 %if cpuflag(sse4)
192     SBUTTERFLYPS 0, 1, 6
193     SBUTTERFLYPS 2, 3, 6
194     SBUTTERFLYPS 4, 5, 6
195
196     blendps   m6, m4, m0, 1100b
197     movlhps   m0, m2
198     movhlps   m4, m2
199     blendps   m2, m5, m1, 1100b
200     movlhps   m1, m3
201     movhlps   m5, m3
202
203     movaps [dstq   ], m0
204     movaps [dstq+16], m6
205     movaps [dstq+32], m4
206     movaps [dstq+48], m1
207     movaps [dstq+64], m2
208     movaps [dstq+80], m5
209 %else ; mmx
210     SBUTTERFLY dq, 0, 1, 6
211     SBUTTERFLY dq, 2, 3, 6
212     SBUTTERFLY dq, 4, 5, 6
213
214     movq   [dstq   ], m0
215     movq   [dstq+ 8], m2
216     movq   [dstq+16], m4
217     movq   [dstq+24], m1
218     movq   [dstq+32], m3
219     movq   [dstq+40], m5
220 %endif
221     add      srcq, mmsize
222     add      dstq, mmsize*6
223     sub      lend, mmsize/4
224     jg .loop
225 %if mmsize == 8
226     emms
227     RET
228 %else
229     REP_RET
230 %endif
231 %endmacro
232
233 INIT_MMX mmx
234 CONV_FLTP_TO_FLT_6CH
235 INIT_XMM sse4
236 CONV_FLTP_TO_FLT_6CH
237 %if HAVE_AVX
238 INIT_XMM avx
239 CONV_FLTP_TO_FLT_6CH
240 %endif