VirtualBox

Changeset 100084 in vbox


Ignore:
Timestamp:
Jun 6, 2023 2:56:14 PM (18 months ago)
Author:
vboxsync
Message:

VMM/IEM: Added iemRegGRegStoreUxx inline helpers and replaced all the ugly casting around iemGRegRef. Fixed SMSW not clearing high 32-bits and made it set unused bits for the 32-bit operand size too if in 386-mode. bugref:10369

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

Legend:

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

    r100061 r100084  
    49544954        {
    49554955            case IEMMODE_16BIT:
    4956                 *(uint16_t *)iemGRegRef(pVCpu, iGReg) = offSeg;
     4956                iemGRegStoreU16(pVCpu, iGReg, offSeg);
    49574957                break;
    49584958            case IEMMODE_32BIT:
    49594959            case IEMMODE_64BIT:
    4960                 *(uint64_t *)iemGRegRef(pVCpu, iGReg) = offSeg;
     4960                iemGRegStoreU64(pVCpu, iGReg, offSeg);
    49614961                break;
    49624962            IEM_NOT_REACHED_DEFAULT_CASE_RET();
     
    55295529    switch (enmEffOpSize)
    55305530    {
    5531         case IEMMODE_16BIT: *(uint16_t *)iemGRegRef(pVCpu, iGReg) = pVCpu->cpum.GstCtx.ldtr.Sel; break;
    5532         case IEMMODE_32BIT: *(uint64_t *)iemGRegRef(pVCpu, iGReg) = pVCpu->cpum.GstCtx.ldtr.Sel; break;
    5533         case IEMMODE_64BIT: *(uint64_t *)iemGRegRef(pVCpu, iGReg) = pVCpu->cpum.GstCtx.ldtr.Sel; break;
     5531        case IEMMODE_16BIT:
     5532            iemGRegStoreU16(pVCpu, iGReg, pVCpu->cpum.GstCtx.ldtr.Sel);
     5533            break;
     5534        case IEMMODE_32BIT:
     5535        case IEMMODE_64BIT:
     5536            iemGRegStoreU64(pVCpu, iGReg, pVCpu->cpum.GstCtx.ldtr.Sel);
     5537            break;
    55345538        IEM_NOT_REACHED_DEFAULT_CASE_RET();
    55355539    }
     
    57115715    switch (enmEffOpSize)
    57125716    {
    5713         case IEMMODE_16BIT: *(uint16_t *)iemGRegRef(pVCpu, iGReg) = pVCpu->cpum.GstCtx.tr.Sel; break;
    5714         case IEMMODE_32BIT: *(uint64_t *)iemGRegRef(pVCpu, iGReg) = pVCpu->cpum.GstCtx.tr.Sel; break;
    5715         case IEMMODE_64BIT: *(uint64_t *)iemGRegRef(pVCpu, iGReg) = pVCpu->cpum.GstCtx.tr.Sel; break;
     5717        case IEMMODE_16BIT:
     5718            iemGRegStoreU16(pVCpu, iGReg, pVCpu->cpum.GstCtx.tr.Sel);
     5719            break;
     5720        case IEMMODE_32BIT:
     5721        case IEMMODE_64BIT:
     5722            iemGRegStoreU64(pVCpu, iGReg, pVCpu->cpum.GstCtx.tr.Sel);
     5723            break;
    57165724        IEM_NOT_REACHED_DEFAULT_CASE_RET();
    57175725    }
     
    58605868    /* Store it. */
    58615869    if (IEM_IS_64BIT_CODE(pVCpu))
    5862         *(uint64_t *)iemGRegRef(pVCpu, iGReg) = crX;
     5870        iemGRegStoreU64(pVCpu, iGReg, crX);
    58635871    else
    5864         *(uint64_t *)iemGRegRef(pVCpu, iGReg) = (uint32_t)crX;
     5872        iemGRegStoreU64(pVCpu, iGReg, (uint32_t)crX);
    58655873
    58665874    return iemRegAddToRipAndFinishingClearingRF(pVCpu, cbInstr);
     
    58935901        case IEMMODE_16BIT:
    58945902            if (IEM_GET_TARGET_CPU(pVCpu) > IEMTARGETCPU_386)
    5895                 *(uint16_t *)iemGRegRef(pVCpu, iGReg) = (uint16_t)u64GuestCr0;
     5903                iemGRegStoreU16(pVCpu, iGReg, (uint16_t)u64GuestCr0);
     5904            /* Unused bits are set on 386 and older CPU: */
    58965905            else if (IEM_GET_TARGET_CPU(pVCpu) >= IEMTARGETCPU_386)
    5897                 *(uint16_t *)iemGRegRef(pVCpu, iGReg) = (uint16_t)u64GuestCr0 | 0xffe0;
     5906                iemGRegStoreU16(pVCpu, iGReg, (uint16_t)u64GuestCr0 | 0xffe0);
    58985907            else
    5899                 *(uint16_t *)iemGRegRef(pVCpu, iGReg) = (uint16_t)u64GuestCr0 | 0xfff0;
     5908                iemGRegStoreU16(pVCpu, iGReg, (uint16_t)u64GuestCr0 | 0xfff0);
    59005909            break;
    59015910
     5911/** @todo testcase for bits 31:16. We're not doing that correctly. */
     5912
    59025913        case IEMMODE_32BIT:
    5903             *(uint32_t *)iemGRegRef(pVCpu, iGReg) = (uint32_t)u64GuestCr0;
     5914            if (IEM_GET_TARGET_CPU(pVCpu) >= IEMTARGETCPU_386)
     5915                iemGRegStoreU32(pVCpu, iGReg, (uint32_t)u64GuestCr0);
     5916            else /** @todo test this! */
     5917                iemGRegStoreU32(pVCpu, iGReg, (uint32_t)u64GuestCr0 | UINT32_C(0x7fffffe0)); /* Unused bits are set on 386. */
    59045918            break;
    59055919
    59065920        case IEMMODE_64BIT:
    5907             *(uint64_t *)iemGRegRef(pVCpu, iGReg) = u64GuestCr0;
     5921            iemGRegStoreU64(pVCpu, iGReg, u64GuestCr0);
    59085922            break;
    59095923
     
    66546668
    66556669    if (IEM_IS_64BIT_CODE(pVCpu))
    6656         *(uint64_t *)iemGRegRef(pVCpu, iGReg) = drX;
     6670        iemGRegStoreU64(pVCpu, iGReg, drX);
    66576671    else
    6658         *(uint64_t *)iemGRegRef(pVCpu, iGReg) = (uint32_t)drX;
     6672        iemGRegStoreU32(pVCpu, iGReg, (uint32_t)drX);
    66596673
    66606674    return iemRegAddToRipAndFinishingClearingRF(pVCpu, cbInstr);
     
    68276841     * (different on 386/486) is exceedingly rare.
    68286842     */
    6829     uint64_t trX;
     6843    uint32_t trX;
    68306844    switch (iTrReg)
    68316845    {
     
    68396853    }
    68406854
    6841     *(uint64_t *)iemGRegRef(pVCpu, iGReg) = (uint32_t)trX;
     6855    iemGRegStoreU32(pVCpu, iGReg, trX);
    68426856
    68436857    return iemRegAddToRipAndFinishingClearingRF(pVCpu, cbInstr);
     
    68736887     * Read the new value from the source register.
    68746888     */
    6875     uint64_t uNewTrX;
    6876     if (IEM_IS_64BIT_CODE(pVCpu)) /** @todo err... 64-bit 386? */
    6877         uNewTrX = iemGRegFetchU64(pVCpu, iGReg);
    6878     else
    6879         uNewTrX = iemGRegFetchU32(pVCpu, iGReg);
     6889    uint32_t uNewTrX = iemGRegFetchU32(pVCpu, iGReg);
    68806890
    68816891    /*
  • trunk/src/VBox/VMM/include/IEMInline.h

    r100059 r100084  
    16041604 * @param   iSegReg             The segment register.
    16051605 */
    1606 DECLINLINE(PCPUMSELREG) iemSRegGetHid(PVMCPUCC pVCpu, uint8_t iSegReg) RT_NOEXCEPT
     1606DECL_FORCE_INLINE(PCPUMSELREG) iemSRegGetHid(PVMCPUCC pVCpu, uint8_t iSegReg) RT_NOEXCEPT
    16071607{
    16081608    Assert(iSegReg < X86_SREG_COUNT);
     
    16221622 * @param   pSReg               The segment register.
    16231623 */
    1624 DECLINLINE(PCPUMSELREG) iemSRegUpdateHid(PVMCPUCC pVCpu, PCPUMSELREG pSReg) RT_NOEXCEPT
     1624DECL_FORCE_INLINE(PCPUMSELREG) iemSRegUpdateHid(PVMCPUCC pVCpu, PCPUMSELREG pSReg) RT_NOEXCEPT
    16251625{
    16261626    Assert(CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pVCpu, pSReg));
     
    16381638 * @param   iSegReg             The segment register.
    16391639 */
    1640 DECLINLINE(uint16_t *) iemSRegRef(PVMCPUCC pVCpu, uint8_t iSegReg) RT_NOEXCEPT
     1640DECL_FORCE_INLINE(uint16_t *) iemSRegRef(PVMCPUCC pVCpu, uint8_t iSegReg) RT_NOEXCEPT
    16411641{
    16421642    Assert(iSegReg < X86_SREG_COUNT);
     
    16531653 * @param   iSegReg             The segment register.
    16541654 */
    1655 DECLINLINE(uint16_t) iemSRegFetchU16(PVMCPUCC pVCpu, uint8_t iSegReg) RT_NOEXCEPT
     1655DECL_FORCE_INLINE(uint16_t) iemSRegFetchU16(PVMCPUCC pVCpu, uint8_t iSegReg) RT_NOEXCEPT
    16561656{
    16571657    Assert(iSegReg < X86_SREG_COUNT);
     
    16681668 * @param   iSegReg             The segment register.
    16691669 */
    1670 DECLINLINE(uint64_t) iemSRegBaseFetchU64(PVMCPUCC pVCpu, uint8_t iSegReg) RT_NOEXCEPT
     1670DECL_FORCE_INLINE(uint64_t) iemSRegBaseFetchU64(PVMCPUCC pVCpu, uint8_t iSegReg) RT_NOEXCEPT
    16711671{
    16721672    Assert(iSegReg < X86_SREG_COUNT);
     
    16831683 * @param   iReg                The general purpose register.
    16841684 */
    1685 DECLINLINE(void *) iemGRegRef(PVMCPUCC pVCpu, uint8_t iReg) RT_NOEXCEPT
     1685DECL_FORCE_INLINE(void *) iemGRegRef(PVMCPUCC pVCpu, uint8_t iReg) RT_NOEXCEPT
    16861686{
    16871687    Assert(iReg < 16);
     
    17001700 * @param   iReg                The register.
    17011701 */
    1702 DECLINLINE(uint8_t *) iemGRegRefU8(PVMCPUCC pVCpu, uint8_t iReg) RT_NOEXCEPT
     1702DECL_FORCE_INLINE(uint8_t *) iemGRegRefU8(PVMCPUCC pVCpu, uint8_t iReg) RT_NOEXCEPT
    17031703{
    17041704    if (iReg < 4 || (pVCpu->iem.s.fPrefixes & IEM_OP_PRF_REX))
     
    17231723 *                              whereas 16 thru 19 maps to AH, CH, DH and BH.
    17241724 */
    1725 DECLINLINE(uint8_t *) iemGRegRefU8Ex(PVMCPUCC pVCpu, uint8_t iRegEx) RT_NOEXCEPT
    1726 {
     1725DECL_FORCE_INLINE(uint8_t *) iemGRegRefU8Ex(PVMCPUCC pVCpu, uint8_t iRegEx) RT_NOEXCEPT
     1726{
     1727    /** @todo This could be done by double indexing on little endian hosts:
     1728     *  return &pVCpu->cpum.GstCtx.aGRegs[iRegEx & 15].ab[iRegEx >> 4]; */
    17271729    if (iRegEx < 16)
    17281730        return &pVCpu->cpum.GstCtx.aGRegs[iRegEx].u8;
     
    17411743 * @param   iReg                The register.
    17421744 */
    1743 DECLINLINE(uint16_t *) iemGRegRefU16(PVMCPUCC pVCpu, uint8_t iReg) RT_NOEXCEPT
     1745DECL_FORCE_INLINE(uint16_t *) iemGRegRefU16(PVMCPUCC pVCpu, uint8_t iReg) RT_NOEXCEPT
    17441746{
    17451747    Assert(iReg < 16);
     
    17551757 * @param   iReg                The register.
    17561758 */
    1757 DECLINLINE(uint32_t *) iemGRegRefU32(PVMCPUCC pVCpu, uint8_t iReg) RT_NOEXCEPT
     1759DECL_FORCE_INLINE(uint32_t *) iemGRegRefU32(PVMCPUCC pVCpu, uint8_t iReg) RT_NOEXCEPT
    17581760{
    17591761    Assert(iReg < 16);
     
    17691771 * @param   iReg                The register.
    17701772 */
    1771 DECLINLINE(int32_t *) iemGRegRefI32(PVMCPUCC pVCpu, uint8_t iReg) RT_NOEXCEPT
     1773DECL_FORCE_INLINE(int32_t *) iemGRegRefI32(PVMCPUCC pVCpu, uint8_t iReg) RT_NOEXCEPT
    17721774{
    17731775    Assert(iReg < 16);
     
    17831785 * @param   iReg                The register.
    17841786 */
    1785 DECLINLINE(uint64_t *) iemGRegRefU64(PVMCPUCC pVCpu, uint8_t iReg) RT_NOEXCEPT
     1787DECL_FORCE_INLINE(uint64_t *) iemGRegRefU64(PVMCPUCC pVCpu, uint8_t iReg) RT_NOEXCEPT
    17861788{
    17871789    Assert(iReg < 64);
     
    17971799 * @param   iReg                The register.
    17981800 */
    1799 DECLINLINE(int64_t *) iemGRegRefI64(PVMCPUCC pVCpu, uint8_t iReg) RT_NOEXCEPT
     1801DECL_FORCE_INLINE(int64_t *) iemGRegRefI64(PVMCPUCC pVCpu, uint8_t iReg) RT_NOEXCEPT
    18001802{
    18011803    Assert(iReg < 16);
     
    18111813 * @param   iSegReg             The segment selector.
    18121814 */
    1813 DECLINLINE(uint64_t *) iemSRegBaseRefU64(PVMCPUCC pVCpu, uint8_t iSegReg) RT_NOEXCEPT
     1815DECL_FORCE_INLINE(uint64_t *) iemSRegBaseRefU64(PVMCPUCC pVCpu, uint8_t iSegReg) RT_NOEXCEPT
    18141816{
    18151817    Assert(iSegReg < X86_SREG_COUNT);
     
    18271829 * @param   iReg                The register.
    18281830 */
    1829 DECLINLINE(uint8_t) iemGRegFetchU8(PVMCPUCC pVCpu, uint8_t iReg) RT_NOEXCEPT
     1831DECL_FORCE_INLINE(uint8_t) iemGRegFetchU8(PVMCPUCC pVCpu, uint8_t iReg) RT_NOEXCEPT
    18301832{
    18311833    return *iemGRegRefU8(pVCpu, iReg);
     
    18431845 *                              whereas 16 thru 19 maps to AH, CH, DH and BH.
    18441846 */
    1845 DECLINLINE(uint8_t) iemGRegFetchU8Ex(PVMCPUCC pVCpu, uint8_t iRegEx) RT_NOEXCEPT
     1847DECL_FORCE_INLINE(uint8_t) iemGRegFetchU8Ex(PVMCPUCC pVCpu, uint8_t iRegEx) RT_NOEXCEPT
    18461848{
    18471849    return *iemGRegRefU8Ex(pVCpu, iRegEx);
     
    18561858 * @param   iReg                The register.
    18571859 */
    1858 DECLINLINE(uint16_t) iemGRegFetchU16(PVMCPUCC pVCpu, uint8_t iReg) RT_NOEXCEPT
     1860DECL_FORCE_INLINE(uint16_t) iemGRegFetchU16(PVMCPUCC pVCpu, uint8_t iReg) RT_NOEXCEPT
    18591861{
    18601862    Assert(iReg < 16);
     
    18701872 * @param   iReg                The register.
    18711873 */
    1872 DECLINLINE(uint32_t) iemGRegFetchU32(PVMCPUCC pVCpu, uint8_t iReg) RT_NOEXCEPT
     1874DECL_FORCE_INLINE(uint32_t) iemGRegFetchU32(PVMCPUCC pVCpu, uint8_t iReg) RT_NOEXCEPT
    18731875{
    18741876    Assert(iReg < 16);
     
    18841886 * @param   iReg                The register.
    18851887 */
    1886 DECLINLINE(uint64_t) iemGRegFetchU64(PVMCPUCC pVCpu, uint8_t iReg) RT_NOEXCEPT
     1888DECL_FORCE_INLINE(uint64_t) iemGRegFetchU64(PVMCPUCC pVCpu, uint8_t iReg) RT_NOEXCEPT
    18871889{
    18881890    Assert(iReg < 16);
     
    18921894
    18931895/**
     1896 * Stores a 16-bit value to a general purpose register.
     1897 *
     1898 * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
     1899 * @param   iReg                The register.
     1900 * @param   uValue              The value to store.
     1901 */
     1902DECL_FORCE_INLINE(void) iemGRegStoreU16(PVMCPUCC pVCpu, uint8_t iReg, uint16_t uValue) RT_NOEXCEPT
     1903{
     1904    Assert(iReg < 16);
     1905    pVCpu->cpum.GstCtx.aGRegs[iReg].u16 = uValue;
     1906}
     1907
     1908
     1909/**
     1910 * Stores a 32-bit value to a general purpose register, implicitly clearing high
     1911 * values.
     1912 *
     1913 * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
     1914 * @param   iReg                The register.
     1915 * @param   uValue              The value to store.
     1916 */
     1917DECL_FORCE_INLINE(void) iemGRegStoreU32(PVMCPUCC pVCpu, uint8_t iReg, uint32_t uValue) RT_NOEXCEPT
     1918{
     1919    Assert(iReg < 16);
     1920    pVCpu->cpum.GstCtx.aGRegs[iReg].u64 = uValue;
     1921}
     1922
     1923
     1924/**
     1925 * Stores a 64-bit value to a general purpose register.
     1926 *
     1927 * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
     1928 * @param   iReg                The register.
     1929 * @param   uValue              The value to store.
     1930 */
     1931DECL_FORCE_INLINE(void) iemGRegStoreU64(PVMCPUCC pVCpu, uint8_t iReg, uint64_t uValue) RT_NOEXCEPT
     1932{
     1933    Assert(iReg < 16);
     1934    pVCpu->cpum.GstCtx.aGRegs[iReg].u64 = uValue;
     1935}
     1936
     1937
     1938/**
    18941939 * Get the address of the top of the stack.
    18951940 *
    18961941 * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    18971942 */
    1898 DECLINLINE(RTGCPTR) iemRegGetEffRsp(PCVMCPU pVCpu) RT_NOEXCEPT
     1943DECL_FORCE_INLINE(RTGCPTR) iemRegGetEffRsp(PCVMCPU pVCpu) RT_NOEXCEPT
    18991944{
    19001945    if (IEM_IS_64BIT_CODE(pVCpu))
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