x86/aacpsdsp: add ff_ps_hybrid_synthesis_deint_{sse,sse4}
[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, 4, 4, dst, src1, src2, n
66     shl      nd, 3
67     add   src1q, nq
68     add    dstq, nq
69     neg      nq
70
71 align 16
72 .loop:
73     movu     m0, [src1q+nq]
74     movu     m1, [src1q+nq+mmsize]
75     mova     m2, [src2q]
76     mova     m3, m2
77     unpcklps m2, m2
78     unpckhps m3, m3
79     mulps    m0, m2
80     mulps    m1, m3
81     mova [dstq+nq], m0
82     mova [dstq+nq+mmsize], m1
83     add   src2q, mmsize
84     add      nq, mmsize*2
85     jl .loop
86     REP_RET
87
88 ;***********************************************************************
89 ;void ff_ps_stereo_interpolate_sse3(float (*l)[2], float (*r)[2],
90 ;                                   float h[2][4], float h_step[2][4],
91 ;                                   int len);
92 ;***********************************************************************
93 INIT_XMM sse3
94 cglobal ps_stereo_interpolate, 5, 5, 6, l, r, h, h_step, n
95     movaps   m0, [hq]
96     movaps   m1, [h_stepq]
97     unpcklps m4, m0, m0
98     unpckhps m0, m0
99     unpcklps m5, m1, m1
100     unpckhps m1, m1
101     shl      nd, 3
102     add      lq, nq
103     add      rq, nq
104     neg      nq
105
106 align 16
107 .loop:
108     addps    m4, m5
109     addps    m0, m1
110     movddup  m2, [lq+nq]
111     movddup  m3, [rq+nq]
112     mulps    m2, m4
113     mulps    m3, m0
114     addps    m2, m3
115     movsd  [lq+nq], m2
116     movhps [rq+nq], m2
117     add      nq, 8
118     jl .loop
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     movaps   m0, [hq]
129     movaps   m1, [hq+mmsize]
130 %if ARCH_X86_64
131     movaps   m8, [h_stepq]
132     movaps   m9, [h_stepq+mmsize]
133     %define  H_STEP0 m8
134     %define  H_STEP1 m9
135 %else
136     %define  H_STEP0 [h_stepq]
137     %define  H_STEP1 [h_stepq+mmsize]
138 %endif
139     shl      nd, 3
140     add      lq, nq
141     add      rq, nq
142     neg      nq
143
144 align 16
145 .loop:
146     addps    m0, H_STEP0
147     addps    m1, H_STEP1
148     movddup  m2, [lq+nq]
149     movddup  m3, [rq+nq]
150     shufps   m4, m2, m2, q2301
151     shufps   m5, m3, m3, q2301
152     unpcklps m6, m0, m0
153     unpckhps m7, m0, m0
154     mulps    m2, m6
155     mulps    m3, m7
156     unpcklps m6, m1, m1
157     unpckhps m7, m1, m1
158     mulps    m4, m6
159     mulps    m5, m7
160     addps    m2, m3
161     addsubps m2, m4
162     addsubps m2, m5
163     movsd  [lq+nq], m2
164     movhps [rq+nq], m2
165     add      nq, 8
166     jl .loop
167     REP_RET
168
169 ;***********************************************************
170 ;void ps_hybrid_synthesis_deint_sse4(float out[2][38][64],
171 ;                                    float (*in)[32][2],
172 ;                                    int i, int len)
173 ;***********************************************************
174 %macro HYBRID_SYNTHESIS_DEINT 0
175 cglobal ps_hybrid_synthesis_deint, 3, 7, 5, out, in, i, len, out0, out1, tmp
176 %if cpuflag(sse4)
177 %define MOVH movsd
178 %else
179 %define MOVH movlps
180 %endif
181     movsxdifnidn        iq, id
182     mov               lend, 32 << 3
183     lea               outq, [outq+iq*4]
184     mov               tmpd, id
185     shl               tmpd, 8
186     add                inq, tmpq
187     mov               tmpd, 64
188     sub               tmpd, id
189     mov                 id, tmpd
190
191     test                id, 1
192     jne .loop4
193     test                id, 2
194     jne .loop8
195
196 align 16
197 .loop16:
198     mov              out0q, outq
199     mov              out1q, 38*64*4
200     add              out1q, out0q
201     mov               tmpd, lend
202
203 .inner_loop16:
204     movaps              m0, [inq]
205     movaps              m1, [inq+lenq]
206     movaps              m2, [inq+lenq*2]
207     movaps              m3, [inq+3*32*2*4]
208     TRANSPOSE4x4PS 0, 1, 2, 3, 4
209     movaps         [out0q], m0
210     movaps         [out1q], m1
211     movaps    [out0q+lenq], m2
212     movaps    [out1q+lenq], m3
213     lea              out0q, [out0q+lenq*2]
214     lea              out1q, [out1q+lenq*2]
215     add                inq, mmsize
216     sub               tmpd, mmsize
217     jg .inner_loop16
218     add               outq, 16
219     add                inq, 3*32*2*4
220     sub                 id, 4
221     jg .loop16
222     RET
223
224 align 16
225 .loop8:
226     mov              out0q, outq
227     mov              out1q, 38*64*4
228     add              out1q, out0q
229     mov               tmpd, lend
230
231 .inner_loop8:
232     movaps              m0, [inq]
233     movaps              m1, [inq+lenq]
234     SBUTTERFLYPS 0, 1, 2
235     SBUTTERFLYPD 0, 1, 2
236     MOVH           [out0q], m0
237     MOVH           [out1q], m1
238     movhps    [out0q+lenq], m0
239     movhps    [out1q+lenq], m1
240     lea              out0q, [out0q+lenq*2]
241     lea              out1q, [out1q+lenq*2]
242     add                inq, mmsize
243     sub               tmpd, mmsize
244     jg .inner_loop8
245     add               outq, 8
246     add                inq, lenq
247     sub                 id, 2
248     jg .loop16
249     RET
250
251 align 16
252 .loop4:
253     mov              out0q, outq
254     mov              out1q, 38*64*4
255     add              out1q, out0q
256     mov               tmpd, lend
257
258 .inner_loop4:
259     movaps              m0, [inq]
260     movss          [out0q], m0
261 %if cpuflag(sse4)
262     extractps      [out1q], m0, 1
263     extractps [out0q+lenq], m0, 2
264     extractps [out1q+lenq], m0, 3
265 %else
266     movhlps             m1, m0
267     movss     [out0q+lenq], m1
268     shufps              m0, m0, 0xb1
269     movss          [out1q], m0
270     movhlps             m1, m0
271     movss     [out1q+lenq], m1
272 %endif
273     lea              out0q, [out0q+lenq*2]
274     lea              out1q, [out1q+lenq*2]
275     add                inq, mmsize
276     sub               tmpd, mmsize
277     jg .inner_loop4
278     add               outq, 4
279     sub                 id, 1
280     test                id, 2
281     jne .loop8
282     cmp                 id, 4
283     jge .loop16
284     RET
285 %endmacro
286
287 INIT_XMM sse
288 HYBRID_SYNTHESIS_DEINT
289 INIT_XMM sse4
290 HYBRID_SYNTHESIS_DEINT
291
292 ;*******************************************************************
293 ;void ff_ps_hybrid_analysis_<opt>(float (*out)[2], float (*in)[2],
294 ;                                 const float (*filter)[8][2],
295 ;                                 int stride, int n);
296 ;*******************************************************************
297 %macro PS_HYBRID_ANALYSIS_LOOP 3
298     movu     %1, [inq+mmsize*%3]
299     movu     m1, [inq+mmsize*(5-%3)+8]
300 %if cpuflag(sse3)
301     pshufd   %2, %1, q2301
302     pshufd   m4, m1, q0123
303     pshufd   m1, m1, q1032
304     pshufd   m2, [filterq+nq+mmsize*%3], q2301
305     addsubps %2, m4
306     addsubps %1, m1
307 %else
308     mova     m2, [filterq+nq+mmsize*%3]
309     mova     %2, %1
310     mova     m4, m1
311     shufps   %2, %2, q2301
312     shufps   m4, m4, q0123
313     shufps   m1, m1, q1032
314     shufps   m2, m2, q2301
315     xorps    m4, m7
316     xorps    m1, m7
317     subps    %2, m4
318     subps    %1, m1
319 %endif
320     mulps    %2, m2
321     mulps    %1, m2
322 %if %3
323     addps    m3, %2
324     addps    m0, %1
325 %endif
326 %endmacro
327
328 %macro PS_HYBRID_ANALYSIS 0
329 cglobal ps_hybrid_analysis, 5, 5, 8, out, in, filter, stride, n
330 %if cpuflag(sse3)
331 %define MOVH movsd
332 %else
333 %define MOVH movlps
334 %endif
335     shl strided, 3
336     shl nd, 6
337     add filterq, nq
338     neg nq
339     mova m7, [ps_p1m1p1m1]
340
341 align 16
342 .loop:
343     PS_HYBRID_ANALYSIS_LOOP m0, m3, 0
344     PS_HYBRID_ANALYSIS_LOOP m5, m6, 1
345     PS_HYBRID_ANALYSIS_LOOP m5, m6, 2
346
347 %if cpuflag(sse3)
348     pshufd   m3, m3, q2301
349     xorps    m0, m7
350     hsubps   m3, m0
351     pshufd   m1, m3, q0020
352     pshufd   m3, m3, q0031
353     addps    m1, m3
354     movsd    m2, [inq+6*8]
355 %else
356     mova     m1, m3
357     mova     m2, m0
358     shufps   m1, m1, q2301
359     shufps   m2, m2, q2301
360     subps    m1, m3
361     addps    m2, m0
362     unpcklps m3, m1, m2
363     unpckhps m1, m2
364     addps    m1, m3
365     movu     m2, [inq+6*8] ; faster than movlps and no risk of overread
366 %endif
367     movss    m3, [filterq+nq+8*6]
368     SPLATD   m3
369     mulps    m2, m3
370     addps    m1, m2
371     MOVH [outq], m1
372     add    outq, strideq
373     add      nq, 64
374     jl .loop
375     REP_RET
376 %endmacro
377
378 INIT_XMM sse
379 PS_HYBRID_ANALYSIS
380 INIT_XMM sse3
381 PS_HYBRID_ANALYSIS