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