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