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