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