1;*****************************************************************************
2;* x86util.asm: x86 utility macros
3;*****************************************************************************
4;* Copyright (C) 2008-2014 x264 project
5;*
6;* Authors: Holger Lubitz <holger@lubitz.org>
7;*          Loren Merritt <lorenm@u.washington.edu>
8;*
9;* This program is free software; you can redistribute it and/or modify
10;* it under the terms of the GNU General Public License as published by
11;* the Free Software Foundation; either version 2 of the License, or
12;* (at your option) any later version.
13;*
14;* This program is distributed in the hope that it will be useful,
15;* but WITHOUT ANY WARRANTY; without even the implied warranty of
16;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17;* GNU General Public License for more details.
18;*
19;* You should have received a copy of the GNU General Public License
20;* along with this program; if not, write to the Free Software
21;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111, USA.
22;*
23;* This program is also available under a commercial proprietary license.
24;* For more information, contact us at licensing@x264.com.
25;*****************************************************************************
26
27%assign FENC_STRIDE 16
28%assign FDEC_STRIDE 32
29
30%assign SIZEOF_PIXEL 1
31%assign SIZEOF_DCTCOEF 2
32%define pixel byte
33%define vpbroadcastdct vpbroadcastw
34%define vpbroadcastpix vpbroadcastb
35%if HIGH_BIT_DEPTH
36    %assign SIZEOF_PIXEL 2
37    %assign SIZEOF_DCTCOEF 4
38    %define pixel word
39    %define vpbroadcastdct vpbroadcastd
40    %define vpbroadcastpix vpbroadcastw
41%endif
42
43%assign FENC_STRIDEB SIZEOF_PIXEL*FENC_STRIDE
44%assign FDEC_STRIDEB SIZEOF_PIXEL*FDEC_STRIDE
45
46%assign PIXEL_MAX ((1 << BIT_DEPTH)-1)
47
48%macro FIX_STRIDES 1-*
49%if HIGH_BIT_DEPTH
50%rep %0
51    add %1, %1
52    %rotate 1
53%endrep
54%endif
55%endmacro
56
57
58%macro SBUTTERFLY 4
59%ifidn %1, dqqq
60    vperm2i128  m%4, m%2, m%3, q0301 ; punpckh
61    vinserti128 m%2, m%2, xm%3, 1    ; punpckl
62%elif avx_enabled && mmsize >= 16
63    punpckh%1 m%4, m%2, m%3
64    punpckl%1 m%2, m%3
65%else
66    mova      m%4, m%2
67    punpckl%1 m%2, m%3
68    punpckh%1 m%4, m%3
69%endif
70    SWAP %3, %4
71%endmacro
72
73%macro SBUTTERFLY2 4
74    punpckl%1 m%4, m%2, m%3
75    punpckh%1 m%2, m%2, m%3
76    SWAP %2, %4, %3
77%endmacro
78
79%macro TRANSPOSE4x4W 5
80    SBUTTERFLY wd, %1, %2, %5
81    SBUTTERFLY wd, %3, %4, %5
82    SBUTTERFLY dq, %1, %3, %5
83    SBUTTERFLY dq, %2, %4, %5
84    SWAP %2, %3
85%endmacro
86
87%macro TRANSPOSE2x4x4W 5
88    SBUTTERFLY wd,  %1, %2, %5
89    SBUTTERFLY wd,  %3, %4, %5
90    SBUTTERFLY dq,  %1, %3, %5
91    SBUTTERFLY dq,  %2, %4, %5
92    SBUTTERFLY qdq, %1, %2, %5
93    SBUTTERFLY qdq, %3, %4, %5
94%endmacro
95
96%macro TRANSPOSE4x4D 5
97    SBUTTERFLY dq,  %1, %2, %5
98    SBUTTERFLY dq,  %3, %4, %5
99    SBUTTERFLY qdq, %1, %3, %5
100    SBUTTERFLY qdq, %2, %4, %5
101    SWAP %2, %3
102%endmacro
103
104%macro TRANSPOSE8x8W 9-11
105%if ARCH_X86_64
106    SBUTTERFLY wd,  %1, %2, %9
107    SBUTTERFLY wd,  %3, %4, %9
108    SBUTTERFLY wd,  %5, %6, %9
109    SBUTTERFLY wd,  %7, %8, %9
110    SBUTTERFLY dq,  %1, %3, %9
111    SBUTTERFLY dq,  %2, %4, %9
112    SBUTTERFLY dq,  %5, %7, %9
113    SBUTTERFLY dq,  %6, %8, %9
114    SBUTTERFLY qdq, %1, %5, %9
115    SBUTTERFLY qdq, %2, %6, %9
116    SBUTTERFLY qdq, %3, %7, %9
117    SBUTTERFLY qdq, %4, %8, %9
118    SWAP %2, %5
119    SWAP %4, %7
120%else
121; in:  m0..m7, unless %11 in which case m6 is in %9
122; out: m0..m7, unless %11 in which case m4 is in %10
123; spills into %9 and %10
124%if %0<11
125    movdqa %9, m%7
126%endif
127    SBUTTERFLY wd,  %1, %2, %7
128    movdqa %10, m%2
129    movdqa m%7, %9
130    SBUTTERFLY wd,  %3, %4, %2
131    SBUTTERFLY wd,  %5, %6, %2
132    SBUTTERFLY wd,  %7, %8, %2
133    SBUTTERFLY dq,  %1, %3, %2
134    movdqa %9, m%3
135    movdqa m%2, %10
136    SBUTTERFLY dq,  %2, %4, %3
137    SBUTTERFLY dq,  %5, %7, %3
138    SBUTTERFLY dq,  %6, %8, %3
139    SBUTTERFLY qdq, %1, %5, %3
140    SBUTTERFLY qdq, %2, %6, %3
141    movdqa %10, m%2
142    movdqa m%3, %9
143    SBUTTERFLY qdq, %3, %7, %2
144    SBUTTERFLY qdq, %4, %8, %2
145    SWAP %2, %5
146    SWAP %4, %7
147%if %0<11
148    movdqa m%5, %10
149%endif
150%endif
151%endmacro
152
153%macro WIDEN_SXWD 2
154    punpckhwd m%2, m%1
155    psrad     m%2, 16
156%if cpuflag(sse4)
157    pmovsxwd  m%1, m%1
158%else
159    punpcklwd m%1, m%1
160    psrad     m%1, 16
161%endif
162%endmacro
163
164%macro ABSW 2-3 ; dst, src, tmp (tmp used only if dst==src)
165%if cpuflag(ssse3)
166    pabsw   %1, %2
167%elifidn %3, sign ; version for pairing with PSIGNW: modifies src
168    pxor    %1, %1
169    pcmpgtw %1, %2
170    pxor    %2, %1
171    psubw   %2, %1
172    SWAP    %1, %2
173%elifidn %1, %2
174    pxor    %3, %3
175    psubw   %3, %1
176    pmaxsw  %1, %3
177%elifid %2
178    pxor    %1, %1
179    psubw   %1, %2
180    pmaxsw  %1, %2
181%elif %0 == 2
182    pxor    %1, %1
183    psubw   %1, %2
184    pmaxsw  %1, %2
185%else
186    mova    %1, %2
187    pxor    %3, %3
188    psubw   %3, %1
189    pmaxsw  %1, %3
190%endif
191%endmacro
192
193%macro ABSW2 6 ; dst1, dst2, src1, src2, tmp, tmp
194%if cpuflag(ssse3)
195    pabsw   %1, %3
196    pabsw   %2, %4
197%elifidn %1, %3
198    pxor    %5, %5
199    pxor    %6, %6
200    psubw   %5, %1
201    psubw   %6, %2
202    pmaxsw  %1, %5
203    pmaxsw  %2, %6
204%else
205    pxor    %1, %1
206    pxor    %2, %2
207    psubw   %1, %3
208    psubw   %2, %4
209    pmaxsw  %1, %3
210    pmaxsw  %2, %4
211%endif
212%endmacro
213
214%macro ABSB 2
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 ABSD 2-3
225%if cpuflag(ssse3)
226    pabsd   %1, %2
227%else
228    %define %%s %2
229%if %0 == 3
230    mova    %3, %2
231    %define %%s %3
232%endif
233    pxor     %1, %1
234    pcmpgtd  %1, %%s
235    pxor    %%s, %1
236    psubd   %%s, %1
237    SWAP     %1, %%s
238%endif
239%endmacro
240
241%macro PSIGN 3-4
242%if cpuflag(ssse3) && %0 == 4
243    psign%1 %2, %3, %4
244%elif cpuflag(ssse3)
245    psign%1 %2, %3
246%elif %0 == 4
247    pxor    %2, %3, %4
248    psub%1  %2, %4
249%else
250    pxor    %2, %3
251    psub%1  %2, %3
252%endif
253%endmacro
254
255%define PSIGNW PSIGN w,
256%define PSIGND PSIGN d,
257
258%macro SPLATB_LOAD 3
259%if cpuflag(ssse3)
260    movd      %1, [%2-3]
261    pshufb    %1, %3
262%else
263    movd      %1, [%2-3] ;to avoid crossing a cacheline
264    punpcklbw %1, %1
265    SPLATW    %1, %1, 3
266%endif
267%endmacro
268
269%imacro SPLATW 2-3 0
270%if cpuflag(avx2) && %3 == 0
271    vpbroadcastw %1, %2
272%else
273    PSHUFLW      %1, %2, (%3)*q1111
274%if mmsize == 16
275    punpcklqdq   %1, %1
276%endif
277%endif
278%endmacro
279
280%imacro SPLATD 2-3 0
281%if mmsize == 16
282    pshufd %1, %2, (%3)*q1111
283%else
284    pshufw %1, %2, (%3)*q0101 + ((%3)+1)*q1010
285%endif
286%endmacro
287
288%macro CLIPW 3 ;(dst, min, max)
289    pmaxsw %1, %2
290    pminsw %1, %3
291%endmacro
292
293%macro HADDD 2 ; sum junk
294%if sizeof%1 == 32
295%define %2 xmm%2
296    vextracti128 %2, %1, 1
297%define %1 xmm%1
298    paddd   %1, %2
299%endif
300%if mmsize >= 16
301%if cpuflag(xop) && sizeof%1 == 16
302    vphadddq %1, %1
303%endif
304    movhlps %2, %1
305    paddd   %1, %2
306%endif
307%if notcpuflag(xop) || sizeof%1 != 16
308    PSHUFLW %2, %1, q0032
309    paddd   %1, %2
310%endif
311%undef %1
312%undef %2
313%endmacro
314
315%macro HADDW 2 ; reg, tmp
316%if cpuflag(xop) && sizeof%1 == 16
317    vphaddwq  %1, %1
318    movhlps   %2, %1
319    paddd     %1, %2
320%else
321    pmaddwd %1, [pw_1]
322    HADDD   %1, %2
323%endif
324%endmacro
325
326%macro HADDUWD 2
327%if cpuflag(xop) && sizeof%1 == 16
328    vphadduwd %1, %1
329%else
330    psrld %2, %1, 16
331    pslld %1, 16
332    psrld %1, 16
333    paddd %1, %2
334%endif
335%endmacro
336
337%macro HADDUW 2
338%if cpuflag(xop) && sizeof%1 == 16
339    vphadduwq %1, %1
340    movhlps   %2, %1
341    paddd     %1, %2
342%else
343    HADDUWD   %1, %2
344    HADDD     %1, %2
345%endif
346%endmacro
347
348%macro PALIGNR 4-5 ; [dst,] src1, src2, imm, tmp
349; AVX2 version uses a precalculated extra input that
350; can be re-used across calls
351%if sizeof%1==32
352                                 ; %3 = abcdefgh ijklmnop (lower address)
353                                 ; %2 = ABCDEFGH IJKLMNOP (higher address)
354;   vperm2i128 %5, %2, %3, q0003 ; %5 = ijklmnop ABCDEFGH
355%if %4 < 16
356    palignr    %1, %5, %3, %4    ; %1 = bcdefghi jklmnopA
357%else
358    palignr    %1, %2, %5, %4-16 ; %1 = pABCDEFG HIJKLMNO
359%endif
360%elif cpuflag(ssse3)
361    %if %0==5
362        palignr %1, %2, %3, %4
363    %else
364        palignr %1, %2, %3
365    %endif
366%else
367    %define %%dst %1
368    %if %0==5
369        %ifnidn %1, %2
370            mova %%dst, %2
371        %endif
372        %rotate 1
373    %endif
374    %ifnidn %4, %2
375        mova %4, %2
376    %endif
377    %if mmsize==8
378        psllq  %%dst, (8-%3)*8
379        psrlq  %4, %3*8
380    %else
381        pslldq %%dst, 16-%3
382        psrldq %4, %3
383    %endif
384    por %%dst, %4
385%endif
386%endmacro
387
388%macro PSHUFLW 1+
389    %if mmsize == 8
390        pshufw %1
391    %else
392        pshuflw %1
393    %endif
394%endmacro
395
396; shift a mmxreg by n bytes, or a xmmreg by 2*n bytes
397; values shifted in are undefined
398; faster if dst==src
399%define PSLLPIX PSXLPIX l, -1, ;dst, src, shift
400%define PSRLPIX PSXLPIX r,  1, ;dst, src, shift
401%macro PSXLPIX 5
402    %if mmsize == 8
403        %if %5&1
404            ps%1lq %3, %4, %5*8
405        %else
406            pshufw %3, %4, (q3210<<8>>(8+%2*%5))&0xff
407        %endif
408    %else
409        ps%1ldq %3, %4, %5*2
410    %endif
411%endmacro
412
413%macro DEINTB 5 ; mask, reg1, mask, reg2, optional src to fill masks from
414%ifnum %5
415    pand   m%3, m%5, m%4 ; src .. y6 .. y4
416    pand   m%1, m%5, m%2 ; dst .. y6 .. y4
417%else
418    mova   m%1, %5
419    pand   m%3, m%1, m%4 ; src .. y6 .. y4
420    pand   m%1, m%1, m%2 ; dst .. y6 .. y4
421%endif
422    psrlw  m%2, 8        ; dst .. y7 .. y5
423    psrlw  m%4, 8        ; src .. y7 .. y5
424%endmacro
425
426%macro SUMSUB_BA 3-4
427%if %0==3
428    padd%1  m%2, m%3
429    padd%1  m%3, m%3
430    psub%1  m%3, m%2
431%elif avx_enabled
432    padd%1  m%4, m%2, m%3
433    psub%1  m%3, m%2
434    SWAP    %2, %4
435%else
436    mova    m%4, m%2
437    padd%1  m%2, m%3
438    psub%1  m%3, m%4
439%endif
440%endmacro
441
442%macro SUMSUB_BADC 5-6
443%if %0==6
444    SUMSUB_BA %1, %2, %3, %6
445    SUMSUB_BA %1, %4, %5, %6
446%else
447    padd%1  m%2, m%3
448    padd%1  m%4, m%5
449    padd%1  m%3, m%3
450    padd%1  m%5, m%5
451    psub%1  m%3, m%2
452    psub%1  m%5, m%4
453%endif
454%endmacro
455
456%macro HADAMARD4_V 4+
457    SUMSUB_BADC w, %1, %2, %3, %4
458    SUMSUB_BADC w, %1, %3, %2, %4
459%endmacro
460
461%macro HADAMARD8_V 8+
462    SUMSUB_BADC w, %1, %2, %3, %4
463    SUMSUB_BADC w, %5, %6, %7, %8
464    SUMSUB_BADC w, %1, %3, %2, %4
465    SUMSUB_BADC w, %5, %7, %6, %8
466    SUMSUB_BADC w, %1, %5, %2, %6
467    SUMSUB_BADC w, %3, %7, %4, %8
468%endmacro
469
470%macro TRANS_SSE2 5-6
471; TRANSPOSE2x2
472; %1: transpose width (d/q) - use SBUTTERFLY qdq for dq
473; %2: ord/unord (for compat with sse4, unused)
474; %3/%4: source regs
475; %5/%6: tmp regs
476%ifidn %1, d
477%define mask [mask_10]
478%define shift 16
479%elifidn %1, q
480%define mask [mask_1100]
481%define shift 32
482%endif
483%if %0==6 ; less dependency if we have two tmp
484    mova   m%5, mask   ; ff00
485    mova   m%6, m%4    ; x5x4
486    psll%1 m%4, shift  ; x4..
487    pand   m%6, m%5    ; x5..
488    pandn  m%5, m%3    ; ..x0
489    psrl%1 m%3, shift  ; ..x1
490    por    m%4, m%5    ; x4x0
491    por    m%3, m%6    ; x5x1
492%else ; more dependency, one insn less. sometimes faster, sometimes not
493    mova   m%5, m%4    ; x5x4
494    psll%1 m%4, shift  ; x4..
495    pxor   m%4, m%3    ; (x4^x1)x0
496    pand   m%4, mask   ; (x4^x1)..
497    pxor   m%3, m%4    ; x4x0
498    psrl%1 m%4, shift  ; ..(x1^x4)
499    pxor   m%5, m%4    ; x5x1
500    SWAP   %4, %3, %5
501%endif
502%endmacro
503
504%macro TRANS_SSE4 5-6 ; see above
505%ifidn %1, d
506%ifidn %2, ord
507    psrl%1  m%5, m%3, 16
508    pblendw m%5, m%4, q2222
509    psll%1  m%4, 16
510    pblendw m%4, m%3, q1111
511    SWAP     %3, %5
512%else
513%if avx_enabled
514    pblendw m%5, m%3, m%4, q2222
515    SWAP     %3, %5
516%else
517    mova    m%5, m%3
518    pblendw m%3, m%4, q2222
519%endif
520    psll%1  m%4, 16
521    psrl%1  m%5, 16
522    por     m%4, m%5
523%endif
524%elifidn %1, q
525    shufps m%5, m%3, m%4, q3131
526    shufps m%3, m%3, m%4, q2020
527    SWAP    %4, %5
528%endif
529%endmacro
530
531%macro TRANS_XOP 5-6
532%ifidn %1, d
533    vpperm m%5, m%3, m%4, [transd_shuf1]
534    vpperm m%3, m%3, m%4, [transd_shuf2]
535%elifidn %1, q
536    shufps m%5, m%3, m%4, q3131
537    shufps m%3, m%4, q2020
538%endif
539    SWAP    %4, %5
540%endmacro
541
542%macro HADAMARD 5-6
543; %1=distance in words (0 for vertical pass, 1/2/4 for horizontal passes)
544; %2=sumsub/max/amax (sum and diff / maximum / maximum of absolutes)
545; %3/%4: regs
546; %5(%6): tmpregs
547%if %1!=0 ; have to reorder stuff for horizontal op
548    %ifidn %2, sumsub
549        %define ORDER ord
550        ; sumsub needs order because a-b != b-a unless a=b
551    %else
552        %define ORDER unord
553        ; if we just max, order doesn't matter (allows pblendw+or in sse4)
554    %endif
555    %if %1==1
556        TRANS d, ORDER, %3, %4, %5, %6
557    %elif %1==2
558        %if mmsize==8
559            SBUTTERFLY dq, %3, %4, %5
560        %else
561            TRANS q, ORDER, %3, %4, %5, %6
562        %endif
563    %elif %1==4
564        SBUTTERFLY qdq, %3, %4, %5
565    %elif %1==8
566        SBUTTERFLY dqqq, %3, %4, %5
567    %endif
568%endif
569%ifidn %2, sumsub
570    SUMSUB_BA w, %3, %4, %5
571%else
572    %ifidn %2, amax
573        %if %0==6
574            ABSW2 m%3, m%4, m%3, m%4, m%5, m%6
575        %else
576            ABSW m%3, m%3, m%5
577            ABSW m%4, m%4, m%5
578        %endif
579    %endif
580    pmaxsw m%3, m%4
581%endif
582%endmacro
583
584
585%macro HADAMARD2_2D 6-7 sumsub
586    HADAMARD 0, sumsub, %1, %2, %5
587    HADAMARD 0, sumsub, %3, %4, %5
588    SBUTTERFLY %6, %1, %2, %5
589%ifnum %7
590    HADAMARD 0, amax, %1, %2, %5, %7
591%else
592    HADAMARD 0, %7, %1, %2, %5
593%endif
594    SBUTTERFLY %6, %3, %4, %5
595%ifnum %7
596    HADAMARD 0, amax, %3, %4, %5, %7
597%else
598    HADAMARD 0, %7, %3, %4, %5
599%endif
600%endmacro
601
602%macro HADAMARD4_2D 5-6 sumsub
603    HADAMARD2_2D %1, %2, %3, %4, %5, wd
604    HADAMARD2_2D %1, %3, %2, %4, %5, dq, %6
605    SWAP %2, %3
606%endmacro
607
608%macro HADAMARD4_2D_SSE 5-6 sumsub
609    HADAMARD  0, sumsub, %1, %2, %5 ; 1st V row 0 + 1
610    HADAMARD  0, sumsub, %3, %4, %5 ; 1st V row 2 + 3
611    SBUTTERFLY   wd, %1, %2, %5     ; %1: m0 1+0 %2: m1 1+0
612    SBUTTERFLY   wd, %3, %4, %5     ; %3: m0 3+2 %4: m1 3+2
613    HADAMARD2_2D %1, %3, %2, %4, %5, dq
614    SBUTTERFLY  qdq, %1, %2, %5
615    HADAMARD  0, %6, %1, %2, %5     ; 2nd H m1/m0 row 0+1
616    SBUTTERFLY  qdq, %3, %4, %5
617    HADAMARD  0, %6, %3, %4, %5     ; 2nd H m1/m0 row 2+3
618%endmacro
619
620%macro HADAMARD8_2D 9-10 sumsub
621    HADAMARD2_2D %1, %2, %3, %4, %9, wd
622    HADAMARD2_2D %5, %6, %7, %8, %9, wd
623    HADAMARD2_2D %1, %3, %2, %4, %9, dq
624    HADAMARD2_2D %5, %7, %6, %8, %9, dq
625    HADAMARD2_2D %1, %5, %3, %7, %9, qdq, %10
626    HADAMARD2_2D %2, %6, %4, %8, %9, qdq, %10
627%ifnidn %10, amax
628    SWAP %2, %5
629    SWAP %4, %7
630%endif
631%endmacro
632
633; doesn't include the "pmaddubsw hmul_8p" pass
634%macro HADAMARD8_2D_HMUL 10
635    HADAMARD4_V %1, %2, %3, %4, %9
636    HADAMARD4_V %5, %6, %7, %8, %9
637    SUMSUB_BADC w, %1, %5, %2, %6, %9
638    HADAMARD 2, sumsub, %1, %5, %9, %10
639    HADAMARD 2, sumsub, %2, %6, %9, %10
640    SUMSUB_BADC w, %3, %7, %4, %8, %9
641    HADAMARD 2, sumsub, %3, %7, %9, %10
642    HADAMARD 2, sumsub, %4, %8, %9, %10
643    HADAMARD 1, amax, %1, %5, %9, %10
644    HADAMARD 1, amax, %2, %6, %9, %5
645    HADAMARD 1, amax, %3, %7, %9, %5
646    HADAMARD 1, amax, %4, %8, %9, %5
647%endmacro
648
649%macro SUMSUB2_AB 4
650%if cpuflag(xop)
651    pmacs%1%1 m%4, m%3, [p%1_m2], m%2
652    pmacs%1%1 m%2, m%2, [p%1_2], m%3
653%elifnum %3
654    psub%1  m%4, m%2, m%3
655    psub%1  m%4, m%3
656    padd%1  m%2, m%2
657    padd%1  m%2, m%3
658%else
659    mova    m%4, m%2
660    padd%1  m%2, m%2
661    padd%1  m%2, %3
662    psub%1  m%4, %3
663    psub%1  m%4, %3
664%endif
665%endmacro
666
667%macro SUMSUBD2_AB 5
668%ifnum %4
669    psra%1  m%5, m%2, 1  ; %3: %3>>1
670    psra%1  m%4, m%3, 1  ; %2: %2>>1
671    padd%1  m%4, m%2     ; %3: %3>>1+%2
672    psub%1  m%5, m%3     ; %2: %2>>1-%3
673    SWAP     %2, %5
674    SWAP     %3, %4
675%else
676    mova    %5, m%2
677    mova    %4, m%3
678    psra%1  m%3, 1  ; %3: %3>>1
679    psra%1  m%2, 1  ; %2: %2>>1
680    padd%1  m%3, %5 ; %3: %3>>1+%2
681    psub%1  m%2, %4 ; %2: %2>>1-%3
682%endif
683%endmacro
684
685%macro DCT4_1D 5
686%ifnum %5
687    SUMSUB_BADC w, %4, %1, %3, %2, %5
688    SUMSUB_BA   w, %3, %4, %5
689    SUMSUB2_AB  w, %1, %2, %5
690    SWAP %1, %3, %4, %5, %2
691%else
692    SUMSUB_BADC w, %4, %1, %3, %2
693    SUMSUB_BA   w, %3, %4
694    mova     [%5], m%2
695    SUMSUB2_AB  w, %1, [%5], %2
696    SWAP %1, %3, %4, %2
697%endif
698%endmacro
699
700%macro IDCT4_1D 6-7
701%ifnum %6
702    SUMSUBD2_AB %1, %3, %5, %7, %6
703    ; %3: %3>>1-%5 %5: %3+%5>>1
704    SUMSUB_BA   %1, %4, %2, %7
705    ; %4: %2+%4 %2: %2-%4
706    SUMSUB_BADC %1, %5, %4, %3, %2, %7
707    ; %5: %2+%4 + (%3+%5>>1)
708    ; %4: %2+%4 - (%3+%5>>1)
709    ; %3: %2-%4 + (%3>>1-%5)
710    ; %2: %2-%4 - (%3>>1-%5)
711%else
712%ifidn %1, w
713    SUMSUBD2_AB %1, %3, %5, [%6], [%6+16]
714%else
715    SUMSUBD2_AB %1, %3, %5, [%6], [%6+32]
716%endif
717    SUMSUB_BA   %1, %4, %2
718    SUMSUB_BADC %1, %5, %4, %3, %2
719%endif
720    SWAP %2, %5, %4
721    ; %2: %2+%4 + (%3+%5>>1) row0
722    ; %3: %2-%4 + (%3>>1-%5) row1
723    ; %4: %2-%4 - (%3>>1-%5) row2
724    ; %5: %2+%4 - (%3+%5>>1) row3
725%endmacro
726
727
728%macro LOAD_DIFF 5-6 1
729%if HIGH_BIT_DEPTH
730%if %6 ; %5 aligned?
731    mova       %1, %4
732    psubw      %1, %5
733%else
734    movu       %1, %4
735    movu       %2, %5
736    psubw      %1, %2
737%endif
738%else ; !HIGH_BIT_DEPTH
739%ifidn %3, none
740    movh       %1, %4
741    movh       %2, %5
742    punpcklbw  %1, %2
743    punpcklbw  %2, %2
744    psubw      %1, %2
745%else
746    movh       %1, %4
747    punpcklbw  %1, %3
748    movh       %2, %5
749    punpcklbw  %2, %3
750    psubw      %1, %2
751%endif
752%endif ; HIGH_BIT_DEPTH
753%endmacro
754
755%macro LOAD_DIFF8x4 8 ; 4x dst, 1x tmp, 1x mul, 2x ptr
756%if BIT_DEPTH == 8 && cpuflag(ssse3)
757    movh       m%2, [%8+%1*FDEC_STRIDE]
758    movh       m%1, [%7+%1*FENC_STRIDE]
759    punpcklbw  m%1, m%2
760    movh       m%3, [%8+%2*FDEC_STRIDE]
761    movh       m%2, [%7+%2*FENC_STRIDE]
762    punpcklbw  m%2, m%3
763    movh       m%4, [%8+%3*FDEC_STRIDE]
764    movh       m%3, [%7+%3*FENC_STRIDE]
765    punpcklbw  m%3, m%4
766    movh       m%5, [%8+%4*FDEC_STRIDE]
767    movh       m%4, [%7+%4*FENC_STRIDE]
768    punpcklbw  m%4, m%5
769    pmaddubsw  m%1, m%6
770    pmaddubsw  m%2, m%6
771    pmaddubsw  m%3, m%6
772    pmaddubsw  m%4, m%6
773%else
774    LOAD_DIFF  m%1, m%5, m%6, [%7+%1*FENC_STRIDEB], [%8+%1*FDEC_STRIDEB]
775    LOAD_DIFF  m%2, m%5, m%6, [%7+%2*FENC_STRIDEB], [%8+%2*FDEC_STRIDEB]
776    LOAD_DIFF  m%3, m%5, m%6, [%7+%3*FENC_STRIDEB], [%8+%3*FDEC_STRIDEB]
777    LOAD_DIFF  m%4, m%5, m%6, [%7+%4*FENC_STRIDEB], [%8+%4*FDEC_STRIDEB]
778%endif
779%endmacro
780
781%macro STORE_DCT 6
782    movq   [%5+%6+ 0], m%1
783    movq   [%5+%6+ 8], m%2
784    movq   [%5+%6+16], m%3
785    movq   [%5+%6+24], m%4
786    movhps [%5+%6+32], m%1
787    movhps [%5+%6+40], m%2
788    movhps [%5+%6+48], m%3
789    movhps [%5+%6+56], m%4
790%endmacro
791
792%macro STORE_IDCT 4
793    movhps [r0-4*FDEC_STRIDE], %1
794    movh   [r0-3*FDEC_STRIDE], %1
795    movhps [r0-2*FDEC_STRIDE], %2
796    movh   [r0-1*FDEC_STRIDE], %2
797    movhps [r0+0*FDEC_STRIDE], %3
798    movh   [r0+1*FDEC_STRIDE], %3
799    movhps [r0+2*FDEC_STRIDE], %4
800    movh   [r0+3*FDEC_STRIDE], %4
801%endmacro
802
803%macro LOAD_DIFF_8x4P 7-11 r0,r2,0,1 ; 4x dest, 2x temp, 2x pointer, increment, aligned?
804    LOAD_DIFF m%1, m%5, m%7, [%8],      [%9],      %11
805    LOAD_DIFF m%2, m%6, m%7, [%8+r1],   [%9+r3],   %11
806    LOAD_DIFF m%3, m%5, m%7, [%8+2*r1], [%9+2*r3], %11
807    LOAD_DIFF m%4, m%6, m%7, [%8+r4],   [%9+r5],   %11
808%if %10
809    lea %8, [%8+4*r1]
810    lea %9, [%9+4*r3]
811%endif
812%endmacro
813
814; 2xdst, 2xtmp, 2xsrcrow
815%macro LOAD_DIFF16x2_AVX2 6
816    pmovzxbw m%1, [r1+%5*FENC_STRIDE]
817    pmovzxbw m%2, [r1+%6*FENC_STRIDE]
818    pmovzxbw m%3, [r2+(%5-4)*FDEC_STRIDE]
819    pmovzxbw m%4, [r2+(%6-4)*FDEC_STRIDE]
820    psubw    m%1, m%3
821    psubw    m%2, m%4
822%endmacro
823
824%macro DIFFx2 6-7
825    movh       %3, %5
826    punpcklbw  %3, %4
827    psraw      %1, 6
828    paddsw     %1, %3
829    movh       %3, %6
830    punpcklbw  %3, %4
831    psraw      %2, 6
832    paddsw     %2, %3
833    packuswb   %2, %1
834%endmacro
835
836; (high depth) in: %1, %2, min to clip, max to clip, mem128
837; in: %1, tmp, %3, mem64
838%macro STORE_DIFF 4-5
839%if HIGH_BIT_DEPTH
840    psrad      %1, 6
841    psrad      %2, 6
842    packssdw   %1, %2
843    paddw      %1, %5
844    CLIPW      %1, %3, %4
845    mova       %5, %1
846%else
847    movh       %2, %4
848    punpcklbw  %2, %3
849    psraw      %1, 6
850    paddsw     %1, %2
851    packuswb   %1, %1
852    movh       %4, %1
853%endif
854%endmacro
855
856%macro SHUFFLE_MASK_W 8
857    %rep 8
858        %if %1>=0x80
859            db %1, %1
860        %else
861            db %1*2
862            db %1*2+1
863        %endif
864        %rotate 1
865    %endrep
866%endmacro
867
868; instruction, accum, input, iteration (zero to swap, nonzero to add)
869%macro ACCUM 4
870%if %4
871    %1        m%2, m%3
872%else
873    SWAP       %2, %3
874%endif
875%endmacro
876