VirtualBox

Changeset 103585 in vbox


Ignore:
Timestamp:
Feb 27, 2024 12:28:50 PM (7 months ago)
Author:
vboxsync
Message:

VMM/IEM: Native translation of IEM_MC_BSWAP_LOCAL_U16/IEM_MC_BSWAP_LOCAL_U32/IEM_MC_BSWAP_LOCAL_U64, bugref:10371

Location:
trunk
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/iprt/armv8.h

    r102770 r103585  
    36473647}
    36483648
     3649
     3650/**
     3651 * A64: Encodes REV instruction.
     3652 *
     3653 * @returns The encoded instruction.
     3654 * @param   iRegDst     The destination register. SP is NOT valid.
     3655 * @param   iRegSrc     The source register. SP is NOT valid, but ZR is
     3656 * @param   f64Bit      true for 64-bit GRPs (default), false for 32-bit GPRs.
     3657 */
     3658DECL_FORCE_INLINE(uint32_t) Armv8A64MkInstrRev(uint32_t iRegDst, uint32_t iRegSrc, bool f64Bit = true)
     3659{
     3660    Assert(iRegDst < 32); Assert(iRegSrc < 32);
     3661
     3662    return ((uint32_t)f64Bit       << 31)
     3663         | (UINT32_C(0x5ac00800))
     3664         | ((uint32_t)f64Bit       << 10)
     3665         | (iRegSrc                <<  5)
     3666         | iRegDst;
     3667}
     3668
     3669
     3670/**
     3671 * A64: Encodes REV16 instruction.
     3672 *
     3673 * @returns The encoded instruction.
     3674 * @param   iRegDst     The destination register. SP is NOT valid.
     3675 * @param   iRegSrc     The source register. SP is NOT valid, but ZR is
     3676 * @param   f64Bit      true for 64-bit GRPs (default), false for 32-bit GPRs.
     3677 */
     3678DECL_FORCE_INLINE(uint32_t) Armv8A64MkInstrRev16(uint32_t iRegDst, uint32_t iRegSrc, bool f64Bit = true)
     3679{
     3680    Assert(iRegDst < 32); Assert(iRegSrc < 32);
     3681
     3682    return ((uint32_t)f64Bit       << 31)
     3683         | (UINT32_C(0x5ac00400))
     3684         | (iRegSrc                <<  5)
     3685         | iRegDst;
     3686}
     3687
     3688
    36493689/** @} */
    36503690
  • trunk/src/VBox/VMM/VMMAll/IEMAllInstPython.py

    r103555 r103585  
    29192919    'IEM_MC_BROADCAST_YREG_U64_ZX_VLMAX':                        (McBlock.parseMcGeneric,           True,  True,  False, ),
    29202920    'IEM_MC_BROADCAST_YREG_U8_ZX_VLMAX':                         (McBlock.parseMcGeneric,           True,  True,  False, ),
    2921     'IEM_MC_BSWAP_LOCAL_U16':                                    (McBlock.parseMcGeneric,           False, False, False, ),
    2922     'IEM_MC_BSWAP_LOCAL_U32':                                    (McBlock.parseMcGeneric,           False, False, False, ),
    2923     'IEM_MC_BSWAP_LOCAL_U64':                                    (McBlock.parseMcGeneric,           False, False, False, ),
     2921    'IEM_MC_BSWAP_LOCAL_U16':                                    (McBlock.parseMcGeneric,           False, False, True, ),
     2922    'IEM_MC_BSWAP_LOCAL_U32':                                    (McBlock.parseMcGeneric,           False, False, True, ),
     2923    'IEM_MC_BSWAP_LOCAL_U64':                                    (McBlock.parseMcGeneric,           False, False, True, ),
    29242924    'IEM_MC_CALC_RM_EFF_ADDR':                                   (McBlock.parseMcGeneric,           False, False, False, ),
    29252925    'IEM_MC_CALL_AIMPL_3':                                       (McBlock.parseMcCallAImpl,         True,  True,  True,  ),
  • trunk/src/VBox/VMM/VMMAll/IEMAllN8veRecompiler.cpp

    r103555 r103585  
    98909890}
    98919891
     9892
     9893#define IEM_MC_BSWAP_LOCAL_U16(a_u16Local) \
     9894    off = iemNativeEmitBswapLocal(pReNative, off, a_u16Local, sizeof(uint16_t))
     9895
     9896#define IEM_MC_BSWAP_LOCAL_U32(a_u32Local) \
     9897    off = iemNativeEmitBswapLocal(pReNative, off, a_u32Local, sizeof(uint32_t))
     9898
     9899#define IEM_MC_BSWAP_LOCAL_U64(a_u64Local) \
     9900    off = iemNativeEmitBswapLocal(pReNative, off, a_u64Local, sizeof(uint64_t))
     9901
     9902/** Emits code for reversing the byte order in a local value.   */
     9903DECL_INLINE_THROW(uint32_t)
     9904iemNativeEmitBswapLocal(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t idxVar, uint8_t cbLocal)
     9905{
     9906    Assert(pReNative->Core.aVars[idxVar].cbVar == cbLocal);
     9907
     9908    uint8_t const idxVarReg = iemNativeVarRegisterAcquire(pReNative, idxVar, &off, true /*fInitialized*/);
     9909
     9910    switch (cbLocal)
     9911    {
     9912        case sizeof(uint16_t): off = iemNativeEmitBswapGpr16(pReNative, off, idxVarReg); break;
     9913        case sizeof(uint32_t): off = iemNativeEmitBswapGpr32(pReNative, off, idxVarReg); break;
     9914        case sizeof(uint64_t): off = iemNativeEmitBswapGpr(pReNative, off, idxVarReg);   break;
     9915        default: AssertFailedBreak();
     9916    }
     9917
     9918    iemNativeVarRegisterRelease(pReNative, idxVar);
     9919    return off;
     9920}
    98929921
    98939922
  • trunk/src/VBox/VMM/include/IEMN8veRecompilerEmit.h

    r103555 r103585  
    49244924
    49254925
     4926/**
     4927 * Emits code for reversing the byte order for a 16-bit value in a 32-bit GPR.
     4928 * @note Bits 63:32 of the destination GPR will be cleared.
     4929 */
     4930DECL_FORCE_INLINE(uint32_t)
     4931iemNativeEmitBswapGpr16(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGpr)
     4932{
     4933#if defined(RT_ARCH_AMD64)
     4934    /*
     4935     * There is no bswap r16 on x86 (the encoding exists but does not work).
     4936     * So just use a rol (gcc -O2 is doing that).
     4937     *
     4938     *    rol r16, 0x8
     4939     */
     4940    uint8_t *pbCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 5);
     4941    pbCodeBuf[off++] = X86_OP_PRF_SIZE_OP;
     4942    if (iGpr >= 8)
     4943        pbCodeBuf[off++] = X86_OP_REX_B;
     4944    pbCodeBuf[off++] = 0xc1;
     4945    pbCodeBuf[off++] = 0xc0 | (iGpr & 7);
     4946    pbCodeBuf[off++] = 0x08;
     4947#elif defined(RT_ARCH_ARM64)
     4948    uint32_t *pu32CodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1);
     4949
     4950    pu32CodeBuf[off++] = Armv8A64MkInstrRev16(iGpr, iGpr, false /*f64Bit*/);
     4951#else
     4952# error "Port me"
     4953#endif
     4954
     4955    IEMNATIVE_ASSERT_INSTR_BUF_ENSURE(pReNative, off);
     4956    return off;
     4957}
     4958
     4959
     4960/**
     4961 * Emits code for reversing the byte order in a 32-bit GPR.
     4962 * @note Bits 63:32 of the destination GPR will be cleared.
     4963 */
     4964DECL_FORCE_INLINE(uint32_t)
     4965iemNativeEmitBswapGpr32(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGpr)
     4966{
     4967#if defined(RT_ARCH_AMD64)
     4968    /* bswap r32 */
     4969    uint8_t *pbCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 3);
     4970
     4971    if (iGpr >= 8)
     4972        pbCodeBuf[off++] = X86_OP_REX_B;
     4973    pbCodeBuf[off++] = 0x0f;
     4974    pbCodeBuf[off++] = 0xc8 | (iGpr & 7);
     4975#elif defined(RT_ARCH_ARM64)
     4976    uint32_t *pu32CodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1);
     4977
     4978    pu32CodeBuf[off++] = Armv8A64MkInstrRev(iGpr, iGpr, false /*f64Bit*/);
     4979#else
     4980# error "Port me"
     4981#endif
     4982
     4983    IEMNATIVE_ASSERT_INSTR_BUF_ENSURE(pReNative, off);
     4984    return off;
     4985}
     4986
     4987
     4988/**
     4989 * Emits code for reversing the byte order in a 64-bit GPR.
     4990 */
     4991DECL_FORCE_INLINE(uint32_t)
     4992iemNativeEmitBswapGpr(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint8_t iGpr)
     4993{
     4994#if defined(RT_ARCH_AMD64)
     4995    /* bswap r64 */
     4996    uint8_t *pbCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 3);
     4997
     4998    if (iGpr >= 8)
     4999        pbCodeBuf[off++] = X86_OP_REX_W | X86_OP_REX_B;
     5000    else
     5001        pbCodeBuf[off++] = X86_OP_REX_W;
     5002    pbCodeBuf[off++] = 0x0f;
     5003    pbCodeBuf[off++] = 0xc8 | (iGpr & 7);
     5004#elif defined(RT_ARCH_ARM64)
     5005    uint32_t *pu32CodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1);
     5006
     5007    pu32CodeBuf[off++] = Armv8A64MkInstrRev(iGpr, iGpr, true /*f64Bit*/);
     5008#else
     5009# error "Port me"
     5010#endif
     5011
     5012    IEMNATIVE_ASSERT_INSTR_BUF_ENSURE(pReNative, off);
     5013    return off;
     5014}
     5015
    49265016
    49275017/*********************************************************************************************************************************
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