]> git.sesse.net Git - ffmpeg/blob - libavutil/x86/float_dsp.asm
x86: float dsp: unroll SSE versions
[ffmpeg] / libavutil / x86 / float_dsp.asm
1 ;*****************************************************************************
2 ;* x86-optimized Float DSP functions
3 ;*
4 ;* Copyright 2006 Loren Merritt
5 ;*
6 ;* This file is part of FFmpeg.
7 ;*
8 ;* FFmpeg 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 ;* FFmpeg 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 FFmpeg; if not, write to the Free Software
20 ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 ;******************************************************************************
22
23 %include "x86util.asm"
24
25 SECTION .text
26
27 ;-----------------------------------------------------------------------------
28 ; void vector_fmul(float *dst, const float *src0, const float *src1, int len)
29 ;-----------------------------------------------------------------------------
30 %macro VECTOR_FMUL 0
31 cglobal vector_fmul, 4,4,2, dst, src0, src1, len
32     lea       lenq, [lend*4 - 64]
33 ALIGN 16
34 .loop:
35 %assign a 0
36 %rep 32/mmsize
37     mova      m0,   [src0q + lenq + (a+0)*mmsize]
38     mova      m1,   [src0q + lenq + (a+1)*mmsize]
39     mulps     m0, m0, [src1q + lenq + (a+0)*mmsize]
40     mulps     m1, m1, [src1q + lenq + (a+1)*mmsize]
41     mova      [dstq + lenq + (a+0)*mmsize], m0
42     mova      [dstq + lenq + (a+1)*mmsize], m1
43 %assign a a+2
44 %endrep
45
46     sub       lenq, 64
47     jge       .loop
48     REP_RET
49 %endmacro
50
51 INIT_XMM sse
52 VECTOR_FMUL
53 %if HAVE_AVX_EXTERNAL
54 INIT_YMM avx
55 VECTOR_FMUL
56 %endif
57
58 ;------------------------------------------------------------------------------
59 ; void ff_vector_fmac_scalar(float *dst, const float *src, float mul, int len)
60 ;------------------------------------------------------------------------------
61
62 %macro VECTOR_FMAC_SCALAR 0
63 %if UNIX64
64 cglobal vector_fmac_scalar, 3,3,3, dst, src, len
65 %else
66 cglobal vector_fmac_scalar, 4,4,3, dst, src, mul, len
67 %endif
68 %if ARCH_X86_32
69     VBROADCASTSS m0, mulm
70 %else
71 %if WIN64
72     mova       xmm0, xmm2
73 %endif
74     shufps     xmm0, xmm0, 0
75 %if cpuflag(avx)
76     vinsertf128  m0, m0, xmm0, 1
77 %endif
78 %endif
79     lea    lenq, [lend*4-64]
80 .loop:
81 %assign a 0
82 %rep 32/mmsize
83     mulps    m1, m0, [srcq+lenq+(a+0)*mmsize]
84     mulps    m2, m0, [srcq+lenq+(a+1)*mmsize]
85     addps    m1, m1, [dstq+lenq+(a+0)*mmsize]
86     addps    m2, m2, [dstq+lenq+(a+1)*mmsize]
87     mova  [dstq+lenq+(a+0)*mmsize], m1
88     mova  [dstq+lenq+(a+1)*mmsize], m2
89 %assign a a+2
90 %endrep
91     sub    lenq, 64
92     jge .loop
93     REP_RET
94 %endmacro
95
96 INIT_XMM sse
97 VECTOR_FMAC_SCALAR
98 %if HAVE_AVX_EXTERNAL
99 INIT_YMM avx
100 VECTOR_FMAC_SCALAR
101 %endif
102
103 ;------------------------------------------------------------------------------
104 ; void ff_vector_fmul_scalar(float *dst, const float *src, float mul, int len)
105 ;------------------------------------------------------------------------------
106
107 %macro VECTOR_FMUL_SCALAR 0
108 %if UNIX64
109 cglobal vector_fmul_scalar, 3,3,2, dst, src, len
110 %else
111 cglobal vector_fmul_scalar, 4,4,3, dst, src, mul, len
112 %endif
113 %if ARCH_X86_32
114     movss    m0, mulm
115 %elif WIN64
116     SWAP 0, 2
117 %endif
118     shufps   m0, m0, 0
119     lea    lenq, [lend*4-mmsize]
120 .loop:
121     mova     m1, [srcq+lenq]
122     mulps    m1, m0
123     mova  [dstq+lenq], m1
124     sub    lenq, mmsize
125     jge .loop
126     REP_RET
127 %endmacro
128
129 INIT_XMM sse
130 VECTOR_FMUL_SCALAR
131
132 ;------------------------------------------------------------------------------
133 ; void ff_vector_dmul_scalar(double *dst, const double *src, double mul,
134 ;                            int len)
135 ;------------------------------------------------------------------------------
136
137 %macro VECTOR_DMUL_SCALAR 0
138 %if ARCH_X86_32
139 cglobal vector_dmul_scalar, 3,4,3, dst, src, mul, len, lenaddr
140     mov          lenq, lenaddrm
141 %elif UNIX64
142 cglobal vector_dmul_scalar, 3,3,3, dst, src, len
143 %else
144 cglobal vector_dmul_scalar, 4,4,3, dst, src, mul, len
145 %endif
146 %if ARCH_X86_32
147     VBROADCASTSD   m0, mulm
148 %else
149 %if WIN64
150     movlhps      xmm2, xmm2
151 %if cpuflag(avx)
152     vinsertf128  ymm2, ymm2, xmm2, 1
153 %endif
154     SWAP 0, 2
155 %else
156     movlhps      xmm0, xmm0
157 %if cpuflag(avx)
158     vinsertf128  ymm0, ymm0, xmm0, 1
159 %endif
160 %endif
161 %endif
162     lea          lenq, [lend*8-2*mmsize]
163 .loop:
164     mulpd          m1, m0, [srcq+lenq       ]
165     mulpd          m2, m0, [srcq+lenq+mmsize]
166     mova   [dstq+lenq       ], m1
167     mova   [dstq+lenq+mmsize], m2
168     sub          lenq, 2*mmsize
169     jge .loop
170     REP_RET
171 %endmacro
172
173 INIT_XMM sse2
174 VECTOR_DMUL_SCALAR
175 %if HAVE_AVX_EXTERNAL
176 INIT_YMM avx
177 VECTOR_DMUL_SCALAR
178 %endif
179
180 ;-----------------------------------------------------------------------------
181 ; vector_fmul_add(float *dst, const float *src0, const float *src1,
182 ;                 const float *src2, int len)
183 ;-----------------------------------------------------------------------------
184 %macro VECTOR_FMUL_ADD 0
185 cglobal vector_fmul_add, 5,5,2, dst, src0, src1, src2, len
186     lea       lenq, [lend*4 - 2*mmsize]
187 ALIGN 16
188 .loop:
189     mova    m0,   [src0q + lenq]
190     mova    m1,   [src0q + lenq + mmsize]
191     mulps   m0, m0, [src1q + lenq]
192     mulps   m1, m1, [src1q + lenq + mmsize]
193     addps   m0, m0, [src2q + lenq]
194     addps   m1, m1, [src2q + lenq + mmsize]
195     mova    [dstq + lenq], m0
196     mova    [dstq + lenq + mmsize], m1
197
198     sub     lenq,   2*mmsize
199     jge     .loop
200     REP_RET
201 %endmacro
202
203 INIT_XMM sse
204 VECTOR_FMUL_ADD
205 %if HAVE_AVX_EXTERNAL
206 INIT_YMM avx
207 VECTOR_FMUL_ADD
208 %endif
209
210 ;-----------------------------------------------------------------------------
211 ; void vector_fmul_reverse(float *dst, const float *src0, const float *src1,
212 ;                          int len)
213 ;-----------------------------------------------------------------------------
214 %macro VECTOR_FMUL_REVERSE 0
215 cglobal vector_fmul_reverse, 4,4,2, dst, src0, src1, len
216     lea       lenq, [lend*4 - 2*mmsize]
217 ALIGN 16
218 .loop:
219 %if cpuflag(avx)
220     vmovaps     xmm0, [src1q + 16]
221     vinsertf128 m0, m0, [src1q], 1
222     vshufps     m0, m0, m0, q0123
223     vmovaps     xmm1, [src1q + mmsize + 16]
224     vinsertf128 m1, m1, [src1q + mmsize], 1
225     vshufps     m1, m1, m1, q0123
226 %else
227     mova    m0, [src1q]
228     mova    m1, [src1q + mmsize]
229     shufps  m0, m0, q0123
230     shufps  m1, m1, q0123
231 %endif
232     mulps   m0, m0, [src0q + lenq + mmsize]
233     mulps   m1, m1, [src0q + lenq]
234     mova    [dstq + lenq + mmsize], m0
235     mova    [dstq + lenq], m1
236     add     src1q, 2*mmsize
237     sub     lenq,  2*mmsize
238     jge     .loop
239     REP_RET
240 %endmacro
241
242 INIT_XMM sse
243 VECTOR_FMUL_REVERSE
244 %if HAVE_AVX_EXTERNAL
245 INIT_YMM avx
246 VECTOR_FMUL_REVERSE
247 %endif
248
249 ; float scalarproduct_float_sse(const float *v1, const float *v2, int len)
250 INIT_XMM sse
251 cglobal scalarproduct_float, 3,3,2, v1, v2, offset
252     neg   offsetq
253     shl   offsetq, 2
254     sub       v1q, offsetq
255     sub       v2q, offsetq
256     xorps    xmm0, xmm0
257 .loop:
258     movaps   xmm1, [v1q+offsetq]
259     mulps    xmm1, [v2q+offsetq]
260     addps    xmm0, xmm1
261     add   offsetq, 16
262     js .loop
263     movhlps  xmm1, xmm0
264     addps    xmm0, xmm1
265     movss    xmm1, xmm0
266     shufps   xmm0, xmm0, 1
267     addss    xmm0, xmm1
268 %if ARCH_X86_64 == 0
269     movss     r0m,  xmm0
270     fld dword r0m
271 %endif
272     RET
273
274 ;-----------------------------------------------------------------------------
275 ; void ff_butterflies_float(float *src0, float *src1, int len);
276 ;-----------------------------------------------------------------------------
277 INIT_XMM sse
278 cglobal butterflies_float, 3,3,3, src0, src1, len
279 %if ARCH_X86_64
280     movsxd    lenq, lend
281 %endif
282     test      lenq, lenq
283     jz .end
284     shl       lenq, 2
285     add      src0q, lenq
286     add      src1q, lenq
287     neg       lenq
288 .loop:
289     mova        m0, [src0q + lenq]
290     mova        m1, [src1q + lenq]
291     subps       m2, m0, m1
292     addps       m0, m0, m1
293     mova        [src1q + lenq], m2
294     mova        [src0q + lenq], m0
295     add       lenq, mmsize
296     jl .loop
297 .end:
298     REP_RET