Changeset 98812 in vbox for trunk/src/VBox/VMM/VMMAll
- Timestamp:
- Mar 1, 2023 7:55:18 PM (2 years ago)
- svn:sync-xref-src-repo-rev:
- 156132
- Location:
- trunk/src/VBox/VMM/VMMAll
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/IEMAllAImplC.cpp
r98781 r98812 16469 16469 * [V]PCMPISTRI 16470 16470 */ 16471 16472 /** 16473 * Does the comparisons based on the mode and source input format. 16474 */ 16475 static void iemAImpl_pcmpxstrx_cmp(bool afCmpRes[16][16], PCRTUINT128U puSrc1, PCRTUINT128U puSrc2, uint8_t bImm) 16476 { 16477 #define PCMPXSTRX_CMP_CASE(a_fCmpRes, a_puSrc1, a_puSrc2, a_SrcMember, a_bAggOp) \ 16478 do \ 16479 { \ 16480 for (uint8_t idxSrc2 = 0; idxSrc2 < RT_ELEMENTS((a_puSrc2)->a_SrcMember); idxSrc2++) \ 16481 for (uint8_t idxSrc1 = 0; idxSrc1 < RT_ELEMENTS((a_puSrc1)->a_SrcMember); idxSrc1 += 2) \ 16482 { \ 16483 switch (a_bAggOp) \ 16484 { \ 16485 case 0: \ 16486 case 2: \ 16487 case 3: \ 16488 afCmpRes[idxSrc2][idxSrc1] = (a_puSrc1)->a_SrcMember[idxSrc1] == (a_puSrc2)->a_SrcMember[idxSrc2]; \ 16489 afCmpRes[idxSrc2][idxSrc1 + 1] = (a_puSrc1)->a_SrcMember[idxSrc1 + 1] == (a_puSrc2)->a_SrcMember[idxSrc2 + 1]; \ 16490 break; \ 16491 case 1: \ 16492 afCmpRes[idxSrc2][idxSrc1] = (a_puSrc1)->a_SrcMember[idxSrc1] >= (a_puSrc2)->a_SrcMember[idxSrc2]; \ 16493 afCmpRes[idxSrc2][idxSrc1 + 1] = (a_puSrc1)->a_SrcMember[idxSrc1 + 1] <= (a_puSrc2)->a_SrcMember[idxSrc2 + 1]; \ 16494 break; \ 16495 default: \ 16496 AssertReleaseFailed(); \ 16497 } \ 16498 } \ 16499 } while(0) 16500 16501 uint8_t bAggOp = (bImm >> 2) & 0x3; 16502 switch (bImm & 0x3) 16503 { 16504 case 0: 16505 PCMPXSTRX_CMP_CASE(afCmpRes, puSrc1, puSrc2, au8, bAggOp); 16506 break; 16507 case 1: 16508 PCMPXSTRX_CMP_CASE(afCmpRes, puSrc1, puSrc2, au16, bAggOp); 16509 break; 16510 case 2: 16511 PCMPXSTRX_CMP_CASE(afCmpRes, puSrc1, puSrc2, ai8, bAggOp); 16512 break; 16513 case 3: 16514 PCMPXSTRX_CMP_CASE(afCmpRes, puSrc1, puSrc2, ai16, bAggOp); 16515 break; 16516 default: 16517 AssertReleaseFailed(); 16518 } 16519 #undef PCMPXSTRX_CMP_CASE 16520 } 16521 16522 static uint8_t iemAImpl_pcmpistrx_get_str_len_implicit(PCRTUINT128U puSrc, uint8_t bImm) 16523 { 16524 if (bImm & 0x1) 16525 { 16526 /* Words -> 8 elements. */ 16527 for (uint8_t i = 0; i < RT_ELEMENTS(puSrc->au16); i++) 16528 if (puSrc->au16[i] == 0) 16529 return i; 16530 16531 return 8; 16532 } 16533 else 16534 { 16535 /* Bytes -> 16 elements. */ 16536 for (uint8_t i = 0; i < RT_ELEMENTS(puSrc->au8); i++) 16537 if (puSrc->au8[i] == 0) 16538 return i; 16539 16540 return 16; 16541 } 16542 } 16543 16544 static uint8_t iemAImpl_pcmpistrx_get_str_len_explicit(int64_t i64Len, uint8_t bImm) 16545 { 16546 if (bImm & 0x1) 16547 { 16548 if (i64Len > -8 && i64Len < 8) 16549 return RT_ABS(i64Len); 16550 16551 return 8; 16552 } 16553 else 16554 { 16555 if (i64Len > -16 && i64Len < 16) 16556 return RT_ABS(i64Len); 16557 16558 return 16; 16559 } 16560 } 16561 16562 /** 16563 * Valid/Invalid override of comparisons (Table 4-7 from 4.1.6 of SDM). 16564 */ 16565 static const bool g_afCmpOverride[4][3] = 16566 { 16567 /* xmm1 AND xmm2/m128 invalid xmm1 invalid, xmm2/m128 valid xmm1 valid, xmm2/m128 invalid */ 16568 { false, false, false }, /* Imm8[3:2] = 00b (equal any) */ 16569 { false, false, false }, /* Imm8[3:2] = 01b (ranges) */ 16570 { true, false, false }, /* Imm8[3:2] = 10b (equal each) */ 16571 { true, true, false }, /* Imm8[3:2] = 11b (equal ordered) */ 16572 }; 16573 16574 DECL_FORCE_INLINE(bool) iemAImpl_pcmpxstrx_cmp_override_if_invalid(bool fCmpRes, bool fSrc1Valid, bool fSrc2Valid, uint8_t bAggOp) 16575 { 16576 if (fSrc1Valid && fSrc2Valid) 16577 return fCmpRes; 16578 16579 uint8_t bSrc1Valid = fSrc1Valid ? 2 : 0; 16580 uint8_t bSrc2Valid = fSrc2Valid ? 1 : 0; 16581 return g_afCmpOverride[bAggOp][bSrc1Valid + bSrc2Valid]; 16582 } 16583 16584 static uint16_t iemAImpl_pcmpxstrx_cmp_aggregate(bool afCmpRes[16][16], uint8_t idxLen1, uint8_t idxLen2, uint8_t bImm) 16585 { 16586 uint8_t cElems = (bImm & 0x1) ? 8 : 16; 16587 uint8_t bAggOp = (bImm >> 2) & 0x3; 16588 uint16_t u16Result = 0; 16589 16590 switch (bAggOp) 16591 { 16592 case 0: /* Equal any */ 16593 for (uint8_t idxSrc2 = 0; idxSrc2 < cElems; idxSrc2++) 16594 { 16595 uint16_t u16Res = 0; 16596 for (uint8_t idxSrc1 = 0; idxSrc1 < cElems; idxSrc1++) 16597 { 16598 if (iemAImpl_pcmpxstrx_cmp_override_if_invalid(afCmpRes[idxSrc2][idxSrc1], 16599 idxSrc1 < idxLen1, 16600 idxSrc2 < idxLen2, 16601 bAggOp)) 16602 { 16603 u16Res = RT_BIT(idxSrc2); 16604 break; 16605 } 16606 } 16607 16608 u16Result |= u16Res; 16609 } 16610 break; 16611 16612 case 1: /* Ranges */ 16613 for (uint8_t idxSrc2 = 0; idxSrc2 < cElems; idxSrc2++) 16614 { 16615 uint16_t u16Res = 0; 16616 for (uint8_t idxSrc1 = 0; idxSrc1 < cElems; idxSrc1 += 2) 16617 { 16618 if ( iemAImpl_pcmpxstrx_cmp_override_if_invalid(afCmpRes[idxSrc2][idxSrc1], 16619 idxSrc1 < idxLen1, 16620 idxSrc2 < idxLen2, 16621 bAggOp) 16622 && iemAImpl_pcmpxstrx_cmp_override_if_invalid(afCmpRes[idxSrc2][idxSrc1 + 1], 16623 (idxSrc1 + 1) < idxLen1, 16624 idxSrc2 < idxLen2, 16625 bAggOp)) 16626 { 16627 u16Res = RT_BIT(idxSrc2); 16628 break; 16629 } 16630 } 16631 16632 u16Result |= u16Res; 16633 } 16634 break; 16635 16636 case 2: /* Equal each */ 16637 for (uint8_t i = 0; i < cElems; i++) 16638 { 16639 if (iemAImpl_pcmpxstrx_cmp_override_if_invalid(afCmpRes[i][i], 16640 i < idxLen1, 16641 i < idxLen2, 16642 bAggOp)) 16643 u16Result |= RT_BIT(i); 16644 } 16645 break; 16646 16647 case 3: /* Equal ordered */ 16648 u16Result = cElems == 8 ? 0xff : 0xffff; 16649 for (uint8_t idxSrc2 = 0; idxSrc2 < cElems; idxSrc2++) 16650 { 16651 uint16_t u16Res = 0; 16652 for (uint8_t idxSrc1 = 0, k = idxSrc2; (idxSrc1 < cElems - idxSrc2) && (k < cElems); idxSrc1++, k++) 16653 { 16654 if (iemAImpl_pcmpxstrx_cmp_override_if_invalid(afCmpRes[k][idxSrc1], 16655 idxSrc1 < idxLen1, 16656 k < idxLen2, 16657 bAggOp)) 16658 { 16659 u16Res = RT_BIT(idxSrc2); 16660 break; 16661 } 16662 } 16663 16664 u16Result &= ~u16Res; 16665 } 16666 break; 16667 } 16668 16669 /* Polarity selection. */ 16670 switch ((bImm >> 4) & 0x3) 16671 { 16672 case 0: 16673 case 2: 16674 /* Nothing to do. */ 16675 break; 16676 case 1: 16677 u16Result = (cElems == 8 ? 0xff : 0xffff) ^ u16Result; 16678 break; 16679 case 3: 16680 for (uint8_t i = 0; i < cElems; i++) 16681 if (i < idxLen2) 16682 u16Result ^= RT_BIT(i); 16683 break; 16684 default: 16685 AssertReleaseFailed(); 16686 } 16687 16688 return u16Result; 16689 } 16690 16691 DECL_FORCE_INLINE(void) iemAImpl_pcmpxstrx_set_eflags(uint32_t *pfEFlags, uint16_t u16Result, uint8_t cLen1, uint8_t cLen2, uint8_t cElems) 16692 { 16693 uint32_t fEFlags = 0; 16694 16695 if (u16Result) 16696 fEFlags |= X86_EFL_CF; 16697 if (cLen2 < cElems) 16698 fEFlags |= X86_EFL_ZF; 16699 if (cLen1 < cElems) 16700 fEFlags |= X86_EFL_SF; 16701 if (u16Result & 0x1) 16702 fEFlags |= X86_EFL_OF; 16703 *pfEFlags = (*pfEFlags & ~X86_EFL_STATUS_BITS) | fEFlags; 16704 } 16705 16471 16706 IEM_DECL_IMPL_DEF(void, iemAImpl_pcmpistri_u128_fallback,(uint32_t *pu32Ecx, uint32_t *pEFlags, PCIEMPCMPISTRXSRC pSrc, uint8_t bEvil)) 16472 16707 { 16473 RT_NOREF(pu32Ecx, pEFlags, pSrc, bEvil); 16474 AssertReleaseFailed(); 16708 bool afCmpRes[16][16]; 16709 uint8_t cElems = (bEvil & RT_BIT(0)) ? 8 : 16; 16710 iemAImpl_pcmpxstrx_cmp(afCmpRes, &pSrc->uSrc1, &pSrc->uSrc2, bEvil); 16711 uint8_t cLen1 = iemAImpl_pcmpistrx_get_str_len_implicit(&pSrc->uSrc1, bEvil); 16712 uint8_t cLen2 = iemAImpl_pcmpistrx_get_str_len_implicit(&pSrc->uSrc2, bEvil); 16713 16714 uint16_t u16Result = iemAImpl_pcmpxstrx_cmp_aggregate(afCmpRes, cLen1, cLen2, bEvil); 16715 if (bEvil & RT_BIT(6)) 16716 { 16717 /* Index for MSB set. */ 16718 uint32_t idxMsb = ASMBitLastSetU16(u16Result); 16719 if (idxMsb) 16720 *pu32Ecx = idxMsb; 16721 else 16722 *pu32Ecx = cElems; 16723 } 16724 else 16725 { 16726 /* Index for LSB set. */ 16727 uint32_t idxLsb = ASMBitFirstSetU16(u16Result); 16728 if (idxLsb) 16729 *pu32Ecx = idxLsb; 16730 else 16731 *pu32Ecx = cElems; 16732 } 16733 16734 iemAImpl_pcmpxstrx_set_eflags(pEFlags, u16Result, cLen1, cLen2, cElems); 16475 16735 } 16476 16736 … … 16481 16741 IEM_DECL_IMPL_DEF(void, iemAImpl_pcmpestri_u128_fallback,(uint32_t *pu32Ecx, uint32_t *pEFlags, PCIEMPCMPESTRXSRC pSrc, uint8_t bEvil)) 16482 16742 { 16483 RT_NOREF(pu32Ecx, pEFlags, pSrc, bEvil); 16484 AssertReleaseFailed(); 16743 bool afCmpRes[16][16]; 16744 uint8_t cElems = (bEvil & RT_BIT(0)) ? 8 : 16; 16745 iemAImpl_pcmpxstrx_cmp(afCmpRes, &pSrc->uSrc1, &pSrc->uSrc2, bEvil); 16746 uint8_t cLen1 = iemAImpl_pcmpistrx_get_str_len_explicit((int64_t)pSrc->u64Rax, bEvil); 16747 uint8_t cLen2 = iemAImpl_pcmpistrx_get_str_len_explicit((int64_t)pSrc->u64Rdx, bEvil); 16748 16749 uint16_t u16Result = iemAImpl_pcmpxstrx_cmp_aggregate(afCmpRes, cLen1, cLen2, bEvil); 16750 if (bEvil & RT_BIT(6)) 16751 { 16752 /* Index for MSB set. */ 16753 uint32_t idxMsb = ASMBitLastSetU16(u16Result); 16754 if (idxMsb) 16755 *pu32Ecx = idxMsb; 16756 else 16757 *pu32Ecx = cElems; 16758 } 16759 else 16760 { 16761 /* Index for LSB set. */ 16762 uint32_t idxLsb = ASMBitFirstSetU16(u16Result); 16763 if (idxLsb) 16764 *pu32Ecx = idxLsb; 16765 else 16766 *pu32Ecx = cElems; 16767 } 16768 16769 iemAImpl_pcmpxstrx_set_eflags(pEFlags, u16Result, cLen1, cLen2, cElems); 16485 16770 } 16486 16771 … … 16491 16776 IEM_DECL_IMPL_DEF(void, iemAImpl_pcmpistrm_u128_fallback,(PRTUINT128U puDst, uint32_t *pEFlags, PCIEMPCMPISTRXSRC pSrc, uint8_t bEvil)) 16492 16777 { 16493 RT_NOREF(puDst, pEFlags, pSrc, bEvil); 16494 AssertReleaseFailed(); 16778 bool afCmpRes[16][16]; 16779 uint8_t cElems = (bEvil & RT_BIT(0)) ? 8 : 16; 16780 iemAImpl_pcmpxstrx_cmp(afCmpRes, &pSrc->uSrc1, &pSrc->uSrc2, bEvil); 16781 uint8_t cLen1 = iemAImpl_pcmpistrx_get_str_len_implicit(&pSrc->uSrc1, bEvil); 16782 uint8_t cLen2 = iemAImpl_pcmpistrx_get_str_len_implicit(&pSrc->uSrc2, bEvil); 16783 16784 uint16_t u16Result = iemAImpl_pcmpxstrx_cmp_aggregate(afCmpRes, cLen1, cLen2, bEvil); 16785 if (bEvil & RT_BIT(6)) 16786 { 16787 /* Generate a mask. */ 16788 if (cElems == 8) 16789 { 16790 for (uint8_t i = 0; i < RT_ELEMENTS(puDst->au16); i++) 16791 if (u16Result & RT_BIT(i)) 16792 puDst->au16[i] = 0xffff; 16793 else 16794 puDst->au16[i] = 0; 16795 } 16796 else 16797 { 16798 for (uint8_t i = 0; i < RT_ELEMENTS(puDst->au8); i++) 16799 if (u16Result & RT_BIT(i)) 16800 puDst->au8[i] = 0xff; 16801 else 16802 puDst->au8[i] = 0; 16803 } 16804 } 16805 else 16806 { 16807 /* Store the result. */ 16808 puDst->au64[0] = u16Result; 16809 puDst->au64[1] = 0; 16810 } 16811 16812 iemAImpl_pcmpxstrx_set_eflags(pEFlags, u16Result, cLen1, cLen2, cElems); 16495 16813 } 16496 16814 … … 16501 16819 IEM_DECL_IMPL_DEF(void, iemAImpl_pcmpestrm_u128_fallback,(PRTUINT128U puDst, uint32_t *pEFlags, PCIEMPCMPESTRXSRC pSrc, uint8_t bEvil)) 16502 16820 { 16503 RT_NOREF(puDst, pEFlags, pSrc, bEvil); 16504 AssertReleaseFailed(); 16821 bool afCmpRes[16][16]; 16822 uint8_t cElems = (bEvil & RT_BIT(0)) ? 8 : 16; 16823 iemAImpl_pcmpxstrx_cmp(afCmpRes, &pSrc->uSrc1, &pSrc->uSrc2, bEvil); 16824 uint8_t cLen1 = iemAImpl_pcmpistrx_get_str_len_explicit((int64_t)pSrc->u64Rax, bEvil); 16825 uint8_t cLen2 = iemAImpl_pcmpistrx_get_str_len_explicit((int64_t)pSrc->u64Rdx, bEvil); 16826 16827 uint16_t u16Result = iemAImpl_pcmpxstrx_cmp_aggregate(afCmpRes, cLen1, cLen2, bEvil); 16828 if (bEvil & RT_BIT(6)) 16829 { 16830 /* Generate a mask. */ 16831 if (cElems == 8) 16832 { 16833 for (uint8_t i = 0; i < RT_ELEMENTS(puDst->au16); i++) 16834 if (u16Result & RT_BIT(i)) 16835 puDst->au16[i] = 0xffff; 16836 else 16837 puDst->au16[i] = 0; 16838 } 16839 else 16840 { 16841 for (uint8_t i = 0; i < RT_ELEMENTS(puDst->au8); i++) 16842 if (u16Result & RT_BIT(i)) 16843 puDst->au8[i] = 0xff; 16844 else 16845 puDst->au8[i] = 0; 16846 } 16847 } 16848 else 16849 { 16850 /* Store the result. */ 16851 puDst->au64[0] = u16Result; 16852 puDst->au64[1] = 0; 16853 } 16854 16855 iemAImpl_pcmpxstrx_set_eflags(pEFlags, u16Result, cLen1, cLen2, cElems); 16505 16856 } 16506 16857 -
trunk/src/VBox/VMM/VMMAll/IEMAllInstructionsThree0f3a.cpp.h
r98781 r98812 1217 1217 IEM_MC_FETCH_XREG_U128(Src.uSrc1, IEM_GET_MODRM_REG(pVCpu, bRm)); 1218 1218 IEM_MC_FETCH_XREG_U128(Src.uSrc2, IEM_GET_MODRM_RM(pVCpu, bRm)); 1219 IEM_MC_FETCH_GREG_U32_ ZX_U64(Src.u64Rax, X86_GREG_xAX);1220 IEM_MC_FETCH_GREG_U32_ ZX_U64(Src.u64Rdx, X86_GREG_xDX);1219 IEM_MC_FETCH_GREG_U32_SX_U64(Src.u64Rax, X86_GREG_xAX); 1220 IEM_MC_FETCH_GREG_U32_SX_U64(Src.u64Rdx, X86_GREG_xDX); 1221 1221 IEM_MC_REF_XREG_U128(puDst, 0 /*xmm0*/); 1222 1222 IEM_MC_REF_EFLAGS(pEFlags); … … 1250 1250 IEM_MC_REF_GREG_U32(pu32Ecx, X86_GREG_xCX); 1251 1251 IEM_MC_FETCH_XREG_U128(Src.uSrc1, IEM_GET_MODRM_REG(pVCpu, bRm)); 1252 IEM_MC_FETCH_GREG_U32_ ZX_U64(Src.u64Rax, X86_GREG_xAX);1253 IEM_MC_FETCH_GREG_U32_ ZX_U64(Src.u64Rdx, X86_GREG_xDX);1252 IEM_MC_FETCH_GREG_U32_SX_U64(Src.u64Rax, X86_GREG_xAX); 1253 IEM_MC_FETCH_GREG_U32_SX_U64(Src.u64Rdx, X86_GREG_xDX); 1254 1254 IEM_MC_REF_EFLAGS(pEFlags); 1255 1255 IEM_MC_CALL_VOID_AIMPL_4(IEM_SELECT_HOST_OR_FALLBACK(fSse42, … … 1355 1355 IEM_MC_FETCH_XREG_U128(Src.uSrc1, IEM_GET_MODRM_REG(pVCpu, bRm)); 1356 1356 IEM_MC_FETCH_XREG_U128(Src.uSrc2, IEM_GET_MODRM_RM(pVCpu, bRm)); 1357 IEM_MC_FETCH_GREG_U32_ ZX_U64(Src.u64Rax, X86_GREG_xAX);1358 IEM_MC_FETCH_GREG_U32_ ZX_U64(Src.u64Rdx, X86_GREG_xDX);1357 IEM_MC_FETCH_GREG_U32_SX_U64(Src.u64Rax, X86_GREG_xAX); 1358 IEM_MC_FETCH_GREG_U32_SX_U64(Src.u64Rdx, X86_GREG_xDX); 1359 1359 IEM_MC_REF_EFLAGS(pEFlags); 1360 1360 IEM_MC_CALL_VOID_AIMPL_4(IEM_SELECT_HOST_OR_FALLBACK(fSse42, … … 1388 1388 IEM_MC_REF_GREG_U32(pu32Ecx, X86_GREG_xCX); 1389 1389 IEM_MC_FETCH_XREG_U128(Src.uSrc1, IEM_GET_MODRM_REG(pVCpu, bRm)); 1390 IEM_MC_FETCH_GREG_U32_ ZX_U64(Src.u64Rax, X86_GREG_xAX);1391 IEM_MC_FETCH_GREG_U32_ ZX_U64(Src.u64Rdx, X86_GREG_xDX);1390 IEM_MC_FETCH_GREG_U32_SX_U64(Src.u64Rax, X86_GREG_xAX); 1391 IEM_MC_FETCH_GREG_U32_SX_U64(Src.u64Rdx, X86_GREG_xDX); 1392 1392 IEM_MC_REF_EFLAGS(pEFlags); 1393 1393 IEM_MC_CALL_VOID_AIMPL_4(IEM_SELECT_HOST_OR_FALLBACK(fSse42,
Note:
See TracChangeset
for help on using the changeset viewer.