x86/aacpsdsp: optimize ff_ps_stereo_interpolate_sse3
[ffmpeg.git] / libavcodec / x86 / aacpsdsp.asm
1 ;******************************************************************************
2 ;* SIMD optimized MPEG-4 Parametric Stereo decoding functions
3 ;*
4 ;* Copyright (C) 2015 James Almer
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 SECTION_RODATA
26
27 ps_p1m1p1m1: dd 0, 0x80000000, 0, 0x80000000
28
29 SECTION .text
30
31 ;*************************************************************************
32 ;void ff_ps_add_squares_<opt>(float *dst, const float (*src)[2], int n);
33 ;*************************************************************************
34 %macro PS_ADD_SQUARES 1
35 cglobal ps_add_squares, 3, 3, %1, dst, src, n
36     shl    nd, 3
37     add  srcq, nq
38     neg    nq
39
40 align 16
41 .loop:
42     movaps m0, [srcq+nq]
43     movaps m1, [srcq+nq+mmsize]
44     mulps  m0, m0
45     mulps  m1, m1
46     HADDPS m0, m1, m2
47     addps  m0, [dstq]
48     movaps [dstq], m0
49     add  dstq, mmsize
50     add    nq, mmsize*2
51     jl .loop
52     REP_RET
53 %endmacro
54
55 INIT_XMM sse
56 PS_ADD_SQUARES 2
57 INIT_XMM sse3
58 PS_ADD_SQUARES 3
59
60 ;*******************************************************************
61 ;void ff_ps_mul_pair_single_sse(float (*dst)[2], float (*src0)[2],
62 ;                                   float *src1, int n);
63 ;*******************************************************************
64 INIT_XMM sse
65 cglobal ps_mul_pair_single, 4, 5, 4, dst, src1, src2, n
66     xor r4q, r4q
67
68 .loop:
69     movu     m0, [src1q+r4q]
70     movu     m1, [src1q+r4q+mmsize]
71     mova     m2, [src2q]
72     mova     m3, m2
73     unpcklps m2, m2
74     unpckhps m3, m3
75     mulps    m0, m2
76     mulps    m1, m3
77     mova [dstq+r4q], m0
78     mova [dstq+r4q+mmsize], m1
79     add   src2q, mmsize
80     add     r4q, mmsize*2
81     sub      nd, mmsize/4
82     jg .loop
83     REP_RET
84
85 ;***********************************************************************
86 ;void ff_ps_stereo_interpolate_sse3(float (*l)[2], float (*r)[2],
87 ;                                   float h[2][4], float h_step[2][4],
88 ;                                   int len);
89 ;***********************************************************************
90 INIT_XMM sse3
91 cglobal ps_stereo_interpolate, 5, 5, 6, l, r, h, h_step, n
92     movaps   m0, [hq]
93     movaps   m1, [h_stepq]
94     cmp      nd, 0
95     jle .ret
96     unpcklps m4, m0, m0
97     unpckhps m0, m0
98     unpcklps m5, m1, m1
99     unpckhps m1, m1
100     shl      nd, 3
101     add      lq, nq
102     add      rq, nq
103     neg      nq
104
105 align 16
106 .loop:
107     addps    m4, m5
108     addps    m0, m1
109     movddup  m2, [lq+nq]
110     movddup  m3, [rq+nq]
111     mulps    m2, m4
112     mulps    m3, m0
113     addps    m2, m3
114     movsd  [lq+nq], m2
115     movhps [rq+nq], m2
116     add      nq, 8
117     jl .loop
118 .ret:
119     REP_RET
120
121 ;***************************************************************************
122 ;void ps_stereo_interpolate_ipdopd_sse3(float (*l)[2], float (*r)[2],
123 ;                                       float h[2][4], float h_step[2][4],
124 ;                                       int len);
125 ;***************************************************************************
126 INIT_XMM sse3
127 cglobal ps_stereo_interpolate_ipdopd, 5, 5, 10, l, r, h, h_step, n
128     cmp      nd, 0
129     jle .ret
130     movaps   m0, [hq]
131     movaps   m1, [hq+mmsize]
132 %if ARCH_X86_64
133     movaps   m8, [h_stepq]
134     movaps   m9, [h_stepq+mmsize]
135     %define  H_STEP0 m8
136     %define  H_STEP1 m9
137 %else
138     %define  H_STEP0 [h_stepq]
139     %define  H_STEP1 [h_stepq+mmsize]
140 %endif
141     shl      nd, 3
142     add      lq, nq
143     add      rq, nq
144     neg      nq
145
146 align 16
147 .loop:
148     addps    m0, H_STEP0
149     addps    m1, H_STEP1
150     movddup  m2, [lq+nq]
151     movddup  m3, [rq+nq]
152     shufps   m4, m2, m2, q2301
153     shufps   m5, m3, m3, q2301
154     unpcklps m6, m0, m0
155     unpckhps m7, m0, m0
156     mulps    m2, m6
157     mulps    m3, m7
158     unpcklps m6, m1, m1
159     unpckhps m7, m1, m1
160     mulps    m4, m6
161     mulps    m5, m7
162     addps    m2, m3
163     addsubps m4, m5
164     addsubps m2, m4
165     movsd  [lq+nq], m2
166     movhps [rq+nq], m2
167     add      nq, 8
168     jl .loop
169 .ret:
170     REP_RET
171
172 ;*******************************************************************
173 ;void ff_ps_hybrid_analysis_<opt>(float (*out)[2], float (*in)[2],
174 ;                                 const float (*filter)[8][2],
175 ;                                 int stride, int n);
176 ;*******************************************************************
177 %macro PS_HYBRID_ANALYSIS_LOOP 3
178     movu     %1, [inq+mmsize*%3]
179     movu     m1, [inq+mmsize*(5-%3)+8]
180 %if cpuflag(sse3)
181     pshufd   %2, %1, q2301
182     pshufd   m4, m1, q0123
183     pshufd   m1, m1, q1032
184     pshufd   m2, [filterq+nq+mmsize*%3], q2301
185     addsubps %2, m4
186     addsubps %1, m1
187 %else
188     mova     m2, [filterq+nq+mmsize*%3]
189     mova     %2, %1
190     mova     m4, m1
191     shufps   %2, %2, q2301
192     shufps   m4, m4, q0123
193     shufps   m1, m1, q1032
194     shufps   m2, m2, q2301
195     xorps    m4, m7
196     xorps    m1, m7
197     subps    %2, m4
198     subps    %1, m1
199 %endif
200     mulps    %2, m2
201     mulps    %1, m2
202 %if %3
203     addps    m3, %2
204     addps    m0, %1
205 %endif
206 %endmacro
207
208 %macro PS_HYBRID_ANALYSIS 0
209 cglobal ps_hybrid_analysis, 5, 5, 8, out, in, filter, stride, n
210 %if cpuflag(sse3)
211 %define MOVH movsd
212 %else
213 %define MOVH movlps
214 %endif
215     shl strided, 3
216     shl nd, 6
217     add filterq, nq
218     neg nq
219     mova m7, [ps_p1m1p1m1]
220
221 align 16
222 .loop:
223     PS_HYBRID_ANALYSIS_LOOP m0, m3, 0
224     PS_HYBRID_ANALYSIS_LOOP m5, m6, 1
225     PS_HYBRID_ANALYSIS_LOOP m5, m6, 2
226
227 %if cpuflag(sse3)
228     pshufd   m3, m3, q2301
229     xorps    m0, m7
230     hsubps   m3, m0
231     pshufd   m1, m3, q0020
232     pshufd   m3, m3, q0031
233     addps    m1, m3
234     movsd    m2, [inq+6*8]
235 %else
236     mova     m1, m3
237     mova     m2, m0
238     shufps   m1, m1, q2301
239     shufps   m2, m2, q2301
240     subps    m1, m3
241     addps    m2, m0
242     unpcklps m3, m1, m2
243     unpckhps m1, m2
244     addps    m1, m3
245     movu     m2, [inq+6*8] ; faster than movlps and no risk of overread
246 %endif
247     movss    m3, [filterq+nq+8*6]
248     SPLATD   m3
249     mulps    m2, m3
250     addps    m1, m2
251     MOVH [outq], m1
252     add    outq, strideq
253     add      nq, 64
254     jl .loop
255     REP_RET
256 %endmacro
257
258 INIT_XMM sse
259 PS_HYBRID_ANALYSIS
260 INIT_XMM sse3
261 PS_HYBRID_ANALYSIS