VirtualBox

Changeset 103181 in vbox


Ignore:
Timestamp:
Feb 3, 2024 2:13:06 AM (12 months ago)
Author:
vboxsync
Message:

VMM/IEM: Liveness analysis, part 1. bugref:10372

Location:
trunk/src/VBox/VMM
Files:
1 added
12 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/Makefile.kmk

    r102663 r103181  
    263263  VBoxVMM_SOURCES += \
    264264        VMMAll/IEMAllN8veRecompiler.cpp \
    265         VMMAll/IEMAllN8veRecompBltIn.cpp
     265        VMMAll/IEMAllN8veRecompBltIn.cpp \
     266        VMMAll/IEMAllN8veLiveness.cpp
    266267  VBoxVMM_SOURCES.amd64 += \
    267268        VMMAll/IEMAllN8veHlpA.asm
     
    593594  VBoxVMM_INTERMEDIATES += \
    594595        $(VBoxVMM_0_OUTDIR)/CommonGenIncs/IEMNativeFunctions.h \
    595         $(VBoxVMM_0_OUTDIR)/CommonGenIncs/IEMNativeFunctions.cpp.h
     596        $(VBoxVMM_0_OUTDIR)/CommonGenIncs/IEMNativeFunctions.cpp.h \
     597        $(VBoxVMM_0_OUTDIR)/CommonGenIncs/IEMNativeLiveness.cpp.h
    596598 endif
    597599 VBoxVMM_CLEAN         += \
     
    604606        $(VBoxVMM_0_OUTDIR)/CommonGenIncs/IEMThreadedInstructions4.cpp.h \
    605607        $(VBoxVMM_0_OUTDIR)/CommonGenIncs/IEMNativeFunctions.h \
    606         $(VBoxVMM_0_OUTDIR)/CommonGenIncs/IEMNativeFunctions.cpp.h
     608        $(VBoxVMM_0_OUTDIR)/CommonGenIncs/IEMNativeFunctions.cpp.h \
     609        $(VBoxVMM_0_OUTDIR)/CommonGenIncs/IEMNativeLiveness.cpp.h
    607610 $(call KB_FN_AUTO_CMD_DEPS,$(VBoxVMM_0_OUTDIR)/CommonGenIncs/IEMThreadedFunctions.h.ts)
    608611 $(VBoxVMM_0_OUTDIR)/CommonGenIncs/IEMThreadedFunctions.h.ts \
     
    611614 +| $(if-expr defined(VBOX_WITH_IEM_NATIVE_RECOMPILER), $(VBoxVMM_0_OUTDIR)/CommonGenIncs/IEMNativeFunctions.h,) \
    612615 +| $(if-expr defined(VBOX_WITH_IEM_NATIVE_RECOMPILER), $(VBoxVMM_0_OUTDIR)/CommonGenIncs/IEMNativeFunctions.cpp.h,) \
     616 +| $(if-expr defined(VBOX_WITH_IEM_NATIVE_RECOMPILER), $(VBoxVMM_0_OUTDIR)/CommonGenIncs/IEMNativeLiveness.cpp.h,) \
    613617 +| $(VBoxVMM_0_OUTDIR)/CommonGenIncs/IEMThreadedInstructions1.cpp.h \
    614618 +| $(VBoxVMM_0_OUTDIR)/CommonGenIncs/IEMThreadedInstructions2.cpp.h \
     
    648652                $(if-expr defined(VBOX_WITH_IEM_NATIVE_RECOMPILER), \
    649653                        --native \
    650                         --out-n8ve-funcs-hdr "$(VBoxVMM_0_OUTDIR)/CommonGenIncs/IEMNativeFunctions.h.ts" \
    651                         --out-n8ve-funcs-cpp "$(VBoxVMM_0_OUTDIR)/CommonGenIncs/IEMNativeFunctions.cpp.h.ts" \
     654                        --out-n8ve-funcs-hdr    "$(VBoxVMM_0_OUTDIR)/CommonGenIncs/IEMNativeFunctions.h.ts" \
     655                        --out-n8ve-funcs-cpp    "$(VBoxVMM_0_OUTDIR)/CommonGenIncs/IEMNativeFunctions.cpp.h.ts" \
     656                        --out-n8ve-liveness-cpp "$(VBoxVMM_0_OUTDIR)/CommonGenIncs/IEMNativeLiveness.cpp.h.ts" \
    652657                ,)
    653658        $(QUIET)$(CP) -v -f --changed -- \
     
    676681                "$(VBoxVMM_0_OUTDIR)/CommonGenIncs/IEMNativeFunctions.cpp.h.ts" \
    677682                "$(VBoxVMM_0_OUTDIR)/CommonGenIncs/IEMNativeFunctions.cpp.h"
     683        $(QUIET)$(CP) -v -f --changed -- \
     684                "$(VBoxVMM_0_OUTDIR)/CommonGenIncs/IEMNativeLiveness.cpp.h.ts" \
     685                "$(VBoxVMM_0_OUTDIR)/CommonGenIncs/IEMNativeLiveness.cpp.h"
    678686 endif
    679687        $(QUIET)$(RM) -f -- \
  • trunk/src/VBox/VMM/VMMAll/IEMAllInstPython.py

    r103155 r103181  
    30173017    'IEM_MC_LOCAL_ASSIGN':                                       (McBlock.parseMcLocalAssign,       False, False, True,  ),
    30183018    'IEM_MC_LOCAL_CONST':                                        (McBlock.parseMcLocalConst,        False, False, True,  ),
     3019    'IEM_MC_NOREF':                                              (McBlock.parseMcGeneric,           False, False, True,  ),
    30193020    'IEM_MC_MAYBE_RAISE_AVX_RELATED_XCPT':                       (McBlock.parseMcGeneric,           True,  True,  False, ),
    30203021    'IEM_MC_MAYBE_RAISE_DEVICE_NOT_AVAILABLE':                   (McBlock.parseMcGeneric,           True,  True,  False, ),
  • trunk/src/VBox/VMM/VMMAll/IEMAllInstTwoByte0f.cpp.h

    r102978 r103181  
    20562056    IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
    20572057    /* Currently a NOP. */
    2058     NOREF(GCPtrEffSrc);
     2058    IEM_MC_NOREF(GCPtrEffSrc);
    20592059    IEM_MC_ADVANCE_RIP_AND_FINISH();
    20602060    IEM_MC_END();
     
    32553255        IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
    32563256        /* Currently a NOP. */
    3257         NOREF(GCPtrEffSrc);
     3257        IEM_MC_NOREF(GCPtrEffSrc);
    32583258        IEM_MC_ADVANCE_RIP_AND_FINISH();
    32593259        IEM_MC_END();
     
    32833283        IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
    32843284        /* Currently a NOP. */
    3285         NOREF(GCPtrEffSrc);
     3285        IEM_MC_NOREF(GCPtrEffSrc);
    32863286        IEM_MC_ADVANCE_RIP_AND_FINISH();
    32873287        IEM_MC_END();
  • trunk/src/VBox/VMM/VMMAll/IEMAllN8vePython.py

    r103155 r103181  
    436436        return dFreedVars;
    437437
    438     def __morphStatements(self, aoStmts):
     438    def __morphStatements(self, aoStmts, fForLiveness):
    439439        """
    440440        Morphs the given statement list into something more suitable for
     
    450450        Returns a new list of statements.
    451451        """
     452        _ = fForLiveness;
    452453
    453454        #
     
    498499
    499500
    500     def renderCode(self, cchIndent):
     501    def renderCode(self, cchIndent, fForLiveness = False):
    501502        """
    502503        Returns the native recompiler function body for this threaded variant.
    503504        """
    504         return iai.McStmt.renderCodeForList(self.__morphStatements(self.oVariation.aoStmtsForThreadedFunction), cchIndent);
     505        return iai.McStmt.renderCodeForList(self.__morphStatements(self.oVariation.aoStmtsForThreadedFunction, fForLiveness),
     506                                            cchIndent);
    505507
    506508    @staticmethod
  • trunk/src/VBox/VMM/VMMAll/IEMAllN8veRecompBltIn.cpp

    r102883 r103181  
    117117    RT_NOREF(pReNative, pCallEntry);
    118118    return off;
     119}
     120
     121IEM_DECL_IEMNATIVELIVENESSFUNC_DEF(iemNativeLivenessFunc_BltIn_Nop)
     122{
     123    *pOutgoing = *pIncoming;
     124    RT_NOREF(pCallEntry);
    119125}
    120126
     
    159165}
    160166
     167IEM_DECL_IEMNATIVELIVENESSFUNC_DEF(iemNativeLivenessFunc_BltIn_LogCpuState)
     168{
     169    IEM_LIVENESS_RAW_INIT_WITH_XCPT_OR_CALL(pOutgoing, pIncoming);
     170    RT_NOREF(pCallEntry);
     171}
     172
    161173
    162174/**
     
    169181    uint64_t const     fGstShwFlush = pCallEntry->auParams[2];
    170182    return iemNativeEmitCImplCall(pReNative, off, pCallEntry->idxInstr, fGstShwFlush, (uintptr_t)pfnCImpl, cbInstr, 0, 0, 0, 0);
     183}
     184
     185IEM_DECL_IEMNATIVELIVENESSFUNC_DEF(iemNativeLivenessFunc_BltIn_DeferToCImpl0)
     186{
     187    IEM_LIVENESS_RAW_INIT_WITH_XCPT_OR_CALL(pOutgoing, pIncoming);
     188    RT_NOREF(pCallEntry);
    171189}
    172190
     
    261279}
    262280
     281IEM_DECL_IEMNATIVELIVENESSFUNC_DEF(iemNativeLivenessFunc_BltIn_CheckIrq)
     282{
     283    IEM_LIVENESS_RAW_INIT_WITH_XCPT_OR_CALL(pOutgoing, pIncoming);
     284    RT_NOREF(pCallEntry);
     285}
     286
    263287
    264288/**
     
    279303    pReNative->fExec = fExpectedExec & IEMTB_F_IEM_F_MASK;
    280304    return off;
     305}
     306
     307IEM_DECL_IEMNATIVELIVENESSFUNC_DEF(iemNativeLivenessFunc_BltIn_CheckMode)
     308{
     309    IEM_LIVENESS_RAW_INIT_WITH_XCPT_OR_CALL(pOutgoing, pIncoming);
     310    RT_NOREF(pCallEntry);
    281311}
    282312
     
    306336#define BODY_CHECK_CS_LIM(a_cbInstr) \
    307337    off = iemNativeEmitBltInCheckCsLim(pReNative, off, (a_cbInstr))
     338
     339#define LIVENESS_CHECK_CS_LIM(a_pOutgoing) \
     340    IEM_LIVENESS_RAW_SEG_LIMIT_INPUT(a_pOutgoing, X86_SREG_CS)
    308341
    309342DECL_FORCE_INLINE(uint32_t)
     
    411444    off = iemNativeEmitBltInConsiderLimChecking(pReNative, off)
    412445
     446#define LIVENESS_CONSIDER_CS_LIM_CHECKING(a_pOutgoing) \
     447    IEM_LIVENESS_RAW_SEG_LIMIT_INPUT(a_pOutgoing, X86_SREG_CS); \
     448    IEM_LIVENESS_RAW_SEG_BASE_INPUT(a_pOutgoing, X86_SREG_CS)
     449
    413450DECL_FORCE_INLINE(uint32_t)
    414451iemNativeEmitBltInConsiderLimChecking(PIEMRECOMPILERSTATE pReNative, uint32_t off)
     
    490527    RT_NOREF(a_cbInstr); \
    491528    off = iemNativeEmitBltInCheckOpcodes(pReNative, off, (a_pTb), (a_idxRange), (a_offRange))
     529
     530#define LIVENESS_CHECK_OPCODES(a_pOutgoing) ((void)0)
    492531
    493532#if 0 /* debugging aid */
     
    10061045    off = iemNativeEmitBltInCheckPcAfterBranch(pReNative, off, a_pTb, a_idxRange, a_offRange)
    10071046
     1047#define LIVENESS_CHECK_PC_AFTER_BRANCH(a_pOutgoing, a_pCallEntry) \
     1048    if (!IEM_F_MODE_X86_IS_FLAT((uint32_t)(a_pCallEntry)->auParams[0] >> 8))  \
     1049        IEM_LIVENESS_RAW_SEG_BASE_INPUT(a_pOutgoing, X86_SREG_CS); \
     1050    else do { } while (0)
     1051
    10081052DECL_FORCE_INLINE(uint32_t)
    10091053iemNativeEmitBltInCheckPcAfterBranch(PIEMRECOMPILERSTATE pReNative, uint32_t off, PCIEMTB pTb,
     
    11831227    off = iemNativeEmitBltLoadTlbForNewPage(pReNative, off, pTb, a_idxRange, a_offInstr)
    11841228
     1229#define LIVENESS_LOAD_TLB_FOR_NEW_PAGE(a_pOutgoing, a_pCallEntry) \
     1230    if (!IEM_F_MODE_X86_IS_FLAT((uint32_t)(a_pCallEntry)->auParams[0] >> 8)) \
     1231        IEM_LIVENESS_RAW_SEG_BASE_INPUT(a_pOutgoing, X86_SREG_CS); \
     1232    else do { } while (0)
     1233
    11851234DECL_FORCE_INLINE(uint32_t)
    11861235iemNativeEmitBltLoadTlbForNewPage(PIEMRECOMPILERSTATE pReNative, uint32_t off, PCIEMTB pTb, uint8_t idxRange, uint8_t offInstr)
     
    12901339    RT_NOREF(a_cbInstr); \
    12911340    off = iemNativeEmitBltLoadTlbAfterBranch(pReNative, off, pTb, a_idxRange)
     1341
     1342#define LIVENESS_LOAD_TLB_AFTER_BRANCH(a_pOutgoing, a_pCallEntry) \
     1343    if (!IEM_F_MODE_X86_IS_FLAT((uint32_t)(a_pCallEntry)->auParams[0] >> 8)) \
     1344        IEM_LIVENESS_RAW_SEG_BASE_INPUT(a_pOutgoing, X86_SREG_CS); \
     1345    else do { } while (0)
    12921346
    12931347DECL_FORCE_INLINE(uint32_t)
     
    15851639IEM_DECL_IEMNATIVERECOMPFUNC_DEF(iemNativeRecompFunc_BltIn_CheckCsLim)
    15861640{
    1587     uint32_t const cbInstr = (uint32_t)pCallEntry->auParams[0];
     1641    uint32_t const cbInstr = (uint8_t)pCallEntry->auParams[0];
    15881642    BODY_SET_CUR_INSTR();
    15891643    BODY_FLUSH_PENDING_WRITES();
     
    15911645    return off;
    15921646}
     1647
     1648IEM_DECL_IEMNATIVELIVENESSFUNC_DEF(iemNativeLivenessFunc_BltIn_CheckCsLim)
     1649{
     1650    IEM_LIVENESS_RAW_INIT_WITH_XCPT_OR_CALL(pOutgoing, pIncoming);
     1651    LIVENESS_CHECK_CS_LIM(pOutgoing);
     1652    RT_NOREF(pCallEntry);
     1653}
    15931654#endif
    15941655
     
    16021663{
    16031664    PCIEMTB const  pTb      = pReNative->pTbOrg;
    1604     uint32_t const cbInstr  = (uint32_t)pCallEntry->auParams[0];
     1665    uint32_t const cbInstr  = (uint8_t)pCallEntry->auParams[0];
    16051666    uint32_t const idxRange = (uint32_t)pCallEntry->auParams[1];
    16061667    uint32_t const offRange = (uint32_t)pCallEntry->auParams[2];
     
    16111672    return off;
    16121673}
     1674
     1675IEM_DECL_IEMNATIVELIVENESSFUNC_DEF(iemNativeLivenessFunc_BltIn_CheckCsLimAndOpcodes)
     1676{
     1677    IEM_LIVENESS_RAW_INIT_WITH_XCPT_OR_CALL(pOutgoing, pIncoming);
     1678    LIVENESS_CHECK_CS_LIM(pOutgoing);
     1679    LIVENESS_CHECK_OPCODES(pOutgoing);
     1680    RT_NOREF(pCallEntry);
     1681}
    16131682#endif
    16141683
     
    16221691{
    16231692    PCIEMTB const  pTb      = pReNative->pTbOrg;
    1624     uint32_t const cbInstr  = (uint32_t)pCallEntry->auParams[0];
     1693    uint32_t const cbInstr  = (uint8_t)pCallEntry->auParams[0];
    16251694    uint32_t const idxRange = (uint32_t)pCallEntry->auParams[1];
    16261695    uint32_t const offRange = (uint32_t)pCallEntry->auParams[2];
     
    16301699    return off;
    16311700}
     1701
     1702IEM_DECL_IEMNATIVELIVENESSFUNC_DEF(iemNativeLivenessFunc_BltIn_CheckOpcodes)
     1703{
     1704    IEM_LIVENESS_RAW_INIT_WITH_XCPT_OR_CALL(pOutgoing, pIncoming);
     1705    LIVENESS_CHECK_OPCODES(pOutgoing);
     1706    RT_NOREF(pCallEntry);
     1707}
    16321708#endif
    16331709
     
    16411717{
    16421718    PCIEMTB const  pTb      = pReNative->pTbOrg;
    1643     uint32_t const cbInstr  = (uint32_t)pCallEntry->auParams[0];
     1719    uint32_t const cbInstr  = (uint8_t)pCallEntry->auParams[0];
    16441720    uint32_t const idxRange = (uint32_t)pCallEntry->auParams[1];
    16451721    uint32_t const offRange = (uint32_t)pCallEntry->auParams[2];
     
    16501726    return off;
    16511727}
     1728
     1729IEM_DECL_IEMNATIVELIVENESSFUNC_DEF(iemNativeLivenessFunc_BltIn_CheckOpcodesConsiderCsLim)
     1730{
     1731    IEM_LIVENESS_RAW_INIT_WITH_XCPT_OR_CALL(pOutgoing, pIncoming);
     1732    LIVENESS_CONSIDER_CS_LIM_CHECKING(pOutgoing);
     1733    LIVENESS_CHECK_OPCODES(pOutgoing);
     1734    RT_NOREF(pCallEntry);
     1735}
    16521736#endif
    16531737
     
    16671751{
    16681752    PCIEMTB const  pTb      = pReNative->pTbOrg;
    1669     uint32_t const cbInstr  = (uint32_t)pCallEntry->auParams[0];
     1753    uint32_t const cbInstr  = (uint8_t)pCallEntry->auParams[0];
    16701754    uint32_t const idxRange = (uint32_t)pCallEntry->auParams[1];
    16711755    uint32_t const offRange = (uint32_t)pCallEntry->auParams[2];
     
    16791763    return off;
    16801764}
     1765
     1766IEM_DECL_IEMNATIVELIVENESSFUNC_DEF(iemNativeLivenessFunc_BltIn_CheckCsLimAndPcAndOpcodes)
     1767{
     1768    IEM_LIVENESS_RAW_INIT_WITH_XCPT_OR_CALL(pOutgoing, pIncoming);
     1769    LIVENESS_CHECK_CS_LIM(pOutgoing);
     1770    LIVENESS_CHECK_PC_AFTER_BRANCH(pOutgoing, pCallEntry);
     1771    LIVENESS_CHECK_OPCODES(pOutgoing);
     1772    RT_NOREF(pCallEntry);
     1773}
    16811774#endif
    16821775
     
    16921785{
    16931786    PCIEMTB const  pTb      = pReNative->pTbOrg;
    1694     uint32_t const cbInstr  = (uint32_t)pCallEntry->auParams[0];
     1787    uint32_t const cbInstr  = (uint8_t)pCallEntry->auParams[0];
    16951788    uint32_t const idxRange = (uint32_t)pCallEntry->auParams[1];
    16961789    uint32_t const offRange = (uint32_t)pCallEntry->auParams[2];
     
    17031796    return off;
    17041797}
     1798
     1799IEM_DECL_IEMNATIVELIVENESSFUNC_DEF(iemNativeLivenessFunc_BltIn_CheckPcAndOpcodes)
     1800{
     1801    IEM_LIVENESS_RAW_INIT_WITH_XCPT_OR_CALL(pOutgoing, pIncoming);
     1802    LIVENESS_CHECK_PC_AFTER_BRANCH(pOutgoing, pCallEntry);
     1803    LIVENESS_CHECK_OPCODES(pOutgoing);
     1804    RT_NOREF(pCallEntry);
     1805}
    17051806#endif
    17061807
     
    17171818{
    17181819    PCIEMTB const  pTb      = pReNative->pTbOrg;
    1719     uint32_t const cbInstr  = (uint32_t)pCallEntry->auParams[0];
     1820    uint32_t const cbInstr  = (uint8_t)pCallEntry->auParams[0];
    17201821    uint32_t const idxRange = (uint32_t)pCallEntry->auParams[1];
    17211822    uint32_t const offRange = (uint32_t)pCallEntry->auParams[2];
     
    17291830    return off;
    17301831}
     1832
     1833IEM_DECL_IEMNATIVELIVENESSFUNC_DEF(iemNativeLivenessFunc_BltIn_CheckPcAndOpcodesConsiderCsLim)
     1834{
     1835    IEM_LIVENESS_RAW_INIT_WITH_XCPT_OR_CALL(pOutgoing, pIncoming);
     1836    LIVENESS_CONSIDER_CS_LIM_CHECKING(pOutgoing);
     1837    LIVENESS_CHECK_PC_AFTER_BRANCH(pOutgoing, pCallEntry);
     1838    LIVENESS_CHECK_OPCODES(pOutgoing);
     1839    RT_NOREF(pCallEntry);
     1840}
    17311841#endif
    17321842
     
    17451855{
    17461856    PCIEMTB const  pTb      = pReNative->pTbOrg;
    1747     uint32_t const cbInstr  = (uint32_t)pCallEntry->auParams[0];
     1857    uint32_t const cbInstr  = (uint8_t)pCallEntry->auParams[0];
    17481858    uint32_t const idxRange = (uint32_t)pCallEntry->auParams[1];
    17491859    uint32_t const offRange = (uint32_t)pCallEntry->auParams[2];
     
    17581868    return off;
    17591869}
     1870
     1871IEM_DECL_IEMNATIVELIVENESSFUNC_DEF(iemNativeLivenessFunc_BltIn_CheckCsLimAndOpcodesLoadingTlb)
     1872{
     1873    IEM_LIVENESS_RAW_INIT_WITH_XCPT_OR_CALL(pOutgoing, pIncoming);
     1874    LIVENESS_CHECK_CS_LIM(pOutgoing);
     1875    LIVENESS_LOAD_TLB_AFTER_BRANCH(pOutgoing, pCallEntry);
     1876    LIVENESS_CHECK_OPCODES(pOutgoing);
     1877    RT_NOREF(pCallEntry);
     1878}
    17601879#endif
    17611880
     
    17741893{
    17751894    PCIEMTB const  pTb      = pReNative->pTbOrg;
    1776     uint32_t const cbInstr  = (uint32_t)pCallEntry->auParams[0];
     1895    uint32_t const cbInstr  = (uint8_t)pCallEntry->auParams[0];
    17771896    uint32_t const idxRange = (uint32_t)pCallEntry->auParams[1];
    17781897    uint32_t const offRange = (uint32_t)pCallEntry->auParams[2];
     
    17861905    return off;
    17871906}
     1907
     1908IEM_DECL_IEMNATIVELIVENESSFUNC_DEF(iemNativeLivenessFunc_BltIn_CheckOpcodesLoadingTlb)
     1909{
     1910    IEM_LIVENESS_RAW_INIT_WITH_XCPT_OR_CALL(pOutgoing, pIncoming);
     1911    LIVENESS_LOAD_TLB_AFTER_BRANCH(pOutgoing, pCallEntry);
     1912    LIVENESS_CHECK_OPCODES(pOutgoing);
     1913    RT_NOREF(pCallEntry);
     1914}
    17881915#endif
    17891916
     
    18021929{
    18031930    PCIEMTB const  pTb      = pReNative->pTbOrg;
    1804     uint32_t const cbInstr  = (uint32_t)pCallEntry->auParams[0];
     1931    uint32_t const cbInstr  = (uint8_t)pCallEntry->auParams[0];
    18051932    uint32_t const idxRange = (uint32_t)pCallEntry->auParams[1];
    18061933    uint32_t const offRange = (uint32_t)pCallEntry->auParams[2];
     
    18151942    return off;
    18161943}
     1944
     1945IEM_DECL_IEMNATIVELIVENESSFUNC_DEF(iemNativeLivenessFunc_BltIn_CheckOpcodesLoadingTlbConsiderCsLim)
     1946{
     1947    IEM_LIVENESS_RAW_INIT_WITH_XCPT_OR_CALL(pOutgoing, pIncoming);
     1948    LIVENESS_CONSIDER_CS_LIM_CHECKING(pOutgoing);
     1949    LIVENESS_LOAD_TLB_AFTER_BRANCH(pOutgoing, pCallEntry);
     1950    LIVENESS_CHECK_OPCODES(pOutgoing);
     1951    RT_NOREF(pCallEntry);
     1952}
    18171953#endif
    18181954
     
    18371973{
    18381974    PCIEMTB const  pTb         = pReNative->pTbOrg;
    1839     uint32_t const cbInstr     = (uint32_t)pCallEntry->auParams[0];
     1975    uint32_t const cbInstr     = (uint8_t)pCallEntry->auParams[0];
    18401976    uint32_t const cbStartPage = (uint32_t)(pCallEntry->auParams[0] >> 32);
    18411977    uint32_t const idxRange1   = (uint32_t)pCallEntry->auParams[1];
     
    18501986    return off;
    18511987}
     1988
     1989IEM_DECL_IEMNATIVELIVENESSFUNC_DEF(iemNativeLivenessFunc_BltIn_CheckCsLimAndOpcodesAcrossPageLoadingTlb)
     1990{
     1991    IEM_LIVENESS_RAW_INIT_WITH_XCPT_OR_CALL(pOutgoing, pIncoming);
     1992    LIVENESS_CHECK_CS_LIM(pOutgoing);
     1993    LIVENESS_CHECK_OPCODES(pOutgoing);
     1994    LIVENESS_LOAD_TLB_FOR_NEW_PAGE(pOutgoing, pCallEntry);
     1995    RT_NOREF(pCallEntry);
     1996}
    18521997#endif
    18531998
     
    18672012{
    18682013    PCIEMTB const  pTb         = pReNative->pTbOrg;
    1869     uint32_t const cbInstr     = (uint32_t)pCallEntry->auParams[0];
     2014    uint32_t const cbInstr     = (uint8_t)pCallEntry->auParams[0];
    18702015    uint32_t const cbStartPage = (uint32_t)(pCallEntry->auParams[0] >> 32);
    18712016    uint32_t const idxRange1   = (uint32_t)pCallEntry->auParams[1];
     
    18792024    return off;
    18802025}
     2026
     2027IEM_DECL_IEMNATIVELIVENESSFUNC_DEF(iemNativeLivenessFunc_BltIn_CheckOpcodesAcrossPageLoadingTlb)
     2028{
     2029    IEM_LIVENESS_RAW_INIT_WITH_XCPT_OR_CALL(pOutgoing, pIncoming);
     2030    LIVENESS_CHECK_OPCODES(pOutgoing);
     2031    LIVENESS_LOAD_TLB_FOR_NEW_PAGE(pOutgoing, pCallEntry);
     2032    RT_NOREF(pCallEntry);
     2033}
    18812034#endif
    18822035
     
    18972050{
    18982051    PCIEMTB const  pTb         = pReNative->pTbOrg;
    1899     uint32_t const cbInstr     = (uint32_t)pCallEntry->auParams[0];
     2052    uint32_t const cbInstr     = (uint8_t)pCallEntry->auParams[0];
    19002053    uint32_t const cbStartPage = (uint32_t)(pCallEntry->auParams[0] >> 32);
    19012054    uint32_t const idxRange1   = (uint32_t)pCallEntry->auParams[1];
     
    19102063    return off;
    19112064}
     2065
     2066IEM_DECL_IEMNATIVELIVENESSFUNC_DEF(iemNativeLivenessFunc_BltIn_CheckOpcodesAcrossPageLoadingTlbConsiderCsLim)
     2067{
     2068    IEM_LIVENESS_RAW_INIT_WITH_XCPT_OR_CALL(pOutgoing, pIncoming);
     2069    LIVENESS_CONSIDER_CS_LIM_CHECKING(pOutgoing);
     2070    LIVENESS_CHECK_OPCODES(pOutgoing);
     2071    LIVENESS_LOAD_TLB_FOR_NEW_PAGE(pOutgoing, pCallEntry);
     2072    RT_NOREF(pCallEntry);
     2073}
    19122074#endif
    19132075
     
    19252087{
    19262088    PCIEMTB const  pTb         = pReNative->pTbOrg;
    1927     uint32_t const cbInstr     = (uint32_t)pCallEntry->auParams[0];
     2089    uint32_t const cbInstr     = (uint8_t)pCallEntry->auParams[0];
    19282090    uint32_t const cbStartPage = (uint32_t)(pCallEntry->auParams[0] >> 32);
    19292091    uint32_t const idxRange1   = (uint32_t)pCallEntry->auParams[1];
     
    19372099    return off;
    19382100}
     2101
     2102IEM_DECL_IEMNATIVELIVENESSFUNC_DEF(iemNativeLivenessFunc_BltIn_CheckCsLimAndOpcodesOnNextPageLoadingTlb)
     2103{
     2104    IEM_LIVENESS_RAW_INIT_WITH_XCPT_OR_CALL(pOutgoing, pIncoming);
     2105    LIVENESS_CHECK_CS_LIM(pOutgoing);
     2106    LIVENESS_LOAD_TLB_FOR_NEW_PAGE(pOutgoing, pCallEntry);
     2107    LIVENESS_CHECK_OPCODES(pOutgoing);
     2108    RT_NOREF(pCallEntry);
     2109}
    19392110#endif
    19402111
     
    19522123{
    19532124    PCIEMTB const  pTb         = pReNative->pTbOrg;
    1954     uint32_t const cbInstr     = (uint32_t)pCallEntry->auParams[0];
     2125    uint32_t const cbInstr     = (uint8_t)pCallEntry->auParams[0];
    19552126    uint32_t const cbStartPage = (uint32_t)(pCallEntry->auParams[0] >> 32);
    19562127    uint32_t const idxRange1   = (uint32_t)pCallEntry->auParams[1];
     
    19632134    return off;
    19642135}
     2136
     2137IEM_DECL_IEMNATIVELIVENESSFUNC_DEF(iemNativeLivenessFunc_BltIn_CheckOpcodesOnNextPageLoadingTlb)
     2138{
     2139    IEM_LIVENESS_RAW_INIT_WITH_XCPT_OR_CALL(pOutgoing, pIncoming);
     2140    LIVENESS_LOAD_TLB_FOR_NEW_PAGE(pOutgoing, pCallEntry);
     2141    LIVENESS_CHECK_OPCODES(pOutgoing);
     2142    RT_NOREF(pCallEntry);
     2143}
    19652144#endif
    19662145
     
    19782157{
    19792158    PCIEMTB const  pTb         = pReNative->pTbOrg;
    1980     uint32_t const cbInstr     = (uint32_t)pCallEntry->auParams[0];
     2159    uint32_t const cbInstr     = (uint8_t)pCallEntry->auParams[0];
    19812160    uint32_t const cbStartPage = (uint32_t)(pCallEntry->auParams[0] >> 32);
    19822161    uint32_t const idxRange1   = (uint32_t)pCallEntry->auParams[1];
     
    19902169    return off;
    19912170}
     2171
     2172IEM_DECL_IEMNATIVELIVENESSFUNC_DEF(iemNativeLivenessFunc_BltIn_CheckOpcodesOnNextPageLoadingTlbConsiderCsLim)
     2173{
     2174    IEM_LIVENESS_RAW_INIT_WITH_XCPT_OR_CALL(pOutgoing, pIncoming);
     2175    LIVENESS_CONSIDER_CS_LIM_CHECKING(pOutgoing);
     2176    LIVENESS_LOAD_TLB_FOR_NEW_PAGE(pOutgoing, pCallEntry);
     2177    LIVENESS_CHECK_OPCODES(pOutgoing);
     2178    RT_NOREF(pCallEntry);
     2179}
    19922180#endif
    19932181
     
    20032191{
    20042192    PCIEMTB const  pTb         = pReNative->pTbOrg;
    2005     uint32_t const cbInstr     = (uint32_t)pCallEntry->auParams[0];
     2193    uint32_t const cbInstr     = (uint8_t)pCallEntry->auParams[0];
    20062194    uint32_t const idxRange    = (uint32_t)pCallEntry->auParams[1];
    20072195    BODY_SET_CUR_INSTR();
     
    20132201    return off;
    20142202}
     2203
     2204IEM_DECL_IEMNATIVELIVENESSFUNC_DEF(iemNativeLivenessFunc_BltIn_CheckCsLimAndOpcodesOnNewPageLoadingTlb)
     2205{
     2206    IEM_LIVENESS_RAW_INIT_WITH_XCPT_OR_CALL(pOutgoing, pIncoming);
     2207    LIVENESS_CHECK_CS_LIM(pOutgoing);
     2208    LIVENESS_LOAD_TLB_FOR_NEW_PAGE(pOutgoing, pCallEntry);
     2209    LIVENESS_CHECK_OPCODES(pOutgoing);
     2210    RT_NOREF(pCallEntry);
     2211}
    20152212#endif
    20162213
     
    20262223{
    20272224    PCIEMTB const  pTb         = pReNative->pTbOrg;
    2028     uint32_t const cbInstr     = (uint32_t)pCallEntry->auParams[0];
     2225    uint32_t const cbInstr     = (uint8_t)pCallEntry->auParams[0];
    20292226    uint32_t const idxRange    = (uint32_t)pCallEntry->auParams[1];
    20302227    BODY_SET_CUR_INSTR();
     
    20352232    return off;
    20362233}
     2234
     2235IEM_DECL_IEMNATIVELIVENESSFUNC_DEF(iemNativeLivenessFunc_BltIn_CheckOpcodesOnNewPageLoadingTlb)
     2236{
     2237    IEM_LIVENESS_RAW_INIT_WITH_XCPT_OR_CALL(pOutgoing, pIncoming);
     2238    LIVENESS_LOAD_TLB_FOR_NEW_PAGE(pOutgoing, pCallEntry);
     2239    LIVENESS_CHECK_OPCODES(pOutgoing);
     2240    RT_NOREF(pCallEntry);
     2241}
    20372242#endif
    20382243
     
    20492254{
    20502255    PCIEMTB const  pTb         = pReNative->pTbOrg;
    2051     uint32_t const cbInstr     = (uint32_t)pCallEntry->auParams[0];
     2256    uint32_t const cbInstr     = (uint8_t)pCallEntry->auParams[0];
    20522257    uint32_t const idxRange    = (uint32_t)pCallEntry->auParams[1];
    20532258    BODY_SET_CUR_INSTR();
     
    20592264    return off;
    20602265}
    2061 #endif
    2062 
     2266
     2267IEM_DECL_IEMNATIVELIVENESSFUNC_DEF(iemNativeLivenessFunc_BltIn_CheckOpcodesOnNewPageLoadingTlbConsiderCsLim)
     2268{
     2269    IEM_LIVENESS_RAW_INIT_WITH_XCPT_OR_CALL(pOutgoing, pIncoming);
     2270    LIVENESS_CONSIDER_CS_LIM_CHECKING(pOutgoing);
     2271    LIVENESS_LOAD_TLB_FOR_NEW_PAGE(pOutgoing, pCallEntry);
     2272    LIVENESS_CHECK_OPCODES(pOutgoing);
     2273    RT_NOREF(pCallEntry);
     2274}
     2275#endif
     2276
  • trunk/src/VBox/VMM/VMMAll/IEMAllN8veRecompiler.cpp

    r102977 r103181  
    34853485    /* [kIemNativeGstReg_GprFirst + X86_GREG_x15] = */  { CPUMCTX_OFF_AND_SIZE(r15),                "r15", },
    34863486    /* [kIemNativeGstReg_Pc] = */                       { CPUMCTX_OFF_AND_SIZE(rip),                "rip", },
    3487     /* [kIemNativeGstReg_EFlags] = */                   { CPUMCTX_OFF_AND_SIZE(eflags),             "eflags", },
     3487    /* [kIemNativeGstReg_LivenessPadding17] = */        { UINT32_MAX / 4, 0,                        "pad17", },
     3488    /* [kIemNativeGstReg_LivenessPadding18] = */        { UINT32_MAX / 4, 0,                        "pad18", },
     3489    /* [kIemNativeGstReg_LivenessPadding19] = */        { UINT32_MAX / 4, 0,                        "pad19", },
     3490    /* [kIemNativeGstReg_SegBaseFirst + 0] = */         { CPUMCTX_OFF_AND_SIZE(aSRegs[0].u64Base),  "es_base", },
     3491    /* [kIemNativeGstReg_SegBaseFirst + 1] = */         { CPUMCTX_OFF_AND_SIZE(aSRegs[1].u64Base),  "cs_base", },
     3492    /* [kIemNativeGstReg_SegBaseFirst + 2] = */         { CPUMCTX_OFF_AND_SIZE(aSRegs[2].u64Base),  "ss_base", },
     3493    /* [kIemNativeGstReg_SegBaseFirst + 3] = */         { CPUMCTX_OFF_AND_SIZE(aSRegs[3].u64Base),  "ds_base", },
     3494    /* [kIemNativeGstReg_SegBaseFirst + 4] = */         { CPUMCTX_OFF_AND_SIZE(aSRegs[4].u64Base),  "fs_base", },
     3495    /* [kIemNativeGstReg_SegBaseFirst + 5] = */         { CPUMCTX_OFF_AND_SIZE(aSRegs[5].u64Base),  "gs_base", },
     3496    /* [kIemNativeGstReg_SegAttribFirst + 0] = */       { CPUMCTX_OFF_AND_SIZE(aSRegs[0].Attr.u),   "es_attrib", },
     3497    /* [kIemNativeGstReg_SegAttribFirst + 1] = */       { CPUMCTX_OFF_AND_SIZE(aSRegs[1].Attr.u),   "cs_attrib", },
     3498    /* [kIemNativeGstReg_SegAttribFirst + 2] = */       { CPUMCTX_OFF_AND_SIZE(aSRegs[2].Attr.u),   "ss_attrib", },
     3499    /* [kIemNativeGstReg_SegAttribFirst + 3] = */       { CPUMCTX_OFF_AND_SIZE(aSRegs[3].Attr.u),   "ds_attrib", },
     3500    /* [kIemNativeGstReg_SegAttribFirst + 4] = */       { CPUMCTX_OFF_AND_SIZE(aSRegs[4].Attr.u),   "fs_attrib", },
     3501    /* [kIemNativeGstReg_SegAttribFirst + 5] = */       { CPUMCTX_OFF_AND_SIZE(aSRegs[5].Attr.u),   "gs_attrib", },
     3502    /* [kIemNativeGstReg_SegLimitFirst + 0] = */        { CPUMCTX_OFF_AND_SIZE(aSRegs[0].u32Limit), "es_limit", },
     3503    /* [kIemNativeGstReg_SegLimitFirst + 1] = */        { CPUMCTX_OFF_AND_SIZE(aSRegs[1].u32Limit), "cs_limit", },
     3504    /* [kIemNativeGstReg_SegLimitFirst + 2] = */        { CPUMCTX_OFF_AND_SIZE(aSRegs[2].u32Limit), "ss_limit", },
     3505    /* [kIemNativeGstReg_SegLimitFirst + 3] = */        { CPUMCTX_OFF_AND_SIZE(aSRegs[3].u32Limit), "ds_limit", },
     3506    /* [kIemNativeGstReg_SegLimitFirst + 4] = */        { CPUMCTX_OFF_AND_SIZE(aSRegs[4].u32Limit), "fs_limit", },
     3507    /* [kIemNativeGstReg_SegLimitFirst + 5] = */        { CPUMCTX_OFF_AND_SIZE(aSRegs[5].u32Limit), "gs_limit", },
    34883508    /* [kIemNativeGstReg_SegSelFirst + 0] = */          { CPUMCTX_OFF_AND_SIZE(aSRegs[0].Sel),      "es", },
    34893509    /* [kIemNativeGstReg_SegSelFirst + 1] = */          { CPUMCTX_OFF_AND_SIZE(aSRegs[1].Sel),      "cs", },
     
    34923512    /* [kIemNativeGstReg_SegSelFirst + 4] = */          { CPUMCTX_OFF_AND_SIZE(aSRegs[4].Sel),      "fs", },
    34933513    /* [kIemNativeGstReg_SegSelFirst + 5] = */          { CPUMCTX_OFF_AND_SIZE(aSRegs[5].Sel),      "gs", },
    3494     /* [kIemNativeGstReg_SegBaseFirst + 0] = */         { CPUMCTX_OFF_AND_SIZE(aSRegs[0].u64Base),  "es_base", },
    3495     /* [kIemNativeGstReg_SegBaseFirst + 1] = */         { CPUMCTX_OFF_AND_SIZE(aSRegs[1].u64Base),  "cs_base", },
    3496     /* [kIemNativeGstReg_SegBaseFirst + 2] = */         { CPUMCTX_OFF_AND_SIZE(aSRegs[2].u64Base),  "ss_base", },
    3497     /* [kIemNativeGstReg_SegBaseFirst + 3] = */         { CPUMCTX_OFF_AND_SIZE(aSRegs[3].u64Base),  "ds_base", },
    3498     /* [kIemNativeGstReg_SegBaseFirst + 4] = */         { CPUMCTX_OFF_AND_SIZE(aSRegs[4].u64Base),  "fs_base", },
    3499     /* [kIemNativeGstReg_SegBaseFirst + 5] = */         { CPUMCTX_OFF_AND_SIZE(aSRegs[5].u64Base),  "gs_base", },
    3500     /* [kIemNativeGstReg_SegLimitFirst + 0] = */        { CPUMCTX_OFF_AND_SIZE(aSRegs[0].u32Limit), "es_limit", },
    3501     /* [kIemNativeGstReg_SegLimitFirst + 1] = */        { CPUMCTX_OFF_AND_SIZE(aSRegs[1].u32Limit), "cs_limit", },
    3502     /* [kIemNativeGstReg_SegLimitFirst + 2] = */        { CPUMCTX_OFF_AND_SIZE(aSRegs[2].u32Limit), "ss_limit", },
    3503     /* [kIemNativeGstReg_SegLimitFirst + 3] = */        { CPUMCTX_OFF_AND_SIZE(aSRegs[3].u32Limit), "ds_limit", },
    3504     /* [kIemNativeGstReg_SegLimitFirst + 4] = */        { CPUMCTX_OFF_AND_SIZE(aSRegs[4].u32Limit), "fs_limit", },
    3505     /* [kIemNativeGstReg_SegLimitFirst + 5] = */        { CPUMCTX_OFF_AND_SIZE(aSRegs[5].u32Limit), "gs_limit", },
    3506     /* [kIemNativeGstReg_SegAttribFirst + 0] = */       { CPUMCTX_OFF_AND_SIZE(aSRegs[0].Attr.u),   "es_attrib", },
    3507     /* [kIemNativeGstReg_SegAttribFirst + 1] = */       { CPUMCTX_OFF_AND_SIZE(aSRegs[1].Attr.u),   "cs_attrib", },
    3508     /* [kIemNativeGstReg_SegAttribFirst + 2] = */       { CPUMCTX_OFF_AND_SIZE(aSRegs[2].Attr.u),   "ss_attrib", },
    3509     /* [kIemNativeGstReg_SegAttribFirst + 3] = */       { CPUMCTX_OFF_AND_SIZE(aSRegs[3].Attr.u),   "ds_attrib", },
    3510     /* [kIemNativeGstReg_SegAttribFirst + 4] = */       { CPUMCTX_OFF_AND_SIZE(aSRegs[4].Attr.u),   "fs_attrib", },
    3511     /* [kIemNativeGstReg_SegAttribFirst + 5] = */       { CPUMCTX_OFF_AND_SIZE(aSRegs[5].Attr.u),   "gs_attrib", },
     3514    /* [kIemNativeGstReg_EFlags] = */                   { CPUMCTX_OFF_AND_SIZE(eflags),             "eflags", },
    35123515#undef CPUMCTX_OFF_AND_SIZE
    35133516};
     
    70357038# define IEM_CIMPL_HIDDEN_ARGS 2
    70367039#endif
     7040
     7041#define IEM_MC_NOREF(a_Name) \
     7042    RT_NOREF_PV(a_Name)
    70377043
    70387044#define IEM_MC_ARG(a_Type, a_Name, a_iArg) \
     
    1335913365    }
    1336013366
     13367#ifdef IEMNATIVE_WITH_LIVENESS_ANALYSIS
     13368    /*
     13369     * First do liveness analysis.  This is done backwards.
     13370     */
     13371    {
     13372        uint32_t idxCall = pTb->Thrd.cCalls;
     13373        if (idxCall <= pReNative->cLivenessEntriesAlloc)
     13374        { /* likely */ }
     13375        else
     13376        {
     13377            uint32_t cAlloc = RT_MAX(pReNative->cLivenessEntriesAlloc, _4K);
     13378            while (idxCall > cAlloc)
     13379                cAlloc *= 2;
     13380            void *pvNew = RTMemRealloc(pReNative->paLivenessEntries, sizeof(pReNative->paLivenessEntries[0]) * cAlloc);
     13381            AssertReturn(pvNew, pTb);
     13382            pReNative->paLivenessEntries     = (PIEMLIVENESSENTRY)pvNew;
     13383            pReNative->cLivenessEntriesAlloc = cAlloc;
     13384        }
     13385        AssertReturn(idxCall > 0, pTb);
     13386        PIEMLIVENESSENTRY const paLivenessEntries = pReNative->paLivenessEntries;
     13387
     13388        /* The initial (final) entry. */
     13389        idxCall--;
     13390        paLivenessEntries[idxCall].s1.bm64 = IEMLIVENESSPART1_ALL_UNUSED;
     13391        paLivenessEntries[idxCall].s2.bm64 = IEMLIVENESSPART2_ALL_UNUSED;
     13392
     13393        /* Loop backwards thru the calls and fill in the other entries. */
     13394        PCIEMTHRDEDCALLENTRY pCallEntry = &pTb->Thrd.paCalls[idxCall];
     13395        while (idxCall > 0)
     13396        {
     13397            PFNIEMNATIVELIVENESSFUNC const pfnLiveness = g_apfnIemNativeLivenessFunctions[pCallEntry->enmFunction];
     13398            if (pfnLiveness)
     13399                pfnLiveness(pCallEntry, &paLivenessEntries[idxCall - 1], &paLivenessEntries[idxCall]);
     13400            else
     13401                IEM_LIVENESS_RAW_INIT_WITH_XCPT_OR_CALL(&paLivenessEntries[idxCall - 1], &paLivenessEntries[idxCall]);
     13402            pCallEntry--;
     13403            idxCall--;
     13404        }
     13405
     13406# ifdef VBOX_WITH_STATISTICS
     13407        /* Check if there are any EFLAGS optimization to be had here.  This requires someone settings them
     13408           to 'clobbered' rather that 'input'.  */
     13409        /** @todo */
     13410# endif
     13411    }
     13412#endif
     13413
    1336113414    /*
    1336213415     * Recompiling and emitting code is done using try/throw/catch or setjmp/longjmp
     
    1338613439        uint32_t             cRecompiledCalls = 0;
    1338713440#endif
     13441#if defined(IEMNATIVE_WITH_LIVENESS_ANALYSIS) || defined(VBOX_STRICT) || defined(LOG_ENABLED)
     13442        uint32_t             idxCurCall       = 0;
     13443#endif
    1338813444        PCIEMTHRDEDCALLENTRY pCallEntry       = pTb->Thrd.paCalls;
    1338913445        pReNative->fExec                      = pTb->fFlags & IEMTB_F_IEM_F_MASK;
     
    1339113447        {
    1339213448            PFNIEMNATIVERECOMPFUNC const pfnRecom = g_apfnIemNativeRecompileFunctions[pCallEntry->enmFunction];
     13449#ifdef IEMNATIVE_WITH_LIVENESS_ANALYSIS
     13450            pReNative->idxCurCall                 = idxCurCall;
     13451#endif
    1339313452
    1339413453            /*
     
    1341313472#if defined(VBOX_STRICT)
    1341413473            off = iemNativeEmitMarker(pReNative, off,
    13415                                       RT_MAKE_U32((pTb->Thrd.cCalls - cCallsLeft - 1) | (pfnRecom ? 0x8000 : 0),
    13416                                                   pCallEntry->enmFunction));
     13474                                      RT_MAKE_U32(idxCurCall | (pfnRecom ? 0x8000 : 0), pCallEntry->enmFunction));
    1341713475#endif
    1341813476#if defined(VBOX_STRICT)
     
    1342313481             * Actual work.
    1342413482             */
    13425             Log2(("%u[%u]: %s%s\n", pTb->Thrd.cCalls - cCallsLeft - 1, pCallEntry->idxInstr,
    13426                   g_apszIemThreadedFunctions[pCallEntry->enmFunction], pfnRecom ? "(recompiled)" : "(todo)"));
     13483            Log2(("%u[%u]: %s%s\n", idxCurCall, pCallEntry->idxInstr, g_apszIemThreadedFunctions[pCallEntry->enmFunction],
     13484                  pfnRecom ? "(recompiled)" : "(todo)"));
    1342713485            if (pfnRecom) /** @todo stats on this.   */
    1342813486            {
     
    1344213500             */
    1344313501            pCallEntry++;
     13502#if defined(IEMNATIVE_WITH_LIVENESS_ANALYSIS) || defined(VBOX_STRICT) || defined(LOG_ENABLED)
     13503            idxCurCall++;
     13504#endif
    1344413505        }
    1344513506
  • trunk/src/VBox/VMM/VMMAll/IEMAllThrdFuncsBltIn.cpp

    r102699 r103181  
    434434IEM_DECL_IEMTHREADEDFUNC_DEF(iemThreadedFunc_BltIn_CheckCsLim)
    435435{
    436     uint32_t const cbInstr = (uint32_t)uParam0;
     436    uint32_t const cbInstr = (uint8_t)uParam0;
    437437    RT_NOREF(uParam1, uParam2);
    438438    BODY_CHECK_CS_LIM(cbInstr);
     
    448448{
    449449    PCIEMTB const  pTb      = pVCpu->iem.s.pCurTbR3;
    450     uint32_t const cbInstr  = (uint32_t)uParam0;
     450    uint32_t const cbInstr  = (uint8_t)uParam0;
    451451    uint32_t const idxRange = (uint32_t)uParam1;
    452452    uint32_t const offRange = (uint32_t)uParam2;
     
    464464{
    465465    PCIEMTB const  pTb      = pVCpu->iem.s.pCurTbR3;
    466     uint32_t const cbInstr  = (uint32_t)uParam0;
     466    uint32_t const cbInstr  = (uint8_t)uParam0;
    467467    uint32_t const idxRange = (uint32_t)uParam1;
    468468    uint32_t const offRange = (uint32_t)uParam2;
     
    479479{
    480480    PCIEMTB const  pTb      = pVCpu->iem.s.pCurTbR3;
    481     uint32_t const cbInstr  = (uint32_t)uParam0;
     481    uint32_t const cbInstr  = (uint8_t)uParam0;
    482482    uint32_t const idxRange = (uint32_t)uParam1;
    483483    uint32_t const offRange = (uint32_t)uParam2;
     
    501501{
    502502    PCIEMTB const  pTb      = pVCpu->iem.s.pCurTbR3;
    503     uint32_t const cbInstr  = (uint32_t)uParam0;
     503    uint32_t const cbInstr  = (uint8_t)uParam0;
    504504    uint32_t const idxRange = (uint32_t)uParam1;
    505505    uint32_t const offRange = (uint32_t)uParam2;
     
    522522{
    523523    PCIEMTB const  pTb      = pVCpu->iem.s.pCurTbR3;
    524     uint32_t const cbInstr  = (uint32_t)uParam0;
     524    uint32_t const cbInstr  = (uint8_t)uParam0;
    525525    uint32_t const idxRange = (uint32_t)uParam1;
    526526    uint32_t const offRange = (uint32_t)uParam2;
     
    543543{
    544544    PCIEMTB const  pTb      = pVCpu->iem.s.pCurTbR3;
    545     uint32_t const cbInstr  = (uint32_t)uParam0;
     545    uint32_t const cbInstr  = (uint8_t)uParam0;
    546546    uint32_t const idxRange = (uint32_t)uParam1;
    547547    uint32_t const offRange = (uint32_t)uParam2;
     
    567567{
    568568    PCIEMTB const  pTb      = pVCpu->iem.s.pCurTbR3;
    569     uint32_t const cbInstr  = (uint32_t)uParam0;
     569    uint32_t const cbInstr  = (uint8_t)uParam0;
    570570    uint32_t const idxRange = (uint32_t)uParam1;
    571571    uint32_t const offRange = (uint32_t)uParam2;
     
    591591{
    592592    PCIEMTB const  pTb      = pVCpu->iem.s.pCurTbR3;
    593     uint32_t const cbInstr  = (uint32_t)uParam0;
     593    uint32_t const cbInstr  = (uint8_t)uParam0;
    594594    uint32_t const idxRange = (uint32_t)uParam1;
    595595    uint32_t const offRange = (uint32_t)uParam2;
     
    614614{
    615615    PCIEMTB const  pTb      = pVCpu->iem.s.pCurTbR3;
    616     uint32_t const cbInstr  = (uint32_t)uParam0;
     616    uint32_t const cbInstr  = (uint8_t)uParam0;
    617617    uint32_t const idxRange = (uint32_t)uParam1;
    618618    uint32_t const offRange = (uint32_t)uParam2;
     
    644644{
    645645    PCIEMTB const  pTb         = pVCpu->iem.s.pCurTbR3;
    646     uint32_t const cbInstr     = (uint32_t)uParam0;
     646    uint32_t const cbInstr     = (uint8_t)uParam0;
    647647    uint32_t const cbStartPage = (uint32_t)(uParam0 >> 32);
    648648    uint32_t const idxRange1   = (uint32_t)uParam1;
     
    670670{
    671671    PCIEMTB const  pTb         = pVCpu->iem.s.pCurTbR3;
    672     uint32_t const cbInstr     = (uint32_t)uParam0;
     672    uint32_t const cbInstr     = (uint8_t)uParam0;
    673673    uint32_t const cbStartPage = (uint32_t)(uParam0 >> 32);
    674674    uint32_t const idxRange1   = (uint32_t)uParam1;
     
    696696{
    697697    PCIEMTB const  pTb         = pVCpu->iem.s.pCurTbR3;
    698     uint32_t const cbInstr     = (uint32_t)uParam0;
     698    uint32_t const cbInstr     = (uint8_t)uParam0;
    699699    uint32_t const cbStartPage = (uint32_t)(uParam0 >> 32);
    700700    uint32_t const idxRange1   = (uint32_t)uParam1;
     
    720720{
    721721    PCIEMTB const  pTb         = pVCpu->iem.s.pCurTbR3;
    722     uint32_t const cbInstr     = (uint32_t)uParam0;
     722    uint32_t const cbInstr     = (uint8_t)uParam0;
    723723    uint32_t const cbStartPage = (uint32_t)(uParam0 >> 32);
    724724    uint32_t const idxRange1   = (uint32_t)uParam1;
     
    744744{
    745745    PCIEMTB const  pTb         = pVCpu->iem.s.pCurTbR3;
    746     uint32_t const cbInstr     = (uint32_t)uParam0;
     746    uint32_t const cbInstr     = (uint8_t)uParam0;
    747747    uint32_t const cbStartPage = (uint32_t)(uParam0 >> 32);
    748748    uint32_t const idxRange1   = (uint32_t)uParam1;
     
    767767{
    768768    PCIEMTB const  pTb         = pVCpu->iem.s.pCurTbR3;
    769     uint32_t const cbInstr     = (uint32_t)uParam0;
     769    uint32_t const cbInstr     = (uint8_t)uParam0;
    770770    uint32_t const cbStartPage = (uint32_t)(uParam0 >> 32);
    771771    uint32_t const idxRange1   = (uint32_t)uParam1;
     
    789789{
    790790    PCIEMTB const  pTb         = pVCpu->iem.s.pCurTbR3;
    791     uint32_t const cbInstr     = (uint32_t)uParam0;
     791    uint32_t const cbInstr     = (uint8_t)uParam0;
    792792    uint32_t const idxRange    = (uint32_t)uParam1;
    793793    RT_NOREF(uParam2); //Assert(uParam2 == 0 /*offRange*/);
     
    809809{
    810810    PCIEMTB const  pTb         = pVCpu->iem.s.pCurTbR3;
    811     uint32_t const cbInstr     = (uint32_t)uParam0;
     811    uint32_t const cbInstr     = (uint8_t)uParam0;
    812812    uint32_t const idxRange    = (uint32_t)uParam1;
    813813    RT_NOREF(uParam2); //Assert(uParam2 == 0 /*offRange*/);
     
    829829{
    830830    PCIEMTB const  pTb         = pVCpu->iem.s.pCurTbR3;
    831     uint32_t const cbInstr     = (uint32_t)uParam0;
     831    uint32_t const cbInstr     = (uint8_t)uParam0;
    832832    uint32_t const idxRange    = (uint32_t)uParam1;
    833833    RT_NOREF(uParam2); //Assert(uParam2 == 0 /*offRange*/);
  • trunk/src/VBox/VMM/VMMAll/IEMAllThrdPython.py

    r102977 r103181  
    637637        return 'iemNativeRecompFunc_' + self.getThreadedFunctionName()[len('iemThreadedFunc_'):];
    638638
     639    def getLivenessFunctionName(self):
     640        return 'iemNativeLivenessFunc_' + self.getThreadedFunctionName()[len('iemThreadedFunc_'):];
     641
    639642    def getShortName(self):
    640643        sName = self.oParent.oMcBlock.sFunction;
     
    25472550        # Prototype the function table.
    25482551        asLines += [
    2549             'extern const PFNIEMNATIVERECOMPFUNC g_apfnIemNativeRecompileFunctions[kIemThreadedFunc_End];',
     2552            'extern const PFNIEMNATIVERECOMPFUNC   g_apfnIemNativeRecompileFunctions[kIemThreadedFunc_End];',
     2553            'extern const PFNIEMNATIVELIVENESSFUNC g_apfnIemNativeLivenessFunctions[kIemThreadedFunc_End];',
    25502554            '',
    25512555        ];
     
    25592563            else:
    25602564                asLines.append('#define IEMNATIVE_WITHOUT_BLTIN_' + atBltIn[0].upper())
     2565
     2566        # Emit prototypes for the builtin functions we use in tables.
     2567        asLines += [
     2568            '',
     2569            '/* Prototypes for built-in functions used in the above tables. */',
     2570        ];
     2571        for sFuncNm, _, fHaveRecompFunc in self.katBltIns:
     2572            if fHaveRecompFunc:
     2573                asLines += [
     2574                    'IEM_DECL_IEMNATIVERECOMPFUNC_PROTO(    iemNativeRecompFunc_BltIn_%s);' % (sFuncNm,),
     2575                    'IEM_DECL_IEMNATIVELIVENESSFUNC_PROTO(iemNativeLivenessFunc_BltIn_%s);' % (sFuncNm,),
     2576                ];
    25612577
    25622578        oOut.write('\n'.join(asLines));
     
    26502666                    assert oVariation.iEnumValue == iThreadedFunction;
    26512667                    sName = oVariation.getNativeFunctionName();
     2668                    if oVariation.oNativeRecomp and oVariation.oNativeRecomp.isRecompilable():
     2669                        oOut.write('    /*%4u*/ %s,\n' % (iThreadedFunction, sName,));
     2670                    else:
     2671                        oOut.write('    /*%4u*/ NULL /*%s*/,\n' % (iThreadedFunction, sName,));
     2672
     2673        oOut.write(  '};\n'
     2674                   + '\n');
     2675        return True;
     2676
     2677    def generateNativeLivenessSource(self, oOut):
     2678        """
     2679        Generates the native recompiler liveness analysis functions source file.
     2680        Returns success indicator.
     2681        """
     2682        if not self.oOptions.fNativeRecompilerEnabled:
     2683            return True;
     2684
     2685        #
     2686        # The file header.
     2687        #
     2688        oOut.write('\n'.join(self.generateLicenseHeader()));
     2689
     2690        #
     2691        # Emit the functions.
     2692        #
     2693        for sVariation in ThreadedFunctionVariation.kasVariationsEmitOrder:
     2694            sVarName = ThreadedFunctionVariation.kdVariationNames[sVariation];
     2695            oOut.write(  '\n'
     2696                       + '\n'
     2697                       + '\n'
     2698                       + '\n'
     2699                       + '/*' + '*' * 128 + '\n'
     2700                       + '*   Variation: ' + sVarName + ' ' * (129 - len(sVarName) - 15) + '*\n'
     2701                       + '*' * 128 + '*/\n');
     2702
     2703            for oThreadedFunction in self.aoThreadedFuncs:
     2704                oVariation = oThreadedFunction.dVariations.get(sVariation, None) # type: ThreadedFunctionVariation
     2705                if oVariation and oVariation.oNativeRecomp and oVariation.oNativeRecomp.isRecompilable():
     2706                    oMcBlock = oThreadedFunction.oMcBlock;
     2707
     2708                    # Function header
     2709                    oOut.write(  '\n'
     2710                               + '\n'
     2711                               + '/**\n'
     2712                               + ' * #%u: %s at line %s offset %s in %s%s\n'
     2713                                  % (oVariation.iEnumValue, oMcBlock.sFunction, oMcBlock.iBeginLine, oMcBlock.offBeginLine,
     2714                                     os.path.split(oMcBlock.sSrcFile)[1],
     2715                                     ' (macro expansion)' if oMcBlock.iBeginLine == oMcBlock.iEndLine else '')
     2716                               + ' */\n'
     2717                               + 'static IEM_DECL_IEMNATIVELIVENESSFUNC_DEF(' + oVariation.getLivenessFunctionName() + ')\n'
     2718                               + '{\n');
     2719
     2720                    # Unpack parameters.
     2721                    self.generateFunctionParameterUnpacking(oVariation, oOut,
     2722                                                            ('pCallEntry->auParams[0]',
     2723                                                             'pCallEntry->auParams[1]',
     2724                                                             'pCallEntry->auParams[2]',));
     2725                    asNoRefs = []; #[ 'RT_NOREF_PV(pReNative);', ];
     2726                    for aoRefs in oVariation.dParamRefs.values():
     2727                        asNoRefs.append('RT_NOREF_PV(%s);' % (aoRefs[0].sNewName,));
     2728                    oOut.write('    %s\n' % (' '.join(asNoRefs),));
     2729
     2730                    # Now for the actual statements.
     2731                    oOut.write(oVariation.oNativeRecomp.renderCode(cchIndent = 4));
     2732
     2733                    oOut.write('}\n');
     2734
     2735        #
     2736        # Output the function table.
     2737        #
     2738        oOut.write(   '\n'
     2739                    + '\n'
     2740                    + '/*\n'
     2741                    + ' * Liveness analysis function table running parallel to g_apfnIemThreadedFunctions and friends.\n'
     2742                    + ' */\n'
     2743                    + 'const PFNIEMNATIVELIVENESSFUNC g_apfnIemNativeLivenessFunctions[kIemThreadedFunc_End] =\n'
     2744                    + '{\n'
     2745                    + '    /*Invalid*/ NULL,'
     2746                    + '\n'
     2747                    + '    /*\n'
     2748                    + '     * Predefined.\n'
     2749                    + '     */\n'
     2750                    );
     2751        for sFuncNm, _, fHaveRecompFunc in self.katBltIns:
     2752            if fHaveRecompFunc:
     2753                oOut.write('    iemNativeLivenessFunc_BltIn_%s,\n' % (sFuncNm,))
     2754            else:
     2755                oOut.write('    NULL, /*BltIn_%s*/\n' % (sFuncNm,))
     2756
     2757        iThreadedFunction = 1 + len(self.katBltIns);
     2758        for sVariation in ThreadedFunctionVariation.kasVariationsEmitOrder:
     2759            oOut.write(  '    /*\n'
     2760                       + '     * Variation: ' + ThreadedFunctionVariation.kdVariationNames[sVariation] + '\n'
     2761                       + '     */\n');
     2762            for oThreadedFunction in self.aoThreadedFuncs:
     2763                oVariation = oThreadedFunction.dVariations.get(sVariation, None);
     2764                if oVariation:
     2765                    iThreadedFunction += 1;
     2766                    assert oVariation.iEnumValue == iThreadedFunction;
     2767                    sName = oVariation.getLivenessFunctionName();
    26522768                    if oVariation.oNativeRecomp and oVariation.oNativeRecomp.isRecompilable():
    26532769                        oOut.write('    /*%4u*/ %s,\n' % (iThreadedFunction, sName,));
     
    28412957                             default = '-',
    28422958                             help    = 'The output C++ file for the native recompiler functions.');
     2959        oParser.add_argument('--out-n8ve-liveness-cpp',
     2960                             metavar = 'file-n8tv-liveness.cpp',
     2961                             dest    = 'sOutFileN8veLivenessCpp',
     2962                             action  = 'store',
     2963                             default = '-',
     2964                             help    = 'The output C++ file for the native recompiler liveness analysis functions.');
    28432965        oParser.add_argument('--native',
    28442966                             dest    = 'fNativeRecompilerEnabled',
     
    28893011            #
    28903012            aaoOutputFiles = (
    2891                  ( self.oOptions.sOutFileThrdFuncsHdr,  self.generateThreadedFunctionsHeader ),
    2892                  ( self.oOptions.sOutFileThrdFuncsCpp,  self.generateThreadedFunctionsSource ),
    2893                  ( self.oOptions.sOutFileN8veFuncsHdr,  self.generateNativeFunctionsHeader ),
    2894                  ( self.oOptions.sOutFileN8veFuncsCpp,  self.generateNativeFunctionsSource ),
    2895                  ( self.oOptions.sOutFileModInput1,     self.generateModifiedInput1 ),
    2896                  ( self.oOptions.sOutFileModInput2,     self.generateModifiedInput2 ),
    2897                  ( self.oOptions.sOutFileModInput3,     self.generateModifiedInput3 ),
    2898                  ( self.oOptions.sOutFileModInput4,     self.generateModifiedInput4 ),
     3013                 ( self.oOptions.sOutFileThrdFuncsHdr,      self.generateThreadedFunctionsHeader ),
     3014                 ( self.oOptions.sOutFileThrdFuncsCpp,      self.generateThreadedFunctionsSource ),
     3015                 ( self.oOptions.sOutFileN8veFuncsHdr,      self.generateNativeFunctionsHeader ),
     3016                 ( self.oOptions.sOutFileN8veFuncsCpp,      self.generateNativeFunctionsSource ),
     3017                 ( self.oOptions.sOutFileN8veLivenessCpp,   self.generateNativeLivenessSource ),
     3018                 ( self.oOptions.sOutFileModInput1,         self.generateModifiedInput1 ),
     3019                 ( self.oOptions.sOutFileModInput2,         self.generateModifiedInput2 ),
     3020                 ( self.oOptions.sOutFileModInput3,         self.generateModifiedInput3 ),
     3021                 ( self.oOptions.sOutFileModInput4,         self.generateModifiedInput4 ),
    28993022            );
    29003023            fRc = True;
  • trunk/src/VBox/VMM/VMMAll/IEMAllThrdRecompiler.cpp

    r102977 r103181  
    18121812    pCall->idxRange    = idxRange;
    18131813    pCall->cbOpcode    = cbInstr;
    1814     pCall->auParams[0] = cbInstr;
     1814    pCall->auParams[0] = (uint32_t)cbInstr
     1815                       | ((pVCpu->iem.s.fExec && UINT32_C(0xffffff)) << 8) /* liveness: Enough of fExec for IEM_F_MODE_X86_IS_FLAT. */
     1816                       /* The upper dword is sometimes used for cbStartPage. */;
    18151817    pCall->auParams[1] = idxRange;
    18161818    pCall->auParams[2] = offOpcode - pTb->aRanges[idxRange].offOpcodes;
  • trunk/src/VBox/VMM/include/IEMMc.h

    r103155 r103181  
    199199#define IEM_MC_LOCAL_ASSIGN(a_Type, a_Name, a_Value)    a_Type a_Name = (a_Value)
    200200#define IEM_MC_LOCAL_CONST(a_Type, a_Name, a_Value)     a_Type const a_Name = (a_Value)
     201#define IEM_MC_NOREF(a_Name)                            RT_NOREF_PV(a_Name) /* NOP/liveness hack */
    201202#define IEM_MC_ARG(a_Type, a_Name, a_iArg)              a_Type a_Name
    202203#define IEM_MC_ARG_CONST(a_Type, a_Name, a_Value, a_iArg)       a_Type const a_Name = (a_Value)
     
    30793080#define IEM_MC_IF_FPUREG_NOT_EMPTY(a_iSt) \
    30803081    if (iemFpuStRegNotEmpty(pVCpu, (a_iSt)) == VINF_SUCCESS) {
    3081 #define IEM_MC_IF_FPUREG_IS_EMPTY(a_iSt) \
    3082     if (iemFpuStRegNotEmpty(pVCpu, (a_iSt)) != VINF_SUCCESS) {
    30833082#define IEM_MC_IF_FPUREG_NOT_EMPTY_REF_R80(a_pr80Dst, a_iSt) \
    30843083    if (iemFpuStRegNotEmptyRef(pVCpu, (a_iSt), &(a_pr80Dst)) == VINF_SUCCESS) {
  • trunk/src/VBox/VMM/include/IEMN8veRecompiler.h

    r102977 r103181  
    4242#if defined(DEBUG) || defined(DOXYGEN_RUNNING)
    4343# define IEMNATIVE_WITH_TB_DEBUG_INFO
     44#endif
     45
     46/** @def IEMNATIVE_WITH_LIVENESS_ANALYSIS
     47 * Enables liveness analysis.  */
     48#if 1 || defined(DOXYGEN_RUNNING)
     49# define IEMNATIVE_WITH_LIVENESS_ANALYSIS
    4450#endif
    4551
     
    376382
    377383
     384typedef union IEMLIVENESSPART1
     385{
     386    uint64_t        bm64;
     387    RT_GCC_EXTENSION struct
     388    {                                     /*   bit no */
     389        uint64_t    bmGprs      : 32;   /**< 0x00 /  0: The 16 general purpose registers. */
     390        uint64_t    u2UnusedPc  : 2;    /**< 0x20 / 32: (PC in ) */
     391        uint64_t    u6Padding   : 6;    /**< 0x22 / 34: */
     392        uint64_t    bmSegBase   : 12;   /**< 0x28 / 40: */
     393        uint64_t    bmSegAttrib : 12;   /**< 0x34 / 52: */
     394    };
     395} IEMLIVENESSPART1;
     396AssertCompileSize(IEMLIVENESSPART1, 8);
     397
     398typedef union IEMLIVENESSPART2
     399{
     400    uint64_t        bm64;
     401    RT_GCC_EXTENSION struct
     402    {                                     /*   bit no */
     403        uint64_t    bmSegLimit  : 12;   /**< 0x40 / 64: */
     404        uint64_t    bmSegSel    : 12;   /**< 0x4c / 76: */
     405        uint64_t    u2EflOther  : 2;    /**< 0x58 / 88: Other EFLAGS bits   (~X86_EFL_STATUS_BITS & X86_EFL_LIVE_MASK). */
     406        uint64_t    u2EflCf     : 2;    /**< 0x5a / 90: Carry flag          (X86_EFL_CF / 0). */
     407        uint64_t    u2EflPf     : 2;    /**< 0x5c / 92: Parity flag         (X86_EFL_PF / 2). */
     408        uint64_t    u2EflAf     : 2;    /**< 0x5e / 94: Auxilary carry flag (X86_EFL_AF / 4). */
     409        uint64_t    u2EflZf     : 2;    /**< 0x60 / 96: Zero flag           (X86_EFL_ZF / 6). */
     410        uint64_t    u2EflSf     : 2;    /**< 0x62 / 98: Signed flag         (X86_EFL_SF / 7). */
     411        uint64_t    u2EflOf     : 2;    /**< 0x64 /100: Overflow flag       (X86_EFL_OF / 12). */
     412        uint64_t    u24Unused   : 24;     /* 0x66 /102 -> 0x80/128 */
     413    };
     414} IEMLIVENESSPART2;
     415AssertCompileSize(IEMLIVENESSPART2, 8);
     416
     417/**
     418 * A liveness state entry.
     419 *
     420 * The first 128 bits runs parallel to kIemNativeGstReg_xxx for the most part.
     421 * Once we add a SSE register shadowing, we'll add another 64-bit element for
     422 * that.
     423 */
     424typedef union IEMLIVENESSENTRY
     425{
     426    uint64_t        bm64[16 / 8];
     427    uint16_t        bm32[16 / 4];
     428    uint16_t        bm16[16 / 2];
     429    uint8_t         bm8[16 / 1];
     430    RT_GCC_EXTENSION struct
     431    {
     432        IEMLIVENESSPART1 s1;
     433        IEMLIVENESSPART2 s2;
     434    };
     435} IEMLIVENESSENTRY;
     436AssertCompileSize(IEMLIVENESSENTRY, 16);
     437/** Pointer to a liveness state entry. */
     438typedef IEMLIVENESSENTRY *PIEMLIVENESSENTRY;
     439/** Pointer to a const liveness state entry. */
     440typedef IEMLIVENESSENTRY const *PCIEMLIVENESSENTRY;
     441
     442/** @name 64-bit value masks for IEMLIVENESSENTRY.
     443 * @{ */                                      /*         0xzzzzyyyyxxxxwwww */
     444#define IEMLIVENESSPART1_MASK                   UINT64_C(0xffffff00ffffffff)
     445#define IEMLIVENESSPART2_MASK                   UINT64_C(0x0000003fffffffff)
     446
     447#define IEMLIVENESSPART1_XCPT_OR_CALL           UINT64_C(0xaaaaaa00aaaaaaaa)
     448#define IEMLIVENESSPART2_XCPT_OR_CALL           UINT64_C(0x0000002aaaaaaaaa)
     449
     450#define IEMLIVENESSPART1_ALL_UNUSED             UINT64_C(0x5555550055555555)
     451#define IEMLIVENESSPART2_ALL_UNUSED             UINT64_C(0x0000001555555555)
     452
     453#define IEMLIVENESSPART1_ALL_EFL_MASK           UINT64_C(0x0000000000000000)
     454#define IEMLIVENESSPART2_ALL_EFL_MASK           UINT64_C(0x0000003fff000000)
     455
     456#define IEMLIVENESSPART1_ALL_EFL_INPUT          IEMLIVENESSPART1_ALL_EFL_MASK
     457#define IEMLIVENESSPART2_ALL_EFL_INPUT          IEMLIVENESSPART2_ALL_EFL_MASK
     458/** @} */
     459
     460
     461/** @name The liveness state for a register.
     462 *
     463 * The state values have been picked to with state accumulation in mind (what
     464 * the iemNativeLivenessFunc_xxxx functions does), as that is the most
     465 * performance critical work done with the values.
     466 *
     467 * This is a compressed state that only requires 2 bits per register.
     468 * When accumulating state, we'll be using three IEMLIVENESSENTRY copies:
     469 *      1. the incoming state from the following call,
     470 *      2. the outgoing state for this call,
     471 *      3. mask of the entries set in the 2nd.
     472 *
     473 * The mask entry (3rd one above) will be used both when updating the outgoing
     474 * state and when merging in incoming state for registers not touched by the
     475 * current call.
     476 *
     477 * @{ */
     478/** The register will be clobbered and the current value thrown away.
     479 *
     480 * When this is applied to the state (2) we'll simply be AND'ing it with the
     481 * (old) mask (3) and adding the register to the mask.   This way we'll
     482 * preserve the high priority IEMLIVENESS_STATE_XCPT_OR_CALL and
     483 * IEMLIVENESS_STATE_INPUT states. */
     484#define IEMLIVENESS_STATE_CLOBBERED     0
     485/** The register is unused in the remainder of the TB.
     486 *
     487 * This is an initial state and can not be set by any of the
     488 * iemNativeLivenessFunc_xxxx callbacks. */
     489#define IEMLIVENESS_STATE_UNUSED        1
     490/** The register value is required in a potential call or exception.
     491 *
     492 * This means that the register value must be calculated and is best written to
     493 * the state, but that any shadowing registers can be flushed thereafter as it's
     494 * not used again.  This state has lower priority than IEMLIVENESS_STATE_INPUT.
     495 *
     496 * It is typically applied across the board, but we preserve incoming
     497 * IEMLIVENESS_STATE_INPUT values.  This latter means we have to do some extra
     498 * trickery to filter out IEMLIVENESS_STATE_UNUSED:
     499 *      1. r0 = old & ~mask;
     500 *      2. r0 = t1 & (t1 >> 1)'
     501 *      3. state |= r0 | 0b10;
     502 *      4. mask = ~0;
     503 */
     504#define IEMLIVENESS_STATE_XCPT_OR_CALL  2
     505/** The register value is used as input.
     506 *
     507 * This means that the register value must be calculated and it is best to keep
     508 * it in a register.  It does not need to be writtent out as such.  This is the
     509 * highest priority state.
     510 *
     511 * Whether the call modifies the register or not isn't relevant to earlier
     512 * calls, so that's not recorded.
     513 *
     514 * When applying this state we just or in the value in the outgoing state and
     515 * mask. */
     516#define IEMLIVENESS_STATE_INPUT         3
     517/** Mask of the state bits.   */
     518#define IEMLIVENESS_STATE_MASK          3
     519/** The number of bits per state.   */
     520#define IEMLIVENESS_STATE_BIT_COUNT     2
     521/** @} */
     522
     523/** @name Liveness helpers for builtin functions and similar.
     524 *
     525 * These are not used by IEM_MC_BEGIN/END blocks, IEMAllN8veLiveness.cpp has its
     526 * own set of manimulator macros for those.
     527 *
     528 * @{ */
     529/** Initializing the outgoing state with a potnetial xcpt or call state.
     530 * This only works when all changes will be IEMLIVENESS_STATE_INPUT. */
     531#define IEM_LIVENESS_RAW_INIT_WITH_XCPT_OR_CALL(a_pOutgoing, a_pIncoming) \
     532    do { \
     533        uint64_t uTmp1 = (a_pIncoming)->s1.bm64; \
     534        uTmp1 = uTmp1 & (uTmp1 >> 1); \
     535        (a_pOutgoing)->s1.bm64 = uTmp1 | IEMLIVENESSPART1_XCPT_OR_CALL; \
     536        \
     537        uint64_t uTmp2 = (a_pIncoming)->s2.bm64; \
     538        uTmp2 = uTmp2 & (uTmp1 >> 1); \
     539        (a_pOutgoing)->s2.bm64 = uTmp2 | IEMLIVENESSPART2_XCPT_OR_CALL; \
     540    } while (0)
     541
     542/** Adds a segment base register as input to the outgoing state. */
     543#define IEM_LIVENESS_RAW_SEG_BASE_INPUT(a_pOutgoing, a_iSReg) \
     544    (a_pOutgoing)->s1.bmSegBase   |= (uint32_t)IEMLIVENESS_STATE_INPUT << ((a_iSReg) * IEMLIVENESS_STATE_BIT_COUNT)
     545
     546/** Adds a segment attribute register as input to the outgoing state. */
     547#define IEM_LIVENESS_RAW_SEG_ATTRIB_INPUT(a_pOutgoing, a_iSReg) \
     548    (a_pOutgoing)->s1.bmSegAttrib |= (uint32_t)IEMLIVENESS_STATE_INPUT << ((a_iSReg) * IEMLIVENESS_STATE_BIT_COUNT)
     549
     550/** Adds a segment limit register as input to the outgoing state. */
     551#define IEM_LIVENESS_RAW_SEG_LIMIT_INPUT(a_pOutgoing, a_iSReg) \
     552    (a_pOutgoing)->s2.bmSegLimit  |= (uint32_t)IEMLIVENESS_STATE_INPUT << ((a_iSReg) * IEMLIVENESS_STATE_BIT_COUNT)
     553/** @} */
     554
    378555/**
    379556 * Guest registers that can be shadowed in GPRs.
     557 *
     558 * This runs parallel to the first 128-bits of liveness state.  To avoid having
     559 * the SegLimitXxxx range cross from the 1st 64-bit word to the 2nd,
     560 * we've inserted some padding.  The EFlags must be placed last, as the liveness
     561 * state tracks it as 7 subcomponents and we don't want to waste space here.
    380562 */
    381563typedef enum IEMNATIVEGSTREG : uint8_t
     
    384566    kIemNativeGstReg_GprLast       = kIemNativeGstReg_GprFirst + 15,
    385567    kIemNativeGstReg_Pc,
    386     kIemNativeGstReg_EFlags,            /**< 32-bit, includes internal flags.  */
     568    kIemNativeGstReg_LivenessPadding17,
     569    kIemNativeGstReg_LivenessPadding18,
     570    kIemNativeGstReg_LivenessPadding19,
     571    kIemNativeGstReg_SegBaseFirst,
     572    kIemNativeGstReg_SegBaseLast   = kIemNativeGstReg_SegBaseFirst + 5,
     573    kIemNativeGstReg_SegAttribFirst,
     574    kIemNativeGstReg_SegAttribLast = kIemNativeGstReg_SegAttribFirst + 5,
     575    kIemNativeGstReg_SegLimitFirst,
     576    kIemNativeGstReg_SegLimitLast  = kIemNativeGstReg_SegLimitFirst + 5,
    387577    kIemNativeGstReg_SegSelFirst,
    388578    kIemNativeGstReg_SegSelLast    = kIemNativeGstReg_SegSelFirst + 5,
    389     kIemNativeGstReg_SegBaseFirst,
    390     kIemNativeGstReg_SegBaseLast   = kIemNativeGstReg_SegBaseFirst + 5,
    391     kIemNativeGstReg_SegLimitFirst,
    392     kIemNativeGstReg_SegLimitLast  = kIemNativeGstReg_SegLimitFirst + 5,
    393     kIemNativeGstReg_SegAttribFirst,
    394     kIemNativeGstReg_SegAttribLast = kIemNativeGstReg_SegAttribFirst + 5,
     579    kIemNativeGstReg_EFlags,            /**< 32-bit, includes internal flags - last! */
    395580    kIemNativeGstReg_End
    396581} IEMNATIVEGSTREG;
     582AssertCompile((int)kIemNativeGstReg_SegLimitFirst == 32);
    397583
    398584/** @name Helpers for converting register numbers to IEMNATIVEGSTREG values.
     
    683869#endif
    684870
     871#ifdef IEMNATIVE_WITH_LIVENESS_ANALYSIS
     872    /** The current call index (liveness array and threaded calls in TB). */
     873    uint32_t                    idxCurCall;
     874    /** Number of liveness entries allocated. */
     875    uint32_t                    cLivenessEntriesAlloc;
     876    /** Liveness entries for all the calls in the TB begin recompiled.
     877     * The entry for idxCurCall contains the info for what the next call will
     878     * require wrt registers.  (Which means the last entry is the initial liveness
     879     * state.) */
     880    PIEMLIVENESSENTRY           paLivenessEntries;
     881#endif
     882
    685883    /** The translation block being recompiled. */
    686884    PCIEMTB                     pTbOrg;
     
    8051003
    8061004
     1005/**
     1006 * Native recompiler liveness analysis worker for a threaded function.
     1007 *
     1008 * @param   pCallEntry  The threaded call entry.
     1009 * @param   pIncoming   The incoming liveness state entry.
     1010 * @param   pOutgoing   The outgoing liveness state entry.
     1011 */
     1012typedef DECLCALLBACKTYPE(void, FNIEMNATIVELIVENESSFUNC, (PCIEMTHRDEDCALLENTRY pCallEntry,
     1013                                                         PCIEMLIVENESSENTRY pIncoming, PIEMLIVENESSENTRY pOutgoing));
     1014/** Pointer to a native recompiler liveness analysis worker for a threaded function. */
     1015typedef FNIEMNATIVELIVENESSFUNC *PFNIEMNATIVELIVENESSFUNC;
     1016
     1017/** Defines a native recompiler liveness analysis worker for a threaded function.
     1018 * @see FNIEMNATIVELIVENESSFUNC  */
     1019#define IEM_DECL_IEMNATIVELIVENESSFUNC_DEF(a_Name) \
     1020    DECLCALLBACK(void) a_Name(PCIEMTHRDEDCALLENTRY pCallEntry, PCIEMLIVENESSENTRY pIncoming, PIEMLIVENESSENTRY pOutgoing)
     1021
     1022/** Prototypes a native recompiler liveness analysis function for a threaded function.
     1023 * @see FNIEMNATIVELIVENESSFUNC  */
     1024#define IEM_DECL_IEMNATIVELIVENESSFUNC_PROTO(a_Name) FNIEMNATIVELIVENESSFUNC a_Name
     1025
     1026
    8071027/** Define a native recompiler helper function, safe to call from the TB code. */
    8081028#define IEM_DECL_NATIVE_HLP_DEF(a_RetType, a_Name, a_ArgList) \
     
    8671087                                                      PCIEMTHRDEDCALLENTRY pCallEntry);
    8681088
    869 IEM_DECL_IEMNATIVERECOMPFUNC_PROTO(iemNativeRecompFunc_BltIn_Nop);
    870 IEM_DECL_IEMNATIVERECOMPFUNC_PROTO(iemNativeRecompFunc_BltIn_LogCpuState);
    871 IEM_DECL_IEMNATIVERECOMPFUNC_PROTO(iemNativeRecompFunc_BltIn_DeferToCImpl0);
    872 IEM_DECL_IEMNATIVERECOMPFUNC_PROTO(iemNativeRecompFunc_BltIn_CheckIrq);
    873 IEM_DECL_IEMNATIVERECOMPFUNC_PROTO(iemNativeRecompFunc_BltIn_CheckMode);
    874 IEM_DECL_IEMNATIVERECOMPFUNC_PROTO(iemNativeRecompFunc_BltIn_CheckCsLim);
    875 IEM_DECL_IEMNATIVERECOMPFUNC_PROTO(iemNativeRecompFunc_BltIn_CheckCsLimAndOpcodes);
    876 IEM_DECL_IEMNATIVERECOMPFUNC_PROTO(iemNativeRecompFunc_BltIn_CheckOpcodes);
    877 IEM_DECL_IEMNATIVERECOMPFUNC_PROTO(iemNativeRecompFunc_BltIn_CheckOpcodesConsiderCsLim);
    878 IEM_DECL_IEMNATIVERECOMPFUNC_PROTO(iemNativeRecompFunc_BltIn_CheckCsLimAndPcAndOpcodes);
    879 IEM_DECL_IEMNATIVERECOMPFUNC_PROTO(iemNativeRecompFunc_BltIn_CheckPcAndOpcodes);
    880 IEM_DECL_IEMNATIVERECOMPFUNC_PROTO(iemNativeRecompFunc_BltIn_CheckPcAndOpcodesConsiderCsLim);
    881 IEM_DECL_IEMNATIVERECOMPFUNC_PROTO(iemNativeRecompFunc_BltIn_CheckCsLimAndOpcodesLoadingTlb);
    882 IEM_DECL_IEMNATIVERECOMPFUNC_PROTO(iemNativeRecompFunc_BltIn_CheckOpcodesLoadingTlb);
    883 IEM_DECL_IEMNATIVERECOMPFUNC_PROTO(iemNativeRecompFunc_BltIn_CheckOpcodesLoadingTlbConsiderCsLim);
    884 IEM_DECL_IEMNATIVERECOMPFUNC_PROTO(iemNativeRecompFunc_BltIn_CheckCsLimAndOpcodesAcrossPageLoadingTlb);
    885 IEM_DECL_IEMNATIVERECOMPFUNC_PROTO(iemNativeRecompFunc_BltIn_CheckOpcodesAcrossPageLoadingTlb);
    886 IEM_DECL_IEMNATIVERECOMPFUNC_PROTO(iemNativeRecompFunc_BltIn_CheckOpcodesAcrossPageLoadingTlbConsiderCsLim);
    887 IEM_DECL_IEMNATIVERECOMPFUNC_PROTO(iemNativeRecompFunc_BltIn_CheckCsLimAndOpcodesOnNextPageLoadingTlb);
    888 IEM_DECL_IEMNATIVERECOMPFUNC_PROTO(iemNativeRecompFunc_BltIn_CheckOpcodesOnNextPageLoadingTlb);
    889 IEM_DECL_IEMNATIVERECOMPFUNC_PROTO(iemNativeRecompFunc_BltIn_CheckOpcodesOnNextPageLoadingTlbConsiderCsLim);
    890 IEM_DECL_IEMNATIVERECOMPFUNC_PROTO(iemNativeRecompFunc_BltIn_CheckCsLimAndOpcodesOnNewPageLoadingTlb);
    891 IEM_DECL_IEMNATIVERECOMPFUNC_PROTO(iemNativeRecompFunc_BltIn_CheckOpcodesOnNewPageLoadingTlb);
    892 IEM_DECL_IEMNATIVERECOMPFUNC_PROTO(iemNativeRecompFunc_BltIn_CheckOpcodesOnNewPageLoadingTlbConsiderCsLim);
    893 
    8941089extern DECL_HIDDEN_DATA(const char * const) g_apszIemNativeHstRegNames[];
    8951090
  • trunk/src/VBox/VMM/testcase/tstIEMCheckMc.cpp

    r103155 r103181  
    610610    a_Type a_Name = (a_Value); \
    611611    NOREF(a_Name)
     612#define IEM_MC_NOREF(a_Name)                            RT_NOREF_PV(a_Name)
    612613
    613614#define IEM_MC_ARG(a_Type, a_Name, a_iArg) (void)fMcBegin; \
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