]> git.sesse.net Git - ffmpeg/blob - libavcodec/x86/imdct36_sse.asm
Merge remote-tracking branch 'qatar/master'
[ffmpeg] / libavcodec / x86 / imdct36_sse.asm
1 ;******************************************************************************
2 ;* 36 point SSE-optimized IMDCT transform
3 ;* Copyright (c) 2011 Vitor Sessak
4 ;*
5 ;* This file is part of Libav.
6 ;*
7 ;* Libav is free software; you can redistribute it and/or
8 ;* modify it under the terms of the GNU Lesser General Public
9 ;* License as published by the Free Software Foundation; either
10 ;* version 2.1 of the License, or (at your option) any later version.
11 ;*
12 ;* Libav is distributed in the hope that it will be useful,
13 ;* but WITHOUT ANY WARRANTY; without even the implied warranty of
14 ;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 ;* Lesser General Public License for more details.
16 ;*
17 ;* You should have received a copy of the GNU Lesser General Public
18 ;* License along with Libav; if not, write to the Free Software
19 ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 ;******************************************************************************
21
22 %include "libavutil/x86/x86inc.asm"
23 %include "libavutil/x86/x86util.asm"
24
25 SECTION_RODATA
26
27 align 16
28 ps_mask:  dd 0, ~0, ~0, ~0
29 ps_mask2: dd 0, ~0,  0, ~0
30 ps_mask3: dd 0,  0,  0, ~0
31 ps_mask4: dd 0, ~0,  0,  0
32
33 ps_val1:  dd          -0.5,          -0.5, -0.8660254038, -0.8660254038
34 ps_val2:  dd           1.0,           1.0,  0.8660254038,  0.8660254038
35 ps_val3:  dd  0.1736481777,  0.1736481777,  0.3420201433,  0.3420201433
36 ps_val4:  dd -0.7660444431, -0.7660444431,  0.8660254038,  0.8660254038
37 ps_val5:  dd -0.9396926208, -0.9396926208, -0.9848077530, -0.9848077530
38 ps_val6:  dd           0.5,           0.5, -0.6427876097, -0.6427876097
39 ps_val7:  dd           1.0,           1.0, -0.6427876097, -0.6427876097
40
41 ps_p1p1m1m1: dd 0,          0, 0x80000000, 0x80000000
42 ps_p1m1p1m1: dd 0, 0x80000000,          0, 0x80000000
43
44 ps_cosh:       dd 1.0, 0.50190991877167369479,  1.0,  5.73685662283492756461
45                dd 1.0, 0.51763809020504152469,  1.0,  1.93185165257813657349
46                dd 1.0, 0.55168895948124587824, -1.0, -1.18310079157624925896
47                dd 1.0, 0.61038729438072803416, -1.0, -0.87172339781054900991
48                dd 1.0, 0.70710678118654752439,  0.0,  0.0
49
50 ps_cosh_sse3:  dd 1.0, -0.50190991877167369479,  1.0, -5.73685662283492756461
51                dd 1.0, -0.51763809020504152469,  1.0, -1.93185165257813657349
52                dd 1.0, -0.55168895948124587824, -1.0,  1.18310079157624925896
53                dd 1.0, -0.61038729438072803416, -1.0,  0.87172339781054900991
54                dd 1.0,  0.70710678118654752439,  0.0,  0.0
55
56 %define SBLIMIT 32
57 SECTION_TEXT
58
59 %macro PSHUFD_SSE_AVX 3
60     shufps %1, %2, %2, %3
61 %endmacro
62 %macro PSHUFD_SSE2 3
63     pshufd %1, %2, %3
64 %endmacro
65
66 ; input  %1={x1,x2,x3,x4}, %2={y1,y2,y3,y4}
67 ; output %3={x3,x4,y1,y2}
68 %macro BUILDINVHIGHLOW_SSE 3
69     movlhps %3, %2
70     movhlps %3, %1
71 %endmacro
72 %macro BUILDINVHIGHLOW_AVX 3
73     shufps %3, %1, %2, 0x4e
74 %endmacro
75
76 ; input  %1={x1,x2,x3,x4}, %2={y1,y2,y3,y4}
77 ; output %3={x4,y1,y2,y3}
78 %macro ROTLEFT_SSE 3
79     BUILDINVHIGHLOW %1, %2, %3
80     shufps  %3, %3, %2, 0x99
81 %endmacro
82
83 %macro ROTLEFT_SSSE3 3
84     palignr  %3, %2, %1, 12
85 %endmacro
86
87 %macro INVERTHL_SSE1 2
88     movhlps %1, %2
89     movlhps %1, %2
90 %endmacro
91
92 %macro INVERTHL_SSE2 2
93     PSHUFD  %1, %2, 0x4e
94 %endmacro
95
96 %macro BUTTERF_SSE12 3
97     INVERTHL %2, %1
98     xorps    %1, [ps_p1p1m1m1]
99     addps    %1, %2
100     mulps    %1, [ps_cosh + %3]
101     PSHUFD   %2, %1, 0xb1
102     xorps    %1, [ps_p1m1p1m1]
103     addps    %1, %2
104 %endmacro
105 %macro BUTTERF_SSE3 3
106     INVERTHL %2, %1
107     xorps    %1, %1, [ps_p1p1m1m1]
108     addps    %1, %1, %2
109     mulps    %1, %1, [ps_cosh_sse3 + %3]
110     PSHUFD   %2, %1, 0xb1
111     addsubps %1, %1, %2
112 %endmacro
113
114 %macro STORE 3
115     movhlps %2, %1
116     movss   [%3             ], %1
117     movss   [%3 +  8*SBLIMIT], %2
118     shufps  %1, %1, 0xb1
119     movss   [%3 +  4*SBLIMIT], %1
120     movhlps %2, %1
121     movss   [%3 + 12*SBLIMIT], %2
122 %endmacro
123
124 %macro LOADA64 2
125    movlps   %1, [%2]
126    movhps   %1, [%2 + 8]
127 %endmacro
128
129 %macro STOREA64 2
130    movlps   [%1    ], %2
131    movhps   [%1 + 8], %2
132 %endmacro
133
134 %macro DEFINE_IMDCT 1
135 cglobal imdct36_float_%1, 4,4,9, out, buf, in, win
136
137     ; for(i=17;i>=1;i--) in[i] += in[i-1];
138     LOADA64 m0, inq
139     LOADA64 m1, inq + 16
140
141     ROTLEFT m0, m1, m5
142
143     PSHUFD  m6, m0, 0x93
144     andps   m6, m6, [ps_mask]
145     addps   m0, m0, m6
146
147     LOADA64 m2, inq + 32
148
149     ROTLEFT m1, m2, m7
150
151     addps   m1, m1, m5
152     LOADA64 m3, inq + 48
153
154     ROTLEFT m2, m3, m5
155
156     xorps   m4, m4, m4
157     movlps  m4, [inq+64]
158     BUILDINVHIGHLOW m3, m4, m6
159     shufps  m6, m6, m4, 0xa9
160
161     addps   m4, m4, m6
162     addps   m2, m2, m7
163     addps   m3, m3, m5
164
165     ; for(i=17;i>=3;i-=2) in[i] += in[i-2];
166     movlhps m5, m5, m0
167     andps   m5, m5, [ps_mask3]
168
169     BUILDINVHIGHLOW m0, m1, m7
170     andps   m7, m7, [ps_mask2]
171
172     addps   m0, m0, m5
173
174     BUILDINVHIGHLOW m1, m2, m6
175     andps   m6, m6, [ps_mask2]
176
177     addps  m1, m1, m7
178
179     BUILDINVHIGHLOW m2, m3, m7
180     andps   m7, m7, [ps_mask2]
181
182     addps   m2, m2, m6
183
184     movhlps m6, m6, m3
185     andps   m6, m6, [ps_mask4]
186
187     addps  m3, m3, m7
188     addps  m4, m4, m6
189
190     ; Populate tmp[]
191     movlhps m6, m1, m5    ; zero out high values
192     subps   m6, m6, m4
193
194     subps  m5, m0, m3
195
196 %ifdef ARCH_X86_64
197     SWAP   m5, m8
198 %endif
199
200     mulps  m7, m2, [ps_val1]
201
202 %ifdef ARCH_X86_64
203     mulps  m5, m8, [ps_val2]
204 %else
205     mulps  m5, m5, [ps_val2]
206 %endif
207     addps  m7, m7, m5
208
209     mulps  m5, m6, [ps_val1]
210     subps  m7, m7, m5
211
212 %ifdef ARCH_X86_64
213     SWAP   m5, m8
214 %else
215     subps  m5, m0, m3
216 %endif
217
218     subps  m5, m5, m6
219     addps  m5, m5, m2
220
221     shufps m6, m4, m3, 0xe4
222     subps  m6, m6, m2
223     mulps  m6, m6, [ps_val3]
224
225     addps  m4, m4, m1
226     mulps  m4, m4, [ps_val4]
227
228     shufps m1, m1, m0, 0xe4
229     addps  m1, m1, m2
230     mulps  m1, m1, [ps_val5]
231
232     mulps  m3, m3, [ps_val6]
233     mulps  m0, m0, [ps_val7]
234     addps  m0, m0, m3
235
236     xorps  m2, m1, [ps_p1p1m1m1]
237     subps  m2, m2, m4
238     addps  m2, m2, m0
239
240     addps  m3, m4, m0
241     subps  m3, m3, m6
242     xorps  m3, m3, [ps_p1p1m1m1]
243
244     shufps m0, m0, m4, 0xe4
245     subps  m0, m0, m1
246     addps  m0, m0, m6
247
248     BUILDINVHIGHLOW m2, m3, m4
249     shufps  m3, m3, m2, 0x4e
250
251     ; we have tmp = {SwAPLH(m0), SwAPLH(m7), m3, m4, m5}
252
253     BUTTERF  m0, m1, 0
254     BUTTERF  m7, m2, 16
255     BUTTERF  m3, m6, 32
256     BUTTERF  m4, m1, 48
257
258     mulps   m5, m5, [ps_cosh + 64]
259     PSHUFD  m1, m5, 0xe1
260     xorps   m5, m5, [ps_p1m1p1m1]
261     addps   m5, m5, m1
262
263     ; permutates:
264     ; m0    0  1  2  3     =>     2  6 10 14   m1
265     ; m7    4  5  6  7     =>     3  7 11 15   m2
266     ; m3    8  9 10 11     =>    17 13  9  5   m3
267     ; m4   12 13 14 15     =>    16 12  8  4   m5
268     ; m5   16 17 xx xx     =>     0  1 xx xx   m0
269
270     unpckhps m1, m0, m7
271     unpckhps m6, m3, m4
272     movhlps  m2, m6, m1
273     movlhps  m1, m1, m6
274
275     unpcklps m5, m5, m4
276     unpcklps m3, m3, m7
277     movhlps  m4, m3, m5
278     movlhps  m5, m5, m3
279     SWAP m4, m3
280     ; permutation done
281
282     PSHUFD  m6, m2, 0xb1
283     movlps  m7, [bufq + 64]
284     mulps   m6, m6, [winq + 16*4]
285     addps   m6, m6, m7
286     movss   [outq + 64*SBLIMIT], m6
287     shufps  m6, m6, m6, 0xb1
288     movss   [outq + 68*SBLIMIT], m6
289
290     mulps   m6, m3, [winq + 4*4]
291     LOADA64 m4, bufq + 16
292     addps   m6, m6, m4
293     STORE   m6, m7, outq + 16*SBLIMIT
294
295     shufps  m4, m0, m3, 0xb5
296     mulps   m4, m4, [winq + 8*4]
297     LOADA64 m7, bufq + 32
298     addps   m4, m4, m7
299     STORE   m4, m6, outq + 32*SBLIMIT
300
301     shufps  m3, m3, m2, 0xb1
302     mulps   m3, m3, [winq + 12*4]
303     LOADA64 m7, bufq + 48
304     addps   m3, m3, m7
305     STORE   m3, m7, outq + 48*SBLIMIT
306
307     mulps   m2, m2, [winq]
308     LOADA64 m6, bufq
309     addps   m2, m2, m6
310     STORE   m2, m7, outq
311
312     mulps    m4, m1, [winq + 20*4]
313     STOREA64 bufq, m4
314
315     mulps    m3, m5, [winq + 24*4]
316     STOREA64 bufq + 16, m3
317
318     shufps   m0, m0, m5, 0xb0
319     mulps    m0, m0, [winq + 28*4]
320     STOREA64 bufq + 32, m0
321
322     shufps   m5, m5, m1, 0xb1
323     mulps    m5, m5, [winq + 32*4]
324     STOREA64 bufq + 48, m5
325
326     shufps   m1, m1, m1, 0xb1
327     mulps    m1, m1, [winq + 36*4]
328     movlps  [bufq + 64], m1
329     RET
330 %endmacro
331
332 %define PSHUFD PSHUFD_SSE_AVX
333 %define INVERTHL INVERTHL_SSE1
334 %define BUTTERF  BUTTERF_SSE12
335 %define BUTTERF0 BUTTERF0_SSE12
336 %define BUILDINVHIGHLOW BUILDINVHIGHLOW_SSE
337 %define ROTLEFT ROTLEFT_SSE
338
339 INIT_XMM
340
341 DEFINE_IMDCT sse
342
343 %define PSHUFD PSHUFD_SSE2
344 %define INVERTHL INVERTHL_SSE2
345
346 DEFINE_IMDCT sse2
347
348 %define BUTTERF  BUTTERF_SSE3
349 %define BUTTERF0 BUTTERF0_SSE3
350
351 DEFINE_IMDCT sse3
352
353 %define ROTLEFT ROTLEFT_SSSE3
354
355 DEFINE_IMDCT ssse3
356
357 %define BUILDINVHIGHLOW BUILDINVHIGHLOW_AVX
358 %define PSHUFD PSHUFD_SSE_AVX
359
360 INIT_AVX
361 DEFINE_IMDCT avx