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