]> git.sesse.net Git - ffmpeg/blob - libavcodec/x86/dct32_sse.asm
9d6169ca66da3a1bdd728a4717f63487fb84c27c
[ffmpeg] / libavcodec / x86 / dct32_sse.asm
1 ;******************************************************************************
2 ;* 32 point SSE-optimized DCT transform
3 ;* Copyright (c) 2010 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 "x86inc.asm"
23 %include "x86util.asm"
24
25 SECTION_RODATA 32
26
27 align 32
28 ps_cos_vec: dd   0.500603,  0.505471,  0.515447,  0.531043
29             dd   0.553104,  0.582935,  0.622504,  0.674808
30             dd -10.190008, -3.407609, -2.057781, -1.484165
31             dd  -1.169440, -0.972568, -0.839350, -0.744536
32             dd   0.502419,  0.522499,  0.566944,  0.646822
33             dd   0.788155,  1.060678,  1.722447,  5.101149
34             dd   0.509796,  0.601345,  0.899976,  2.562916
35             dd   0.509796,  0.601345,  0.899976,  2.562916
36             dd   1.000000,  1.000000,  1.306563,  0.541196
37             dd   1.000000,  1.000000,  1.306563,  0.541196
38             dd   1.000000,  0.707107,  1.000000, -0.707107
39             dd   1.000000,  0.707107,  1.000000, -0.707107
40             dd   0.707107,  0.707107,  0.707107,  0.707107
41
42 align 32
43 ps_p1p1m1m1: dd 0, 0, 0x80000000, 0x80000000, 0, 0, 0x80000000, 0x80000000
44
45 %macro BUTTERFLY 4
46     subps  %4, %1, %2
47     addps  %2, %2, %1
48     mulps  %1, %4, %3
49 %endmacro
50
51 %macro BUTTERFLY0 5
52 %if cpuflag(sse2) && notcpuflag(avx)
53     pshufd %4, %1, %5
54     xorps  %1, %2
55     addps  %1, %4
56     mulps  %1, %3
57 %else
58     shufps %4, %1, %1, %5
59     xorps  %1, %1, %2
60     addps  %4, %4, %1
61     mulps  %1, %4, %3
62 %endif
63 %endmacro
64
65 %macro BUTTERFLY2 4
66     BUTTERFLY0 %1, %2, %3, %4, 0x1b
67 %endmacro
68
69 %macro BUTTERFLY3 4
70     BUTTERFLY0 %1, %2, %3, %4, 0xb1
71 %endmacro
72
73 %macro BUTTERFLY3V 5
74     movaps m%5, m%1
75     addps  m%1, m%2
76     subps  m%5, m%2
77     SWAP %2, %5
78     mulps  m%2, [ps_cos_vec+192]
79     movaps m%5, m%3
80     addps  m%3, m%4
81     subps  m%4, m%5
82     mulps  m%4, [ps_cos_vec+192]
83 %endmacro
84
85 %macro PASS6_AND_PERMUTE 0
86     mov         tmpd, [outq+4]
87     movss         m7, [outq+72]
88     addss         m7, [outq+76]
89     movss         m3, [outq+56]
90     addss         m3, [outq+60]
91     addss         m4, m3
92     movss         m2, [outq+52]
93     addss         m2, m3
94     movss         m3, [outq+104]
95     addss         m3, [outq+108]
96     addss         m1, m3
97     addss         m5, m4
98     movss [outq+ 16], m1
99     movss         m1, [outq+100]
100     addss         m1, m3
101     movss         m3, [outq+40]
102     movss [outq+ 48], m1
103     addss         m3, [outq+44]
104     movss         m1, [outq+100]
105     addss         m4, m3
106     addss         m3, m2
107     addss         m1, [outq+108]
108     movss [outq+ 40], m3
109     addss         m2, [outq+36]
110     movss         m3, [outq+8]
111     movss [outq+ 56], m2
112     addss         m3, [outq+12]
113     movss [outq+ 32], m3
114     movss         m3, [outq+80]
115     movss [outq+  8], m5
116     movss [outq+ 80], m1
117     movss         m2, [outq+52]
118     movss         m5, [outq+120]
119     addss         m5, [outq+124]
120     movss         m1, [outq+64]
121     addss         m2, [outq+60]
122     addss         m0, m5
123     addss         m5, [outq+116]
124     mov    [outq+64], tmpd
125     addss         m6, m0
126     addss         m1, m6
127     mov         tmpd, [outq+12]
128     mov   [outq+ 96], tmpd
129     movss [outq+  4], m1
130     movss         m1, [outq+24]
131     movss [outq+ 24], m4
132     movss         m4, [outq+88]
133     addss         m4, [outq+92]
134     addss         m3, m4
135     addss         m4, [outq+84]
136     mov         tmpd, [outq+108]
137     addss         m1, [outq+28]
138     addss         m0, m1
139     addss         m1, m5
140     addss         m6, m3
141     addss         m3, m0
142     addss         m0, m7
143     addss         m5, [outq+20]
144     addss         m7, m1
145     movss [outq+ 12], m6
146     mov   [outq+112], tmpd
147     movss         m6, [outq+28]
148     movss [outq+ 28], m0
149     movss         m0, [outq+36]
150     movss [outq+ 36], m7
151     addss         m1, m4
152     movss         m7, [outq+116]
153     addss         m0, m2
154     addss         m7, [outq+124]
155     movss [outq+ 72], m0
156     movss         m0, [outq+44]
157     addss         m2, m0
158     movss [outq+ 44], m1
159     movss [outq+ 88], m2
160     addss         m0, [outq+60]
161     mov         tmpd, [outq+60]
162     mov   [outq+120], tmpd
163     movss [outq+104], m0
164     addss         m4, m5
165     addss         m5, [outq+68]
166     movss  [outq+52], m4
167     movss  [outq+60], m5
168     movss         m4, [outq+68]
169     movss         m5, [outq+20]
170     movss [outq+ 20], m3
171     addss         m5, m7
172     addss         m7, m6
173     addss         m4, m5
174     movss         m2, [outq+84]
175     addss         m2, [outq+92]
176     addss         m5, m2
177     movss [outq+ 68], m4
178     addss         m2, m7
179     movss         m4, [outq+76]
180     movss [outq+ 84], m2
181     movss [outq+ 76], m5
182     addss         m7, m4
183     addss         m6, [outq+124]
184     addss         m4, m6
185     addss         m6, [outq+92]
186     movss [outq+100], m4
187     movss [outq+108], m6
188     movss         m6, [outq+92]
189     movss  [outq+92], m7
190     addss         m6, [outq+124]
191     movss [outq+116], m6
192 %endmacro
193
194 INIT_YMM avx
195 SECTION_TEXT
196 %if HAVE_AVX
197 ; void ff_dct32_float_avx(FFTSample *out, const FFTSample *in)
198 cglobal dct32_float, 2,3,8, out, in, tmp
199     ; pass 1
200     vmovaps     m4, [inq+0]
201     vinsertf128 m5, m5, [inq+96], 1
202     vinsertf128 m5, m5, [inq+112], 0
203     vshufps     m5, m5, m5, 0x1b
204     BUTTERFLY   m4, m5, [ps_cos_vec], m6
205
206     vmovaps     m2, [inq+64]
207     vinsertf128 m6, m6, [inq+32], 1
208     vinsertf128 m6, m6, [inq+48], 0
209     vshufps     m6, m6, m6, 0x1b
210     BUTTERFLY   m2, m6, [ps_cos_vec+32], m0
211
212     ; pass 2
213
214     BUTTERFLY  m5, m6, [ps_cos_vec+64], m0
215     BUTTERFLY  m4, m2, [ps_cos_vec+64], m7
216
217
218     ; pass 3
219     vperm2f128  m3, m6, m4, 0x31
220     vperm2f128  m1, m6, m4, 0x20
221     vshufps     m3, m3, m3, 0x1b
222
223     BUTTERFLY   m1, m3, [ps_cos_vec+96], m6
224
225
226     vperm2f128  m4, m5, m2, 0x20
227     vperm2f128  m5, m5, m2, 0x31
228     vshufps     m5, m5, m5, 0x1b
229
230     BUTTERFLY   m4, m5, [ps_cos_vec+96], m6
231
232     ; pass 4
233     vmovaps m6, [ps_p1p1m1m1+0]
234     vmovaps m2, [ps_cos_vec+128]
235
236     BUTTERFLY2  m5, m6, m2, m7
237     BUTTERFLY2  m4, m6, m2, m7
238     BUTTERFLY2  m1, m6, m2, m7
239     BUTTERFLY2  m3, m6, m2, m7
240
241
242     ; pass 5
243     vshufps m6, m6, m6, 0xcc
244     vmovaps m2, [ps_cos_vec+160]
245
246     BUTTERFLY3  m5, m6, m2, m7
247     BUTTERFLY3  m4, m6, m2, m7
248     BUTTERFLY3  m1, m6, m2, m7
249     BUTTERFLY3  m3, m6, m2, m7
250
251     vperm2f128  m6, m3, m3, 0x31
252     vmovaps [outq], m3
253
254     vextractf128  [outq+64], m5, 1
255     vextractf128  [outq+32], m5, 0
256
257     vextractf128  [outq+80], m4, 1
258     vextractf128  [outq+48], m4, 0
259
260     vperm2f128  m0, m1, m1, 0x31
261     vmovaps [outq+96], m1
262
263     vzeroupper
264
265     ;    pass 6, no SIMD...
266 INIT_XMM
267     PASS6_AND_PERMUTE
268     RET
269 %endif
270
271 %if ARCH_X86_64
272 %define SPILL SWAP
273 %define UNSPILL SWAP
274
275 %macro PASS5 0
276     nop ; FIXME code alignment
277     SWAP 5, 8
278     SWAP 4, 12
279     SWAP 6, 14
280     SWAP 7, 13
281     SWAP 0, 15
282     PERMUTE 9,10, 10,12, 11,14, 12,9, 13,11, 14,13
283     TRANSPOSE4x4PS 8, 9, 10, 11, 0
284     BUTTERFLY3V    8, 9, 10, 11, 0
285     addps   m10, m11
286     TRANSPOSE4x4PS 12, 13, 14, 15, 0
287     BUTTERFLY3V    12, 13, 14, 15, 0
288     addps   m14, m15
289     addps   m12, m14
290     addps   m14, m13
291     addps   m13, m15
292 %endmacro
293
294 %macro PASS6 0
295     SWAP 9, 12
296     SWAP 11, 14
297     movss [outq+0x00], m8
298     pshuflw m0, m8, 0xe
299     movss [outq+0x10], m9
300     pshuflw m1, m9, 0xe
301     movss [outq+0x20], m10
302     pshuflw m2, m10, 0xe
303     movss [outq+0x30], m11
304     pshuflw m3, m11, 0xe
305     movss [outq+0x40], m12
306     pshuflw m4, m12, 0xe
307     movss [outq+0x50], m13
308     pshuflw m5, m13, 0xe
309     movss [outq+0x60], m14
310     pshuflw m6, m14, 0xe
311     movaps [outq+0x70], m15
312     pshuflw m7, m15, 0xe
313     addss   m0, m1
314     addss   m1, m2
315     movss [outq+0x08], m0
316     addss   m2, m3
317     movss [outq+0x18], m1
318     addss   m3, m4
319     movss [outq+0x28], m2
320     addss   m4, m5
321     movss [outq+0x38], m3
322     addss   m5, m6
323     movss [outq+0x48], m4
324     addss   m6, m7
325     movss [outq+0x58], m5
326     movss [outq+0x68], m6
327     movss [outq+0x78], m7
328
329     PERMUTE 1,8, 3,9, 5,10, 7,11, 9,12, 11,13, 13,14, 8,1, 10,3, 12,5, 14,7
330     movhlps m0, m1
331     pshufd  m1, m1, 3
332     SWAP 0, 2, 4, 6, 8, 10, 12, 14
333     SWAP 1, 3, 5, 7, 9, 11, 13, 15
334 %rep 7
335     movhlps m0, m1
336     pshufd  m1, m1, 3
337     addss   m15, m1
338     SWAP 0, 2, 4, 6, 8, 10, 12, 14
339     SWAP 1, 3, 5, 7, 9, 11, 13, 15
340 %endrep
341 %assign i 4
342 %rep 15
343     addss m0, m1
344     movss [outq+i], m0
345     SWAP 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
346     %assign i i+8
347 %endrep
348 %endmacro
349
350 %else ; ARCH_X86_32
351 %macro SPILL 2 ; xmm#, mempos
352     movaps [outq+(%2-8)*16], m%1
353 %endmacro
354 %macro UNSPILL 2
355     movaps m%1, [outq+(%2-8)*16]
356 %endmacro
357
358 %define PASS6 PASS6_AND_PERMUTE
359 %macro PASS5 0
360     movaps      m2, [ps_cos_vec+160]
361     shufps      m3, m3, 0xcc
362
363     BUTTERFLY3  m5, m3, m2, m1
364     SPILL 5, 8
365
366     UNSPILL 1, 9
367     BUTTERFLY3  m1, m3, m2, m5
368     SPILL 1, 14
369
370     BUTTERFLY3  m4, m3, m2, m5
371     SPILL 4, 12
372
373     BUTTERFLY3  m7, m3, m2, m5
374     SPILL 7, 13
375
376     UNSPILL 5, 10
377     BUTTERFLY3  m5, m3, m2, m7
378     SPILL 5, 10
379
380     UNSPILL 4, 11
381     BUTTERFLY3  m4, m3, m2, m7
382     SPILL 4, 11
383
384     BUTTERFLY3  m6, m3, m2, m7
385     SPILL 6, 9
386
387     BUTTERFLY3  m0, m3, m2, m7
388     SPILL 0, 15
389 %endmacro
390 %endif
391
392
393 ; void ff_dct32_float_sse(FFTSample *out, const FFTSample *in)
394 %macro DCT32_FUNC 0
395 cglobal dct32_float, 2, 3, 16, out, in, tmp
396     ; pass 1
397
398     movaps      m0, [inq+0]
399     LOAD_INV    m1, [inq+112]
400     BUTTERFLY   m0, m1, [ps_cos_vec], m3
401
402     movaps      m7, [inq+64]
403     LOAD_INV    m4, [inq+48]
404     BUTTERFLY   m7, m4, [ps_cos_vec+32], m3
405
406     ; pass 2
407     movaps      m2, [ps_cos_vec+64]
408     BUTTERFLY   m1, m4, m2, m3
409     SPILL 1, 11
410     SPILL 4, 8
411
412     ; pass 1
413     movaps      m1, [inq+16]
414     LOAD_INV    m6, [inq+96]
415     BUTTERFLY   m1, m6, [ps_cos_vec+16], m3
416
417     movaps      m4, [inq+80]
418     LOAD_INV    m5, [inq+32]
419     BUTTERFLY   m4, m5, [ps_cos_vec+48], m3
420
421     ; pass 2
422     BUTTERFLY   m0, m7, m2, m3
423
424     movaps      m2, [ps_cos_vec+80]
425     BUTTERFLY   m6, m5, m2, m3
426
427     BUTTERFLY   m1, m4, m2, m3
428
429     ; pass 3
430     movaps      m2, [ps_cos_vec+96]
431     shufps      m1, m1, 0x1b
432     BUTTERFLY   m0, m1, m2, m3
433     SPILL 0, 15
434     SPILL 1, 14
435
436     UNSPILL 0, 8
437     shufps      m5, m5, 0x1b
438     BUTTERFLY   m0, m5, m2, m3
439
440     UNSPILL 1, 11
441     shufps      m6, m6, 0x1b
442     BUTTERFLY   m1, m6, m2, m3
443     SPILL 1, 11
444
445     shufps      m4, m4, 0x1b
446     BUTTERFLY   m7, m4, m2, m3
447
448     ; pass 4
449     movaps      m3, [ps_p1p1m1m1+0]
450     movaps      m2, [ps_cos_vec+128]
451
452     BUTTERFLY2  m5, m3, m2, m1
453
454     BUTTERFLY2  m0, m3, m2, m1
455     SPILL 0, 9
456
457     BUTTERFLY2  m6, m3, m2, m1
458     SPILL 6, 10
459
460     UNSPILL 0, 11
461     BUTTERFLY2  m0, m3, m2, m1
462     SPILL 0, 11
463
464     BUTTERFLY2  m4, m3, m2, m1
465
466     BUTTERFLY2  m7, m3, m2, m1
467
468     UNSPILL 6, 14
469     BUTTERFLY2  m6, m3, m2, m1
470
471     UNSPILL 0, 15
472     BUTTERFLY2  m0, m3, m2, m1
473
474     PASS5
475     PASS6
476     RET
477 %endmacro
478
479 %macro LOAD_INV 2
480 %if cpuflag(sse2)
481     pshufd      %1, %2, 0x1b
482 %elif cpuflag(sse)
483     movaps      %1, %2
484     shufps      %1, %1, 0x1b
485 %endif
486 %endmacro
487
488 INIT_XMM sse
489 DCT32_FUNC
490 INIT_XMM sse2
491 DCT32_FUNC