VirtualBox

Changeset 104269 in vbox


Ignore:
Timestamp:
Apr 10, 2024 9:42:20 AM (10 months ago)
Author:
vboxsync
Message:

VMM/IEM: Rework pcmpistri emulation to pass the new ECX value as return argument freeing up one argument which can be used to pass both source operands by reference getting rid of IEMPCMPISTRXSRC for this. This enables recompilation of pcmpistri which is used by Linux a fair bit, bugref:10641

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

Legend:

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

    r104268 r104269  
    59575957; The pcmpistri instruction.
    59585958;
    5959 ; @param    A0      Pointer to the ECX register to store the result to (output).
    5960 ; @param    A1      Pointer to the EFLAGS register.
    5961 ; @param    A2      Pointer to the structure containing the source operands (input).
     5959; @return   R0_32   The new ECX value.
     5960; @param    A0      Pointer to the EFLAGS register.
     5961; @param    A1      Pointer to the first operand (input).
     5962; @param    A1      Pointer to the second operand (input).
    59625963; @param    A3      The 8-bit immediate
    59635964;
     
    59675968
    59685969        movzx   A3, A3_8                ; must clear top bits
    5969         movdqu  xmm0, [A2 + IEMPCMPISTRXSRC.uSrc1]
    5970         movdqu  xmm1, [A2 + IEMPCMPISTRXSRC.uSrc2]
     5970        movdqu  xmm0, [A1]
     5971        movdqu  xmm1, [A2]
    59715972        mov     T2, A0                  ; A0 can be ecx/rcx in some calling conventions which gets overwritten later (T2 only available on AMD64)
    59725973        IEMIMPL_CALL_JUMP_TABLE_TARGET T1, A3, 8
    59735974
    59745975        IEM_SAVE_FLAGS_OLD A1, X86_EFL_CF | X86_EFL_ZF | X86_EFL_SF | X86_EFL_OF, 0, X86_EFL_AF | X86_EFL_PF
    5975         mov    [T2], ecx
     5976        mov    R0_32, ecx
    59765977
    59775978        IEMIMPL_SSE_EPILOGUE
  • trunk/src/VBox/VMM/VMMAll/IEMAllAImplC.cpp

    r104263 r104269  
    1807718077}
    1807818078
    18079 DECL_FORCE_INLINE(void) iemAImpl_pcmpxstri_set_result_index(uint32_t *pu32Ecx, uint16_t u16Result, uint8_t cElems, uint8_t bImm)
    18080 {
     18079DECL_FORCE_INLINE(uint32_t) iemAImpl_pcmpxstri_set_result_index(uint16_t u16Result, uint8_t cElems, uint8_t bImm)
     18080{
     18081    uint32_t u32Ecx;
    1808118082    if (bImm & RT_BIT(6))
    1808218083    {
     
    1808418085        uint32_t idxMsb = ASMBitLastSetU16(u16Result);
    1808518086        if (idxMsb)
    18086             *pu32Ecx = idxMsb - 1;
     18087            u32Ecx = idxMsb - 1;
    1808718088        else
    18088             *pu32Ecx = cElems;
     18089            u32Ecx = cElems;
    1808918090    }
    1809018091    else
     
    1809318094        uint32_t idxLsb = ASMBitFirstSetU16(u16Result);
    1809418095        if (idxLsb)
    18095             *pu32Ecx = idxLsb - 1;
     18096            u32Ecx = idxLsb - 1;
    1809618097        else
    18097             *pu32Ecx = cElems;
    18098     }
    18099 }
    18100 
    18101 IEM_DECL_IMPL_DEF(void, iemAImpl_pcmpistri_u128_fallback,(uint32_t *pu32Ecx, uint32_t *pEFlags, PCIEMPCMPISTRXSRC pSrc, uint8_t bEvil))
     18098            u32Ecx = cElems;
     18099    }
     18100
     18101    return u32Ecx;
     18102}
     18103
     18104IEM_DECL_IMPL_DEF(uint32_t, iemAImpl_pcmpistri_u128_fallback,(uint32_t *pEFlags, PCRTUINT128U pSrc1, PCRTUINT128U pSrc2, uint8_t bEvil))
    1810218105{
    1810318106    uint8_t cElems = (bEvil & RT_BIT(0)) ? 8 : 16;
    18104     uint8_t cLen1 = iemAImpl_pcmpistrx_get_str_len_implicit(&pSrc->uSrc1, bEvil);
    18105     uint8_t cLen2 = iemAImpl_pcmpistrx_get_str_len_implicit(&pSrc->uSrc2, bEvil);
    18106 
    18107     uint16_t u16Result = iemAImpl_pcmpxstrx_worker(pEFlags, &pSrc->uSrc1, &pSrc->uSrc2, cLen1, cLen2, bEvil);
    18108     iemAImpl_pcmpxstri_set_result_index(pu32Ecx, u16Result, cElems, bEvil);
     18107    uint8_t cLen1 = iemAImpl_pcmpistrx_get_str_len_implicit(pSrc1, bEvil);
     18108    uint8_t cLen2 = iemAImpl_pcmpistrx_get_str_len_implicit(pSrc2, bEvil);
     18109
     18110    uint16_t u16Result = iemAImpl_pcmpxstrx_worker(pEFlags, pSrc1, pSrc2, cLen1, cLen2, bEvil);
     18111    return iemAImpl_pcmpxstri_set_result_index(u16Result, cElems, bEvil);
    1810918112}
    1811018113
     
    1812018123
    1812118124    uint16_t u16Result = iemAImpl_pcmpxstrx_worker(pEFlags, &pSrc->uSrc1, &pSrc->uSrc2, cLen1, cLen2, bEvil);
    18122     iemAImpl_pcmpxstri_set_result_index(pu32Ecx, u16Result, cElems, bEvil);
     18125    *pu32Ecx = iemAImpl_pcmpxstri_set_result_index(u16Result, cElems, bEvil);
    1812318126}
    1812418127
  • trunk/src/VBox/VMM/VMMAll/IEMAllInstThree0f3a.cpp.h

    r104156 r104269  
    14631463        IEM_MC_BEGIN(IEM_MC_F_NOT_286_OR_OLDER, 0);
    14641464        IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX_EX(fSse42);
    1465         IEM_MC_ARG(uint32_t *,                 pu32Ecx,             0);
    1466         IEM_MC_ARG(uint32_t *,                 pEFlags,             1);
    1467         IEM_MC_LOCAL(IEMPCMPISTRXSRC,          Src);
    1468         IEM_MC_ARG_LOCAL_REF(PIEMPCMPISTRXSRC, pSrc,           Src, 2);
     1465        IEM_MC_ARG(uint32_t *,                 pEFlags,             0);
     1466        IEM_MC_ARG(PCRTUINT128U,               pSrc1,               1);
     1467        IEM_MC_ARG(PCRTUINT128U,               pSrc2,               2);
    14691468        IEM_MC_ARG_CONST(uint8_t,              bImmArg, /*=*/ bImm, 3);
    14701469        IEM_MC_MAYBE_RAISE_SSE_RELATED_XCPT();
    14711470        IEM_MC_PREPARE_SSE_USAGE();
    1472         IEM_MC_FETCH_XREG_PAIR_U128(Src, IEM_GET_MODRM_REG(pVCpu, bRm), IEM_GET_MODRM_RM(pVCpu, bRm));
    1473         IEM_MC_REF_GREG_U32(pu32Ecx, X86_GREG_xCX);
     1471        IEM_MC_REF_XREG_U128_CONST(pSrc1, IEM_GET_MODRM_REG(pVCpu, bRm));
     1472        IEM_MC_REF_XREG_U128_CONST(pSrc2, IEM_GET_MODRM_RM(pVCpu, bRm));
     1473        IEM_MC_REF_EFLAGS(pEFlags);
     1474        IEM_MC_CALL_AIMPL_4(uint32_t, u32Ecx,
     1475                            IEM_SELECT_HOST_OR_FALLBACK(fSse42,
     1476                                                        iemAImpl_pcmpistri_u128,
     1477                                                        iemAImpl_pcmpistri_u128_fallback),
     1478                            pEFlags, pSrc1, pSrc2, bImmArg);
     1479        /** @todo testcase: High dword of RCX cleared? */
     1480        IEM_MC_STORE_GREG_U32(X86_GREG_xCX, u32Ecx);
    14741481        IEM_MC_CLEAR_HIGH_GREG_U64(X86_GREG_xCX);
     1482
     1483        IEM_MC_ADVANCE_RIP_AND_FINISH();
     1484        IEM_MC_END();
     1485    }
     1486    else
     1487    {
     1488        /*
     1489         * Register, memory.
     1490         */
     1491        IEM_MC_BEGIN(IEM_MC_F_NOT_286_OR_OLDER, 0);
     1492        IEM_MC_ARG(uint32_t *,                 pEFlags,             0);
     1493        IEM_MC_ARG(PCRTUINT128U,               pSrc1,               1);
     1494        IEM_MC_LOCAL(RTUINT128U,               Src2);
     1495        IEM_MC_ARG_LOCAL_REF(PCRTUINT128U,     pSrc2, Src2,         2);
     1496        IEM_MC_LOCAL(RTGCPTR,                  GCPtrEffSrc);
     1497
     1498        IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 1);
     1499        uint8_t bImm; IEM_OPCODE_GET_NEXT_U8(&bImm);
     1500        IEM_MC_ARG_CONST(uint8_t,              bImmArg, /*=*/ bImm, 3);
     1501        IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX_EX(fSse42);
     1502        IEM_MC_MAYBE_RAISE_SSE_RELATED_XCPT();
     1503        IEM_MC_PREPARE_SSE_USAGE();
     1504
     1505        IEM_MC_FETCH_MEM_U128(Src2, pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
     1506        IEM_MC_REF_XREG_U128_CONST(pSrc1, IEM_GET_MODRM_REG(pVCpu, bRm));
    14751507        IEM_MC_REF_EFLAGS(pEFlags);
    1476         IEM_MC_CALL_VOID_AIMPL_4(IEM_SELECT_HOST_OR_FALLBACK(fSse42,
    1477                                                              iemAImpl_pcmpistri_u128,
    1478                                                              iemAImpl_pcmpistri_u128_fallback),
    1479                                  pu32Ecx, pEFlags, pSrc, bImmArg);
     1508        IEM_MC_CALL_AIMPL_4(uint32_t, u32Ecx,
     1509                            IEM_SELECT_HOST_OR_FALLBACK(fSse42,
     1510                                                        iemAImpl_pcmpistri_u128,
     1511                                                        iemAImpl_pcmpistri_u128_fallback),
     1512                            pEFlags, pSrc1, pSrc2, bImmArg);
    14801513        /** @todo testcase: High dword of RCX cleared? */
    1481         IEM_MC_ADVANCE_RIP_AND_FINISH();
    1482         IEM_MC_END();
    1483     }
    1484     else
    1485     {
    1486         /*
    1487          * Register, memory.
    1488          */
    1489         IEM_MC_BEGIN(IEM_MC_F_NOT_286_OR_OLDER, 0);
    1490         IEM_MC_ARG(uint32_t *,                  pu32Ecx,             0);
    1491         IEM_MC_ARG(uint32_t *,                  pEFlags,             1);
    1492         IEM_MC_LOCAL(IEMPCMPISTRXSRC,           Src);
    1493         IEM_MC_ARG_LOCAL_REF(PIEMPCMPISTRXSRC,  pSrc,           Src, 2);
    1494         IEM_MC_LOCAL(RTGCPTR,                   GCPtrEffSrc);
    1495 
    1496         IEM_MC_CALC_RM_EFF_ADDR(GCPtrEffSrc, bRm, 1);
    1497         uint8_t bImm; IEM_OPCODE_GET_NEXT_U8(&bImm);
    1498         IEM_MC_ARG_CONST(uint8_t,               bImmArg, /*=*/ bImm, 3);
    1499         IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX_EX(fSse42);
    1500         IEM_MC_MAYBE_RAISE_SSE_RELATED_XCPT();
    1501         IEM_MC_PREPARE_SSE_USAGE();
    1502 
    1503         IEM_MC_FETCH_MEM_U128_AND_XREG_U128(Src, IEM_GET_MODRM_REG(pVCpu, bRm), pVCpu->iem.s.iEffSeg, GCPtrEffSrc);
    1504         IEM_MC_REF_GREG_U32(pu32Ecx, X86_GREG_xCX);
     1514        IEM_MC_STORE_GREG_U32(X86_GREG_xCX, u32Ecx);
    15051515        IEM_MC_CLEAR_HIGH_GREG_U64(X86_GREG_xCX);
    1506         IEM_MC_REF_EFLAGS(pEFlags);
    1507         IEM_MC_CALL_VOID_AIMPL_4(IEM_SELECT_HOST_OR_FALLBACK(fSse42,
    1508                                                              iemAImpl_pcmpistri_u128,
    1509                                                              iemAImpl_pcmpistri_u128_fallback),
    1510                                  pu32Ecx, pEFlags, pSrc, bImmArg);
    1511         /** @todo testcase: High dword of RCX cleared? */
    15121516        IEM_MC_ADVANCE_RIP_AND_FINISH();
    15131517        IEM_MC_END();
  • trunk/src/VBox/VMM/include/IEMInternal.h

    r104268 r104269  
    37663766typedef const IEMPCMPESTRXSRC *PCIEMPCMPESTRXSRC;
    37673767
    3768 typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLPCMPISTRIU128IMM8,(uint32_t *pu32Ecx, uint32_t *pEFlags, PCIEMPCMPISTRXSRC pSrc, uint8_t bEvil));
     3768typedef IEM_DECL_IMPL_TYPE(uint32_t, FNIEMAIMPLPCMPISTRIU128IMM8,(uint32_t *pEFlags, PCRTUINT128U pSrc1, PCRTUINT128U pSrc2, uint8_t bEvil));
    37693769typedef FNIEMAIMPLPCMPISTRIU128IMM8 *PFNIEMAIMPLPCMPISTRIU128IMM8;
    37703770typedef IEM_DECL_IMPL_TYPE(void, FNIEMAIMPLPCMPESTRIU128IMM8,(uint32_t *pu32Ecx, uint32_t *pEFlags, PCIEMPCMPESTRXSRC pSrc, uint8_t bEvil));
  • trunk/src/VBox/VMM/testcase/tstIEMAImpl.cpp

    r104238 r104269  
    94829482            TestData.InVal2.uXmm = iTest < cTests ? RandU128() : s_aSpecials[iTest - cTests].uSrc2;
    94839483
    9484             IEMPCMPISTRXSRC TestVal;
    9485             TestVal.uSrc1 = TestData.InVal1.uXmm;
    9486             TestVal.uSrc2 = TestData.InVal2.uXmm;
    9487 
    94889484            uint32_t const fEFlagsIn = RandEFlags();
    94899485            for (uint16_t u16Imm = 0; u16Imm < 256; u16Imm++)
    94909486            {
    94919487                uint32_t fEFlagsOut = fEFlagsIn;
    9492                 pfn(&TestData.u32EcxOut, &fEFlagsOut, &TestVal, (uint8_t)u16Imm);
     9488                TestData.u32EcxOut  = pfn(&fEFlagsOut, &TestData.InVal1.uXmm,  &TestData.InVal2.uXmm, (uint8_t)u16Imm);
    94939489                TestData.fEFlagsIn  = fEFlagsIn;
    94949490                TestData.fEFlagsOut = fEFlagsOut;
     
    94989494
    94999495            /* Repeat the test with the input value being the same. */
    9500             TestData.InVal2.uXmm = TestData.InVal1.uXmm;
    9501             TestVal.uSrc1 = TestData.InVal1.uXmm;
    9502             TestVal.uSrc2 = TestData.InVal2.uXmm;
    9503 
    95049496            for (uint16_t u16Imm = 0; u16Imm < 256; u16Imm++)
    95059497            {
    95069498                uint32_t fEFlagsOut = fEFlagsIn;
    9507                 pfn(&TestData.u32EcxOut, &fEFlagsOut, &TestVal, (uint8_t)u16Imm);
     9499                TestData.u32EcxOut  = pfn(&fEFlagsOut, &TestData.InVal1.uXmm,  &TestData.InVal2.uXmm, (uint8_t)u16Imm);
    95089500                TestData.fEFlagsIn  = fEFlagsIn;
    95099501                TestData.fEFlagsOut = fEFlagsOut;
     
    95389530            for (uint32_t iTest = 0; iTest < cTests; iTest++)
    95399531            {
    9540                 IEMPCMPISTRXSRC TestVal;
    9541                 TestVal.uSrc1 = paTests[iTest].InVal1.uXmm;
    9542                 TestVal.uSrc2 = paTests[iTest].InVal2.uXmm;
    9543 
    95449532                uint32_t fEFlags = paTests[iTest].fEFlagsIn;
    9545                 uint32_t u32EcxOut = 0;
    9546                 pfn(&u32EcxOut, &fEFlags, &TestVal, paTests[iTest].bImm);
     9533                uint32_t u32EcxOut = pfn(&fEFlags, &paTests[iTest].InVal1.uXmm, &paTests[iTest].InVal2.uXmm, paTests[iTest].bImm);
    95479534                if (   fEFlags != paTests[iTest].fEFlagsOut
    95489535                    || u32EcxOut != paTests[iTest].u32EcxOut)
Note: See TracChangeset for help on using the changeset viewer.

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