Changeset 93756 in vbox for trunk/src/VBox
- Timestamp:
- Feb 15, 2022 3:08:15 PM (3 years ago)
- Location:
- trunk/src/VBox/VMM
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/Makefile.kmk
r93725 r93756 206 206 VBoxVMM_SOURCES.amd64 += \ 207 207 VMMR3/PGMR3DbgA.asm \ 208 VMMAll/IEMAllAImpl.asm\208 $(if-expr !defined(IEM_WITHOUT_ASSEMBLY),VMMAll/IEMAllAImpl.asm,) \ 209 209 VMMAll/VMMAllA.asm 210 210 ifdef VBOX_WITH_VUSB … … 511 511 VMMAll/HMVMXAll.cpp \ 512 512 VMMAll/IEMAll.cpp \ 513 VMMAll/IEMAllAImpl.asm\513 $(if-expr !defined(IEM_WITHOUT_ASSEMBLY),VMMAll/IEMAllAImpl.asm,) \ 514 514 VMMAll/IEMAllAImplC.cpp \ 515 515 VMMAll/IOMAll.cpp \ -
trunk/src/VBox/VMM/VMMAll/IEMAllAImplC.cpp
r93744 r93756 28 28 29 29 /********************************************************************************************************************************* 30 * Defined Constants And Macros * 31 *********************************************************************************************************************************/ 32 #if defined(RT_ARCH_ARM32) || defined(RT_ARCH_ARM64) 33 # define IEM_WITHOUT_ASSEMBLY 34 #endif 35 36 /** 37 * Calculates the signed flag value given a result and it's bit width. 38 * 39 * The signed flag (SF) is a duplication of the most significant bit in the 40 * result. 41 * 42 * @returns X86_EFL_SF or 0. 43 * @param a_uResult Unsigned result value. 44 * @param a_cBitsWidth The width of the result (8, 16, 32, 64). 45 */ 46 #define X86_EFL_CALC_SF(a_uResult, a_cBitsWidth) \ 47 ( (uint32_t)((a_uResult) >> ((a_cBitsWidth) - X86_EFL_SF_BIT - 1)) & X86_EFL_SF ) 48 49 /** 50 * Calculates the zero flag value given a result. 51 * 52 * The zero flag (ZF) indicates whether the result is zero or not. 53 * 54 * @returns X86_EFL_ZF or 0. 55 * @param a_uResult Unsigned result value. 56 */ 57 #define X86_EFL_CALC_ZF(a_uResult) \ 58 ( (uint32_t)((a_uResult) == 0) << X86_EFL_ZF_BIT ) 59 60 /** 61 * Updates the status bits (CF, PF, AF, ZF, SF, and OF) after arithmetic op. 62 * 63 * CF and OF are defined to be 0 by logical operations. AF on the other hand is 64 * undefined. We do not set AF, as that seems to make the most sense (which 65 * probably makes it the most wrong in real life). 66 * 67 * @returns Status bits. 68 * @param a_pfEFlags Pointer to the 32-bit EFLAGS value to update. 69 * @param a_uResult Unsigned result value. 70 * @param a_uSrc The source value (for AF calc). 71 * @param a_uDst The original destination value (for AF calc). 72 * @param a_cBitsWidth The width of the result (8, 16, 32, 64). 73 * @param a_CfExpr Bool expression for the carry flag (CF). 74 * @param a_OfMethod 0 for ADD-style, 1 for SUB-style. 75 */ 76 #define IEM_EFL_UPDATE_STATUS_BITS_FOR_ARITHMETIC(a_pfEFlags, a_uResult, a_uDst, a_Src, a_cBitsWidth, a_CfExpr, a_OfMethod) \ 77 do { \ 78 uint32_t fEflTmp = *(a_pfEFlags); \ 79 fEflTmp &= ~X86_EFL_STATUS_BITS; \ 80 fEflTmp |= (a_CfExpr) << X86_EFL_CF_BIT; \ 81 fEflTmp |= g_afParity[(a_uResult) & 0xff]; \ 82 fEflTmp |= ((uint32_t)uResult ^ (uint32_t)uSrc ^ (uint32_t)uDst) & X86_EFL_AF; \ 83 fEflTmp |= X86_EFL_CALC_ZF(a_uResult); \ 84 fEflTmp |= X86_EFL_CALC_SF(a_uResult, a_cBitsWidth); \ 85 fEflTmp |= ( ((uDst ^ uSrc ^ (a_OfMethod == 0 ? RT_BIT_64(a_cBitsWidth - 1) : 0)) & (uResult ^ uDst)) \ 86 >> (64 - X86_EFL_OF_BIT)) & X86_EFL_OF; \ 87 *(a_pfEFlags) = fEflTmp; \ 88 } while (0) 89 90 /** 91 * Updates the status bits (CF, PF, AF, ZF, SF, and OF) after a logical op. 92 * 93 * CF and OF are defined to be 0 by logical operations. AF on the other hand is 94 * undefined. We do not set AF, as that seems to make the most sense (which 95 * probably makes it the most wrong in real life). 96 * 97 * @returns Status bits. 98 * @param a_pfEFlags Pointer to the 32-bit EFLAGS value to update. 99 * @param a_uResult Unsigned result value. 100 * @param a_cBitsWidth The width of the result (8, 16, 32, 64). 101 * @param a_fExtra Additional bits to set. 102 */ 103 #define IEM_EFL_UPDATE_STATUS_BITS_FOR_LOGIC(a_pfEFlags, a_uResult, a_cBitsWidth, a_fExtra) \ 104 do { \ 105 uint32_t fEflTmp = *(a_pfEFlags); \ 106 fEflTmp &= ~X86_EFL_STATUS_BITS; \ 107 fEflTmp |= g_afParity[(a_uResult) & 0xff]; \ 108 fEflTmp |= X86_EFL_CALC_ZF(a_uResult); \ 109 fEflTmp |= X86_EFL_CALC_SF(a_uResult, a_cBitsWidth); \ 110 fEflTmp |= (a_fExtra); \ 111 *(a_pfEFlags) = fEflTmp; \ 112 } while (0) 113 114 115 /********************************************************************************************************************************* 30 116 * Global Variables * 31 117 *********************************************************************************************************************************/ 32 #if ndef RT_ARCH_AMD64118 #if !defined(RT_ARCH_AMD64) || defined(IEM_WITHOUT_ASSEMBLY) 33 119 /** 34 120 * Parity calculation table. … … 326 412 /* 0xff = 11111111b */ X86_EFL_PF, 327 413 }; 328 #endif /* RT_ARCH_AMD64 */ 329 330 331 /** 332 * Calculates the signed flag value given a result and it's bit width. 333 * 334 * The signed flag (SF) is a duplication of the most significant bit in the 335 * result. 336 * 337 * @returns X86_EFL_SF or 0. 338 * @param a_uResult Unsigned result value. 339 * @param a_cBitsWidth The width of the result (8, 16, 32, 64). 340 */ 341 #define X86_EFL_CALC_SF(a_uResult, a_cBitsWidth) \ 342 ( (uint32_t)((a_uResult) >> ((a_cBitsWidth) - X86_EFL_SF_BIT - 1)) & X86_EFL_SF ) 343 344 /** 345 * Calculates the zero flag value given a result. 346 * 347 * The zero flag (ZF) indicates whether the result is zero or not. 348 * 349 * @returns X86_EFL_ZF or 0. 350 * @param a_uResult Unsigned result value. 351 */ 352 #define X86_EFL_CALC_ZF(a_uResult) \ 353 ( (uint32_t)((a_uResult) == 0) << X86_EFL_ZF_BIT ) 354 355 /** 356 * Updates the status bits (CF, PF, AF, ZF, SF, and OF) after a logical op. 357 * 358 * CF and OF are defined to be 0 by logical operations. AF on the other hand is 359 * undefined. We do not set AF, as that seems to make the most sense (which 360 * probably makes it the most wrong in real life). 361 * 362 * @returns Status bits. 363 * @param a_pfEFlags Pointer to the 32-bit EFLAGS value to update. 364 * @param a_uResult Unsigned result value. 365 * @param a_cBitsWidth The width of the result (8, 16, 32, 64). 366 * @param a_fExtra Additional bits to set. 367 */ 368 #define IEM_EFL_UPDATE_STATUS_BITS_FOR_LOGIC(a_pfEFlags, a_uResult, a_cBitsWidth, a_fExtra) \ 369 do { \ 370 uint32_t fEflTmp = *(a_pfEFlags); \ 371 fEflTmp &= ~X86_EFL_STATUS_BITS; \ 372 fEflTmp |= g_afParity[(a_uResult) & 0xff]; \ 373 fEflTmp |= X86_EFL_CALC_ZF(a_uResult); \ 374 fEflTmp |= X86_EFL_CALC_SF(a_uResult, a_cBitsWidth); \ 375 fEflTmp |= (a_fExtra); \ 376 *(a_pfEFlags) = fEflTmp; \ 377 } while (0) 378 379 380 #ifndef RT_ARCH_AMD64 414 #endif /* !RT_ARCH_AMD64 || IEM_WITHOUT_ASSEMBLY */ 415 416 417 418 #if !defined(RT_ARCH_AMD64) || defined(IEM_WITHOUT_ASSEMBLY) 381 419 /* 382 420 * There are a few 64-bit on 32-bit things we'd rather do in C. Actually, doing … … 384 422 */ 385 423 386 387 /* Binary ops */ 424 /********************************************************************************************************************************* 425 * Binary Operations * 426 *********************************************************************************************************************************/ 427 428 /* 429 * ADD 430 */ 388 431 389 432 IEM_DECL_IMPL_DEF(void, iemAImpl_add_u64,(uint64_t *puDst, uint64_t uSrc, uint32_t *pfEFlags)) … … 392 435 uint64_t uResult = uDst + uSrc; 393 436 *puDst = uResult; 394 395 /* Calc EFLAGS. */ 396 uint32_t fEfl = *pfEFlags & ~X86_EFL_STATUS_BITS; 397 fEfl |= (uResult < uDst) << X86_EFL_CF_BIT; 398 fEfl |= g_afParity[uResult & 0xff]; 399 fEfl |= ((uint32_t)uResult ^ (uint32_t)uSrc ^ (uint32_t)uDst) & X86_EFL_AF; 400 fEfl |= X86_EFL_CALC_ZF(uResult); 401 fEfl |= X86_EFL_CALC_SF(uResult, 64); 402 fEfl |= (((uDst ^ uSrc ^ RT_BIT_64(63)) & (uResult ^ uDst)) >> (64 - X86_EFL_OF_BIT)) & X86_EFL_OF; 403 *pfEFlags = fEfl; 404 } 405 437 IEM_EFL_UPDATE_STATUS_BITS_FOR_ARITHMETIC(pfEFlags, uResult, uDst, uSrc, 64, uResult < uDst, 0); 438 } 439 440 # if !defined(RT_ARCH_X86) || defined(IEM_WITHOUT_ASSEMBLY) 441 442 IEM_DECL_IMPL_DEF(void, iemAImpl_add_u32,(uint32_t *puDst, uint32_t uSrc, uint32_t *pfEFlags)) 443 { 444 uint32_t uDst = *puDst; 445 uint32_t uResult = uDst + uSrc; 446 *puDst = uResult; 447 IEM_EFL_UPDATE_STATUS_BITS_FOR_ARITHMETIC(pfEFlags, uResult, uDst, uSrc, 32, uResult < uDst, 0); 448 } 449 450 451 IEM_DECL_IMPL_DEF(void, iemAImpl_add_u16,(uint16_t *puDst, uint16_t uSrc, uint32_t *pfEFlags)) 452 { 453 uint16_t uDst = *puDst; 454 uint16_t uResult = uDst + uSrc; 455 *puDst = uResult; 456 IEM_EFL_UPDATE_STATUS_BITS_FOR_ARITHMETIC(pfEFlags, uResult, uDst, uSrc, 16, uResult < uDst, 0); 457 } 458 459 460 IEM_DECL_IMPL_DEF(void, iemAImpl_add_u8,(uint8_t *puDst, uint8_t uSrc, uint32_t *pfEFlags)) 461 { 462 uint8_t uDst = *puDst; 463 uint8_t uResult = uDst + uSrc; 464 *puDst = uResult; 465 IEM_EFL_UPDATE_STATUS_BITS_FOR_ARITHMETIC(pfEFlags, uResult, uDst, uSrc, 8, uResult < uDst, 0); 466 } 467 468 # endif /* !defined(RT_ARCH_X86) || defined(IEM_WITHOUT_ASSEMBLY) */ 469 470 /* 471 * ADC 472 */ 406 473 407 474 IEM_DECL_IMPL_DEF(void, iemAImpl_adc_u64,(uint64_t *puDst, uint64_t uSrc, uint32_t *pfEFlags)) … … 414 481 uint64_t uResult = uDst + uSrc + 1; 415 482 *puDst = uResult; 416 417 /* Calc EFLAGS. */418 483 /** @todo verify AF and OF calculations. */ 419 uint32_t fEfl = *pfEFlags & ~X86_EFL_STATUS_BITS; 420 fEfl |= (uResult <= uDst) << X86_EFL_CF_BIT; 421 fEfl |= g_afParity[uResult & 0xff]; 422 fEfl |= ((uint32_t)uResult ^ (uint32_t)uSrc ^ (uint32_t)uDst) & X86_EFL_AF; 423 fEfl |= X86_EFL_CALC_ZF(uResult); 424 fEfl |= X86_EFL_CALC_SF(uResult, 64); 425 fEfl |= (((uDst ^ uSrc ^ RT_BIT_64(63)) & (uResult ^ uDst)) >> (64 - X86_EFL_OF_BIT)) & X86_EFL_OF; 426 *pfEFlags = fEfl; 427 } 428 } 429 484 IEM_EFL_UPDATE_STATUS_BITS_FOR_ARITHMETIC(pfEFlags, uResult, uDst, uSrc, 64, uResult <= uDst, 0); 485 } 486 } 487 488 # if !defined(RT_ARCH_X86) || defined(IEM_WITHOUT_ASSEMBLY) 489 490 IEM_DECL_IMPL_DEF(void, iemAImpl_adc_u32,(uint32_t *puDst, uint32_t uSrc, uint32_t *pfEFlags)) 491 { 492 if (!(*pfEFlags & X86_EFL_CF)) 493 iemAImpl_add_u32(puDst, uSrc, pfEFlags); 494 else 495 { 496 uint32_t uDst = *puDst; 497 uint32_t uResult = uDst + uSrc + 1; 498 *puDst = uResult; 499 /** @todo verify AF and OF calculations. */ 500 IEM_EFL_UPDATE_STATUS_BITS_FOR_ARITHMETIC(pfEFlags, uResult, uDst, uSrc, 32, uResult <= uDst, 0); 501 } 502 } 503 504 505 IEM_DECL_IMPL_DEF(void, iemAImpl_adc_u16,(uint16_t *puDst, uint16_t uSrc, uint32_t *pfEFlags)) 506 { 507 if (!(*pfEFlags & X86_EFL_CF)) 508 iemAImpl_add_u16(puDst, uSrc, pfEFlags); 509 else 510 { 511 uint16_t uDst = *puDst; 512 uint16_t uResult = uDst + uSrc + 1; 513 *puDst = uResult; 514 /** @todo verify AF and OF calculations. */ 515 IEM_EFL_UPDATE_STATUS_BITS_FOR_ARITHMETIC(pfEFlags, uResult, uDst, uSrc, 16, uResult <= uDst, 0); 516 } 517 } 518 519 520 IEM_DECL_IMPL_DEF(void, iemAImpl_adc_u8,(uint8_t *puDst, uint8_t uSrc, uint32_t *pfEFlags)) 521 { 522 if (!(*pfEFlags & X86_EFL_CF)) 523 iemAImpl_add_u8(puDst, uSrc, pfEFlags); 524 else 525 { 526 uint8_t uDst = *puDst; 527 uint8_t uResult = uDst + uSrc + 1; 528 *puDst = uResult; 529 /** @todo verify AF and OF calculations. */ 530 IEM_EFL_UPDATE_STATUS_BITS_FOR_ARITHMETIC(pfEFlags, uResult, uDst, uSrc, 8, uResult <= uDst, 0); 531 } 532 } 533 534 # endif /* !defined(RT_ARCH_X86) || defined(IEM_WITHOUT_ASSEMBLY) */ 535 536 /* 537 * SUB 538 */ 430 539 431 540 IEM_DECL_IMPL_DEF(void, iemAImpl_sub_u64,(uint64_t *puDst, uint64_t uSrc, uint32_t *pfEFlags)) … … 434 543 uint64_t uResult = uDst - uSrc; 435 544 *puDst = uResult; 436 437 /* Calc EFLAGS. */ 438 uint32_t fEfl = *pfEFlags & ~X86_EFL_STATUS_BITS; 439 fEfl |= (uDst < uSrc) << X86_EFL_CF_BIT; 440 fEfl |= g_afParity[uResult & 0xff]; 441 fEfl |= ((uint32_t)uResult ^ (uint32_t)uSrc ^ (uint32_t)uDst) & X86_EFL_AF; 442 fEfl |= X86_EFL_CALC_ZF(uResult); 443 fEfl |= X86_EFL_CALC_SF(uResult, 64); 444 fEfl |= (((uDst ^ uSrc) & (uResult ^ uDst)) >> (64 - X86_EFL_OF_BIT)) & X86_EFL_OF; 445 *pfEFlags = fEfl; 446 } 447 545 IEM_EFL_UPDATE_STATUS_BITS_FOR_ARITHMETIC(pfEFlags, uResult, uDst, uSrc, 64, uResult < uDst, 1); 546 } 547 548 # if !defined(RT_ARCH_X86) || defined(IEM_WITHOUT_ASSEMBLY) 549 550 IEM_DECL_IMPL_DEF(void, iemAImpl_sub_u32,(uint32_t *puDst, uint32_t uSrc, uint32_t *pfEFlags)) 551 { 552 uint32_t uDst = *puDst; 553 uint32_t uResult = uDst - uSrc; 554 *puDst = uResult; 555 IEM_EFL_UPDATE_STATUS_BITS_FOR_ARITHMETIC(pfEFlags, uResult, uDst, uSrc, 32, uResult < uDst, 1); 556 } 557 558 559 IEM_DECL_IMPL_DEF(void, iemAImpl_sub_u16,(uint16_t *puDst, uint16_t uSrc, uint32_t *pfEFlags)) 560 { 561 uint16_t uDst = *puDst; 562 uint16_t uResult = uDst - uSrc; 563 *puDst = uResult; 564 IEM_EFL_UPDATE_STATUS_BITS_FOR_ARITHMETIC(pfEFlags, uResult, uDst, uSrc, 16, uResult < uDst, 1); 565 } 566 567 568 IEM_DECL_IMPL_DEF(void, iemAImpl_sub_u8,(uint8_t *puDst, uint8_t uSrc, uint32_t *pfEFlags)) 569 { 570 uint8_t uDst = *puDst; 571 uint8_t uResult = uDst - uSrc; 572 *puDst = uResult; 573 IEM_EFL_UPDATE_STATUS_BITS_FOR_ARITHMETIC(pfEFlags, uResult, uDst, uSrc, 8, uResult < uDst, 1); 574 } 575 576 # endif /* !defined(RT_ARCH_X86) || defined(IEM_WITHOUT_ASSEMBLY) */ 577 578 /* 579 * SBB 580 */ 448 581 449 582 IEM_DECL_IMPL_DEF(void, iemAImpl_sbb_u64,(uint64_t *puDst, uint64_t uSrc, uint32_t *pfEFlags)) … … 456 589 uint64_t uResult = uDst - uSrc - 1; 457 590 *puDst = uResult; 458 459 /* Calc EFLAGS. */460 591 /** @todo verify AF and OF calculations. */ 461 uint32_t fEfl = *pfEFlags & ~X86_EFL_STATUS_BITS; 462 fEfl |= (uDst <= uSrc) << X86_EFL_CF_BIT; 463 fEfl |= g_afParity[uResult & 0xff]; 464 fEfl |= ((uint32_t)uResult ^ (uint32_t)uSrc ^ (uint32_t)uDst) & X86_EFL_AF; 465 fEfl |= X86_EFL_CALC_ZF(uResult); 466 fEfl |= X86_EFL_CALC_SF(uResult, 64); 467 fEfl |= (((uDst ^ uSrc) & (uResult ^ uDst)) >> (64 - X86_EFL_OF_BIT)) & X86_EFL_OF; 468 *pfEFlags = fEfl; 469 } 470 } 471 592 IEM_EFL_UPDATE_STATUS_BITS_FOR_ARITHMETIC(pfEFlags, uResult, uDst, uSrc, 64, uResult <= uDst, 1); 593 } 594 } 595 596 # if !defined(RT_ARCH_X86) || defined(IEM_WITHOUT_ASSEMBLY) 597 598 IEM_DECL_IMPL_DEF(void, iemAImpl_sbb_u32,(uint32_t *puDst, uint32_t uSrc, uint32_t *pfEFlags)) 599 { 600 if (!(*pfEFlags & X86_EFL_CF)) 601 iemAImpl_sub_u32(puDst, uSrc, pfEFlags); 602 else 603 { 604 uint32_t uDst = *puDst; 605 uint32_t uResult = uDst - uSrc - 1; 606 *puDst = uResult; 607 /** @todo verify AF and OF calculations. */ 608 IEM_EFL_UPDATE_STATUS_BITS_FOR_ARITHMETIC(pfEFlags, uResult, uDst, uSrc, 32, uResult <= uDst, 1); 609 } 610 } 611 612 613 IEM_DECL_IMPL_DEF(void, iemAImpl_sbb_u16,(uint16_t *puDst, uint16_t uSrc, uint32_t *pfEFlags)) 614 { 615 if (!(*pfEFlags & X86_EFL_CF)) 616 iemAImpl_sub_u16(puDst, uSrc, pfEFlags); 617 else 618 { 619 uint16_t uDst = *puDst; 620 uint16_t uResult = uDst - uSrc - 1; 621 *puDst = uResult; 622 /** @todo verify AF and OF calculations. */ 623 IEM_EFL_UPDATE_STATUS_BITS_FOR_ARITHMETIC(pfEFlags, uResult, uDst, uSrc, 16, uResult <= uDst, 1); 624 } 625 } 626 627 628 IEM_DECL_IMPL_DEF(void, iemAImpl_sbb_u8,(uint8_t *puDst, uint8_t uSrc, uint32_t *pfEFlags)) 629 { 630 if (!(*pfEFlags & X86_EFL_CF)) 631 iemAImpl_sub_u8(puDst, uSrc, pfEFlags); 632 else 633 { 634 uint8_t uDst = *puDst; 635 uint8_t uResult = uDst - uSrc - 1; 636 *puDst = uResult; 637 /** @todo verify AF and OF calculations. */ 638 IEM_EFL_UPDATE_STATUS_BITS_FOR_ARITHMETIC(pfEFlags, uResult, uDst, uSrc, 8, uResult <= uDst, 1); 639 } 640 } 641 642 # endif /* !defined(RT_ARCH_X86) || defined(IEM_WITHOUT_ASSEMBLY) */ 643 644 645 /* 646 * OR 647 */ 472 648 473 649 IEM_DECL_IMPL_DEF(void, iemAImpl_or_u64,(uint64_t *puDst, uint64_t uSrc, uint32_t *pfEFlags)) … … 478 654 } 479 655 656 # if !defined(RT_ARCH_X86) || defined(IEM_WITHOUT_ASSEMBLY) 657 658 IEM_DECL_IMPL_DEF(void, iemAImpl_or_u32,(uint32_t *puDst, uint32_t uSrc, uint32_t *pfEFlags)) 659 { 660 uint32_t uResult = *puDst | uSrc; 661 *puDst = uResult; 662 IEM_EFL_UPDATE_STATUS_BITS_FOR_LOGIC(pfEFlags, uResult, 32, 0); 663 } 664 665 666 IEM_DECL_IMPL_DEF(void, iemAImpl_or_u16,(uint16_t *puDst, uint16_t uSrc, uint32_t *pfEFlags)) 667 { 668 uint16_t uResult = *puDst | uSrc; 669 *puDst = uResult; 670 IEM_EFL_UPDATE_STATUS_BITS_FOR_LOGIC(pfEFlags, uResult, 16, 0); 671 } 672 673 674 IEM_DECL_IMPL_DEF(void, iemAImpl_or_u8,(uint8_t *puDst, uint8_t uSrc, uint32_t *pfEFlags)) 675 { 676 uint8_t uResult = *puDst | uSrc; 677 *puDst = uResult; 678 IEM_EFL_UPDATE_STATUS_BITS_FOR_LOGIC(pfEFlags, uResult, 8, 0); 679 } 680 681 # endif /* !defined(RT_ARCH_X86) || defined(IEM_WITHOUT_ASSEMBLY) */ 682 683 /* 684 * XOR 685 */ 480 686 481 687 IEM_DECL_IMPL_DEF(void, iemAImpl_xor_u64,(uint64_t *puDst, uint64_t uSrc, uint32_t *pfEFlags)) … … 486 692 } 487 693 694 # if !defined(RT_ARCH_X86) || defined(IEM_WITHOUT_ASSEMBLY) 695 696 IEM_DECL_IMPL_DEF(void, iemAImpl_xor_u32,(uint32_t *puDst, uint32_t uSrc, uint32_t *pfEFlags)) 697 { 698 uint32_t uResult = *puDst ^ uSrc; 699 *puDst = uResult; 700 IEM_EFL_UPDATE_STATUS_BITS_FOR_LOGIC(pfEFlags, uResult, 32, 0); 701 } 702 703 704 IEM_DECL_IMPL_DEF(void, iemAImpl_xor_u16,(uint16_t *puDst, uint16_t uSrc, uint32_t *pfEFlags)) 705 { 706 uint16_t uResult = *puDst ^ uSrc; 707 *puDst = uResult; 708 IEM_EFL_UPDATE_STATUS_BITS_FOR_LOGIC(pfEFlags, uResult, 16, 0); 709 } 710 711 712 IEM_DECL_IMPL_DEF(void, iemAImpl_xor_u8,(uint8_t *puDst, uint8_t uSrc, uint32_t *pfEFlags)) 713 { 714 uint8_t uResult = *puDst ^ uSrc; 715 *puDst = uResult; 716 IEM_EFL_UPDATE_STATUS_BITS_FOR_LOGIC(pfEFlags, uResult, 8, 0); 717 } 718 719 # endif /* !defined(RT_ARCH_X86) || defined(IEM_WITHOUT_ASSEMBLY) */ 720 721 /* 722 * AND 723 */ 488 724 489 725 IEM_DECL_IMPL_DEF(void, iemAImpl_and_u64,(uint64_t *puDst, uint64_t uSrc, uint32_t *pfEFlags)) … … 494 730 } 495 731 732 # if !defined(RT_ARCH_X86) || defined(IEM_WITHOUT_ASSEMBLY) 733 734 IEM_DECL_IMPL_DEF(void, iemAImpl_and_u32,(uint32_t *puDst, uint32_t uSrc, uint32_t *pfEFlags)) 735 { 736 uint32_t uResult = *puDst & uSrc; 737 *puDst = uResult; 738 IEM_EFL_UPDATE_STATUS_BITS_FOR_LOGIC(pfEFlags, uResult, 32, 0); 739 } 740 741 742 IEM_DECL_IMPL_DEF(void, iemAImpl_and_u16,(uint16_t *puDst, uint16_t uSrc, uint32_t *pfEFlags)) 743 { 744 uint16_t uResult = *puDst & uSrc; 745 *puDst = uResult; 746 IEM_EFL_UPDATE_STATUS_BITS_FOR_LOGIC(pfEFlags, uResult, 16, 0); 747 } 748 749 750 IEM_DECL_IMPL_DEF(void, iemAImpl_and_u8,(uint8_t *puDst, uint8_t uSrc, uint32_t *pfEFlags)) 751 { 752 uint8_t uResult = *puDst & uSrc; 753 *puDst = uResult; 754 IEM_EFL_UPDATE_STATUS_BITS_FOR_LOGIC(pfEFlags, uResult, 8, 0); 755 } 756 757 # endif /* !defined(RT_ARCH_X86) || defined(IEM_WITHOUT_ASSEMBLY) */ 758 759 /* 760 * CMP 761 */ 496 762 497 763 IEM_DECL_IMPL_DEF(void, iemAImpl_cmp_u64,(uint64_t *puDst, uint64_t uSrc, uint32_t *pfEFlags)) … … 501 767 } 502 768 769 # if !defined(RT_ARCH_X86) || defined(IEM_WITHOUT_ASSEMBLY) 770 771 IEM_DECL_IMPL_DEF(void, iemAImpl_cmp_u32,(uint32_t *puDst, uint32_t uSrc, uint32_t *pfEFlags)) 772 { 773 uint32_t uDstTmp = *puDst; 774 iemAImpl_sub_u32(&uDstTmp, uSrc, pfEFlags); 775 } 776 777 778 IEM_DECL_IMPL_DEF(void, iemAImpl_cmp_u16,(uint16_t *puDst, uint16_t uSrc, uint32_t *pfEFlags)) 779 { 780 uint16_t uDstTmp = *puDst; 781 iemAImpl_sub_u16(&uDstTmp, uSrc, pfEFlags); 782 } 783 784 785 IEM_DECL_IMPL_DEF(void, iemAImpl_cmp_u8,(uint8_t *puDst, uint8_t uSrc, uint32_t *pfEFlags)) 786 { 787 uint8_t uDstTmp = *puDst; 788 iemAImpl_sub_u8(&uDstTmp, uSrc, pfEFlags); 789 } 790 791 # endif /* !defined(RT_ARCH_X86) || defined(IEM_WITHOUT_ASSEMBLY) */ 792 793 /* 794 * TEST 795 */ 503 796 504 797 IEM_DECL_IMPL_DEF(void, iemAImpl_test_u64,(uint64_t *puDst, uint64_t uSrc, uint32_t *pfEFlags)) … … 508 801 } 509 802 803 # if !defined(RT_ARCH_X86) || defined(IEM_WITHOUT_ASSEMBLY) 804 805 IEM_DECL_IMPL_DEF(void, iemAImpl_test_u32,(uint32_t *puDst, uint32_t uSrc, uint32_t *pfEFlags)) 806 { 807 uint32_t uResult = *puDst & uSrc; 808 IEM_EFL_UPDATE_STATUS_BITS_FOR_LOGIC(pfEFlags, uResult, 32, 0); 809 } 810 811 812 IEM_DECL_IMPL_DEF(void, iemAImpl_test_u16,(uint16_t *puDst, uint16_t uSrc, uint32_t *pfEFlags)) 813 { 814 uint16_t uResult = *puDst & uSrc; 815 IEM_EFL_UPDATE_STATUS_BITS_FOR_LOGIC(pfEFlags, uResult, 16, 0); 816 } 817 818 819 IEM_DECL_IMPL_DEF(void, iemAImpl_test_u8,(uint8_t *puDst, uint8_t uSrc, uint32_t *pfEFlags)) 820 { 821 uint8_t uResult = *puDst & uSrc; 822 IEM_EFL_UPDATE_STATUS_BITS_FOR_LOGIC(pfEFlags, uResult, 8, 0); 823 } 824 825 # endif /* !defined(RT_ARCH_X86) || defined(IEM_WITHOUT_ASSEMBLY) */ 826 827 828 /* 829 * LOCK prefixed variants of the above 830 */ 510 831 511 832 /** 64-bit locked binary operand operation. */ 512 # define DO_LOCKED_BIN_OP _U64(a_Mnemonic) \833 # define DO_LOCKED_BIN_OP(a_Mnemonic, a_cBitsWidth) \ 513 834 do { \ 514 uint 64_t uOld = ASMAtomicReadU64(puDst); \515 uint 64_t uTmp; \835 uint ## a_cBitsWidth ## _t uOld = ASMAtomicUoReadU ## a_cBitsWidth(puDst); \ 836 uint ## a_cBitsWidth ## _t uTmp; \ 516 837 uint32_t fEflTmp; \ 517 838 do \ … … 519 840 uTmp = uOld; \ 520 841 fEflTmp = *pfEFlags; \ 521 iemAImpl_ ## a_Mnemonic ## _u 64(&uTmp, uSrc, &fEflTmp); \522 } while (!ASMAtomicCmpXchgExU 64(puDst, uTmp, uOld, &uOld)); \842 iemAImpl_ ## a_Mnemonic ## _u ## a_cBitsWidth(&uTmp, uSrc, &fEflTmp); \ 843 } while (!ASMAtomicCmpXchgExU ## a_cBitsWidth(puDst, uTmp, uOld, &uOld)); \ 523 844 *pfEFlags = fEflTmp; \ 524 845 } while (0) 525 846 526 847 527 IEM_DECL_IMPL_DEF(void, iemAImpl_add_u64_locked,(uint64_t *puDst, uint64_t uSrc, uint32_t *pfEFlags)) 528 { 529 DO_LOCKED_BIN_OP_U64(add); 530 } 531 532 533 IEM_DECL_IMPL_DEF(void, iemAImpl_adc_u64_locked,(uint64_t *puDst, uint64_t uSrc, uint32_t *pfEFlags)) 534 { 535 DO_LOCKED_BIN_OP_U64(adc); 536 } 537 538 539 IEM_DECL_IMPL_DEF(void, iemAImpl_sub_u64_locked,(uint64_t *puDst, uint64_t uSrc, uint32_t *pfEFlags)) 540 { 541 DO_LOCKED_BIN_OP_U64(sub); 542 } 543 544 545 IEM_DECL_IMPL_DEF(void, iemAImpl_sbb_u64_locked,(uint64_t *puDst, uint64_t uSrc, uint32_t *pfEFlags)) 546 { 547 DO_LOCKED_BIN_OP_U64(sbb); 548 } 549 550 551 IEM_DECL_IMPL_DEF(void, iemAImpl_or_u64_locked,(uint64_t *puDst, uint64_t uSrc, uint32_t *pfEFlags)) 552 { 553 DO_LOCKED_BIN_OP_U64(or); 554 } 555 556 557 IEM_DECL_IMPL_DEF(void, iemAImpl_xor_u64_locked,(uint64_t *puDst, uint64_t uSrc, uint32_t *pfEFlags)) 558 { 559 DO_LOCKED_BIN_OP_U64(xor); 560 } 561 562 563 IEM_DECL_IMPL_DEF(void, iemAImpl_and_u64_locked,(uint64_t *puDst, uint64_t uSrc, uint32_t *pfEFlags)) 564 { 565 DO_LOCKED_BIN_OP_U64(and); 566 } 567 568 569 IEM_DECL_IMPL_DEF(void, iemAImpl_xadd_u64,(uint64_t *puDst, uint64_t *puReg, uint32_t *pfEFlags)) 570 { 571 uint64_t uDst = *puDst; 572 uint64_t uResult = uDst; 573 iemAImpl_add_u64(&uResult, *puReg, pfEFlags); 574 *puDst = uResult; 575 *puReg = uDst; 576 } 577 578 579 IEM_DECL_IMPL_DEF(void, iemAImpl_xadd_u64_locked,(uint64_t *puDst, uint64_t *puReg, uint32_t *pfEFlags)) 580 { 581 uint64_t uOld = ASMAtomicReadU64(puDst); 582 uint64_t uTmpDst; 583 uint32_t fEflTmp; 584 do 585 { 586 uTmpDst = uOld; 587 fEflTmp = *pfEFlags; 588 iemAImpl_add_u64(&uTmpDst, *puReg, pfEFlags); 589 } while (!ASMAtomicCmpXchgExU64(puDst, uTmpDst, uOld, &uOld)); 590 *puReg = uOld; 591 *pfEFlags = fEflTmp; 592 } 593 594 595 /* Bit operations (same signature as above). */ 848 #define EMIT_LOCKED_BIN_OP(a_Mnemonic, a_cBitsWidth) \ 849 IEM_DECL_IMPL_DEF(void, iemAImpl_ ## a_Mnemonic ## _u ## a_cBitsWidth ## _locked,(uint ## a_cBitsWidth ## _t *puDst, \ 850 uint ## a_cBitsWidth ## _t uSrc, \ 851 uint32_t *pfEFlags)) \ 852 { \ 853 DO_LOCKED_BIN_OP(a_Mnemonic, a_cBitsWidth); \ 854 } 855 856 EMIT_LOCKED_BIN_OP(add, 64) 857 EMIT_LOCKED_BIN_OP(adc, 64) 858 EMIT_LOCKED_BIN_OP(sub, 64) 859 EMIT_LOCKED_BIN_OP(sbb, 64) 860 EMIT_LOCKED_BIN_OP(or, 64) 861 EMIT_LOCKED_BIN_OP(xor, 64) 862 EMIT_LOCKED_BIN_OP(and, 64) 863 # if !defined(RT_ARCH_X86) || defined(IEM_WITHOUT_ASSEMBLY) 864 EMIT_LOCKED_BIN_OP(add, 32) 865 EMIT_LOCKED_BIN_OP(adc, 32) 866 EMIT_LOCKED_BIN_OP(sub, 32) 867 EMIT_LOCKED_BIN_OP(sbb, 32) 868 EMIT_LOCKED_BIN_OP(or, 32) 869 EMIT_LOCKED_BIN_OP(xor, 32) 870 EMIT_LOCKED_BIN_OP(and, 32) 871 872 EMIT_LOCKED_BIN_OP(add, 16) 873 EMIT_LOCKED_BIN_OP(adc, 16) 874 EMIT_LOCKED_BIN_OP(sub, 16) 875 EMIT_LOCKED_BIN_OP(sbb, 16) 876 EMIT_LOCKED_BIN_OP(or, 16) 877 EMIT_LOCKED_BIN_OP(xor, 16) 878 EMIT_LOCKED_BIN_OP(and, 16) 879 880 EMIT_LOCKED_BIN_OP(add, 8) 881 EMIT_LOCKED_BIN_OP(adc, 8) 882 EMIT_LOCKED_BIN_OP(sub, 8) 883 EMIT_LOCKED_BIN_OP(sbb, 8) 884 EMIT_LOCKED_BIN_OP(or, 8) 885 EMIT_LOCKED_BIN_OP(xor, 8) 886 EMIT_LOCKED_BIN_OP(and, 8) 887 # endif /* !defined(RT_ARCH_X86) || defined(IEM_WITHOUT_ASSEMBLY) */ 888 889 890 /* 891 * Bit operations (same signature as above). 892 */ 893 894 /* 895 * BT 896 */ 596 897 597 898 IEM_DECL_IMPL_DEF(void, iemAImpl_bt_u64,(uint64_t *puDst, uint64_t uSrc, uint32_t *pfEFlags)) … … 607 908 } 608 909 910 # if !defined(RT_ARCH_X86) || defined(IEM_WITHOUT_ASSEMBLY) 911 912 IEM_DECL_IMPL_DEF(void, iemAImpl_bt_u32,(uint32_t *puDst, uint32_t uSrc, uint32_t *pfEFlags)) 913 { 914 /* Note! "undefined" flags: OF, SF, ZF, AF, PF. We set them as after an 915 logical operation (AND/OR/whatever). */ 916 Assert(uSrc < 32); 917 uint32_t uDst = *puDst; 918 if (uDst & RT_BIT_32(uSrc)) 919 IEM_EFL_UPDATE_STATUS_BITS_FOR_LOGIC(pfEFlags, uDst, 32, X86_EFL_CF); 920 else 921 IEM_EFL_UPDATE_STATUS_BITS_FOR_LOGIC(pfEFlags, uDst, 32, 0); 922 } 923 924 IEM_DECL_IMPL_DEF(void, iemAImpl_bt_u16,(uint16_t *puDst, uint16_t uSrc, uint32_t *pfEFlags)) 925 { 926 /* Note! "undefined" flags: OF, SF, ZF, AF, PF. We set them as after an 927 logical operation (AND/OR/whatever). */ 928 Assert(uSrc < 16); 929 uint16_t uDst = *puDst; 930 if (uDst & RT_BIT_32(uSrc)) 931 IEM_EFL_UPDATE_STATUS_BITS_FOR_LOGIC(pfEFlags, uDst, 16, X86_EFL_CF); 932 else 933 IEM_EFL_UPDATE_STATUS_BITS_FOR_LOGIC(pfEFlags, uDst, 16, 0); 934 } 935 936 # endif /* !defined(RT_ARCH_X86) || defined(IEM_WITHOUT_ASSEMBLY) */ 937 938 /* 939 * BTC 940 */ 941 609 942 IEM_DECL_IMPL_DEF(void, iemAImpl_btc_u64,(uint64_t *puDst, uint64_t uSrc, uint32_t *pfEFlags)) 610 943 { … … 628 961 } 629 962 963 # if !defined(RT_ARCH_X86) || defined(IEM_WITHOUT_ASSEMBLY) 964 965 IEM_DECL_IMPL_DEF(void, iemAImpl_btc_u32,(uint32_t *puDst, uint32_t uSrc, uint32_t *pfEFlags)) 966 { 967 /* Note! "undefined" flags: OF, SF, ZF, AF, PF. We set them as after an 968 logical operation (AND/OR/whatever). */ 969 Assert(uSrc < 32); 970 uint32_t fMask = RT_BIT_32(uSrc); 971 uint32_t uDst = *puDst; 972 if (uDst & fMask) 973 { 974 uDst &= ~fMask; 975 *puDst = uDst; 976 IEM_EFL_UPDATE_STATUS_BITS_FOR_LOGIC(pfEFlags, uDst, 32, X86_EFL_CF); 977 } 978 else 979 { 980 uDst |= fMask; 981 *puDst = uDst; 982 IEM_EFL_UPDATE_STATUS_BITS_FOR_LOGIC(pfEFlags, uDst, 32, 0); 983 } 984 } 985 986 987 IEM_DECL_IMPL_DEF(void, iemAImpl_btc_u16,(uint16_t *puDst, uint16_t uSrc, uint32_t *pfEFlags)) 988 { 989 /* Note! "undefined" flags: OF, SF, ZF, AF, PF. We set them as after an 990 logical operation (AND/OR/whatever). */ 991 Assert(uSrc < 16); 992 uint16_t fMask = RT_BIT_32(uSrc); 993 uint16_t uDst = *puDst; 994 if (uDst & fMask) 995 { 996 uDst &= ~fMask; 997 *puDst = uDst; 998 IEM_EFL_UPDATE_STATUS_BITS_FOR_LOGIC(pfEFlags, uDst, 16, X86_EFL_CF); 999 } 1000 else 1001 { 1002 uDst |= fMask; 1003 *puDst = uDst; 1004 IEM_EFL_UPDATE_STATUS_BITS_FOR_LOGIC(pfEFlags, uDst, 16, 0); 1005 } 1006 } 1007 1008 # endif /* !defined(RT_ARCH_X86) || defined(IEM_WITHOUT_ASSEMBLY) */ 1009 1010 /* 1011 * BTR 1012 */ 1013 630 1014 IEM_DECL_IMPL_DEF(void, iemAImpl_btr_u64,(uint64_t *puDst, uint64_t uSrc, uint32_t *pfEFlags)) 631 1015 { … … 644 1028 IEM_EFL_UPDATE_STATUS_BITS_FOR_LOGIC(pfEFlags, uDst, 64, 0); 645 1029 } 1030 1031 # if !defined(RT_ARCH_X86) || defined(IEM_WITHOUT_ASSEMBLY) 1032 1033 IEM_DECL_IMPL_DEF(void, iemAImpl_btr_u32,(uint32_t *puDst, uint32_t uSrc, uint32_t *pfEFlags)) 1034 { 1035 /* Note! "undefined" flags: OF, SF, ZF, AF, PF. We set them as after an 1036 logical operation (AND/OR/whatever). */ 1037 Assert(uSrc < 32); 1038 uint32_t fMask = RT_BIT_32(uSrc); 1039 uint32_t uDst = *puDst; 1040 if (uDst & fMask) 1041 { 1042 uDst &= ~fMask; 1043 *puDst = uDst; 1044 IEM_EFL_UPDATE_STATUS_BITS_FOR_LOGIC(pfEFlags, uDst, 32, X86_EFL_CF); 1045 } 1046 else 1047 IEM_EFL_UPDATE_STATUS_BITS_FOR_LOGIC(pfEFlags, uDst, 32, 0); 1048 } 1049 1050 1051 IEM_DECL_IMPL_DEF(void, iemAImpl_btr_u16,(uint16_t *puDst, uint16_t uSrc, uint32_t *pfEFlags)) 1052 { 1053 /* Note! "undefined" flags: OF, SF, ZF, AF, PF. We set them as after an 1054 logical operation (AND/OR/whatever). */ 1055 Assert(uSrc < 16); 1056 uint16_t fMask = RT_BIT_32(uSrc); 1057 uint16_t uDst = *puDst; 1058 if (uDst & fMask) 1059 { 1060 uDst &= ~fMask; 1061 *puDst = uDst; 1062 IEM_EFL_UPDATE_STATUS_BITS_FOR_LOGIC(pfEFlags, uDst, 16, X86_EFL_CF); 1063 } 1064 else 1065 IEM_EFL_UPDATE_STATUS_BITS_FOR_LOGIC(pfEFlags, uDst, 16, 0); 1066 } 1067 1068 # endif /* !defined(RT_ARCH_X86) || defined(IEM_WITHOUT_ASSEMBLY) */ 1069 1070 /* 1071 * BTS 1072 */ 646 1073 647 1074 IEM_DECL_IMPL_DEF(void, iemAImpl_bts_u64,(uint64_t *puDst, uint64_t uSrc, uint32_t *pfEFlags)) … … 662 1089 } 663 1090 664 665 IEM_DECL_IMPL_DEF(void, iemAImpl_btc_u64_locked,(uint64_t *puDst, uint64_t uSrc, uint32_t *pfEFlags)) 666 { 667 DO_LOCKED_BIN_OP_U64(btc); 668 } 669 670 IEM_DECL_IMPL_DEF(void, iemAImpl_btr_u64_locked,(uint64_t *puDst, uint64_t uSrc, uint32_t *pfEFlags)) 671 { 672 DO_LOCKED_BIN_OP_U64(btr); 673 } 674 675 IEM_DECL_IMPL_DEF(void, iemAImpl_bts_u64_locked,(uint64_t *puDst, uint64_t uSrc, uint32_t *pfEFlags)) 676 { 677 DO_LOCKED_BIN_OP_U64(bts); 678 } 1091 # if !defined(RT_ARCH_X86) || defined(IEM_WITHOUT_ASSEMBLY) 1092 1093 IEM_DECL_IMPL_DEF(void, iemAImpl_bts_u32,(uint32_t *puDst, uint32_t uSrc, uint32_t *pfEFlags)) 1094 { 1095 /* Note! "undefined" flags: OF, SF, ZF, AF, PF. We set them as after an 1096 logical operation (AND/OR/whatever). */ 1097 Assert(uSrc < 32); 1098 uint32_t fMask = RT_BIT_32(uSrc); 1099 uint32_t uDst = *puDst; 1100 if (uDst & fMask) 1101 IEM_EFL_UPDATE_STATUS_BITS_FOR_LOGIC(pfEFlags, uDst, 32, X86_EFL_CF); 1102 else 1103 { 1104 uDst |= fMask; 1105 *puDst = uDst; 1106 IEM_EFL_UPDATE_STATUS_BITS_FOR_LOGIC(pfEFlags, uDst, 32, 0); 1107 } 1108 } 1109 1110 1111 IEM_DECL_IMPL_DEF(void, iemAImpl_bts_u16,(uint16_t *puDst, uint16_t uSrc, uint32_t *pfEFlags)) 1112 { 1113 /* Note! "undefined" flags: OF, SF, ZF, AF, PF. We set them as after an 1114 logical operation (AND/OR/whatever). */ 1115 Assert(uSrc < 16); 1116 uint16_t fMask = RT_BIT_32(uSrc); 1117 uint32_t uDst = *puDst; 1118 if (uDst & fMask) 1119 IEM_EFL_UPDATE_STATUS_BITS_FOR_LOGIC(pfEFlags, uDst, 32, X86_EFL_CF); 1120 else 1121 { 1122 uDst |= fMask; 1123 *puDst = uDst; 1124 IEM_EFL_UPDATE_STATUS_BITS_FOR_LOGIC(pfEFlags, uDst, 32, 0); 1125 } 1126 } 1127 1128 # endif /* !defined(RT_ARCH_X86) || defined(IEM_WITHOUT_ASSEMBLY) */ 1129 1130 1131 EMIT_LOCKED_BIN_OP(btc, 64) 1132 EMIT_LOCKED_BIN_OP(btr, 64) 1133 EMIT_LOCKED_BIN_OP(bts, 64) 1134 # if !defined(RT_ARCH_X86) || defined(IEM_WITHOUT_ASSEMBLY) 1135 EMIT_LOCKED_BIN_OP(btc, 32) 1136 EMIT_LOCKED_BIN_OP(btr, 32) 1137 EMIT_LOCKED_BIN_OP(bts, 32) 1138 1139 EMIT_LOCKED_BIN_OP(btc, 16) 1140 EMIT_LOCKED_BIN_OP(btr, 16) 1141 EMIT_LOCKED_BIN_OP(bts, 16) 1142 # endif /* !defined(RT_ARCH_X86) || defined(IEM_WITHOUT_ASSEMBLY) */ 679 1143 680 1144 … … 1132 1596 1133 1597 1134 #endif /* !RT_ARCH_AMD64 */ 1135 #ifndef RT_ARCH_AMD64 1598 /* 1599 * XADD and LOCK XADD. 1600 */ 1601 1602 IEM_DECL_IMPL_DEF(void, iemAImpl_xadd_u64,(uint64_t *puDst, uint64_t *puReg, uint32_t *pfEFlags)) 1603 { 1604 uint64_t uDst = *puDst; 1605 uint64_t uResult = uDst; 1606 iemAImpl_add_u64(&uResult, *puReg, pfEFlags); 1607 *puDst = uResult; 1608 *puReg = uDst; 1609 } 1610 1611 1612 IEM_DECL_IMPL_DEF(void, iemAImpl_xadd_u64_locked,(uint64_t *puDst, uint64_t *puReg, uint32_t *pfEFlags)) 1613 { 1614 uint64_t uOld = ASMAtomicUoReadU64(puDst); 1615 uint64_t uTmpDst; 1616 uint32_t fEflTmp; 1617 do 1618 { 1619 uTmpDst = uOld; 1620 fEflTmp = *pfEFlags; 1621 iemAImpl_add_u64(&uTmpDst, *puReg, pfEFlags); 1622 } while (!ASMAtomicCmpXchgExU64(puDst, uTmpDst, uOld, &uOld)); 1623 *puReg = uOld; 1624 *pfEFlags = fEflTmp; 1625 } 1626 1627 # if !defined(RT_ARCH_X86) || defined(IEM_WITHOUT_ASSEMBLY) 1628 1629 IEM_DECL_IMPL_DEF(void, iemAImpl_xadd_u32,(uint32_t *puDst, uint32_t *puReg, uint32_t *pfEFlags)) 1630 { 1631 uint32_t uDst = *puDst; 1632 uint32_t uResult = uDst; 1633 iemAImpl_add_u32(&uResult, *puReg, pfEFlags); 1634 *puDst = uResult; 1635 *puReg = uDst; 1636 } 1637 1638 1639 IEM_DECL_IMPL_DEF(void, iemAImpl_xadd_u32_locked,(uint32_t *puDst, uint32_t *puReg, uint32_t *pfEFlags)) 1640 { 1641 uint32_t uOld = ASMAtomicUoReadU32(puDst); 1642 uint32_t uTmpDst; 1643 uint32_t fEflTmp; 1644 do 1645 { 1646 uTmpDst = uOld; 1647 fEflTmp = *pfEFlags; 1648 iemAImpl_add_u32(&uTmpDst, *puReg, pfEFlags); 1649 } while (!ASMAtomicCmpXchgExU32(puDst, uTmpDst, uOld, &uOld)); 1650 *puReg = uOld; 1651 *pfEFlags = fEflTmp; 1652 } 1653 1654 1655 IEM_DECL_IMPL_DEF(void, iemAImpl_xadd_u16,(uint16_t *puDst, uint16_t *puReg, uint32_t *pfEFlags)) 1656 { 1657 uint16_t uDst = *puDst; 1658 uint16_t uResult = uDst; 1659 iemAImpl_add_u16(&uResult, *puReg, pfEFlags); 1660 *puDst = uResult; 1661 *puReg = uDst; 1662 } 1663 1664 1665 IEM_DECL_IMPL_DEF(void, iemAImpl_xadd_u16_locked,(uint16_t *puDst, uint16_t *puReg, uint32_t *pfEFlags)) 1666 { 1667 uint16_t uOld = ASMAtomicUoReadU16(puDst); 1668 uint16_t uTmpDst; 1669 uint32_t fEflTmp; 1670 do 1671 { 1672 uTmpDst = uOld; 1673 fEflTmp = *pfEFlags; 1674 iemAImpl_add_u16(&uTmpDst, *puReg, pfEFlags); 1675 } while (!ASMAtomicCmpXchgExU16(puDst, uTmpDst, uOld, &uOld)); 1676 *puReg = uOld; 1677 *pfEFlags = fEflTmp; 1678 } 1679 1680 1681 IEM_DECL_IMPL_DEF(void, iemAImpl_xadd_u8,(uint8_t *puDst, uint8_t *puReg, uint32_t *pfEFlags)) 1682 { 1683 uint8_t uDst = *puDst; 1684 uint8_t uResult = uDst; 1685 iemAImpl_add_u8(&uResult, *puReg, pfEFlags); 1686 *puDst = uResult; 1687 *puReg = uDst; 1688 } 1689 1690 1691 IEM_DECL_IMPL_DEF(void, iemAImpl_xadd_u8_locked,(uint8_t *puDst, uint8_t *puReg, uint32_t *pfEFlags)) 1692 { 1693 uint8_t uOld = ASMAtomicUoReadU8(puDst); 1694 uint8_t uTmpDst; 1695 uint32_t fEflTmp; 1696 do 1697 { 1698 uTmpDst = uOld; 1699 fEflTmp = *pfEFlags; 1700 iemAImpl_add_u8(&uTmpDst, *puReg, pfEFlags); 1701 } while (!ASMAtomicCmpXchgExU8(puDst, uTmpDst, uOld, &uOld)); 1702 *puReg = uOld; 1703 *pfEFlags = fEflTmp; 1704 } 1705 1706 # endif 1707 1708 1709 #endif /* !RT_ARCH_AMD64 || IEM_WITHOUT_ASSEMBLY */ 1710 #if !defined(RT_ARCH_AMD64) || defined(IEM_WITHOUT_ASSEMBLY) 1136 1711 1137 1712 /* multiplication and division */ … … 1337 1912 1338 1913 1339 #endif /* !RT_ARCH_AMD64 */1914 #endif /* !RT_ARCH_AMD64 || IEM_WITHOUT_ASSEMBLY */ 1340 1915 1341 1916
Note:
See TracChangeset
for help on using the changeset viewer.