e24acdd940471eaff4710e53875a670652b13350
[ffmpeg.git] / libavutil / x86 / x86util.asm
1 ;*****************************************************************************
2 ;* x86util.asm
3 ;*****************************************************************************
4 ;* Copyright (C) 2008-2010 x264 project
5 ;*
6 ;* Authors: Loren Merritt <lorenm@u.washington.edu>
7 ;*          Holger Lubitz <holger@lubitz.org>
8 ;*
9 ;* This file is part of Libav.
10 ;*
11 ;* Libav is free software; you can redistribute it and/or
12 ;* modify it under the terms of the GNU Lesser General Public
13 ;* License as published by the Free Software Foundation; either
14 ;* version 2.1 of the License, or (at your option) any later version.
15 ;*
16 ;* Libav is distributed in the hope that it will be useful,
17 ;* but WITHOUT ANY WARRANTY; without even the implied warranty of
18 ;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19 ;* Lesser General Public License for more details.
20 ;*
21 ;* You should have received a copy of the GNU Lesser General Public
22 ;* License along with Libav; if not, write to the Free Software
23 ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24 ;******************************************************************************
25
26 %define program_name ff
27 %define cpuflags_mmxext cpuflags_mmx2
28
29 %include "libavutil/x86/x86inc.asm"
30
31 %macro SBUTTERFLY 4
32 %if avx_enabled == 0
33     mova      m%4, m%2
34     punpckl%1 m%2, m%3
35     punpckh%1 m%4, m%3
36 %else
37     punpckh%1 m%4, m%2, m%3
38     punpckl%1 m%2, m%3
39 %endif
40     SWAP %3, %4
41 %endmacro
42
43 %macro SBUTTERFLY2 4
44     punpckl%1 m%4, m%2, m%3
45     punpckh%1 m%2, m%2, m%3
46     SWAP %2, %4, %3
47 %endmacro
48
49 %macro SBUTTERFLYPS 3
50     unpcklps m%3, m%1, m%2
51     unpckhps m%1, m%1, m%2
52     SWAP %1, %3, %2
53 %endmacro
54
55 %macro TRANSPOSE4x4B 5
56     SBUTTERFLY bw, %1, %2, %5
57     SBUTTERFLY bw, %3, %4, %5
58     SBUTTERFLY wd, %1, %3, %5
59     SBUTTERFLY wd, %2, %4, %5
60     SWAP %2, %3
61 %endmacro
62
63 %macro TRANSPOSE4x4W 5
64     SBUTTERFLY wd, %1, %2, %5
65     SBUTTERFLY wd, %3, %4, %5
66     SBUTTERFLY dq, %1, %3, %5
67     SBUTTERFLY dq, %2, %4, %5
68     SWAP %2, %3
69 %endmacro
70
71 %macro TRANSPOSE2x4x4W 5
72     SBUTTERFLY wd,  %1, %2, %5
73     SBUTTERFLY wd,  %3, %4, %5
74     SBUTTERFLY dq,  %1, %3, %5
75     SBUTTERFLY dq,  %2, %4, %5
76     SBUTTERFLY qdq, %1, %2, %5
77     SBUTTERFLY qdq, %3, %4, %5
78 %endmacro
79
80 %macro TRANSPOSE4x4D 5
81     SBUTTERFLY dq,  %1, %2, %5
82     SBUTTERFLY dq,  %3, %4, %5
83     SBUTTERFLY qdq, %1, %3, %5
84     SBUTTERFLY qdq, %2, %4, %5
85     SWAP %2, %3
86 %endmacro
87
88 ; identical behavior to TRANSPOSE4x4D, but using SSE1 float ops
89 %macro TRANSPOSE4x4PS 5
90     SBUTTERFLYPS %1, %2, %5
91     SBUTTERFLYPS %3, %4, %5
92     movlhps m%5, m%1, m%3
93     movhlps m%3, m%1
94     SWAP %5, %1
95     movlhps m%5, m%2, m%4
96     movhlps m%4, m%2
97     SWAP %5, %2, %3
98 %endmacro
99
100 %macro TRANSPOSE8x8W 9-11
101 %if ARCH_X86_64
102     SBUTTERFLY wd,  %1, %2, %9
103     SBUTTERFLY wd,  %3, %4, %9
104     SBUTTERFLY wd,  %5, %6, %9
105     SBUTTERFLY wd,  %7, %8, %9
106     SBUTTERFLY dq,  %1, %3, %9
107     SBUTTERFLY dq,  %2, %4, %9
108     SBUTTERFLY dq,  %5, %7, %9
109     SBUTTERFLY dq,  %6, %8, %9
110     SBUTTERFLY qdq, %1, %5, %9
111     SBUTTERFLY qdq, %2, %6, %9
112     SBUTTERFLY qdq, %3, %7, %9
113     SBUTTERFLY qdq, %4, %8, %9
114     SWAP %2, %5
115     SWAP %4, %7
116 %else
117 ; in:  m0..m7, unless %11 in which case m6 is in %9
118 ; out: m0..m7, unless %11 in which case m4 is in %10
119 ; spills into %9 and %10
120 %if %0<11
121     movdqa %9, m%7
122 %endif
123     SBUTTERFLY wd,  %1, %2, %7
124     movdqa %10, m%2
125     movdqa m%7, %9
126     SBUTTERFLY wd,  %3, %4, %2
127     SBUTTERFLY wd,  %5, %6, %2
128     SBUTTERFLY wd,  %7, %8, %2
129     SBUTTERFLY dq,  %1, %3, %2
130     movdqa %9, m%3
131     movdqa m%2, %10
132     SBUTTERFLY dq,  %2, %4, %3
133     SBUTTERFLY dq,  %5, %7, %3
134     SBUTTERFLY dq,  %6, %8, %3
135     SBUTTERFLY qdq, %1, %5, %3
136     SBUTTERFLY qdq, %2, %6, %3
137     movdqa %10, m%2
138     movdqa m%3, %9
139     SBUTTERFLY qdq, %3, %7, %2
140     SBUTTERFLY qdq, %4, %8, %2
141     SWAP %2, %5
142     SWAP %4, %7
143 %if %0<11
144     movdqa m%5, %10
145 %endif
146 %endif
147 %endmacro
148
149 ; PABSW macro assumes %1 != %2, while ABS1/2 macros work in-place
150 %macro PABSW 2
151 %if cpuflag(ssse3)
152     pabsw      %1, %2
153 %elif cpuflag(mmxext)
154     pxor    %1, %1
155     psubw   %1, %2
156     pmaxsw  %1, %2
157 %else
158     pxor       %1, %1
159     pcmpgtw    %1, %2
160     pxor       %2, %1
161     psubw      %2, %1
162     SWAP       %1, %2
163 %endif
164 %endmacro
165
166 %macro PSIGNW_MMX 2
167     pxor       %1, %2
168     psubw      %1, %2
169 %endmacro
170
171 %macro PSIGNW_SSSE3 2
172     psignw     %1, %2
173 %endmacro
174
175 %macro ABS1 2
176 %if cpuflag(ssse3)
177     pabsw   %1, %1
178 %elif cpuflag(mmxext) ; a, tmp
179     pxor    %2, %2
180     psubw   %2, %1
181     pmaxsw  %1, %2
182 %else ; a, tmp
183     pxor       %2, %2
184     pcmpgtw    %2, %1
185     pxor       %1, %2
186     psubw      %1, %2
187 %endif
188 %endmacro
189
190 %macro ABS2_MMX 4    ; a, b, tmp0, tmp1
191     pxor       %3, %3
192     pxor       %4, %4
193     pcmpgtw    %3, %1
194     pcmpgtw    %4, %2
195     pxor       %1, %3
196     pxor       %2, %4
197     psubw      %1, %3
198     psubw      %2, %4
199 %endmacro
200
201 %macro ABS2_MMXEXT 4 ; a, b, tmp0, tmp1
202     pxor    %3, %3
203     pxor    %4, %4
204     psubw   %3, %1
205     psubw   %4, %2
206     pmaxsw  %1, %3
207     pmaxsw  %2, %4
208 %endmacro
209
210 %macro ABS2_SSSE3 4
211     pabsw   %1, %1
212     pabsw   %2, %2
213 %endmacro
214
215 %macro ABSB_MMX 2
216     pxor    %2, %2
217     psubb   %2, %1
218     pminub  %1, %2
219 %endmacro
220
221 %macro ABSB2_MMX 4
222     pxor    %3, %3
223     pxor    %4, %4
224     psubb   %3, %1
225     psubb   %4, %2
226     pminub  %1, %3
227     pminub  %2, %4
228 %endmacro
229
230 %macro ABSD2_MMX 4
231     pxor    %3, %3
232     pxor    %4, %4
233     pcmpgtd %3, %1
234     pcmpgtd %4, %2
235     pxor    %1, %3
236     pxor    %2, %4
237     psubd   %1, %3
238     psubd   %2, %4
239 %endmacro
240
241 %macro ABSB_SSSE3 2
242     pabsb   %1, %1
243 %endmacro
244
245 %macro ABSB2_SSSE3 4
246     pabsb   %1, %1
247     pabsb   %2, %2
248 %endmacro
249
250 %macro ABS4 6
251     ABS2 %1, %2, %5, %6
252     ABS2 %3, %4, %5, %6
253 %endmacro
254
255 %define ABS2 ABS2_MMX
256 %define ABSB ABSB_MMX
257 %define ABSB2 ABSB2_MMX
258
259 %macro SPLATB_LOAD 3
260 %if cpuflag(ssse3)
261     movd      %1, [%2-3]
262     pshufb    %1, %3
263 %else
264     movd      %1, [%2-3] ;to avoid crossing a cacheline
265     punpcklbw %1, %1
266     SPLATW    %1, %1, 3
267 %endif
268 %endmacro
269
270 %macro SPLATB_REG 3
271 %if cpuflag(ssse3)
272     movd      %1, %2d
273     pshufb    %1, %3
274 %else
275     movd      %1, %2d
276     punpcklbw %1, %1
277     SPLATW    %1, %1, 0
278 %endif
279 %endmacro
280
281 %macro PALIGNR 4-5
282 %if cpuflag(ssse3)
283 %if %0==5
284     palignr %1, %2, %3, %4
285 %else
286     palignr %1, %2, %3
287 %endif
288 %elif cpuflag(mmx) ; [dst,] src1, src2, imm, tmp
289     %define %%dst %1
290 %if %0==5
291 %ifnidn %1, %2
292     mova    %%dst, %2
293 %endif
294     %rotate 1
295 %endif
296 %ifnidn %4, %2
297     mova    %4, %2
298 %endif
299 %if mmsize==8
300     psllq   %%dst, (8-%3)*8
301     psrlq   %4, %3*8
302 %else
303     pslldq  %%dst, 16-%3
304     psrldq  %4, %3
305 %endif
306     por     %%dst, %4
307 %endif
308 %endmacro
309
310 %macro PSHUFLW 1+
311     %if mmsize == 8
312         pshufw %1
313     %else
314         pshuflw %1
315     %endif
316 %endmacro
317
318 %macro PSWAPD 2
319 %if cpuflag(mmxext)
320     pshufw    %1, %2, q1032
321 %elif cpuflag(3dnowext)
322     pswapd    %1, %2
323 %elif cpuflag(3dnow)
324     movq      %1, %2
325     psrlq     %1, 32
326     punpckldq %1, %2
327 %endif
328 %endmacro
329
330 %macro DEINTB 5 ; mask, reg1, mask, reg2, optional src to fill masks from
331 %ifnum %5
332     pand   m%3, m%5, m%4 ; src .. y6 .. y4
333     pand   m%1, m%5, m%2 ; dst .. y6 .. y4
334 %else
335     mova   m%1, %5
336     pand   m%3, m%1, m%4 ; src .. y6 .. y4
337     pand   m%1, m%1, m%2 ; dst .. y6 .. y4
338 %endif
339     psrlw  m%2, 8        ; dst .. y7 .. y5
340     psrlw  m%4, 8        ; src .. y7 .. y5
341 %endmacro
342
343 %macro SUMSUB_BA 3-4
344 %if %0==3
345     padd%1  m%2, m%3
346     padd%1  m%3, m%3
347     psub%1  m%3, m%2
348 %else
349 %if avx_enabled == 0
350     mova    m%4, m%2
351     padd%1  m%2, m%3
352     psub%1  m%3, m%4
353 %else
354     padd%1  m%4, m%2, m%3
355     psub%1  m%3, m%2
356     SWAP    %2, %4
357 %endif
358 %endif
359 %endmacro
360
361 %macro SUMSUB_BADC 5-6
362 %if %0==6
363     SUMSUB_BA %1, %2, %3, %6
364     SUMSUB_BA %1, %4, %5, %6
365 %else
366     padd%1  m%2, m%3
367     padd%1  m%4, m%5
368     padd%1  m%3, m%3
369     padd%1  m%5, m%5
370     psub%1  m%3, m%2
371     psub%1  m%5, m%4
372 %endif
373 %endmacro
374
375 %macro SUMSUB2_AB 4
376 %ifnum %3
377     psub%1  m%4, m%2, m%3
378     psub%1  m%4, m%3
379     padd%1  m%2, m%2
380     padd%1  m%2, m%3
381 %else
382     mova    m%4, m%2
383     padd%1  m%2, m%2
384     padd%1  m%2, %3
385     psub%1  m%4, %3
386     psub%1  m%4, %3
387 %endif
388 %endmacro
389
390 %macro SUMSUB2_BA 4
391 %if avx_enabled == 0
392     mova    m%4, m%2
393     padd%1  m%2, m%3
394     padd%1  m%2, m%3
395     psub%1  m%3, m%4
396     psub%1  m%3, m%4
397 %else
398     padd%1  m%4, m%2, m%3
399     padd%1  m%4, m%3
400     psub%1  m%3, m%2
401     psub%1  m%3, m%2
402     SWAP     %2,  %4
403 %endif
404 %endmacro
405
406 %macro SUMSUBD2_AB 5
407 %ifnum %4
408     psra%1  m%5, m%2, 1  ; %3: %3>>1
409     psra%1  m%4, m%3, 1  ; %2: %2>>1
410     padd%1  m%4, m%2     ; %3: %3>>1+%2
411     psub%1  m%5, m%3     ; %2: %2>>1-%3
412     SWAP     %2, %5
413     SWAP     %3, %4
414 %else
415     mova    %5, m%2
416     mova    %4, m%3
417     psra%1  m%3, 1  ; %3: %3>>1
418     psra%1  m%2, 1  ; %2: %2>>1
419     padd%1  m%3, %5 ; %3: %3>>1+%2
420     psub%1  m%2, %4 ; %2: %2>>1-%3
421 %endif
422 %endmacro
423
424 %macro DCT4_1D 5
425 %ifnum %5
426     SUMSUB_BADC w, %4, %1, %3, %2, %5
427     SUMSUB_BA   w, %3, %4, %5
428     SUMSUB2_AB  w, %1, %2, %5
429     SWAP %1, %3, %4, %5, %2
430 %else
431     SUMSUB_BADC w, %4, %1, %3, %2
432     SUMSUB_BA   w, %3, %4
433     mova     [%5], m%2
434     SUMSUB2_AB  w, %1, [%5], %2
435     SWAP %1, %3, %4, %2
436 %endif
437 %endmacro
438
439 %macro IDCT4_1D 6-7
440 %ifnum %6
441     SUMSUBD2_AB %1, %3, %5, %7, %6
442     ; %3: %3>>1-%5 %5: %3+%5>>1
443     SUMSUB_BA   %1, %4, %2, %7
444     ; %4: %2+%4 %2: %2-%4
445     SUMSUB_BADC %1, %5, %4, %3, %2, %7
446     ; %5: %2+%4 + (%3+%5>>1)
447     ; %4: %2+%4 - (%3+%5>>1)
448     ; %3: %2-%4 + (%3>>1-%5)
449     ; %2: %2-%4 - (%3>>1-%5)
450 %else
451 %ifidn %1, w
452     SUMSUBD2_AB %1, %3, %5, [%6], [%6+16]
453 %else
454     SUMSUBD2_AB %1, %3, %5, [%6], [%6+32]
455 %endif
456     SUMSUB_BA   %1, %4, %2
457     SUMSUB_BADC %1, %5, %4, %3, %2
458 %endif
459     SWAP %2, %5, %4
460     ; %2: %2+%4 + (%3+%5>>1) row0
461     ; %3: %2-%4 + (%3>>1-%5) row1
462     ; %4: %2-%4 - (%3>>1-%5) row2
463     ; %5: %2+%4 - (%3+%5>>1) row3
464 %endmacro
465
466
467 %macro LOAD_DIFF 5
468 %ifidn %3, none
469     movh       %1, %4
470     movh       %2, %5
471     punpcklbw  %1, %2
472     punpcklbw  %2, %2
473     psubw      %1, %2
474 %else
475     movh       %1, %4
476     punpcklbw  %1, %3
477     movh       %2, %5
478     punpcklbw  %2, %3
479     psubw      %1, %2
480 %endif
481 %endmacro
482
483 %macro STORE_DCT 6
484     movq   [%5+%6+ 0], m%1
485     movq   [%5+%6+ 8], m%2
486     movq   [%5+%6+16], m%3
487     movq   [%5+%6+24], m%4
488     movhps [%5+%6+32], m%1
489     movhps [%5+%6+40], m%2
490     movhps [%5+%6+48], m%3
491     movhps [%5+%6+56], m%4
492 %endmacro
493
494 %macro LOAD_DIFF_8x4P 7-10 r0,r2,0 ; 4x dest, 2x temp, 2x pointer, increment?
495     LOAD_DIFF m%1, m%5, m%7, [%8],      [%9]
496     LOAD_DIFF m%2, m%6, m%7, [%8+r1],   [%9+r3]
497     LOAD_DIFF m%3, m%5, m%7, [%8+2*r1], [%9+2*r3]
498     LOAD_DIFF m%4, m%6, m%7, [%8+r4],   [%9+r5]
499 %if %10
500     lea %8, [%8+4*r1]
501     lea %9, [%9+4*r3]
502 %endif
503 %endmacro
504
505 %macro DIFFx2 6-7
506     movh       %3, %5
507     punpcklbw  %3, %4
508     psraw      %1, 6
509     paddsw     %1, %3
510     movh       %3, %6
511     punpcklbw  %3, %4
512     psraw      %2, 6
513     paddsw     %2, %3
514     packuswb   %2, %1
515 %endmacro
516
517 %macro STORE_DIFF 4
518     movh       %2, %4
519     punpcklbw  %2, %3
520     psraw      %1, 6
521     paddsw     %1, %2
522     packuswb   %1, %1
523     movh       %4, %1
524 %endmacro
525
526 %macro STORE_DIFFx2 8 ; add1, add2, reg1, reg2, zero, shift, source, stride
527     movh       %3, [%7]
528     movh       %4, [%7+%8]
529     psraw      %1, %6
530     psraw      %2, %6
531     punpcklbw  %3, %5
532     punpcklbw  %4, %5
533     paddw      %3, %1
534     paddw      %4, %2
535     packuswb   %3, %5
536     packuswb   %4, %5
537     movh     [%7], %3
538     movh  [%7+%8], %4
539 %endmacro
540
541 %macro PMINUB 3 ; dst, src, ignored
542 %if cpuflag(mmxext)
543     pminub   %1, %2
544 %else ; dst, src, tmp
545     mova     %3, %1
546     psubusb  %3, %2
547     psubb    %1, %3
548 %endif
549 %endmacro
550
551 %macro SPLATW 2-3 0
552 %if mmsize == 16
553     pshuflw    %1, %2, (%3)*0x55
554     punpcklqdq %1, %1
555 %elif cpuflag(mmxext)
556     pshufw     %1, %2, (%3)*0x55
557 %else
558     %ifnidn %1, %2
559         mova       %1, %2
560     %endif
561     %if %3 & 2
562         punpckhwd  %1, %1
563     %else
564         punpcklwd  %1, %1
565     %endif
566     %if %3 & 1
567         punpckhwd  %1, %1
568     %else
569         punpcklwd  %1, %1
570     %endif
571 %endif
572 %endmacro
573
574 %macro SPLATD 1
575 %if mmsize == 8
576     punpckldq  %1, %1
577 %elif cpuflag(sse2)
578     pshufd  %1, %1, 0
579 %elif cpuflag(sse)
580     shufps  %1, %1, 0
581 %endif
582 %endmacro
583
584 %macro CLIPW 3 ;(dst, min, max)
585     pmaxsw %1, %2
586     pminsw %1, %3
587 %endmacro
588
589 %macro PMINSD_MMX 3 ; dst, src, tmp
590     mova      %3, %2
591     pcmpgtd   %3, %1
592     pxor      %1, %2
593     pand      %1, %3
594     pxor      %1, %2
595 %endmacro
596
597 %macro PMAXSD_MMX 3 ; dst, src, tmp
598     mova      %3, %1
599     pcmpgtd   %3, %2
600     pand      %1, %3
601     pandn     %3, %2
602     por       %1, %3
603 %endmacro
604
605 %macro CLIPD_MMX 3-4 ; src/dst, min, max, tmp
606     PMINSD_MMX %1, %3, %4
607     PMAXSD_MMX %1, %2, %4
608 %endmacro
609
610 %macro CLIPD_SSE2 3-4 ; src/dst, min (float), max (float), unused
611     cvtdq2ps  %1, %1
612     minps     %1, %3
613     maxps     %1, %2
614     cvtps2dq  %1, %1
615 %endmacro
616
617 %macro CLIPD_SSE41 3-4 ;  src/dst, min, max, unused
618     pminsd  %1, %3
619     pmaxsd  %1, %2
620 %endmacro
621
622 %macro VBROADCASTSS 2 ; dst xmm/ymm, src m32
623 %if cpuflag(avx)
624     vbroadcastss %1, %2
625 %else ; sse
626     movss        %1, %2
627     shufps       %1, %1, 0
628 %endif
629 %endmacro
630
631 %macro VBROADCASTSD 2 ; dst xmm/ymm, src m64
632 %if cpuflag(avx) && mmsize == 32
633     vbroadcastsd %1, %2
634 %elif cpuflag(sse3)
635     movddup      %1, %2
636 %else ; sse2
637     movsd        %1, %2
638     movlhps      %1, %1
639 %endif
640 %endmacro
641
642 %macro SHUFFLE_MASK_W 8
643     %rep 8
644         %if %1>=0x80
645             db %1, %1
646         %else
647             db %1*2
648             db %1*2+1
649         %endif
650         %rotate 1
651     %endrep
652 %endmacro
653
654 %macro PMOVSXWD 2; dst, src
655 %if cpuflag(sse4)
656     pmovsxwd     %1, %2
657 %else
658     %ifnidn %1, %2
659     mova         %1, %2
660     %endif
661     punpcklwd    %1, %1
662     psrad        %1, 16
663 %endif
664 %endmacro