VirtualBox

Changeset 101537 in vbox for trunk/src/VBox/VMM


Ignore:
Timestamp:
Oct 21, 2023 2:16:05 AM (16 months ago)
Author:
vboxsync
Message:

VMM/IEM: Undebugged code for IEM_MC_IF_EFL_BIT_SET/IEM_MC_ELSE/IEM_MC_ENDIF support (disabled). bugref:10371

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

Legend:

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

    r101484 r101537  
    28892889    'IEM_MC_IF_EFL_BIT_NOT_SET':                                 (McBlock.parseMcGenericCond,       True,  False, ),
    28902890    'IEM_MC_IF_EFL_BIT_NOT_SET_AND_BITS_EQ':                     (McBlock.parseMcGenericCond,       True,  False, ),
    2891     'IEM_MC_IF_EFL_BIT_SET':                                     (McBlock.parseMcGenericCond,       True,  False, ),
     2891    'IEM_MC_IF_EFL_BIT_SET':                                     (McBlock.parseMcGenericCond,       True,  False,), #True, ),
    28922892    'IEM_MC_IF_EFL_BIT_SET_OR_BITS_NE':                          (McBlock.parseMcGenericCond,       True,  False, ),
    28932893    'IEM_MC_IF_EFL_BITS_EQ':                                     (McBlock.parseMcGenericCond,       True,  False, ),
  • trunk/src/VBox/VMM/VMMAll/IEMAllN8veRecompiler.cpp

    r101536 r101537  
    15871587    pReNative->bmHstRegsWithGstShadow = 0;
    15881588    pReNative->bmGstRegShadows        = 0;
     1589    pReNative->cCondDepth             = 0;
     1590    pReNative->uCondSeqNo             = 0;
    15891591    pReNative->bmVars                 = 0;
    15901592    pReNative->u64ArgVars             = UINT64_MAX;
     
    19341936    /* [kIemNativeGstReg_GprFirst + X86_GREG_x15] = */  { CPUMCTX_OFF_AND_SIZE(r15),                "r15", },
    19351937    /* [kIemNativeGstReg_Pc] = */                       { CPUMCTX_OFF_AND_SIZE(rip),                "rip", },
    1936     /* [kIemNativeGstReg_Rflags] = */                   { CPUMCTX_OFF_AND_SIZE(rflags),             "rflags", },
     1938    /* [kIemNativeGstReg_EFlags] = */                   { CPUMCTX_OFF_AND_SIZE(eflags),             "eflags", },
    19371939    /* [18] = */                                        { UINT32_C(0xfffffff7),                  0, NULL, },
    19381940    /* [19] = */                                        { UINT32_C(0xfffffff5),                  0, NULL, },
     
    35693571    {
    35703572
     3573/** We have to get to the end in recompilation mode, as otherwise we won't
     3574 * generate code for all the IEM_MC_IF_XXX branches. */
    35713575#define IEM_MC_END() \
    3572     } AssertFailedReturn(UINT32_MAX /* shouldn't be reached! */)
    3573 
     3576    } return off
     3577
     3578
     3579/*
     3580 * Standalone CImpl deferals.
     3581 */
    35743582
    35753583#define IEM_MC_DEFER_TO_CIMPL_0_RET_THREADED(a_cbInstr, a_fFlags, a_pfnCImpl) \
     
    36123620
    36133621#define IEM_MC_ADVANCE_RIP_AND_FINISH_THREADED_PC64(a_cbInstr) \
    3614     return iemNativeEmitAddToRip64AndFinishingNoFlags(pReNative, off, (a_cbInstr))
     3622    off = iemNativeEmitAddToRip64AndFinishingNoFlags(pReNative, off, (a_cbInstr)); \
     3623    AssertReturn(off != UINT32_MAX, UINT32_MAX)
    36153624
    36163625/** Same as iemRegAddToRip64AndFinishingNoFlags. */
     
    36333642
    36343643#define IEM_MC_ADVANCE_RIP_AND_FINISH_THREADED_PC32(a_cbInstr) \
    3635     return iemNativeEmitAddToEip32AndFinishingNoFlags(pReNative, off, (a_cbInstr))
     3644    off = iemNativeEmitAddToEip32AndFinishingNoFlags(pReNative, off, (a_cbInstr)); \
     3645    AssertReturn(off != UINT32_MAX, UINT32_MAX)
    36363646
    36373647/** Same as iemRegAddToEip32AndFinishingNoFlags. */
     
    36543664
    36553665#define IEM_MC_ADVANCE_RIP_AND_FINISH_THREADED_PC16(a_cbInstr) \
    3656     return iemNativeEmitAddToIp16AndFinishingNoFlags(pReNative, off, (a_cbInstr))
     3666    off = iemNativeEmitAddToIp16AndFinishingNoFlags(pReNative, off, (a_cbInstr)); \
     3667    AssertReturn(off != UINT32_MAX, UINT32_MAX)
    36573668
    36583669/** Same as iemRegAddToIp16AndFinishingNoFlags. */
     
    36803691
    36813692#define IEM_MC_REL_JMP_S8_AND_FINISH_THREADED_PC64(a_i8, a_cbInstr, a_enmEffOpSize) \
    3682     return iemNativeEmitRip64RelativeJumpAndFinishingNoFlags(pReNative, off, (a_cbInstr), (int8_t)(a_i8), (a_enmEffOpSize), pCallEntry->idxInstr)
     3693    off = iemNativeEmitRip64RelativeJumpAndFinishingNoFlags(pReNative, off, (a_cbInstr), (int8_t)(a_i8), \
     3694                                                            (a_enmEffOpSize), pCallEntry->idxInstr); \
     3695    AssertReturn(off != UINT32_MAX, UINT32_MAX)
     3696
    36833697
    36843698#define IEM_MC_REL_JMP_S16_AND_FINISH_THREADED_PC64(a_i16, a_cbInstr) \
    3685     return iemNativeEmitRip64RelativeJumpAndFinishingNoFlags(pReNative, off, (a_cbInstr), (int16_t)(a_i16), IEMMODE_16BIT, pCallEntry->idxInstr)
     3699    off =  iemNativeEmitRip64RelativeJumpAndFinishingNoFlags(pReNative, off, (a_cbInstr), (int16_t)(a_i16), \
     3700                                                             IEMMODE_16BIT, pCallEntry->idxInstr); \
     3701    AssertReturn(off != UINT32_MAX, UINT32_MAX)
    36863702
    36873703#define IEM_MC_REL_JMP_S32_AND_FINISH_THREADED_PC64(a_i32, a_cbInstr) \
    3688     return iemNativeEmitRip64RelativeJumpAndFinishingNoFlags(pReNative, off, (a_cbInstr), (a_i32), IEMMODE_64BIT, pCallEntry->idxInstr)
     3704    off =  iemNativeEmitRip64RelativeJumpAndFinishingNoFlags(pReNative, off, (a_cbInstr), (a_i32), \
     3705                                                             IEMMODE_64BIT, pCallEntry->idxInstr); \
     3706    AssertReturn(off != UINT32_MAX, UINT32_MAX)
    36893707
    36903708/** Same as iemRegRip64RelativeJumpS8AndFinishNoFlags,
     
    37283746
    37293747#define IEM_MC_REL_JMP_S8_AND_FINISH_THREADED_PC32(a_i8, a_cbInstr, a_enmEffOpSize) \
    3730     return iemNativeEmitEip32RelativeJumpAndFinishingNoFlags(pReNative, off, (a_cbInstr), (int8_t)(a_i8), (a_enmEffOpSize), pCallEntry->idxInstr)
     3748    off = iemNativeEmitEip32RelativeJumpAndFinishingNoFlags(pReNative, off, (a_cbInstr), (int8_t)(a_i8), \
     3749                                                            (a_enmEffOpSize), pCallEntry->idxInstr); \
     3750    AssertReturn(off != UINT32_MAX, UINT32_MAX)
    37313751
    37323752#define IEM_MC_REL_JMP_S16_AND_FINISH_THREADED_PC32(a_i16, a_cbInstr) \
    3733     return iemNativeEmitEip32RelativeJumpAndFinishingNoFlags(pReNative, off, (a_cbInstr), (int16_t)(a_i16), IEMMODE_16BIT, pCallEntry->idxInstr)
     3753    off = iemNativeEmitEip32RelativeJumpAndFinishingNoFlags(pReNative, off, (a_cbInstr), (int16_t)(a_i16), \
     3754                                                            IEMMODE_16BIT, pCallEntry->idxInstr); \
     3755    AssertReturn(off != UINT32_MAX, UINT32_MAX)
    37343756
    37353757#define IEM_MC_REL_JMP_S32_AND_FINISH_THREADED_PC32(a_i32, a_cbInstr) \
    3736     return iemNativeEmitEip32RelativeJumpAndFinishingNoFlags(pReNative, off, (a_cbInstr), (a_i32), IEMMODE_32BIT, pCallEntry->idxInstr)
     3758    off = iemNativeEmitEip32RelativeJumpAndFinishingNoFlags(pReNative, off, (a_cbInstr), (a_i32), \
     3759                                                            IEMMODE_32BIT, pCallEntry->idxInstr); \
     3760    AssertReturn(off != UINT32_MAX, UINT32_MAX)
    37373761
    37383762/** Same as iemRegEip32RelativeJumpS8AndFinishNoFlags,
     
    37753799
    37763800#define IEM_MC_REL_JMP_S8_AND_FINISH_THREADED_PC16(a_i8, a_cbInstr) \
    3777     return iemNativeEmitIp16RelativeJumpAndFinishingNoFlags(pReNative, off, (a_cbInstr), (int8_t)(a_i8), pCallEntry->idxInstr)
     3801    off = iemNativeEmitIp16RelativeJumpAndFinishingNoFlags(pReNative, off, (a_cbInstr), (int8_t)(a_i8), pCallEntry->idxInstr); \
     3802    AssertReturn(off != UINT32_MAX, UINT32_MAX)
    37783803
    37793804#define IEM_MC_REL_JMP_S16_AND_FINISH_THREADED_PC16(a_i16, a_cbInstr) \
    3780     return iemNativeEmitIp16RelativeJumpAndFinishingNoFlags(pReNative, off, (a_cbInstr), (int16_t)(a_i16), pCallEntry->idxInstr)
     3805    off = iemNativeEmitIp16RelativeJumpAndFinishingNoFlags(pReNative, off, (a_cbInstr), (int16_t)(a_i16), pCallEntry->idxInstr); \
     3806    AssertReturn(off != UINT32_MAX, UINT32_MAX)
    37813807
    37823808#define IEM_MC_REL_JMP_S32_AND_FINISH_THREADED_PC16(a_i32, a_cbInstr) \
    3783     return iemNativeEmitIp16RelativeJumpAndFinishingNoFlags(pReNative, off, (a_cbInstr), (a_i32), pCallEntry->idxInstr)
     3809    off = iemNativeEmitIp16RelativeJumpAndFinishingNoFlags(pReNative, off, (a_cbInstr), (a_i32), pCallEntry->idxInstr); \
     3810    AssertReturn(off != UINT32_MAX, UINT32_MAX)
    37843811
    37853812/** Same as iemRegIp16RelativeJumpS8AndFinishNoFlags. */
     
    38023829    /* Free but don't flush the PC register. */
    38033830    iemNativeRegFreeTmp(pReNative, idxPcReg);
     3831
     3832    return off;
     3833}
     3834
     3835
     3836/*
     3837 * Conditionals.
     3838 */
     3839
     3840/**
     3841 * Pushes an IEM_MC_IF_XXX onto the condition stack.
     3842 *
     3843 * @returns Pointer to the condition stack entry on success, NULL on failure
     3844 *          (too many nestings)
     3845 */
     3846DECLINLINE(PIEMNATIVECOND) iemNativeCondPushIf(PIEMRECOMPILERSTATE pReNative)
     3847{
     3848    uint32_t const idxStack = pReNative->cCondDepth;
     3849    AssertReturn(idxStack < RT_ELEMENTS(pReNative->aCondStack), NULL);
     3850
     3851    PIEMNATIVECOND const pEntry = &pReNative->aCondStack[idxStack];
     3852    pReNative->cCondDepth = (uint8_t)(idxStack + 1);
     3853
     3854    uint16_t const uCondSeqNo = ++pReNative->uCondSeqNo;
     3855    pEntry->fInElse       = false;
     3856    pEntry->idxLabelElse  = iemNativeMakeLabel(pReNative, kIemNativeLabelType_Else, UINT32_MAX /*offWhere*/, uCondSeqNo);
     3857    AssertReturn(pEntry->idxLabelElse != UINT32_MAX, NULL);
     3858    pEntry->idxLabelEndIf = iemNativeMakeLabel(pReNative, kIemNativeLabelType_Endif, UINT32_MAX /*offWhere*/, uCondSeqNo);
     3859    AssertReturn(pEntry->idxLabelEndIf != UINT32_MAX, NULL);
     3860
     3861    return pEntry;
     3862}
     3863
     3864
     3865#define IEM_MC_ELSE() } while (0); \
     3866        off = iemNativeEmitElse(pReNative, off); \
     3867        AssertReturn(off != UINT32_MAX, UINT32_MAX); \
     3868        do {
     3869
     3870/** Emits code related to IEM_MC_ELSE. */
     3871DECLINLINE(uint32_t) iemNativeEmitElse(PIEMRECOMPILERSTATE pReNative, uint32_t off)
     3872{
     3873    /* Check sanity and get the conditional stack entry. */
     3874    Assert(off != UINT32_MAX);
     3875    Assert(pReNative->cCondDepth > 0 && pReNative->cCondDepth <= RT_ELEMENTS(pReNative->aCondStack));
     3876    PIEMNATIVECOND const pEntry = &pReNative->aCondStack[pReNative->cCondDepth - 1];
     3877    Assert(!pEntry->fInElse);
     3878
     3879    /* Jump to the endif */
     3880    off = iemNativeEmitJmpToLabel(pReNative, off, pEntry->idxLabelEndIf);
     3881
     3882    /* Define the else label and enter the else part of the condition. */
     3883    pReNative->paLabels[pEntry->idxLabelElse].off = off;
     3884    pEntry->fInElse = true;
     3885
     3886    return off;
     3887}
     3888
     3889
     3890#define IEM_MC_ENDIF() } while (0); \
     3891        off = iemNativeEmitEndIf(pReNative, off); \
     3892        AssertReturn(off != UINT32_MAX, UINT32_MAX)
     3893
     3894/** Emits code related to IEM_MC_ENDIF. */
     3895DECLINLINE(uint32_t) iemNativeEmitEndIf(PIEMRECOMPILERSTATE pReNative, uint32_t off)
     3896{
     3897    /* Check sanity and get the conditional stack entry. */
     3898    Assert(off != UINT32_MAX);
     3899    Assert(pReNative->cCondDepth > 0 && pReNative->cCondDepth <= RT_ELEMENTS(pReNative->aCondStack));
     3900    PIEMNATIVECOND const pEntry = &pReNative->aCondStack[pReNative->cCondDepth - 1];
     3901
     3902    /* Define the endif label and maybe the else one if we're still in the 'if' part. */
     3903    if (!pEntry->fInElse)
     3904        pReNative->paLabels[pEntry->idxLabelElse].off = off;
     3905    else
     3906        Assert(pReNative->paLabels[pEntry->idxLabelElse].off <= off);
     3907    pReNative->paLabels[pEntry->idxLabelEndIf].off    = off;
     3908
     3909    /* Pop the conditional stack.*/
     3910    pReNative->cCondDepth -= 1;
     3911
     3912    return off;
     3913}
     3914
     3915
     3916#define IEM_MC_IF_EFL_BIT_SET(a_fBit) \
     3917        off = iemNativeEmitIfEflagsBitSet(pReNative, off, (a_fBit)); \
     3918        AssertReturn(off != UINT32_MAX, UINT32_MAX); \
     3919        do {
     3920
     3921/** Emits code for IEM_MC_IF_EFL_BIT_SET. */
     3922DECLINLINE(uint32_t) iemNativeEmitIfEflagsBitSet(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint32_t fBitInEfl)
     3923{
     3924    PIEMNATIVECOND pEntry = iemNativeCondPushIf(pReNative);
     3925    AssertReturn(pEntry, UINT32_MAX);
     3926
     3927    /* Get the eflags. */
     3928    uint8_t const idxEflReg = iemNativeRegAllocTmpForGuestReg(pReNative, &off, kIemNativeGstReg_EFlags,
     3929                                                              kIemNativeGstRegUse_ReadOnly);
     3930    AssertReturn(idxEflReg != UINT8_MAX, UINT32_MAX);
     3931
     3932    unsigned const iBitNo = ASMBitFirstSetU32(fBitInEfl) - 1;
     3933    Assert(RT_BIT_32(iBitNo) == fBitInEfl);
     3934
     3935    /* Test and jump. */
     3936    off = iemNativeEmitTestBitInGprAndJmpToLabelIfSet(pReNative, off, idxEflReg, iBitNo, pEntry->idxLabelElse);
     3937
     3938    /* Free but don't flush the EFlags register. */
     3939    iemNativeRegFreeTmp(pReNative, idxEflReg);
    38043940
    38053941    return off;
     
    38954031            off = iemNativeEmitThreadedCall(pReNative, off, pCallEntry);
    38964032        AssertReturn(off != UINT32_MAX, pTb);
     4033        Assert(pReNative->cCondDepth == 0);
    38974034
    38984035        pCallEntry++;
  • trunk/src/VBox/VMM/include/IEMN8veRecompiler.h

    r101535 r101537  
    257257    kIemNativeLabelType_Invalid = 0,
    258258    kIemNativeLabelType_Return,
     259    kIemNativeLabelType_Else,
     260    kIemNativeLabelType_Endif,
    259261    kIemNativeLabelType_NonZeroRetOrPassUp,
    260262    kIemNativeLabelType_RaiseGp0,
     
    285287    kIemNativeFixupType_Rel32,
    286288#elif defined(RT_ARCH_ARM64)
    287     /** ARM64 fixup: PC relative offset at bits 23:5 (CBZ, CBNZ).  */
     289    /** ARM64 fixup: PC relative offset at bits 23:5 (CBZ, CBNZ, B, B.CC).  */
    288290    kIemNativeFixupType_RelImm19At5,
     291    /** ARM64 fixup: PC relative offset at bits 18:5 (TBZ, TBNZ).  */
     292    kIemNativeFixupType_RelImm14At5,
    289293#endif
    290294    kIemNativeFixupType_End
     
    315319    kIemNativeGstReg_GprLast       = 15,
    316320    kIemNativeGstReg_Pc,
    317     kIemNativeGstReg_Rflags,
     321    kIemNativeGstReg_EFlags,            /**< This one is problematic since the higher bits are used internally. */
    318322    /* gap: 18..23 */
    319323    kIemNativeGstReg_SegSelFirst   = 24,
     
    466470
    467471/**
     472 * Conditional stack entry.
     473 */
     474typedef struct IEMNATIVECOND
     475{
     476    /** Set if we're in the "else" part, clear if we're in the "if" before it. */
     477    bool     fInElse;
     478    /** The label for the IEM_MC_ELSE. */
     479    uint32_t idxLabelElse;
     480    /** The label for the IEM_MC_ENDIF. */
     481    uint32_t idxLabelEndIf;
     482} IEMNATIVECOND;
     483/** Pointer to a condition stack entry. */
     484typedef IEMNATIVECOND *PIEMNATIVECOND;
     485
     486
     487/**
    468488 * Native recompiler state.
    469489 */
     
    510530    uint64_t                    bmGstRegShadows;
    511531
     532    /** The current condition stack depth (aCondStack). */
     533    uint8_t                     cCondDepth;
     534    uint8_t                     bPadding;
     535    /** Condition sequence number (for generating unique labels). */
     536    uint16_t                    uCondSeqNo;
     537
    512538    /** Allocation bitmap for aVars. */
    513539    uint32_t                    bmVars;
    514     uint32_t                    u32Align;
    515540    union
    516541    {
     
    528553     * there are no duplicate copies or ambiguities like that). */
    529554    uint8_t                     aidxGstRegShadows[kIemNativeGstReg_End];
     555
     556    /** The condition nesting stack. */
     557    IEMNATIVECOND               aCondStack[4];
     558
    530559    /** Variables and arguments. */
    531560    IEMNATIVEVAR                aVars[16];
     
    658687}
    659688
     689
     690/*********************************************************************************************************************************
     691*   Loads, Stores and Related Stuff.                                                                                             *
     692*********************************************************************************************************************************/
    660693
    661694/**
     
    12981331
    12991332
     1333/*********************************************************************************************************************************
     1334*   Subtraction and Additions                                                                                                    *
     1335*********************************************************************************************************************************/
     1336
     1337
    13001338#ifdef RT_ARCH_AMD64
    13011339/**
     
    15631601
    15641602
     1603
     1604/*********************************************************************************************************************************
     1605*   Bit Operations                                                                                                               *
     1606*********************************************************************************************************************************/
     1607
    15651608/**
    15661609 * Emits code for clearing bits 16 thru 63 in the GPR.
     
    16221665
    16231666
     1667/*********************************************************************************************************************************
     1668*   Compare and Testing                                                                                                          *
     1669*********************************************************************************************************************************/
     1670
     1671
    16241672#ifdef RT_ARCH_ARM64
    16251673/**
     
    16911739}
    16921740
     1741
     1742
     1743/*********************************************************************************************************************************
     1744*   Branching                                                                                                                    *
     1745*********************************************************************************************************************************/
    16931746
    16941747/**
     
    17641817/** Condition type. */
    17651818#ifdef RT_ARCH_AMD64
    1766 typedef uint8_t         IEMNATIVEINSTRCOND;
     1819typedef enum IEMNATIVEINSTRCOND : uint8_t
     1820{
     1821    kIemNativeInstrCond_o = 0,
     1822    kIemNativeInstrCond_no,
     1823    kIemNativeInstrCond_c,
     1824    kIemNativeInstrCond_nc,
     1825    kIemNativeInstrCond_e,
     1826    kIemNativeInstrCond_ne,
     1827    kIemNativeInstrCond_be,
     1828    kIemNativeInstrCond_nbe,
     1829    kIemNativeInstrCond_s,
     1830    kIemNativeInstrCond_ns,
     1831    kIemNativeInstrCond_p,
     1832    kIemNativeInstrCond_np,
     1833    kIemNativeInstrCond_l,
     1834    kIemNativeInstrCond_nl,
     1835    kIemNativeInstrCond_le,
     1836    kIemNativeInstrCond_nle
     1837} IEMNATIVEINSTRCOND;
    17671838#elif defined(RT_ARCH_ARM64)
    17681839typedef ARMV8INSTRCOND  IEMNATIVEINSTRCOND;
     
    17851856    AssertReturn(pbCodeBuf, UINT32_MAX);
    17861857    pbCodeBuf[off++] = 0x0f;
    1787     pbCodeBuf[off++] = enmCond | 0x80;
     1858    pbCodeBuf[off++] = (uint8_t)enmCond | 0x80;
    17881859    AssertReturn(iemNativeAddFixup(pReNative, off, idxLabel, kIemNativeFixupType_Rel32, -4), UINT32_MAX);
    17891860    pbCodeBuf[off++] = 0x00;
     
    18191890
    18201891/**
     1892 * Emits a JZ/JE rel32 / B.EQ imm19 to the given label.
     1893 */
     1894DECLINLINE(uint32_t) iemNativeEmitJzToLabel(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint32_t idxLabel)
     1895{
     1896#ifdef RT_ARCH_AMD64
     1897    return iemNativeEmitJccToLabel(pReNative, off, idxLabel, kIemNativeInstrCond_e);
     1898#elif defined(RT_ARCH_ARM64)
     1899    return iemNativeEmitJccToLabel(pReNative, off, idxLabel, kArmv8InstrCond_Eq);
     1900#else
     1901# error "Port me!"
     1902#endif
     1903}
     1904
     1905/**
    18211906 * Emits a JZ/JE rel32 / B.EQ imm19 to a new label.
    18221907 */
     
    18251910{
    18261911#ifdef RT_ARCH_AMD64
    1827     return iemNativeEmitJccToNewLabel(pReNative, off, enmLabelType, uData, 0x4);
     1912    return iemNativeEmitJccToNewLabel(pReNative, off, enmLabelType, uData, kIemNativeInstrCond_e);
    18281913#elif defined(RT_ARCH_ARM64)
    18291914    return iemNativeEmitJccToNewLabel(pReNative, off, enmLabelType, uData, kArmv8InstrCond_Eq);
     
    18331918}
    18341919
     1920
     1921/**
     1922 * Emits a JNZ/JNE rel32 / B.NE imm19 to the given label.
     1923 */
     1924DECLINLINE(uint32_t) iemNativeEmitJnzToLabel(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint32_t idxLabel)
     1925{
     1926#ifdef RT_ARCH_AMD64
     1927    return iemNativeEmitJccToLabel(pReNative, off, idxLabel, kIemNativeInstrCond_ne);
     1928#elif defined(RT_ARCH_ARM64)
     1929    return iemNativeEmitJccToLabel(pReNative, off, idxLabel, kArmv8InstrCond_Ne);
     1930#else
     1931# error "Port me!"
     1932#endif
     1933}
    18351934
    18361935/**
     
    18411940{
    18421941#ifdef RT_ARCH_AMD64
    1843     return iemNativeEmitJccToNewLabel(pReNative, off, enmLabelType, uData, 0x5);
     1942    return iemNativeEmitJccToNewLabel(pReNative, off, enmLabelType, uData, kIemNativeInstrCond_ne);
    18441943#elif defined(RT_ARCH_ARM64)
    18451944    return iemNativeEmitJccToNewLabel(pReNative, off, enmLabelType, uData, kArmv8InstrCond_Ne);
     
    18491948}
    18501949
     1950
     1951/**
     1952 * Emits a JBE/JNA rel32 / B.LS imm19 to the given label.
     1953 */
     1954DECLINLINE(uint32_t) iemNativeEmitJbeToLabel(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint32_t idxLabel)
     1955{
     1956#ifdef RT_ARCH_AMD64
     1957    return iemNativeEmitJccToLabel(pReNative, off, idxLabel, kIemNativeInstrCond_be);
     1958#elif defined(RT_ARCH_ARM64)
     1959    return iemNativeEmitJccToLabel(pReNative, off, idxLabel, kArmv8InstrCond_Ls);
     1960#else
     1961# error "Port me!"
     1962#endif
     1963}
    18511964
    18521965/**
     
    18571970{
    18581971#ifdef RT_ARCH_AMD64
    1859     return iemNativeEmitJccToNewLabel(pReNative, off, enmLabelType, uData, 0x6);
     1972    return iemNativeEmitJccToNewLabel(pReNative, off, enmLabelType, uData, kIemNativeInstrCond_be);
    18601973#elif defined(RT_ARCH_ARM64)
    18611974    return iemNativeEmitJccToNewLabel(pReNative, off, enmLabelType, uData, kArmv8InstrCond_Ls);
     
    18651978}
    18661979
     1980
     1981/**
     1982 * Emits a JA/JNBE rel32 / B.HI imm19 to the given label.
     1983 */
     1984DECLINLINE(uint32_t) iemNativeEmitJaToLabel(PIEMRECOMPILERSTATE pReNative, uint32_t off, uint32_t idxLabel)
     1985{
     1986#ifdef RT_ARCH_AMD64
     1987    return iemNativeEmitJccToLabel(pReNative, off, idxLabel, kIemNativeInstrCond_nbe);
     1988#elif defined(RT_ARCH_ARM64)
     1989    return iemNativeEmitJccToLabel(pReNative, off, idxLabel, kArmv8InstrCond_Hi);
     1990#else
     1991# error "Port me!"
     1992#endif
     1993}
    18671994
    18681995/**
     
    18732000{
    18742001#ifdef RT_ARCH_AMD64
    1875     return iemNativeEmitJccToNewLabel(pReNative, off, enmLabelType, uData, 0x7);
     2002    return iemNativeEmitJccToNewLabel(pReNative, off, enmLabelType, uData, kIemNativeInstrCond_nbe);
    18762003#elif defined(RT_ARCH_ARM64)
    18772004    return iemNativeEmitJccToNewLabel(pReNative, off, enmLabelType, uData, kArmv8InstrCond_Hi);
     
    18952022    if (offTarget < 128 && offTarget >= -128)
    18962023    {
    1897         pbCodeBuf[off++] = enmCond | 0x70;
     2024        pbCodeBuf[off++] = (uint8_t)enmCond | 0x70;
    18982025        pbCodeBuf[off++] = RT_BYTE1((uint32_t)offTarget);
    18992026    }
     
    19012028    {
    19022029        pbCodeBuf[off++] = 0x0f;
    1903         pbCodeBuf[off++] = enmCond | 0x80;
     2030        pbCodeBuf[off++] = (uint8_t)enmCond | 0x80;
    19042031        pbCodeBuf[off++] = RT_BYTE1((uint32_t)offTarget);
    19052032        pbCodeBuf[off++] = RT_BYTE2((uint32_t)offTarget);
     
    19282055{
    19292056#ifdef RT_ARCH_AMD64
    1930     return iemNativeEmitJccToFixed(pReNative, off, offTarget, 0x4);
     2057    return iemNativeEmitJccToFixed(pReNative, off, offTarget, kIemNativeInstrCond_e);
    19312058#elif defined(RT_ARCH_ARM64)
    19322059    return iemNativeEmitJccToFixed(pReNative, off, offTarget, kArmv8InstrCond_Eq);
     
    19442071{
    19452072#ifdef RT_ARCH_AMD64
    1946     return iemNativeEmitJccToFixed(pReNative, off, offTarget, 0x5);
     2073    return iemNativeEmitJccToFixed(pReNative, off, offTarget, kIemNativeInstrCond_ne);
    19472074#elif defined(RT_ARCH_ARM64)
    19482075    return iemNativeEmitJccToFixed(pReNative, off, offTarget, kArmv8InstrCond_Ne);
     
    19602087{
    19612088#ifdef RT_ARCH_AMD64
    1962     return iemNativeEmitJccToFixed(pReNative, off, offTarget, 0x6);
     2089    return iemNativeEmitJccToFixed(pReNative, off, offTarget, kIemNativeInstrCond_be);
    19632090#elif defined(RT_ARCH_ARM64)
    19642091    return iemNativeEmitJccToFixed(pReNative, off, offTarget, kArmv8InstrCond_Ls);
     
    19762103{
    19772104#ifdef RT_ARCH_AMD64
    1978     return iemNativeEmitJccToFixed(pReNative, off, offTarget, 0x7);
     2105    return iemNativeEmitJccToFixed(pReNative, off, offTarget, kIemNativeInstrCond_nbe);
    19792106#elif defined(RT_ARCH_ARM64)
    19802107    return iemNativeEmitJccToFixed(pReNative, off, offTarget, kArmv8InstrCond_Hi);
     
    20202147
    20212148/**
     2149 * Internal helper, don't call directly.
     2150 */
     2151DECLINLINE(uint32_t) iemNativeEmitTestBitInGprAndJmpToLabelIfCc(PIEMRECOMPILERSTATE pReNative, uint32_t off,
     2152                                                                uint8_t iGprSrc, uint8_t iBitNo, uint32_t idxLabel,
     2153                                                                bool fJmpIfSet)
     2154{
     2155    Assert(iBitNo < 64);
     2156#ifdef RT_ARCH_AMD64
     2157    uint8_t * const pbCodeBuf = iemNativeInstrBufEnsure(pReNative, off, 5);
     2158    AssertReturn(pbCodeBuf, UINT32_MAX);
     2159    if (iBitNo < 8)
     2160    {
     2161        /* test Eb, imm8 */
     2162        if (iGprSrc >= 8)
     2163            pbCodeBuf[off++] = X86_OP_REX_B;
     2164        pbCodeBuf[off++] = 0xf6;
     2165        pbCodeBuf[off++] = X86_MODRM_MAKE(X86_MOD_REG, 0, iGprSrc & 7);
     2166        pbCodeBuf[off++] = (uint8_t)1 << iBitNo;
     2167        off = iemNativeEmitJccToLabel(pReNative, off, idxLabel, fJmpIfSet ? kIemNativeInstrCond_ne : kIemNativeInstrCond_e);
     2168    }
     2169    else
     2170    {
     2171        /* bt Ev, imm8 */
     2172        if (iBitNo >= 32)
     2173            pbCodeBuf[off++] = X86_OP_REX_W | (iGprSrc < 8 ? 0 : X86_OP_REX_B);
     2174        else if (iGprSrc >= 8)
     2175            pbCodeBuf[off++] = X86_OP_REX_B;
     2176        pbCodeBuf[off++] = 0x0f;
     2177        pbCodeBuf[off++] = 0xba;
     2178        pbCodeBuf[off++] = X86_MODRM_MAKE(X86_MOD_REG, 4, iGprSrc & 7);
     2179        pbCodeBuf[off++] = iBitNo;
     2180        off = iemNativeEmitJccToLabel(pReNative, off, idxLabel, fJmpIfSet ? kIemNativeInstrCond_c : kIemNativeInstrCond_nc);
     2181    }
     2182
     2183#elif defined(RT_ARCH_ARM64)
     2184    /* Use the TBNZ instruction here. */
     2185    uint32_t * const pu32CodeBuf = iemNativeInstrBufEnsure(pReNative, off, 1);
     2186    AssertReturn(pu32CodeBuf, UINT32_MAX);
     2187    AssertReturn(iemNativeAddFixup(pReNative, off, idxLabel, kIemNativeFixupType_RelImm14At5), UINT32_MAX);
     2188    pu32CodeBuf[off++] = Armv8A64MkInstrTbzTbnz(fJmpIfSet, 0, iGprSrc, iBitNo);
     2189
     2190#else
     2191# error "Port me!"
     2192#endif
     2193    return off;
     2194}
     2195
     2196
     2197/**
     2198 * Emits a jump to @a idxLabel con the condition that bit@a iBitNo _is_ _set_ in
     2199 * @a iGprSrc.
     2200 *
     2201 * @note On ARM64 the range is only +/-8191 instructions.
     2202 */
     2203DECLINLINE(uint32_t) iemNativeEmitTestBitInGprAndJmpToLabelIfSet(PIEMRECOMPILERSTATE pReNative, uint32_t off,
     2204                                                                 uint8_t iGprSrc, uint8_t iBitNo, uint32_t idxLabel)
     2205{
     2206    return iemNativeEmitTestBitInGprAndJmpToLabelIfCc(pReNative, off, iGprSrc, iBitNo, idxLabel, false /*fJmpIfSet*/);
     2207}
     2208
     2209
     2210/**
     2211 * Emits a jump to @a idxLabel con the condition that bit@a iBitNo _is_ _not_
     2212 * _set_ in @a iGprSrc.
     2213 *
     2214 * @note On ARM64 the range is only +/-8191 instructions.
     2215 */
     2216DECLINLINE(uint32_t) iemNativeEmitTestBitInGprAndJmpToLabelIfNotSet(PIEMRECOMPILERSTATE pReNative, uint32_t off,
     2217                                                                    uint8_t iGprSrc, uint8_t iBitNo, uint32_t idxLabel)
     2218{
     2219    return iemNativeEmitTestBitInGprAndJmpToLabelIfCc(pReNative, off, iGprSrc, iBitNo, idxLabel, true /*fJmpIfSet*/);
     2220}
     2221
     2222
     2223/**
    20222224 * Emits a call to a 64-bit address.
    20232225 */
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