VirtualBox

Ignore:
Timestamp:
May 18, 2024 5:00:15 AM (9 months ago)
Author:
vboxsync
Message:

VMM/IEM: Implement vmaskmovp[sd], vpmaskmov[dq] instruction decoding, dispatch & emulation, bugref:9898

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMAll/IEMAllCImpl.cpp

    r104516 r104722  
    98829882}
    98839883
     9884
     9885/**
     9886 * Worker for 'VMASKMOVPS / VPMASKMOVD' 128-bit 32-bit-masked load.
     9887 *
     9888 * @param   pVCpu           The cross context virtual CPU structure of the calling thread.
     9889 * @param   cbInstr         The current instruction length.
     9890 * @param   iXRegDst        The destination XMM register index.
     9891 * @param   iXRegMsk        The mask XMM register index.
     9892 * @param   iEffSeg         The effective segment.
     9893 * @param   GCPtrEffSrc     The source memory address.
     9894 */
     9895static VBOXSTRICTRC iemCImpl_maskmov_load_u128_32_worker(PVMCPUCC pVCpu, uint8_t cbInstr, uint8_t iXRegDst, uint8_t iXRegMsk, uint8_t iEffSeg, RTGCPTR GCPtrEffSrc)
     9896{
     9897    uint32_t fAccessed = 0;
     9898
     9899     PRTUINT128U puDst =  (PRTUINT128U)&pVCpu->cpum.GstCtx.XState.x87.aXMM[iXRegDst];
     9900    PCRTUINT128U puMsk = (PCRTUINT128U)&pVCpu->cpum.GstCtx.XState.x87.aXMM[iXRegMsk];
     9901    PCRTUINT128U puSrc;
     9902
     9903    for (uint32_t i = 0; i < RT_ELEMENTS(puMsk->au32); i++)
     9904    {
     9905        fAccessed |= puMsk->au32[i];
     9906    }
     9907
     9908    if (fAccessed & RT_BIT(31)) {
     9909        /*
     9910         * Access the source memory.
     9911         */
     9912        uint8_t bUnmapInfo;
     9913        void   *pvMemSrc;
     9914        VBOXSTRICTRC rcStrict = iemMemMap(pVCpu, &pvMemSrc, &bUnmapInfo, sizeof(*puSrc),
     9915                                          iEffSeg, GCPtrEffSrc, IEM_ACCESS_DATA_R, 0);
     9916        if (rcStrict != VINF_SUCCESS)
     9917            return rcStrict;
     9918
     9919        puSrc = (PCRTUINT128U)pvMemSrc;
     9920
     9921        for (uint32_t i = 0; i < RT_ELEMENTS(puSrc->au32); i++)
     9922        {
     9923            puDst->au32[i] = (puMsk->au32[i] & RT_BIT(31)) ? puSrc->au32[i] : 0;
     9924        }
     9925        pVCpu->cpum.GstCtx.XState.u.YmmHi.aYmmHi[iXRegDst].au64[0] = 0;
     9926        pVCpu->cpum.GstCtx.XState.u.YmmHi.aYmmHi[iXRegDst].au64[1] = 0;
     9927
     9928        rcStrict = iemMemCommitAndUnmap(pVCpu, bUnmapInfo);
     9929        if (rcStrict != VINF_SUCCESS)
     9930            return rcStrict;
     9931    }
     9932    else
     9933    {
     9934        puDst->au64[0] = 0;
     9935        puDst->au64[1] = 0;
     9936        pVCpu->cpum.GstCtx.XState.u.YmmHi.aYmmHi[iXRegDst].au64[0] = 0;
     9937        pVCpu->cpum.GstCtx.XState.u.YmmHi.aYmmHi[iXRegDst].au64[1] = 0;
     9938    }
     9939
     9940    return iemRegAddToRipAndFinishingClearingRF(pVCpu, cbInstr);
     9941}
     9942
     9943
     9944
     9945/**
     9946 * Worker for 'VMASKMOVPS / VPMASKMOVD' 256-bit 32-bit-masked load.
     9947 *
     9948 * @param   pVCpu           The cross context virtual CPU structure of the calling thread.
     9949 * @param   cbInstr         The current instruction length.
     9950 * @param   iYRegDst        The destination YMM register index.
     9951 * @param   iYRegMsk        The mask YMM register index.
     9952 * @param   iEffSeg         The effective segment.
     9953 * @param   GCPtrEffSrc     The source memory address.
     9954 */
     9955static VBOXSTRICTRC iemCImpl_maskmov_load_u256_32_worker(PVMCPUCC pVCpu, uint8_t cbInstr, uint8_t iYRegDst, uint8_t iYRegMsk, uint8_t iEffSeg, RTGCPTR GCPtrEffSrc)
     9956{
     9957    uint32_t fAccessed = 0;
     9958
     9959     PRTUINT128U puDstLo =  (PRTUINT128U)&pVCpu->cpum.GstCtx.XState.x87.aXMM[iYRegDst];
     9960     PRTUINT128U puDstHi =  (PRTUINT128U)&pVCpu->cpum.GstCtx.XState.u.YmmHi.aYmmHi[iYRegDst];
     9961    PCRTUINT128U puMskLo = (PCRTUINT128U)&pVCpu->cpum.GstCtx.XState.x87.aXMM[iYRegMsk];
     9962    PCRTUINT128U puMskHi = (PCRTUINT128U)&pVCpu->cpum.GstCtx.XState.u.YmmHi.aYmmHi[iYRegMsk];
     9963    PCRTUINT256U puSrc;
     9964
     9965    for (uint32_t i = 0; i < RT_ELEMENTS(puMskLo->au32); i++)
     9966    {
     9967        fAccessed |= puMskLo->au32[i] | puMskHi->au32[i];
     9968    }
     9969
     9970    if (fAccessed & RT_BIT(31)) {
     9971        /*
     9972         * Access the source memory.
     9973         */
     9974        uint8_t bUnmapInfo;
     9975        void   *pvMemSrc;
     9976        VBOXSTRICTRC rcStrict = iemMemMap(pVCpu, &pvMemSrc, &bUnmapInfo, sizeof(*puSrc),
     9977                                          iEffSeg, GCPtrEffSrc, IEM_ACCESS_DATA_R, 0);
     9978        if (rcStrict != VINF_SUCCESS)
     9979            return rcStrict;
     9980
     9981        puSrc   = (PCRTUINT256U)pvMemSrc;
     9982
     9983        uint8_t const iHalf = RT_ELEMENTS(puSrc->au32) / 2;
     9984
     9985        for (uint32_t i = 0; i < iHalf; i++)
     9986        {
     9987            puDstLo->au32[i] = (puMskLo->au32[i] & RT_BIT(31)) ? puSrc->au32[i] : 0;
     9988        }
     9989        for (uint32_t i = iHalf; i < RT_ELEMENTS(puSrc->au32); i++)
     9990        {
     9991            puDstHi->au32[i - iHalf] = (puMskHi->au32[i - iHalf] & RT_BIT(31)) ? puSrc->au32[i] : 0;
     9992        }
     9993
     9994        rcStrict = iemMemCommitAndUnmap(pVCpu, bUnmapInfo);
     9995        if (rcStrict != VINF_SUCCESS)
     9996            return rcStrict;
     9997    }
     9998    else
     9999    {
     10000        puDstLo->au64[0] = 0;
     10001        puDstLo->au64[1] = 0;
     10002        puDstHi->au64[0] = 0;
     10003        puDstHi->au64[1] = 0;
     10004    }
     10005
     10006    return iemRegAddToRipAndFinishingClearingRF(pVCpu, cbInstr);
     10007}
     10008
     10009
     10010/**
     10011 * Worker for 'VMASKMOVPS / VPMASKMOVD' 128-bit 32-bit-masked store.
     10012 *
     10013 * @param   pVCpu           The cross context virtual CPU structure of the calling thread.
     10014 * @param   cbInstr         The current instruction length.
     10015 * @param   iEffSeg         The effective segment.
     10016 * @param   GCPtrEffDst     The destination memory address.
     10017 * @param   iXRegMsk        The mask XMM register index.
     10018 * @param   iXRegSrc        The source XMM register index.
     10019 */
     10020static VBOXSTRICTRC iemCImpl_maskmov_store_u128_32_worker(PVMCPUCC pVCpu, uint8_t cbInstr, uint8_t iEffSeg, RTGCPTR GCPtrEffDst, uint8_t iXRegMsk, uint8_t iXRegSrc)
     10021{
     10022    uint32_t fAccessed = 0;
     10023
     10024     PRTUINT128U puDst;
     10025    PCRTUINT128U puMsk = (PCRTUINT128U)&pVCpu->cpum.GstCtx.XState.x87.aXMM[iXRegMsk];
     10026    PCRTUINT128U puSrc = (PCRTUINT128U)&pVCpu->cpum.GstCtx.XState.x87.aXMM[iXRegSrc];
     10027
     10028    for (uint32_t i = 0; i < RT_ELEMENTS(puMsk->au32); i++)
     10029    {
     10030        fAccessed |= puMsk->au32[i];
     10031    }
     10032
     10033    if (fAccessed & RT_BIT(31)) {
     10034        /*
     10035         * Access the destination memory.
     10036         */
     10037        uint8_t bUnmapInfo;
     10038        void   *pvMemDst;
     10039        VBOXSTRICTRC rcStrict = iemMemMap(pVCpu, &pvMemDst, &bUnmapInfo, sizeof(*puDst),
     10040                                          iEffSeg, GCPtrEffDst, IEM_ACCESS_DATA_RW, 0);
     10041        if (rcStrict != VINF_SUCCESS)
     10042            return rcStrict;
     10043
     10044        puDst =  (PRTUINT128U)pvMemDst;
     10045
     10046        for (uint32_t i = 0; i < RT_ELEMENTS(puDst->au32); i++)
     10047        {
     10048            if (puMsk->au32[i] & RT_BIT(31))
     10049                puDst->au32[i] = puSrc->au32[i];
     10050        }
     10051
     10052        rcStrict = iemMemCommitAndUnmap(pVCpu, bUnmapInfo);
     10053        if (rcStrict != VINF_SUCCESS)
     10054            return rcStrict;
     10055    }
     10056
     10057    return iemRegAddToRipAndFinishingClearingRF(pVCpu, cbInstr);
     10058}
     10059
     10060
     10061
     10062/**
     10063 * Worker for 'VMASKMOVPS / VPMASKMOVD' 256-bit 32-bit-masked store.
     10064 *
     10065 * @param   pVCpu           The cross context virtual CPU structure of the calling thread.
     10066 * @param   cbInstr         The current instruction length.
     10067 * @param   iEffSeg         The effective segment.
     10068 * @param   GCPtrEffDst     The destination memory address.
     10069 * @param   iYRegMsk        The mask YMM register index.
     10070 * @param   iYRegSrc        The source YMM register index.
     10071 */
     10072static VBOXSTRICTRC iemCImpl_maskmov_store_u256_32_worker(PVMCPUCC pVCpu, uint8_t cbInstr, uint8_t iEffSeg, RTGCPTR GCPtrEffDst, uint8_t iYRegMsk, uint8_t iYRegSrc)
     10073{
     10074    uint32_t fAccessed = 0;
     10075
     10076     PRTUINT256U puDst;
     10077    PCRTUINT128U puMskLo = (PCRTUINT128U)&pVCpu->cpum.GstCtx.XState.x87.aXMM[iYRegMsk];
     10078    PCRTUINT128U puMskHi = (PCRTUINT128U)&pVCpu->cpum.GstCtx.XState.u.YmmHi.aYmmHi[iYRegMsk];
     10079    PCRTUINT128U puSrcLo = (PCRTUINT128U)&pVCpu->cpum.GstCtx.XState.x87.aXMM[iYRegSrc];
     10080    PCRTUINT128U puSrcHi = (PCRTUINT128U)&pVCpu->cpum.GstCtx.XState.u.YmmHi.aYmmHi[iYRegSrc];
     10081
     10082    for (uint32_t i = 0; i < RT_ELEMENTS(puMskLo->au32); i++)
     10083    {
     10084        fAccessed |= puMskLo->au32[i] | puMskHi->au32[i];
     10085    }
     10086
     10087    if (fAccessed & RT_BIT(31)) {
     10088        /*
     10089         * Access the destination memory.
     10090         */
     10091        uint8_t bUnmapInfo;
     10092        void   *pvMemDst;
     10093        VBOXSTRICTRC rcStrict = iemMemMap(pVCpu, &pvMemDst, &bUnmapInfo, sizeof(*puDst),
     10094                                          iEffSeg, GCPtrEffDst, IEM_ACCESS_DATA_RW, 0);
     10095        if (rcStrict != VINF_SUCCESS)
     10096            return rcStrict;
     10097
     10098        puDst   =  (PRTUINT256U)pvMemDst;
     10099
     10100        uint8_t const iHalf = RT_ELEMENTS(puDst->au32) / 2;
     10101
     10102        for (uint32_t i = 0; i < iHalf; i++)
     10103        {
     10104            if (puMskLo->au32[i] & RT_BIT(31))
     10105                puDst->au32[i] = puSrcLo->au32[i];
     10106        }
     10107        for (uint32_t i = iHalf; i < RT_ELEMENTS(puDst->au32); i++)
     10108        {
     10109            if (puMskHi->au32[i - iHalf] & RT_BIT(31))
     10110                puDst->au32[i] = puSrcHi->au32[i - iHalf];
     10111        }
     10112
     10113        rcStrict = iemMemCommitAndUnmap(pVCpu, bUnmapInfo);
     10114        if (rcStrict != VINF_SUCCESS)
     10115            return rcStrict;
     10116    }
     10117
     10118    return iemRegAddToRipAndFinishingClearingRF(pVCpu, cbInstr);
     10119}
     10120
     10121
     10122/**
     10123 * Worker for 'VMASKMOVPD / VPMASKMOVQ' 128-bit 64-bit-masked load.
     10124 *
     10125 * @param   pVCpu           The cross context virtual CPU structure of the calling thread.
     10126 * @param   cbInstr         The current instruction length.
     10127 * @param   iXRegDst        The destination XMM register index.
     10128 * @param   iXRegMsk        The mask XMM register index.
     10129 * @param   iEffSeg         The effective segment.
     10130 * @param   GCPtrEffSrc     The source memory address.
     10131 */
     10132static VBOXSTRICTRC iemCImpl_maskmov_load_u128_64_worker(PVMCPUCC pVCpu, uint8_t cbInstr, uint8_t iXRegDst, uint8_t iXRegMsk, uint8_t iEffSeg, RTGCPTR GCPtrEffSrc)
     10133{
     10134    uint64_t fAccessed = 0;
     10135
     10136     PRTUINT128U puDst =  (PRTUINT128U)&pVCpu->cpum.GstCtx.XState.x87.aXMM[iXRegDst];
     10137    PCRTUINT128U puMsk = (PCRTUINT128U)&pVCpu->cpum.GstCtx.XState.x87.aXMM[iXRegMsk];
     10138    PCRTUINT128U puSrc;
     10139
     10140    for (uint32_t i = 0; i < RT_ELEMENTS(puMsk->au64); i++)
     10141    {
     10142        fAccessed |= puMsk->au64[i];
     10143    }
     10144
     10145    if (fAccessed & RT_BIT_64(63)) {
     10146        /*
     10147         * Access the source memory.
     10148         */
     10149        uint8_t bUnmapInfo;
     10150        void   *pvMemSrc;
     10151        VBOXSTRICTRC rcStrict = iemMemMap(pVCpu, &pvMemSrc, &bUnmapInfo, sizeof(*puSrc),
     10152                                          iEffSeg, GCPtrEffSrc, IEM_ACCESS_DATA_R, 0);
     10153        if (rcStrict != VINF_SUCCESS)
     10154            return rcStrict;
     10155
     10156        puSrc = (PCRTUINT128U)pvMemSrc;
     10157
     10158        for (uint32_t i = 0; i < RT_ELEMENTS(puSrc->au64); i++)
     10159        {
     10160            puDst->au64[i] = (puMsk->au64[i] & RT_BIT_64(63)) ? puSrc->au64[i] : 0;
     10161        }
     10162        pVCpu->cpum.GstCtx.XState.u.YmmHi.aYmmHi[iXRegDst].au64[0] = 0;
     10163        pVCpu->cpum.GstCtx.XState.u.YmmHi.aYmmHi[iXRegDst].au64[1] = 0;
     10164
     10165        rcStrict = iemMemCommitAndUnmap(pVCpu, bUnmapInfo);
     10166        if (rcStrict != VINF_SUCCESS)
     10167            return rcStrict;
     10168    }
     10169    else
     10170    {
     10171        puDst->au64[0] = 0;
     10172        puDst->au64[1] = 0;
     10173        pVCpu->cpum.GstCtx.XState.u.YmmHi.aYmmHi[iXRegDst].au64[0] = 0;
     10174        pVCpu->cpum.GstCtx.XState.u.YmmHi.aYmmHi[iXRegDst].au64[1] = 0;
     10175    }
     10176
     10177    return iemRegAddToRipAndFinishingClearingRF(pVCpu, cbInstr);
     10178}
     10179
     10180
     10181
     10182/**
     10183 * Worker for 'VMASKMOVPD / VPMASKMOVQ' 256-bit 64-bit-masked load.
     10184 *
     10185 * @param   pVCpu           The cross context virtual CPU structure of the calling thread.
     10186 * @param   cbInstr         The current instruction length.
     10187 * @param   iYRegDst        The destination YMM register index.
     10188 * @param   iYRegMsk        The mask YMM register index.
     10189 * @param   iEffSeg         The effective segment.
     10190 * @param   GCPtrEffSrc     The source memory address.
     10191 */
     10192static VBOXSTRICTRC iemCImpl_maskmov_load_u256_64_worker(PVMCPUCC pVCpu, uint8_t cbInstr, uint8_t iYRegDst, uint8_t iYRegMsk, uint8_t iEffSeg, RTGCPTR GCPtrEffSrc)
     10193{
     10194    uint64_t fAccessed = 0;
     10195
     10196     PRTUINT128U puDstLo =  (PRTUINT128U)&pVCpu->cpum.GstCtx.XState.x87.aXMM[iYRegDst];
     10197     PRTUINT128U puDstHi =  (PRTUINT128U)&pVCpu->cpum.GstCtx.XState.u.YmmHi.aYmmHi[iYRegDst];
     10198    PCRTUINT128U puMskLo = (PCRTUINT128U)&pVCpu->cpum.GstCtx.XState.x87.aXMM[iYRegMsk];
     10199    PCRTUINT128U puMskHi = (PCRTUINT128U)&pVCpu->cpum.GstCtx.XState.u.YmmHi.aYmmHi[iYRegMsk];
     10200    PCRTUINT256U puSrc;
     10201
     10202    for (uint32_t i = 0; i < RT_ELEMENTS(puMskLo->au64); i++)
     10203    {
     10204        fAccessed |= puMskLo->au64[i] | puMskHi->au64[i];
     10205    }
     10206
     10207    if (fAccessed & RT_BIT_64(63)) {
     10208        /*
     10209         * Access the source memory.
     10210         */
     10211        uint8_t bUnmapInfo;
     10212        void   *pvMemSrc;
     10213        VBOXSTRICTRC rcStrict = iemMemMap(pVCpu, &pvMemSrc, &bUnmapInfo, sizeof(*puSrc),
     10214                                          iEffSeg, GCPtrEffSrc, IEM_ACCESS_DATA_R, 0);
     10215        if (rcStrict != VINF_SUCCESS)
     10216            return rcStrict;
     10217
     10218        puSrc   = (PCRTUINT256U)pvMemSrc;
     10219
     10220        uint8_t const iHalf = RT_ELEMENTS(puSrc->au64) / 2;
     10221
     10222        for (uint32_t i = 0; i < iHalf; i++)
     10223        {
     10224            puDstLo->au64[i] = (puMskLo->au64[i] & RT_BIT_64(63)) ? puSrc->au64[i] : 0;
     10225        }
     10226        for (uint32_t i = iHalf; i < RT_ELEMENTS(puSrc->au64); i++)
     10227        {
     10228            puDstHi->au64[i - iHalf] = (puMskHi->au64[i - iHalf] & RT_BIT_64(63)) ? puSrc->au64[i] : 0;
     10229        }
     10230
     10231        rcStrict = iemMemCommitAndUnmap(pVCpu, bUnmapInfo);
     10232        if (rcStrict != VINF_SUCCESS)
     10233            return rcStrict;
     10234    }
     10235    else
     10236    {
     10237        puDstLo->au64[0] = 0;
     10238        puDstLo->au64[1] = 0;
     10239        puDstHi->au64[0] = 0;
     10240        puDstHi->au64[1] = 0;
     10241    }
     10242
     10243    return iemRegAddToRipAndFinishingClearingRF(pVCpu, cbInstr);
     10244}
     10245
     10246
     10247/**
     10248 * Worker for 'VMASKMOVPD / VPMASKMOVQ' 128-bit 64-bit-masked store.
     10249 *
     10250 * @param   pVCpu           The cross context virtual CPU structure of the calling thread.
     10251 * @param   cbInstr         The current instruction length.
     10252 * @param   iEffSeg         The effective segment.
     10253 * @param   GCPtrEffDst     The destination memory address.
     10254 * @param   iXRegMsk        The mask XMM register index.
     10255 * @param   iXRegSrc        The source XMM register index.
     10256 */
     10257static VBOXSTRICTRC iemCImpl_maskmov_store_u128_64_worker(PVMCPUCC pVCpu, uint8_t cbInstr, uint8_t iEffSeg, RTGCPTR GCPtrEffDst, uint8_t iXRegMsk, uint8_t iXRegSrc)
     10258{
     10259    uint64_t fAccessed = 0;
     10260
     10261     PRTUINT128U puDst;
     10262    PCRTUINT128U puMsk = (PCRTUINT128U)&pVCpu->cpum.GstCtx.XState.x87.aXMM[iXRegMsk];
     10263    PCRTUINT128U puSrc = (PCRTUINT128U)&pVCpu->cpum.GstCtx.XState.x87.aXMM[iXRegSrc];
     10264
     10265    for (uint32_t i = 0; i < RT_ELEMENTS(puMsk->au64); i++)
     10266    {
     10267        fAccessed |= puMsk->au64[i];
     10268    }
     10269
     10270    if (fAccessed & RT_BIT_64(63)) {
     10271        /*
     10272         * Access the destination memory.
     10273         */
     10274        uint8_t bUnmapInfo;
     10275        void   *pvMemDst;
     10276        VBOXSTRICTRC rcStrict = iemMemMap(pVCpu, &pvMemDst, &bUnmapInfo, sizeof(*puDst),
     10277                                          iEffSeg, GCPtrEffDst, IEM_ACCESS_DATA_RW, 0);
     10278        if (rcStrict != VINF_SUCCESS)
     10279            return rcStrict;
     10280
     10281        puDst =  (PRTUINT128U)pvMemDst;
     10282
     10283        for (uint32_t i = 0; i < RT_ELEMENTS(puDst->au64); i++)
     10284        {
     10285            if (puMsk->au64[i] & RT_BIT_64(63))
     10286                puDst->au64[i] = puSrc->au64[i];
     10287        }
     10288
     10289        rcStrict = iemMemCommitAndUnmap(pVCpu, bUnmapInfo);
     10290        if (rcStrict != VINF_SUCCESS)
     10291            return rcStrict;
     10292    }
     10293
     10294    return iemRegAddToRipAndFinishingClearingRF(pVCpu, cbInstr);
     10295}
     10296
     10297
     10298
     10299/**
     10300 * Worker for 'VMASKMOVPD / VPMASKMOVQ' 256-bit 64-bit-masked store.
     10301 *
     10302 * @param   pVCpu           The cross context virtual CPU structure of the calling thread.
     10303 * @param   cbInstr         The current instruction length.
     10304 * @param   iEffSeg         The effective segment.
     10305 * @param   GCPtrEffDst     The destination memory address.
     10306 * @param   iYRegMsk        The mask YMM register index.
     10307 * @param   iYRegSrc        The source YMM register index.
     10308 */
     10309static VBOXSTRICTRC iemCImpl_maskmov_store_u256_64_worker(PVMCPUCC pVCpu, uint8_t cbInstr, uint8_t iEffSeg, RTGCPTR GCPtrEffDst, uint8_t iYRegMsk, uint8_t iYRegSrc)
     10310{
     10311    uint64_t fAccessed = 0;
     10312
     10313     PRTUINT256U puDst;
     10314    PCRTUINT128U puMskLo = (PCRTUINT128U)&pVCpu->cpum.GstCtx.XState.x87.aXMM[iYRegMsk];
     10315    PCRTUINT128U puMskHi = (PCRTUINT128U)&pVCpu->cpum.GstCtx.XState.u.YmmHi.aYmmHi[iYRegMsk];
     10316    PCRTUINT128U puSrcLo = (PCRTUINT128U)&pVCpu->cpum.GstCtx.XState.x87.aXMM[iYRegSrc];
     10317    PCRTUINT128U puSrcHi = (PCRTUINT128U)&pVCpu->cpum.GstCtx.XState.u.YmmHi.aYmmHi[iYRegSrc];
     10318
     10319    for (uint32_t i = 0; i < RT_ELEMENTS(puMskLo->au64); i++)
     10320    {
     10321        fAccessed |= puMskLo->au64[i] | puMskHi->au64[i];
     10322    }
     10323
     10324    if (fAccessed & RT_BIT_64(63)) {
     10325        /*
     10326         * Access the destination memory.
     10327         */
     10328        uint8_t bUnmapInfo;
     10329        void   *pvMemDst;
     10330        VBOXSTRICTRC rcStrict = iemMemMap(pVCpu, &pvMemDst, &bUnmapInfo, sizeof(*puDst),
     10331                                          iEffSeg, GCPtrEffDst, IEM_ACCESS_DATA_RW, 0);
     10332        if (rcStrict != VINF_SUCCESS)
     10333            return rcStrict;
     10334
     10335        puDst   =  (PRTUINT256U)pvMemDst;
     10336
     10337        uint8_t const iHalf = RT_ELEMENTS(puDst->au64) / 2;
     10338
     10339        for (uint32_t i = 0; i < iHalf; i++)
     10340        {
     10341            if (puMskLo->au64[i] & RT_BIT_64(63))
     10342                puDst->au64[i] = puSrcLo->au64[i];
     10343        }
     10344        for (uint32_t i = iHalf; i < RT_ELEMENTS(puDst->au64); i++)
     10345        {
     10346            if (puMskHi->au64[i - iHalf] & RT_BIT_64(63))
     10347                puDst->au64[i] = puSrcHi->au64[i - iHalf];
     10348        }
     10349
     10350        rcStrict = iemMemCommitAndUnmap(pVCpu, bUnmapInfo);
     10351        if (rcStrict != VINF_SUCCESS)
     10352            return rcStrict;
     10353    }
     10354
     10355    return iemRegAddToRipAndFinishingClearingRF(pVCpu, cbInstr);
     10356}
     10357
     10358
     10359/**
     10360 * Implements 'VMASKMOVPS' 128-bit 32-bit-masked load.
     10361 *
     10362 * @param   iXRegDst        The destination XMM register index.
     10363 * @param   iXRegMsk        The mask XMM register index.
     10364 * @param   iEffSeg         The effective segment.
     10365 * @param   GCPtrEffSrc     The source memory address.
     10366 */
     10367IEM_CIMPL_DEF_4(iemCImpl_vmaskmovps_load_u128, uint8_t, iXRegDst, uint8_t, iXRegMsk, uint8_t, iEffSeg, RTGCPTR, GCPtrEffSrc)
     10368{
     10369    return iemCImpl_maskmov_load_u128_32_worker(pVCpu, cbInstr, iXRegDst, iXRegMsk, iEffSeg, GCPtrEffSrc);
     10370}
     10371
     10372
     10373/**
     10374 * Implements 'VMASKMOVPS' 256-bit 32-bit-masked load.
     10375 *
     10376 * @param   iYRegDst        The destination YMM register index.
     10377 * @param   iYRegMsk        The mask YMM register index.
     10378 * @param   iEffSeg         The effective segment.
     10379 * @param   GCPtrEffSrc     The source memory address.
     10380 */
     10381IEM_CIMPL_DEF_4(iemCImpl_vmaskmovps_load_u256, uint8_t, iYRegDst, uint8_t, iYRegMsk, uint8_t, iEffSeg, RTGCPTR, GCPtrEffSrc)
     10382{
     10383    return iemCImpl_maskmov_load_u256_32_worker(pVCpu, cbInstr, iYRegDst, iYRegMsk, iEffSeg, GCPtrEffSrc);
     10384}
     10385
     10386
     10387/**
     10388 * Implements 'VMASKMOVPS' 128-bit 32-bit-masked store.
     10389 *
     10390 * @param   iEffSeg         The effective segment.
     10391 * @param   GCPtrEffDst     The destination memory address.
     10392 * @param   iXRegMsk        The mask XMM register index.
     10393 * @param   iXRegSrc        The source XMM register index.
     10394 */
     10395IEM_CIMPL_DEF_4(iemCImpl_vmaskmovps_store_u128, uint8_t, iEffSeg, RTGCPTR, GCPtrEffDst, uint8_t, iXRegMsk, uint8_t, iXRegSrc)
     10396{
     10397    return iemCImpl_maskmov_store_u128_32_worker(pVCpu, cbInstr, iEffSeg, GCPtrEffDst, iXRegMsk, iXRegSrc);
     10398}
     10399
     10400
     10401/**
     10402 * Implements 'VMASKMOVPS' 256-bit 32-bit-masked store.
     10403 *
     10404 * @param   iEffSeg         The effective segment.
     10405 * @param   GCPtrEffDst     The destination memory address.
     10406 * @param   iYRegMsk        The mask YMM register index.
     10407 * @param   iYRegSrc        The source YMM register index.
     10408 */
     10409IEM_CIMPL_DEF_4(iemCImpl_vmaskmovps_store_u256, uint8_t, iEffSeg, RTGCPTR, GCPtrEffDst, uint8_t, iYRegMsk, uint8_t, iYRegSrc)
     10410{
     10411    return iemCImpl_maskmov_store_u256_32_worker(pVCpu, cbInstr, iEffSeg, GCPtrEffDst, iYRegMsk, iYRegSrc);
     10412}
     10413
     10414
     10415/**
     10416 * Implements 'VPMASKMOVD' 128-bit 32-bit-masked load.
     10417 *
     10418 * @param   iXRegDst        The destination XMM register index.
     10419 * @param   iXRegMsk        The mask XMM register index.
     10420 * @param   iEffSeg         The effective segment.
     10421 * @param   GCPtrEffSrc     The source memory address.
     10422 */
     10423IEM_CIMPL_DEF_4(iemCImpl_vpmaskmovd_load_u128, uint8_t, iXRegDst, uint8_t, iXRegMsk, uint8_t, iEffSeg, RTGCPTR, GCPtrEffSrc)
     10424{
     10425    return iemCImpl_maskmov_load_u128_32_worker(pVCpu, cbInstr, iXRegDst, iXRegMsk, iEffSeg, GCPtrEffSrc);
     10426}
     10427
     10428
     10429/**
     10430 * Implements 'VPMASKMOVD' 256-bit 32-bit-masked load.
     10431 *
     10432 * @param   iYRegDst        The destination YMM register index.
     10433 * @param   iYRegMsk        The mask YMM register index.
     10434 * @param   iEffSeg         The effective segment.
     10435 * @param   GCPtrEffSrc     The source memory address.
     10436 */
     10437IEM_CIMPL_DEF_4(iemCImpl_vpmaskmovd_load_u256, uint8_t, iYRegDst, uint8_t, iYRegMsk, uint8_t, iEffSeg, RTGCPTR, GCPtrEffSrc)
     10438{
     10439    return iemCImpl_maskmov_load_u256_32_worker(pVCpu, cbInstr, iYRegDst, iYRegMsk, iEffSeg, GCPtrEffSrc);
     10440}
     10441
     10442
     10443/**
     10444 * Implements 'VPMASKMOVD' 128-bit 32-bit-masked store.
     10445 *
     10446 * @param   iEffSeg         The effective segment.
     10447 * @param   GCPtrEffDst     The destination memory address.
     10448 * @param   iXRegMsk        The mask XMM register index.
     10449 * @param   iXRegSrc        The source XMM register index.
     10450 */
     10451IEM_CIMPL_DEF_4(iemCImpl_vpmaskmovd_store_u128, uint8_t, iEffSeg, RTGCPTR, GCPtrEffDst, uint8_t, iXRegMsk, uint8_t, iXRegSrc)
     10452{
     10453    return iemCImpl_maskmov_store_u128_32_worker(pVCpu, cbInstr, iEffSeg, GCPtrEffDst, iXRegMsk, iXRegSrc);
     10454}
     10455
     10456
     10457/**
     10458 * Implements 'VPMASKMOVD' 256-bit 32-bit-masked store.
     10459 *
     10460 * @param   iEffSeg         The effective segment.
     10461 * @param   GCPtrEffDst     The destination memory address.
     10462 * @param   iYRegMsk        The mask YMM register index.
     10463 * @param   iYRegSrc        The source YMM register index.
     10464 */
     10465IEM_CIMPL_DEF_4(iemCImpl_vpmaskmovd_store_u256, uint8_t, iEffSeg, RTGCPTR, GCPtrEffDst, uint8_t, iYRegMsk, uint8_t, iYRegSrc)
     10466{
     10467    return iemCImpl_maskmov_store_u256_32_worker(pVCpu, cbInstr, iEffSeg, GCPtrEffDst, iYRegMsk, iYRegSrc);
     10468}
     10469
     10470
     10471/**
     10472 * Implements 'VMASKMOVPD' 128-bit 64-bit-masked load.
     10473 *
     10474 * @param   iXRegDst        The destination XMM register index.
     10475 * @param   iXRegMsk        The mask XMM register index.
     10476 * @param   iEffSeg         The effective segment.
     10477 * @param   GCPtrEffSrc     The source memory address.
     10478 */
     10479IEM_CIMPL_DEF_4(iemCImpl_vmaskmovpd_load_u128, uint8_t, iXRegDst, uint8_t, iXRegMsk, uint8_t, iEffSeg, RTGCPTR, GCPtrEffSrc)
     10480{
     10481    return iemCImpl_maskmov_load_u128_64_worker(pVCpu, cbInstr, iXRegDst, iXRegMsk, iEffSeg, GCPtrEffSrc);
     10482}
     10483
     10484
     10485/**
     10486 * Implements 'VMASKMOVPD' 256-bit 64-bit-masked load.
     10487 *
     10488 * @param   iYRegDst        The destination YMM register index.
     10489 * @param   iYRegMsk        The mask YMM register index.
     10490 * @param   iEffSeg         The effective segment.
     10491 * @param   GCPtrEffSrc     The source memory address.
     10492 */
     10493IEM_CIMPL_DEF_4(iemCImpl_vmaskmovpd_load_u256, uint8_t, iYRegDst, uint8_t, iYRegMsk, uint8_t, iEffSeg, RTGCPTR, GCPtrEffSrc)
     10494{
     10495    return iemCImpl_maskmov_load_u256_64_worker(pVCpu, cbInstr, iYRegDst, iYRegMsk, iEffSeg, GCPtrEffSrc);
     10496}
     10497
     10498
     10499/**
     10500 * Implements 'VMASKMOVPD' 128-bit 64-bit-masked store.
     10501 *
     10502 * @param   iEffSeg         The effective segment.
     10503 * @param   GCPtrEffDst     The destination memory address.
     10504 * @param   iXRegMsk        The mask XMM register index.
     10505 * @param   iXRegSrc        The source XMM register index.
     10506 */
     10507IEM_CIMPL_DEF_4(iemCImpl_vmaskmovpd_store_u128, uint8_t, iEffSeg, RTGCPTR, GCPtrEffDst, uint8_t, iXRegMsk, uint8_t, iXRegSrc)
     10508{
     10509    return iemCImpl_maskmov_store_u128_64_worker(pVCpu, cbInstr, iEffSeg, GCPtrEffDst, iXRegMsk, iXRegSrc);
     10510}
     10511
     10512
     10513/**
     10514 * Implements 'VMASKMOVPD' 256-bit 64-bit-masked store.
     10515 *
     10516 * @param   iEffSeg         The effective segment.
     10517 * @param   GCPtrEffDst     The destination memory address.
     10518 * @param   iYRegMsk        The mask YMM register index.
     10519 * @param   iYRegSrc        The source YMM register index.
     10520 */
     10521IEM_CIMPL_DEF_4(iemCImpl_vmaskmovpd_store_u256, uint8_t, iEffSeg, RTGCPTR, GCPtrEffDst, uint8_t, iYRegMsk, uint8_t, iYRegSrc)
     10522{
     10523    return iemCImpl_maskmov_store_u256_64_worker(pVCpu, cbInstr, iEffSeg, GCPtrEffDst, iYRegMsk, iYRegSrc);
     10524}
     10525
     10526
     10527/**
     10528 * Implements 'VPMASKMOVQ' 128-bit 64-bit-masked load.
     10529 *
     10530 * @param   iXRegDst        The destination XMM register index.
     10531 * @param   iXRegMsk        The mask XMM register index.
     10532 * @param   iEffSeg         The effective segment.
     10533 * @param   GCPtrEffSrc     The source memory address.
     10534 */
     10535IEM_CIMPL_DEF_4(iemCImpl_vpmaskmovq_load_u128, uint8_t, iXRegDst, uint8_t, iXRegMsk, uint8_t, iEffSeg, RTGCPTR, GCPtrEffSrc)
     10536{
     10537    return iemCImpl_maskmov_load_u128_64_worker(pVCpu, cbInstr, iXRegDst, iXRegMsk, iEffSeg, GCPtrEffSrc);
     10538}
     10539
     10540
     10541/**
     10542 * Implements 'VPMASKMOVQ' 256-bit 64-bit-masked load.
     10543 *
     10544 * @param   iYRegDst        The destination YMM register index.
     10545 * @param   iYRegMsk        The mask YMM register index.
     10546 * @param   iEffSeg         The effective segment.
     10547 * @param   GCPtrEffSrc     The source memory address.
     10548 */
     10549IEM_CIMPL_DEF_4(iemCImpl_vpmaskmovq_load_u256, uint8_t, iYRegDst, uint8_t, iYRegMsk, uint8_t, iEffSeg, RTGCPTR, GCPtrEffSrc)
     10550{
     10551    return iemCImpl_maskmov_load_u256_64_worker(pVCpu, cbInstr, iYRegDst, iYRegMsk, iEffSeg, GCPtrEffSrc);
     10552}
     10553
     10554
     10555/**
     10556 * Implements 'VPMASKMOVQ' 128-bit 64-bit-masked store.
     10557 *
     10558 * @param   iEffSeg         The effective segment.
     10559 * @param   GCPtrEffDst     The destination memory address.
     10560 * @param   iXRegMsk        The mask XMM register index.
     10561 * @param   iXRegSrc        The source XMM register index.
     10562 */
     10563IEM_CIMPL_DEF_4(iemCImpl_vpmaskmovq_store_u128, uint8_t, iEffSeg, RTGCPTR, GCPtrEffDst, uint8_t, iXRegMsk, uint8_t, iXRegSrc)
     10564{
     10565    return iemCImpl_maskmov_store_u128_64_worker(pVCpu, cbInstr, iEffSeg, GCPtrEffDst, iXRegMsk, iXRegSrc);
     10566}
     10567
     10568
     10569/**
     10570 * Implements 'VPMASKMOVQ' 256-bit 64-bit-masked store.
     10571 *
     10572 * @param   iEffSeg         The effective segment.
     10573 * @param   GCPtrEffDst     The destination memory address.
     10574 * @param   iYRegMsk        The mask YMM register index.
     10575 * @param   iYRegSrc        The source YMM register index.
     10576 */
     10577IEM_CIMPL_DEF_4(iemCImpl_vpmaskmovq_store_u256, uint8_t, iEffSeg, RTGCPTR, GCPtrEffDst, uint8_t, iYRegMsk, uint8_t, iYRegSrc)
     10578{
     10579    return iemCImpl_maskmov_store_u256_64_worker(pVCpu, cbInstr, iEffSeg, GCPtrEffDst, iYRegMsk, iYRegSrc);
     10580}
     10581
     10582
    988410583/** @} */
    988510584
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