bb8a7f5df013490dcb2dae5c80890d75d5c6d0a6
[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     shl      nd, 3
97     add      lq, nq
98     add      rq, nq
99     neg      nq
100
101 align 16
102 .loop:
103     addps    m0, m1
104     movddup  m2, [lq+nq]
105     movddup  m3, [rq+nq]
106     movaps   m4, m0
107     movaps   m5, m0
108     unpcklps m4, m4
109     unpckhps m5, m5
110     mulps    m2, m4
111     mulps    m3, m5
112     addps    m2, m3
113     movsd  [lq+nq], m2
114     movhps [rq+nq], m2
115     add      nq, 8
116     jl .loop
117 .ret:
118     REP_RET
119
120 ;***************************************************************************
121 ;void ps_stereo_interpolate_ipdopd_sse3(float (*l)[2], float (*r)[2],
122 ;                                       float h[2][4], float h_step[2][4],
123 ;                                       int len);
124 ;***************************************************************************
125 INIT_XMM sse3
126 cglobal ps_stereo_interpolate_ipdopd, 5, 5, 10, l, r, h, h_step, n
127     cmp      nd, 0
128     jle .ret
129     movaps   m0, [hq]
130     movaps   m1, [hq+mmsize]
131 %if ARCH_X86_64
132     movaps   m8, [h_stepq]
133     movaps   m9, [h_stepq+mmsize]
134     %define  H_STEP0 m8
135     %define  H_STEP1 m9
136 %else
137     %define  H_STEP0 [h_stepq]
138     %define  H_STEP1 [h_stepq+mmsize]
139 %endif
140     shl      nd, 3
141     add      lq, nq
142     add      rq, nq
143     neg      nq
144
145 align 16
146 .loop:
147     addps    m0, H_STEP0
148     addps    m1, H_STEP1
149     movddup  m2, [lq+nq]
150     movddup  m3, [rq+nq]
151     shufps   m4, m2, m2, q2301
152     shufps   m5, m3, m3, q2301
153     unpcklps m6, m0, m0
154     unpckhps m7, m0, m0
155     mulps    m2, m6
156     mulps    m3, m7
157     unpcklps m6, m1, m1
158     unpckhps m7, m1, m1
159     mulps    m4, m6
160     mulps    m5, m7
161     addps    m2, m3
162     addsubps m4, m5
163     addsubps m2, m4
164     movsd  [lq+nq], m2
165     movhps [rq+nq], m2
166     add      nq, 8
167     jl .loop
168 .ret:
169     REP_RET
170
171 ;*******************************************************************
172 ;void ff_ps_hybrid_analysis_<opt>(float (*out)[2], float (*in)[2],
173 ;                                 const float (*filter)[8][2],
174 ;                                 int stride, int n);
175 ;*******************************************************************
176 %macro PS_HYBRID_ANALYSIS_LOOP 3
177     movu     %1, [inq+mmsize*%3]
178     movu     m1, [inq+mmsize*(5-%3)+8]
179 %if cpuflag(sse3)
180     pshufd   %2, %1, q2301
181     pshufd   m4, m1, q0123
182     pshufd   m1, m1, q1032
183     pshufd   m2, [filterq+nq+mmsize*%3], q2301
184     addsubps %2, m4
185     addsubps %1, m1
186 %else
187     mova     m2, [filterq+nq+mmsize*%3]
188     mova     %2, %1
189     mova     m4, m1
190     shufps   %2, %2, q2301
191     shufps   m4, m4, q0123
192     shufps   m1, m1, q1032
193     shufps   m2, m2, q2301
194     xorps    m4, m7
195     xorps    m1, m7
196     subps    %2, m4
197     subps    %1, m1
198 %endif
199     mulps    %2, m2
200     mulps    %1, m2
201 %if %3
202     addps    m3, %2
203     addps    m0, %1
204 %endif
205 %endmacro
206
207 %macro PS_HYBRID_ANALYSIS 0
208 cglobal ps_hybrid_analysis, 5, 5, 8, out, in, filter, stride, n
209 %if cpuflag(sse3)
210 %define MOVH movsd
211 %else
212 %define MOVH movlps
213 %endif
214     shl strided, 3
215     shl nd, 6
216     add filterq, nq
217     neg nq
218     mova m7, [ps_p1m1p1m1]
219
220 align 16
221 .loop:
222     PS_HYBRID_ANALYSIS_LOOP m0, m3, 0
223     PS_HYBRID_ANALYSIS_LOOP m5, m6, 1
224     PS_HYBRID_ANALYSIS_LOOP m5, m6, 2
225
226 %if cpuflag(sse3)
227     pshufd   m3, m3, q2301
228     xorps    m0, m7
229     hsubps   m3, m0
230     pshufd   m1, m3, q0020
231     pshufd   m3, m3, q0031
232     addps    m1, m3
233     movsd    m2, [inq+6*8]
234 %else
235     mova     m1, m3
236     mova     m2, m0
237     shufps   m1, m1, q2301
238     shufps   m2, m2, q2301
239     subps    m1, m3
240     addps    m2, m0
241     unpcklps m3, m1, m2
242     unpckhps m1, m2
243     addps    m1, m3
244     movu     m2, [inq+6*8] ; faster than movlps and no risk of overread
245 %endif
246     movss    m3, [filterq+nq+8*6]
247     SPLATD   m3
248     mulps    m2, m3
249     addps    m1, m2
250     MOVH [outq], m1
251     add    outq, strideq
252     add      nq, 64
253     jl .loop
254     REP_RET
255 %endmacro
256
257 INIT_XMM sse
258 PS_HYBRID_ANALYSIS
259 INIT_XMM sse3
260 PS_HYBRID_ANALYSIS