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