x86/float_dsp: add ff_vector_dmac_scalar_{sse2,avx,fma3}
[ffmpeg.git] / 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,5, dst, src, len
65 %else
66 cglobal vector_fmac_scalar, 4,4,5, dst, src, mul, len
67 %endif
68 %if ARCH_X86_32
69     VBROADCASTSS m0, mulm
70 %else
71 %if WIN64
72     SWAP 0, 2
73 %endif
74     shufps      xm0, xm0, 0
75 %if cpuflag(avx)
76     vinsertf128  m0, m0, xm0, 1
77 %endif
78 %endif
79     lea    lenq, [lend*4-64]
80 .loop:
81 %if cpuflag(fma3)
82     mova     m1,     [dstq+lenq]
83     mova     m2,     [dstq+lenq+1*mmsize]
84     fmaddps  m1, m0, [srcq+lenq], m1
85     fmaddps  m2, m0, [srcq+lenq+1*mmsize], m2
86 %else ; cpuflag
87     mulps    m1, m0, [srcq+lenq]
88     mulps    m2, m0, [srcq+lenq+1*mmsize]
89 %if mmsize < 32
90     mulps    m3, m0, [srcq+lenq+2*mmsize]
91     mulps    m4, m0, [srcq+lenq+3*mmsize]
92 %endif ; mmsize
93     addps    m1, m1, [dstq+lenq]
94     addps    m2, m2, [dstq+lenq+1*mmsize]
95 %if mmsize < 32
96     addps    m3, m3, [dstq+lenq+2*mmsize]
97     addps    m4, m4, [dstq+lenq+3*mmsize]
98 %endif ; mmsize
99 %endif ; cpuflag
100     mova  [dstq+lenq], m1
101     mova  [dstq+lenq+1*mmsize], m2
102 %if mmsize < 32
103     mova  [dstq+lenq+2*mmsize], m3
104     mova  [dstq+lenq+3*mmsize], m4
105 %endif ; mmsize
106     sub    lenq, 64
107     jge .loop
108     REP_RET
109 %endmacro
110
111 INIT_XMM sse
112 VECTOR_FMAC_SCALAR
113 %if HAVE_AVX_EXTERNAL
114 INIT_YMM avx
115 VECTOR_FMAC_SCALAR
116 %endif
117 %if HAVE_FMA3_EXTERNAL
118 INIT_YMM fma3
119 VECTOR_FMAC_SCALAR
120 %endif
121
122 ;------------------------------------------------------------------------------
123 ; void ff_vector_fmul_scalar(float *dst, const float *src, float mul, int len)
124 ;------------------------------------------------------------------------------
125
126 %macro VECTOR_FMUL_SCALAR 0
127 %if UNIX64
128 cglobal vector_fmul_scalar, 3,3,2, dst, src, len
129 %else
130 cglobal vector_fmul_scalar, 4,4,3, dst, src, mul, len
131 %endif
132 %if ARCH_X86_32
133     movss    m0, mulm
134 %elif WIN64
135     SWAP 0, 2
136 %endif
137     shufps   m0, m0, 0
138     lea    lenq, [lend*4-mmsize]
139 .loop:
140     mova     m1, [srcq+lenq]
141     mulps    m1, m0
142     mova  [dstq+lenq], m1
143     sub    lenq, mmsize
144     jge .loop
145     REP_RET
146 %endmacro
147
148 INIT_XMM sse
149 VECTOR_FMUL_SCALAR
150
151 ;------------------------------------------------------------------------------
152 ; void ff_vector_dmac_scalar(double *dst, const double *src, double mul,
153 ;                            int len)
154 ;------------------------------------------------------------------------------
155
156 %macro VECTOR_DMAC_SCALAR 0
157 %if ARCH_X86_32
158 cglobal vector_dmac_scalar, 2,4,5, dst, src, mul, len, lenaddr
159     mov          lenq, lenaddrm
160     VBROADCASTSD m0, mulm
161 %else
162 %if UNIX64
163 cglobal vector_dmac_scalar, 3,3,5, dst, src, len
164 %else
165 cglobal vector_dmac_scalar, 4,4,5, dst, src, mul, len
166     SWAP 0, 2
167 %endif
168     movlhps     xm0, xm0
169 %if cpuflag(avx)
170     vinsertf128  m0, m0, xm0, 1
171 %endif
172 %endif
173     lea    lenq, [lend*8-mmsize*4]
174 .loop:
175 %if cpuflag(fma3)
176     movaps   m1,     [dstq+lenq]
177     movaps   m2,     [dstq+lenq+1*mmsize]
178     movaps   m3,     [dstq+lenq+2*mmsize]
179     movaps   m4,     [dstq+lenq+3*mmsize]
180     fmaddpd  m1, m0, [srcq+lenq], m1
181     fmaddpd  m2, m0, [srcq+lenq+1*mmsize], m2
182     fmaddpd  m3, m0, [srcq+lenq+2*mmsize], m3
183     fmaddpd  m4, m0, [srcq+lenq+3*mmsize], m4
184 %else ; cpuflag
185     mulpd    m1, m0, [srcq+lenq]
186     mulpd    m2, m0, [srcq+lenq+1*mmsize]
187     mulpd    m3, m0, [srcq+lenq+2*mmsize]
188     mulpd    m4, m0, [srcq+lenq+3*mmsize]
189     addpd    m1, m1, [dstq+lenq]
190     addpd    m2, m2, [dstq+lenq+1*mmsize]
191     addpd    m3, m3, [dstq+lenq+2*mmsize]
192     addpd    m4, m4, [dstq+lenq+3*mmsize]
193 %endif ; cpuflag
194     movaps [dstq+lenq], m1
195     movaps [dstq+lenq+1*mmsize], m2
196     movaps [dstq+lenq+2*mmsize], m3
197     movaps [dstq+lenq+3*mmsize], m4
198     sub    lenq, mmsize*4
199     jge .loop
200     REP_RET
201 %endmacro
202
203 INIT_XMM sse2
204 VECTOR_DMAC_SCALAR
205 %if HAVE_AVX_EXTERNAL
206 INIT_YMM avx
207 VECTOR_DMAC_SCALAR
208 %endif
209 %if HAVE_FMA3_EXTERNAL
210 INIT_YMM fma3
211 VECTOR_DMAC_SCALAR
212 %endif
213
214 ;------------------------------------------------------------------------------
215 ; void ff_vector_dmul_scalar(double *dst, const double *src, double mul,
216 ;                            int len)
217 ;------------------------------------------------------------------------------
218
219 %macro VECTOR_DMUL_SCALAR 0
220 %if ARCH_X86_32
221 cglobal vector_dmul_scalar, 3,4,3, dst, src, mul, len, lenaddr
222     mov          lenq, lenaddrm
223 %elif UNIX64
224 cglobal vector_dmul_scalar, 3,3,3, dst, src, len
225 %else
226 cglobal vector_dmul_scalar, 4,4,3, dst, src, mul, len
227 %endif
228 %if ARCH_X86_32
229     VBROADCASTSD   m0, mulm
230 %else
231 %if WIN64
232     SWAP 0, 2
233 %endif
234     movlhps       xm0, xm0
235 %if cpuflag(avx)
236     vinsertf128   ym0, ym0, xm0, 1
237 %endif
238 %endif
239     lea          lenq, [lend*8-2*mmsize]
240 .loop:
241     mulpd          m1, m0, [srcq+lenq       ]
242     mulpd          m2, m0, [srcq+lenq+mmsize]
243     mova   [dstq+lenq       ], m1
244     mova   [dstq+lenq+mmsize], m2
245     sub          lenq, 2*mmsize
246     jge .loop
247     REP_RET
248 %endmacro
249
250 INIT_XMM sse2
251 VECTOR_DMUL_SCALAR
252 %if HAVE_AVX_EXTERNAL
253 INIT_YMM avx
254 VECTOR_DMUL_SCALAR
255 %endif
256
257 ;-----------------------------------------------------------------------------
258 ; vector_fmul_window(float *dst, const float *src0,
259 ;                    const float *src1, const float *win, int len);
260 ;-----------------------------------------------------------------------------
261 %macro VECTOR_FMUL_WINDOW 0
262 cglobal vector_fmul_window, 5, 6, 6, dst, src0, src1, win, len, len1
263     shl     lend, 2
264     lea    len1q, [lenq - mmsize]
265     add    src0q, lenq
266     add     dstq, lenq
267     add     winq, lenq
268     neg     lenq
269 .loop:
270     mova      m0, [winq  + lenq]
271     mova      m4, [src0q + lenq]
272 %if cpuflag(sse)
273     mova      m1, [winq  + len1q]
274     mova      m5, [src1q + len1q]
275     shufps    m1, m1, 0x1b
276     shufps    m5, m5, 0x1b
277     mova      m2, m0
278     mova      m3, m1
279     mulps     m2, m4
280     mulps     m3, m5
281     mulps     m1, m4
282     mulps     m0, m5
283     addps     m2, m3
284     subps     m1, m0
285     shufps    m2, m2, 0x1b
286 %else
287     pswapd    m1, [winq  + len1q]
288     pswapd    m5, [src1q + len1q]
289     mova      m2, m0
290     mova      m3, m1
291     pfmul     m2, m4
292     pfmul     m3, m5
293     pfmul     m1, m4
294     pfmul     m0, m5
295     pfadd     m2, m3
296     pfsub     m1, m0
297     pswapd    m2, m2
298 %endif
299     mova      [dstq + lenq], m1
300     mova      [dstq + len1q], m2
301     sub       len1q, mmsize
302     add       lenq,  mmsize
303     jl .loop
304 %if mmsize == 8
305     femms
306 %endif
307     REP_RET
308 %endmacro
309
310 INIT_MMX 3dnowext
311 VECTOR_FMUL_WINDOW
312 INIT_XMM sse
313 VECTOR_FMUL_WINDOW
314
315 ;-----------------------------------------------------------------------------
316 ; vector_fmul_add(float *dst, const float *src0, const float *src1,
317 ;                 const float *src2, int len)
318 ;-----------------------------------------------------------------------------
319 %macro VECTOR_FMUL_ADD 0
320 cglobal vector_fmul_add, 5,5,4, dst, src0, src1, src2, len
321     lea       lenq, [lend*4 - 2*mmsize]
322 ALIGN 16
323 .loop:
324     mova    m0,   [src0q + lenq]
325     mova    m1,   [src0q + lenq + mmsize]
326 %if cpuflag(fma3)
327     mova    m2,     [src2q + lenq]
328     mova    m3,     [src2q + lenq + mmsize]
329     fmaddps m0, m0, [src1q + lenq], m2
330     fmaddps m1, m1, [src1q + lenq + mmsize], m3
331 %else
332     mulps   m0, m0, [src1q + lenq]
333     mulps   m1, m1, [src1q + lenq + mmsize]
334     addps   m0, m0, [src2q + lenq]
335     addps   m1, m1, [src2q + lenq + mmsize]
336 %endif
337     mova    [dstq + lenq], m0
338     mova    [dstq + lenq + mmsize], m1
339
340     sub     lenq,   2*mmsize
341     jge     .loop
342     REP_RET
343 %endmacro
344
345 INIT_XMM sse
346 VECTOR_FMUL_ADD
347 %if HAVE_AVX_EXTERNAL
348 INIT_YMM avx
349 VECTOR_FMUL_ADD
350 %endif
351 %if HAVE_FMA3_EXTERNAL
352 INIT_YMM fma3
353 VECTOR_FMUL_ADD
354 %endif
355
356 ;-----------------------------------------------------------------------------
357 ; void vector_fmul_reverse(float *dst, const float *src0, const float *src1,
358 ;                          int len)
359 ;-----------------------------------------------------------------------------
360 %macro VECTOR_FMUL_REVERSE 0
361 cglobal vector_fmul_reverse, 4,4,2, dst, src0, src1, len
362     lea       lenq, [lend*4 - 2*mmsize]
363 ALIGN 16
364 .loop:
365 %if cpuflag(avx)
366     vmovaps     xmm0, [src1q + 16]
367     vinsertf128 m0, m0, [src1q], 1
368     vshufps     m0, m0, m0, q0123
369     vmovaps     xmm1, [src1q + mmsize + 16]
370     vinsertf128 m1, m1, [src1q + mmsize], 1
371     vshufps     m1, m1, m1, q0123
372 %else
373     mova    m0, [src1q]
374     mova    m1, [src1q + mmsize]
375     shufps  m0, m0, q0123
376     shufps  m1, m1, q0123
377 %endif
378     mulps   m0, m0, [src0q + lenq + mmsize]
379     mulps   m1, m1, [src0q + lenq]
380     mova    [dstq + lenq + mmsize], m0
381     mova    [dstq + lenq], m1
382     add     src1q, 2*mmsize
383     sub     lenq,  2*mmsize
384     jge     .loop
385     REP_RET
386 %endmacro
387
388 INIT_XMM sse
389 VECTOR_FMUL_REVERSE
390 %if HAVE_AVX_EXTERNAL
391 INIT_YMM avx
392 VECTOR_FMUL_REVERSE
393 %endif
394
395 ; float scalarproduct_float_sse(const float *v1, const float *v2, int len)
396 INIT_XMM sse
397 cglobal scalarproduct_float, 3,3,2, v1, v2, offset
398     shl   offsetd, 2
399     add       v1q, offsetq
400     add       v2q, offsetq
401     neg   offsetq
402     xorps    xmm0, xmm0
403 .loop:
404     movaps   xmm1, [v1q+offsetq]
405     mulps    xmm1, [v2q+offsetq]
406     addps    xmm0, xmm1
407     add   offsetq, 16
408     js .loop
409     movhlps  xmm1, xmm0
410     addps    xmm0, xmm1
411     movss    xmm1, xmm0
412     shufps   xmm0, xmm0, 1
413     addss    xmm0, xmm1
414 %if ARCH_X86_64 == 0
415     movss     r0m,  xmm0
416     fld dword r0m
417 %endif
418     RET
419
420 ;-----------------------------------------------------------------------------
421 ; void ff_butterflies_float(float *src0, float *src1, int len);
422 ;-----------------------------------------------------------------------------
423 INIT_XMM sse
424 cglobal butterflies_float, 3,3,3, src0, src1, len
425     shl       lend, 2
426     add      src0q, lenq
427     add      src1q, lenq
428     neg       lenq
429 .loop:
430     mova        m0, [src0q + lenq]
431     mova        m1, [src1q + lenq]
432     subps       m2, m0, m1
433     addps       m0, m0, m1
434     mova        [src1q + lenq], m2
435     mova        [src0q + lenq], m0
436     add       lenq, mmsize
437     jl .loop
438     REP_RET