x86: ABS2: 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 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 4
191 %if cpuflag(ssse3)
192     pabsw   %1, %1
193     pabsw   %2, %2
194 %elif cpuflag(mmxext) ; a, b, tmp0, tmp1
195     pxor    %3, %3
196     pxor    %4, %4
197     psubw   %3, %1
198     psubw   %4, %2
199     pmaxsw  %1, %3
200     pmaxsw  %2, %4
201 %else ; a, b, tmp0, tmp1
202     pxor       %3, %3
203     pxor       %4, %4
204     pcmpgtw    %3, %1
205     pcmpgtw    %4, %2
206     pxor       %1, %3
207     pxor       %2, %4
208     psubw      %1, %3
209     psubw      %2, %4
210 %endif
211 %endmacro
212
213 %macro ABSB_MMX 2
214     pxor    %2, %2
215     psubb   %2, %1
216     pminub  %1, %2
217 %endmacro
218
219 %macro ABSB2_MMX 4
220     pxor    %3, %3
221     pxor    %4, %4
222     psubb   %3, %1
223     psubb   %4, %2
224     pminub  %1, %3
225     pminub  %2, %4
226 %endmacro
227
228 %macro ABSD2_MMX 4
229     pxor    %3, %3
230     pxor    %4, %4
231     pcmpgtd %3, %1
232     pcmpgtd %4, %2
233     pxor    %1, %3
234     pxor    %2, %4
235     psubd   %1, %3
236     psubd   %2, %4
237 %endmacro
238
239 %macro ABSB_SSSE3 2
240     pabsb   %1, %1
241 %endmacro
242
243 %macro ABSB2_SSSE3 4
244     pabsb   %1, %1
245     pabsb   %2, %2
246 %endmacro
247
248 %macro ABS4 6
249     ABS2 %1, %2, %5, %6
250     ABS2 %3, %4, %5, %6
251 %endmacro
252
253 %define ABSB ABSB_MMX
254 %define ABSB2 ABSB2_MMX
255
256 %macro SPLATB_LOAD 3
257 %if cpuflag(ssse3)
258     movd      %1, [%2-3]
259     pshufb    %1, %3
260 %else
261     movd      %1, [%2-3] ;to avoid crossing a cacheline
262     punpcklbw %1, %1
263     SPLATW    %1, %1, 3
264 %endif
265 %endmacro
266
267 %macro SPLATB_REG 3
268 %if cpuflag(ssse3)
269     movd      %1, %2d
270     pshufb    %1, %3
271 %else
272     movd      %1, %2d
273     punpcklbw %1, %1
274     SPLATW    %1, %1, 0
275 %endif
276 %endmacro
277
278 %macro PALIGNR 4-5
279 %if cpuflag(ssse3)
280 %if %0==5
281     palignr %1, %2, %3, %4
282 %else
283     palignr %1, %2, %3
284 %endif
285 %elif cpuflag(mmx) ; [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 %endif
305 %endmacro
306
307 %macro PSHUFLW 1+
308     %if mmsize == 8
309         pshufw %1
310     %else
311         pshuflw %1
312     %endif
313 %endmacro
314
315 %macro PSWAPD 2
316 %if cpuflag(mmxext)
317     pshufw    %1, %2, q1032
318 %elif cpuflag(3dnowext)
319     pswapd    %1, %2
320 %elif cpuflag(3dnow)
321     movq      %1, %2
322     psrlq     %1, 32
323     punpckldq %1, %2
324 %endif
325 %endmacro
326
327 %macro DEINTB 5 ; mask, reg1, mask, reg2, optional src to fill masks from
328 %ifnum %5
329     pand   m%3, m%5, m%4 ; src .. y6 .. y4
330     pand   m%1, m%5, m%2 ; dst .. y6 .. y4
331 %else
332     mova   m%1, %5
333     pand   m%3, m%1, m%4 ; src .. y6 .. y4
334     pand   m%1, m%1, m%2 ; dst .. y6 .. y4
335 %endif
336     psrlw  m%2, 8        ; dst .. y7 .. y5
337     psrlw  m%4, 8        ; src .. y7 .. y5
338 %endmacro
339
340 %macro SUMSUB_BA 3-4
341 %if %0==3
342     padd%1  m%2, m%3
343     padd%1  m%3, m%3
344     psub%1  m%3, m%2
345 %else
346 %if avx_enabled == 0
347     mova    m%4, m%2
348     padd%1  m%2, m%3
349     psub%1  m%3, m%4
350 %else
351     padd%1  m%4, m%2, m%3
352     psub%1  m%3, m%2
353     SWAP    %2, %4
354 %endif
355 %endif
356 %endmacro
357
358 %macro SUMSUB_BADC 5-6
359 %if %0==6
360     SUMSUB_BA %1, %2, %3, %6
361     SUMSUB_BA %1, %4, %5, %6
362 %else
363     padd%1  m%2, m%3
364     padd%1  m%4, m%5
365     padd%1  m%3, m%3
366     padd%1  m%5, m%5
367     psub%1  m%3, m%2
368     psub%1  m%5, m%4
369 %endif
370 %endmacro
371
372 %macro SUMSUB2_AB 4
373 %ifnum %3
374     psub%1  m%4, m%2, m%3
375     psub%1  m%4, m%3
376     padd%1  m%2, m%2
377     padd%1  m%2, m%3
378 %else
379     mova    m%4, m%2
380     padd%1  m%2, m%2
381     padd%1  m%2, %3
382     psub%1  m%4, %3
383     psub%1  m%4, %3
384 %endif
385 %endmacro
386
387 %macro SUMSUB2_BA 4
388 %if avx_enabled == 0
389     mova    m%4, m%2
390     padd%1  m%2, m%3
391     padd%1  m%2, m%3
392     psub%1  m%3, m%4
393     psub%1  m%3, m%4
394 %else
395     padd%1  m%4, m%2, m%3
396     padd%1  m%4, m%3
397     psub%1  m%3, m%2
398     psub%1  m%3, m%2
399     SWAP     %2,  %4
400 %endif
401 %endmacro
402
403 %macro SUMSUBD2_AB 5
404 %ifnum %4
405     psra%1  m%5, m%2, 1  ; %3: %3>>1
406     psra%1  m%4, m%3, 1  ; %2: %2>>1
407     padd%1  m%4, m%2     ; %3: %3>>1+%2
408     psub%1  m%5, m%3     ; %2: %2>>1-%3
409     SWAP     %2, %5
410     SWAP     %3, %4
411 %else
412     mova    %5, m%2
413     mova    %4, m%3
414     psra%1  m%3, 1  ; %3: %3>>1
415     psra%1  m%2, 1  ; %2: %2>>1
416     padd%1  m%3, %5 ; %3: %3>>1+%2
417     psub%1  m%2, %4 ; %2: %2>>1-%3
418 %endif
419 %endmacro
420
421 %macro DCT4_1D 5
422 %ifnum %5
423     SUMSUB_BADC w, %4, %1, %3, %2, %5
424     SUMSUB_BA   w, %3, %4, %5
425     SUMSUB2_AB  w, %1, %2, %5
426     SWAP %1, %3, %4, %5, %2
427 %else
428     SUMSUB_BADC w, %4, %1, %3, %2
429     SUMSUB_BA   w, %3, %4
430     mova     [%5], m%2
431     SUMSUB2_AB  w, %1, [%5], %2
432     SWAP %1, %3, %4, %2
433 %endif
434 %endmacro
435
436 %macro IDCT4_1D 6-7
437 %ifnum %6
438     SUMSUBD2_AB %1, %3, %5, %7, %6
439     ; %3: %3>>1-%5 %5: %3+%5>>1
440     SUMSUB_BA   %1, %4, %2, %7
441     ; %4: %2+%4 %2: %2-%4
442     SUMSUB_BADC %1, %5, %4, %3, %2, %7
443     ; %5: %2+%4 + (%3+%5>>1)
444     ; %4: %2+%4 - (%3+%5>>1)
445     ; %3: %2-%4 + (%3>>1-%5)
446     ; %2: %2-%4 - (%3>>1-%5)
447 %else
448 %ifidn %1, w
449     SUMSUBD2_AB %1, %3, %5, [%6], [%6+16]
450 %else
451     SUMSUBD2_AB %1, %3, %5, [%6], [%6+32]
452 %endif
453     SUMSUB_BA   %1, %4, %2
454     SUMSUB_BADC %1, %5, %4, %3, %2
455 %endif
456     SWAP %2, %5, %4
457     ; %2: %2+%4 + (%3+%5>>1) row0
458     ; %3: %2-%4 + (%3>>1-%5) row1
459     ; %4: %2-%4 - (%3>>1-%5) row2
460     ; %5: %2+%4 - (%3+%5>>1) row3
461 %endmacro
462
463
464 %macro LOAD_DIFF 5
465 %ifidn %3, none
466     movh       %1, %4
467     movh       %2, %5
468     punpcklbw  %1, %2
469     punpcklbw  %2, %2
470     psubw      %1, %2
471 %else
472     movh       %1, %4
473     punpcklbw  %1, %3
474     movh       %2, %5
475     punpcklbw  %2, %3
476     psubw      %1, %2
477 %endif
478 %endmacro
479
480 %macro STORE_DCT 6
481     movq   [%5+%6+ 0], m%1
482     movq   [%5+%6+ 8], m%2
483     movq   [%5+%6+16], m%3
484     movq   [%5+%6+24], m%4
485     movhps [%5+%6+32], m%1
486     movhps [%5+%6+40], m%2
487     movhps [%5+%6+48], m%3
488     movhps [%5+%6+56], m%4
489 %endmacro
490
491 %macro LOAD_DIFF_8x4P 7-10 r0,r2,0 ; 4x dest, 2x temp, 2x pointer, increment?
492     LOAD_DIFF m%1, m%5, m%7, [%8],      [%9]
493     LOAD_DIFF m%2, m%6, m%7, [%8+r1],   [%9+r3]
494     LOAD_DIFF m%3, m%5, m%7, [%8+2*r1], [%9+2*r3]
495     LOAD_DIFF m%4, m%6, m%7, [%8+r4],   [%9+r5]
496 %if %10
497     lea %8, [%8+4*r1]
498     lea %9, [%9+4*r3]
499 %endif
500 %endmacro
501
502 %macro DIFFx2 6-7
503     movh       %3, %5
504     punpcklbw  %3, %4
505     psraw      %1, 6
506     paddsw     %1, %3
507     movh       %3, %6
508     punpcklbw  %3, %4
509     psraw      %2, 6
510     paddsw     %2, %3
511     packuswb   %2, %1
512 %endmacro
513
514 %macro STORE_DIFF 4
515     movh       %2, %4
516     punpcklbw  %2, %3
517     psraw      %1, 6
518     paddsw     %1, %2
519     packuswb   %1, %1
520     movh       %4, %1
521 %endmacro
522
523 %macro STORE_DIFFx2 8 ; add1, add2, reg1, reg2, zero, shift, source, stride
524     movh       %3, [%7]
525     movh       %4, [%7+%8]
526     psraw      %1, %6
527     psraw      %2, %6
528     punpcklbw  %3, %5
529     punpcklbw  %4, %5
530     paddw      %3, %1
531     paddw      %4, %2
532     packuswb   %3, %5
533     packuswb   %4, %5
534     movh     [%7], %3
535     movh  [%7+%8], %4
536 %endmacro
537
538 %macro PMINUB 3 ; dst, src, ignored
539 %if cpuflag(mmxext)
540     pminub   %1, %2
541 %else ; dst, src, tmp
542     mova     %3, %1
543     psubusb  %3, %2
544     psubb    %1, %3
545 %endif
546 %endmacro
547
548 %macro SPLATW 2-3 0
549 %if mmsize == 16
550     pshuflw    %1, %2, (%3)*0x55
551     punpcklqdq %1, %1
552 %elif cpuflag(mmxext)
553     pshufw     %1, %2, (%3)*0x55
554 %else
555     %ifnidn %1, %2
556         mova       %1, %2
557     %endif
558     %if %3 & 2
559         punpckhwd  %1, %1
560     %else
561         punpcklwd  %1, %1
562     %endif
563     %if %3 & 1
564         punpckhwd  %1, %1
565     %else
566         punpcklwd  %1, %1
567     %endif
568 %endif
569 %endmacro
570
571 %macro SPLATD 1
572 %if mmsize == 8
573     punpckldq  %1, %1
574 %elif cpuflag(sse2)
575     pshufd  %1, %1, 0
576 %elif cpuflag(sse)
577     shufps  %1, %1, 0
578 %endif
579 %endmacro
580
581 %macro CLIPW 3 ;(dst, min, max)
582     pmaxsw %1, %2
583     pminsw %1, %3
584 %endmacro
585
586 %macro PMINSD_MMX 3 ; dst, src, tmp
587     mova      %3, %2
588     pcmpgtd   %3, %1
589     pxor      %1, %2
590     pand      %1, %3
591     pxor      %1, %2
592 %endmacro
593
594 %macro PMAXSD_MMX 3 ; dst, src, tmp
595     mova      %3, %1
596     pcmpgtd   %3, %2
597     pand      %1, %3
598     pandn     %3, %2
599     por       %1, %3
600 %endmacro
601
602 %macro CLIPD_MMX 3-4 ; src/dst, min, max, tmp
603     PMINSD_MMX %1, %3, %4
604     PMAXSD_MMX %1, %2, %4
605 %endmacro
606
607 %macro CLIPD_SSE2 3-4 ; src/dst, min (float), max (float), unused
608     cvtdq2ps  %1, %1
609     minps     %1, %3
610     maxps     %1, %2
611     cvtps2dq  %1, %1
612 %endmacro
613
614 %macro CLIPD_SSE41 3-4 ;  src/dst, min, max, unused
615     pminsd  %1, %3
616     pmaxsd  %1, %2
617 %endmacro
618
619 %macro VBROADCASTSS 2 ; dst xmm/ymm, src m32
620 %if cpuflag(avx)
621     vbroadcastss %1, %2
622 %else ; sse
623     movss        %1, %2
624     shufps       %1, %1, 0
625 %endif
626 %endmacro
627
628 %macro VBROADCASTSD 2 ; dst xmm/ymm, src m64
629 %if cpuflag(avx) && mmsize == 32
630     vbroadcastsd %1, %2
631 %elif cpuflag(sse3)
632     movddup      %1, %2
633 %else ; sse2
634     movsd        %1, %2
635     movlhps      %1, %1
636 %endif
637 %endmacro
638
639 %macro SHUFFLE_MASK_W 8
640     %rep 8
641         %if %1>=0x80
642             db %1, %1
643         %else
644             db %1*2
645             db %1*2+1
646         %endif
647         %rotate 1
648     %endrep
649 %endmacro
650
651 %macro PMOVSXWD 2; dst, src
652 %if cpuflag(sse4)
653     pmovsxwd     %1, %2
654 %else
655     %ifnidn %1, %2
656     mova         %1, %2
657     %endif
658     punpcklwd    %1, %1
659     psrad        %1, 16
660 %endif
661 %endmacro