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 Libav. 10;* 11;* Libav 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;* Libav 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 Libav; 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 PALIGNR 4-5 277%if cpuflag(ssse3) 278%if %0==5 279 palignr %1, %2, %3, %4 280%else 281 palignr %1, %2, %3 282%endif 283%elif cpuflag(mmx) ; [dst,] src1, src2, imm, tmp 284 %define %%dst %1 285%if %0==5 286%ifnidn %1, %2 287 mova %%dst, %2 288%endif 289 %rotate 1 290%endif 291%ifnidn %4, %2 292 mova %4, %2 293%endif 294%if mmsize==8 295 psllq %%dst, (8-%3)*8 296 psrlq %4, %3*8 297%else 298 pslldq %%dst, 16-%3 299 psrldq %4, %3 300%endif 301 por %%dst, %4 302%endif 303%endmacro 304 305%macro PAVGB 2 306%if cpuflag(mmxext) 307 pavgb %1, %2 308%elif cpuflag(3dnow) 309 pavgusb %1, %2 310%endif 311%endmacro 312 313%macro PSHUFLW 1+ 314 %if mmsize == 8 315 pshufw %1 316 %else 317 pshuflw %1 318 %endif 319%endmacro 320 321%macro PSWAPD 2 322%if cpuflag(mmxext) 323 pshufw %1, %2, q1032 324%elif cpuflag(3dnowext) 325 pswapd %1, %2 326%elif cpuflag(3dnow) 327 movq %1, %2 328 psrlq %1, 32 329 punpckldq %1, %2 330%endif 331%endmacro 332 333%macro DEINTB 5 ; mask, reg1, mask, reg2, optional src to fill masks from 334%ifnum %5 335 pand m%3, m%5, m%4 ; src .. y6 .. y4 336 pand m%1, m%5, m%2 ; dst .. y6 .. y4 337%else 338 mova m%1, %5 339 pand m%3, m%1, m%4 ; src .. y6 .. y4 340 pand m%1, m%1, m%2 ; dst .. y6 .. y4 341%endif 342 psrlw m%2, 8 ; dst .. y7 .. y5 343 psrlw m%4, 8 ; src .. y7 .. y5 344%endmacro 345 346%macro SUMSUB_BA 3-4 347%if %0==3 348 padd%1 m%2, m%3 349 padd%1 m%3, m%3 350 psub%1 m%3, m%2 351%else 352%if avx_enabled == 0 353 mova m%4, m%2 354 padd%1 m%2, m%3 355 psub%1 m%3, m%4 356%else 357 padd%1 m%4, m%2, m%3 358 psub%1 m%3, m%2 359 SWAP %2, %4 360%endif 361%endif 362%endmacro 363 364%macro SUMSUB_BADC 5-6 365%if %0==6 366 SUMSUB_BA %1, %2, %3, %6 367 SUMSUB_BA %1, %4, %5, %6 368%else 369 padd%1 m%2, m%3 370 padd%1 m%4, m%5 371 padd%1 m%3, m%3 372 padd%1 m%5, m%5 373 psub%1 m%3, m%2 374 psub%1 m%5, m%4 375%endif 376%endmacro 377 378%macro SUMSUB2_AB 4 379%ifnum %3 380 psub%1 m%4, m%2, m%3 381 psub%1 m%4, m%3 382 padd%1 m%2, m%2 383 padd%1 m%2, m%3 384%else 385 mova m%4, m%2 386 padd%1 m%2, m%2 387 padd%1 m%2, %3 388 psub%1 m%4, %3 389 psub%1 m%4, %3 390%endif 391%endmacro 392 393%macro SUMSUB2_BA 4 394%if avx_enabled == 0 395 mova m%4, m%2 396 padd%1 m%2, m%3 397 padd%1 m%2, m%3 398 psub%1 m%3, m%4 399 psub%1 m%3, m%4 400%else 401 padd%1 m%4, m%2, m%3 402 padd%1 m%4, m%3 403 psub%1 m%3, m%2 404 psub%1 m%3, m%2 405 SWAP %2, %4 406%endif 407%endmacro 408 409%macro SUMSUBD2_AB 5 410%ifnum %4 411 psra%1 m%5, m%2, 1 ; %3: %3>>1 412 psra%1 m%4, m%3, 1 ; %2: %2>>1 413 padd%1 m%4, m%2 ; %3: %3>>1+%2 414 psub%1 m%5, m%3 ; %2: %2>>1-%3 415 SWAP %2, %5 416 SWAP %3, %4 417%else 418 mova %5, m%2 419 mova %4, m%3 420 psra%1 m%3, 1 ; %3: %3>>1 421 psra%1 m%2, 1 ; %2: %2>>1 422 padd%1 m%3, %5 ; %3: %3>>1+%2 423 psub%1 m%2, %4 ; %2: %2>>1-%3 424%endif 425%endmacro 426 427%macro DCT4_1D 5 428%ifnum %5 429 SUMSUB_BADC w, %4, %1, %3, %2, %5 430 SUMSUB_BA w, %3, %4, %5 431 SUMSUB2_AB w, %1, %2, %5 432 SWAP %1, %3, %4, %5, %2 433%else 434 SUMSUB_BADC w, %4, %1, %3, %2 435 SUMSUB_BA w, %3, %4 436 mova [%5], m%2 437 SUMSUB2_AB w, %1, [%5], %2 438 SWAP %1, %3, %4, %2 439%endif 440%endmacro 441 442%macro IDCT4_1D 6-7 443%ifnum %6 444 SUMSUBD2_AB %1, %3, %5, %7, %6 445 ; %3: %3>>1-%5 %5: %3+%5>>1 446 SUMSUB_BA %1, %4, %2, %7 447 ; %4: %2+%4 %2: %2-%4 448 SUMSUB_BADC %1, %5, %4, %3, %2, %7 449 ; %5: %2+%4 + (%3+%5>>1) 450 ; %4: %2+%4 - (%3+%5>>1) 451 ; %3: %2-%4 + (%3>>1-%5) 452 ; %2: %2-%4 - (%3>>1-%5) 453%else 454%ifidn %1, w 455 SUMSUBD2_AB %1, %3, %5, [%6], [%6+16] 456%else 457 SUMSUBD2_AB %1, %3, %5, [%6], [%6+32] 458%endif 459 SUMSUB_BA %1, %4, %2 460 SUMSUB_BADC %1, %5, %4, %3, %2 461%endif 462 SWAP %2, %5, %4 463 ; %2: %2+%4 + (%3+%5>>1) row0 464 ; %3: %2-%4 + (%3>>1-%5) row1 465 ; %4: %2-%4 - (%3>>1-%5) row2 466 ; %5: %2+%4 - (%3+%5>>1) row3 467%endmacro 468 469 470%macro LOAD_DIFF 5 471%ifidn %3, none 472 movh %1, %4 473 movh %2, %5 474 punpcklbw %1, %2 475 punpcklbw %2, %2 476 psubw %1, %2 477%else 478 movh %1, %4 479 punpcklbw %1, %3 480 movh %2, %5 481 punpcklbw %2, %3 482 psubw %1, %2 483%endif 484%endmacro 485 486%macro STORE_DCT 6 487 movq [%5+%6+ 0], m%1 488 movq [%5+%6+ 8], m%2 489 movq [%5+%6+16], m%3 490 movq [%5+%6+24], m%4 491 movhps [%5+%6+32], m%1 492 movhps [%5+%6+40], m%2 493 movhps [%5+%6+48], m%3 494 movhps [%5+%6+56], m%4 495%endmacro 496 497%macro LOAD_DIFF_8x4P 7-10 r0,r2,0 ; 4x dest, 2x temp, 2x pointer, increment? 498 LOAD_DIFF m%1, m%5, m%7, [%8], [%9] 499 LOAD_DIFF m%2, m%6, m%7, [%8+r1], [%9+r3] 500 LOAD_DIFF m%3, m%5, m%7, [%8+2*r1], [%9+2*r3] 501 LOAD_DIFF m%4, m%6, m%7, [%8+r4], [%9+r5] 502%if %10 503 lea %8, [%8+4*r1] 504 lea %9, [%9+4*r3] 505%endif 506%endmacro 507 508%macro DIFFx2 6-7 509 movh %3, %5 510 punpcklbw %3, %4 511 psraw %1, 6 512 paddsw %1, %3 513 movh %3, %6 514 punpcklbw %3, %4 515 psraw %2, 6 516 paddsw %2, %3 517 packuswb %2, %1 518%endmacro 519 520%macro STORE_DIFF 4 521 movh %2, %4 522 punpcklbw %2, %3 523 psraw %1, 6 524 paddsw %1, %2 525 packuswb %1, %1 526 movh %4, %1 527%endmacro 528 529%macro STORE_DIFFx2 8 ; add1, add2, reg1, reg2, zero, shift, source, stride 530 movh %3, [%7] 531 movh %4, [%7+%8] 532 psraw %1, %6 533 psraw %2, %6 534 punpcklbw %3, %5 535 punpcklbw %4, %5 536 paddw %3, %1 537 paddw %4, %2 538 packuswb %3, %5 539 packuswb %4, %5 540 movh [%7], %3 541 movh [%7+%8], %4 542%endmacro 543 544%macro PMINUB 3 ; dst, src, ignored 545%if cpuflag(mmxext) 546 pminub %1, %2 547%else ; dst, src, tmp 548 mova %3, %1 549 psubusb %3, %2 550 psubb %1, %3 551%endif 552%endmacro 553 554%macro SPLATW 2-3 0 555%if mmsize == 16 556 pshuflw %1, %2, (%3)*0x55 557 punpcklqdq %1, %1 558%elif cpuflag(mmxext) 559 pshufw %1, %2, (%3)*0x55 560%else 561 %ifnidn %1, %2 562 mova %1, %2 563 %endif 564 %if %3 & 2 565 punpckhwd %1, %1 566 %else 567 punpcklwd %1, %1 568 %endif 569 %if %3 & 1 570 punpckhwd %1, %1 571 %else 572 punpcklwd %1, %1 573 %endif 574%endif 575%endmacro 576 577%macro SPLATD 1 578%if mmsize == 8 579 punpckldq %1, %1 580%elif cpuflag(sse2) 581 pshufd %1, %1, 0 582%elif cpuflag(sse) 583 shufps %1, %1, 0 584%endif 585%endmacro 586 587%macro CLIPW 3 ;(dst, min, max) 588 pmaxsw %1, %2 589 pminsw %1, %3 590%endmacro 591 592%macro PMINSD_MMX 3 ; dst, src, tmp 593 mova %3, %2 594 pcmpgtd %3, %1 595 pxor %1, %2 596 pand %1, %3 597 pxor %1, %2 598%endmacro 599 600%macro PMAXSD_MMX 3 ; dst, src, tmp 601 mova %3, %1 602 pcmpgtd %3, %2 603 pand %1, %3 604 pandn %3, %2 605 por %1, %3 606%endmacro 607 608%macro CLIPD_MMX 3-4 ; src/dst, min, max, tmp 609 PMINSD_MMX %1, %3, %4 610 PMAXSD_MMX %1, %2, %4 611%endmacro 612 613%macro CLIPD_SSE2 3-4 ; src/dst, min (float), max (float), unused 614 cvtdq2ps %1, %1 615 minps %1, %3 616 maxps %1, %2 617 cvtps2dq %1, %1 618%endmacro 619 620%macro CLIPD_SSE41 3-4 ; src/dst, min, max, unused 621 pminsd %1, %3 622 pmaxsd %1, %2 623%endmacro 624 625%macro VBROADCASTSS 2 ; dst xmm/ymm, src m32 626%if cpuflag(avx) 627 vbroadcastss %1, %2 628%else ; sse 629 movss %1, %2 630 shufps %1, %1, 0 631%endif 632%endmacro 633 634%macro VBROADCASTSD 2 ; dst xmm/ymm, src m64 635%if cpuflag(avx) && mmsize == 32 636 vbroadcastsd %1, %2 637%elif cpuflag(sse3) 638 movddup %1, %2 639%else ; sse2 640 movsd %1, %2 641 movlhps %1, %1 642%endif 643%endmacro 644 645%macro SHUFFLE_MASK_W 8 646 %rep 8 647 %if %1>=0x80 648 db %1, %1 649 %else 650 db %1*2 651 db %1*2+1 652 %endif 653 %rotate 1 654 %endrep 655%endmacro 656 657%macro PMOVSXWD 2; dst, src 658%if cpuflag(sse4) 659 pmovsxwd %1, %2 660%else 661 %ifnidn %1, %2 662 mova %1, %2 663 %endif 664 punpcklwd %1, %1 665 psrad %1, 16 666%endif 667%endmacro 668 669; Wrapper for non-FMA version of fmaddps 670%macro FMULADD_PS 5 671 %if cpuflag(fma3) || cpuflag(fma4) 672 fmaddps %1, %2, %3, %4 673 %elifidn %1, %4 674 mulps %5, %2, %3 675 addps %1, %4, %5 676 %else 677 mulps %1, %2, %3 678 addps %1, %4 679 %endif 680%endmacro 681