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