41b52df2f69970396ea5c5bc72e31e1f8851680a
[x264/x264-sandbox.git] / common / x86 / x86util.asm
1 ;*****************************************************************************
2 ;* x86util.asm: x86 utility macros
3 ;*****************************************************************************
4 ;* Copyright (C) 2008-2015 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