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