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