avutil/x86util: move haddps sse emulation from showcqt
[ffmpeg.git] / libavfilter / x86 / avf_showcqt.asm
1 ;*****************************************************************************
2 ;* x86-optimized functions for showcqt filter
3 ;*
4 ;* Copyright (C) 2016 Muhammad Faiz <mfcc64@gmail.com>
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 "libavutil/x86/x86util.asm"
24
25 %if ARCH_X86_64
26 %define pointer resq
27 %else
28 %define pointer resd
29 %endif
30
31 struc Coeffs
32     .val:   pointer 1
33     .start: resd 1
34     .len:   resd 1
35     .sizeof:
36 endstruc
37
38 %macro EMULATE_FMADDPS 5 ; dst, src1, src2, src3, tmp
39 %if cpuflag(fma3) || cpuflag(fma4)
40     fmaddps %1, %2, %3, %4
41 %else
42     mulps   %5, %2, %3
43     addps   %1, %4, %5
44 %endif
45 %endmacro ; EMULATE_FMADDPS
46
47 %macro CQT_CALC 9
48 ; %1 = a_re, %2 = a_im, %3 = b_re, %4 = b_im
49 ; %5 = m_re, %6 = m_im, %7 = tmp, %8 = coeffval, %9 = coeffsq_offset
50     mov     id, xd
51     add     id, [coeffsq + Coeffs.start + %9]
52     movaps  m%5, [srcq + 8 * iq]
53     movaps  m%7, [srcq + 8 * iq + mmsize]
54     shufps  m%6, m%5, m%7, q3131
55     shufps  m%5, m%5, m%7, q2020
56     sub     id, fft_lend
57     EMULATE_FMADDPS m%2, m%6, m%8, m%2, m%6
58     neg     id
59     EMULATE_FMADDPS m%1, m%5, m%8, m%1, m%5
60     movups  m%5, [srcq + 8 * iq - mmsize + 8]
61     movups  m%7, [srcq + 8 * iq - 2*mmsize + 8]
62     %if mmsize == 32
63     vperm2f128 m%5, m%5, m%5, 1
64     vperm2f128 m%7, m%7, m%7, 1
65     %endif
66     shufps  m%6, m%5, m%7, q1313
67     shufps  m%5, m%5, m%7, q0202
68     EMULATE_FMADDPS m%4, m%6, m%8, m%4, m%6
69     EMULATE_FMADDPS m%3, m%5, m%8, m%3, m%5
70 %endmacro ; CQT_CALC
71
72 %macro CQT_SEPARATE 6 ; a_re, a_im, b_re, b_im, tmp, tmp2
73     addps   m%5, m%4, m%2
74     subps   m%6, m%3, m%1
75     addps   m%1, m%3
76     subps   m%2, m%4
77     HADDPS  m%5, m%6, m%3
78     HADDPS  m%1, m%2, m%3
79     HADDPS  m%1, m%5, m%2
80     %if mmsize == 32
81     vextractf128 xmm%2, m%1, 1
82     addps   xmm%1, xmm%2
83     %endif
84 %endmacro ; CQT_SEPARATE
85
86 %macro DECLARE_CQT_CALC 0
87 ; ff_showcqt_cqt_calc_*(dst, src, coeffs, len, fft_len)
88 %if ARCH_X86_64
89 cglobal showcqt_cqt_calc, 5, 10, 12, dst, src, coeffs, len, fft_len, x, coeffs_val, coeffs_val2, i, coeffs_len
90     align   16
91     .loop_k:
92         mov     xd, [coeffsq + Coeffs.len]
93         xorps   m0, m0
94         movaps  m1, m0
95         movaps  m2, m0
96         mov     coeffs_lend, [coeffsq + Coeffs.len + Coeffs.sizeof]
97         movaps  m3, m0
98         movaps  m8, m0
99         cmp     coeffs_lend, xd
100         movaps  m9, m0
101         movaps  m10, m0
102         movaps  m11, m0
103         cmova   coeffs_lend, xd
104         xor     xd, xd
105         test    coeffs_lend, coeffs_lend
106         jz      .check_loop_b
107         mov     coeffs_valq, [coeffsq + Coeffs.val]
108         mov     coeffs_val2q, [coeffsq + Coeffs.val + Coeffs.sizeof]
109         align   16
110         .loop_ab:
111             movaps  m7, [coeffs_valq + 4 * xq]
112             CQT_CALC 0, 1, 2, 3, 4, 5, 6, 7, 0
113             movaps  m7, [coeffs_val2q + 4 * xq]
114             CQT_CALC 8, 9, 10, 11, 4, 5, 6, 7, Coeffs.sizeof
115             add     xd, mmsize/4
116             cmp     xd, coeffs_lend
117             jb      .loop_ab
118         .check_loop_b:
119         cmp     xd, [coeffsq + Coeffs.len + Coeffs.sizeof]
120         jae     .check_loop_a
121         align   16
122         .loop_b:
123             movaps  m7, [coeffs_val2q + 4 * xq]
124             CQT_CALC 8, 9, 10, 11, 4, 5, 6, 7, Coeffs.sizeof
125             add     xd, mmsize/4
126             cmp     xd, [coeffsq + Coeffs.len + Coeffs.sizeof]
127             jb      .loop_b
128         .loop_end:
129         CQT_SEPARATE 0, 1, 2, 3, 4, 5
130         CQT_SEPARATE 8, 9, 10, 11, 4, 5
131         mulps   xmm0, xmm0
132         mulps   xmm8, xmm8
133         HADDPS  xmm0, xmm8, xmm1
134         movaps  [dstq], xmm0
135         sub     lend, 2
136         lea     dstq, [dstq + 16]
137         lea     coeffsq, [coeffsq + 2*Coeffs.sizeof]
138         jnz     .loop_k
139         REP_RET
140         align   16
141         .check_loop_a:
142         cmp     xd, [coeffsq + Coeffs.len]
143         jae     .loop_end
144         align   16
145         .loop_a:
146             movaps  m7, [coeffs_valq + 4 * xq]
147             CQT_CALC 0, 1, 2, 3, 4, 5, 6, 7, 0
148             add     xd, mmsize/4
149             cmp     xd, [coeffsq + Coeffs.len]
150             jb      .loop_a
151         jmp     .loop_end
152 %else
153 cglobal showcqt_cqt_calc, 4, 7, 8, dst, src, coeffs, len, x, coeffs_val, i
154 %define fft_lend r4m
155     align   16
156     .loop_k:
157         mov     xd, [coeffsq + Coeffs.len]
158         xorps   m0, m0
159         movaps  m1, m0
160         movaps  m2, m0
161         movaps  m3, m0
162         test    xd, xd
163         jz      .store
164         mov     coeffs_valq, [coeffsq + Coeffs.val]
165         xor     xd, xd
166         align   16
167         .loop_x:
168             movaps  m7, [coeffs_valq + 4 * xq]
169             CQT_CALC 0, 1, 2, 3, 4, 5, 6, 7, 0
170             add     xd, mmsize/4
171             cmp     xd, [coeffsq + Coeffs.len]
172             jb      .loop_x
173         CQT_SEPARATE 0, 1, 2, 3, 4, 5
174         mulps   xmm0, xmm0
175         HADDPS  xmm0, xmm0, xmm1
176         .store:
177         movlps  [dstq], xmm0
178         sub     lend, 1
179         lea     dstq, [dstq + 8]
180         lea     coeffsq, [coeffsq + Coeffs.sizeof]
181         jnz     .loop_k
182         REP_RET
183 %endif ; ARCH_X86_64
184 %endmacro ; DECLARE_CQT_CALC
185
186 INIT_XMM sse
187 DECLARE_CQT_CALC
188 INIT_XMM sse3
189 DECLARE_CQT_CALC
190 INIT_YMM avx
191 DECLARE_CQT_CALC
192 INIT_YMM fma3
193 DECLARE_CQT_CALC
194 INIT_XMM fma4
195 DECLARE_CQT_CALC