]> git.sesse.net Git - ffmpeg/blob - libavutil/x86/x86util.asm
Merge commit 'e9ef6171396dc4106526aaa86b620c61ca3d1017'
[ffmpeg] / libavutil / x86 / x86util.asm
1 ;*****************************************************************************
2 ;* x86util.asm
3 ;*****************************************************************************
4 ;* Copyright (C) 2008-2010 x264 project
5 ;*
6 ;* Authors: Loren Merritt <lorenm@u.washington.edu>
7 ;*          Holger Lubitz <holger@lubitz.org>
8 ;*
9 ;* This file is part of FFmpeg.
10 ;*
11 ;* FFmpeg is free software; you can redistribute it and/or
12 ;* modify it under the terms of the GNU Lesser General Public
13 ;* License as published by the Free Software Foundation; either
14 ;* version 2.1 of the License, or (at your option) any later version.
15 ;*
16 ;* FFmpeg is distributed in the hope that it will be useful,
17 ;* but WITHOUT ANY WARRANTY; without even the implied warranty of
18 ;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19 ;* Lesser General Public License for more details.
20 ;*
21 ;* You should have received a copy of the GNU Lesser General Public
22 ;* License along with FFmpeg; if not, write to the Free Software
23 ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24 ;******************************************************************************
25
26 %define private_prefix ff
27 %define public_prefix  avpriv
28 %define cpuflags_mmxext cpuflags_mmx2
29
30 %include "libavutil/x86/x86inc.asm"
31
32 ; expands to [base],...,[base+7*stride]
33 %define PASS8ROWS(base, base3, stride, stride3) \
34     [base],           [base  + stride],   [base  + 2*stride], [base3], \
35     [base3 + stride], [base3 + 2*stride], [base3 + stride3],  [base3 + stride*4]
36
37 ; Interleave low src0 with low src1 and store in src0,
38 ; interleave high src0 with high src1 and store in src1.
39 ; %1 - types
40 ; %2 - index of the register with src0
41 ; %3 - index of the register with src1
42 ; %4 - index of the register for intermediate results
43 ; example for %1 - wd: input: src0: x0 x1 x2 x3 z0 z1 z2 z3
44 ;                             src1: y0 y1 y2 y3 q0 q1 q2 q3
45 ;                     output: src0: x0 y0 x1 y1 x2 y2 x3 y3
46 ;                             src1: z0 q0 z1 q1 z2 q2 z3 q3
47 %macro SBUTTERFLY 4
48 %ifidn %1, dqqq
49     vperm2i128  m%4, m%2, m%3, q0301
50     vinserti128 m%2, m%2, xm%3, 1
51 %elif avx_enabled == 0
52     mova      m%4, m%2
53     punpckl%1 m%2, m%3
54     punpckh%1 m%4, m%3
55 %else
56     punpckh%1 m%4, m%2, m%3
57     punpckl%1 m%2, m%3
58 %endif
59     SWAP %3, %4
60 %endmacro
61
62 %macro SBUTTERFLY2 4
63     punpckl%1 m%4, m%2, m%3
64     punpckh%1 m%2, m%2, m%3
65     SWAP %2, %4, %3
66 %endmacro
67
68 %macro SBUTTERFLYPS 3
69     unpcklps m%3, m%1, m%2
70     unpckhps m%1, m%1, m%2
71     SWAP %1, %3, %2
72 %endmacro
73
74 %macro TRANSPOSE4x4B 5
75     SBUTTERFLY bw, %1, %2, %5
76     SBUTTERFLY bw, %3, %4, %5
77     SBUTTERFLY wd, %1, %3, %5
78     SBUTTERFLY wd, %2, %4, %5
79     SWAP %2, %3
80 %endmacro
81
82 %macro TRANSPOSE4x4W 5
83     SBUTTERFLY wd, %1, %2, %5
84     SBUTTERFLY wd, %3, %4, %5
85     SBUTTERFLY dq, %1, %3, %5
86     SBUTTERFLY dq, %2, %4, %5
87     SWAP %2, %3
88 %endmacro
89
90 %macro TRANSPOSE2x4x4B 5
91     SBUTTERFLY bw,  %1, %2, %5
92     SBUTTERFLY bw,  %3, %4, %5
93     SBUTTERFLY wd,  %1, %3, %5
94     SBUTTERFLY wd,  %2, %4, %5
95     SBUTTERFLY dq,  %1, %2, %5
96     SBUTTERFLY dq,  %3, %4, %5
97 %endmacro
98
99 %macro TRANSPOSE2x4x4W 5
100     SBUTTERFLY wd,  %1, %2, %5
101     SBUTTERFLY wd,  %3, %4, %5
102     SBUTTERFLY dq,  %1, %3, %5
103     SBUTTERFLY dq,  %2, %4, %5
104     SBUTTERFLY qdq, %1, %2, %5
105     SBUTTERFLY qdq, %3, %4, %5
106 %endmacro
107
108 %macro TRANSPOSE4x4D 5
109     SBUTTERFLY dq,  %1, %2, %5
110     SBUTTERFLY dq,  %3, %4, %5
111     SBUTTERFLY qdq, %1, %3, %5
112     SBUTTERFLY qdq, %2, %4, %5
113     SWAP %2, %3
114 %endmacro
115
116 ; identical behavior to TRANSPOSE4x4D, but using SSE1 float ops
117 %macro TRANSPOSE4x4PS 5
118     SBUTTERFLYPS %1, %2, %5
119     SBUTTERFLYPS %3, %4, %5
120     movlhps m%5, m%1, m%3
121     movhlps m%3, m%1
122     SWAP %5, %1
123     movlhps m%5, m%2, m%4
124     movhlps m%4, m%2
125     SWAP %5, %2, %3
126 %endmacro
127
128 %macro TRANSPOSE8x4D 9-11
129 %if ARCH_X86_64
130     SBUTTERFLY dq,  %1, %2, %9
131     SBUTTERFLY dq,  %3, %4, %9
132     SBUTTERFLY dq,  %5, %6, %9
133     SBUTTERFLY dq,  %7, %8, %9
134     SBUTTERFLY qdq, %1, %3, %9
135     SBUTTERFLY qdq, %2, %4, %9
136     SBUTTERFLY qdq, %5, %7, %9
137     SBUTTERFLY qdq, %6, %8, %9
138     SWAP %2, %5
139     SWAP %4, %7
140 %else
141 ; in:  m0..m7
142 ; out: m0..m7, unless %11 in which case m2 is in %9
143 ; spills into %9 and %10
144     movdqa %9, m%7
145     SBUTTERFLY dq,  %1, %2, %7
146     movdqa %10, m%2
147     movdqa m%7, %9
148     SBUTTERFLY dq,  %3, %4, %2
149     SBUTTERFLY dq,  %5, %6, %2
150     SBUTTERFLY dq,  %7, %8, %2
151     SBUTTERFLY qdq, %1, %3, %2
152     movdqa %9, m%3
153     movdqa m%2, %10
154     SBUTTERFLY qdq, %2, %4, %3
155     SBUTTERFLY qdq, %5, %7, %3
156     SBUTTERFLY qdq, %6, %8, %3
157     SWAP %2, %5
158     SWAP %4, %7
159 %if %0<11
160     movdqa m%3, %9
161 %endif
162 %endif
163 %endmacro
164
165 %macro TRANSPOSE8x8W 9-11
166 %if ARCH_X86_64
167     SBUTTERFLY wd,  %1, %2, %9
168     SBUTTERFLY wd,  %3, %4, %9
169     SBUTTERFLY wd,  %5, %6, %9
170     SBUTTERFLY wd,  %7, %8, %9
171     SBUTTERFLY dq,  %1, %3, %9
172     SBUTTERFLY dq,  %2, %4, %9
173     SBUTTERFLY dq,  %5, %7, %9
174     SBUTTERFLY dq,  %6, %8, %9
175     SBUTTERFLY qdq, %1, %5, %9
176     SBUTTERFLY qdq, %2, %6, %9
177     SBUTTERFLY qdq, %3, %7, %9
178     SBUTTERFLY qdq, %4, %8, %9
179     SWAP %2, %5
180     SWAP %4, %7
181 %else
182 ; in:  m0..m7, unless %11 in which case m6 is in %9
183 ; out: m0..m7, unless %11 in which case m4 is in %10
184 ; spills into %9 and %10
185 %if %0<11
186     movdqa %9, m%7
187 %endif
188     SBUTTERFLY wd,  %1, %2, %7
189     movdqa %10, m%2
190     movdqa m%7, %9
191     SBUTTERFLY wd,  %3, %4, %2
192     SBUTTERFLY wd,  %5, %6, %2
193     SBUTTERFLY wd,  %7, %8, %2
194     SBUTTERFLY dq,  %1, %3, %2
195     movdqa %9, m%3
196     movdqa m%2, %10
197     SBUTTERFLY dq,  %2, %4, %3
198     SBUTTERFLY dq,  %5, %7, %3
199     SBUTTERFLY dq,  %6, %8, %3
200     SBUTTERFLY qdq, %1, %5, %3
201     SBUTTERFLY qdq, %2, %6, %3
202     movdqa %10, m%2
203     movdqa m%3, %9
204     SBUTTERFLY qdq, %3, %7, %2
205     SBUTTERFLY qdq, %4, %8, %2
206     SWAP %2, %5
207     SWAP %4, %7
208 %if %0<11
209     movdqa m%5, %10
210 %endif
211 %endif
212 %endmacro
213
214 %macro TRANSPOSE16x16W 18-19
215 ; in:  m0..m15, unless %19 in which case m6 is in %17
216 ; out: m0..m15, unless %19 in which case m4 is in %18
217 ; spills into %17 and %18
218 %if %0 < 19
219     mova       %17, m%7
220 %endif
221
222     SBUTTERFLY dqqq, %1,  %9, %7
223     SBUTTERFLY dqqq, %2, %10, %7
224     SBUTTERFLY dqqq, %3, %11, %7
225     SBUTTERFLY dqqq, %4, %12, %7
226     SBUTTERFLY dqqq, %5, %13, %7
227     SBUTTERFLY dqqq, %6, %14, %7
228     mova       %18, m%14
229     mova       m%7, %17
230     SBUTTERFLY dqqq, %7, %15, %14
231     SBUTTERFLY dqqq, %8, %16, %14
232
233     SBUTTERFLY  wd,  %1,  %2, %14
234     SBUTTERFLY  wd,  %3,  %4, %14
235     SBUTTERFLY  wd,  %5,  %6, %14
236     SBUTTERFLY  wd,  %7,  %8, %14
237     SBUTTERFLY  wd,  %9, %10, %14
238     SBUTTERFLY  wd, %11, %12, %14
239     mova       %17, m%12
240     mova      m%14, %18
241     SBUTTERFLY  wd, %13, %14, %12
242     SBUTTERFLY  wd, %15, %16, %12
243
244     SBUTTERFLY  dq,  %1,  %3, %12
245     SBUTTERFLY  dq,  %2,  %4, %12
246     SBUTTERFLY  dq,  %5,  %7, %12
247     SBUTTERFLY  dq,  %6,  %8, %12
248     SBUTTERFLY  dq,  %9, %11, %12
249     mova       %18, m%11
250     mova      m%12, %17
251     SBUTTERFLY  dq, %10, %12, %11
252     SBUTTERFLY  dq, %13, %15, %11
253     SBUTTERFLY  dq, %14, %16, %11
254
255     SBUTTERFLY qdq,  %1,  %5, %11
256     SBUTTERFLY qdq,  %2,  %6, %11
257     SBUTTERFLY qdq,  %3,  %7, %11
258     SBUTTERFLY qdq,  %4,  %8, %11
259
260     SWAP        %2, %5
261     SWAP        %4, %7
262
263     SBUTTERFLY qdq,  %9, %13, %11
264     SBUTTERFLY qdq, %10, %14, %11
265     mova      m%11, %18
266     mova       %18, m%5
267     SBUTTERFLY qdq, %11, %15, %5
268     SBUTTERFLY qdq, %12, %16, %5
269
270 %if %0 < 19
271     mova       m%5, %18
272 %endif
273
274     SWAP       %10, %13
275     SWAP       %12, %15
276 %endmacro
277
278 %macro TRANSPOSE_8X8B 8
279     %if mmsize == 8
280         %error "This macro does not support mmsize == 8"
281     %endif
282     punpcklbw m%1, m%2
283     punpcklbw m%3, m%4
284     punpcklbw m%5, m%6
285     punpcklbw m%7, m%8
286     TRANSPOSE4x4W %1, %3, %5, %7, %2
287     MOVHL m%2, m%1
288     MOVHL m%4, m%3
289     MOVHL m%6, m%5
290     MOVHL m%8, m%7
291 %endmacro
292
293 ; PABSW macro assumes %1 != %2, while ABS1/2 macros work in-place
294 %macro PABSW 2
295 %if cpuflag(ssse3)
296     pabsw      %1, %2
297 %elif cpuflag(mmxext)
298     pxor    %1, %1
299     psubw   %1, %2
300     pmaxsw  %1, %2
301 %else
302     pxor       %1, %1
303     pcmpgtw    %1, %2
304     pxor       %2, %1
305     psubw      %2, %1
306     SWAP       %1, %2
307 %endif
308 %endmacro
309
310 %macro PSIGNW 2
311 %if cpuflag(ssse3)
312     psignw     %1, %2
313 %else
314     pxor       %1, %2
315     psubw      %1, %2
316 %endif
317 %endmacro
318
319 %macro ABS1 2
320 %if cpuflag(ssse3)
321     pabsw   %1, %1
322 %elif cpuflag(mmxext) ; a, tmp
323     pxor    %2, %2
324     psubw   %2, %1
325     pmaxsw  %1, %2
326 %else ; a, tmp
327     pxor       %2, %2
328     pcmpgtw    %2, %1
329     pxor       %1, %2
330     psubw      %1, %2
331 %endif
332 %endmacro
333
334 %macro ABS2 4
335 %if cpuflag(ssse3)
336     pabsw   %1, %1
337     pabsw   %2, %2
338 %elif cpuflag(mmxext) ; a, b, tmp0, tmp1
339     pxor    %3, %3
340     pxor    %4, %4
341     psubw   %3, %1
342     psubw   %4, %2
343     pmaxsw  %1, %3
344     pmaxsw  %2, %4
345 %else ; a, b, tmp0, tmp1
346     pxor       %3, %3
347     pxor       %4, %4
348     pcmpgtw    %3, %1
349     pcmpgtw    %4, %2
350     pxor       %1, %3
351     pxor       %2, %4
352     psubw      %1, %3
353     psubw      %2, %4
354 %endif
355 %endmacro
356
357 %macro ABSB 2 ; source mmreg, temp mmreg (unused for ssse3)
358 %if cpuflag(ssse3)
359     pabsb   %1, %1
360 %else
361     pxor    %2, %2
362     psubb   %2, %1
363     pminub  %1, %2
364 %endif
365 %endmacro
366
367 %macro ABSB2 4 ; src1, src2, tmp1, tmp2 (tmp1/2 unused for SSSE3)
368 %if cpuflag(ssse3)
369     pabsb   %1, %1
370     pabsb   %2, %2
371 %else
372     pxor    %3, %3
373     pxor    %4, %4
374     psubb   %3, %1
375     psubb   %4, %2
376     pminub  %1, %3
377     pminub  %2, %4
378 %endif
379 %endmacro
380
381 %macro ABSD2_MMX 4
382     pxor    %3, %3
383     pxor    %4, %4
384     pcmpgtd %3, %1
385     pcmpgtd %4, %2
386     pxor    %1, %3
387     pxor    %2, %4
388     psubd   %1, %3
389     psubd   %2, %4
390 %endmacro
391
392 %macro ABS4 6
393     ABS2 %1, %2, %5, %6
394     ABS2 %3, %4, %5, %6
395 %endmacro
396
397 %macro SPLATB_LOAD 3
398 %if cpuflag(ssse3)
399     movd      %1, [%2-3]
400     pshufb    %1, %3
401 %else
402     movd      %1, [%2-3] ;to avoid crossing a cacheline
403     punpcklbw %1, %1
404     SPLATW    %1, %1, 3
405 %endif
406 %endmacro
407
408 %macro SPLATB_REG 3
409 %if cpuflag(ssse3)
410     movd      %1, %2d
411     pshufb    %1, %3
412 %else
413     movd      %1, %2d
414     punpcklbw %1, %1
415     SPLATW    %1, %1, 0
416 %endif
417 %endmacro
418
419 %macro HADDD 2 ; sum junk
420 %if sizeof%1 == 32
421 %define %2 xmm%2
422     vextracti128 %2, %1, 1
423 %define %1 xmm%1
424     paddd   %1, %2
425 %endif
426 %if mmsize >= 16
427 %if cpuflag(xop) && sizeof%1 == 16
428     vphadddq %1, %1
429 %endif
430     movhlps %2, %1
431     paddd   %1, %2
432 %endif
433 %if notcpuflag(xop) || sizeof%1 != 16
434 %if cpuflag(mmxext)
435     PSHUFLW %2, %1, q0032
436 %else ; mmx
437     mova    %2, %1
438     psrlq   %2, 32
439 %endif
440     paddd   %1, %2
441 %endif
442 %undef %1
443 %undef %2
444 %endmacro
445
446 %macro HADDW 2 ; reg, tmp
447 %if cpuflag(xop) && sizeof%1 == 16
448     vphaddwq  %1, %1
449     movhlps   %2, %1
450     paddd     %1, %2
451 %else
452     pmaddwd %1, [pw_1]
453     HADDD   %1, %2
454 %endif
455 %endmacro
456
457 %macro HADDPS 3 ; dst, src, tmp
458 %if cpuflag(sse3)
459     haddps  %1, %1, %2
460 %else
461     movaps  %3, %1
462     shufps  %1, %2, q2020
463     shufps  %3, %2, q3131
464     addps   %1, %3
465 %endif
466 %endmacro
467
468 %macro PALIGNR 4-5
469 %if cpuflag(ssse3)
470 %if %0==5
471     palignr %1, %2, %3, %4
472 %else
473     palignr %1, %2, %3
474 %endif
475 %elif cpuflag(mmx) ; [dst,] src1, src2, imm, tmp
476     %define %%dst %1
477 %if %0==5
478 %ifnidn %1, %2
479     mova    %%dst, %2
480 %endif
481     %rotate 1
482 %endif
483 %ifnidn %4, %2
484     mova    %4, %2
485 %endif
486 %if mmsize==8
487     psllq   %%dst, (8-%3)*8
488     psrlq   %4, %3*8
489 %else
490     pslldq  %%dst, 16-%3
491     psrldq  %4, %3
492 %endif
493     por     %%dst, %4
494 %endif
495 %endmacro
496
497 %macro PAVGB 2-4
498 %if cpuflag(mmxext)
499     pavgb   %1, %2
500 %elif cpuflag(3dnow)
501     pavgusb %1, %2
502 %elif cpuflag(mmx)
503     movu   %3, %2
504     por    %3, %1
505     pxor   %1, %2
506     pand   %1, %4
507     psrlq  %1, 1
508     psubb  %3, %1
509     SWAP   %1, %3
510 %endif
511 %endmacro
512
513 %macro PSHUFLW 1+
514     %if mmsize == 8
515         pshufw %1
516     %else
517         pshuflw %1
518     %endif
519 %endmacro
520
521 %macro PSWAPD 2
522 %if cpuflag(mmxext)
523     pshufw    %1, %2, q1032
524 %elif cpuflag(3dnowext)
525     pswapd    %1, %2
526 %elif cpuflag(3dnow)
527     movq      %1, %2
528     psrlq     %1, 32
529     punpckldq %1, %2
530 %endif
531 %endmacro
532
533 %macro DEINTB 5 ; mask, reg1, mask, reg2, optional src to fill masks from
534 %ifnum %5
535     pand   m%3, m%5, m%4 ; src .. y6 .. y4
536     pand   m%1, m%5, m%2 ; dst .. y6 .. y4
537 %else
538     mova   m%1, %5
539     pand   m%3, m%1, m%4 ; src .. y6 .. y4
540     pand   m%1, m%1, m%2 ; dst .. y6 .. y4
541 %endif
542     psrlw  m%2, 8        ; dst .. y7 .. y5
543     psrlw  m%4, 8        ; src .. y7 .. y5
544 %endmacro
545
546 %macro SUMSUB_BA 3-4
547 %if %0==3
548     padd%1  m%2, m%3
549     padd%1  m%3, m%3
550     psub%1  m%3, m%2
551 %else
552 %if avx_enabled == 0
553     mova    m%4, m%2
554     padd%1  m%2, m%3
555     psub%1  m%3, m%4
556 %else
557     padd%1  m%4, m%2, m%3
558     psub%1  m%3, m%2
559     SWAP    %2, %4
560 %endif
561 %endif
562 %endmacro
563
564 %macro SUMSUB_BADC 5-6
565 %if %0==6
566     SUMSUB_BA %1, %2, %3, %6
567     SUMSUB_BA %1, %4, %5, %6
568 %else
569     padd%1  m%2, m%3
570     padd%1  m%4, m%5
571     padd%1  m%3, m%3
572     padd%1  m%5, m%5
573     psub%1  m%3, m%2
574     psub%1  m%5, m%4
575 %endif
576 %endmacro
577
578 %macro SUMSUB2_AB 4
579 %ifnum %3
580     psub%1  m%4, m%2, m%3
581     psub%1  m%4, m%3
582     padd%1  m%2, m%2
583     padd%1  m%2, m%3
584 %else
585     mova    m%4, m%2
586     padd%1  m%2, m%2
587     padd%1  m%2, %3
588     psub%1  m%4, %3
589     psub%1  m%4, %3
590 %endif
591 %endmacro
592
593 %macro SUMSUB2_BA 4
594 %if avx_enabled == 0
595     mova    m%4, m%2
596     padd%1  m%2, m%3
597     padd%1  m%2, m%3
598     psub%1  m%3, m%4
599     psub%1  m%3, m%4
600 %else
601     padd%1  m%4, m%2, m%3
602     padd%1  m%4, m%3
603     psub%1  m%3, m%2
604     psub%1  m%3, m%2
605     SWAP     %2,  %4
606 %endif
607 %endmacro
608
609 %macro SUMSUBD2_AB 5
610 %ifnum %4
611     psra%1  m%5, m%2, 1  ; %3: %3>>1
612     psra%1  m%4, m%3, 1  ; %2: %2>>1
613     padd%1  m%4, m%2     ; %3: %3>>1+%2
614     psub%1  m%5, m%3     ; %2: %2>>1-%3
615     SWAP     %2, %5
616     SWAP     %3, %4
617 %else
618     mova    %5, m%2
619     mova    %4, m%3
620     psra%1  m%3, 1  ; %3: %3>>1
621     psra%1  m%2, 1  ; %2: %2>>1
622     padd%1  m%3, %5 ; %3: %3>>1+%2
623     psub%1  m%2, %4 ; %2: %2>>1-%3
624 %endif
625 %endmacro
626
627 %macro DCT4_1D 5
628 %ifnum %5
629     SUMSUB_BADC w, %4, %1, %3, %2, %5
630     SUMSUB_BA   w, %3, %4, %5
631     SUMSUB2_AB  w, %1, %2, %5
632     SWAP %1, %3, %4, %5, %2
633 %else
634     SUMSUB_BADC w, %4, %1, %3, %2
635     SUMSUB_BA   w, %3, %4
636     mova     [%5], m%2
637     SUMSUB2_AB  w, %1, [%5], %2
638     SWAP %1, %3, %4, %2
639 %endif
640 %endmacro
641
642 %macro IDCT4_1D 6-7
643 %ifnum %6
644     SUMSUBD2_AB %1, %3, %5, %7, %6
645     ; %3: %3>>1-%5 %5: %3+%5>>1
646     SUMSUB_BA   %1, %4, %2, %7
647     ; %4: %2+%4 %2: %2-%4
648     SUMSUB_BADC %1, %5, %4, %3, %2, %7
649     ; %5: %2+%4 + (%3+%5>>1)
650     ; %4: %2+%4 - (%3+%5>>1)
651     ; %3: %2-%4 + (%3>>1-%5)
652     ; %2: %2-%4 - (%3>>1-%5)
653 %else
654 %ifidn %1, w
655     SUMSUBD2_AB %1, %3, %5, [%6], [%6+16]
656 %else
657     SUMSUBD2_AB %1, %3, %5, [%6], [%6+32]
658 %endif
659     SUMSUB_BA   %1, %4, %2
660     SUMSUB_BADC %1, %5, %4, %3, %2
661 %endif
662     SWAP %2, %5, %4
663     ; %2: %2+%4 + (%3+%5>>1) row0
664     ; %3: %2-%4 + (%3>>1-%5) row1
665     ; %4: %2-%4 - (%3>>1-%5) row2
666     ; %5: %2+%4 - (%3+%5>>1) row3
667 %endmacro
668
669
670 %macro LOAD_DIFF 5
671 %ifidn %3, none
672     movh       %1, %4
673     movh       %2, %5
674     punpcklbw  %1, %2
675     punpcklbw  %2, %2
676     psubw      %1, %2
677 %else
678     movh       %1, %4
679     punpcklbw  %1, %3
680     movh       %2, %5
681     punpcklbw  %2, %3
682     psubw      %1, %2
683 %endif
684 %endmacro
685
686 %macro STORE_DCT 6
687     movq   [%5+%6+ 0], m%1
688     movq   [%5+%6+ 8], m%2
689     movq   [%5+%6+16], m%3
690     movq   [%5+%6+24], m%4
691     movhps [%5+%6+32], m%1
692     movhps [%5+%6+40], m%2
693     movhps [%5+%6+48], m%3
694     movhps [%5+%6+56], m%4
695 %endmacro
696
697 %macro LOAD_DIFF_8x4P 7-10 r0,r2,0 ; 4x dest, 2x temp, 2x pointer, increment?
698     LOAD_DIFF m%1, m%5, m%7, [%8],      [%9]
699     LOAD_DIFF m%2, m%6, m%7, [%8+r1],   [%9+r3]
700     LOAD_DIFF m%3, m%5, m%7, [%8+2*r1], [%9+2*r3]
701     LOAD_DIFF m%4, m%6, m%7, [%8+r4],   [%9+r5]
702 %if %10
703     lea %8, [%8+4*r1]
704     lea %9, [%9+4*r3]
705 %endif
706 %endmacro
707
708 %macro DIFFx2 6-7
709     movh       %3, %5
710     punpcklbw  %3, %4
711     psraw      %1, 6
712     paddsw     %1, %3
713     movh       %3, %6
714     punpcklbw  %3, %4
715     psraw      %2, 6
716     paddsw     %2, %3
717     packuswb   %2, %1
718 %endmacro
719
720 %macro STORE_DIFF 4
721     movh       %2, %4
722     punpcklbw  %2, %3
723     psraw      %1, 6
724     paddsw     %1, %2
725     packuswb   %1, %1
726     movh       %4, %1
727 %endmacro
728
729 %macro STORE_DIFFx2 8 ; add1, add2, reg1, reg2, zero, shift, source, stride
730     movh       %3, [%7]
731     movh       %4, [%7+%8]
732     psraw      %1, %6
733     psraw      %2, %6
734     punpcklbw  %3, %5
735     punpcklbw  %4, %5
736     paddw      %3, %1
737     paddw      %4, %2
738     packuswb   %3, %5
739     packuswb   %4, %5
740     movh     [%7], %3
741     movh  [%7+%8], %4
742 %endmacro
743
744 %macro PMINUB 3 ; dst, src, ignored
745 %if cpuflag(mmxext)
746     pminub   %1, %2
747 %else ; dst, src, tmp
748     mova     %3, %1
749     psubusb  %3, %2
750     psubb    %1, %3
751 %endif
752 %endmacro
753
754 %macro SPLATW 2-3 0
755 %if cpuflag(avx2) && %3 == 0
756     vpbroadcastw %1, %2
757 %elif mmsize == 16
758     pshuflw    %1, %2, (%3)*0x55
759     punpcklqdq %1, %1
760 %elif cpuflag(mmxext)
761     pshufw     %1, %2, (%3)*0x55
762 %else
763     %ifnidn %1, %2
764         mova       %1, %2
765     %endif
766     %if %3 & 2
767         punpckhwd  %1, %1
768     %else
769         punpcklwd  %1, %1
770     %endif
771     %if %3 & 1
772         punpckhwd  %1, %1
773     %else
774         punpcklwd  %1, %1
775     %endif
776 %endif
777 %endmacro
778
779 %macro SPLATD 1
780 %if mmsize == 8
781     punpckldq  %1, %1
782 %elif cpuflag(sse2)
783     pshufd  %1, %1, 0
784 %elif cpuflag(sse)
785     shufps  %1, %1, 0
786 %endif
787 %endmacro
788
789 %macro CLIPUB 3 ;(dst, min, max)
790     pmaxub %1, %2
791     pminub %1, %3
792 %endmacro
793
794 %macro CLIPW 3 ;(dst, min, max)
795     pmaxsw %1, %2
796     pminsw %1, %3
797 %endmacro
798
799 %macro PMINSD_MMX 3 ; dst, src, tmp
800     mova      %3, %2
801     pcmpgtd   %3, %1
802     pxor      %1, %2
803     pand      %1, %3
804     pxor      %1, %2
805 %endmacro
806
807 %macro PMAXSD_MMX 3 ; dst, src, tmp
808     mova      %3, %1
809     pcmpgtd   %3, %2
810     pand      %1, %3
811     pandn     %3, %2
812     por       %1, %3
813 %endmacro
814
815 %macro CLIPD_MMX 3-4 ; src/dst, min, max, tmp
816     PMINSD_MMX %1, %3, %4
817     PMAXSD_MMX %1, %2, %4
818 %endmacro
819
820 %macro CLIPD_SSE2 3-4 ; src/dst, min (float), max (float), unused
821     cvtdq2ps  %1, %1
822     minps     %1, %3
823     maxps     %1, %2
824     cvtps2dq  %1, %1
825 %endmacro
826
827 %macro CLIPD_SSE41 3-4 ;  src/dst, min, max, unused
828     pminsd  %1, %3
829     pmaxsd  %1, %2
830 %endmacro
831
832 %macro VBROADCASTSS 2 ; dst xmm/ymm, src m32
833 %if cpuflag(avx)
834     vbroadcastss %1, %2
835 %else ; sse
836     movss        %1, %2
837     shufps       %1, %1, 0
838 %endif
839 %endmacro
840
841 %macro VBROADCASTSD 2 ; dst xmm/ymm, src m64
842 %if cpuflag(avx) && mmsize == 32
843     vbroadcastsd %1, %2
844 %elif cpuflag(sse3)
845     movddup      %1, %2
846 %else ; sse2
847     movsd        %1, %2
848     movlhps      %1, %1
849 %endif
850 %endmacro
851
852 %macro SHUFFLE_MASK_W 8
853     %rep 8
854         %if %1>=0x80
855             db %1, %1
856         %else
857             db %1*2
858             db %1*2+1
859         %endif
860         %rotate 1
861     %endrep
862 %endmacro
863
864 %macro PMOVSXWD 2; dst, src
865 %if cpuflag(sse4)
866     pmovsxwd     %1, %2
867 %else
868     %ifnidn %1, %2
869     mova         %1, %2
870     %endif
871     punpcklwd    %1, %1
872     psrad        %1, 16
873 %endif
874 %endmacro
875
876 ; Wrapper for non-FMA version of fmaddps
877 %macro FMULADD_PS 5
878     %if cpuflag(fma3) || cpuflag(fma4)
879         fmaddps %1, %2, %3, %4
880     %elifidn %1, %4
881         mulps   %5, %2, %3
882         addps   %1, %4, %5
883     %else
884         mulps   %1, %2, %3
885         addps   %1, %4
886     %endif
887 %endmacro
888
889 %macro LSHIFT 2
890 %if mmsize > 8
891     pslldq  %1, %2
892 %else
893     psllq   %1, 8*(%2)
894 %endif
895 %endmacro
896
897 %macro RSHIFT 2
898 %if mmsize > 8
899     psrldq  %1, %2
900 %else
901     psrlq   %1, 8*(%2)
902 %endif
903 %endmacro
904
905 %macro MOVHL 2 ; dst, src
906 %ifidn %1, %2
907     punpckhqdq %1, %2
908 %elif cpuflag(avx)
909     punpckhqdq %1, %2, %2
910 %elif cpuflag(sse4)
911     pshufd     %1, %2, q3232 ; pshufd is slow on some older CPUs, so only use it on more modern ones
912 %else
913     movhlps    %1, %2        ; may cause an int/float domain transition and has a dependency on dst
914 %endif
915 %endmacro