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