lavr: Add x86-optimized functions for s16 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_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_fltp_to_flt_6ch(float *dst, float *const *src, int len,
88 ;                              int channels);
89 ;-----------------------------------------------------------------------------
90
91 %macro CONV_FLTP_TO_FLT_6CH 0
92 cglobal conv_fltp_to_flt_6ch, 2,8,7, dst, src, src1, src2, src3, src4, src5, len
93 %if ARCH_X86_64
94     mov     lend, r2d
95 %else
96     %define lend dword r2m
97 %endif
98     mov    src1q, [srcq+1*gprsize]
99     mov    src2q, [srcq+2*gprsize]
100     mov    src3q, [srcq+3*gprsize]
101     mov    src4q, [srcq+4*gprsize]
102     mov    src5q, [srcq+5*gprsize]
103     mov     srcq, [srcq]
104     sub    src1q, srcq
105     sub    src2q, srcq
106     sub    src3q, srcq
107     sub    src4q, srcq
108     sub    src5q, srcq
109 .loop:
110     mova      m0, [srcq      ]
111     mova      m1, [srcq+src1q]
112     mova      m2, [srcq+src2q]
113     mova      m3, [srcq+src3q]
114     mova      m4, [srcq+src4q]
115     mova      m5, [srcq+src5q]
116 %if cpuflag(sse4)
117     SBUTTERFLYPS 0, 1, 6
118     SBUTTERFLYPS 2, 3, 6
119     SBUTTERFLYPS 4, 5, 6
120
121     blendps   m6, m4, m0, 1100b
122     movlhps   m0, m2
123     movhlps   m4, m2
124     blendps   m2, m5, m1, 1100b
125     movlhps   m1, m3
126     movhlps   m5, m3
127
128     movaps [dstq   ], m0
129     movaps [dstq+16], m6
130     movaps [dstq+32], m4
131     movaps [dstq+48], m1
132     movaps [dstq+64], m2
133     movaps [dstq+80], m5
134 %else ; mmx
135     SBUTTERFLY dq, 0, 1, 6
136     SBUTTERFLY dq, 2, 3, 6
137     SBUTTERFLY dq, 4, 5, 6
138
139     movq   [dstq   ], m0
140     movq   [dstq+ 8], m2
141     movq   [dstq+16], m4
142     movq   [dstq+24], m1
143     movq   [dstq+32], m3
144     movq   [dstq+40], m5
145 %endif
146     add      srcq, mmsize
147     add      dstq, mmsize*6
148     sub      lend, mmsize/4
149     jg .loop
150 %if mmsize == 8
151     emms
152     RET
153 %else
154     REP_RET
155 %endif
156 %endmacro
157
158 INIT_MMX mmx
159 CONV_FLTP_TO_FLT_6CH
160 INIT_XMM sse4
161 CONV_FLTP_TO_FLT_6CH
162 %if HAVE_AVX
163 INIT_XMM avx
164 CONV_FLTP_TO_FLT_6CH
165 %endif