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