VirtualBox

Changeset 98821 in vbox


Ignore:
Timestamp:
Mar 2, 2023 3:00:34 PM (2 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
156141
Message:

VMM/IEM: Fixes and optimizations for the pcmp{i,e}str{i,m} instructions, bugref:9898

Location:
trunk/src/VBox/VMM
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMAll/IEMAllAImpl.asm

    r98781 r98821  
    53055305 %rep 256
    53065306.imm %+ bImm:
     5307       db 0x48                          ; Use the REX.W prefix to make pcmpestr{i,m} use full RAX/RDX (would use EAX/EDX only otherwise.)
    53075308       pcmpestri xmm0, xmm1, bImm
    53085309       ret
    5309        int3
    53105310  %assign bImm bImm + 1
    53115311 %endrep
     
    53645364        IEMIMPL_SSE_PROLOGUE
    53655365
    5366         push xAX
    5367         push xDX
    53685366        movdqu  xmm1, [A2 + IEMPCMPESTRXSRC.uSrc1]
    53695367        movdqu  xmm2, [A2 + IEMPCMPESTRXSRC.uSrc2]
    5370         mov     xAX,  [A2 + IEMPCMPESTRXSRC.u64Rax]
    5371         mov     xDX,  [A2 + IEMPCMPESTRXSRC.u64Rdx]
    53725368        lea     T1, [.imm0 xWrtRIP]
    53735369        lea     T0, [A3 + A3*3]         ; sizeof(insnX+ret) == 8: (A3 * 4) * 2
    53745370        lea     T1, [T1 + T0*2]
     5371        push    xDX                                     ; xDX can be A1 or A2 depending on the calling convention
     5372        mov     xAX,  [A2 + IEMPCMPESTRXSRC.u64Rax]     ; T0 is rax, so only overwrite it after we're done using it
     5373        mov     xDX,  [A2 + IEMPCMPESTRXSRC.u64Rdx]
    53755374        call    T1
    53765375
     5376        pop    xDX
    53775377        IEM_SAVE_FLAGS A1, X86_EFL_STATUS_BITS, 0
    53785378        movdqu  [A0], xmm0
    5379         pop    xDX
    5380         pop    xAX
    53815379
    53825380        IEMIMPL_SSE_EPILOGUE
     
    53855383 %rep 256
    53865384.imm %+ bImm:
     5385       db 0x48                          ; Use the REX.W prefix to make pcmpestr{i,m} use full RAX/RDX (would use EAX/EDX only otherwise.)
    53875386       pcmpestrm xmm1, xmm2, bImm
    53885387       ret
    5389        int3
    53905388  %assign bImm bImm + 1
    53915389 %endrep
  • trunk/src/VBox/VMM/VMMAll/IEMAllAImplC.cpp

    r98812 r98821  
    1648716487                    case 3: \
    1648816488                        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]; \
     16489                        afCmpRes[idxSrc2][idxSrc1 + 1] = (a_puSrc1)->a_SrcMember[idxSrc1 + 1] == (a_puSrc2)->a_SrcMember[idxSrc2]; \
    1649016490                        break; \
    1649116491                    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]; \
     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]; \
    1649416494                        break; \
    1649516495                    default: \
     
    1658216582}
    1658316583
    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;
     16584static uint16_t iemAImpl_pcmpxstrx_cmp_aggregate(bool afCmpRes[16][16], uint8_t idxLen1, uint8_t idxLen2, uint8_t cElems, uint8_t bImm)
     16585{
    1658716586    uint8_t bAggOp = (bImm >> 2) & 0x3;
    1658816587    uint16_t u16Result = 0;
     
    1664616645
    1664716646        case 3: /* Equal ordered */
    16648             u16Result = cElems == 8 ? 0xff : 0xffff;
     16647            u16Result = 0;
    1664916648            for (uint8_t idxSrc2 = 0; idxSrc2 < cElems; idxSrc2++)
    1665016649            {
    16651                 uint16_t u16Res = 0;
    16652                 for (uint8_t idxSrc1 = 0, k = idxSrc2; (idxSrc1 < cElems - idxSrc2) && (k < cElems); idxSrc1++, k++)
     16650                uint16_t u16Res = RT_BIT(idxSrc2);
     16651                for (uint8_t idxSrc1 = 0, k = idxSrc2; (idxSrc1 < (cElems - idxSrc2)) && (k < cElems); idxSrc1++, k++)
    1665316652                {
    16654                     if (iemAImpl_pcmpxstrx_cmp_override_if_invalid(afCmpRes[k][idxSrc1],
    16655                                                                    idxSrc1 < idxLen1,
    16656                                                                    k < idxLen2,
    16657                                                                    bAggOp))
     16653                    if (!iemAImpl_pcmpxstrx_cmp_override_if_invalid(afCmpRes[k][idxSrc1],
     16654                                                                    idxSrc1 < idxLen1,
     16655                                                                    k < idxLen2,
     16656                                                                    bAggOp))
    1665816657                    {
    16659                         u16Res = RT_BIT(idxSrc2);
     16658                        u16Res = 0;
    1666016659                        break;
    1666116660                    }
    1666216661                }
    1666316662
    16664                 u16Result &= ~u16Res;
     16663                u16Result |= u16Res;
    1666516664            }
    1666616665            break;
     
    1667816677            break;
    1667916678        case 3:
    16680             for (uint8_t i = 0; i < cElems; i++)
    16681                 if (i < idxLen2)
    16682                     u16Result ^= RT_BIT(i);
     16679            u16Result ^= RT_BIT(idxLen2) - 1;
    1668316680            break;
    1668416681        default:
     
    1670416701}
    1670516702
    16706 IEM_DECL_IMPL_DEF(void, iemAImpl_pcmpistri_u128_fallback,(uint32_t *pu32Ecx, uint32_t *pEFlags, PCIEMPCMPISTRXSRC pSrc, uint8_t bEvil))
     16703DECL_FORCE_INLINE(uint16_t) iemAImpl_pcmpxstrx_worker(uint32_t *pEFlags, PCRTUINT128U puSrc1, PCRTUINT128U puSrc2,
     16704                                                      uint8_t cLen1, uint8_t cLen2, uint8_t bEvil)
    1670716705{
    1670816706    bool afCmpRes[16][16];
    1670916707    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))
     16708
     16709    iemAImpl_pcmpxstrx_cmp(afCmpRes, puSrc1, puSrc2, bEvil);
     16710    uint16_t u16Result = iemAImpl_pcmpxstrx_cmp_aggregate(afCmpRes, cLen1, cLen2, cElems, bEvil);
     16711    iemAImpl_pcmpxstrx_set_eflags(pEFlags, u16Result, cLen1, cLen2, cElems);
     16712
     16713    return u16Result;
     16714}
     16715
     16716DECL_FORCE_INLINE(void) iemAImpl_pcmpxstri_set_result_index(uint32_t *pu32Ecx, uint16_t u16Result, uint8_t cElems, uint8_t bImm)
     16717{
     16718    if (bImm & RT_BIT(6))
    1671616719    {
    1671716720        /* Index for MSB set. */
    1671816721        uint32_t idxMsb = ASMBitLastSetU16(u16Result);
    1671916722        if (idxMsb)
    16720             *pu32Ecx = idxMsb;
     16723            *pu32Ecx = idxMsb - 1;
    1672116724        else
    1672216725            *pu32Ecx = cElems;
     
    1672716730        uint32_t idxLsb = ASMBitFirstSetU16(u16Result);
    1672816731        if (idxLsb)
    16729             *pu32Ecx = idxLsb;
     16732            *pu32Ecx = idxLsb - 1;
    1673016733        else
    1673116734            *pu32Ecx = cElems;
    1673216735    }
    16733 
    16734     iemAImpl_pcmpxstrx_set_eflags(pEFlags, u16Result, cLen1, cLen2, cElems);
     16736}
     16737
     16738IEM_DECL_IMPL_DEF(void, iemAImpl_pcmpistri_u128_fallback,(uint32_t *pu32Ecx, uint32_t *pEFlags, PCIEMPCMPISTRXSRC pSrc, uint8_t bEvil))
     16739{
     16740    uint8_t cElems = (bEvil & RT_BIT(0)) ? 8 : 16;
     16741    uint8_t cLen1 = iemAImpl_pcmpistrx_get_str_len_implicit(&pSrc->uSrc1, bEvil);
     16742    uint8_t cLen2 = iemAImpl_pcmpistrx_get_str_len_implicit(&pSrc->uSrc2, bEvil);
     16743
     16744    uint16_t u16Result = iemAImpl_pcmpxstrx_worker(pEFlags, &pSrc->uSrc1, &pSrc->uSrc2, cLen1, cLen2, bEvil);
     16745    iemAImpl_pcmpxstri_set_result_index(pu32Ecx, u16Result, cElems, bEvil);
    1673516746}
    1673616747
     
    1674116752IEM_DECL_IMPL_DEF(void, iemAImpl_pcmpestri_u128_fallback,(uint32_t *pu32Ecx, uint32_t *pEFlags, PCIEMPCMPESTRXSRC pSrc, uint8_t bEvil))
    1674216753{
    16743     bool afCmpRes[16][16];
    1674416754    uint8_t cElems = (bEvil & RT_BIT(0)) ? 8 : 16;
    16745     iemAImpl_pcmpxstrx_cmp(afCmpRes, &pSrc->uSrc1, &pSrc->uSrc2, bEvil);
    1674616755    uint8_t cLen1 = iemAImpl_pcmpistrx_get_str_len_explicit((int64_t)pSrc->u64Rax, bEvil);
    1674716756    uint8_t cLen2 = iemAImpl_pcmpistrx_get_str_len_explicit((int64_t)pSrc->u64Rdx, bEvil);
    1674816757
    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);
     16758    uint16_t u16Result = iemAImpl_pcmpxstrx_worker(pEFlags, &pSrc->uSrc1, &pSrc->uSrc2, cLen1, cLen2, bEvil);
     16759    iemAImpl_pcmpxstri_set_result_index(pu32Ecx, u16Result, cElems, bEvil);
    1677016760}
    1677116761
     
    1677416764 * [V]PCMPISTRM
    1677516765 */
    16776 IEM_DECL_IMPL_DEF(void, iemAImpl_pcmpistrm_u128_fallback,(PRTUINT128U puDst, uint32_t *pEFlags, PCIEMPCMPISTRXSRC pSrc, uint8_t bEvil))
    16777 {
    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))
     16766DECL_FORCE_INLINE(void) iemAImpl_pcmpxstrm_set_result_mask(PRTUINT128U puDst, uint16_t u16Result, uint8_t cElems, uint8_t bImm)
     16767{
     16768    if (bImm & RT_BIT(6))
    1678616769    {
    1678716770        /* Generate a mask. */
     
    1680916792        puDst->au64[1] = 0;
    1681016793    }
    16811 
    16812     iemAImpl_pcmpxstrx_set_eflags(pEFlags, u16Result, cLen1, cLen2, cElems);
     16794}
     16795
     16796IEM_DECL_IMPL_DEF(void, iemAImpl_pcmpistrm_u128_fallback,(PRTUINT128U puDst, uint32_t *pEFlags, PCIEMPCMPISTRXSRC pSrc, uint8_t bEvil))
     16797{
     16798    uint8_t cElems = (bEvil & RT_BIT(0)) ? 8 : 16;
     16799    uint8_t cLen1 = iemAImpl_pcmpistrx_get_str_len_implicit(&pSrc->uSrc1, bEvil);
     16800    uint8_t cLen2 = iemAImpl_pcmpistrx_get_str_len_implicit(&pSrc->uSrc2, bEvil);
     16801
     16802    uint16_t u16Result = iemAImpl_pcmpxstrx_worker(pEFlags, &pSrc->uSrc1, &pSrc->uSrc2, cLen1, cLen2, bEvil);
     16803    iemAImpl_pcmpxstrm_set_result_mask(puDst, u16Result, cElems, bEvil);
    1681316804}
    1681416805
     
    1681916810IEM_DECL_IMPL_DEF(void, iemAImpl_pcmpestrm_u128_fallback,(PRTUINT128U puDst, uint32_t *pEFlags, PCIEMPCMPESTRXSRC pSrc, uint8_t bEvil))
    1682016811{
    16821     bool afCmpRes[16][16];
    1682216812    uint8_t cElems = (bEvil & RT_BIT(0)) ? 8 : 16;
    16823     iemAImpl_pcmpxstrx_cmp(afCmpRes, &pSrc->uSrc1, &pSrc->uSrc2, bEvil);
    1682416813    uint8_t cLen1 = iemAImpl_pcmpistrx_get_str_len_explicit((int64_t)pSrc->u64Rax, bEvil);
    1682516814    uint8_t cLen2 = iemAImpl_pcmpistrx_get_str_len_explicit((int64_t)pSrc->u64Rdx, bEvil);
    1682616815
    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);
     16816    uint16_t u16Result = iemAImpl_pcmpxstrx_worker(pEFlags, &pSrc->uSrc1, &pSrc->uSrc2, cLen1, cLen2, bEvil);
     16817    iemAImpl_pcmpxstrm_set_result_mask(puDst, u16Result, cElems, bEvil);
    1685616818}
    1685716819
  • trunk/src/VBox/VMM/include/IEMInternal.h

    r98797 r98821  
    24052405typedef const IEMPCMPESTRXSRC *PCIEMPCMPESTRXSRC;
    24062406
    2407 IEM_DECL_IMPL_DEF(void, iemAImpl_pcmpistri_u128,(uint32_t *pu32Ecx, uint32_t *pEFlags, PCIEMPCMPISTRXSRC pSrc, uint8_t bEvil));
    2408 IEM_DECL_IMPL_DEF(void, iemAImpl_pcmpistri_u128_fallback,(uint32_t *pu32Ecx, uint32_t *pEFlags, PCIEMPCMPISTRXSRC pSrc, uint8_t bEvil));
    2409 IEM_DECL_IMPL_DEF(void, iemAImpl_pcmpestri_u128,(uint32_t *pu32Ecx, uint32_t *pEFlags, PCIEMPCMPESTRXSRC pSrc, uint8_t bEvil));
    2410 IEM_DECL_IMPL_DEF(void, iemAImpl_pcmpestri_u128_fallback,(uint32_t *pu32Ecx, uint32_t *pEFlags, PCIEMPCMPESTRXSRC pSrc, uint8_t bEvil));
    2411 
    2412 IEM_DECL_IMPL_DEF(void, iemAImpl_pcmpistrm_u128,(PRTUINT128U puDst, uint32_t *pEFlags, PCIEMPCMPISTRXSRC pSrc, uint8_t bEvil));
    2413 IEM_DECL_IMPL_DEF(void, iemAImpl_pcmpistrm_u128_fallback,(PRTUINT128U puDst, uint32_t *pEFlags, PCIEMPCMPISTRXSRC pSrc, uint8_t bEvil));
    2414 IEM_DECL_IMPL_DEF(void, iemAImpl_pcmpestrm_u128,(PRTUINT128U puDst, uint32_t *pEFlags, PCIEMPCMPESTRXSRC pSrc, uint8_t bEvil));
    2415 IEM_DECL_IMPL_DEF(void, iemAImpl_pcmpestrm_u128_fallback,(PRTUINT128U puDst, uint32_t *pEFlags, PCIEMPCMPESTRXSRC pSrc, uint8_t bEvil));
     2407typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLPCMPISTRIU128IMM8,(uint32_t *pu32Ecx, uint32_t *pEFlags, PCIEMPCMPISTRXSRC pSrc, uint8_t bEvil));
     2408typedef FNIEMAIMPLPCMPISTRIU128IMM8 *PFNIEMAIMPLPCMPISTRIU128IMM8;
     2409typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLPCMPESTRIU128IMM8,(uint32_t *pu32Ecx, uint32_t *pEFlags, PCIEMPCMPESTRXSRC pSrc, uint8_t bEvil));
     2410typedef FNIEMAIMPLPCMPESTRIU128IMM8 *PFNIEMAIMPLPCMPESTRIU128IMM8;
     2411
     2412typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLPCMPISTRMU128IMM8,(PRTUINT128U puDst, uint32_t *pEFlags, PCIEMPCMPISTRXSRC pSrc, uint8_t bEvil));
     2413typedef FNIEMAIMPLPCMPISTRMU128IMM8 *PFNIEMAIMPLPCMPISTRMU128IMM8;
     2414typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLPCMPESTRMU128IMM8,(PRTUINT128U puDst, uint32_t *pEFlags, PCIEMPCMPESTRXSRC pSrc, uint8_t bEvil));
     2415typedef FNIEMAIMPLPCMPESTRMU128IMM8 *PFNIEMAIMPLPCMPESTRMU128IMM8;
     2416
     2417FNIEMAIMPLPCMPISTRIU128IMM8 iemAImpl_pcmpistri_u128, iemAImpl_pcmpistri_u128_fallback;
     2418FNIEMAIMPLPCMPESTRIU128IMM8 iemAImpl_pcmpestri_u128, iemAImpl_pcmpestri_u128_fallback;
     2419FNIEMAIMPLPCMPISTRMU128IMM8 iemAImpl_pcmpistrm_u128, iemAImpl_pcmpistrm_u128_fallback;
     2420FNIEMAIMPLPCMPESTRMU128IMM8 iemAImpl_pcmpestrm_u128, iemAImpl_pcmpestrm_u128_fallback;
    24162421
    24172422FNIEMAIMPLMEDIAOPTF2U128IMM8 iemAImpl_pclmulqdq_u128, iemAImpl_pclmulqdq_u128_fallback;
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette