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