]> git.sesse.net Git - x264/blob - common/x86/x86util.asm
x86-64: 64-bit variant of AVX2 hpel_filter
[x264] / common / x86 / x86util.asm
1 ;*****************************************************************************
2 ;* x86util.asm: x86 utility macros
3 ;*****************************************************************************
4 ;* Copyright (C) 2008-2013 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     movhlps %2, %1
302     paddd   %1, %2
303 %endif
304     PSHUFLW %2, %1, q0032
305     paddd   %1, %2
306 %undef %1
307 %undef %2
308 %endmacro
309
310 %macro HADDW 2 ; reg, tmp
311 %if cpuflag(xop) && sizeof%1 == 16
312     vphaddwq  %1, %1
313     movhlps   %2, %1
314     paddd     %1, %2
315 %else
316     pmaddwd %1, [pw_1]
317     HADDD   %1, %2
318 %endif
319 %endmacro
320
321 %macro HADDUWD 2
322 %if cpuflag(xop) && sizeof%1 == 16
323     vphadduwd %1, %1
324 %else
325     psrld %2, %1, 16
326     pslld %1, 16
327     psrld %1, 16
328     paddd %1, %2
329 %endif
330 %endmacro
331
332 %macro HADDUW 2
333 %if cpuflag(xop) && sizeof%1 == 16
334     vphadduwq %1, %1
335     movhlps   %2, %1
336     paddd     %1, %2
337 %else
338     HADDUWD   %1, %2
339     HADDD     %1, %2
340 %endif
341 %endmacro
342
343 %macro PALIGNR 4-5 ; [dst,] src1, src2, imm, tmp
344 ; AVX2 version uses a precalculated extra input that
345 ; can be re-used across calls
346 %if sizeof%1==32
347                                  ; %3 = abcdefgh ijklmnop (lower address)
348                                  ; %2 = ABCDEFGH IJKLMNOP (higher address)
349 ;   vperm2i128 %5, %2, %3, q0003 ; %5 = ijklmnop ABCDEFGH
350 %if %4 < 16
351     palignr    %1, %5, %3, %4    ; %1 = bcdefghi jklmnopA
352 %else
353     palignr    %1, %2, %5, %4-16 ; %1 = pABCDEFG HIJKLMNO
354 %endif
355 %elif cpuflag(ssse3)
356     %if %0==5
357         palignr %1, %2, %3, %4
358     %else
359         palignr %1, %2, %3
360     %endif
361 %else
362     %define %%dst %1
363     %if %0==5
364         %ifnidn %1, %2
365             mova %%dst, %2
366         %endif
367         %rotate 1
368     %endif
369     %ifnidn %4, %2
370         mova %4, %2
371     %endif
372     %if mmsize==8
373         psllq  %%dst, (8-%3)*8
374         psrlq  %4, %3*8
375     %else
376         pslldq %%dst, 16-%3
377         psrldq %4, %3
378     %endif
379     por %%dst, %4
380 %endif
381 %endmacro
382
383 %macro PSHUFLW 1+
384     %if mmsize == 8
385         pshufw %1
386     %else
387         pshuflw %1
388     %endif
389 %endmacro
390
391 ; shift a mmxreg by n bytes, or a xmmreg by 2*n bytes
392 ; values shifted in are undefined
393 ; faster if dst==src
394 %define PSLLPIX PSXLPIX l, -1, ;dst, src, shift
395 %define PSRLPIX PSXLPIX r,  1, ;dst, src, shift
396 %macro PSXLPIX 5
397     %if mmsize == 8
398         %if %5&1
399             ps%1lq %3, %4, %5*8
400         %else
401             pshufw %3, %4, (q3210<<8>>(8+%2*%5))&0xff
402         %endif
403     %else
404         ps%1ldq %3, %4, %5*2
405     %endif
406 %endmacro
407
408 %macro DEINTB 5 ; mask, reg1, mask, reg2, optional src to fill masks from
409 %ifnum %5
410     pand   m%3, m%5, m%4 ; src .. y6 .. y4
411     pand   m%1, m%5, m%2 ; dst .. y6 .. y4
412 %else
413     mova   m%1, %5
414     pand   m%3, m%1, m%4 ; src .. y6 .. y4
415     pand   m%1, m%1, m%2 ; dst .. y6 .. y4
416 %endif
417     psrlw  m%2, 8        ; dst .. y7 .. y5
418     psrlw  m%4, 8        ; src .. y7 .. y5
419 %endmacro
420
421 %macro SUMSUB_BA 3-4
422 %if %0==3
423     padd%1  m%2, m%3
424     padd%1  m%3, m%3
425     psub%1  m%3, m%2
426 %elif avx_enabled
427     padd%1  m%4, m%2, m%3
428     psub%1  m%3, m%2
429     SWAP    %2, %4
430 %else
431     mova    m%4, m%2
432     padd%1  m%2, m%3
433     psub%1  m%3, m%4
434 %endif
435 %endmacro
436
437 %macro SUMSUB_BADC 5-6
438 %if %0==6
439     SUMSUB_BA %1, %2, %3, %6
440     SUMSUB_BA %1, %4, %5, %6
441 %else
442     padd%1  m%2, m%3
443     padd%1  m%4, m%5
444     padd%1  m%3, m%3
445     padd%1  m%5, m%5
446     psub%1  m%3, m%2
447     psub%1  m%5, m%4
448 %endif
449 %endmacro
450
451 %macro HADAMARD4_V 4+
452     SUMSUB_BADC w, %1, %2, %3, %4
453     SUMSUB_BADC w, %1, %3, %2, %4
454 %endmacro
455
456 %macro HADAMARD8_V 8+
457     SUMSUB_BADC w, %1, %2, %3, %4
458     SUMSUB_BADC w, %5, %6, %7, %8
459     SUMSUB_BADC w, %1, %3, %2, %4
460     SUMSUB_BADC w, %5, %7, %6, %8
461     SUMSUB_BADC w, %1, %5, %2, %6
462     SUMSUB_BADC w, %3, %7, %4, %8
463 %endmacro
464
465 %macro TRANS_SSE2 5-6
466 ; TRANSPOSE2x2
467 ; %1: transpose width (d/q) - use SBUTTERFLY qdq for dq
468 ; %2: ord/unord (for compat with sse4, unused)
469 ; %3/%4: source regs
470 ; %5/%6: tmp regs
471 %ifidn %1, d
472 %define mask [mask_10]
473 %define shift 16
474 %elifidn %1, q
475 %define mask [mask_1100]
476 %define shift 32
477 %endif
478 %if %0==6 ; less dependency if we have two tmp
479     mova   m%5, mask   ; ff00
480     mova   m%6, m%4    ; x5x4
481     psll%1 m%4, shift  ; x4..
482     pand   m%6, m%5    ; x5..
483     pandn  m%5, m%3    ; ..x0
484     psrl%1 m%3, shift  ; ..x1
485     por    m%4, m%5    ; x4x0
486     por    m%3, m%6    ; x5x1
487 %else ; more dependency, one insn less. sometimes faster, sometimes not
488     mova   m%5, m%4    ; x5x4
489     psll%1 m%4, shift  ; x4..
490     pxor   m%4, m%3    ; (x4^x1)x0
491     pand   m%4, mask   ; (x4^x1)..
492     pxor   m%3, m%4    ; x4x0
493     psrl%1 m%4, shift  ; ..(x1^x4)
494     pxor   m%5, m%4    ; x5x1
495     SWAP   %4, %3, %5
496 %endif
497 %endmacro
498
499 %macro TRANS_SSE4 5-6 ; see above
500 %ifidn %1, d
501 %ifidn %2, ord
502     psrl%1  m%5, m%3, 16
503     pblendw m%5, m%4, q2222
504     psll%1  m%4, 16
505     pblendw m%4, m%3, q1111
506     SWAP     %3, %5
507 %else
508 %if avx_enabled
509     pblendw m%5, m%3, m%4, q2222
510     SWAP     %3, %5
511 %else
512     mova    m%5, m%3
513     pblendw m%3, m%4, q2222
514 %endif
515     psll%1  m%4, 16
516     psrl%1  m%5, 16
517     por     m%4, m%5
518 %endif
519 %elifidn %1, q
520     shufps m%5, m%3, m%4, q3131
521     shufps m%3, m%3, m%4, q2020
522     SWAP    %4, %5
523 %endif
524 %endmacro
525
526 %macro TRANS_XOP 5-6
527 %ifidn %1, d
528     vpperm m%5, m%3, m%4, [transd_shuf1]
529     vpperm m%3, m%3, m%4, [transd_shuf2]
530 %elifidn %1, q
531     shufps m%5, m%3, m%4, q3131
532     shufps m%3, m%4, q2020
533 %endif
534     SWAP    %4, %5
535 %endmacro
536
537 %macro HADAMARD 5-6
538 ; %1=distance in words (0 for vertical pass, 1/2/4 for horizontal passes)
539 ; %2=sumsub/max/amax (sum and diff / maximum / maximum of absolutes)
540 ; %3/%4: regs
541 ; %5(%6): tmpregs
542 %if %1!=0 ; have to reorder stuff for horizontal op
543     %ifidn %2, sumsub
544         %define ORDER ord
545         ; sumsub needs order because a-b != b-a unless a=b
546     %else
547         %define ORDER unord
548         ; if we just max, order doesn't matter (allows pblendw+or in sse4)
549     %endif
550     %if %1==1
551         TRANS d, ORDER, %3, %4, %5, %6
552     %elif %1==2
553         %if mmsize==8
554             SBUTTERFLY dq, %3, %4, %5
555         %else
556             TRANS q, ORDER, %3, %4, %5, %6
557         %endif
558     %elif %1==4
559         SBUTTERFLY qdq, %3, %4, %5
560     %elif %1==8
561         SBUTTERFLY dqqq, %3, %4, %5
562     %endif
563 %endif
564 %ifidn %2, sumsub
565     SUMSUB_BA w, %3, %4, %5
566 %else
567     %ifidn %2, amax
568         %if %0==6
569             ABSW2 m%3, m%4, m%3, m%4, m%5, m%6
570         %else
571             ABSW m%3, m%3, m%5
572             ABSW m%4, m%4, m%5
573         %endif
574     %endif
575     pmaxsw m%3, m%4
576 %endif
577 %endmacro
578
579
580 %macro HADAMARD2_2D 6-7 sumsub
581     HADAMARD 0, sumsub, %1, %2, %5
582     HADAMARD 0, sumsub, %3, %4, %5
583     SBUTTERFLY %6, %1, %2, %5
584 %ifnum %7
585     HADAMARD 0, amax, %1, %2, %5, %7
586 %else
587     HADAMARD 0, %7, %1, %2, %5
588 %endif
589     SBUTTERFLY %6, %3, %4, %5
590 %ifnum %7
591     HADAMARD 0, amax, %3, %4, %5, %7
592 %else
593     HADAMARD 0, %7, %3, %4, %5
594 %endif
595 %endmacro
596
597 %macro HADAMARD4_2D 5-6 sumsub
598     HADAMARD2_2D %1, %2, %3, %4, %5, wd
599     HADAMARD2_2D %1, %3, %2, %4, %5, dq, %6
600     SWAP %2, %3
601 %endmacro
602
603 %macro HADAMARD4_2D_SSE 5-6 sumsub
604     HADAMARD  0, sumsub, %1, %2, %5 ; 1st V row 0 + 1
605     HADAMARD  0, sumsub, %3, %4, %5 ; 1st V row 2 + 3
606     SBUTTERFLY   wd, %1, %2, %5     ; %1: m0 1+0 %2: m1 1+0
607     SBUTTERFLY   wd, %3, %4, %5     ; %3: m0 3+2 %4: m1 3+2
608     HADAMARD2_2D %1, %3, %2, %4, %5, dq
609     SBUTTERFLY  qdq, %1, %2, %5
610     HADAMARD  0, %6, %1, %2, %5     ; 2nd H m1/m0 row 0+1
611     SBUTTERFLY  qdq, %3, %4, %5
612     HADAMARD  0, %6, %3, %4, %5     ; 2nd H m1/m0 row 2+3
613 %endmacro
614
615 %macro HADAMARD8_2D 9-10 sumsub
616     HADAMARD2_2D %1, %2, %3, %4, %9, wd
617     HADAMARD2_2D %5, %6, %7, %8, %9, wd
618     HADAMARD2_2D %1, %3, %2, %4, %9, dq
619     HADAMARD2_2D %5, %7, %6, %8, %9, dq
620     HADAMARD2_2D %1, %5, %3, %7, %9, qdq, %10
621     HADAMARD2_2D %2, %6, %4, %8, %9, qdq, %10
622 %ifnidn %10, amax
623     SWAP %2, %5
624     SWAP %4, %7
625 %endif
626 %endmacro
627
628 ; doesn't include the "pmaddubsw hmul_8p" pass
629 %macro HADAMARD8_2D_HMUL 10
630     HADAMARD4_V %1, %2, %3, %4, %9
631     HADAMARD4_V %5, %6, %7, %8, %9
632     SUMSUB_BADC w, %1, %5, %2, %6, %9
633     HADAMARD 2, sumsub, %1, %5, %9, %10
634     HADAMARD 2, sumsub, %2, %6, %9, %10
635     SUMSUB_BADC w, %3, %7, %4, %8, %9
636     HADAMARD 2, sumsub, %3, %7, %9, %10
637     HADAMARD 2, sumsub, %4, %8, %9, %10
638     HADAMARD 1, amax, %1, %5, %9, %10
639     HADAMARD 1, amax, %2, %6, %9, %5
640     HADAMARD 1, amax, %3, %7, %9, %5
641     HADAMARD 1, amax, %4, %8, %9, %5
642 %endmacro
643
644 %macro SUMSUB2_AB 4
645 %if cpuflag(xop)
646     pmacs%1%1 m%4, m%3, [p%1_m2], m%2
647     pmacs%1%1 m%2, m%2, [p%1_2], m%3
648 %elifnum %3
649     psub%1  m%4, m%2, m%3
650     psub%1  m%4, m%3
651     padd%1  m%2, m%2
652     padd%1  m%2, m%3
653 %else
654     mova    m%4, m%2
655     padd%1  m%2, m%2
656     padd%1  m%2, %3
657     psub%1  m%4, %3
658     psub%1  m%4, %3
659 %endif
660 %endmacro
661
662 %macro SUMSUBD2_AB 5
663 %ifnum %4
664     psra%1  m%5, m%2, 1  ; %3: %3>>1
665     psra%1  m%4, m%3, 1  ; %2: %2>>1
666     padd%1  m%4, m%2     ; %3: %3>>1+%2
667     psub%1  m%5, m%3     ; %2: %2>>1-%3
668     SWAP     %2, %5
669     SWAP     %3, %4
670 %else
671     mova    %5, m%2
672     mova    %4, m%3
673     psra%1  m%3, 1  ; %3: %3>>1
674     psra%1  m%2, 1  ; %2: %2>>1
675     padd%1  m%3, %5 ; %3: %3>>1+%2
676     psub%1  m%2, %4 ; %2: %2>>1-%3
677 %endif
678 %endmacro
679
680 %macro DCT4_1D 5
681 %ifnum %5
682     SUMSUB_BADC w, %4, %1, %3, %2, %5
683     SUMSUB_BA   w, %3, %4, %5
684     SUMSUB2_AB  w, %1, %2, %5
685     SWAP %1, %3, %4, %5, %2
686 %else
687     SUMSUB_BADC w, %4, %1, %3, %2
688     SUMSUB_BA   w, %3, %4
689     mova     [%5], m%2
690     SUMSUB2_AB  w, %1, [%5], %2
691     SWAP %1, %3, %4, %2
692 %endif
693 %endmacro
694
695 %macro IDCT4_1D 6-7
696 %ifnum %6
697     SUMSUBD2_AB %1, %3, %5, %7, %6
698     ; %3: %3>>1-%5 %5: %3+%5>>1
699     SUMSUB_BA   %1, %4, %2, %7
700     ; %4: %2+%4 %2: %2-%4
701     SUMSUB_BADC %1, %5, %4, %3, %2, %7
702     ; %5: %2+%4 + (%3+%5>>1)
703     ; %4: %2+%4 - (%3+%5>>1)
704     ; %3: %2-%4 + (%3>>1-%5)
705     ; %2: %2-%4 - (%3>>1-%5)
706 %else
707 %ifidn %1, w
708     SUMSUBD2_AB %1, %3, %5, [%6], [%6+16]
709 %else
710     SUMSUBD2_AB %1, %3, %5, [%6], [%6+32]
711 %endif
712     SUMSUB_BA   %1, %4, %2
713     SUMSUB_BADC %1, %5, %4, %3, %2
714 %endif
715     SWAP %2, %5, %4
716     ; %2: %2+%4 + (%3+%5>>1) row0
717     ; %3: %2-%4 + (%3>>1-%5) row1
718     ; %4: %2-%4 - (%3>>1-%5) row2
719     ; %5: %2+%4 - (%3+%5>>1) row3
720 %endmacro
721
722
723 %macro LOAD_DIFF 5-6 1
724 %if HIGH_BIT_DEPTH
725 %if %6 ; %5 aligned?
726     mova       %1, %4
727     psubw      %1, %5
728 %else
729     movu       %1, %4
730     movu       %2, %5
731     psubw      %1, %2
732 %endif
733 %else ; !HIGH_BIT_DEPTH
734 %ifidn %3, none
735     movh       %1, %4
736     movh       %2, %5
737     punpcklbw  %1, %2
738     punpcklbw  %2, %2
739     psubw      %1, %2
740 %else
741     movh       %1, %4
742     punpcklbw  %1, %3
743     movh       %2, %5
744     punpcklbw  %2, %3
745     psubw      %1, %2
746 %endif
747 %endif ; HIGH_BIT_DEPTH
748 %endmacro
749
750 %macro LOAD_DIFF8x4 8 ; 4x dst, 1x tmp, 1x mul, 2x ptr
751 %if BIT_DEPTH == 8 && cpuflag(ssse3)
752     movh       m%2, [%8+%1*FDEC_STRIDE]
753     movh       m%1, [%7+%1*FENC_STRIDE]
754     punpcklbw  m%1, m%2
755     movh       m%3, [%8+%2*FDEC_STRIDE]
756     movh       m%2, [%7+%2*FENC_STRIDE]
757     punpcklbw  m%2, m%3
758     movh       m%4, [%8+%3*FDEC_STRIDE]
759     movh       m%3, [%7+%3*FENC_STRIDE]
760     punpcklbw  m%3, m%4
761     movh       m%5, [%8+%4*FDEC_STRIDE]
762     movh       m%4, [%7+%4*FENC_STRIDE]
763     punpcklbw  m%4, m%5
764     pmaddubsw  m%1, m%6
765     pmaddubsw  m%2, m%6
766     pmaddubsw  m%3, m%6
767     pmaddubsw  m%4, m%6
768 %else
769     LOAD_DIFF  m%1, m%5, m%6, [%7+%1*FENC_STRIDEB], [%8+%1*FDEC_STRIDEB]
770     LOAD_DIFF  m%2, m%5, m%6, [%7+%2*FENC_STRIDEB], [%8+%2*FDEC_STRIDEB]
771     LOAD_DIFF  m%3, m%5, m%6, [%7+%3*FENC_STRIDEB], [%8+%3*FDEC_STRIDEB]
772     LOAD_DIFF  m%4, m%5, m%6, [%7+%4*FENC_STRIDEB], [%8+%4*FDEC_STRIDEB]
773 %endif
774 %endmacro
775
776 %macro STORE_DCT 6
777     movq   [%5+%6+ 0], m%1
778     movq   [%5+%6+ 8], m%2
779     movq   [%5+%6+16], m%3
780     movq   [%5+%6+24], m%4
781     movhps [%5+%6+32], m%1
782     movhps [%5+%6+40], m%2
783     movhps [%5+%6+48], m%3
784     movhps [%5+%6+56], m%4
785 %endmacro
786
787 %macro STORE_IDCT 4
788     movhps [r0-4*FDEC_STRIDE], %1
789     movh   [r0-3*FDEC_STRIDE], %1
790     movhps [r0-2*FDEC_STRIDE], %2
791     movh   [r0-1*FDEC_STRIDE], %2
792     movhps [r0+0*FDEC_STRIDE], %3
793     movh   [r0+1*FDEC_STRIDE], %3
794     movhps [r0+2*FDEC_STRIDE], %4
795     movh   [r0+3*FDEC_STRIDE], %4
796 %endmacro
797
798 %macro LOAD_DIFF_8x4P 7-11 r0,r2,0,1 ; 4x dest, 2x temp, 2x pointer, increment, aligned?
799     LOAD_DIFF m%1, m%5, m%7, [%8],      [%9],      %11
800     LOAD_DIFF m%2, m%6, m%7, [%8+r1],   [%9+r3],   %11
801     LOAD_DIFF m%3, m%5, m%7, [%8+2*r1], [%9+2*r3], %11
802     LOAD_DIFF m%4, m%6, m%7, [%8+r4],   [%9+r5],   %11
803 %if %10
804     lea %8, [%8+4*r1]
805     lea %9, [%9+4*r3]
806 %endif
807 %endmacro
808
809 ; 2xdst, 2xtmp, 2xsrcrow
810 %macro LOAD_DIFF16x2_AVX2 6
811     pmovzxbw m%1, [r1+%5*FENC_STRIDE]
812     pmovzxbw m%2, [r1+%6*FENC_STRIDE]
813     pmovzxbw m%3, [r2+(%5-4)*FDEC_STRIDE]
814     pmovzxbw m%4, [r2+(%6-4)*FDEC_STRIDE]
815     psubw    m%1, m%3
816     psubw    m%2, m%4
817 %endmacro
818
819 %macro DIFFx2 6-7
820     movh       %3, %5
821     punpcklbw  %3, %4
822     psraw      %1, 6
823     paddsw     %1, %3
824     movh       %3, %6
825     punpcklbw  %3, %4
826     psraw      %2, 6
827     paddsw     %2, %3
828     packuswb   %2, %1
829 %endmacro
830
831 ; (high depth) in: %1, %2, min to clip, max to clip, mem128
832 ; in: %1, tmp, %3, mem64
833 %macro STORE_DIFF 4-5
834 %if HIGH_BIT_DEPTH
835     psrad      %1, 6
836     psrad      %2, 6
837     packssdw   %1, %2
838     paddw      %1, %5
839     CLIPW      %1, %3, %4
840     mova       %5, %1
841 %else
842     movh       %2, %4
843     punpcklbw  %2, %3
844     psraw      %1, 6
845     paddsw     %1, %2
846     packuswb   %1, %1
847     movh       %4, %1
848 %endif
849 %endmacro
850
851 %macro SHUFFLE_MASK_W 8
852     %rep 8
853         %if %1>=0x80
854             db %1, %1
855         %else
856             db %1*2
857             db %1*2+1
858         %endif
859         %rotate 1
860     %endrep
861 %endmacro
862
863 ; instruction, accum, input, iteration (zero to swap, nonzero to add)
864 %macro ACCUM 4
865 %if %4
866     %1        m%2, m%3
867 %else
868     SWAP       %2, %3
869 %endif
870 %endmacro