VirtualBox

Changeset 101587 in vbox for trunk


Ignore:
Timestamp:
Oct 25, 2023 12:25:11 PM (15 months ago)
Author:
vboxsync
Message:

VMM/IEM: Native IEM_MC_SUB_GREG_U32 and IEM_MC_SUB_GREG_U64. Covers 32-bit and 64-bit loop instructions. Some cleanups. bugref:10371

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

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMAll/IEMAllInstPython.py

    r101585 r101587  
    27042704    'IEM_MC_ADD_GREG_U64':                                       (McBlock.parseMcGeneric,           True,  False, ),
    27052705    'IEM_MC_ADD_GREG_U64_TO_LOCAL':                              (McBlock.parseMcGeneric,           False, False, ),
    2706     'IEM_MC_ADD_GREG_U8':                                        (McBlock.parseMcGeneric,           True,  False, ),
    27072706    'IEM_MC_ADD_GREG_U8_TO_LOCAL':                               (McBlock.parseMcGeneric,           False, False, ),
    27082707    'IEM_MC_ADD_LOCAL_S16_TO_EFF_ADDR':                          (McBlock.parseMcGeneric,           True,  False, ),
     
    30763075    'IEM_MC_STORE_YREG_U64_ZX_VLMAX':                            (McBlock.parseMcGeneric,           True,  False, ),
    30773076    'IEM_MC_SUB_GREG_U16':                                       (McBlock.parseMcGeneric,           True,  True,  ),
    3078     'IEM_MC_SUB_GREG_U32':                                       (McBlock.parseMcGeneric,           True,  False, ),
    3079     'IEM_MC_SUB_GREG_U64':                                       (McBlock.parseMcGeneric,           True,  False, ),
    3080     'IEM_MC_SUB_GREG_U8':                                        (McBlock.parseMcGeneric,           True,  False, ),
     3077    'IEM_MC_SUB_GREG_U32':                                       (McBlock.parseMcGeneric,           True,  True,  ),
     3078    'IEM_MC_SUB_GREG_U64':                                       (McBlock.parseMcGeneric,           True,  True,  ),
    30813079    'IEM_MC_SUB_LOCAL_U16':                                      (McBlock.parseMcGeneric,           False, False, ),
    30823080    'IEM_MC_UPDATE_FPU_OPCODE_IP':                               (McBlock.parseMcGeneric,           True,  False, ),
  • trunk/src/VBox/VMM/VMMAll/IEMAllN8veRecompiler.cpp

    r101585 r101587  
    46614661 */
    46624662
    4663 #define IEM_MC_SUB_GREG_U16(a_iGReg, a_u16Value) \
    4664     off = iemNativeEmitSubGregU16(pReNative, off, a_iGReg, a_u16Value); \
     4663#define IEM_MC_SUB_GREG_U16(a_iGReg, a_u8SubtrahendConst) \
     4664    off = iemNativeEmitSubGregU16(pReNative, off, a_iGReg, a_u8SubtrahendConst); \
    46654665    AssertReturn(off != UINT32_MAX, UINT32_MAX)
    46664666
    46674667/** Emits code for IEM_MC_SUB_GREG_U16. */
    4668 DECLINLINE(uint32_t) iemNativeEmitSubGregU16(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGReg, uint16_t uSubtrahend)
     4668DECLINLINE(uint32_t) iemNativeEmitSubGregU16(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGReg, uint8_t uSubtrahend)
    46694669{
    46704670    uint8_t const idxGstTmpReg = iemNativeRegAllocTmpForGuestReg(pReNative, &off,
     
    46744674
    46754675#ifdef RT_ARCH_AMD64
    4676     uint8_t *pbCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 6);
     4676    uint8_t *pbCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 4);
    46774677    AssertReturn(pbCodeBuf, UINT32_MAX);
    46784678    pbCodeBuf[off++] = X86_OP_PRF_SIZE_OP;
    46794679    if (idxGstTmpReg >= 8)
    46804680        pbCodeBuf[off++] = X86_OP_REX_B;
    4681     pbCodeBuf[off++] = 0x81;
    4682     pbCodeBuf[off++] = X86_MODRM_MAKE(X86_MOD_REG, 5, idxGstTmpReg & 7);
    4683     pbCodeBuf[off++] = RT_BYTE1(uSubtrahend);
    4684     pbCodeBuf[off++] = RT_BYTE2(uSubtrahend);
     4681    if (uSubtrahend)
     4682    {
     4683        pbCodeBuf[off++] = 0xff; /* dec */
     4684        pbCodeBuf[off++] = X86_MODRM_MAKE(X86_MOD_REG, 1, idxGstTmpReg & 7);
     4685    }
     4686    else
     4687    {
     4688        pbCodeBuf[off++] = 0x81;
     4689        pbCodeBuf[off++] = X86_MODRM_MAKE(X86_MOD_REG, 5, idxGstTmpReg & 7);
     4690        pbCodeBuf[off++] = uSubtrahend;
     4691        pbCodeBuf[off++] = 0;
     4692    }
    46854693
    46864694#else
    4687     uint8_t const idxTmpReg = iemNativeRegAllocTmpImm(pReNative, &off, uSubtrahend);
     4695    uint8_t const idxTmpReg = iemNativeRegAllocTmp(pReNative, &off);
    46884696    AssertReturn(idxTmpReg != UINT8_MAX, UINT32_MAX);
    46894697
     
    46914699    AssertReturn(pu32CodeBuf, UINT32_MAX);
    46924700
    4693     /* sub w2, w1, w2, uxth - kind of performs a 16-bit subtract. */
    4694     /** @todo could also use sub #imm12 variant here if uSubtrahend is in range,
    4695      *        avoiding an const mov instruction.  We don't really need the UxtH
    4696      *        bit either, since the register value is zero extended */
    4697     pu32CodeBuf[off++] = Armv8A64MkInstrAddSubRegExtend(true /*fSub*/, idxTmpReg, idxGstTmpReg, idxTmpReg2, false /*f64Bit*/,
    4698                                                         false /*fSetFlags*/, kArmv8A64InstrExtend_UxtH);
     4701    /* sub tmp, gstgrp, uSubtrahend */
     4702    pu32CodeBuf[off++] = Armv8A64MkInstrAddSubUImm12(true /*fSub*/, idxTmpReg, idxGstTmpReg, uSubtrahend, false /*f64Bit*/);
    46994703
    47004704    /* bfi w1, w2, 0, 16 - moves bits 15:0 from tmpreg2 to tmpreg. */
     
    47124716}
    47134717
     4718
     4719#define IEM_MC_SUB_GREG_U32(a_iGReg, a_u8Const) \
     4720    off = iemNativeEmitSubGregU32U64(pReNative, off, a_iGReg, a_u8Const, false /*f64Bit*/); \
     4721    AssertReturn(off != UINT32_MAX, UINT32_MAX)
     4722
     4723#define IEM_MC_SUB_GREG_U64(a_iGReg, a_u8Const) \
     4724    off = iemNativeEmitSubGregU32U64(pReNative, off, a_iGReg, a_u8Const, true /*f64Bit*/); \
     4725    AssertReturn(off != UINT32_MAX, UINT32_MAX)
     4726
     4727/** Emits code for IEM_MC_SUB_GREG_U32 and IEM_MC_SUB_GREG_U64. */
     4728DECLINLINE(uint32_t) iemNativeEmitSubGregU32U64(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGReg,
     4729                                                uint8_t uSubtrahend, bool f64Bit)
     4730{
     4731    uint8_t const idxGstTmpReg = iemNativeRegAllocTmpForGuestReg(pReNative, &off,
     4732                                                                 (IEMNATIVEGSTREG)(kIemNativeGstReg_GprFirst + iGReg),
     4733                                                                  kIemNativeGstRegUse_ForUpdate);
     4734    AssertReturn(idxGstTmpReg != UINT8_MAX, UINT32_MAX);
     4735
     4736#ifdef RT_ARCH_AMD64
     4737    uint8_t *pbCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 6);
     4738    AssertReturn(pbCodeBuf, UINT32_MAX);
     4739    if (f64Bit)
     4740        pbCodeBuf[off++] = X86_OP_REX_W | (idxGstTmpReg >= 8 ? X86_OP_REX_B : 0);
     4741    else if (idxGstTmpReg >= 8)
     4742        pbCodeBuf[off++] = X86_OP_REX_B;
     4743    if (uSubtrahend == 1)
     4744    {
     4745        /* dec */
     4746        pbCodeBuf[off++] = 0xff;
     4747        pbCodeBuf[off++] = X86_MODRM_MAKE(X86_MOD_REG, 1, idxGstTmpReg & 7);
     4748    }
     4749    else if (uSubtrahend < 128)
     4750    {
     4751        pbCodeBuf[off++] = 0x83; /* sub */
     4752        pbCodeBuf[off++] = X86_MODRM_MAKE(X86_MOD_REG, 5, idxGstTmpReg & 7);
     4753        pbCodeBuf[off++] = RT_BYTE1(uSubtrahend);
     4754    }
     4755    else
     4756    {
     4757        pbCodeBuf[off++] = 0x81; /* sub */
     4758        pbCodeBuf[off++] = X86_MODRM_MAKE(X86_MOD_REG, 5, idxGstTmpReg & 7);
     4759        pbCodeBuf[off++] = RT_BYTE1(uSubtrahend);
     4760        pbCodeBuf[off++] = 0;
     4761        pbCodeBuf[off++] = 0;
     4762        pbCodeBuf[off++] = 0;
     4763    }
     4764
     4765#else
     4766    /* sub tmp, gstgrp, uSubtrahend */
     4767    uint32_t *pu32CodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1);
     4768    AssertReturn(pu32CodeBuf, UINT32_MAX);
     4769    pu32CodeBuf[off++] = Armv8A64MkInstrAddSubUImm12(true /*fSub*/, idxTmpReg, idxGstTmpReg, uSubtrahend, f64Bit);
     4770
     4771#endif
     4772
     4773    IEMNATIVE_ASSERT_INSTR_BUF_ENSURE(pReNative, off);
     4774
     4775    off = iemNativeEmitStoreGprToVCpuU64(pReNative, off, idxGstTmpReg, RT_UOFFSETOF_DYN(VMCPU, cpum.GstCtx.aGRegs[iGReg]));
     4776
     4777    iemNativeRegFreeTmp(pReNative, idxGstTmpReg);
     4778    return off;
     4779}
    47144780
    47154781
  • trunk/src/VBox/VMM/VMMAll/IEMAllThrdFuncs.cpp

    r101387 r101587  
    356356    (a_pu8Dst) = iemGRegRefU8Ex(pVCpu, (a_iGRegEx))
    357357#undef IEM_MC_REF_GREG_U8
    358 
    359 /** Variant of IEM_MC_ADD_GREG_U8 with extended (20) register index. */
    360 #define IEM_MC_ADD_GREG_U8_THREADED(a_iGRegEx, a_u8Value) \
    361     *iemGRegRefU8Ex(pVCpu, (a_iGRegEx)) += (a_u8Value)
    362 #undef IEM_MC_ADD_GREG_U8
    363 
    364 /** Variant of IEM_MC_SUB_GREG_U8 with extended (20) register index. */
    365 #define IEM_MC_SUB_GREG_U8_THREADED(a_iGRegEx,  a_u8Value) \
    366     *iemGRegRefU8Ex(pVCpu, (a_iGRegEx)) -= (a_u8Value)
    367 #undef IEM_MC_SUB_GREG_U8
    368358
    369359/** Variant of IEM_MC_ADD_GREG_U8_TO_LOCAL with extended (20) register index. */
  • trunk/src/VBox/VMM/include/IEMMc.h

    r101484 r101587  
    297297#define IEM_MC_REF_MXCSR(a_pfMxcsr)                     (a_pfMxcsr) = &pVCpu->cpum.GstCtx.XState.x87.MXCSR
    298298
    299 #define IEM_MC_ADD_GREG_U8(a_iGReg, a_u8Value)          *iemGRegRefU8( pVCpu, (a_iGReg)) += (a_u8Value)
    300299#define IEM_MC_ADD_GREG_U16(a_iGReg, a_u16Value)        *iemGRegRefU16(pVCpu, (a_iGReg)) += (a_u16Value)
    301300#define IEM_MC_ADD_GREG_U32(a_iGReg, a_u32Value) \
     
    307306#define IEM_MC_ADD_GREG_U64(a_iGReg, a_u64Value)        *iemGRegRefU64(pVCpu, (a_iGReg)) += (a_u64Value)
    308307
    309 #define IEM_MC_SUB_GREG_U8(a_iGReg,  a_u8Value)         *iemGRegRefU8( pVCpu, (a_iGReg)) -= (a_u8Value)
    310 #define IEM_MC_SUB_GREG_U16(a_iGReg, a_u16Value)        *iemGRegRefU16(pVCpu, (a_iGReg)) -= (a_u16Value)
    311 #define IEM_MC_SUB_GREG_U32(a_iGReg, a_u32Value) \
     308#define IEM_MC_SUB_GREG_U16(a_iGReg, a_u8Const)         *iemGRegRefU16(pVCpu, (a_iGReg)) -= (a_u8Const)
     309#define IEM_MC_SUB_GREG_U32(a_iGReg, a_u8Const) \
    312310    do { \
    313311        uint32_t *pu32Reg = iemGRegRefU32(pVCpu, (a_iGReg)); \
    314         *pu32Reg -= (a_u32Value); \
     312        *pu32Reg -= (a_u8Const); \
    315313        pu32Reg[1] = 0; /* implicitly clear the high bit. */ \
    316314    } while (0)
    317 #define IEM_MC_SUB_GREG_U64(a_iGReg, a_u64Value)        *iemGRegRefU64(pVCpu, (a_iGReg)) -= (a_u64Value)
    318 #define IEM_MC_SUB_LOCAL_U16(a_u16Value, a_u16Const)   do { (a_u16Value) -= a_u16Const; } while (0)
     315#define IEM_MC_SUB_GREG_U64(a_iGReg, a_u8Const)          *iemGRegRefU64(pVCpu, (a_iGReg)) -= (a_u8Const)
     316#define IEM_MC_SUB_LOCAL_U16(a_u16Value, a_u16Const)     do { (a_u16Value) -= a_u16Const; } while (0)
    319317
    320318#define IEM_MC_ADD_GREG_U8_TO_LOCAL(a_u8Value, a_iGReg)    do { (a_u8Value)  += iemGRegFetchU8( pVCpu, (a_iGReg)); } while (0)
  • trunk/src/VBox/VMM/testcase/tstIEMCheckMc.cpp

    r101387 r101587  
    689689#define IEM_MC_REF_MXCSR(a_pfMxcsr)                     do { (a_pfMxcsr) = (uint32_t *)((uintptr_t)0); CHK_PTYPE(uint32_t *, a_pfMxcsr); (void)fMcBegin; (void)fSseRead; } while (0)
    690690
    691 #define IEM_MC_ADD_GREG_U8(a_iGReg, a_u8Value)          do { CHK_GREG_IDX(a_iGReg); CHK_CONST(uint8_t,  a_u8Value);  (void)fMcBegin; } while (0)
    692691#define IEM_MC_ADD_GREG_U16(a_iGReg, a_u16Value)        do { CHK_GREG_IDX(a_iGReg); CHK_CONST(uint16_t, a_u16Value); (void)fMcBegin; } while (0)
    693692#define IEM_MC_ADD_GREG_U32(a_iGReg, a_u32Value)        do { CHK_GREG_IDX(a_iGReg); CHK_CONST(uint32_t, a_u32Value); (void)fMcBegin; } while (0)
    694693#define IEM_MC_ADD_GREG_U64(a_iGReg, a_u64Value)        do { CHK_GREG_IDX(a_iGReg); CHK_CONST(uint64_t, a_u64Value); (void)fMcBegin; } while (0)
    695 #define IEM_MC_SUB_GREG_U8(a_iGReg,  a_u8Value)         do { CHK_GREG_IDX(a_iGReg); CHK_CONST(uint8_t,  a_u8Value);  (void)fMcBegin; } while (0)
    696 #define IEM_MC_SUB_GREG_U16(a_iGReg, a_u16Value)        do { CHK_GREG_IDX(a_iGReg); CHK_CONST(uint16_t, a_u16Value); (void)fMcBegin; } while (0)
    697 #define IEM_MC_SUB_GREG_U32(a_iGReg, a_u32Value)        do { CHK_GREG_IDX(a_iGReg); CHK_CONST(uint32_t, a_u32Value); (void)fMcBegin; } while (0)
    698 #define IEM_MC_SUB_GREG_U64(a_iGReg, a_u64Value)        do { CHK_GREG_IDX(a_iGReg); CHK_CONST(uint64_t, a_u64Value); (void)fMcBegin; } while (0)
     694#define IEM_MC_SUB_GREG_U16(a_iGReg, a_u8Const)         do { CHK_GREG_IDX(a_iGReg); CHK_CONST(uint8_t, a_u8Const); (void)fMcBegin; } while (0)
     695#define IEM_MC_SUB_GREG_U32(a_iGReg, a_u8Const)         do { CHK_GREG_IDX(a_iGReg); CHK_CONST(uint8_t, a_u8Const); (void)fMcBegin; } while (0)
     696#define IEM_MC_SUB_GREG_U64(a_iGReg, a_u8Const)         do { CHK_GREG_IDX(a_iGReg); CHK_CONST(uint8_t, a_u8Const); (void)fMcBegin; } while (0)
    699697#define IEM_MC_SUB_LOCAL_U16(a_u16Value, a_u16Const)    do { CHK_CONST(uint16_t, a_u16Const); (void)fMcBegin; } while (0)
    700698
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