]> git.sesse.net Git - ffmpeg/blob - libavcodec/x86/flacdsp.asm
Merge commit '93f16f338f9e8aba0c006752eb3afc3fe6e137fd'
[ffmpeg] / libavcodec / x86 / flacdsp.asm
1 ;******************************************************************************
2 ;* FLAC DSP SIMD optimizations
3 ;*
4 ;* Copyright (C) 2014 Loren Merritt
5 ;* Copyright (C) 2014 James Almer
6 ;*
7 ;* This file is part of FFmpeg.
8 ;*
9 ;* FFmpeg is free software; you can redistribute it and/or
10 ;* modify it under the terms of the GNU Lesser General Public
11 ;* License as published by the Free Software Foundation; either
12 ;* version 2.1 of the License, or (at your option) any later version.
13 ;*
14 ;* FFmpeg is distributed in the hope that it will be useful,
15 ;* but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17 ;* Lesser General Public License for more details.
18 ;*
19 ;* You should have received a copy of the GNU Lesser General Public
20 ;* License along with FFmpeg; if not, write to the Free Software
21 ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 ;******************************************************************************
23
24 %include "libavutil/x86/x86util.asm"
25
26 SECTION .text
27
28 %macro LPC_32 1
29 INIT_XMM %1
30 cglobal flac_lpc_32, 5,6,5, decoded, coeffs, pred_order, qlevel, len, j
31     sub    lend, pred_orderd
32     jle .ret
33     lea    decodedq, [decodedq+pred_orderq*4-8]
34     lea    coeffsq, [coeffsq+pred_orderq*4]
35     neg    pred_orderq
36     movd   m4, qlevelm
37 ALIGN 16
38 .loop_sample:
39     movd   m0, [decodedq+pred_orderq*4+8]
40     add    decodedq, 8
41     movd   m1, [coeffsq+pred_orderq*4]
42     pxor   m2, m2
43     pxor   m3, m3
44     lea    jq, [pred_orderq+1]
45     test   jq, jq
46     jz .end_order
47 .loop_order:
48     PMACSDQL m2, m0, m1, m2, m0
49     movd   m0, [decodedq+jq*4]
50     PMACSDQL m3, m1, m0, m3, m1
51     movd   m1, [coeffsq+jq*4]
52     inc    jq
53     jl .loop_order
54 .end_order:
55     PMACSDQL m2, m0, m1, m2, m0
56     psrlq  m2, m4
57     movd   m0, [decodedq]
58     paddd  m0, m2
59     movd   [decodedq], m0
60     sub  lend, 2
61     jl .ret
62     PMACSDQL m3, m1, m0, m3, m1
63     psrlq  m3, m4
64     movd   m1, [decodedq+4]
65     paddd  m1, m3
66     movd   [decodedq+4], m1
67     jg .loop_sample
68 .ret:
69     REP_RET
70 %endmacro
71
72 %if HAVE_XOP_EXTERNAL
73 LPC_32 xop
74 %endif
75 LPC_32 sse4
76
77 ;----------------------------------------------------------------------------------
78 ;void ff_flac_decorrelate_[lrm]s_16_sse2(uint8_t **out, int32_t **in, int channels,
79 ;                                                   int len, int shift);
80 ;----------------------------------------------------------------------------------
81 %macro FLAC_DECORRELATE_16 3-4
82 cglobal flac_decorrelate_%1_16, 2, 4, 4, out, in0, in1, len
83 %if ARCH_X86_32
84     mov      lend, lenm
85 %endif
86     movd       m3, r4m
87     shl      lend, 2
88     mov      in1q, [in0q + gprsize]
89     mov      in0q, [in0q]
90     mov      outq, [outq]
91     add      in1q, lenq
92     add      in0q, lenq
93     add      outq, lenq
94     neg      lenq
95
96 align 16
97 .loop:
98     mova       m0, [in0q + lenq]
99     mova       m1, [in1q + lenq]
100 %ifidn %1, ms
101     psrad      m2, m1, 1
102     psubd      m0, m2
103 %endif
104 %ifnidn %1, indep2
105     p%4d       m2, m0, m1
106 %endif
107     packssdw  m%2, m%2
108     packssdw  m%3, m%3
109     punpcklwd m%2, m%3
110     psllw     m%2, m3
111     mova [outq + lenq], m%2
112     add      lenq, 16
113     jl .loop
114     REP_RET
115 %endmacro
116
117 INIT_XMM sse2
118 FLAC_DECORRELATE_16 ls, 0, 2, sub
119 FLAC_DECORRELATE_16 rs, 2, 1, add
120 FLAC_DECORRELATE_16 ms, 2, 0, add
121
122 ;----------------------------------------------------------------------------------
123 ;void ff_flac_decorrelate_[lrm]s_32_sse2(uint8_t **out, int32_t **in, int channels,
124 ;                                        int len, int shift);
125 ;----------------------------------------------------------------------------------
126 %macro FLAC_DECORRELATE_32 5
127 cglobal flac_decorrelate_%1_32, 2, 4, 4, out, in0, in1, len
128 %if ARCH_X86_32
129     mov      lend, lenm
130 %endif
131     movd       m3, r4m
132     mov      in1q, [in0q + gprsize]
133     mov      in0q, [in0q]
134     mov      outq, [outq]
135     sub      in1q, in0q
136
137 align 16
138 .loop:
139     mova       m0, [in0q]
140     mova       m1, [in0q + in1q]
141 %ifidn %1, ms
142     psrad      m2, m1, 1
143     psubd      m0, m2
144 %endif
145     p%5d       m2, m0, m1
146     pslld     m%2, m3
147     pslld     m%3, m3
148
149     SBUTTERFLY dq, %2, %3, %4
150
151     mova  [outq         ], m%2
152     mova  [outq + mmsize], m%3
153
154     add      in0q, mmsize
155     add      outq, mmsize*2
156     sub      lend, mmsize/4
157     jg .loop
158     REP_RET
159 %endmacro
160
161 INIT_XMM sse2
162 FLAC_DECORRELATE_32 ls, 0, 2, 1, sub
163 FLAC_DECORRELATE_32 rs, 2, 1, 0, add
164 FLAC_DECORRELATE_32 ms, 2, 0, 1, add
165
166 ;-----------------------------------------------------------------------------------------
167 ;void ff_flac_decorrelate_indep<ch>_<bps>_<opt>(uint8_t **out, int32_t **in, int channels,
168 ;                                            int len, int shift);
169 ;-----------------------------------------------------------------------------------------
170 ;%1 = bps
171 ;%2 = channels
172 ;%3 = last xmm reg used
173 ;%4 = word/dword (shift instruction)
174 %macro FLAC_DECORRELATE_INDEP 4
175 %define REPCOUNT %2/(32/%1) ; 16bits = channels / 2; 32bits = channels
176 cglobal flac_decorrelate_indep%2_%1, 2, %2+2, %3+1, out, in0, in1, len, in2, in3, in4, in5, in6, in7
177 %if ARCH_X86_32
178 %if %2 == 6
179     DEFINE_ARGS out, in0, in1, in2, in3, in4, in5
180     %define  lend  dword r3m
181 %else
182     mov      lend, lenm
183 %endif
184 %endif
185     movd      m%3, r4m
186
187 %assign %%i 1
188 %rep %2-1
189     mov      in %+ %%i %+ q, [in0q+%%i*gprsize]
190 %assign %%i %%i+1
191 %endrep
192
193     mov      in0q, [in0q]
194     mov      outq, [outq]
195
196 %assign %%i 1
197 %rep %2-1
198     sub      in %+ %%i %+ q, in0q
199 %assign %%i %%i+1
200 %endrep
201
202 align 16
203 .loop:
204     mova       m0, [in0q]
205
206 %assign %%i 1
207 %rep REPCOUNT-1
208     mova     m %+ %%i, [in0q + in %+ %%i %+ q]
209 %assign %%i %%i+1
210 %endrep
211
212 %if %1 == 32
213
214 %if %2 == 8
215     TRANSPOSE8x4D 0, 1, 2, 3, 4, 5, 6, 7, 8
216 %elif %2 == 6
217     SBUTTERFLY dq, 0, 1, 6
218     SBUTTERFLY dq, 2, 3, 6
219     SBUTTERFLY dq, 4, 5, 6
220
221     punpcklqdq m6, m0, m2
222     punpckhqdq m2, m4
223     shufps     m4, m0, 0xe4
224     punpcklqdq m0, m1, m3
225     punpckhqdq m3, m5
226     shufps     m5, m1, 0xe4
227     SWAP 0,6,1,4,5,3
228 %elif %2 == 4
229     TRANSPOSE4x4D 0, 1, 2, 3, 4
230 %else ; %2 == 2
231     SBUTTERFLY dq, 0, 1, 2
232 %endif
233
234 %else ; %1 == 16
235
236 %if %2 == 8
237     packssdw   m0, [in0q + in4q]
238     packssdw   m1, [in0q + in5q]
239     packssdw   m2, [in0q + in6q]
240     packssdw   m3, [in0q + in7q]
241     TRANSPOSE2x4x4W 0, 1, 2, 3, 4
242 %elif %2 == 6
243     packssdw   m0, [in0q + in3q]
244     packssdw   m1, [in0q + in4q]
245     packssdw   m2, [in0q + in5q]
246     pshufd     m3, m0,     q1032
247     punpcklwd  m0, m1
248     punpckhwd  m1, m2
249     punpcklwd  m2, m3
250
251     shufps     m3, m0, m2, q2020
252     shufps     m0, m1,     q2031
253     shufps     m2, m1,     q3131
254     shufps     m1, m2, m3, q3120
255     shufps     m3, m0,     q0220
256     shufps     m0, m2,     q3113
257     SWAP 2, 0, 3
258 %else ; %2 == 4
259     packssdw   m0, [in0q + in2q]
260     packssdw   m1, [in0q + in3q]
261     SBUTTERFLY wd, 0, 1, 2
262     SBUTTERFLY dq, 0, 1, 2
263 %endif
264
265 %endif
266
267 %assign %%i 0
268 %rep REPCOUNT
269     psll%4   m %+ %%i, m%3
270 %assign %%i %%i+1
271 %endrep
272
273 %assign %%i 0
274 %rep REPCOUNT
275     mova [outq + %%i*mmsize], m %+ %%i
276 %assign %%i %%i+1
277 %endrep
278
279     add      in0q, mmsize
280     add      outq, mmsize*REPCOUNT
281     sub      lend, mmsize/4
282     jg .loop
283     REP_RET
284 %endmacro
285
286 INIT_XMM sse2
287 FLAC_DECORRELATE_16 indep2, 0, 1 ; Reuse stereo 16bits macro
288 FLAC_DECORRELATE_INDEP 32, 2, 3, d
289 FLAC_DECORRELATE_INDEP 16, 4, 3, w
290 FLAC_DECORRELATE_INDEP 32, 4, 5, d
291 FLAC_DECORRELATE_INDEP 16, 6, 4, w
292 FLAC_DECORRELATE_INDEP 32, 6, 7, d
293 %if ARCH_X86_64
294 FLAC_DECORRELATE_INDEP 16, 8, 5, w
295 FLAC_DECORRELATE_INDEP 32, 8, 9, d
296 %endif
297
298 INIT_XMM avx
299 FLAC_DECORRELATE_INDEP 32, 4, 5, d
300 FLAC_DECORRELATE_INDEP 32, 6, 7, d
301 %if ARCH_X86_64
302 FLAC_DECORRELATE_INDEP 16, 8, 5, w
303 FLAC_DECORRELATE_INDEP 32, 8, 9, d
304 %endif