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