VirtualBox

Changeset 108260 in vbox


Ignore:
Timestamp:
Feb 17, 2025 3:24:14 PM (3 months ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
167582
Message:

VMM/IEM: Splitting up IEMInline.h. jiraref:VBP-1531

Location:
trunk/src/VBox/VMM
Files:
1 added
19 edited
3 copied

Legend:

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

    r108249 r108260  
    158158
    159159#include "IEMInline.h"
     160#ifdef VBOX_VMM_TARGET_X86
     161# include "target-x86/IEMInline-x86.h"
     162# include "target-x86/IEMInlineDecode-x86.h"
     163#endif
    160164
    161165
  • trunk/src/VBox/VMM/VMMAll/IEMAllMem.cpp

    r108250 r108260  
    5050#include "IEMInline.h"
    5151#ifdef VBOX_VMM_TARGET_X86
     52# include "target-x86/IEMInline-x86.h" /* not really required. sigh. */
    5253# include "target-x86/IEMAllTlbInline-x86.h"
    5354#endif
  • trunk/src/VBox/VMM/VMMAll/IEMAllThrdFuncsBltIn.cpp

    r108195 r108260  
    7171
    7272#include "IEMInline.h"
     73#ifdef VBOX_VMM_TARGET_X86
     74# include "target-x86/IEMInline-x86.h"
     75#endif
    7376
    7477
  • trunk/src/VBox/VMM/VMMAll/IEMAllThrdRecompiler.cpp

    r108195 r108260  
    5555#include <VBox/vmm/iem.h>
    5656#include <VBox/vmm/cpum.h>
    57 #include <VBox/vmm/pdmapic.h>
    58 #include <VBox/vmm/pdm.h>
    59 #include <VBox/vmm/pgm.h>
    60 #include <VBox/vmm/iom.h>
    61 #include <VBox/vmm/em.h>
    62 #include <VBox/vmm/hm.h>
    63 #include <VBox/vmm/nem.h>
    64 #include <VBox/vmm/gim.h>
    65 #ifdef VBOX_WITH_NESTED_HWVIRT_SVM
    66 # include <VBox/vmm/em.h>
    67 # include <VBox/vmm/hm_svm.h>
    68 #endif
    69 #ifdef VBOX_WITH_NESTED_HWVIRT_VMX
    70 # include <VBox/vmm/hmvmxinline.h>
    71 #endif
    7257#include <VBox/vmm/tm.h>
    7358#include <VBox/vmm/dbgf.h>
     
    8974#include <iprt/x86.h>
    9075
    91 #ifndef TST_IEM_CHECK_MC
    92 # include "IEMInline.h"
    93 # include "IEMOpHlp.h"
    94 # include "IEMMc.h"
    95 #endif
     76#include "IEMInline.h"
     77#ifdef VBOX_VMM_TARGET_X86
     78# include "target-x86/IEMInline-x86.h"
     79# include "target-x86/IEMInlineDecode-x86.h"
     80#endif
     81#include "IEMOpHlp.h"
     82#include "IEMMc.h"
    9683
    9784#include "IEMThreadedFunctions.h"
  • trunk/src/VBox/VMM/VMMAll/target-x86/IEMAll-x86.cpp

    r108246 r108260  
    4343#include <VBox/param.h>
    4444#include <iprt/assert.h>
     45#include <iprt/errcore.h>
    4546#include <iprt/string.h>
    4647#include <iprt/x86.h>
    4748
    48 #include "IEMInline.h"
     49#include "IEMInline-x86.h" /* iemRegFinishClearingRF */
    4950
    5051
  • trunk/src/VBox/VMM/VMMAll/target-x86/IEMAllCImpl-x86.cpp

    r108196 r108260  
    3939#include <VBox/vmm/cpum.h>
    4040#include <VBox/vmm/pdmapic.h>
    41 #include <VBox/vmm/pdm.h>
    4241#include <VBox/vmm/pgm.h>
    4342#include <VBox/vmm/iom.h>
    4443#include <VBox/vmm/em.h>
    45 #include <VBox/vmm/hm.h>
    46 #include <VBox/vmm/nem.h>
    47 #include <VBox/vmm/gim.h>
    4844#include <VBox/vmm/gcm.h>
    4945#ifdef VBOX_WITH_NESTED_HWVIRT_SVM
    50 # include <VBox/vmm/em.h>
    5146# include <VBox/vmm/hm_svm.h>
    5247#endif
     
    6560#include <VBox/err.h>
    6661#include <VBox/param.h>
    67 #include <VBox/dis.h>
    68 #include <iprt/asm-math.h>
    6962#include <iprt/assert.h>
    7063#include <iprt/string.h>
     
    7265
    7366#include "IEMInline.h"
     67#include "IEMInline-x86.h"
     68#include "IEMInlineMem-x86.h"
    7469
    7570
  • trunk/src/VBox/VMM/VMMAll/target-x86/IEMAllCImplSvmInstr-x86.cpp

    r108196 r108260  
    3636#endif
    3737#include <VBox/vmm/iem.h>
    38 #include <VBox/vmm/pdmapic.h>
    3938#include <VBox/vmm/cpum.h>
    4039#include <VBox/vmm/dbgf.h>
     
    5857
    5958#include "IEMInline.h"
     59#include "IEMInline-x86.h"
    6060
    6161#ifdef VBOX_WITH_NESTED_HWVIRT_SVM /* Almost the whole file. */
  • trunk/src/VBox/VMM/VMMAll/target-x86/IEMAllCImplVmxInstr-x86.cpp

    r108196 r108260  
    5959
    6060#include "IEMInline.h"
     61#include "IEMInline-x86.h"
    6162
    6263
  • trunk/src/VBox/VMM/VMMAll/target-x86/IEMAllExec-x86.cpp

    r108220 r108260  
    5050
    5151#include "IEMInline.h"
     52#include "IEMInline-x86.h"
    5253
    5354
  • trunk/src/VBox/VMM/VMMAll/target-x86/IEMAllHlpFpu-x86.cpp

    r108226 r108260  
    5050#include <iprt/x86.h>
    5151
    52 #include "IEMInline.h"
     52#include "IEMInline-x86.h"
    5353
    5454
  • trunk/src/VBox/VMM/VMMAll/target-x86/IEMAllIntprTables-x86.h

    r108205 r108260  
    7878#ifndef TST_IEM_CHECK_MC
    7979# include "IEMInline.h"
     80# include "IEMInline-x86.h"
     81# include "IEMInlineDecode-x86.h"
     82# include "IEMInlineMem-x86.h"
    8083# include "IEMOpHlp.h"
    8184# include "IEMMc.h"
  • trunk/src/VBox/VMM/VMMAll/target-x86/IEMAllMem-x86.cpp

    r108232 r108260  
    4848
    4949#include "IEMInline.h"
     50#include "IEMInline-x86.h"
     51#include "IEMInlineMem-x86.h"
    5052#include "IEMAllTlbInline-x86.h"
    5153
  • trunk/src/VBox/VMM/VMMAll/target-x86/IEMAllOpHlp-x86.cpp

    r108243 r108260  
    4646#include <iprt/x86.h>
    4747
    48 #include "IEMInline.h"
     48#include "IEMInlineDecode-x86.h"
    4949
    5050
  • trunk/src/VBox/VMM/VMMAll/target-x86/IEMAllOpcodeFetch-x86.cpp

    r108246 r108260  
    4444#include <VBox/param.h>
    4545#include <iprt/assert.h>
     46#include <iprt/errcore.h>
    4647#include <iprt/string.h>
    4748#include <iprt/x86.h>
    4849
    4950#include "IEMInline.h"
    50 #ifdef VBOX_VMM_TARGET_X86
    51 # include "IEMAllTlbInline-x86.h"
    52 #endif
     51#include "IEMInline-x86.h"
     52#include "IEMAllTlbInline-x86.h"
    5353
    5454
  • trunk/src/VBox/VMM/VMMAll/target-x86/IEMAllThrdFuncs-x86.cpp

    r108204 r108260  
    7171
    7272#include "IEMInline.h"
     73#include "IEMInline-x86.h"
     74#include "IEMInlineMem-x86.h"
    7375#include "IEMMc.h"
    7476
  • trunk/src/VBox/VMM/VMMAll/target-x86/IEMAllThrdTables-x86.h

    r108205 r108260  
    8181#ifndef TST_IEM_CHECK_MC
    8282# include "IEMInline.h"
     83# include "IEMInline-x86.h"
     84# include "IEMInlineDecode-x86.h"
     85# include "IEMInlineMem-x86.h"
    8386# include "IEMOpHlp.h"
    8487# include "IEMMc.h"
  • trunk/src/VBox/VMM/VMMAll/target-x86/IEMAllXcpt-x86.cpp

    r108248 r108260  
    3737#include <VBox/vmm/iem.h>
    3838#include <VBox/vmm/cpum.h>
    39 #include <VBox/vmm/pdmapic.h>
     39#include <VBox/vmm/em.h>
    4040#include <VBox/vmm/pdm.h>
    41 #include <VBox/vmm/pgm.h>
    42 #include <VBox/vmm/iom.h>
    43 #include <VBox/vmm/em.h>
    44 #include <VBox/vmm/hm.h>
    45 #include <VBox/vmm/nem.h>
    4641#include <VBox/vmm/gcm.h>
    47 #include <VBox/vmm/gim.h>
    4842#ifdef VBOX_WITH_NESTED_HWVIRT_SVM
    49 # include <VBox/vmm/em.h>
    5043# include <VBox/vmm/hm_svm.h>
    5144#endif
     
    6154#include <VBox/err.h>
    6255#include <VBox/param.h>
    63 #include <VBox/dis.h>
    64 #include <iprt/asm-math.h>
    65 #if defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86)
    66 # include <iprt/asm-amd64-x86.h>
    67 #elif defined(RT_ARCH_ARM64) || defined(RT_ARCH_ARM32)
    68 # include <iprt/asm-arm.h>
    69 #endif
    7056#include <iprt/assert.h>
    7157#include <iprt/string.h>
    7258#include <iprt/x86.h>
    7359
    74 #include "IEMInline.h"
     60#include "IEMInline-x86.h"
    7561
    7662
  • trunk/src/VBox/VMM/VMMAll/target-x86/IEMInline-x86.h

    r108246 r108260  
    11/* $Id$ */
    22/** @file
    3  * IEM - Interpreted Execution Manager - Inlined Functions.
     3 * IEM - Interpreted Execution Manager - Inlined Functions, x86 target.
    44 */
    55
     
    2626 */
    2727
    28 #ifndef VMM_INCLUDED_SRC_include_IEMInline_h
    29 #define VMM_INCLUDED_SRC_include_IEMInline_h
     28#ifndef VMM_INCLUDED_SRC_VMMAll_target_x86_IEMInline_x86_h
     29#define VMM_INCLUDED_SRC_VMMAll_target_x86_IEMInline_x86_h
    3030#ifndef RT_WITHOUT_PRAGMA_ONCE
    3131# pragma once
     
    3333
    3434#include <VBox/err.h>
    35 
    36 
    37 /**
    38  * Makes status code addjustments (pass up from I/O and access handler)
    39  * as well as maintaining statistics.
    40  *
    41  * @returns Strict VBox status code to pass up.
    42  * @param   pVCpu       The cross context virtual CPU structure of the calling thread.
    43  * @param   rcStrict    The status from executing an instruction.
    44  */
    45 DECL_FORCE_INLINE(VBOXSTRICTRC) iemExecStatusCodeFiddling(PVMCPUCC pVCpu, VBOXSTRICTRC rcStrict) RT_NOEXCEPT
    46 {
    47     if (rcStrict != VINF_SUCCESS)
    48     {
    49         /* Deal with the cases that should be treated as VINF_SUCCESS first. */
    50         if (   rcStrict == VINF_IEM_YIELD_PENDING_FF
    51 #ifdef VBOX_WITH_NESTED_HWVIRT_VMX /** @todo r=bird: Why do we need TWO status codes here? */
    52             || rcStrict == VINF_VMX_VMEXIT
    53 #endif
    54 #ifdef VBOX_WITH_NESTED_HWVIRT_SVM
    55             || rcStrict == VINF_SVM_VMEXIT
    56 #endif
    57             )
    58         {
    59             rcStrict = pVCpu->iem.s.rcPassUp;
    60             if (RT_LIKELY(rcStrict == VINF_SUCCESS))
    61             { /* likely */ }
    62             else
    63                 pVCpu->iem.s.cRetPassUpStatus++;
    64         }
    65         else if (RT_SUCCESS(rcStrict))
    66         {
    67             AssertMsg(   (rcStrict >= VINF_EM_FIRST && rcStrict <= VINF_EM_LAST)
    68                       || rcStrict == VINF_IOM_R3_IOPORT_READ
    69                       || rcStrict == VINF_IOM_R3_IOPORT_WRITE
    70                       || rcStrict == VINF_IOM_R3_IOPORT_COMMIT_WRITE
    71                       || rcStrict == VINF_IOM_R3_MMIO_READ
    72                       || rcStrict == VINF_IOM_R3_MMIO_READ_WRITE
    73                       || rcStrict == VINF_IOM_R3_MMIO_WRITE
    74                       || rcStrict == VINF_IOM_R3_MMIO_COMMIT_WRITE
    75                       || rcStrict == VINF_CPUM_R3_MSR_READ
    76                       || rcStrict == VINF_CPUM_R3_MSR_WRITE
    77                       || rcStrict == VINF_EM_RAW_EMULATE_INSTR
    78                       || rcStrict == VINF_EM_RAW_TO_R3
    79                       || rcStrict == VINF_EM_TRIPLE_FAULT
    80                       || rcStrict == VINF_EM_EMULATE_SPLIT_LOCK
    81                       || rcStrict == VINF_GIM_R3_HYPERCALL
    82                       /* raw-mode / virt handlers only: */
    83                       || rcStrict == VINF_EM_RAW_EMULATE_INSTR_GDT_FAULT
    84                       || rcStrict == VINF_EM_RAW_EMULATE_INSTR_TSS_FAULT
    85                       || rcStrict == VINF_EM_RAW_EMULATE_INSTR_LDT_FAULT
    86                       || rcStrict == VINF_EM_RAW_EMULATE_INSTR_IDT_FAULT
    87                       || rcStrict == VINF_SELM_SYNC_GDT
    88                       || rcStrict == VINF_CSAM_PENDING_ACTION
    89                       || rcStrict == VINF_PATM_CHECK_PATCH_PAGE
    90                       /* nested hw.virt codes: */
    91                       || rcStrict == VINF_VMX_INTERCEPT_NOT_ACTIVE
    92                       || rcStrict == VINF_VMX_MODIFIES_BEHAVIOR
    93                       , ("rcStrict=%Rrc\n", VBOXSTRICTRC_VAL(rcStrict)));
    94 /** @todo adjust for VINF_EM_RAW_EMULATE_INSTR. */
    95             int32_t const rcPassUp = pVCpu->iem.s.rcPassUp;
    96             if (rcPassUp == VINF_SUCCESS)
    97                 pVCpu->iem.s.cRetInfStatuses++;
    98             else if (   rcPassUp < VINF_EM_FIRST
    99                      || rcPassUp > VINF_EM_LAST
    100                      || rcPassUp < VBOXSTRICTRC_VAL(rcStrict))
    101             {
    102                 LogEx(LOG_GROUP_IEM,("IEM: rcPassUp=%Rrc! rcStrict=%Rrc\n", rcPassUp, VBOXSTRICTRC_VAL(rcStrict)));
    103                 pVCpu->iem.s.cRetPassUpStatus++;
    104                 rcStrict = rcPassUp;
    105             }
    106             else
    107             {
    108                 LogEx(LOG_GROUP_IEM,("IEM: rcPassUp=%Rrc  rcStrict=%Rrc!\n", rcPassUp, VBOXSTRICTRC_VAL(rcStrict)));
    109                 pVCpu->iem.s.cRetInfStatuses++;
    110             }
    111         }
    112         else if (rcStrict == VERR_IEM_ASPECT_NOT_IMPLEMENTED)
    113             pVCpu->iem.s.cRetAspectNotImplemented++;
    114         else if (rcStrict == VERR_IEM_INSTR_NOT_IMPLEMENTED)
    115             pVCpu->iem.s.cRetInstrNotImplemented++;
    116         else
    117             pVCpu->iem.s.cRetErrStatuses++;
    118     }
    119     else
    120     {
    121         rcStrict = pVCpu->iem.s.rcPassUp;
    122         if (rcStrict != VINF_SUCCESS)
    123             pVCpu->iem.s.cRetPassUpStatus++;
    124     }
    125 
    126     /* Just clear it here as well. */
    127     pVCpu->iem.s.rcPassUp = VINF_SUCCESS;
    128 
    129     return rcStrict;
    130 }
    131 
    132 
    133 /**
    134  * Sets the pass up status.
    135  *
    136  * @returns VINF_SUCCESS.
    137  * @param   pVCpu               The cross context virtual CPU structure of the
    138  *                              calling thread.
    139  * @param   rcPassUp            The pass up status.  Must be informational.
    140  *                              VINF_SUCCESS is not allowed.
    141  */
    142 DECLINLINE(int) iemSetPassUpStatus(PVMCPUCC pVCpu, VBOXSTRICTRC rcPassUp) RT_NOEXCEPT
    143 {
    144     AssertRC(VBOXSTRICTRC_VAL(rcPassUp)); Assert(rcPassUp != VINF_SUCCESS);
    145 
    146     int32_t const rcOldPassUp = pVCpu->iem.s.rcPassUp;
    147     if (rcOldPassUp == VINF_SUCCESS)
    148         pVCpu->iem.s.rcPassUp = VBOXSTRICTRC_VAL(rcPassUp);
    149     /* If both are EM scheduling codes, use EM priority rules. */
    150     else if (   rcOldPassUp >= VINF_EM_FIRST && rcOldPassUp <= VINF_EM_LAST
    151              && rcPassUp    >= VINF_EM_FIRST && rcPassUp    <= VINF_EM_LAST)
    152     {
    153         if (rcPassUp < rcOldPassUp)
    154         {
    155             LogEx(LOG_GROUP_IEM,("IEM: rcPassUp=%Rrc! rcOldPassUp=%Rrc\n", VBOXSTRICTRC_VAL(rcPassUp), rcOldPassUp));
    156             pVCpu->iem.s.rcPassUp = VBOXSTRICTRC_VAL(rcPassUp);
    157         }
    158         else
    159             LogEx(LOG_GROUP_IEM,("IEM: rcPassUp=%Rrc  rcOldPassUp=%Rrc!\n", VBOXSTRICTRC_VAL(rcPassUp), rcOldPassUp));
    160     }
    161     /* Override EM scheduling with specific status code. */
    162     else if (rcOldPassUp >= VINF_EM_FIRST && rcOldPassUp <= VINF_EM_LAST)
    163     {
    164         LogEx(LOG_GROUP_IEM,("IEM: rcPassUp=%Rrc! rcOldPassUp=%Rrc\n", VBOXSTRICTRC_VAL(rcPassUp), rcOldPassUp));
    165         pVCpu->iem.s.rcPassUp = VBOXSTRICTRC_VAL(rcPassUp);
    166     }
    167     /* Don't override specific status code, first come first served. */
    168     else
    169         LogEx(LOG_GROUP_IEM,("IEM: rcPassUp=%Rrc  rcOldPassUp=%Rrc!\n", VBOXSTRICTRC_VAL(rcPassUp), rcOldPassUp));
    170     return VINF_SUCCESS;
    171 }
    17235
    17336
     
    383246}
    384247
    385 /**
    386  * Calculates the the IEM_F_XXX flags.
    387  *
    388  * @returns IEM_F_XXX combination match the current CPU state.
    389  * @param   pVCpu               The cross context virtual CPU structure of the
    390  *                              calling thread.
    391  */
     248
    392249DECL_FORCE_INLINE(uint32_t) iemCalcExecFlags(PVMCPUCC pVCpu) RT_NOEXCEPT
    393250{
     
    429286
    430287#ifndef IEM_WITH_OPAQUE_DECODER_STATE
    431 
    432 # if defined(VBOX_INCLUDED_vmm_dbgf_h) || defined(DOXYGEN_RUNNING) /* dbgf.ro.cEnabledHwBreakpoints */
    433 
    434 /**
    435  * Initializes the execution state.
    436  *
    437  * @param   pVCpu               The cross context virtual CPU structure of the
    438  *                              calling thread.
    439  * @param   fExecOpts           Optional execution flags:
    440  *                                  - IEM_F_BYPASS_HANDLERS
    441  *                                  - IEM_F_X86_DISREGARD_LOCK
    442  *
    443  * @remarks Callers of this must call iemUninitExec() to undo potentially fatal
    444  *          side-effects in strict builds.
    445  */
    446 DECLINLINE(void) iemInitExec(PVMCPUCC pVCpu, uint32_t fExecOpts) RT_NOEXCEPT
    447 {
    448     IEM_CTX_ASSERT(pVCpu, IEM_CPUMCTX_EXTRN_EXEC_DECODED_NO_MEM_MASK);
    449     Assert(!VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_IEM));
     288# ifdef VBOX_STRICT
     289DECLINLINE(void) iemInitExecTargetStrict(PVMCPUCC pVCpu) RT_NOEXCEPT
     290{
    450291    Assert(CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pVCpu, &pVCpu->cpum.GstCtx.cs));
    451292    Assert(CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pVCpu, &pVCpu->cpum.GstCtx.ss));
     
    457298    Assert(CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pVCpu, &pVCpu->cpum.GstCtx.tr));
    458299
    459     pVCpu->iem.s.rcPassUp           = VINF_SUCCESS;
    460     pVCpu->iem.s.fExec              = iemCalcExecFlags(pVCpu) | fExecOpts;
    461     pVCpu->iem.s.cActiveMappings    = 0;
    462     pVCpu->iem.s.iNextMapping       = 0;
    463 
    464 #  ifdef VBOX_STRICT
    465300    pVCpu->iem.s.enmDefAddrMode     = (IEMMODE)0xfe;
    466301    pVCpu->iem.s.enmEffAddrMode     = (IEMMODE)0xfe;
     
    478313    pVCpu->iem.s.fEvexStuff         = 127;
    479314    pVCpu->iem.s.uFpuOpcode         = UINT16_MAX;
    480  ifdef IEM_WITH_CODE_TLB
     315ifdef IEM_WITH_CODE_TLB
    481316    pVCpu->iem.s.offInstrNextByte   = UINT16_MAX;
    482317    pVCpu->iem.s.pbInstrBuf         = NULL;
     
    485320    pVCpu->iem.s.offCurInstrStart   = INT16_MAX;
    486321    pVCpu->iem.s.uInstrBufPc        = UINT64_C(0xc0ffc0ffcff0c0ff);
    487 #    ifdef IEM_WITH_CODE_TLB_AND_OPCODE_BUF
     322#   ifdef IEM_WITH_CODE_TLB_AND_OPCODE_BUF
    488323    pVCpu->iem.s.offOpcode          = 127;
    489 #    endif
    490  else
     324#   endif
     325else
    491326    pVCpu->iem.s.offOpcode          = 127;
    492327    pVCpu->iem.s.cbOpcode           = 127;
    493 #   endif
    494 #  endif /* VBOX_STRICT */
    495 }
    496 
    497 
    498 #  if defined(VBOX_WITH_NESTED_HWVIRT_SVM) || defined(VBOX_WITH_NESTED_HWVIRT_VMX)
    499 /**
    500  * Performs a minimal reinitialization of the execution state.
    501  *
    502  * This is intended to be used by VM-exits, SMM, LOADALL and other similar
    503  * 'world-switch' types operations on the CPU. Currently only nested
    504  * hardware-virtualization uses it.
    505  *
    506  * @param   pVCpu               The cross context virtual CPU structure of the calling EMT.
    507  * @param   cbInstr             The instruction length (for flushing).
    508  */
    509 DECLINLINE(void) iemReInitExec(PVMCPUCC pVCpu, uint8_t cbInstr) RT_NOEXCEPT
    510 {
    511     pVCpu->iem.s.fExec = iemCalcExecFlags(pVCpu) | (pVCpu->iem.s.fExec & IEM_F_USER_OPTS);
    512     iemOpcodeFlushHeavy(pVCpu, cbInstr);
    513 }
    514328#  endif
    515 
    516 # endif /* VBOX_INCLUDED_vmm_dbgf_h || DOXYGEN_RUNNING */
    517 
    518 /**
    519  * Counterpart to #iemInitExec that undoes evil strict-build stuff.
    520  *
    521  * @param   pVCpu               The cross context virtual CPU structure of the
    522  *                              calling thread.
    523  */
    524 DECLINLINE(void) iemUninitExec(PVMCPUCC pVCpu) RT_NOEXCEPT
    525 {
    526     /* Note! do not touch fInPatchCode here! (see iemUninitExecAndFiddleStatusAndMaybeReenter) */
    527 # ifdef VBOX_STRICT
    528 #  ifdef IEM_WITH_CODE_TLB
    529     NOREF(pVCpu);
    530 #  else
    531     pVCpu->iem.s.cbOpcode = 0;
    532 #  endif
    533 # else
    534     NOREF(pVCpu);
    535 # endif
    536 }
    537 
    538 
    539 /**
    540  * Calls iemUninitExec, iemExecStatusCodeFiddling and iemRCRawMaybeReenter.
    541  *
    542  * Only calling iemRCRawMaybeReenter in raw-mode, obviously.
    543  *
    544  * @returns Fiddled strict vbox status code, ready to return to non-IEM caller.
    545  * @param   pVCpu       The cross context virtual CPU structure of the calling thread.
    546  * @param   rcStrict    The status code to fiddle.
    547  */
    548 DECLINLINE(VBOXSTRICTRC) iemUninitExecAndFiddleStatusAndMaybeReenter(PVMCPUCC pVCpu, VBOXSTRICTRC rcStrict) RT_NOEXCEPT
    549 {
    550     iemUninitExec(pVCpu);
    551     return iemExecStatusCodeFiddling(pVCpu, rcStrict);
    552 }
     329}
     330# endif /* VBOX_STRICT */
     331#endif /* !IEM_WITH_OPAQUE_DECODER_STATE */
    553332
    554333
     
    561340 * @param   a_cbMin     The minimum length.
    562341 */
    563 # define IEMEXEC_ASSERT_INSTR_LEN_RETURN(a_cbInstr, a_cbMin) \
     342#define IEMEXEC_ASSERT_INSTR_LEN_RETURN(a_cbInstr, a_cbMin) \
    564343    AssertMsgReturn((unsigned)(a_cbInstr) - (unsigned)(a_cbMin) <= (unsigned)15 - (unsigned)(a_cbMin), \
    565344                    ("cbInstr=%u cbMin=%u\n", (a_cbInstr), (a_cbMin)), VERR_IEM_INVALID_INSTR_LENGTH)
    566 
    567 
    568 # ifndef IEM_WITH_SETJMP
    569 
    570 /**
    571  * Fetches the first opcode byte.
    572  *
    573  * @returns Strict VBox status code.
    574  * @param   pVCpu               The cross context virtual CPU structure of the
    575  *                              calling thread.
    576  * @param   pu8                 Where to return the opcode byte.
    577  */
    578 DECLINLINE(VBOXSTRICTRC) iemOpcodeGetFirstU8(PVMCPUCC pVCpu, uint8_t *pu8) RT_NOEXCEPT
    579 {
    580     /*
    581      * Check for hardware instruction breakpoints.
    582      * Note! Guest breakpoints are only checked after POP SS or MOV SS on AMD CPUs.
    583      */
    584     if (RT_LIKELY(!(pVCpu->iem.s.fExec & IEM_F_PENDING_BRK_INSTR)))
    585     { /* likely */ }
    586     else
    587     {
    588         VBOXSTRICTRC rcStrict = DBGFBpCheckInstruction(pVCpu->CTX_SUFF(pVM), pVCpu,
    589                                                        pVCpu->cpum.GstCtx.rip + pVCpu->cpum.GstCtx.cs.u64Base,
    590                                                           !(pVCpu->cpum.GstCtx.rflags.uBoth & CPUMCTX_INHIBIT_SHADOW_SS)
    591                                                        || IEM_IS_GUEST_CPU_AMD(pVCpu));
    592         if (RT_LIKELY(rcStrict == VINF_SUCCESS))
    593         { /* likely */ }
    594         else
    595         {
    596             *pu8 = 0xff; /* shut up gcc. sigh */
    597             if (rcStrict == VINF_EM_RAW_GUEST_TRAP)
    598                 return iemRaiseDebugException(pVCpu);
    599             return rcStrict;
    600         }
    601     }
    602 
    603     /*
    604      * Fetch the first opcode byte.
    605      */
    606     uintptr_t const offOpcode = pVCpu->iem.s.offOpcode;
    607     if (RT_LIKELY((uint8_t)offOpcode < pVCpu->iem.s.cbOpcode))
    608     {
    609         pVCpu->iem.s.offOpcode = (uint8_t)offOpcode + 1;
    610         *pu8 = pVCpu->iem.s.abOpcode[offOpcode];
    611         return VINF_SUCCESS;
    612     }
    613     return iemOpcodeGetNextU8Slow(pVCpu, pu8);
    614 }
    615 
    616 # else  /* IEM_WITH_SETJMP */
    617 
    618 /**
    619  * Fetches the first opcode byte, longjmp on error.
    620  *
    621  * @returns The opcode byte.
    622  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    623  */
    624 DECL_INLINE_THROW(uint8_t) iemOpcodeGetFirstU8Jmp(PVMCPUCC pVCpu) IEM_NOEXCEPT_MAY_LONGJMP
    625 {
    626     /*
    627      * Check for hardware instruction breakpoints.
    628     * Note! Guest breakpoints are only checked after POP SS or MOV SS on AMD CPUs.
    629      */
    630     if (RT_LIKELY(!(pVCpu->iem.s.fExec & IEM_F_PENDING_BRK_INSTR)))
    631     { /* likely */ }
    632     else
    633     {
    634         VBOXSTRICTRC rcStrict = DBGFBpCheckInstruction(pVCpu->CTX_SUFF(pVM), pVCpu,
    635                                                        pVCpu->cpum.GstCtx.rip + pVCpu->cpum.GstCtx.cs.u64Base,
    636                                                           !(pVCpu->cpum.GstCtx.rflags.uBoth & CPUMCTX_INHIBIT_SHADOW_SS)
    637                                                        || IEM_IS_GUEST_CPU_AMD(pVCpu));
    638         if (RT_LIKELY(rcStrict == VINF_SUCCESS))
    639         { /* likely */ }
    640         else
    641         {
    642             if (rcStrict == VINF_EM_RAW_GUEST_TRAP)
    643                 rcStrict = iemRaiseDebugException(pVCpu);
    644             IEM_DO_LONGJMP(pVCpu, VBOXSTRICTRC_VAL(rcStrict));
    645         }
    646     }
    647 
    648     /*
    649      * Fetch the first opcode byte.
    650      */
    651 #  ifdef IEM_WITH_CODE_TLB
    652     uint8_t         bRet;
    653     uintptr_t       offBuf = pVCpu->iem.s.offInstrNextByte;
    654     uint8_t const  *pbBuf  = pVCpu->iem.s.pbInstrBuf;
    655     if (RT_LIKELY(   pbBuf != NULL
    656                   && offBuf < pVCpu->iem.s.cbInstrBuf))
    657     {
    658         pVCpu->iem.s.offInstrNextByte = (uint32_t)offBuf + 1;
    659         bRet = pbBuf[offBuf];
    660     }
    661     else
    662         bRet = iemOpcodeGetNextU8SlowJmp(pVCpu);
    663 #   ifdef IEM_WITH_CODE_TLB_AND_OPCODE_BUF
    664     Assert(pVCpu->iem.s.offOpcode == 0);
    665     pVCpu->iem.s.abOpcode[pVCpu->iem.s.offOpcode++] = bRet;
    666 #   endif
    667     return bRet;
    668 
    669 #  else /* !IEM_WITH_CODE_TLB */
    670     uintptr_t offOpcode = pVCpu->iem.s.offOpcode;
    671     if (RT_LIKELY((uint8_t)offOpcode < pVCpu->iem.s.cbOpcode))
    672     {
    673         pVCpu->iem.s.offOpcode = (uint8_t)offOpcode + 1;
    674         return pVCpu->iem.s.abOpcode[offOpcode];
    675     }
    676     return iemOpcodeGetNextU8SlowJmp(pVCpu);
    677 #  endif
    678 }
    679 
    680 # endif /* IEM_WITH_SETJMP */
    681 
    682 /**
    683  * Fetches the first opcode byte, returns/throws automatically on failure.
    684  *
    685  * @param   a_pu8               Where to return the opcode byte.
    686  * @remark Implicitly references pVCpu.
    687  */
    688 # ifndef IEM_WITH_SETJMP
    689 #  define IEM_OPCODE_GET_FIRST_U8(a_pu8) \
    690     do \
    691     { \
    692         VBOXSTRICTRC rcStrict2 = iemOpcodeGetFirstU8(pVCpu, (a_pu8)); \
    693         if (rcStrict2 == VINF_SUCCESS) \
    694         { /* likely */ } \
    695         else \
    696             return rcStrict2; \
    697     } while (0)
    698 # else
    699 #  define IEM_OPCODE_GET_FIRST_U8(a_pu8) (*(a_pu8) = iemOpcodeGetFirstU8Jmp(pVCpu))
    700 # endif /* IEM_WITH_SETJMP */
    701 
    702 
    703 # ifndef IEM_WITH_SETJMP
    704 
    705 /**
    706  * Fetches the next opcode byte.
    707  *
    708  * @returns Strict VBox status code.
    709  * @param   pVCpu               The cross context virtual CPU structure of the
    710  *                              calling thread.
    711  * @param   pu8                 Where to return the opcode byte.
    712  */
    713 DECLINLINE(VBOXSTRICTRC) iemOpcodeGetNextU8(PVMCPUCC pVCpu, uint8_t *pu8) RT_NOEXCEPT
    714 {
    715     uintptr_t const offOpcode = pVCpu->iem.s.offOpcode;
    716     if (RT_LIKELY((uint8_t)offOpcode < pVCpu->iem.s.cbOpcode))
    717     {
    718         pVCpu->iem.s.offOpcode = (uint8_t)offOpcode + 1;
    719         *pu8 = pVCpu->iem.s.abOpcode[offOpcode];
    720         return VINF_SUCCESS;
    721     }
    722     return iemOpcodeGetNextU8Slow(pVCpu, pu8);
    723 }
    724 
    725 # else  /* IEM_WITH_SETJMP */
    726 
    727 /**
    728  * Fetches the next opcode byte, longjmp on error.
    729  *
    730  * @returns The opcode byte.
    731  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    732  */
    733 DECL_INLINE_THROW(uint8_t) iemOpcodeGetNextU8Jmp(PVMCPUCC pVCpu) IEM_NOEXCEPT_MAY_LONGJMP
    734 {
    735 #  ifdef IEM_WITH_CODE_TLB
    736     uint8_t         bRet;
    737     uintptr_t       offBuf = pVCpu->iem.s.offInstrNextByte;
    738     uint8_t const  *pbBuf  = pVCpu->iem.s.pbInstrBuf;
    739     if (RT_LIKELY(   pbBuf != NULL
    740                   && offBuf < pVCpu->iem.s.cbInstrBuf))
    741     {
    742         pVCpu->iem.s.offInstrNextByte = (uint32_t)offBuf + 1;
    743         bRet = pbBuf[offBuf];
    744     }
    745     else
    746         bRet = iemOpcodeGetNextU8SlowJmp(pVCpu);
    747 #   ifdef IEM_WITH_CODE_TLB_AND_OPCODE_BUF
    748     Assert(pVCpu->iem.s.offOpcode < sizeof(pVCpu->iem.s.abOpcode));
    749     pVCpu->iem.s.abOpcode[pVCpu->iem.s.offOpcode++] = bRet;
    750 #   endif
    751     return bRet;
    752 
    753 #  else /* !IEM_WITH_CODE_TLB */
    754     uintptr_t offOpcode = pVCpu->iem.s.offOpcode;
    755     if (RT_LIKELY((uint8_t)offOpcode < pVCpu->iem.s.cbOpcode))
    756     {
    757         pVCpu->iem.s.offOpcode = (uint8_t)offOpcode + 1;
    758         return pVCpu->iem.s.abOpcode[offOpcode];
    759     }
    760     return iemOpcodeGetNextU8SlowJmp(pVCpu);
    761 #  endif
    762 }
    763 
    764 # endif /* IEM_WITH_SETJMP */
    765 
    766 /**
    767  * Fetches the next opcode byte, returns automatically on failure.
    768  *
    769  * @param   a_pu8               Where to return the opcode byte.
    770  * @remark Implicitly references pVCpu.
    771  */
    772 # ifndef IEM_WITH_SETJMP
    773 #  define IEM_OPCODE_GET_NEXT_U8(a_pu8) \
    774     do \
    775     { \
    776         VBOXSTRICTRC rcStrict2 = iemOpcodeGetNextU8(pVCpu, (a_pu8)); \
    777         if (rcStrict2 == VINF_SUCCESS) \
    778         { /* likely */ } \
    779         else \
    780             return rcStrict2; \
    781     } while (0)
    782 # else
    783 #  define IEM_OPCODE_GET_NEXT_U8(a_pu8) (*(a_pu8) = iemOpcodeGetNextU8Jmp(pVCpu))
    784 # endif /* IEM_WITH_SETJMP */
    785 
    786 
    787 # ifndef IEM_WITH_SETJMP
    788 /**
    789  * Fetches the next signed byte from the opcode stream.
    790  *
    791  * @returns Strict VBox status code.
    792  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    793  * @param   pi8                 Where to return the signed byte.
    794  */
    795 DECLINLINE(VBOXSTRICTRC) iemOpcodeGetNextS8(PVMCPUCC pVCpu, int8_t *pi8) RT_NOEXCEPT
    796 {
    797     return iemOpcodeGetNextU8(pVCpu, (uint8_t *)pi8);
    798 }
    799 # endif /* !IEM_WITH_SETJMP */
    800 
    801 
    802 /**
    803  * Fetches the next signed byte from the opcode stream, returning automatically
    804  * on failure.
    805  *
    806  * @param   a_pi8               Where to return the signed byte.
    807  * @remark Implicitly references pVCpu.
    808  */
    809 # ifndef IEM_WITH_SETJMP
    810 #  define IEM_OPCODE_GET_NEXT_S8(a_pi8) \
    811     do \
    812     { \
    813         VBOXSTRICTRC rcStrict2 = iemOpcodeGetNextS8(pVCpu, (a_pi8)); \
    814         if (rcStrict2 != VINF_SUCCESS) \
    815             return rcStrict2; \
    816     } while (0)
    817 # else /* IEM_WITH_SETJMP */
    818 #  define IEM_OPCODE_GET_NEXT_S8(a_pi8) (*(a_pi8) = (int8_t)iemOpcodeGetNextU8Jmp(pVCpu))
    819 
    820 # endif /* IEM_WITH_SETJMP */
    821 
    822 
    823 # ifndef IEM_WITH_SETJMP
    824 /**
    825  * Fetches the next signed byte from the opcode stream, extending it to
    826  * unsigned 16-bit.
    827  *
    828  * @returns Strict VBox status code.
    829  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    830  * @param   pu16                Where to return the unsigned word.
    831  */
    832 DECLINLINE(VBOXSTRICTRC) iemOpcodeGetNextS8SxU16(PVMCPUCC pVCpu, uint16_t *pu16) RT_NOEXCEPT
    833 {
    834     uint8_t const offOpcode = pVCpu->iem.s.offOpcode;
    835     if (RT_UNLIKELY(offOpcode >= pVCpu->iem.s.cbOpcode))
    836         return iemOpcodeGetNextS8SxU16Slow(pVCpu, pu16);
    837 
    838     *pu16 = (uint16_t)(int16_t)(int8_t)pVCpu->iem.s.abOpcode[offOpcode];
    839     pVCpu->iem.s.offOpcode = offOpcode + 1;
    840     return VINF_SUCCESS;
    841 }
    842 # endif /* !IEM_WITH_SETJMP */
    843 
    844 /**
    845  * Fetches the next signed byte from the opcode stream and sign-extending it to
    846  * a word, returning automatically on failure.
    847  *
    848  * @param   a_pu16              Where to return the word.
    849  * @remark Implicitly references pVCpu.
    850  */
    851 # ifndef IEM_WITH_SETJMP
    852 #  define IEM_OPCODE_GET_NEXT_S8_SX_U16(a_pu16) \
    853     do \
    854     { \
    855         VBOXSTRICTRC rcStrict2 = iemOpcodeGetNextS8SxU16(pVCpu, (a_pu16)); \
    856         if (rcStrict2 != VINF_SUCCESS) \
    857             return rcStrict2; \
    858     } while (0)
    859 # else
    860 #  define IEM_OPCODE_GET_NEXT_S8_SX_U16(a_pu16) (*(a_pu16) = (uint16_t)(int16_t)(int8_t)iemOpcodeGetNextU8Jmp(pVCpu))
    861 # endif
    862 
    863 # ifndef IEM_WITH_SETJMP
    864 /**
    865  * Fetches the next signed byte from the opcode stream, extending it to
    866  * unsigned 32-bit.
    867  *
    868  * @returns Strict VBox status code.
    869  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    870  * @param   pu32                Where to return the unsigned dword.
    871  */
    872 DECLINLINE(VBOXSTRICTRC) iemOpcodeGetNextS8SxU32(PVMCPUCC pVCpu, uint32_t *pu32) RT_NOEXCEPT
    873 {
    874     uint8_t const offOpcode = pVCpu->iem.s.offOpcode;
    875     if (RT_UNLIKELY(offOpcode >= pVCpu->iem.s.cbOpcode))
    876         return iemOpcodeGetNextS8SxU32Slow(pVCpu, pu32);
    877 
    878     *pu32 = (uint32_t)(int32_t)(int8_t)pVCpu->iem.s.abOpcode[offOpcode];
    879     pVCpu->iem.s.offOpcode = offOpcode + 1;
    880     return VINF_SUCCESS;
    881 }
    882 # endif /* !IEM_WITH_SETJMP */
    883 
    884 /**
    885  * Fetches the next signed byte from the opcode stream and sign-extending it to
    886  * a word, returning automatically on failure.
    887  *
    888  * @param   a_pu32              Where to return the word.
    889  * @remark Implicitly references pVCpu.
    890  */
    891 # ifndef IEM_WITH_SETJMP
    892 #  define IEM_OPCODE_GET_NEXT_S8_SX_U32(a_pu32) \
    893     do \
    894     { \
    895         VBOXSTRICTRC rcStrict2 = iemOpcodeGetNextS8SxU32(pVCpu, (a_pu32)); \
    896         if (rcStrict2 != VINF_SUCCESS) \
    897             return rcStrict2; \
    898     } while (0)
    899 # else
    900 #  define IEM_OPCODE_GET_NEXT_S8_SX_U32(a_pu32) (*(a_pu32) = (uint32_t)(int32_t)(int8_t)iemOpcodeGetNextU8Jmp(pVCpu))
    901 # endif
    902 
    903 
    904 # ifndef IEM_WITH_SETJMP
    905 /**
    906  * Fetches the next signed byte from the opcode stream, extending it to
    907  * unsigned 64-bit.
    908  *
    909  * @returns Strict VBox status code.
    910  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    911  * @param   pu64                Where to return the unsigned qword.
    912  */
    913 DECLINLINE(VBOXSTRICTRC) iemOpcodeGetNextS8SxU64(PVMCPUCC pVCpu, uint64_t *pu64) RT_NOEXCEPT
    914 {
    915     uint8_t const offOpcode = pVCpu->iem.s.offOpcode;
    916     if (RT_UNLIKELY(offOpcode >= pVCpu->iem.s.cbOpcode))
    917         return iemOpcodeGetNextS8SxU64Slow(pVCpu, pu64);
    918 
    919     *pu64 = (uint64_t)(int64_t)(int8_t)pVCpu->iem.s.abOpcode[offOpcode];
    920     pVCpu->iem.s.offOpcode = offOpcode + 1;
    921     return VINF_SUCCESS;
    922 }
    923 # endif /* !IEM_WITH_SETJMP */
    924 
    925 /**
    926  * Fetches the next signed byte from the opcode stream and sign-extending it to
    927  * a word, returning automatically on failure.
    928  *
    929  * @param   a_pu64              Where to return the word.
    930  * @remark Implicitly references pVCpu.
    931  */
    932 # ifndef IEM_WITH_SETJMP
    933 #  define IEM_OPCODE_GET_NEXT_S8_SX_U64(a_pu64) \
    934     do \
    935     { \
    936         VBOXSTRICTRC rcStrict2 = iemOpcodeGetNextS8SxU64(pVCpu, (a_pu64)); \
    937         if (rcStrict2 != VINF_SUCCESS) \
    938             return rcStrict2; \
    939     } while (0)
    940 # else
    941 #  define IEM_OPCODE_GET_NEXT_S8_SX_U64(a_pu64) (*(a_pu64) = (uint64_t)(int64_t)(int8_t)iemOpcodeGetNextU8Jmp(pVCpu))
    942 # endif
    943 
    944 
    945 # ifndef IEM_WITH_SETJMP
    946 
    947 /**
    948  * Fetches the next opcode word.
    949  *
    950  * @returns Strict VBox status code.
    951  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    952  * @param   pu16                Where to return the opcode word.
    953  */
    954 DECLINLINE(VBOXSTRICTRC) iemOpcodeGetNextU16(PVMCPUCC pVCpu, uint16_t *pu16) RT_NOEXCEPT
    955 {
    956     uintptr_t const offOpcode = pVCpu->iem.s.offOpcode;
    957     if (RT_LIKELY((uint8_t)offOpcode + 2 <= pVCpu->iem.s.cbOpcode))
    958     {
    959         pVCpu->iem.s.offOpcode = (uint8_t)offOpcode + 2;
    960 #  ifdef IEM_USE_UNALIGNED_DATA_ACCESS
    961         *pu16 = *(uint16_t const *)&pVCpu->iem.s.abOpcode[offOpcode];
    962 #  else
    963         *pu16 = RT_MAKE_U16(pVCpu->iem.s.abOpcode[offOpcode], pVCpu->iem.s.abOpcode[offOpcode + 1]);
    964 #  endif
    965         return VINF_SUCCESS;
    966     }
    967     return iemOpcodeGetNextU16Slow(pVCpu, pu16);
    968 }
    969 
    970 # else  /* IEM_WITH_SETJMP */
    971 
    972 /**
    973  * Fetches the next opcode word, longjmp on error.
    974  *
    975  * @returns The opcode word.
    976  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    977  */
    978 DECL_INLINE_THROW(uint16_t) iemOpcodeGetNextU16Jmp(PVMCPUCC pVCpu) IEM_NOEXCEPT_MAY_LONGJMP
    979 {
    980 #  ifdef IEM_WITH_CODE_TLB
    981     uint16_t        u16Ret;
    982     uintptr_t       offBuf = pVCpu->iem.s.offInstrNextByte;
    983     uint8_t const  *pbBuf  = pVCpu->iem.s.pbInstrBuf;
    984     if (RT_LIKELY(   pbBuf != NULL
    985                   && offBuf + 2 <= pVCpu->iem.s.cbInstrBuf))
    986     {
    987         pVCpu->iem.s.offInstrNextByte = (uint32_t)offBuf + 2;
    988 #   ifdef IEM_USE_UNALIGNED_DATA_ACCESS
    989         u16Ret = *(uint16_t const *)&pbBuf[offBuf];
    990 #   else
    991         u16Ret = RT_MAKE_U16(pbBuf[offBuf], pbBuf[offBuf + 1]);
    992 #   endif
    993     }
    994     else
    995         u16Ret = iemOpcodeGetNextU16SlowJmp(pVCpu);
    996 
    997 #   ifdef IEM_WITH_CODE_TLB_AND_OPCODE_BUF
    998     uintptr_t const offOpcode = pVCpu->iem.s.offOpcode;
    999     Assert(offOpcode + 1 < sizeof(pVCpu->iem.s.abOpcode));
    1000 #    ifdef IEM_USE_UNALIGNED_DATA_ACCESS
    1001     *(uint16_t *)&pVCpu->iem.s.abOpcode[offOpcode] = u16Ret;
    1002 #    else
    1003     pVCpu->iem.s.abOpcode[offOpcode]     = RT_LO_U8(u16Ret);
    1004     pVCpu->iem.s.abOpcode[offOpcode + 1] = RT_HI_U8(u16Ret);
    1005 #    endif
    1006     pVCpu->iem.s.offOpcode = (uint8_t)offOpcode + (uint8_t)2;
    1007 #   endif
    1008 
    1009     return u16Ret;
    1010 
    1011 #  else /* !IEM_WITH_CODE_TLB */
    1012     uintptr_t const offOpcode = pVCpu->iem.s.offOpcode;
    1013     if (RT_LIKELY((uint8_t)offOpcode + 2 <= pVCpu->iem.s.cbOpcode))
    1014     {
    1015         pVCpu->iem.s.offOpcode = (uint8_t)offOpcode + 2;
    1016 #   ifdef IEM_USE_UNALIGNED_DATA_ACCESS
    1017         return *(uint16_t const *)&pVCpu->iem.s.abOpcode[offOpcode];
    1018 #   else
    1019         return RT_MAKE_U16(pVCpu->iem.s.abOpcode[offOpcode], pVCpu->iem.s.abOpcode[offOpcode + 1]);
    1020 #   endif
    1021     }
    1022     return iemOpcodeGetNextU16SlowJmp(pVCpu);
    1023 #  endif /* !IEM_WITH_CODE_TLB */
    1024 }
    1025 
    1026 # endif /* IEM_WITH_SETJMP */
    1027 
    1028 /**
    1029  * Fetches the next opcode word, returns automatically on failure.
    1030  *
    1031  * @param   a_pu16              Where to return the opcode word.
    1032  * @remark Implicitly references pVCpu.
    1033  */
    1034 # ifndef IEM_WITH_SETJMP
    1035 #  define IEM_OPCODE_GET_NEXT_U16(a_pu16) \
    1036     do \
    1037     { \
    1038         VBOXSTRICTRC rcStrict2 = iemOpcodeGetNextU16(pVCpu, (a_pu16)); \
    1039         if (rcStrict2 != VINF_SUCCESS) \
    1040             return rcStrict2; \
    1041     } while (0)
    1042 # else
    1043 #  define IEM_OPCODE_GET_NEXT_U16(a_pu16) (*(a_pu16) = iemOpcodeGetNextU16Jmp(pVCpu))
    1044 # endif
    1045 
    1046 # ifndef IEM_WITH_SETJMP
    1047 /**
    1048  * Fetches the next opcode word, zero extending it to a double word.
    1049  *
    1050  * @returns Strict VBox status code.
    1051  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    1052  * @param   pu32                Where to return the opcode double word.
    1053  */
    1054 DECLINLINE(VBOXSTRICTRC) iemOpcodeGetNextU16ZxU32(PVMCPUCC pVCpu, uint32_t *pu32) RT_NOEXCEPT
    1055 {
    1056     uint8_t const offOpcode = pVCpu->iem.s.offOpcode;
    1057     if (RT_UNLIKELY(offOpcode + 2 > pVCpu->iem.s.cbOpcode))
    1058         return iemOpcodeGetNextU16ZxU32Slow(pVCpu, pu32);
    1059 
    1060     *pu32 = RT_MAKE_U16(pVCpu->iem.s.abOpcode[offOpcode], pVCpu->iem.s.abOpcode[offOpcode + 1]);
    1061     pVCpu->iem.s.offOpcode = offOpcode + 2;
    1062     return VINF_SUCCESS;
    1063 }
    1064 # endif /* !IEM_WITH_SETJMP */
    1065 
    1066 /**
    1067  * Fetches the next opcode word and zero extends it to a double word, returns
    1068  * automatically on failure.
    1069  *
    1070  * @param   a_pu32              Where to return the opcode double word.
    1071  * @remark Implicitly references pVCpu.
    1072  */
    1073 # ifndef IEM_WITH_SETJMP
    1074 #  define IEM_OPCODE_GET_NEXT_U16_ZX_U32(a_pu32) \
    1075     do \
    1076     { \
    1077         VBOXSTRICTRC rcStrict2 = iemOpcodeGetNextU16ZxU32(pVCpu, (a_pu32)); \
    1078         if (rcStrict2 != VINF_SUCCESS) \
    1079             return rcStrict2; \
    1080     } while (0)
    1081 # else
    1082 #  define IEM_OPCODE_GET_NEXT_U16_ZX_U32(a_pu32) (*(a_pu32) = iemOpcodeGetNextU16Jmp(pVCpu))
    1083 # endif
    1084 
    1085 # ifndef IEM_WITH_SETJMP
    1086 /**
    1087  * Fetches the next opcode word, zero extending it to a quad word.
    1088  *
    1089  * @returns Strict VBox status code.
    1090  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    1091  * @param   pu64                Where to return the opcode quad word.
    1092  */
    1093 DECLINLINE(VBOXSTRICTRC) iemOpcodeGetNextU16ZxU64(PVMCPUCC pVCpu, uint64_t *pu64) RT_NOEXCEPT
    1094 {
    1095     uint8_t const offOpcode = pVCpu->iem.s.offOpcode;
    1096     if (RT_UNLIKELY(offOpcode + 2 > pVCpu->iem.s.cbOpcode))
    1097         return iemOpcodeGetNextU16ZxU64Slow(pVCpu, pu64);
    1098 
    1099     *pu64 = RT_MAKE_U16(pVCpu->iem.s.abOpcode[offOpcode], pVCpu->iem.s.abOpcode[offOpcode + 1]);
    1100     pVCpu->iem.s.offOpcode = offOpcode + 2;
    1101     return VINF_SUCCESS;
    1102 }
    1103 # endif /* !IEM_WITH_SETJMP */
    1104 
    1105 /**
    1106  * Fetches the next opcode word and zero extends it to a quad word, returns
    1107  * automatically on failure.
    1108  *
    1109  * @param   a_pu64              Where to return the opcode quad word.
    1110  * @remark Implicitly references pVCpu.
    1111  */
    1112 # ifndef IEM_WITH_SETJMP
    1113 #  define IEM_OPCODE_GET_NEXT_U16_ZX_U64(a_pu64) \
    1114     do \
    1115     { \
    1116         VBOXSTRICTRC rcStrict2 = iemOpcodeGetNextU16ZxU64(pVCpu, (a_pu64)); \
    1117         if (rcStrict2 != VINF_SUCCESS) \
    1118             return rcStrict2; \
    1119     } while (0)
    1120 # else
    1121 #  define IEM_OPCODE_GET_NEXT_U16_ZX_U64(a_pu64)  (*(a_pu64) = iemOpcodeGetNextU16Jmp(pVCpu))
    1122 # endif
    1123 
    1124 
    1125 # ifndef IEM_WITH_SETJMP
    1126 /**
    1127  * Fetches the next signed word from the opcode stream.
    1128  *
    1129  * @returns Strict VBox status code.
    1130  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    1131  * @param   pi16                Where to return the signed word.
    1132  */
    1133 DECLINLINE(VBOXSTRICTRC) iemOpcodeGetNextS16(PVMCPUCC pVCpu, int16_t *pi16) RT_NOEXCEPT
    1134 {
    1135     return iemOpcodeGetNextU16(pVCpu, (uint16_t *)pi16);
    1136 }
    1137 # endif /* !IEM_WITH_SETJMP */
    1138 
    1139 
    1140 /**
    1141  * Fetches the next signed word from the opcode stream, returning automatically
    1142  * on failure.
    1143  *
    1144  * @param   a_pi16              Where to return the signed word.
    1145  * @remark Implicitly references pVCpu.
    1146  */
    1147 # ifndef IEM_WITH_SETJMP
    1148 #  define IEM_OPCODE_GET_NEXT_S16(a_pi16) \
    1149     do \
    1150     { \
    1151         VBOXSTRICTRC rcStrict2 = iemOpcodeGetNextS16(pVCpu, (a_pi16)); \
    1152         if (rcStrict2 != VINF_SUCCESS) \
    1153             return rcStrict2; \
    1154     } while (0)
    1155 # else
    1156 #  define IEM_OPCODE_GET_NEXT_S16(a_pi16) (*(a_pi16) = (int16_t)iemOpcodeGetNextU16Jmp(pVCpu))
    1157 # endif
    1158 
    1159 # ifndef IEM_WITH_SETJMP
    1160 
    1161 /**
    1162  * Fetches the next opcode dword.
    1163  *
    1164  * @returns Strict VBox status code.
    1165  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    1166  * @param   pu32                Where to return the opcode double word.
    1167  */
    1168 DECLINLINE(VBOXSTRICTRC) iemOpcodeGetNextU32(PVMCPUCC pVCpu, uint32_t *pu32) RT_NOEXCEPT
    1169 {
    1170     uintptr_t const offOpcode = pVCpu->iem.s.offOpcode;
    1171     if (RT_LIKELY((uint8_t)offOpcode + 4 <= pVCpu->iem.s.cbOpcode))
    1172     {
    1173         pVCpu->iem.s.offOpcode = (uint8_t)offOpcode + 4;
    1174 #  ifdef IEM_USE_UNALIGNED_DATA_ACCESS
    1175         *pu32 = *(uint32_t const *)&pVCpu->iem.s.abOpcode[offOpcode];
    1176 #  else
    1177         *pu32 = RT_MAKE_U32_FROM_U8(pVCpu->iem.s.abOpcode[offOpcode],
    1178                                     pVCpu->iem.s.abOpcode[offOpcode + 1],
    1179                                     pVCpu->iem.s.abOpcode[offOpcode + 2],
    1180                                     pVCpu->iem.s.abOpcode[offOpcode + 3]);
    1181 #  endif
    1182         return VINF_SUCCESS;
    1183     }
    1184     return iemOpcodeGetNextU32Slow(pVCpu, pu32);
    1185 }
    1186 
    1187 # else  /* IEM_WITH_SETJMP */
    1188 
    1189 /**
    1190  * Fetches the next opcode dword, longjmp on error.
    1191  *
    1192  * @returns The opcode dword.
    1193  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    1194  */
    1195 DECL_INLINE_THROW(uint32_t) iemOpcodeGetNextU32Jmp(PVMCPUCC pVCpu) IEM_NOEXCEPT_MAY_LONGJMP
    1196 {
    1197 #  ifdef IEM_WITH_CODE_TLB
    1198     uint32_t u32Ret;
    1199     uintptr_t       offBuf = pVCpu->iem.s.offInstrNextByte;
    1200     uint8_t const  *pbBuf  = pVCpu->iem.s.pbInstrBuf;
    1201     if (RT_LIKELY(   pbBuf != NULL
    1202                   && offBuf + 4 <= pVCpu->iem.s.cbInstrBuf))
    1203     {
    1204         pVCpu->iem.s.offInstrNextByte = (uint32_t)offBuf + 4;
    1205 #   ifdef IEM_USE_UNALIGNED_DATA_ACCESS
    1206         u32Ret = *(uint32_t const *)&pbBuf[offBuf];
    1207 #   else
    1208         u32Ret = RT_MAKE_U32_FROM_U8(pbBuf[offBuf],
    1209                                      pbBuf[offBuf + 1],
    1210                                      pbBuf[offBuf + 2],
    1211                                      pbBuf[offBuf + 3]);
    1212 #   endif
    1213     }
    1214     else
    1215         u32Ret = iemOpcodeGetNextU32SlowJmp(pVCpu);
    1216 
    1217 #   ifdef IEM_WITH_CODE_TLB_AND_OPCODE_BUF
    1218     uintptr_t const offOpcode = pVCpu->iem.s.offOpcode;
    1219     Assert(offOpcode + 3 < sizeof(pVCpu->iem.s.abOpcode));
    1220 #    ifdef IEM_USE_UNALIGNED_DATA_ACCESS
    1221     *(uint32_t *)&pVCpu->iem.s.abOpcode[offOpcode] = u32Ret;
    1222 #    else
    1223     pVCpu->iem.s.abOpcode[offOpcode]     = RT_BYTE1(u32Ret);
    1224     pVCpu->iem.s.abOpcode[offOpcode + 1] = RT_BYTE2(u32Ret);
    1225     pVCpu->iem.s.abOpcode[offOpcode + 2] = RT_BYTE3(u32Ret);
    1226     pVCpu->iem.s.abOpcode[offOpcode + 3] = RT_BYTE4(u32Ret);
    1227 #    endif
    1228     pVCpu->iem.s.offOpcode = (uint8_t)offOpcode + (uint8_t)4;
    1229 #   endif /* IEM_WITH_CODE_TLB_AND_OPCODE_BUF */
    1230 
    1231     return u32Ret;
    1232 
    1233 #  else  /* !IEM_WITH_CODE_TLB */
    1234     uintptr_t const offOpcode = pVCpu->iem.s.offOpcode;
    1235     if (RT_LIKELY((uint8_t)offOpcode + 4 <= pVCpu->iem.s.cbOpcode))
    1236     {
    1237         pVCpu->iem.s.offOpcode = (uint8_t)offOpcode + 4;
    1238 #   ifdef IEM_USE_UNALIGNED_DATA_ACCESS
    1239         return *(uint32_t const *)&pVCpu->iem.s.abOpcode[offOpcode];
    1240 #   else
    1241         return RT_MAKE_U32_FROM_U8(pVCpu->iem.s.abOpcode[offOpcode],
    1242                                    pVCpu->iem.s.abOpcode[offOpcode + 1],
    1243                                    pVCpu->iem.s.abOpcode[offOpcode + 2],
    1244                                    pVCpu->iem.s.abOpcode[offOpcode + 3]);
    1245 #   endif
    1246     }
    1247     return iemOpcodeGetNextU32SlowJmp(pVCpu);
    1248 #  endif
    1249 }
    1250 
    1251 # endif /* IEM_WITH_SETJMP */
    1252 
    1253 /**
    1254  * Fetches the next opcode dword, returns automatically on failure.
    1255  *
    1256  * @param   a_pu32              Where to return the opcode dword.
    1257  * @remark Implicitly references pVCpu.
    1258  */
    1259 # ifndef IEM_WITH_SETJMP
    1260 #  define IEM_OPCODE_GET_NEXT_U32(a_pu32) \
    1261     do \
    1262     { \
    1263         VBOXSTRICTRC rcStrict2 = iemOpcodeGetNextU32(pVCpu, (a_pu32)); \
    1264         if (rcStrict2 != VINF_SUCCESS) \
    1265             return rcStrict2; \
    1266     } while (0)
    1267 # else
    1268 #  define IEM_OPCODE_GET_NEXT_U32(a_pu32) (*(a_pu32) = iemOpcodeGetNextU32Jmp(pVCpu))
    1269 # endif
    1270 
    1271 # ifndef IEM_WITH_SETJMP
    1272 /**
    1273  * Fetches the next opcode dword, zero extending it to a quad word.
    1274  *
    1275  * @returns Strict VBox status code.
    1276  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    1277  * @param   pu64                Where to return the opcode quad word.
    1278  */
    1279 DECLINLINE(VBOXSTRICTRC) iemOpcodeGetNextU32ZxU64(PVMCPUCC pVCpu, uint64_t *pu64) RT_NOEXCEPT
    1280 {
    1281     uint8_t const offOpcode = pVCpu->iem.s.offOpcode;
    1282     if (RT_UNLIKELY(offOpcode + 4 > pVCpu->iem.s.cbOpcode))
    1283         return iemOpcodeGetNextU32ZxU64Slow(pVCpu, pu64);
    1284 
    1285     *pu64 = RT_MAKE_U32_FROM_U8(pVCpu->iem.s.abOpcode[offOpcode],
    1286                                 pVCpu->iem.s.abOpcode[offOpcode + 1],
    1287                                 pVCpu->iem.s.abOpcode[offOpcode + 2],
    1288                                 pVCpu->iem.s.abOpcode[offOpcode + 3]);
    1289     pVCpu->iem.s.offOpcode = offOpcode + 4;
    1290     return VINF_SUCCESS;
    1291 }
    1292 # endif /* !IEM_WITH_SETJMP */
    1293 
    1294 /**
    1295  * Fetches the next opcode dword and zero extends it to a quad word, returns
    1296  * automatically on failure.
    1297  *
    1298  * @param   a_pu64              Where to return the opcode quad word.
    1299  * @remark Implicitly references pVCpu.
    1300  */
    1301 # ifndef IEM_WITH_SETJMP
    1302 #  define IEM_OPCODE_GET_NEXT_U32_ZX_U64(a_pu64) \
    1303     do \
    1304     { \
    1305         VBOXSTRICTRC rcStrict2 = iemOpcodeGetNextU32ZxU64(pVCpu, (a_pu64)); \
    1306         if (rcStrict2 != VINF_SUCCESS) \
    1307             return rcStrict2; \
    1308     } while (0)
    1309 # else
    1310 #  define IEM_OPCODE_GET_NEXT_U32_ZX_U64(a_pu64) (*(a_pu64) = iemOpcodeGetNextU32Jmp(pVCpu))
    1311 # endif
    1312 
    1313 
    1314 # ifndef IEM_WITH_SETJMP
    1315 /**
    1316  * Fetches the next signed double word from the opcode stream.
    1317  *
    1318  * @returns Strict VBox status code.
    1319  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    1320  * @param   pi32                Where to return the signed double word.
    1321  */
    1322 DECLINLINE(VBOXSTRICTRC) iemOpcodeGetNextS32(PVMCPUCC pVCpu, int32_t *pi32) RT_NOEXCEPT
    1323 {
    1324     return iemOpcodeGetNextU32(pVCpu, (uint32_t *)pi32);
    1325 }
    1326 # endif
    1327 
    1328 /**
    1329  * Fetches the next signed double word from the opcode stream, returning
    1330  * automatically on failure.
    1331  *
    1332  * @param   a_pi32              Where to return the signed double word.
    1333  * @remark Implicitly references pVCpu.
    1334  */
    1335 # ifndef IEM_WITH_SETJMP
    1336 #  define IEM_OPCODE_GET_NEXT_S32(a_pi32) \
    1337     do \
    1338     { \
    1339         VBOXSTRICTRC rcStrict2 = iemOpcodeGetNextS32(pVCpu, (a_pi32)); \
    1340         if (rcStrict2 != VINF_SUCCESS) \
    1341             return rcStrict2; \
    1342     } while (0)
    1343 # else
    1344 #  define IEM_OPCODE_GET_NEXT_S32(a_pi32)    (*(a_pi32) = (int32_t)iemOpcodeGetNextU32Jmp(pVCpu))
    1345 # endif
    1346 
    1347 # ifndef IEM_WITH_SETJMP
    1348 /**
    1349  * Fetches the next opcode dword, sign extending it into a quad word.
    1350  *
    1351  * @returns Strict VBox status code.
    1352  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    1353  * @param   pu64                Where to return the opcode quad word.
    1354  */
    1355 DECLINLINE(VBOXSTRICTRC) iemOpcodeGetNextS32SxU64(PVMCPUCC pVCpu, uint64_t *pu64) RT_NOEXCEPT
    1356 {
    1357     uint8_t const offOpcode = pVCpu->iem.s.offOpcode;
    1358     if (RT_UNLIKELY(offOpcode + 4 > pVCpu->iem.s.cbOpcode))
    1359         return iemOpcodeGetNextS32SxU64Slow(pVCpu, pu64);
    1360 
    1361     int32_t i32 = RT_MAKE_U32_FROM_U8(pVCpu->iem.s.abOpcode[offOpcode],
    1362                                       pVCpu->iem.s.abOpcode[offOpcode + 1],
    1363                                       pVCpu->iem.s.abOpcode[offOpcode + 2],
    1364                                       pVCpu->iem.s.abOpcode[offOpcode + 3]);
    1365     *pu64 = (uint64_t)(int64_t)i32;
    1366     pVCpu->iem.s.offOpcode = offOpcode + 4;
    1367     return VINF_SUCCESS;
    1368 }
    1369 # endif /* !IEM_WITH_SETJMP */
    1370 
    1371 /**
    1372  * Fetches the next opcode double word and sign extends it to a quad word,
    1373  * returns automatically on failure.
    1374  *
    1375  * @param   a_pu64              Where to return the opcode quad word.
    1376  * @remark Implicitly references pVCpu.
    1377  */
    1378 # ifndef IEM_WITH_SETJMP
    1379 #  define IEM_OPCODE_GET_NEXT_S32_SX_U64(a_pu64) \
    1380     do \
    1381     { \
    1382         VBOXSTRICTRC rcStrict2 = iemOpcodeGetNextS32SxU64(pVCpu, (a_pu64)); \
    1383         if (rcStrict2 != VINF_SUCCESS) \
    1384             return rcStrict2; \
    1385     } while (0)
    1386 # else
    1387 #  define IEM_OPCODE_GET_NEXT_S32_SX_U64(a_pu64) (*(a_pu64) = (uint64_t)(int64_t)(int32_t)iemOpcodeGetNextU32Jmp(pVCpu))
    1388 # endif
    1389 
    1390 # ifndef IEM_WITH_SETJMP
    1391 
    1392 /**
    1393  * Fetches the next opcode qword.
    1394  *
    1395  * @returns Strict VBox status code.
    1396  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    1397  * @param   pu64                Where to return the opcode qword.
    1398  */
    1399 DECLINLINE(VBOXSTRICTRC) iemOpcodeGetNextU64(PVMCPUCC pVCpu, uint64_t *pu64) RT_NOEXCEPT
    1400 {
    1401     uintptr_t const offOpcode = pVCpu->iem.s.offOpcode;
    1402     if (RT_LIKELY((uint8_t)offOpcode + 8 <= pVCpu->iem.s.cbOpcode))
    1403     {
    1404 #  ifdef IEM_USE_UNALIGNED_DATA_ACCESS
    1405         *pu64 = *(uint64_t const *)&pVCpu->iem.s.abOpcode[offOpcode];
    1406 #  else
    1407         *pu64 = RT_MAKE_U64_FROM_U8(pVCpu->iem.s.abOpcode[offOpcode],
    1408                                     pVCpu->iem.s.abOpcode[offOpcode + 1],
    1409                                     pVCpu->iem.s.abOpcode[offOpcode + 2],
    1410                                     pVCpu->iem.s.abOpcode[offOpcode + 3],
    1411                                     pVCpu->iem.s.abOpcode[offOpcode + 4],
    1412                                     pVCpu->iem.s.abOpcode[offOpcode + 5],
    1413                                     pVCpu->iem.s.abOpcode[offOpcode + 6],
    1414                                     pVCpu->iem.s.abOpcode[offOpcode + 7]);
    1415 #  endif
    1416         pVCpu->iem.s.offOpcode = (uint8_t)offOpcode + 8;
    1417         return VINF_SUCCESS;
    1418     }
    1419     return iemOpcodeGetNextU64Slow(pVCpu, pu64);
    1420 }
    1421 
    1422 # else  /* IEM_WITH_SETJMP */
    1423 
    1424 /**
    1425  * Fetches the next opcode qword, longjmp on error.
    1426  *
    1427  * @returns The opcode qword.
    1428  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    1429  */
    1430 DECL_INLINE_THROW(uint64_t) iemOpcodeGetNextU64Jmp(PVMCPUCC pVCpu) IEM_NOEXCEPT_MAY_LONGJMP
    1431 {
    1432 #  ifdef IEM_WITH_CODE_TLB
    1433     uint64_t        u64Ret;
    1434     uintptr_t       offBuf = pVCpu->iem.s.offInstrNextByte;
    1435     uint8_t const  *pbBuf  = pVCpu->iem.s.pbInstrBuf;
    1436     if (RT_LIKELY(   pbBuf != NULL
    1437                   && offBuf + 8 <= pVCpu->iem.s.cbInstrBuf))
    1438     {
    1439         pVCpu->iem.s.offInstrNextByte = (uint32_t)offBuf + 8;
    1440 #   ifdef IEM_USE_UNALIGNED_DATA_ACCESS
    1441         u64Ret = *(uint64_t const *)&pbBuf[offBuf];
    1442 #   else
    1443         u64Ret = RT_MAKE_U64_FROM_U8(pbBuf[offBuf],
    1444                                      pbBuf[offBuf + 1],
    1445                                      pbBuf[offBuf + 2],
    1446                                      pbBuf[offBuf + 3],
    1447                                      pbBuf[offBuf + 4],
    1448                                      pbBuf[offBuf + 5],
    1449                                      pbBuf[offBuf + 6],
    1450                                      pbBuf[offBuf + 7]);
    1451 #   endif
    1452     }
    1453     else
    1454         u64Ret = iemOpcodeGetNextU64SlowJmp(pVCpu);
    1455 
    1456 #   ifdef IEM_WITH_CODE_TLB_AND_OPCODE_BUF
    1457     uintptr_t const offOpcode = pVCpu->iem.s.offOpcode;
    1458     Assert(offOpcode + 7 < sizeof(pVCpu->iem.s.abOpcode));
    1459 #    ifdef IEM_USE_UNALIGNED_DATA_ACCESS
    1460     *(uint64_t *)&pVCpu->iem.s.abOpcode[offOpcode] = u64Ret;
    1461 #    else
    1462     pVCpu->iem.s.abOpcode[offOpcode]     = RT_BYTE1(u64Ret);
    1463     pVCpu->iem.s.abOpcode[offOpcode + 1] = RT_BYTE2(u64Ret);
    1464     pVCpu->iem.s.abOpcode[offOpcode + 2] = RT_BYTE3(u64Ret);
    1465     pVCpu->iem.s.abOpcode[offOpcode + 3] = RT_BYTE4(u64Ret);
    1466     pVCpu->iem.s.abOpcode[offOpcode + 4] = RT_BYTE5(u64Ret);
    1467     pVCpu->iem.s.abOpcode[offOpcode + 5] = RT_BYTE6(u64Ret);
    1468     pVCpu->iem.s.abOpcode[offOpcode + 6] = RT_BYTE7(u64Ret);
    1469     pVCpu->iem.s.abOpcode[offOpcode + 7] = RT_BYTE8(u64Ret);
    1470 #    endif
    1471     pVCpu->iem.s.offOpcode = (uint8_t)offOpcode + (uint8_t)8;
    1472 #   endif /* IEM_WITH_CODE_TLB_AND_OPCODE_BUF */
    1473 
    1474     return u64Ret;
    1475 
    1476 #  else /* !IEM_WITH_CODE_TLB */
    1477     uintptr_t const offOpcode = pVCpu->iem.s.offOpcode;
    1478     if (RT_LIKELY((uint8_t)offOpcode + 8 <= pVCpu->iem.s.cbOpcode))
    1479     {
    1480         pVCpu->iem.s.offOpcode = (uint8_t)offOpcode + 8;
    1481 #   ifdef IEM_USE_UNALIGNED_DATA_ACCESS
    1482         return *(uint64_t const *)&pVCpu->iem.s.abOpcode[offOpcode];
    1483 #   else
    1484         return RT_MAKE_U64_FROM_U8(pVCpu->iem.s.abOpcode[offOpcode],
    1485                                    pVCpu->iem.s.abOpcode[offOpcode + 1],
    1486                                    pVCpu->iem.s.abOpcode[offOpcode + 2],
    1487                                    pVCpu->iem.s.abOpcode[offOpcode + 3],
    1488                                    pVCpu->iem.s.abOpcode[offOpcode + 4],
    1489                                    pVCpu->iem.s.abOpcode[offOpcode + 5],
    1490                                    pVCpu->iem.s.abOpcode[offOpcode + 6],
    1491                                    pVCpu->iem.s.abOpcode[offOpcode + 7]);
    1492 #   endif
    1493     }
    1494     return iemOpcodeGetNextU64SlowJmp(pVCpu);
    1495 #  endif /* !IEM_WITH_CODE_TLB */
    1496 }
    1497 
    1498 # endif /* IEM_WITH_SETJMP */
    1499 
    1500 /**
    1501  * Fetches the next opcode quad word, returns automatically on failure.
    1502  *
    1503  * @param   a_pu64              Where to return the opcode quad word.
    1504  * @remark Implicitly references pVCpu.
    1505  */
    1506 # ifndef IEM_WITH_SETJMP
    1507 #  define IEM_OPCODE_GET_NEXT_U64(a_pu64) \
    1508     do \
    1509     { \
    1510         VBOXSTRICTRC rcStrict2 = iemOpcodeGetNextU64(pVCpu, (a_pu64)); \
    1511         if (rcStrict2 != VINF_SUCCESS) \
    1512             return rcStrict2; \
    1513     } while (0)
    1514 # else
    1515 #  define IEM_OPCODE_GET_NEXT_U64(a_pu64)    ( *(a_pu64) = iemOpcodeGetNextU64Jmp(pVCpu) )
    1516 # endif
    1517 
    1518 /**
    1519  * For fetching the opcode bytes for an ModR/M effective address, but throw
    1520  * away the result.
    1521  *
    1522  * This is used when decoding undefined opcodes and such where we want to avoid
    1523  * unnecessary MC blocks.
    1524  *
    1525  * @note The recompiler code overrides this one so iemOpHlpCalcRmEffAddrJmpEx is
    1526  *       used instead.  At least for now...
    1527  */
    1528 # ifndef IEM_WITH_SETJMP
    1529 #  define IEM_OPCODE_SKIP_RM_EFF_ADDR_BYTES(a_bRm) do { \
    1530         RTGCPTR      GCPtrEff; \
    1531         VBOXSTRICTRC rcStrict = iemOpHlpCalcRmEffAddr(pVCpu, bRm, 0, &GCPtrEff); \
    1532         if (rcStrict != VINF_SUCCESS) \
    1533             return rcStrict; \
    1534     } while (0)
    1535 # else
    1536 #  define IEM_OPCODE_SKIP_RM_EFF_ADDR_BYTES(a_bRm) do { \
    1537         (void)iemOpHlpCalcRmEffAddrJmp(pVCpu, bRm, 0); \
    1538     } while (0)
    1539 # endif
    1540 
    1541 #endif /* !IEM_WITH_OPAQUE_DECODER_STATE */
    1542345
    1543346
     
    1594397
    1595398/** @} */
    1596 
    1597 
    1598 /*
    1599  *
    1600  * Helpers routines.
    1601  * Helpers routines.
    1602  * Helpers routines.
    1603  *
    1604  */
    1605 
    1606 #ifndef IEM_WITH_OPAQUE_DECODER_STATE
    1607 
    1608 /**
    1609  * Recalculates the effective operand size.
    1610  *
    1611  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    1612  */
    1613 DECLINLINE(void) iemRecalEffOpSize(PVMCPUCC pVCpu) RT_NOEXCEPT
    1614 {
    1615     switch (IEM_GET_CPU_MODE(pVCpu))
    1616     {
    1617         case IEMMODE_16BIT:
    1618             pVCpu->iem.s.enmEffOpSize = pVCpu->iem.s.fPrefixes & IEM_OP_PRF_SIZE_OP ? IEMMODE_32BIT : IEMMODE_16BIT;
    1619             break;
    1620         case IEMMODE_32BIT:
    1621             pVCpu->iem.s.enmEffOpSize = pVCpu->iem.s.fPrefixes & IEM_OP_PRF_SIZE_OP ? IEMMODE_16BIT : IEMMODE_32BIT;
    1622             break;
    1623         case IEMMODE_64BIT:
    1624             switch (pVCpu->iem.s.fPrefixes & (IEM_OP_PRF_SIZE_REX_W | IEM_OP_PRF_SIZE_OP))
    1625             {
    1626                 case 0:
    1627                     pVCpu->iem.s.enmEffOpSize = pVCpu->iem.s.enmDefOpSize;
    1628                     break;
    1629                 case IEM_OP_PRF_SIZE_OP:
    1630                     pVCpu->iem.s.enmEffOpSize = IEMMODE_16BIT;
    1631                     break;
    1632                 case IEM_OP_PRF_SIZE_REX_W:
    1633                 case IEM_OP_PRF_SIZE_REX_W | IEM_OP_PRF_SIZE_OP:
    1634                     pVCpu->iem.s.enmEffOpSize = IEMMODE_64BIT;
    1635                     break;
    1636             }
    1637             break;
    1638         default:
    1639             AssertFailed();
    1640     }
    1641 }
    1642 
    1643 
    1644 /**
    1645  * Sets the default operand size to 64-bit and recalculates the effective
    1646  * operand size.
    1647  *
    1648  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    1649  */
    1650 DECLINLINE(void) iemRecalEffOpSize64Default(PVMCPUCC pVCpu) RT_NOEXCEPT
    1651 {
    1652     Assert(IEM_IS_64BIT_CODE(pVCpu));
    1653     pVCpu->iem.s.enmDefOpSize = IEMMODE_64BIT;
    1654     if ((pVCpu->iem.s.fPrefixes & (IEM_OP_PRF_SIZE_REX_W | IEM_OP_PRF_SIZE_OP)) != IEM_OP_PRF_SIZE_OP)
    1655         pVCpu->iem.s.enmEffOpSize = IEMMODE_64BIT;
    1656     else
    1657         pVCpu->iem.s.enmEffOpSize = IEMMODE_16BIT;
    1658 }
    1659 
    1660 
    1661 /**
    1662  * Sets the default operand size to 64-bit and recalculates the effective
    1663  * operand size, with intel ignoring any operand size prefix (AMD respects it).
    1664  *
    1665  * This is for the relative jumps.
    1666  *
    1667  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    1668  */
    1669 DECLINLINE(void) iemRecalEffOpSize64DefaultAndIntelIgnoresOpSizePrefix(PVMCPUCC pVCpu) RT_NOEXCEPT
    1670 {
    1671     Assert(IEM_IS_64BIT_CODE(pVCpu));
    1672     pVCpu->iem.s.enmDefOpSize = IEMMODE_64BIT;
    1673     if (   (pVCpu->iem.s.fPrefixes & (IEM_OP_PRF_SIZE_REX_W | IEM_OP_PRF_SIZE_OP)) != IEM_OP_PRF_SIZE_OP
    1674         || pVCpu->iem.s.enmCpuVendor == CPUMCPUVENDOR_INTEL)
    1675         pVCpu->iem.s.enmEffOpSize = IEMMODE_64BIT;
    1676     else
    1677         pVCpu->iem.s.enmEffOpSize = IEMMODE_16BIT;
    1678 }
    1679 
    1680 #endif /* !IEM_WITH_OPAQUE_DECODER_STATE */
    1681 
    1682399
    1683400
     
    45623279
    45633280
    4564 /** @name   Memory access.
    4565  *
    4566  * @{
    4567  */
    4568 
    4569 
    4570 /**
    4571  * Checks whether alignment checks are enabled or not.
    4572  *
    4573  * @returns true if enabled, false if not.
    4574  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    4575  */
    4576 DECLINLINE(bool) iemMemAreAlignmentChecksEnabled(PVMCPUCC pVCpu) RT_NOEXCEPT
    4577 {
    4578 #if 0
    4579     AssertCompile(X86_CR0_AM == X86_EFL_AC);
    4580     return IEM_GET_CPL(pVCpu) == 3
    4581         && (((uint32_t)pVCpu->cpum.GstCtx.cr0 & pVCpu->cpum.GstCtx.eflags.u) & X86_CR0_AM);
    4582 #else
    4583     return RT_BOOL(pVCpu->iem.s.fExec & IEM_F_X86_AC);
    4584 #endif
    4585 }
    4586 
    4587 /**
    4588  * Checks if the given segment can be written to, raise the appropriate
    4589  * exception if not.
    4590  *
    4591  * @returns VBox strict status code.
    4592  *
    4593  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    4594  * @param   pHid                Pointer to the hidden register.
    4595  * @param   iSegReg             The register number.
    4596  * @param   pu64BaseAddr        Where to return the base address to use for the
    4597  *                              segment. (In 64-bit code it may differ from the
    4598  *                              base in the hidden segment.)
    4599  */
    4600 DECLINLINE(VBOXSTRICTRC) iemMemSegCheckWriteAccessEx(PVMCPUCC pVCpu, PCCPUMSELREGHID pHid,
    4601                                                      uint8_t iSegReg, uint64_t *pu64BaseAddr) RT_NOEXCEPT
    4602 {
    4603     IEM_CTX_ASSERT(pVCpu, CPUMCTX_EXTRN_SREG_FROM_IDX(iSegReg));
    4604 
    4605     if (IEM_IS_64BIT_CODE(pVCpu))
    4606         *pu64BaseAddr = iSegReg < X86_SREG_FS ? 0 : pHid->u64Base;
    4607     else
    4608     {
    4609         if (!pHid->Attr.n.u1Present)
    4610         {
    4611             uint16_t    uSel = iemSRegFetchU16(pVCpu, iSegReg);
    4612             AssertRelease(uSel == 0);
    4613             LogEx(LOG_GROUP_IEM,("iemMemSegCheckWriteAccessEx: %#x (index %u) - bad selector -> #GP\n", uSel, iSegReg));
    4614             return iemRaiseGeneralProtectionFault0(pVCpu);
    4615         }
    4616 
    4617         if (   (   (pHid->Attr.n.u4Type & X86_SEL_TYPE_CODE)
    4618                 || !(pHid->Attr.n.u4Type & X86_SEL_TYPE_WRITE) )
    4619             && !IEM_IS_64BIT_CODE(pVCpu) )
    4620             return iemRaiseSelectorInvalidAccess(pVCpu, iSegReg, IEM_ACCESS_DATA_W);
    4621         *pu64BaseAddr = pHid->u64Base;
    4622     }
    4623     return VINF_SUCCESS;
    4624 }
    4625 
    4626 
    4627 /**
    4628  * Checks if the given segment can be read from, raise the appropriate
    4629  * exception if not.
    4630  *
    4631  * @returns VBox strict status code.
    4632  *
    4633  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    4634  * @param   pHid                Pointer to the hidden register.
    4635  * @param   iSegReg             The register number.
    4636  * @param   pu64BaseAddr        Where to return the base address to use for the
    4637  *                              segment. (In 64-bit code it may differ from the
    4638  *                              base in the hidden segment.)
    4639  */
    4640 DECLINLINE(VBOXSTRICTRC) iemMemSegCheckReadAccessEx(PVMCPUCC pVCpu, PCCPUMSELREGHID pHid,
    4641                                                     uint8_t iSegReg, uint64_t *pu64BaseAddr) RT_NOEXCEPT
    4642 {
    4643     IEM_CTX_ASSERT(pVCpu, CPUMCTX_EXTRN_SREG_FROM_IDX(iSegReg));
    4644 
    4645     if (IEM_IS_64BIT_CODE(pVCpu))
    4646         *pu64BaseAddr = iSegReg < X86_SREG_FS ? 0 : pHid->u64Base;
    4647     else
    4648     {
    4649         if (!pHid->Attr.n.u1Present)
    4650         {
    4651             uint16_t    uSel = iemSRegFetchU16(pVCpu, iSegReg);
    4652             AssertRelease(uSel == 0);
    4653             LogEx(LOG_GROUP_IEM,("iemMemSegCheckReadAccessEx: %#x (index %u) - bad selector -> #GP\n", uSel, iSegReg));
    4654             return iemRaiseGeneralProtectionFault0(pVCpu);
    4655         }
    4656 
    4657         if ((pHid->Attr.n.u4Type & (X86_SEL_TYPE_CODE | X86_SEL_TYPE_READ)) == X86_SEL_TYPE_CODE)
    4658             return iemRaiseSelectorInvalidAccess(pVCpu, iSegReg, IEM_ACCESS_DATA_R);
    4659         *pu64BaseAddr = pHid->u64Base;
    4660     }
    4661     return VINF_SUCCESS;
    4662 }
    4663 
    4664 
    4665 /**
    4666  * Maps a physical page.
    4667  *
    4668  * @returns VBox status code (see PGMR3PhysTlbGCPhys2Ptr).
    4669  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    4670  * @param   GCPhysMem           The physical address.
    4671  * @param   fAccess             The intended access.
    4672  * @param   ppvMem              Where to return the mapping address.
    4673  * @param   pLock               The PGM lock.
    4674  */
    4675 DECLINLINE(int) iemMemPageMap(PVMCPUCC pVCpu, RTGCPHYS GCPhysMem, uint32_t fAccess,
    4676                               void **ppvMem, PPGMPAGEMAPLOCK pLock) RT_NOEXCEPT
    4677 {
    4678 #ifdef IEM_LOG_MEMORY_WRITES
    4679     if (fAccess & IEM_ACCESS_TYPE_WRITE)
    4680         return VERR_PGM_PHYS_TLB_CATCH_ALL;
    4681 #endif
    4682 
    4683     /** @todo This API may require some improving later.  A private deal with PGM
    4684      *        regarding locking and unlocking needs to be struct.  A couple of TLBs
    4685      *        living in PGM, but with publicly accessible inlined access methods
    4686      *        could perhaps be an even better solution. */
    4687     int rc = PGMPhysIemGCPhys2Ptr(pVCpu->CTX_SUFF(pVM), pVCpu,
    4688                                   GCPhysMem,
    4689                                   RT_BOOL(fAccess & IEM_ACCESS_TYPE_WRITE),
    4690                                   RT_BOOL(pVCpu->iem.s.fExec & IEM_F_BYPASS_HANDLERS),
    4691                                   ppvMem,
    4692                                   pLock);
    4693     /*Log(("PGMPhysIemGCPhys2Ptr %Rrc pLock=%.*Rhxs\n", rc, sizeof(*pLock), pLock));*/
    4694     AssertMsg(rc == VINF_SUCCESS || RT_FAILURE_NP(rc), ("%Rrc\n", rc));
    4695 
    4696     return rc;
    4697 }
    4698 
    4699 
    4700 /**
    4701  * Unmap a page previously mapped by iemMemPageMap.
    4702  *
    4703  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    4704  * @param   GCPhysMem           The physical address.
    4705  * @param   fAccess             The intended access.
    4706  * @param   pvMem               What iemMemPageMap returned.
    4707  * @param   pLock               The PGM lock.
    4708  */
    4709 DECLINLINE(void) iemMemPageUnmap(PVMCPUCC pVCpu, RTGCPHYS GCPhysMem, uint32_t fAccess,
    4710                                  const void *pvMem, PPGMPAGEMAPLOCK pLock) RT_NOEXCEPT
    4711 {
    4712     NOREF(pVCpu);
    4713     NOREF(GCPhysMem);
    4714     NOREF(fAccess);
    4715     NOREF(pvMem);
    4716     PGMPhysReleasePageMappingLock(pVCpu->CTX_SUFF(pVM), pLock);
    4717 }
    4718 
    4719 #ifdef IEM_WITH_SETJMP
    4720 
    4721 /** @todo slim this down   */
    4722 DECL_INLINE_THROW(RTGCPTR) iemMemApplySegmentToReadJmp(PVMCPUCC pVCpu, uint8_t iSegReg,
    4723                                                        size_t cbMem, RTGCPTR GCPtrMem) IEM_NOEXCEPT_MAY_LONGJMP
    4724 {
    4725     Assert(cbMem >= 1);
    4726     Assert(iSegReg < X86_SREG_COUNT);
    4727 
    4728     /*
    4729      * 64-bit mode is simpler.
    4730      */
    4731     if (IEM_IS_64BIT_CODE(pVCpu))
    4732     {
    4733         if (iSegReg >= X86_SREG_FS && iSegReg != UINT8_MAX)
    4734         {
    4735             IEM_CTX_IMPORT_JMP(pVCpu, CPUMCTX_EXTRN_SREG_FROM_IDX(iSegReg));
    4736             PCPUMSELREGHID const pSel = iemSRegGetHid(pVCpu, iSegReg);
    4737             GCPtrMem += pSel->u64Base;
    4738         }
    4739 
    4740         if (RT_LIKELY(X86_IS_CANONICAL(GCPtrMem) && X86_IS_CANONICAL(GCPtrMem + cbMem - 1)))
    4741             return GCPtrMem;
    4742         iemRaiseGeneralProtectionFault0Jmp(pVCpu);
    4743     }
    4744     /*
    4745      * 16-bit and 32-bit segmentation.
    4746      */
    4747     else if (iSegReg != UINT8_MAX)
    4748     {
    4749         /** @todo Does this apply to segments with 4G-1 limit? */
    4750         uint32_t const GCPtrLast32 = (uint32_t)GCPtrMem + (uint32_t)cbMem - 1;
    4751         if (RT_LIKELY(GCPtrLast32 >= (uint32_t)GCPtrMem))
    4752         {
    4753             IEM_CTX_IMPORT_JMP(pVCpu, CPUMCTX_EXTRN_SREG_FROM_IDX(iSegReg));
    4754             PCPUMSELREGHID const pSel = iemSRegGetHid(pVCpu, iSegReg);
    4755             switch (pSel->Attr.u & (  X86DESCATTR_P     | X86DESCATTR_UNUSABLE
    4756                                     | X86_SEL_TYPE_READ | X86_SEL_TYPE_WRITE /* same as read */
    4757                                     | X86_SEL_TYPE_DOWN | X86_SEL_TYPE_CONF  /* same as down */
    4758                                     | X86_SEL_TYPE_CODE))
    4759             {
    4760                 case X86DESCATTR_P:                                         /* readonly data, expand up */
    4761                 case X86DESCATTR_P | X86_SEL_TYPE_WRITE:                    /* writable data, expand up */
    4762                 case X86DESCATTR_P | X86_SEL_TYPE_CODE | X86_SEL_TYPE_READ: /* code, read-only */
    4763                 case X86DESCATTR_P | X86_SEL_TYPE_CODE | X86_SEL_TYPE_READ | X86_SEL_TYPE_CONF: /* conforming code, read-only */
    4764                     /* expand up */
    4765                     if (RT_LIKELY(GCPtrLast32 <= pSel->u32Limit))
    4766                         return (uint32_t)GCPtrMem + (uint32_t)pSel->u64Base;
    4767                     Log10(("iemMemApplySegmentToReadJmp: out of bounds %#x..%#x vs %#x\n",
    4768                            (uint32_t)GCPtrMem, GCPtrLast32, pSel->u32Limit));
    4769                     break;
    4770 
    4771                 case X86DESCATTR_P | X86_SEL_TYPE_DOWN:                         /* readonly data, expand down */
    4772                 case X86DESCATTR_P | X86_SEL_TYPE_DOWN | X86_SEL_TYPE_WRITE:    /* writable data, expand down */
    4773                     /* expand down */
    4774                     if (RT_LIKELY(   (uint32_t)GCPtrMem > pSel->u32Limit
    4775                                   && (   pSel->Attr.n.u1DefBig
    4776                                       || GCPtrLast32 <= UINT32_C(0xffff)) ))
    4777                         return (uint32_t)GCPtrMem + (uint32_t)pSel->u64Base;
    4778                     Log10(("iemMemApplySegmentToReadJmp: expand down out of bounds %#x..%#x vs %#x..%#x\n",
    4779                            (uint32_t)GCPtrMem, GCPtrLast32, pSel->u32Limit, pSel->Attr.n.u1DefBig ? UINT32_MAX : UINT16_MAX));
    4780                     break;
    4781 
    4782                 default:
    4783                     Log10(("iemMemApplySegmentToReadJmp: bad selector %#x\n", pSel->Attr.u));
    4784                     iemRaiseSelectorInvalidAccessJmp(pVCpu, iSegReg, IEM_ACCESS_DATA_R);
    4785                     break;
    4786             }
    4787         }
    4788         Log10(("iemMemApplySegmentToReadJmp: out of bounds %#x..%#x\n",(uint32_t)GCPtrMem, GCPtrLast32));
    4789         iemRaiseSelectorBoundsJmp(pVCpu, iSegReg, IEM_ACCESS_DATA_R);
    4790     }
    4791     /*
    4792      * 32-bit flat address.
    4793      */
    4794     else
    4795         return GCPtrMem;
    4796 }
    4797 
    4798 
    4799 /** @todo slim this down   */
    4800 DECL_INLINE_THROW(RTGCPTR) iemMemApplySegmentToWriteJmp(PVMCPUCC pVCpu, uint8_t iSegReg, size_t cbMem,
    4801                                                         RTGCPTR GCPtrMem) IEM_NOEXCEPT_MAY_LONGJMP
    4802 {
    4803     Assert(cbMem >= 1);
    4804     Assert(iSegReg < X86_SREG_COUNT);
    4805 
    4806     /*
    4807      * 64-bit mode is simpler.
    4808      */
    4809     if (IEM_IS_64BIT_CODE(pVCpu))
    4810     {
    4811         if (iSegReg >= X86_SREG_FS)
    4812         {
    4813             IEM_CTX_IMPORT_JMP(pVCpu, CPUMCTX_EXTRN_SREG_FROM_IDX(iSegReg));
    4814             PCPUMSELREGHID pSel = iemSRegGetHid(pVCpu, iSegReg);
    4815             GCPtrMem += pSel->u64Base;
    4816         }
    4817 
    4818         if (RT_LIKELY(X86_IS_CANONICAL(GCPtrMem) && X86_IS_CANONICAL(GCPtrMem + cbMem - 1)))
    4819             return GCPtrMem;
    4820     }
    4821     /*
    4822      * 16-bit and 32-bit segmentation.
    4823      */
    4824     else
    4825     {
    4826         Assert(GCPtrMem <= UINT32_MAX);
    4827         IEM_CTX_IMPORT_JMP(pVCpu, CPUMCTX_EXTRN_SREG_FROM_IDX(iSegReg));
    4828         PCPUMSELREGHID pSel           = iemSRegGetHid(pVCpu, iSegReg);
    4829         uint32_t const fRelevantAttrs = pSel->Attr.u & (  X86DESCATTR_P     | X86DESCATTR_UNUSABLE
    4830                                                         | X86_SEL_TYPE_CODE | X86_SEL_TYPE_WRITE | X86_SEL_TYPE_DOWN);
    4831         if (   fRelevantAttrs == (X86DESCATTR_P | X86_SEL_TYPE_WRITE) /* data, expand up */
    4832                /** @todo explore exactly how the CS stuff works in real mode. See also
    4833                 *        http://www.rcollins.org/Productivity/DescriptorCache.html and
    4834                 *        http://www.rcollins.org/ddj/Aug98/Aug98.html for some insight. */
    4835             || (iSegReg == X86_SREG_CS && IEM_IS_REAL_OR_V86_MODE(pVCpu)) ) /* Ignored for CS. */ /** @todo testcase! */
    4836         {
    4837             /* expand up */
    4838             uint32_t const GCPtrLast32 = (uint32_t)GCPtrMem + (uint32_t)cbMem - 1;
    4839             if (RT_LIKELY(   GCPtrLast32 <= pSel->u32Limit
    4840                           && GCPtrLast32 >= (uint32_t)GCPtrMem))
    4841                 return (uint32_t)GCPtrMem + (uint32_t)pSel->u64Base;
    4842             iemRaiseSelectorBoundsJmp(pVCpu, iSegReg, IEM_ACCESS_DATA_W);
    4843         }
    4844         else if (fRelevantAttrs == (X86DESCATTR_P | X86_SEL_TYPE_WRITE | X86_SEL_TYPE_DOWN)) /* data, expand up */
    4845         {
    4846             /* expand down - the uppger boundary is defined by the B bit, not G. */
    4847             uint32_t GCPtrLast32 = (uint32_t)GCPtrMem + (uint32_t)cbMem - 1;
    4848             if (RT_LIKELY(   (uint32_t)GCPtrMem >= pSel->u32Limit
    4849                           && (pSel->Attr.n.u1DefBig || GCPtrLast32 <= UINT32_C(0xffff))
    4850                           && GCPtrLast32 >= (uint32_t)GCPtrMem))
    4851                 return (uint32_t)GCPtrMem + (uint32_t)pSel->u64Base;
    4852             iemRaiseSelectorBoundsJmp(pVCpu, iSegReg, IEM_ACCESS_DATA_W);
    4853         }
    4854         else
    4855             iemRaiseSelectorInvalidAccessJmp(pVCpu, iSegReg, IEM_ACCESS_DATA_W);
    4856     }
    4857     iemRaiseGeneralProtectionFault0Jmp(pVCpu);
    4858 }
    4859 
    4860 #endif /* IEM_WITH_SETJMP */
    4861 
    4862 /**
    4863  * Fakes a long mode stack selector for SS = 0.
    4864  *
    4865  * @param   pDescSs             Where to return the fake stack descriptor.
    4866  * @param   uDpl                The DPL we want.
    4867  */
    4868 DECLINLINE(void) iemMemFakeStackSelDesc(PIEMSELDESC pDescSs, uint32_t uDpl) RT_NOEXCEPT
    4869 {
    4870     pDescSs->Long.au64[0] = 0;
    4871     pDescSs->Long.au64[1] = 0;
    4872     pDescSs->Long.Gen.u4Type     = X86_SEL_TYPE_RW_ACC;
    4873     pDescSs->Long.Gen.u1DescType = 1; /* 1 = code / data, 0 = system. */
    4874     pDescSs->Long.Gen.u2Dpl      = uDpl;
    4875     pDescSs->Long.Gen.u1Present  = 1;
    4876     pDescSs->Long.Gen.u1Long     = 1;
    4877 }
    4878 
    4879 
    4880 /*
    4881  * Unmap helpers.
    4882  */
    4883 
    4884 #ifdef IEM_WITH_SETJMP
    4885 
    4886 DECL_INLINE_THROW(void) iemMemCommitAndUnmapRwJmp(PVMCPUCC pVCpu, uint8_t bMapInfo) IEM_NOEXCEPT_MAY_LONGJMP
    4887 {
    4888 # if defined(IEM_WITH_DATA_TLB) && defined(IN_RING3)
    4889     if (RT_LIKELY(bMapInfo == 0))
    4890         return;
    4891 # endif
    4892     iemMemCommitAndUnmapRwSafeJmp(pVCpu, bMapInfo);
    4893 }
    4894 
    4895 
    4896 DECL_INLINE_THROW(void) iemMemCommitAndUnmapAtJmp(PVMCPUCC pVCpu, uint8_t bMapInfo) IEM_NOEXCEPT_MAY_LONGJMP
    4897 {
    4898 # if defined(IEM_WITH_DATA_TLB) && defined(IN_RING3)
    4899     if (RT_LIKELY(bMapInfo == 0))
    4900         return;
    4901 # endif
    4902     iemMemCommitAndUnmapAtSafeJmp(pVCpu, bMapInfo);
    4903 }
    4904 
    4905 
    4906 DECL_INLINE_THROW(void) iemMemCommitAndUnmapWoJmp(PVMCPUCC pVCpu, uint8_t bMapInfo) IEM_NOEXCEPT_MAY_LONGJMP
    4907 {
    4908 # if defined(IEM_WITH_DATA_TLB) && defined(IN_RING3)
    4909     if (RT_LIKELY(bMapInfo == 0))
    4910         return;
    4911 # endif
    4912     iemMemCommitAndUnmapWoSafeJmp(pVCpu, bMapInfo);
    4913 }
    4914 
    4915 
    4916 DECL_INLINE_THROW(void) iemMemCommitAndUnmapRoJmp(PVMCPUCC pVCpu, uint8_t bMapInfo) IEM_NOEXCEPT_MAY_LONGJMP
    4917 {
    4918 # if defined(IEM_WITH_DATA_TLB) && defined(IN_RING3)
    4919     if (RT_LIKELY(bMapInfo == 0))
    4920         return;
    4921 # endif
    4922     iemMemCommitAndUnmapRoSafeJmp(pVCpu, bMapInfo);
    4923 }
    4924 
    4925 DECLINLINE(void) iemMemRollbackAndUnmapWo(PVMCPUCC pVCpu, uint8_t bMapInfo) RT_NOEXCEPT
    4926 {
    4927 # if defined(IEM_WITH_DATA_TLB) && defined(IN_RING3)
    4928     if (RT_LIKELY(bMapInfo == 0))
    4929         return;
    4930 # endif
    4931     iemMemRollbackAndUnmapWoSafe(pVCpu, bMapInfo);
    4932 }
    4933 
    4934 #endif /* IEM_WITH_SETJMP */
    4935 
    4936 
    4937 /*
    4938  * Instantiate R/W inline templates.
    4939  */
    4940 
    4941 /** @def TMPL_MEM_CHECK_UNALIGNED_WITHIN_PAGE_OK
    4942  * Used to check if an unaligned access is if within the page and won't
    4943  * trigger an \#AC.
    4944  *
    4945  * This can also be used to deal with misaligned accesses on platforms that are
    4946  * senstive to such if desires.
    4947  */
    4948 #if 1
    4949 # define TMPL_MEM_CHECK_UNALIGNED_WITHIN_PAGE_OK(a_pVCpu, a_GCPtrEff, a_TmplMemType) \
    4950     (   ((a_GCPtrEff) & GUEST_PAGE_OFFSET_MASK) <= GUEST_PAGE_SIZE - sizeof(a_TmplMemType) \
    4951      && !((a_pVCpu)->iem.s.fExec & IEM_F_X86_AC) )
    4952 #else
    4953 # define TMPL_MEM_CHECK_UNALIGNED_WITHIN_PAGE_OK(a_pVCpu, a_GCPtrEff, a_TmplMemType) 0
    4954 #endif
    4955 
    4956 #define TMPL_MEM_WITH_ATOMIC_MAPPING
    4957 
    4958 #define TMPL_MEM_TYPE       uint8_t
    4959 #define TMPL_MEM_TYPE_ALIGN 0
    4960 #define TMPL_MEM_TYPE_SIZE  1
    4961 #define TMPL_MEM_FN_SUFF    U8
    4962 #define TMPL_MEM_FMT_TYPE   "%#04x"
    4963 #define TMPL_MEM_FMT_DESC   "byte"
    4964 #include "../VMMAll/IEMAllMemRWTmplInline.cpp.h"
    4965 
    4966 #define TMPL_MEM_WITH_STACK
    4967 
    4968 #define TMPL_MEM_TYPE       uint16_t
    4969 #define TMPL_MEM_TYPE_ALIGN 1
    4970 #define TMPL_MEM_TYPE_SIZE  2
    4971 #define TMPL_MEM_FN_SUFF    U16
    4972 #define TMPL_MEM_FMT_TYPE   "%#06x"
    4973 #define TMPL_MEM_FMT_DESC   "word"
    4974 #include "../VMMAll/IEMAllMemRWTmplInline.cpp.h"
    4975 
    4976 #define TMPL_WITH_PUSH_SREG
    4977 #define TMPL_MEM_TYPE       uint32_t
    4978 #define TMPL_MEM_TYPE_ALIGN 3
    4979 #define TMPL_MEM_TYPE_SIZE  4
    4980 #define TMPL_MEM_FN_SUFF    U32
    4981 #define TMPL_MEM_FMT_TYPE   "%#010x"
    4982 #define TMPL_MEM_FMT_DESC   "dword"
    4983 #include "../VMMAll/IEMAllMemRWTmplInline.cpp.h"
    4984 #undef  TMPL_WITH_PUSH_SREG
    4985 
    4986 #define TMPL_MEM_TYPE       uint64_t
    4987 #define TMPL_MEM_TYPE_ALIGN 7
    4988 #define TMPL_MEM_TYPE_SIZE  8
    4989 #define TMPL_MEM_FN_SUFF    U64
    4990 #define TMPL_MEM_FMT_TYPE   "%#018RX64"
    4991 #define TMPL_MEM_FMT_DESC   "qword"
    4992 #include "../VMMAll/IEMAllMemRWTmplInline.cpp.h"
    4993 
    4994 #undef TMPL_MEM_WITH_STACK
    4995 #undef TMPL_MEM_WITH_ATOMIC_MAPPING
    4996 
    4997 #define TMPL_MEM_NO_MAPPING /* currently sticky */
    4998 
    4999 #define TMPL_MEM_NO_STORE
    5000 #define TMPL_MEM_TYPE       uint32_t
    5001 #define TMPL_MEM_TYPE_ALIGN 0
    5002 #define TMPL_MEM_TYPE_SIZE  4
    5003 #define TMPL_MEM_FN_SUFF    U32NoAc
    5004 #define TMPL_MEM_FMT_TYPE   "%#010x"
    5005 #define TMPL_MEM_FMT_DESC   "dword"
    5006 #include "../VMMAll/IEMAllMemRWTmplInline.cpp.h"
    5007 
    5008 #define TMPL_MEM_NO_STORE
    5009 #define TMPL_MEM_TYPE       uint64_t
    5010 #define TMPL_MEM_TYPE_ALIGN 0
    5011 #define TMPL_MEM_TYPE_SIZE  8
    5012 #define TMPL_MEM_FN_SUFF    U64NoAc
    5013 #define TMPL_MEM_FMT_TYPE   "%#018RX64"
    5014 #define TMPL_MEM_FMT_DESC   "qword"
    5015 #include "../VMMAll/IEMAllMemRWTmplInline.cpp.h"
    5016 
    5017 #define TMPL_MEM_NO_STORE
    5018 #define TMPL_MEM_TYPE       uint64_t
    5019 #define TMPL_MEM_TYPE_ALIGN 15
    5020 #define TMPL_MEM_TYPE_SIZE  8
    5021 #define TMPL_MEM_FN_SUFF    U64AlignedU128
    5022 #define TMPL_MEM_FMT_TYPE   "%#018RX64"
    5023 #define TMPL_MEM_FMT_DESC   "qword"
    5024 #include "../VMMAll/IEMAllMemRWTmplInline.cpp.h"
    5025 
    5026 #undef TMPL_MEM_NO_MAPPING
    5027 
    5028 #define TMPL_MEM_TYPE       RTFLOAT80U
    5029 #define TMPL_MEM_TYPE_ALIGN 7
    5030 #define TMPL_MEM_TYPE_SIZE  10
    5031 #define TMPL_MEM_FN_SUFF    R80
    5032 #define TMPL_MEM_FMT_TYPE   "%.10Rhxs"
    5033 #define TMPL_MEM_FMT_DESC   "tword"
    5034 #include "../VMMAll/IEMAllMemRWTmplInline.cpp.h"
    5035 
    5036 #define TMPL_MEM_TYPE       RTPBCD80U
    5037 #define TMPL_MEM_TYPE_ALIGN 7           /** @todo RTPBCD80U alignment testcase */
    5038 #define TMPL_MEM_TYPE_SIZE  10
    5039 #define TMPL_MEM_FN_SUFF    D80
    5040 #define TMPL_MEM_FMT_TYPE   "%.10Rhxs"
    5041 #define TMPL_MEM_FMT_DESC   "tword"
    5042 #include "../VMMAll/IEMAllMemRWTmplInline.cpp.h"
    5043 
    5044 #define TMPL_MEM_WITH_ATOMIC_MAPPING
    5045 #define TMPL_MEM_TYPE       RTUINT128U
    5046 #define TMPL_MEM_TYPE_ALIGN 15
    5047 #define TMPL_MEM_TYPE_SIZE  16
    5048 #define TMPL_MEM_FN_SUFF    U128
    5049 #define TMPL_MEM_FMT_TYPE   "%.16Rhxs"
    5050 #define TMPL_MEM_FMT_DESC   "dqword"
    5051 #include "../VMMAll/IEMAllMemRWTmplInline.cpp.h"
    5052 #undef  TMPL_MEM_WITH_ATOMIC_MAPPING
    5053 
    5054 #define TMPL_MEM_NO_MAPPING
    5055 #define TMPL_MEM_TYPE       RTUINT128U
    5056 #define TMPL_MEM_TYPE_ALIGN 0
    5057 #define TMPL_MEM_TYPE_SIZE  16
    5058 #define TMPL_MEM_FN_SUFF    U128NoAc
    5059 #define TMPL_MEM_FMT_TYPE   "%.16Rhxs"
    5060 #define TMPL_MEM_FMT_DESC   "dqword"
    5061 #include "../VMMAll/IEMAllMemRWTmplInline.cpp.h"
    5062 #undef TMPL_MEM_NO_MAPPING
    5063 
    5064 
    5065 /* Every template relying on unaligned accesses inside a page not being okay should go below. */
    5066 #undef TMPL_MEM_CHECK_UNALIGNED_WITHIN_PAGE_OK
    5067 #define TMPL_MEM_CHECK_UNALIGNED_WITHIN_PAGE_OK(a_pVCpu, a_GCPtrEff, a_TmplMemType) 0
    5068 
    5069 #define TMPL_MEM_NO_MAPPING
    5070 #define TMPL_MEM_TYPE       RTUINT128U
    5071 #define TMPL_MEM_TYPE_ALIGN 15
    5072 #define TMPL_MEM_TYPE_SIZE  16
    5073 #define TMPL_MEM_FN_SUFF    U128AlignedSse
    5074 #define TMPL_MEM_FMT_TYPE   "%.16Rhxs"
    5075 #define TMPL_MEM_FMT_DESC   "dqword"
    5076 #include "../VMMAll/IEMAllMemRWTmplInline.cpp.h"
    5077 #undef  TMPL_MEM_NO_MAPPING
    5078 
    5079 #define TMPL_MEM_NO_MAPPING
    5080 #define TMPL_MEM_TYPE       RTUINT256U
    5081 #define TMPL_MEM_TYPE_ALIGN 0
    5082 #define TMPL_MEM_TYPE_SIZE  32
    5083 #define TMPL_MEM_FN_SUFF    U256NoAc
    5084 #define TMPL_MEM_FMT_TYPE   "%.32Rhxs"
    5085 #define TMPL_MEM_FMT_DESC   "qqword"
    5086 #include "../VMMAll/IEMAllMemRWTmplInline.cpp.h"
    5087 #undef TMPL_MEM_NO_MAPPING
    5088 
    5089 #define TMPL_MEM_NO_MAPPING
    5090 #define TMPL_MEM_TYPE       RTUINT256U
    5091 #define TMPL_MEM_TYPE_ALIGN 31
    5092 #define TMPL_MEM_TYPE_SIZE  32
    5093 #define TMPL_MEM_FN_SUFF    U256AlignedAvx
    5094 #define TMPL_MEM_FMT_TYPE   "%.32Rhxs"
    5095 #define TMPL_MEM_FMT_DESC   "qqword"
    5096 #include "../VMMAll/IEMAllMemRWTmplInline.cpp.h"
    5097 #undef TMPL_MEM_NO_MAPPING
    5098 
    5099 #undef TMPL_MEM_CHECK_UNALIGNED_WITHIN_PAGE_OK
    5100 
    5101 /** @} */
    5102 
    5103 
    51043281#ifdef VBOX_WITH_NESTED_HWVIRT_VMX
    51053282
     
    51593336#endif /* VBOX_WITH_NESTED_HWVIRT_VMX */
    51603337
    5161 #if defined(IEM_WITH_TLB_TRACE) && defined(IN_RING3)
    5162 /**
    5163  * Adds an entry to the TLB trace buffer.
    5164  *
    5165  * @note Don't use directly, only via the IEMTLBTRACE_XXX macros.
    5166  */
    5167 DECLINLINE(void) iemTlbTrace(PVMCPU pVCpu, IEMTLBTRACETYPE enmType, uint64_t u64Param, uint64_t u64Param2 = 0,
    5168                              uint8_t bParam = 0, uint32_t u32Param = 0/*, uint16_t u16Param = 0 */)
    5169 {
    5170     uint32_t const          fMask  = RT_BIT_32(pVCpu->iem.s.cTlbTraceEntriesShift) - 1;
    5171     PIEMTLBTRACEENTRY const pEntry = &pVCpu->iem.s.paTlbTraceEntries[pVCpu->iem.s.idxTlbTraceEntry++ & fMask];
    5172     pEntry->u64Param  = u64Param;
    5173     pEntry->u64Param2 = u64Param2;
    5174     pEntry->u16Param  = 0; //u16Param;
    5175     pEntry->u32Param  = u32Param;
    5176     pEntry->bParam    = bParam;
    5177     pEntry->enmType   = enmType;
    5178     pEntry->rip       = pVCpu->cpum.GstCtx.rip + pVCpu->cpum.GstCtx.cs.u64Base;
    5179 }
    5180 #endif
    5181 
    5182 #endif /* !VMM_INCLUDED_SRC_include_IEMInline_h */
     3338#endif /* !VMM_INCLUDED_SRC_VMMAll_target_x86_IEMInline_x86_h */
  • trunk/src/VBox/VMM/VMMAll/target-x86/IEMInlineDecode-x86.h

    r108246 r108260  
    11/* $Id$ */
    22/** @file
    3  * IEM - Interpreted Execution Manager - Inlined Functions.
     3 * IEM - Interpreted Execution Manager - Inlined Decoding related Functions, x86 target.
    44 */
    55
     
    2626 */
    2727
    28 #ifndef VMM_INCLUDED_SRC_include_IEMInline_h
    29 #define VMM_INCLUDED_SRC_include_IEMInline_h
     28#ifndef VMM_INCLUDED_SRC_VMMAll_target_x86_IEMInlineDecode_x86_h
     29#define VMM_INCLUDED_SRC_VMMAll_target_x86_IEMInlineDecode_x86_h
    3030#ifndef RT_WITHOUT_PRAGMA_ONCE
    3131# pragma once
     
    3535
    3636
    37 /**
    38  * Makes status code addjustments (pass up from I/O and access handler)
    39  * as well as maintaining statistics.
    40  *
    41  * @returns Strict VBox status code to pass up.
    42  * @param   pVCpu       The cross context virtual CPU structure of the calling thread.
    43  * @param   rcStrict    The status from executing an instruction.
    44  */
    45 DECL_FORCE_INLINE(VBOXSTRICTRC) iemExecStatusCodeFiddling(PVMCPUCC pVCpu, VBOXSTRICTRC rcStrict) RT_NOEXCEPT
    46 {
    47     if (rcStrict != VINF_SUCCESS)
    48     {
    49         /* Deal with the cases that should be treated as VINF_SUCCESS first. */
    50         if (   rcStrict == VINF_IEM_YIELD_PENDING_FF
    51 #ifdef VBOX_WITH_NESTED_HWVIRT_VMX /** @todo r=bird: Why do we need TWO status codes here? */
    52             || rcStrict == VINF_VMX_VMEXIT
    53 #endif
    54 #ifdef VBOX_WITH_NESTED_HWVIRT_SVM
    55             || rcStrict == VINF_SVM_VMEXIT
    56 #endif
    57             )
    58         {
    59             rcStrict = pVCpu->iem.s.rcPassUp;
    60             if (RT_LIKELY(rcStrict == VINF_SUCCESS))
    61             { /* likely */ }
    62             else
    63                 pVCpu->iem.s.cRetPassUpStatus++;
    64         }
    65         else if (RT_SUCCESS(rcStrict))
    66         {
    67             AssertMsg(   (rcStrict >= VINF_EM_FIRST && rcStrict <= VINF_EM_LAST)
    68                       || rcStrict == VINF_IOM_R3_IOPORT_READ
    69                       || rcStrict == VINF_IOM_R3_IOPORT_WRITE
    70                       || rcStrict == VINF_IOM_R3_IOPORT_COMMIT_WRITE
    71                       || rcStrict == VINF_IOM_R3_MMIO_READ
    72                       || rcStrict == VINF_IOM_R3_MMIO_READ_WRITE
    73                       || rcStrict == VINF_IOM_R3_MMIO_WRITE
    74                       || rcStrict == VINF_IOM_R3_MMIO_COMMIT_WRITE
    75                       || rcStrict == VINF_CPUM_R3_MSR_READ
    76                       || rcStrict == VINF_CPUM_R3_MSR_WRITE
    77                       || rcStrict == VINF_EM_RAW_EMULATE_INSTR
    78                       || rcStrict == VINF_EM_RAW_TO_R3
    79                       || rcStrict == VINF_EM_TRIPLE_FAULT
    80                       || rcStrict == VINF_EM_EMULATE_SPLIT_LOCK
    81                       || rcStrict == VINF_GIM_R3_HYPERCALL
    82                       /* raw-mode / virt handlers only: */
    83                       || rcStrict == VINF_EM_RAW_EMULATE_INSTR_GDT_FAULT
    84                       || rcStrict == VINF_EM_RAW_EMULATE_INSTR_TSS_FAULT
    85                       || rcStrict == VINF_EM_RAW_EMULATE_INSTR_LDT_FAULT
    86                       || rcStrict == VINF_EM_RAW_EMULATE_INSTR_IDT_FAULT
    87                       || rcStrict == VINF_SELM_SYNC_GDT
    88                       || rcStrict == VINF_CSAM_PENDING_ACTION
    89                       || rcStrict == VINF_PATM_CHECK_PATCH_PAGE
    90                       /* nested hw.virt codes: */
    91                       || rcStrict == VINF_VMX_INTERCEPT_NOT_ACTIVE
    92                       || rcStrict == VINF_VMX_MODIFIES_BEHAVIOR
    93                       , ("rcStrict=%Rrc\n", VBOXSTRICTRC_VAL(rcStrict)));
    94 /** @todo adjust for VINF_EM_RAW_EMULATE_INSTR. */
    95             int32_t const rcPassUp = pVCpu->iem.s.rcPassUp;
    96             if (rcPassUp == VINF_SUCCESS)
    97                 pVCpu->iem.s.cRetInfStatuses++;
    98             else if (   rcPassUp < VINF_EM_FIRST
    99                      || rcPassUp > VINF_EM_LAST
    100                      || rcPassUp < VBOXSTRICTRC_VAL(rcStrict))
    101             {
    102                 LogEx(LOG_GROUP_IEM,("IEM: rcPassUp=%Rrc! rcStrict=%Rrc\n", rcPassUp, VBOXSTRICTRC_VAL(rcStrict)));
    103                 pVCpu->iem.s.cRetPassUpStatus++;
    104                 rcStrict = rcPassUp;
    105             }
    106             else
    107             {
    108                 LogEx(LOG_GROUP_IEM,("IEM: rcPassUp=%Rrc  rcStrict=%Rrc!\n", rcPassUp, VBOXSTRICTRC_VAL(rcStrict)));
    109                 pVCpu->iem.s.cRetInfStatuses++;
    110             }
    111         }
    112         else if (rcStrict == VERR_IEM_ASPECT_NOT_IMPLEMENTED)
    113             pVCpu->iem.s.cRetAspectNotImplemented++;
    114         else if (rcStrict == VERR_IEM_INSTR_NOT_IMPLEMENTED)
    115             pVCpu->iem.s.cRetInstrNotImplemented++;
    116         else
    117             pVCpu->iem.s.cRetErrStatuses++;
    118     }
    119     else
    120     {
    121         rcStrict = pVCpu->iem.s.rcPassUp;
    122         if (rcStrict != VINF_SUCCESS)
    123             pVCpu->iem.s.cRetPassUpStatus++;
    124     }
    125 
    126     /* Just clear it here as well. */
    127     pVCpu->iem.s.rcPassUp = VINF_SUCCESS;
    128 
    129     return rcStrict;
    130 }
    131 
    132 
    133 /**
    134  * Sets the pass up status.
    135  *
    136  * @returns VINF_SUCCESS.
    137  * @param   pVCpu               The cross context virtual CPU structure of the
    138  *                              calling thread.
    139  * @param   rcPassUp            The pass up status.  Must be informational.
    140  *                              VINF_SUCCESS is not allowed.
    141  */
    142 DECLINLINE(int) iemSetPassUpStatus(PVMCPUCC pVCpu, VBOXSTRICTRC rcPassUp) RT_NOEXCEPT
    143 {
    144     AssertRC(VBOXSTRICTRC_VAL(rcPassUp)); Assert(rcPassUp != VINF_SUCCESS);
    145 
    146     int32_t const rcOldPassUp = pVCpu->iem.s.rcPassUp;
    147     if (rcOldPassUp == VINF_SUCCESS)
    148         pVCpu->iem.s.rcPassUp = VBOXSTRICTRC_VAL(rcPassUp);
    149     /* If both are EM scheduling codes, use EM priority rules. */
    150     else if (   rcOldPassUp >= VINF_EM_FIRST && rcOldPassUp <= VINF_EM_LAST
    151              && rcPassUp    >= VINF_EM_FIRST && rcPassUp    <= VINF_EM_LAST)
    152     {
    153         if (rcPassUp < rcOldPassUp)
    154         {
    155             LogEx(LOG_GROUP_IEM,("IEM: rcPassUp=%Rrc! rcOldPassUp=%Rrc\n", VBOXSTRICTRC_VAL(rcPassUp), rcOldPassUp));
    156             pVCpu->iem.s.rcPassUp = VBOXSTRICTRC_VAL(rcPassUp);
    157         }
    158         else
    159             LogEx(LOG_GROUP_IEM,("IEM: rcPassUp=%Rrc  rcOldPassUp=%Rrc!\n", VBOXSTRICTRC_VAL(rcPassUp), rcOldPassUp));
    160     }
    161     /* Override EM scheduling with specific status code. */
    162     else if (rcOldPassUp >= VINF_EM_FIRST && rcOldPassUp <= VINF_EM_LAST)
    163     {
    164         LogEx(LOG_GROUP_IEM,("IEM: rcPassUp=%Rrc! rcOldPassUp=%Rrc\n", VBOXSTRICTRC_VAL(rcPassUp), rcOldPassUp));
    165         pVCpu->iem.s.rcPassUp = VBOXSTRICTRC_VAL(rcPassUp);
    166     }
    167     /* Don't override specific status code, first come first served. */
    168     else
    169         LogEx(LOG_GROUP_IEM,("IEM: rcPassUp=%Rrc  rcOldPassUp=%Rrc!\n", VBOXSTRICTRC_VAL(rcPassUp), rcOldPassUp));
    170     return VINF_SUCCESS;
    171 }
    172 
    173 
    174 /**
    175  * Calculates the IEM_F_X86_AC flags.
    176  *
    177  * @returns IEM_F_X86_AC or zero
    178  * @param   pVCpu               The cross context virtual CPU structure of the
    179  *                              calling thread.
    180  */
    181 DECL_FORCE_INLINE(uint32_t) iemCalcExecAcFlag(PVMCPUCC pVCpu) RT_NOEXCEPT
    182 {
    183     IEM_CTX_ASSERT(pVCpu, CPUMCTX_EXTRN_CR0 | CPUMCTX_EXTRN_RFLAGS);
    184     Assert(CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pVCpu, &pVCpu->cpum.GstCtx.ss));
    185 
    186     if (   !pVCpu->cpum.GstCtx.eflags.Bits.u1AC
    187         || (pVCpu->cpum.GstCtx.cr0 & (X86_CR0_AM | X86_CR0_PE)) != (X86_CR0_AM | X86_CR0_PE)
    188         || (   !pVCpu->cpum.GstCtx.eflags.Bits.u1VM
    189             && pVCpu->cpum.GstCtx.ss.Attr.n.u2Dpl != 3))
    190         return 0;
    191     return IEM_F_X86_AC;
    192 }
    193 
    194 
    195 /**
    196  * Calculates the IEM_F_MODE_X86_32BIT_FLAT flag.
    197  *
    198  * Checks if CS, SS, DS and SS are all wide open flat 32-bit segments. This will
    199  * reject expand down data segments and conforming code segments.
    200  *
    201  * ASSUMES that the CPU is in 32-bit mode.
    202  *
    203  * @note    Will return zero when if any of the segment register state is marked
    204  *          external, this must be factored into assertions checking fExec
    205  *          consistency.
    206  *
    207  * @returns IEM_F_MODE_X86_32BIT_FLAT or zero.
    208  * @param   pVCpu               The cross context virtual CPU structure of the
    209  *                              calling thread.
    210  * @sa      iemCalc32BitFlatIndicatorEsDs
    211  */
    212 DECL_FORCE_INLINE(uint32_t) iemCalc32BitFlatIndicator(PVMCPUCC pVCpu) RT_NOEXCEPT
    213 {
    214     AssertCompile(X86_SEL_TYPE_DOWN == X86_SEL_TYPE_CONF);
    215     return (  (    pVCpu->cpum.GstCtx.es.Attr.u
    216                  | pVCpu->cpum.GstCtx.cs.Attr.u
    217                  | pVCpu->cpum.GstCtx.ss.Attr.u
    218                  | pVCpu->cpum.GstCtx.ds.Attr.u)
    219               & (X86_SEL_TYPE_ACCESSED | X86DESCATTR_G | X86DESCATTR_D | X86DESCATTR_P | X86_SEL_TYPE_DOWN | X86DESCATTR_UNUSABLE))
    220            ==   (X86_SEL_TYPE_ACCESSED | X86DESCATTR_G | X86DESCATTR_D | X86DESCATTR_P)
    221         &&    (  (pVCpu->cpum.GstCtx.es.u32Limit + 1)
    222                | (pVCpu->cpum.GstCtx.cs.u32Limit + 1)
    223                | (pVCpu->cpum.GstCtx.ss.u32Limit + 1)
    224                | (pVCpu->cpum.GstCtx.ds.u32Limit + 1))
    225            == 0
    226         &&    (  pVCpu->cpum.GstCtx.es.u64Base
    227                | pVCpu->cpum.GstCtx.cs.u64Base
    228                | pVCpu->cpum.GstCtx.ss.u64Base
    229                | pVCpu->cpum.GstCtx.ds.u64Base)
    230            == 0
    231         && !(pVCpu->cpum.GstCtx.fExtrn & (CPUMCTX_EXTRN_ES | CPUMCTX_EXTRN_CS | CPUMCTX_EXTRN_SS | CPUMCTX_EXTRN_ES))
    232         ? IEM_F_MODE_X86_32BIT_FLAT : 0;
    233 }
    234 
    235 
    236 /**
    237  * Calculates the IEM_F_MODE_X86_32BIT_FLAT flag, ASSUMING the CS and SS are
    238  * flat already.
    239  *
    240  * This is used by sysenter.
    241  *
    242  * @note    Will return zero when if any of the segment register state is marked
    243  *          external, this must be factored into assertions checking fExec
    244  *          consistency.
    245  *
    246  * @returns IEM_F_MODE_X86_32BIT_FLAT or zero.
    247  * @param   pVCpu               The cross context virtual CPU structure of the
    248  *                              calling thread.
    249  * @sa      iemCalc32BitFlatIndicator
    250  */
    251 DECL_FORCE_INLINE(uint32_t) iemCalc32BitFlatIndicatorEsDs(PVMCPUCC pVCpu) RT_NOEXCEPT
    252 {
    253     AssertCompile(X86_SEL_TYPE_DOWN == X86_SEL_TYPE_CONF);
    254     return (  (    pVCpu->cpum.GstCtx.es.Attr.u
    255                  | pVCpu->cpum.GstCtx.ds.Attr.u)
    256               & (X86_SEL_TYPE_ACCESSED | X86DESCATTR_G | X86DESCATTR_D | X86DESCATTR_P | X86_SEL_TYPE_DOWN | X86DESCATTR_UNUSABLE))
    257            ==   (X86_SEL_TYPE_ACCESSED | X86DESCATTR_G | X86DESCATTR_D | X86DESCATTR_P)
    258         &&    (  (pVCpu->cpum.GstCtx.es.u32Limit + 1)
    259                | (pVCpu->cpum.GstCtx.ds.u32Limit + 1))
    260            == 0
    261         &&    (  pVCpu->cpum.GstCtx.es.u64Base
    262                | pVCpu->cpum.GstCtx.ds.u64Base)
    263            == 0
    264         && !(pVCpu->cpum.GstCtx.fExtrn & (CPUMCTX_EXTRN_ES | CPUMCTX_EXTRN_CS | CPUMCTX_EXTRN_SS | CPUMCTX_EXTRN_ES))
    265         ? IEM_F_MODE_X86_32BIT_FLAT : 0;
    266 }
    267 
    268 
    269 /**
    270  * Calculates the IEM_F_MODE_XXX, CPL and AC flags.
    271  *
    272  * @returns IEM_F_MODE_XXX, IEM_F_X86_CPL_MASK and IEM_F_X86_AC.
    273  * @param   pVCpu               The cross context virtual CPU structure of the
    274  *                              calling thread.
    275  */
    276 DECL_FORCE_INLINE(uint32_t) iemCalcExecModeAndCplFlags(PVMCPUCC pVCpu) RT_NOEXCEPT
    277 {
    278     /*
    279      * We're duplicates code from CPUMGetGuestCPL and CPUMIsGuestIn64BitCodeEx
    280      * here to try get this done as efficiently as possible.
    281      */
    282     IEM_CTX_ASSERT(pVCpu, CPUMCTX_EXTRN_CR0 | CPUMCTX_EXTRN_EFER | CPUMCTX_EXTRN_RFLAGS | CPUMCTX_EXTRN_SS | CPUMCTX_EXTRN_CS);
    283 
    284     if (pVCpu->cpum.GstCtx.cr0 & X86_CR0_PE)
    285     {
    286         if (!pVCpu->cpum.GstCtx.eflags.Bits.u1VM)
    287         {
    288             Assert(CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pVCpu, &pVCpu->cpum.GstCtx.ss));
    289             uint32_t fExec = ((uint32_t)pVCpu->cpum.GstCtx.ss.Attr.n.u2Dpl << IEM_F_X86_CPL_SHIFT);
    290             if (   !pVCpu->cpum.GstCtx.eflags.Bits.u1AC
    291                 || !(pVCpu->cpum.GstCtx.cr0 & X86_CR0_AM)
    292                 || fExec != (3U << IEM_F_X86_CPL_SHIFT))
    293             { /* likely */ }
    294             else
    295                 fExec |= IEM_F_X86_AC;
    296 
    297             if (pVCpu->cpum.GstCtx.cs.Attr.n.u1DefBig)
    298             {
    299                 Assert(!pVCpu->cpum.GstCtx.cs.Attr.n.u1Long || !(pVCpu->cpum.GstCtx.msrEFER & MSR_K6_EFER_LMA));
    300                 fExec |= IEM_F_MODE_X86_32BIT_PROT | iemCalc32BitFlatIndicator(pVCpu);
    301             }
    302             else if (   pVCpu->cpum.GstCtx.cs.Attr.n.u1Long
    303                      && (pVCpu->cpum.GstCtx.msrEFER & MSR_K6_EFER_LMA))
    304                 fExec |= IEM_F_MODE_X86_64BIT;
    305             else if (IEM_GET_TARGET_CPU(pVCpu) >= IEMTARGETCPU_386)
    306                 fExec |= IEM_F_MODE_X86_16BIT_PROT;
    307             else
    308                 fExec |= IEM_F_MODE_X86_16BIT_PROT_PRE_386;
    309             return fExec;
    310         }
    311         if (   !pVCpu->cpum.GstCtx.eflags.Bits.u1AC
    312             || !(pVCpu->cpum.GstCtx.cr0 & X86_CR0_AM))
    313             return IEM_F_MODE_X86_16BIT_PROT_V86 | (UINT32_C(3) << IEM_F_X86_CPL_SHIFT);
    314         return IEM_F_MODE_X86_16BIT_PROT_V86 | (UINT32_C(3) << IEM_F_X86_CPL_SHIFT) | IEM_F_X86_AC;
    315     }
    316 
    317     /* Real mode is zero; CPL set to 3 for VT-x real-mode emulation. */
    318     if (RT_LIKELY(!pVCpu->cpum.GstCtx.cs.Attr.n.u1DefBig))
    319     {
    320         if (IEM_GET_TARGET_CPU(pVCpu) >= IEMTARGETCPU_386)
    321             return IEM_F_MODE_X86_16BIT;
    322         return IEM_F_MODE_X86_16BIT_PRE_386;
    323     }
    324 
    325     /* 32-bit unreal mode. */
    326     return IEM_F_MODE_X86_32BIT | iemCalc32BitFlatIndicator(pVCpu);
    327 }
    328 
    329 
    330 /**
    331  * Calculates the AMD-V and VT-x related context flags.
    332  *
    333  * @returns 0 or a combination of IEM_F_X86_CTX_IN_GUEST, IEM_F_X86_CTX_SVM and
    334  *          IEM_F_X86_CTX_VMX.
    335  * @param   pVCpu               The cross context virtual CPU structure of the
    336  *                              calling thread.
    337  */
    338 DECL_FORCE_INLINE(uint32_t) iemCalcExecHwVirtFlags(PVMCPUCC pVCpu) RT_NOEXCEPT
    339 {
    340     /*
    341      * This duplicates code from CPUMIsGuestVmxEnabled, CPUMIsGuestSvmEnabled
    342      * and CPUMIsGuestInNestedHwvirtMode to some extent.
    343      */
    344     IEM_CTX_ASSERT(pVCpu, CPUMCTX_EXTRN_CR4 | CPUMCTX_EXTRN_EFER);
    345 
    346     AssertCompile(X86_CR4_VMXE != MSR_K6_EFER_SVME);
    347     uint64_t const fTmp = (pVCpu->cpum.GstCtx.cr4     & X86_CR4_VMXE)
    348                         | (pVCpu->cpum.GstCtx.msrEFER & MSR_K6_EFER_SVME);
    349     if (RT_LIKELY(!fTmp))
    350         return 0; /* likely */
    351 
    352     if (fTmp & X86_CR4_VMXE)
    353     {
    354         Assert(pVCpu->cpum.GstCtx.hwvirt.enmHwvirt == CPUMHWVIRT_VMX);
    355         if (pVCpu->cpum.GstCtx.hwvirt.vmx.fInVmxNonRootMode)
    356             return IEM_F_X86_CTX_VMX | IEM_F_X86_CTX_IN_GUEST;
    357         return IEM_F_X86_CTX_VMX;
    358     }
    359 
    360     Assert(pVCpu->cpum.GstCtx.hwvirt.enmHwvirt == CPUMHWVIRT_SVM);
    361     if (pVCpu->cpum.GstCtx.hwvirt.svm.Vmcb.ctrl.u64InterceptCtrl & SVM_CTRL_INTERCEPT_VMRUN)
    362         return IEM_F_X86_CTX_SVM | IEM_F_X86_CTX_IN_GUEST;
    363     return IEM_F_X86_CTX_SVM;
    364 }
    365 
    366 #ifdef VBOX_INCLUDED_vmm_dbgf_h /* VM::dbgf.ro.cEnabledHwBreakpoints is only accessible if VBox/vmm/dbgf.h is included. */
    367 
    368 /**
    369  * Calculates IEM_F_BRK_PENDING_XXX (IEM_F_PENDING_BRK_MASK) flags.
    370  *
    371  * @returns IEM_F_BRK_PENDING_XXX or zero.
    372  * @param   pVCpu               The cross context virtual CPU structure of the
    373  *                              calling thread.
    374  */
    375 DECL_FORCE_INLINE(uint32_t) iemCalcExecDbgFlags(PVMCPUCC pVCpu) RT_NOEXCEPT
    376 {
    377     IEM_CTX_ASSERT(pVCpu, CPUMCTX_EXTRN_DR7);
    378 
    379     if (RT_LIKELY(   !(pVCpu->cpum.GstCtx.dr[7] & X86_DR7_ENABLED_MASK)
    380                   && pVCpu->CTX_SUFF(pVM)->dbgf.ro.cEnabledHwBreakpoints == 0))
    381         return 0;
    382     return iemCalcExecDbgFlagsSlow(pVCpu);
    383 }
    384 
    385 /**
    386  * Calculates the the IEM_F_XXX flags.
    387  *
    388  * @returns IEM_F_XXX combination match the current CPU state.
    389  * @param   pVCpu               The cross context virtual CPU structure of the
    390  *                              calling thread.
    391  */
    392 DECL_FORCE_INLINE(uint32_t) iemCalcExecFlags(PVMCPUCC pVCpu) RT_NOEXCEPT
    393 {
    394     return iemCalcExecModeAndCplFlags(pVCpu)
    395          | iemCalcExecHwVirtFlags(pVCpu)
    396          /* SMM is not yet implemented */
    397          | iemCalcExecDbgFlags(pVCpu)
    398          ;
    399 }
    400 
    401 
    402 /**
    403  * Re-calculates the MODE and CPL parts of IEMCPU::fExec.
    404  *
    405  * @param   pVCpu               The cross context virtual CPU structure of the
    406  *                              calling thread.
    407  */
    408 DECL_FORCE_INLINE(void) iemRecalcExecModeAndCplAndAcFlags(PVMCPUCC pVCpu)
    409 {
    410     pVCpu->iem.s.fExec = (pVCpu->iem.s.fExec & ~(IEM_F_MODE_MASK | IEM_F_X86_CPL_MASK | IEM_F_X86_AC))
    411                        | iemCalcExecModeAndCplFlags(pVCpu);
    412 }
    413 
    414 
    415 /**
    416  * Re-calculates the IEM_F_PENDING_BRK_MASK part of IEMCPU::fExec.
    417  *
    418  * @param   pVCpu               The cross context virtual CPU structure of the
    419  *                              calling thread.
    420  */
    421 DECL_FORCE_INLINE(void) iemRecalcExecDbgFlags(PVMCPUCC pVCpu)
    422 {
    423     pVCpu->iem.s.fExec = (pVCpu->iem.s.fExec & ~IEM_F_PENDING_BRK_MASK)
    424                        | iemCalcExecDbgFlags(pVCpu);
    425 }
    426 
    427 #endif /* VBOX_INCLUDED_vmm_dbgf_h */
    428 
    429 
    43037#ifndef IEM_WITH_OPAQUE_DECODER_STATE
    431 
    432 # if defined(VBOX_INCLUDED_vmm_dbgf_h) || defined(DOXYGEN_RUNNING) /* dbgf.ro.cEnabledHwBreakpoints */
    433 
    434 /**
    435  * Initializes the execution state.
    436  *
    437  * @param   pVCpu               The cross context virtual CPU structure of the
    438  *                              calling thread.
    439  * @param   fExecOpts           Optional execution flags:
    440  *                                  - IEM_F_BYPASS_HANDLERS
    441  *                                  - IEM_F_X86_DISREGARD_LOCK
    442  *
    443  * @remarks Callers of this must call iemUninitExec() to undo potentially fatal
    444  *          side-effects in strict builds.
    445  */
    446 DECLINLINE(void) iemInitExec(PVMCPUCC pVCpu, uint32_t fExecOpts) RT_NOEXCEPT
    447 {
    448     IEM_CTX_ASSERT(pVCpu, IEM_CPUMCTX_EXTRN_EXEC_DECODED_NO_MEM_MASK);
    449     Assert(!VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_IEM));
    450     Assert(CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pVCpu, &pVCpu->cpum.GstCtx.cs));
    451     Assert(CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pVCpu, &pVCpu->cpum.GstCtx.ss));
    452     Assert(CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pVCpu, &pVCpu->cpum.GstCtx.es));
    453     Assert(CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pVCpu, &pVCpu->cpum.GstCtx.ds));
    454     Assert(CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pVCpu, &pVCpu->cpum.GstCtx.fs));
    455     Assert(CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pVCpu, &pVCpu->cpum.GstCtx.gs));
    456     Assert(CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pVCpu, &pVCpu->cpum.GstCtx.ldtr));
    457     Assert(CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pVCpu, &pVCpu->cpum.GstCtx.tr));
    458 
    459     pVCpu->iem.s.rcPassUp           = VINF_SUCCESS;
    460     pVCpu->iem.s.fExec              = iemCalcExecFlags(pVCpu) | fExecOpts;
    461     pVCpu->iem.s.cActiveMappings    = 0;
    462     pVCpu->iem.s.iNextMapping       = 0;
    463 
    464 #  ifdef VBOX_STRICT
    465     pVCpu->iem.s.enmDefAddrMode     = (IEMMODE)0xfe;
    466     pVCpu->iem.s.enmEffAddrMode     = (IEMMODE)0xfe;
    467     pVCpu->iem.s.enmDefOpSize       = (IEMMODE)0xfe;
    468     pVCpu->iem.s.enmEffOpSize       = (IEMMODE)0xfe;
    469     pVCpu->iem.s.fPrefixes          = 0xfeedbeef;
    470     pVCpu->iem.s.uRexReg            = 127;
    471     pVCpu->iem.s.uRexB              = 127;
    472     pVCpu->iem.s.offModRm           = 127;
    473     pVCpu->iem.s.uRexIndex          = 127;
    474     pVCpu->iem.s.iEffSeg            = 127;
    475     pVCpu->iem.s.idxPrefix          = 127;
    476     pVCpu->iem.s.uVex3rdReg         = 127;
    477     pVCpu->iem.s.uVexLength         = 127;
    478     pVCpu->iem.s.fEvexStuff         = 127;
    479     pVCpu->iem.s.uFpuOpcode         = UINT16_MAX;
    480 #   ifdef IEM_WITH_CODE_TLB
    481     pVCpu->iem.s.offInstrNextByte   = UINT16_MAX;
    482     pVCpu->iem.s.pbInstrBuf         = NULL;
    483     pVCpu->iem.s.cbInstrBuf         = UINT16_MAX;
    484     pVCpu->iem.s.cbInstrBufTotal    = UINT16_MAX;
    485     pVCpu->iem.s.offCurInstrStart   = INT16_MAX;
    486     pVCpu->iem.s.uInstrBufPc        = UINT64_C(0xc0ffc0ffcff0c0ff);
    487 #    ifdef IEM_WITH_CODE_TLB_AND_OPCODE_BUF
    488     pVCpu->iem.s.offOpcode          = 127;
    489 #    endif
    490 #   else
    491     pVCpu->iem.s.offOpcode          = 127;
    492     pVCpu->iem.s.cbOpcode           = 127;
    493 #   endif
    494 #  endif /* VBOX_STRICT */
    495 }
    496 
    497 
    498 #  if defined(VBOX_WITH_NESTED_HWVIRT_SVM) || defined(VBOX_WITH_NESTED_HWVIRT_VMX)
    499 /**
    500  * Performs a minimal reinitialization of the execution state.
    501  *
    502  * This is intended to be used by VM-exits, SMM, LOADALL and other similar
    503  * 'world-switch' types operations on the CPU. Currently only nested
    504  * hardware-virtualization uses it.
    505  *
    506  * @param   pVCpu               The cross context virtual CPU structure of the calling EMT.
    507  * @param   cbInstr             The instruction length (for flushing).
    508  */
    509 DECLINLINE(void) iemReInitExec(PVMCPUCC pVCpu, uint8_t cbInstr) RT_NOEXCEPT
    510 {
    511     pVCpu->iem.s.fExec = iemCalcExecFlags(pVCpu) | (pVCpu->iem.s.fExec & IEM_F_USER_OPTS);
    512     iemOpcodeFlushHeavy(pVCpu, cbInstr);
    513 }
    514 #  endif
    515 
    516 # endif /* VBOX_INCLUDED_vmm_dbgf_h || DOXYGEN_RUNNING */
    517 
    518 /**
    519  * Counterpart to #iemInitExec that undoes evil strict-build stuff.
    520  *
    521  * @param   pVCpu               The cross context virtual CPU structure of the
    522  *                              calling thread.
    523  */
    524 DECLINLINE(void) iemUninitExec(PVMCPUCC pVCpu) RT_NOEXCEPT
    525 {
    526     /* Note! do not touch fInPatchCode here! (see iemUninitExecAndFiddleStatusAndMaybeReenter) */
    527 # ifdef VBOX_STRICT
    528 #  ifdef IEM_WITH_CODE_TLB
    529     NOREF(pVCpu);
    530 #  else
    531     pVCpu->iem.s.cbOpcode = 0;
    532 #  endif
    533 # else
    534     NOREF(pVCpu);
    535 # endif
    536 }
    537 
    538 
    539 /**
    540  * Calls iemUninitExec, iemExecStatusCodeFiddling and iemRCRawMaybeReenter.
    541  *
    542  * Only calling iemRCRawMaybeReenter in raw-mode, obviously.
    543  *
    544  * @returns Fiddled strict vbox status code, ready to return to non-IEM caller.
    545  * @param   pVCpu       The cross context virtual CPU structure of the calling thread.
    546  * @param   rcStrict    The status code to fiddle.
    547  */
    548 DECLINLINE(VBOXSTRICTRC) iemUninitExecAndFiddleStatusAndMaybeReenter(PVMCPUCC pVCpu, VBOXSTRICTRC rcStrict) RT_NOEXCEPT
    549 {
    550     iemUninitExec(pVCpu);
    551     return iemExecStatusCodeFiddling(pVCpu, rcStrict);
    552 }
    553 
    554 
    555 /**
    556  * Macro used by the IEMExec* method to check the given instruction length.
    557  *
    558  * Will return on failure!
    559  *
    560  * @param   a_cbInstr   The given instruction length.
    561  * @param   a_cbMin     The minimum length.
    562  */
    563 # define IEMEXEC_ASSERT_INSTR_LEN_RETURN(a_cbInstr, a_cbMin) \
    564     AssertMsgReturn((unsigned)(a_cbInstr) - (unsigned)(a_cbMin) <= (unsigned)15 - (unsigned)(a_cbMin), \
    565                     ("cbInstr=%u cbMin=%u\n", (a_cbInstr), (a_cbMin)), VERR_IEM_INVALID_INSTR_LENGTH)
    566 
    56738
    56839# ifndef IEM_WITH_SETJMP
     
    15411012#endif /* !IEM_WITH_OPAQUE_DECODER_STATE */
    15421013
    1543 
    1544 /** @name  Misc Worker Functions.
    1545  * @{
    1546  */
    1547 
    1548 /**
    1549  * Gets the correct EFLAGS regardless of whether PATM stores parts of them or
    1550  * not (kind of obsolete now).
    1551  *
    1552  * @param   a_pVCpu The cross context virtual CPU structure of the calling thread.
    1553  */
    1554 #define IEMMISC_GET_EFL(a_pVCpu)            ( (a_pVCpu)->cpum.GstCtx.eflags.u  )
    1555 
    1556 /**
    1557  * Updates the EFLAGS in the correct manner wrt. PATM (kind of obsolete).
    1558  *
    1559  * @param   a_pVCpu The cross context virtual CPU structure of the calling thread.
    1560  * @param   a_fEfl  The new EFLAGS.
    1561  */
    1562 #define IEMMISC_SET_EFL(a_pVCpu, a_fEfl)    do { (a_pVCpu)->cpum.GstCtx.eflags.u = (a_fEfl); } while (0)
    1563 
    1564 
    1565 /**
    1566  * Loads a NULL data selector into a selector register, both the hidden and
    1567  * visible parts, in protected mode.
    1568  *
    1569  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    1570  * @param   pSReg               Pointer to the segment register.
    1571  * @param   uRpl                The RPL.
    1572  */
    1573 DECLINLINE(void) iemHlpLoadNullDataSelectorProt(PVMCPUCC pVCpu, PCPUMSELREG pSReg, RTSEL uRpl) RT_NOEXCEPT
    1574 {
    1575     /** @todo Testcase: write a testcase checking what happends when loading a NULL
    1576      *        data selector in protected mode. */
    1577     pSReg->Sel      = uRpl;
    1578     pSReg->ValidSel = uRpl;
    1579     pSReg->fFlags   = CPUMSELREG_FLAGS_VALID;
    1580     if (IEM_IS_GUEST_CPU_INTEL(pVCpu))
    1581     {
    1582         /* VT-x (Intel 3960x) observed doing something like this. */
    1583         pSReg->Attr.u   = X86DESCATTR_UNUSABLE | X86DESCATTR_G | X86DESCATTR_D | (IEM_GET_CPL(pVCpu) << X86DESCATTR_DPL_SHIFT);
    1584         pSReg->u32Limit = UINT32_MAX;
    1585         pSReg->u64Base  = 0;
    1586     }
    1587     else
    1588     {
    1589         pSReg->Attr.u   = X86DESCATTR_UNUSABLE;
    1590         pSReg->u32Limit = 0;
    1591         pSReg->u64Base  = 0;
    1592     }
    1593 }
    1594 
    1595 /** @} */
    1596 
    1597 
    1598 /*
    1599  *
    1600  * Helpers routines.
    1601  * Helpers routines.
    1602  * Helpers routines.
    1603  *
    1604  */
    16051014
    16061015#ifndef IEM_WITH_OPAQUE_DECODER_STATE
     
    16811090
    16821091
    1683 
    1684 /** @name   Register Access.
    1685  * @{
    1686  */
    1687 
    1688 /**
    1689  * Gets a reference (pointer) to the specified hidden segment register.
    1690  *
    1691  * @returns Hidden register reference.
    1692  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    1693  * @param   iSegReg             The segment register.
    1694  */
    1695 DECL_FORCE_INLINE(PCPUMSELREG) iemSRegGetHid(PVMCPUCC pVCpu, uint8_t iSegReg) RT_NOEXCEPT
    1696 {
    1697     Assert(iSegReg < X86_SREG_COUNT);
    1698     IEM_CTX_ASSERT(pVCpu, CPUMCTX_EXTRN_SREG_FROM_IDX(iSegReg));
    1699     PCPUMSELREG pSReg = &pVCpu->cpum.GstCtx.aSRegs[iSegReg];
    1700 
    1701     Assert(CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pVCpu, pSReg));
    1702     return pSReg;
    1703 }
    1704 
    1705 
    1706 /**
    1707  * Ensures that the given hidden segment register is up to date.
    1708  *
    1709  * @returns Hidden register reference.
    1710  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    1711  * @param   pSReg               The segment register.
    1712  */
    1713 DECL_FORCE_INLINE(PCPUMSELREG) iemSRegUpdateHid(PVMCPUCC pVCpu, PCPUMSELREG pSReg) RT_NOEXCEPT
    1714 {
    1715     Assert(CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pVCpu, pSReg));
    1716     NOREF(pVCpu);
    1717     return pSReg;
    1718 }
    1719 
    1720 
    1721 /**
    1722  * Gets a reference (pointer) to the specified segment register (the selector
    1723  * value).
    1724  *
    1725  * @returns Pointer to the selector variable.
    1726  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    1727  * @param   iSegReg             The segment register.
    1728  */
    1729 DECL_FORCE_INLINE(uint16_t *) iemSRegRef(PVMCPUCC pVCpu, uint8_t iSegReg) RT_NOEXCEPT
    1730 {
    1731     Assert(iSegReg < X86_SREG_COUNT);
    1732     IEM_CTX_ASSERT(pVCpu, CPUMCTX_EXTRN_SREG_FROM_IDX(iSegReg));
    1733     return &pVCpu->cpum.GstCtx.aSRegs[iSegReg].Sel;
    1734 }
    1735 
    1736 
    1737 /**
    1738  * Fetches the selector value of a segment register.
    1739  *
    1740  * @returns The selector value.
    1741  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    1742  * @param   iSegReg             The segment register.
    1743  */
    1744 DECL_FORCE_INLINE(uint16_t) iemSRegFetchU16(PVMCPUCC pVCpu, uint8_t iSegReg) RT_NOEXCEPT
    1745 {
    1746     Assert(iSegReg < X86_SREG_COUNT);
    1747     IEM_CTX_ASSERT(pVCpu, CPUMCTX_EXTRN_SREG_FROM_IDX(iSegReg));
    1748     return pVCpu->cpum.GstCtx.aSRegs[iSegReg].Sel;
    1749 }
    1750 
    1751 
    1752 /**
    1753  * Fetches the base address value of a segment register.
    1754  *
    1755  * @returns The selector value.
    1756  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    1757  * @param   iSegReg             The segment register.
    1758  */
    1759 DECL_FORCE_INLINE(uint64_t) iemSRegBaseFetchU64(PVMCPUCC pVCpu, uint8_t iSegReg) RT_NOEXCEPT
    1760 {
    1761     Assert(iSegReg < X86_SREG_COUNT);
    1762     IEM_CTX_ASSERT(pVCpu, CPUMCTX_EXTRN_SREG_FROM_IDX(iSegReg));
    1763     return pVCpu->cpum.GstCtx.aSRegs[iSegReg].u64Base;
    1764 }
    1765 
    1766 
    1767 /**
    1768  * Gets a reference (pointer) to the specified general purpose register.
    1769  *
    1770  * @returns Register reference.
    1771  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    1772  * @param   iReg                The general purpose register.
    1773  */
    1774 DECL_FORCE_INLINE(void *) iemGRegRef(PVMCPUCC pVCpu, uint8_t iReg) RT_NOEXCEPT
    1775 {
    1776     Assert(iReg < 16);
    1777     return &pVCpu->cpum.GstCtx.aGRegs[iReg];
    1778 }
    1779 
    1780 
    1781 #ifndef IEM_WITH_OPAQUE_DECODER_STATE
    1782 /**
    1783  * Gets a reference (pointer) to the specified 8-bit general purpose register.
    1784  *
    1785  * Because of AH, CH, DH and BH we cannot use iemGRegRef directly here.
    1786  *
    1787  * @returns Register reference.
    1788  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    1789  * @param   iReg                The register.
    1790  */
    1791 DECL_FORCE_INLINE(uint8_t *) iemGRegRefU8(PVMCPUCC pVCpu, uint8_t iReg) RT_NOEXCEPT
    1792 {
    1793     if (iReg < 4 || (pVCpu->iem.s.fPrefixes & (IEM_OP_PRF_REX | IEM_OP_PRF_VEX)))
    1794     {
    1795         Assert(iReg < 16);
    1796         return &pVCpu->cpum.GstCtx.aGRegs[iReg].u8;
    1797     }
    1798     /* high 8-bit register. */
    1799     Assert(iReg < 8);
    1800     return &pVCpu->cpum.GstCtx.aGRegs[iReg & 3].bHi;
    1801 }
    1802 #endif
    1803 
    1804 
    1805 /**
    1806  * Gets a reference (pointer) to the specified 8-bit general purpose register,
    1807  * alternative version with extended (20) register index.
    1808  *
    1809  * @returns Register reference.
    1810  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    1811  * @param   iRegEx              The register.  The 16 first are regular ones,
    1812  *                              whereas 16 thru 19 maps to AH, CH, DH and BH.
    1813  */
    1814 DECL_FORCE_INLINE(uint8_t *) iemGRegRefU8Ex(PVMCPUCC pVCpu, uint8_t iRegEx) RT_NOEXCEPT
    1815 {
    1816     /** @todo This could be done by double indexing on little endian hosts:
    1817      *  return &pVCpu->cpum.GstCtx.aGRegs[iRegEx & 15].ab[iRegEx >> 4]; */
    1818     if (iRegEx < 16)
    1819         return &pVCpu->cpum.GstCtx.aGRegs[iRegEx].u8;
    1820 
    1821     /* high 8-bit register. */
    1822     Assert(iRegEx < 20);
    1823     return &pVCpu->cpum.GstCtx.aGRegs[iRegEx & 3].bHi;
    1824 }
    1825 
    1826 
    1827 /**
    1828  * Gets a reference (pointer) to the specified 16-bit general purpose register.
    1829  *
    1830  * @returns Register reference.
    1831  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    1832  * @param   iReg                The register.
    1833  */
    1834 DECL_FORCE_INLINE(uint16_t *) iemGRegRefU16(PVMCPUCC pVCpu, uint8_t iReg) RT_NOEXCEPT
    1835 {
    1836     Assert(iReg < 16);
    1837     return &pVCpu->cpum.GstCtx.aGRegs[iReg].u16;
    1838 }
    1839 
    1840 
    1841 /**
    1842  * Gets a reference (pointer) to the specified 32-bit general purpose register.
    1843  *
    1844  * @returns Register reference.
    1845  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    1846  * @param   iReg                The register.
    1847  */
    1848 DECL_FORCE_INLINE(uint32_t *) iemGRegRefU32(PVMCPUCC pVCpu, uint8_t iReg) RT_NOEXCEPT
    1849 {
    1850     Assert(iReg < 16);
    1851     return &pVCpu->cpum.GstCtx.aGRegs[iReg].u32;
    1852 }
    1853 
    1854 
    1855 /**
    1856  * Gets a reference (pointer) to the specified signed 32-bit general purpose register.
    1857  *
    1858  * @returns Register reference.
    1859  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    1860  * @param   iReg                The register.
    1861  */
    1862 DECL_FORCE_INLINE(int32_t *) iemGRegRefI32(PVMCPUCC pVCpu, uint8_t iReg) RT_NOEXCEPT
    1863 {
    1864     Assert(iReg < 16);
    1865     return (int32_t *)&pVCpu->cpum.GstCtx.aGRegs[iReg].u32;
    1866 }
    1867 
    1868 
    1869 /**
    1870  * Gets a reference (pointer) to the specified 64-bit general purpose register.
    1871  *
    1872  * @returns Register reference.
    1873  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    1874  * @param   iReg                The register.
    1875  */
    1876 DECL_FORCE_INLINE(uint64_t *) iemGRegRefU64(PVMCPUCC pVCpu, uint8_t iReg) RT_NOEXCEPT
    1877 {
    1878     Assert(iReg < 64);
    1879     return &pVCpu->cpum.GstCtx.aGRegs[iReg].u64;
    1880 }
    1881 
    1882 
    1883 /**
    1884  * Gets a reference (pointer) to the specified signed 64-bit general purpose register.
    1885  *
    1886  * @returns Register reference.
    1887  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    1888  * @param   iReg                The register.
    1889  */
    1890 DECL_FORCE_INLINE(int64_t *) iemGRegRefI64(PVMCPUCC pVCpu, uint8_t iReg) RT_NOEXCEPT
    1891 {
    1892     Assert(iReg < 16);
    1893     return (int64_t *)&pVCpu->cpum.GstCtx.aGRegs[iReg].u64;
    1894 }
    1895 
    1896 
    1897 /**
    1898  * Gets a reference (pointer) to the specified segment register's base address.
    1899  *
    1900  * @returns Segment register base address reference.
    1901  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    1902  * @param   iSegReg             The segment selector.
    1903  */
    1904 DECL_FORCE_INLINE(uint64_t *) iemSRegBaseRefU64(PVMCPUCC pVCpu, uint8_t iSegReg) RT_NOEXCEPT
    1905 {
    1906     Assert(iSegReg < X86_SREG_COUNT);
    1907     IEM_CTX_ASSERT(pVCpu, CPUMCTX_EXTRN_SREG_FROM_IDX(iSegReg));
    1908     return &pVCpu->cpum.GstCtx.aSRegs[iSegReg].u64Base;
    1909 }
    1910 
    1911 
    1912 #ifndef IEM_WITH_OPAQUE_DECODER_STATE
    1913 /**
    1914  * Fetches the value of a 8-bit general purpose register.
    1915  *
    1916  * @returns The register value.
    1917  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    1918  * @param   iReg                The register.
    1919  */
    1920 DECL_FORCE_INLINE(uint8_t) iemGRegFetchU8(PVMCPUCC pVCpu, uint8_t iReg) RT_NOEXCEPT
    1921 {
    1922     return *iemGRegRefU8(pVCpu, iReg);
    1923 }
    1924 #endif
    1925 
    1926 
    1927 /**
    1928  * Fetches the value of a 8-bit general purpose register, alternative version
    1929  * with extended (20) register index.
    1930 
    1931  * @returns The register value.
    1932  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    1933  * @param   iRegEx              The register.  The 16 first are regular ones,
    1934  *                              whereas 16 thru 19 maps to AH, CH, DH and BH.
    1935  */
    1936 DECL_FORCE_INLINE(uint8_t) iemGRegFetchU8Ex(PVMCPUCC pVCpu, uint8_t iRegEx) RT_NOEXCEPT
    1937 {
    1938     return *iemGRegRefU8Ex(pVCpu, iRegEx);
    1939 }
    1940 
    1941 
    1942 /**
    1943  * Fetches the value of a 16-bit general purpose register.
    1944  *
    1945  * @returns The register value.
    1946  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    1947  * @param   iReg                The register.
    1948  */
    1949 DECL_FORCE_INLINE(uint16_t) iemGRegFetchU16(PVMCPUCC pVCpu, uint8_t iReg) RT_NOEXCEPT
    1950 {
    1951     Assert(iReg < 16);
    1952     return pVCpu->cpum.GstCtx.aGRegs[iReg].u16;
    1953 }
    1954 
    1955 
    1956 /**
    1957  * Fetches the value of a 32-bit general purpose register.
    1958  *
    1959  * @returns The register value.
    1960  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    1961  * @param   iReg                The register.
    1962  */
    1963 DECL_FORCE_INLINE(uint32_t) iemGRegFetchU32(PVMCPUCC pVCpu, uint8_t iReg) RT_NOEXCEPT
    1964 {
    1965     Assert(iReg < 16);
    1966     return pVCpu->cpum.GstCtx.aGRegs[iReg].u32;
    1967 }
    1968 
    1969 
    1970 /**
    1971  * Fetches the value of a 64-bit general purpose register.
    1972  *
    1973  * @returns The register value.
    1974  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    1975  * @param   iReg                The register.
    1976  */
    1977 DECL_FORCE_INLINE(uint64_t) iemGRegFetchU64(PVMCPUCC pVCpu, uint8_t iReg) RT_NOEXCEPT
    1978 {
    1979     Assert(iReg < 16);
    1980     return pVCpu->cpum.GstCtx.aGRegs[iReg].u64;
    1981 }
    1982 
    1983 
    1984 /**
    1985  * Stores a 16-bit value to a general purpose register.
    1986  *
    1987  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    1988  * @param   iReg                The register.
    1989  * @param   uValue              The value to store.
    1990  */
    1991 DECL_FORCE_INLINE(void) iemGRegStoreU16(PVMCPUCC pVCpu, uint8_t iReg, uint16_t uValue) RT_NOEXCEPT
    1992 {
    1993     Assert(iReg < 16);
    1994     pVCpu->cpum.GstCtx.aGRegs[iReg].u16 = uValue;
    1995 }
    1996 
    1997 
    1998 /**
    1999  * Stores a 32-bit value to a general purpose register, implicitly clearing high
    2000  * values.
    2001  *
    2002  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    2003  * @param   iReg                The register.
    2004  * @param   uValue              The value to store.
    2005  */
    2006 DECL_FORCE_INLINE(void) iemGRegStoreU32(PVMCPUCC pVCpu, uint8_t iReg, uint32_t uValue) RT_NOEXCEPT
    2007 {
    2008     Assert(iReg < 16);
    2009     pVCpu->cpum.GstCtx.aGRegs[iReg].u64 = uValue;
    2010 }
    2011 
    2012 
    2013 /**
    2014  * Stores a 64-bit value to a general purpose register.
    2015  *
    2016  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    2017  * @param   iReg                The register.
    2018  * @param   uValue              The value to store.
    2019  */
    2020 DECL_FORCE_INLINE(void) iemGRegStoreU64(PVMCPUCC pVCpu, uint8_t iReg, uint64_t uValue) RT_NOEXCEPT
    2021 {
    2022     Assert(iReg < 16);
    2023     pVCpu->cpum.GstCtx.aGRegs[iReg].u64 = uValue;
    2024 }
    2025 
    2026 
    2027 /**
    2028  * Get the address of the top of the stack.
    2029  *
    2030  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    2031  */
    2032 DECL_FORCE_INLINE(RTGCPTR) iemRegGetEffRsp(PCVMCPU pVCpu) RT_NOEXCEPT
    2033 {
    2034     if (IEM_IS_64BIT_CODE(pVCpu))
    2035         return pVCpu->cpum.GstCtx.rsp;
    2036     if (pVCpu->cpum.GstCtx.ss.Attr.n.u1DefBig)
    2037         return pVCpu->cpum.GstCtx.esp;
    2038     return pVCpu->cpum.GstCtx.sp;
    2039 }
    2040 
    2041 
    2042 /**
    2043  * Updates the RIP/EIP/IP to point to the next instruction.
    2044  *
    2045  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    2046  * @param   cbInstr             The number of bytes to add.
    2047  */
    2048 DECL_FORCE_INLINE(void) iemRegAddToRip(PVMCPUCC pVCpu, uint8_t cbInstr) RT_NOEXCEPT
    2049 {
    2050     /*
    2051      * Advance RIP.
    2052      *
    2053      * When we're targetting 8086/8, 80186/8 or 80286 mode the updates are 16-bit,
    2054      * while in all other modes except LM64 the updates are 32-bit.  This means
    2055      * we need to watch for both 32-bit and 16-bit "carry" situations, i.e.
    2056      * 4GB and 64KB rollovers, and decide whether anything needs masking.
    2057      *
    2058      * See PC wrap around tests in bs3-cpu-weird-1.
    2059      */
    2060     uint64_t const uRipPrev = pVCpu->cpum.GstCtx.rip;
    2061     uint64_t const uRipNext = uRipPrev + cbInstr;
    2062     if (RT_LIKELY(   !((uRipNext ^ uRipPrev) & (RT_BIT_64(32) | RT_BIT_64(16)))
    2063                   || IEM_IS_64BIT_CODE(pVCpu)))
    2064         pVCpu->cpum.GstCtx.rip = uRipNext;
    2065     else if (IEM_GET_TARGET_CPU(pVCpu) >= IEMTARGETCPU_386)
    2066         pVCpu->cpum.GstCtx.rip = (uint32_t)uRipNext;
    2067     else
    2068         pVCpu->cpum.GstCtx.rip = (uint16_t)uRipNext;
    2069 }
    2070 
    2071 
    2072 /**
    2073  * Called by iemRegAddToRipAndFinishingClearingRF and others when any of the
    2074  * following EFLAGS bits are set:
    2075  *      - X86_EFL_RF - clear it.
    2076  *      - CPUMCTX_INHIBIT_SHADOW (_SS/_STI) - clear them.
    2077  *      - X86_EFL_TF - generate single step \#DB trap.
    2078  *      - CPUMCTX_DBG_HIT_DR0/1/2/3 - generate \#DB trap (data or I/O, not
    2079  *        instruction).
    2080  *
    2081  * According to @sdmv3{077,200,Table 6-2,Priority Among Concurrent Events},
    2082  * a \#DB due to TF (single stepping) or a DRx non-instruction breakpoint
    2083  * takes priority over both NMIs and hardware interrupts.  So, neither is
    2084  * considered here.  (The RESET, \#MC, SMI, INIT, STOPCLK and FLUSH events are
    2085  * either unsupported will be triggered on-top of any \#DB raised here.)
    2086  *
    2087  * The RF flag only needs to be cleared here as it only suppresses instruction
    2088  * breakpoints which are not raised here (happens synchronously during
    2089  * instruction fetching).
    2090  *
    2091  * The CPUMCTX_INHIBIT_SHADOW_SS flag will be cleared by this function, so its
    2092  * status has no bearing on whether \#DB exceptions are raised.
    2093  *
    2094  * @note This must *NOT* be called by the two instructions setting the
    2095  *       CPUMCTX_INHIBIT_SHADOW_SS flag.
    2096  *
    2097  * @see  @sdmv3{077,200,Table 6-2,Priority Among Concurrent Events}
    2098  * @see  @sdmv3{077,200,6.8.3,Masking Exceptions and Interrupts When Switching
    2099  *              Stacks}
    2100  */
    2101 template<uint32_t const a_fTF = X86_EFL_TF>
    2102 static VBOXSTRICTRC iemFinishInstructionWithFlagsSet(PVMCPUCC pVCpu, int rcNormal) RT_NOEXCEPT
    2103 {
    2104     /*
    2105      * Normally we're just here to clear RF and/or interrupt shadow bits.
    2106      */
    2107     if (RT_LIKELY((pVCpu->cpum.GstCtx.eflags.uBoth & (a_fTF | CPUMCTX_DBG_HIT_DRX_MASK | CPUMCTX_DBG_DBGF_MASK)) == 0))
    2108         pVCpu->cpum.GstCtx.eflags.uBoth &= ~(X86_EFL_RF | CPUMCTX_INHIBIT_SHADOW);
    2109     else
    2110     {
    2111         /*
    2112          * Raise a #DB or/and DBGF event.
    2113          */
    2114         VBOXSTRICTRC rcStrict;
    2115         if (pVCpu->cpum.GstCtx.eflags.uBoth & (a_fTF | CPUMCTX_DBG_HIT_DRX_MASK))
    2116         {
    2117             IEM_CTX_IMPORT_RET(pVCpu, CPUMCTX_EXTRN_DR6);
    2118             pVCpu->cpum.GstCtx.dr[6] &= ~X86_DR6_B_MASK;
    2119             if (pVCpu->cpum.GstCtx.eflags.uBoth & a_fTF)
    2120                 pVCpu->cpum.GstCtx.dr[6] |= X86_DR6_BS;
    2121             pVCpu->cpum.GstCtx.dr[6] |= (pVCpu->cpum.GstCtx.eflags.uBoth & CPUMCTX_DBG_HIT_DRX_MASK_NONSILENT)
    2122                                      >> CPUMCTX_DBG_HIT_DRX_SHIFT;
    2123             LogFlowFunc(("Guest #DB fired at %04X:%016llX: DR6=%08X, RFLAGS=%16RX64\n",
    2124                          pVCpu->cpum.GstCtx.cs.Sel, pVCpu->cpum.GstCtx.rip, (unsigned)pVCpu->cpum.GstCtx.dr[6],
    2125                          pVCpu->cpum.GstCtx.rflags.uBoth));
    2126 
    2127             pVCpu->cpum.GstCtx.eflags.uBoth &= ~(X86_EFL_RF | CPUMCTX_INHIBIT_SHADOW | CPUMCTX_DBG_HIT_DRX_MASK);
    2128             rcStrict = iemRaiseDebugException(pVCpu);
    2129 
    2130             /* A DBGF event/breakpoint trumps the iemRaiseDebugException informational status code. */
    2131             if ((pVCpu->cpum.GstCtx.eflags.uBoth & CPUMCTX_DBG_DBGF_MASK) && RT_FAILURE(rcStrict))
    2132             {
    2133                 rcStrict = pVCpu->cpum.GstCtx.eflags.uBoth & CPUMCTX_DBG_DBGF_BP ? VINF_EM_DBG_BREAKPOINT : VINF_EM_DBG_EVENT;
    2134                 LogFlowFunc(("dbgf at %04X:%016llX: %Rrc\n", pVCpu->cpum.GstCtx.cs.Sel, pVCpu->cpum.GstCtx.rip, VBOXSTRICTRC_VAL(rcStrict)));
    2135             }
    2136         }
    2137         else
    2138         {
    2139             Assert(pVCpu->cpum.GstCtx.eflags.uBoth & CPUMCTX_DBG_DBGF_MASK);
    2140             rcStrict = pVCpu->cpum.GstCtx.eflags.uBoth & CPUMCTX_DBG_DBGF_BP ? VINF_EM_DBG_BREAKPOINT : VINF_EM_DBG_EVENT;
    2141             LogFlowFunc(("dbgf at %04X:%016llX: %Rrc\n", pVCpu->cpum.GstCtx.cs.Sel, pVCpu->cpum.GstCtx.rip, VBOXSTRICTRC_VAL(rcStrict)));
    2142         }
    2143         pVCpu->cpum.GstCtx.eflags.uBoth &= ~CPUMCTX_DBG_DBGF_MASK;
    2144         Assert(rcStrict != VINF_SUCCESS);
    2145         return rcStrict;
    2146     }
    2147     return rcNormal;
    2148 }
    2149 
    2150 
    2151 /**
    2152  * Clears the RF and CPUMCTX_INHIBIT_SHADOW, triggering \#DB if pending.
    2153  *
    2154  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    2155  * @param   rcNormal            VINF_SUCCESS to continue TB.
    2156  *                              VINF_IEM_REEXEC_BREAK to force TB exit when
    2157  *                              taking the wrong conditional branhc.
    2158  */
    2159 DECL_FORCE_INLINE(VBOXSTRICTRC) iemRegFinishClearingRF(PVMCPUCC pVCpu, int rcNormal) RT_NOEXCEPT
    2160 {
    2161     /*
    2162      * We assume that most of the time nothing actually needs doing here.
    2163      */
    2164     AssertCompile(CPUMCTX_INHIBIT_SHADOW < UINT32_MAX);
    2165     if (RT_LIKELY(!(  pVCpu->cpum.GstCtx.eflags.uBoth
    2166                     & (X86_EFL_TF | X86_EFL_RF | CPUMCTX_INHIBIT_SHADOW | CPUMCTX_DBG_HIT_DRX_MASK | CPUMCTX_DBG_DBGF_MASK)) ))
    2167         return rcNormal;
    2168     return iemFinishInstructionWithFlagsSet(pVCpu, rcNormal);
    2169 }
    2170 
    2171 
    2172 /**
    2173  * Updates the RIP/EIP/IP to point to the next instruction and clears EFLAGS.RF
    2174  * and CPUMCTX_INHIBIT_SHADOW.
    2175  *
    2176  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    2177  * @param   cbInstr             The number of bytes to add.
    2178  */
    2179 DECL_FORCE_INLINE(VBOXSTRICTRC) iemRegAddToRipAndFinishingClearingRF(PVMCPUCC pVCpu, uint8_t cbInstr) RT_NOEXCEPT
    2180 {
    2181     iemRegAddToRip(pVCpu, cbInstr);
    2182     return iemRegFinishClearingRF(pVCpu, VINF_SUCCESS);
    2183 }
    2184 
    2185 
    2186 /**
    2187  * Updates the RIP to point to the next instruction and clears EFLAGS.RF
    2188  * and CPUMCTX_INHIBIT_SHADOW.
    2189  *
    2190  * Only called from 64-bit code.
    2191  *
    2192  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    2193  * @param   cbInstr             The number of bytes to add.
    2194  * @param   rcNormal            VINF_SUCCESS to continue TB.
    2195  *                              VINF_IEM_REEXEC_BREAK to force TB exit when
    2196  *                              taking the wrong conditional branhc.
    2197  */
    2198 DECL_FORCE_INLINE(VBOXSTRICTRC) iemRegAddToRip64AndFinishingClearingRF(PVMCPUCC pVCpu, uint8_t cbInstr, int rcNormal) RT_NOEXCEPT
    2199 {
    2200     pVCpu->cpum.GstCtx.rip = pVCpu->cpum.GstCtx.rip + cbInstr;
    2201     return iemRegFinishClearingRF(pVCpu, rcNormal);
    2202 }
    2203 
    2204 
    2205 /**
    2206  * Updates the EIP to point to the next instruction and clears EFLAGS.RF and
    2207  * CPUMCTX_INHIBIT_SHADOW.
    2208  *
    2209  * This is never from 64-bit code.
    2210  *
    2211  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    2212  * @param   cbInstr             The number of bytes to add.
    2213  * @param   rcNormal            VINF_SUCCESS to continue TB.
    2214  *                              VINF_IEM_REEXEC_BREAK to force TB exit when
    2215  *                              taking the wrong conditional branhc.
    2216  */
    2217 DECL_FORCE_INLINE(VBOXSTRICTRC) iemRegAddToEip32AndFinishingClearingRF(PVMCPUCC pVCpu, uint8_t cbInstr, int rcNormal) RT_NOEXCEPT
    2218 {
    2219     pVCpu->cpum.GstCtx.rip = (uint32_t)(pVCpu->cpum.GstCtx.eip + cbInstr);
    2220     return iemRegFinishClearingRF(pVCpu, rcNormal);
    2221 }
    2222 
    2223 
    2224 /**
    2225  * Updates the IP to point to the next instruction and clears EFLAGS.RF and
    2226  * CPUMCTX_INHIBIT_SHADOW.
    2227  *
    2228  * This is only ever used from 16-bit code on a pre-386 CPU.
    2229  *
    2230  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    2231  * @param   cbInstr             The number of bytes to add.
    2232  * @param   rcNormal            VINF_SUCCESS to continue TB.
    2233  *                              VINF_IEM_REEXEC_BREAK to force TB exit when
    2234  *                              taking the wrong conditional branhc.
    2235  */
    2236 DECL_FORCE_INLINE(VBOXSTRICTRC) iemRegAddToIp16AndFinishingClearingRF(PVMCPUCC pVCpu, uint8_t cbInstr, int rcNormal) RT_NOEXCEPT
    2237 {
    2238     pVCpu->cpum.GstCtx.rip = (uint16_t)(pVCpu->cpum.GstCtx.ip + cbInstr);
    2239     return iemRegFinishClearingRF(pVCpu, rcNormal);
    2240 }
    2241 
    2242 
    2243 /**
    2244  * Tail method for a finish function that does't clear flags or raise \#DB.
    2245  *
    2246  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    2247  * @param   rcNormal            VINF_SUCCESS to continue TB.
    2248  *                              VINF_IEM_REEXEC_BREAK to force TB exit when
    2249  *                              taking the wrong conditional branhc.
    2250  */
    2251 DECL_FORCE_INLINE(VBOXSTRICTRC) iemRegFinishNoFlags(PVMCPUCC pVCpu, int rcNormal) RT_NOEXCEPT
    2252 {
    2253     AssertCompile(CPUMCTX_INHIBIT_SHADOW < UINT32_MAX);
    2254     Assert(!(  pVCpu->cpum.GstCtx.eflags.uBoth
    2255              & (X86_EFL_TF | X86_EFL_RF | CPUMCTX_INHIBIT_SHADOW | CPUMCTX_DBG_HIT_DRX_MASK | CPUMCTX_DBG_DBGF_MASK)) );
    2256     RT_NOREF(pVCpu);
    2257     return rcNormal;
    2258 }
    2259 
    2260 
    2261 /**
    2262  * Updates the RIP to point to the next instruction, but does not need to clear
    2263  * EFLAGS.RF or CPUMCTX_INHIBIT_SHADOW nor check for debug flags.
    2264  *
    2265  * Only called from 64-bit code.
    2266  *
    2267  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    2268  * @param   cbInstr             The number of bytes to add.
    2269  * @param   rcNormal            VINF_SUCCESS to continue TB.
    2270  *                              VINF_IEM_REEXEC_BREAK to force TB exit when
    2271  *                              taking the wrong conditional branhc.
    2272  */
    2273 DECL_FORCE_INLINE(VBOXSTRICTRC) iemRegAddToRip64AndFinishingNoFlags(PVMCPUCC pVCpu, uint8_t cbInstr, int rcNormal) RT_NOEXCEPT
    2274 {
    2275     pVCpu->cpum.GstCtx.rip = pVCpu->cpum.GstCtx.rip + cbInstr;
    2276     return iemRegFinishNoFlags(pVCpu, rcNormal);
    2277 }
    2278 
    2279 
    2280 /**
    2281  * Updates the EIP to point to the next instruction, but does not need to clear
    2282  * EFLAGS.RF or CPUMCTX_INHIBIT_SHADOW nor check for debug flags.
    2283  *
    2284  * This is never from 64-bit code.
    2285  *
    2286  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    2287  * @param   cbInstr             The number of bytes to add.
    2288  * @param   rcNormal            VINF_SUCCESS to continue TB.
    2289  *                              VINF_IEM_REEXEC_BREAK to force TB exit when
    2290  *                              taking the wrong conditional branhc.
    2291  */
    2292 DECL_FORCE_INLINE(VBOXSTRICTRC) iemRegAddToEip32AndFinishingNoFlags(PVMCPUCC pVCpu, uint8_t cbInstr, int rcNormal) RT_NOEXCEPT
    2293 {
    2294     pVCpu->cpum.GstCtx.rip = (uint32_t)(pVCpu->cpum.GstCtx.eip + cbInstr);
    2295     return iemRegFinishNoFlags(pVCpu, rcNormal);
    2296 }
    2297 
    2298 
    2299 /**
    2300  * Updates the IP to point to the next instruction, but does not need to clear
    2301  * EFLAGS.RF or CPUMCTX_INHIBIT_SHADOW nor check for debug flags.
    2302  *
    2303  * This is only ever used from 16-bit code on a pre-386 CPU.
    2304  *
    2305  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    2306  * @param   cbInstr             The number of bytes to add.
    2307  * @param   rcNormal            VINF_SUCCESS to continue TB.
    2308  *                              VINF_IEM_REEXEC_BREAK to force TB exit when
    2309  *                              taking the wrong conditional branhc.
    2310  *
    2311  */
    2312 DECL_FORCE_INLINE(VBOXSTRICTRC) iemRegAddToIp16AndFinishingNoFlags(PVMCPUCC pVCpu, uint8_t cbInstr, int rcNormal) RT_NOEXCEPT
    2313 {
    2314     pVCpu->cpum.GstCtx.rip = (uint16_t)(pVCpu->cpum.GstCtx.ip + cbInstr);
    2315     return iemRegFinishNoFlags(pVCpu, rcNormal);
    2316 }
    2317 
    2318 
    2319 /**
    2320  * Adds a 8-bit signed jump offset to RIP from 64-bit code.
    2321  *
    2322  * May raise a \#GP(0) if the new RIP is non-canonical or outside the code
    2323  * segment limit.
    2324  *
    2325  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    2326  * @param   cbInstr             Instruction size.
    2327  * @param   offNextInstr        The offset of the next instruction.
    2328  * @param   enmEffOpSize        Effective operand size.
    2329  * @param   rcNormal            VINF_SUCCESS to continue TB.
    2330  *                              VINF_IEM_REEXEC_BREAK to force TB exit when
    2331  *                              taking the wrong conditional branhc.
    2332  */
    2333 DECL_FORCE_INLINE(VBOXSTRICTRC) iemRegRip64RelativeJumpS8AndFinishClearingRF(PVMCPUCC pVCpu, uint8_t cbInstr, int8_t offNextInstr,
    2334                                                                              IEMMODE enmEffOpSize, int rcNormal) RT_NOEXCEPT
    2335 {
    2336     Assert(IEM_IS_64BIT_CODE(pVCpu));
    2337     Assert(enmEffOpSize == IEMMODE_64BIT || enmEffOpSize == IEMMODE_16BIT);
    2338 
    2339     uint64_t uNewRip = pVCpu->cpum.GstCtx.rip + cbInstr + (int64_t)offNextInstr;
    2340     if (enmEffOpSize == IEMMODE_16BIT)
    2341         uNewRip &= UINT16_MAX;
    2342 
    2343     if (RT_LIKELY(IEM_IS_CANONICAL(uNewRip)))
    2344         pVCpu->cpum.GstCtx.rip = uNewRip;
    2345     else
    2346         return iemRaiseGeneralProtectionFault0(pVCpu);
    2347 
    2348 #ifndef IEM_WITH_CODE_TLB
    2349     iemOpcodeFlushLight(pVCpu, cbInstr);
    2350 #endif
    2351 
    2352     /*
    2353      * Clear RF and finish the instruction (maybe raise #DB).
    2354      */
    2355     return iemRegFinishClearingRF(pVCpu, rcNormal);
    2356 }
    2357 
    2358 
    2359 /**
    2360  * Adds a 8-bit signed jump offset to RIP from 64-bit code when the caller is
    2361  * sure it stays within the same page.
    2362  *
    2363  * May raise a \#GP(0) if the new RIP is non-canonical or outside the code
    2364  * segment limit.
    2365  *
    2366  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    2367  * @param   cbInstr             Instruction size.
    2368  * @param   offNextInstr        The offset of the next instruction.
    2369  * @param   enmEffOpSize        Effective operand size.
    2370  * @param   rcNormal            VINF_SUCCESS to continue TB.
    2371  *                              VINF_IEM_REEXEC_BREAK to force TB exit when
    2372  *                              taking the wrong conditional branhc.
    2373  */
    2374 DECL_FORCE_INLINE(VBOXSTRICTRC)
    2375 iemRegRip64RelativeJumpS8IntraPgAndFinishClearingRF(PVMCPUCC pVCpu, uint8_t cbInstr, int8_t offNextInstr,
    2376                                                     IEMMODE enmEffOpSize, int rcNormal) RT_NOEXCEPT
    2377 {
    2378     Assert(IEM_IS_64BIT_CODE(pVCpu));
    2379     Assert(enmEffOpSize == IEMMODE_64BIT); RT_NOREF(enmEffOpSize);
    2380 
    2381     uint64_t const uNewRip = pVCpu->cpum.GstCtx.rip + cbInstr + (int64_t)offNextInstr;
    2382     Assert((pVCpu->cpum.GstCtx.rip >> GUEST_PAGE_SHIFT) == (uNewRip >> GUEST_PAGE_SHIFT));
    2383     pVCpu->cpum.GstCtx.rip = uNewRip;
    2384 
    2385 #ifndef IEM_WITH_CODE_TLB
    2386     iemOpcodeFlushLight(pVCpu, cbInstr);
    2387 #endif
    2388 
    2389     /*
    2390      * Clear RF and finish the instruction (maybe raise #DB).
    2391      */
    2392     return iemRegFinishClearingRF(pVCpu, rcNormal);
    2393 }
    2394 
    2395 
    2396 /**
    2397  * Adds a 8-bit signed jump offset to EIP, on 386 or later from 16-bit or 32-bit
    2398  * code (never 64-bit).
    2399  *
    2400  * May raise a \#GP(0) if the new RIP is non-canonical or outside the code
    2401  * segment limit.
    2402  *
    2403  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    2404  * @param   cbInstr             Instruction size.
    2405  * @param   offNextInstr        The offset of the next instruction.
    2406  * @param   enmEffOpSize        Effective operand size.
    2407  * @param   rcNormal            VINF_SUCCESS to continue TB.
    2408  *                              VINF_IEM_REEXEC_BREAK to force TB exit when
    2409  *                              taking the wrong conditional branhc.
    2410  */
    2411 DECL_FORCE_INLINE(VBOXSTRICTRC) iemRegEip32RelativeJumpS8AndFinishClearingRF(PVMCPUCC pVCpu, uint8_t cbInstr, int8_t offNextInstr,
    2412                                                                              IEMMODE enmEffOpSize, int rcNormal) RT_NOEXCEPT
    2413 {
    2414     Assert(!IEM_IS_64BIT_CODE(pVCpu));
    2415     Assert(enmEffOpSize == IEMMODE_32BIT || enmEffOpSize == IEMMODE_16BIT);
    2416 
    2417     uint32_t uNewEip = pVCpu->cpum.GstCtx.eip + cbInstr + (int32_t)offNextInstr;
    2418     if (enmEffOpSize == IEMMODE_16BIT)
    2419         uNewEip &= UINT16_MAX;
    2420     if (RT_LIKELY(uNewEip <= pVCpu->cpum.GstCtx.cs.u32Limit))
    2421         pVCpu->cpum.GstCtx.rip = uNewEip;
    2422     else
    2423         return iemRaiseGeneralProtectionFault0(pVCpu);
    2424 
    2425 #ifndef IEM_WITH_CODE_TLB
    2426     iemOpcodeFlushLight(pVCpu, cbInstr);
    2427 #endif
    2428 
    2429     /*
    2430      * Clear RF and finish the instruction (maybe raise #DB).
    2431      */
    2432     return iemRegFinishClearingRF(pVCpu, rcNormal);
    2433 }
    2434 
    2435 
    2436 /**
    2437  * Adds a 8-bit signed jump offset to EIP, on 386 or later from FLAT 32-bit code
    2438  * (never 64-bit).
    2439  *
    2440  * May raise a \#GP(0) if the new RIP is non-canonical or outside the code
    2441  * segment limit.
    2442  *
    2443  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    2444  * @param   cbInstr             Instruction size.
    2445  * @param   offNextInstr        The offset of the next instruction.
    2446  * @param   enmEffOpSize        Effective operand size.
    2447  * @param   rcNormal            VINF_SUCCESS to continue TB.
    2448  *                              VINF_IEM_REEXEC_BREAK to force TB exit when
    2449  *                              taking the wrong conditional branhc.
    2450  */
    2451 DECL_FORCE_INLINE(VBOXSTRICTRC)
    2452  iemRegEip32RelativeJumpS8FlatAndFinishClearingRF(PVMCPUCC pVCpu, uint8_t cbInstr, int8_t offNextInstr,
    2453                                                   IEMMODE enmEffOpSize, int rcNormal) RT_NOEXCEPT
    2454 {
    2455     Assert(!IEM_IS_64BIT_CODE(pVCpu));
    2456     Assert(enmEffOpSize == IEMMODE_32BIT || enmEffOpSize == IEMMODE_16BIT);
    2457 
    2458     uint32_t uNewEip = pVCpu->cpum.GstCtx.eip + cbInstr + (int32_t)offNextInstr;
    2459     if (enmEffOpSize == IEMMODE_16BIT)
    2460         uNewEip &= UINT16_MAX;
    2461     pVCpu->cpum.GstCtx.rip = uNewEip;
    2462 
    2463 #ifndef IEM_WITH_CODE_TLB
    2464     iemOpcodeFlushLight(pVCpu, cbInstr);
    2465 #endif
    2466 
    2467     /*
    2468      * Clear RF and finish the instruction (maybe raise #DB).
    2469      */
    2470     return iemRegFinishClearingRF(pVCpu, rcNormal);
    2471 }
    2472 
    2473 
    2474 /**
    2475  * Adds a 8-bit signed jump offset to IP, on a pre-386 CPU.
    2476  *
    2477  * May raise a \#GP(0) if the new RIP is non-canonical or outside the code
    2478  * segment limit.
    2479  *
    2480  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    2481  * @param   cbInstr             Instruction size.
    2482  * @param   offNextInstr        The offset of the next instruction.
    2483  * @param   rcNormal            VINF_SUCCESS to continue TB.
    2484  *                              VINF_IEM_REEXEC_BREAK to force TB exit when
    2485  *                              taking the wrong conditional branhc.
    2486  */
    2487 DECL_FORCE_INLINE(VBOXSTRICTRC) iemRegIp16RelativeJumpS8AndFinishClearingRF(PVMCPUCC pVCpu, uint8_t cbInstr,
    2488                                                                             int8_t offNextInstr, int rcNormal) RT_NOEXCEPT
    2489 {
    2490     Assert(!IEM_IS_64BIT_CODE(pVCpu));
    2491 
    2492     uint16_t const uNewIp = pVCpu->cpum.GstCtx.ip + cbInstr + (int16_t)offNextInstr;
    2493     if (RT_LIKELY(uNewIp <= pVCpu->cpum.GstCtx.cs.u32Limit))
    2494         pVCpu->cpum.GstCtx.rip = uNewIp;
    2495     else
    2496         return iemRaiseGeneralProtectionFault0(pVCpu);
    2497 
    2498 #ifndef IEM_WITH_CODE_TLB
    2499     iemOpcodeFlushLight(pVCpu, cbInstr);
    2500 #endif
    2501 
    2502     /*
    2503      * Clear RF and finish the instruction (maybe raise #DB).
    2504      */
    2505     return iemRegFinishClearingRF(pVCpu, rcNormal);
    2506 }
    2507 
    2508 
    2509 /**
    2510  * Adds a 8-bit signed jump offset to RIP from 64-bit code, no checking or
    2511  * clearing of flags.
    2512  *
    2513  * May raise a \#GP(0) if the new RIP is non-canonical or outside the code
    2514  * segment limit.
    2515  *
    2516  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    2517  * @param   cbInstr             Instruction size.
    2518  * @param   offNextInstr        The offset of the next instruction.
    2519  * @param   enmEffOpSize        Effective operand size.
    2520  * @param   rcNormal            VINF_SUCCESS to continue TB.
    2521  *                              VINF_IEM_REEXEC_BREAK to force TB exit when
    2522  *                              taking the wrong conditional branhc.
    2523  */
    2524 DECL_FORCE_INLINE(VBOXSTRICTRC) iemRegRip64RelativeJumpS8AndFinishNoFlags(PVMCPUCC pVCpu, uint8_t cbInstr, int8_t offNextInstr,
    2525                                                                           IEMMODE enmEffOpSize, int rcNormal) RT_NOEXCEPT
    2526 {
    2527     Assert(IEM_IS_64BIT_CODE(pVCpu));
    2528     Assert(enmEffOpSize == IEMMODE_64BIT || enmEffOpSize == IEMMODE_16BIT);
    2529 
    2530     uint64_t uNewRip = pVCpu->cpum.GstCtx.rip + cbInstr + (int64_t)offNextInstr;
    2531     if (enmEffOpSize == IEMMODE_16BIT)
    2532         uNewRip &= UINT16_MAX;
    2533 
    2534     if (RT_LIKELY(IEM_IS_CANONICAL(uNewRip)))
    2535         pVCpu->cpum.GstCtx.rip = uNewRip;
    2536     else
    2537         return iemRaiseGeneralProtectionFault0(pVCpu);
    2538 
    2539 #ifndef IEM_WITH_CODE_TLB
    2540     iemOpcodeFlushLight(pVCpu, cbInstr);
    2541 #endif
    2542     return iemRegFinishNoFlags(pVCpu, rcNormal);
    2543 }
    2544 
    2545 
    2546 /**
    2547  * Adds a 8-bit signed jump offset to RIP from 64-bit code when caller is sure
    2548  * it stays within the same page, no checking or clearing of flags.
    2549  *
    2550  * May raise a \#GP(0) if the new RIP is non-canonical or outside the code
    2551  * segment limit.
    2552  *
    2553  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    2554  * @param   cbInstr             Instruction size.
    2555  * @param   offNextInstr        The offset of the next instruction.
    2556  * @param   enmEffOpSize        Effective operand size.
    2557  * @param   rcNormal            VINF_SUCCESS to continue TB.
    2558  *                              VINF_IEM_REEXEC_BREAK to force TB exit when
    2559  *                              taking the wrong conditional branhc.
    2560  */
    2561 DECL_FORCE_INLINE(VBOXSTRICTRC)
    2562 iemRegRip64RelativeJumpS8IntraPgAndFinishNoFlags(PVMCPUCC pVCpu, uint8_t cbInstr, int8_t offNextInstr,
    2563                                                  IEMMODE enmEffOpSize, int rcNormal) RT_NOEXCEPT
    2564 {
    2565     Assert(IEM_IS_64BIT_CODE(pVCpu));
    2566     Assert(enmEffOpSize == IEMMODE_64BIT); RT_NOREF(enmEffOpSize);
    2567 
    2568     uint64_t const uNewRip = pVCpu->cpum.GstCtx.rip + cbInstr + (int64_t)offNextInstr;
    2569     Assert((pVCpu->cpum.GstCtx.rip >> GUEST_PAGE_SHIFT) == (uNewRip >> GUEST_PAGE_SHIFT));
    2570     pVCpu->cpum.GstCtx.rip = uNewRip;
    2571 
    2572 #ifndef IEM_WITH_CODE_TLB
    2573     iemOpcodeFlushLight(pVCpu, cbInstr);
    2574 #endif
    2575     return iemRegFinishNoFlags(pVCpu, rcNormal);
    2576 }
    2577 
    2578 
    2579 /**
    2580  * Adds a 8-bit signed jump offset to EIP, on 386 or later from 16-bit or 32-bit
    2581  * code (never 64-bit), no checking or clearing of flags.
    2582  *
    2583  * May raise a \#GP(0) if the new RIP is non-canonical or outside the code
    2584  * segment limit.
    2585  *
    2586  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    2587  * @param   cbInstr             Instruction size.
    2588  * @param   offNextInstr        The offset of the next instruction.
    2589  * @param   enmEffOpSize        Effective operand size.
    2590  * @param   rcNormal            VINF_SUCCESS to continue TB.
    2591  *                              VINF_IEM_REEXEC_BREAK to force TB exit when
    2592  *                              taking the wrong conditional branhc.
    2593  */
    2594 DECL_FORCE_INLINE(VBOXSTRICTRC) iemRegEip32RelativeJumpS8AndFinishNoFlags(PVMCPUCC pVCpu, uint8_t cbInstr, int8_t offNextInstr,
    2595                                                                           IEMMODE enmEffOpSize, int rcNormal) RT_NOEXCEPT
    2596 {
    2597     Assert(!IEM_IS_64BIT_CODE(pVCpu));
    2598     Assert(enmEffOpSize == IEMMODE_32BIT || enmEffOpSize == IEMMODE_16BIT);
    2599 
    2600     uint32_t uNewEip = pVCpu->cpum.GstCtx.eip + cbInstr + (int32_t)offNextInstr;
    2601     if (enmEffOpSize == IEMMODE_16BIT)
    2602         uNewEip &= UINT16_MAX;
    2603     if (RT_LIKELY(uNewEip <= pVCpu->cpum.GstCtx.cs.u32Limit))
    2604         pVCpu->cpum.GstCtx.rip = uNewEip;
    2605     else
    2606         return iemRaiseGeneralProtectionFault0(pVCpu);
    2607 
    2608 #ifndef IEM_WITH_CODE_TLB
    2609     iemOpcodeFlushLight(pVCpu, cbInstr);
    2610 #endif
    2611     return iemRegFinishNoFlags(pVCpu, rcNormal);
    2612 }
    2613 
    2614 
    2615 /**
    2616  * Adds a 8-bit signed jump offset to EIP, on 386 or later from flat 32-bit code
    2617  * (never 64-bit), no checking or clearing of flags.
    2618  *
    2619  * May raise a \#GP(0) if the new RIP is non-canonical or outside the code
    2620  * segment limit.
    2621  *
    2622  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    2623  * @param   cbInstr             Instruction size.
    2624  * @param   offNextInstr        The offset of the next instruction.
    2625  * @param   enmEffOpSize        Effective operand size.
    2626  * @param   rcNormal            VINF_SUCCESS to continue TB.
    2627  *                              VINF_IEM_REEXEC_BREAK to force TB exit when
    2628  *                              taking the wrong conditional branhc.
    2629  */
    2630 DECL_FORCE_INLINE(VBOXSTRICTRC)
    2631 iemRegEip32RelativeJumpS8FlatAndFinishNoFlags(PVMCPUCC pVCpu, uint8_t cbInstr, int8_t offNextInstr,
    2632                                               IEMMODE enmEffOpSize, int rcNormal) RT_NOEXCEPT
    2633 {
    2634     Assert(!IEM_IS_64BIT_CODE(pVCpu));
    2635     Assert(enmEffOpSize == IEMMODE_32BIT || enmEffOpSize == IEMMODE_16BIT);
    2636 
    2637     uint32_t uNewEip = pVCpu->cpum.GstCtx.eip + cbInstr + (int32_t)offNextInstr;
    2638     if (enmEffOpSize == IEMMODE_16BIT)
    2639         uNewEip &= UINT16_MAX;
    2640     pVCpu->cpum.GstCtx.rip = uNewEip;
    2641 
    2642 #ifndef IEM_WITH_CODE_TLB
    2643     iemOpcodeFlushLight(pVCpu, cbInstr);
    2644 #endif
    2645     return iemRegFinishNoFlags(pVCpu, rcNormal);
    2646 }
    2647 
    2648 
    2649 /**
    2650  * Adds a 8-bit signed jump offset to IP, on a pre-386 CPU, no checking or
    2651  * clearing of flags.
    2652  *
    2653  * May raise a \#GP(0) if the new RIP is non-canonical or outside the code
    2654  * segment limit.
    2655  *
    2656  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    2657  * @param   cbInstr             Instruction size.
    2658  * @param   offNextInstr        The offset of the next instruction.
    2659  * @param   rcNormal            VINF_SUCCESS to continue TB.
    2660  *                              VINF_IEM_REEXEC_BREAK to force TB exit when
    2661  *                              taking the wrong conditional branhc.
    2662  */
    2663 DECL_FORCE_INLINE(VBOXSTRICTRC) iemRegIp16RelativeJumpS8AndFinishNoFlags(PVMCPUCC pVCpu, uint8_t cbInstr,
    2664                                                                          int8_t offNextInstr, int rcNormal) RT_NOEXCEPT
    2665 {
    2666     Assert(!IEM_IS_64BIT_CODE(pVCpu));
    2667 
    2668     uint16_t const uNewIp = pVCpu->cpum.GstCtx.ip + cbInstr + (int16_t)offNextInstr;
    2669     if (RT_LIKELY(uNewIp <= pVCpu->cpum.GstCtx.cs.u32Limit))
    2670         pVCpu->cpum.GstCtx.rip = uNewIp;
    2671     else
    2672         return iemRaiseGeneralProtectionFault0(pVCpu);
    2673 
    2674 #ifndef IEM_WITH_CODE_TLB
    2675     iemOpcodeFlushLight(pVCpu, cbInstr);
    2676 #endif
    2677     return iemRegFinishNoFlags(pVCpu, rcNormal);
    2678 }
    2679 
    2680 
    2681 /**
    2682  * Adds a 16-bit signed jump offset to RIP from 64-bit code.
    2683  *
    2684  * @returns Strict VBox status code.
    2685  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    2686  * @param   cbInstr             Instruction size.
    2687  * @param   offNextInstr        The offset of the next instruction.
    2688  * @param   rcNormal            VINF_SUCCESS to continue TB.
    2689  *                              VINF_IEM_REEXEC_BREAK to force TB exit when
    2690  *                              taking the wrong conditional branhc.
    2691  */
    2692 DECL_FORCE_INLINE(VBOXSTRICTRC) iemRegRip64RelativeJumpS16AndFinishClearingRF(PVMCPUCC pVCpu, uint8_t cbInstr,
    2693                                                                               int16_t offNextInstr, int rcNormal) RT_NOEXCEPT
    2694 {
    2695     Assert(IEM_IS_64BIT_CODE(pVCpu));
    2696 
    2697     pVCpu->cpum.GstCtx.rip = (uint16_t)(pVCpu->cpum.GstCtx.ip + cbInstr + offNextInstr);
    2698 
    2699 #ifndef IEM_WITH_CODE_TLB
    2700     iemOpcodeFlushLight(pVCpu, cbInstr);
    2701 #endif
    2702 
    2703     /*
    2704      * Clear RF and finish the instruction (maybe raise #DB).
    2705      */
    2706     return iemRegFinishClearingRF(pVCpu, rcNormal);
    2707 }
    2708 
    2709 
    2710 /**
    2711  * Adds a 16-bit signed jump offset to EIP from 16-bit or 32-bit code.
    2712  *
    2713  * May raise a \#GP(0) if the new RIP is non-canonical or outside the code
    2714  * segment limit.
    2715  *
    2716  * @returns Strict VBox status code.
    2717  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    2718  * @param   cbInstr             Instruction size.
    2719  * @param   offNextInstr        The offset of the next instruction.
    2720  * @param   rcNormal            VINF_SUCCESS to continue TB.
    2721  *                              VINF_IEM_REEXEC_BREAK to force TB exit when
    2722  *                              taking the wrong conditional branhc.
    2723  *
    2724  * @note    This is also used by 16-bit code in pre-386 mode, as the code is
    2725  *          identical.
    2726  */
    2727 DECL_FORCE_INLINE(VBOXSTRICTRC) iemRegEip32RelativeJumpS16AndFinishClearingRF(PVMCPUCC pVCpu, uint8_t cbInstr,
    2728                                                                               int16_t offNextInstr, int rcNormal) RT_NOEXCEPT
    2729 {
    2730     Assert(!IEM_IS_64BIT_CODE(pVCpu));
    2731 
    2732     uint16_t const uNewIp = pVCpu->cpum.GstCtx.ip + cbInstr + offNextInstr;
    2733     if (RT_LIKELY(uNewIp <= pVCpu->cpum.GstCtx.cs.u32Limit))
    2734         pVCpu->cpum.GstCtx.rip = uNewIp;
    2735     else
    2736         return iemRaiseGeneralProtectionFault0(pVCpu);
    2737 
    2738 #ifndef IEM_WITH_CODE_TLB
    2739     iemOpcodeFlushLight(pVCpu, cbInstr);
    2740 #endif
    2741 
    2742     /*
    2743      * Clear RF and finish the instruction (maybe raise #DB).
    2744      */
    2745     return iemRegFinishClearingRF(pVCpu, rcNormal);
    2746 }
    2747 
    2748 
    2749 /**
    2750  * Adds a 16-bit signed jump offset to EIP from FLAT 32-bit code.
    2751  *
    2752  * May raise a \#GP(0) if the new RIP is non-canonical or outside the code
    2753  * segment limit.
    2754  *
    2755  * @returns Strict VBox status code.
    2756  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    2757  * @param   cbInstr             Instruction size.
    2758  * @param   offNextInstr        The offset of the next instruction.
    2759  * @param   rcNormal            VINF_SUCCESS to continue TB.
    2760  *                              VINF_IEM_REEXEC_BREAK to force TB exit when
    2761  *                              taking the wrong conditional branhc.
    2762  *
    2763  * @note    This is also used by 16-bit code in pre-386 mode, as the code is
    2764  *          identical.
    2765  */
    2766 DECL_FORCE_INLINE(VBOXSTRICTRC) iemRegEip32RelativeJumpS16FlatAndFinishClearingRF(PVMCPUCC pVCpu, uint8_t cbInstr,
    2767                                                                                   int16_t offNextInstr, int rcNormal) RT_NOEXCEPT
    2768 {
    2769     Assert(!IEM_IS_64BIT_CODE(pVCpu));
    2770 
    2771     uint16_t const uNewIp = pVCpu->cpum.GstCtx.ip + cbInstr + offNextInstr;
    2772     pVCpu->cpum.GstCtx.rip = uNewIp;
    2773 
    2774 #ifndef IEM_WITH_CODE_TLB
    2775     iemOpcodeFlushLight(pVCpu, cbInstr);
    2776 #endif
    2777 
    2778     /*
    2779      * Clear RF and finish the instruction (maybe raise #DB).
    2780      */
    2781     return iemRegFinishClearingRF(pVCpu, rcNormal);
    2782 }
    2783 
    2784 
    2785 /**
    2786  * Adds a 16-bit signed jump offset to RIP from 64-bit code, no checking or
    2787  * clearing of flags.
    2788  *
    2789  * @returns Strict VBox status code.
    2790  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    2791  * @param   cbInstr             Instruction size.
    2792  * @param   offNextInstr        The offset of the next instruction.
    2793  * @param   rcNormal            VINF_SUCCESS to continue TB.
    2794  *                              VINF_IEM_REEXEC_BREAK to force TB exit when
    2795  *                              taking the wrong conditional branhc.
    2796  */
    2797 DECL_FORCE_INLINE(VBOXSTRICTRC) iemRegRip64RelativeJumpS16AndFinishNoFlags(PVMCPUCC pVCpu, uint8_t cbInstr,
    2798                                                                            int16_t offNextInstr, int rcNormal) RT_NOEXCEPT
    2799 {
    2800     Assert(IEM_IS_64BIT_CODE(pVCpu));
    2801 
    2802     pVCpu->cpum.GstCtx.rip = (uint16_t)(pVCpu->cpum.GstCtx.ip + cbInstr + offNextInstr);
    2803 
    2804 #ifndef IEM_WITH_CODE_TLB
    2805     iemOpcodeFlushLight(pVCpu, cbInstr);
    2806 #endif
    2807     return iemRegFinishNoFlags(pVCpu, rcNormal);
    2808 }
    2809 
    2810 
    2811 /**
    2812  * Adds a 16-bit signed jump offset to EIP from 16-bit or 32-bit code,
    2813  * no checking or clearing of flags.
    2814  *
    2815  * May raise a \#GP(0) if the new RIP is non-canonical or outside the code
    2816  * segment limit.
    2817  *
    2818  * @returns Strict VBox status code.
    2819  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    2820  * @param   cbInstr             Instruction size.
    2821  * @param   offNextInstr        The offset of the next instruction.
    2822  * @param   rcNormal            VINF_SUCCESS to continue TB.
    2823  *                              VINF_IEM_REEXEC_BREAK to force TB exit when
    2824  *                              taking the wrong conditional branhc.
    2825  *
    2826  * @note    This is also used by 16-bit code in pre-386 mode, as the code is
    2827  *          identical.
    2828  */
    2829 DECL_FORCE_INLINE(VBOXSTRICTRC) iemRegEip32RelativeJumpS16AndFinishNoFlags(PVMCPUCC pVCpu, uint8_t cbInstr,
    2830                                                                            int16_t offNextInstr, int rcNormal) RT_NOEXCEPT
    2831 {
    2832     Assert(!IEM_IS_64BIT_CODE(pVCpu));
    2833 
    2834     uint16_t const uNewIp = pVCpu->cpum.GstCtx.ip + cbInstr + offNextInstr;
    2835     if (RT_LIKELY(uNewIp <= pVCpu->cpum.GstCtx.cs.u32Limit))
    2836         pVCpu->cpum.GstCtx.rip = uNewIp;
    2837     else
    2838         return iemRaiseGeneralProtectionFault0(pVCpu);
    2839 
    2840 #ifndef IEM_WITH_CODE_TLB
    2841     iemOpcodeFlushLight(pVCpu, cbInstr);
    2842 #endif
    2843     return iemRegFinishNoFlags(pVCpu, rcNormal);
    2844 }
    2845 
    2846 
    2847 /**
    2848  * Adds a 16-bit signed jump offset to EIP from FLAT 32-bit code, no checking or
    2849  * clearing of flags.
    2850  *
    2851  * May raise a \#GP(0) if the new RIP is non-canonical or outside the code
    2852  * segment limit.
    2853  *
    2854  * @returns Strict VBox status code.
    2855  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    2856  * @param   cbInstr             Instruction size.
    2857  * @param   offNextInstr        The offset of the next instruction.
    2858  * @param   rcNormal            VINF_SUCCESS to continue TB.
    2859  *                              VINF_IEM_REEXEC_BREAK to force TB exit when
    2860  *                              taking the wrong conditional branhc.
    2861  *
    2862  * @note    This is also used by 16-bit code in pre-386 mode, as the code is
    2863  *          identical.
    2864  */
    2865 DECL_FORCE_INLINE(VBOXSTRICTRC) iemRegEip32RelativeJumpS16FlatAndFinishNoFlags(PVMCPUCC pVCpu, uint8_t cbInstr,
    2866                                                                                int16_t offNextInstr, int rcNormal) RT_NOEXCEPT
    2867 {
    2868     Assert(!IEM_IS_64BIT_CODE(pVCpu));
    2869 
    2870     uint16_t const uNewIp = pVCpu->cpum.GstCtx.ip + cbInstr + offNextInstr;
    2871     pVCpu->cpum.GstCtx.rip = uNewIp;
    2872 
    2873 #ifndef IEM_WITH_CODE_TLB
    2874     iemOpcodeFlushLight(pVCpu, cbInstr);
    2875 #endif
    2876     return iemRegFinishNoFlags(pVCpu, rcNormal);
    2877 }
    2878 
    2879 
    2880 /**
    2881  * Adds a 32-bit signed jump offset to RIP from 64-bit code.
    2882  *
    2883  * May raise a \#GP(0) if the new RIP is non-canonical or outside the code
    2884  * segment limit.
    2885  *
    2886  * We ASSUME that the effective operand size is 64-bit here, as 16-bit is the
    2887  * only alternative for relative jumps in 64-bit code and that is already
    2888  * handled in the decoder stage.
    2889  *
    2890  * @returns Strict VBox status code.
    2891  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    2892  * @param   cbInstr             Instruction size.
    2893  * @param   offNextInstr        The offset of the next instruction.
    2894  * @param   rcNormal            VINF_SUCCESS to continue TB.
    2895  *                              VINF_IEM_REEXEC_BREAK to force TB exit when
    2896  *                              taking the wrong conditional branhc.
    2897  */
    2898 DECL_FORCE_INLINE(VBOXSTRICTRC) iemRegRip64RelativeJumpS32AndFinishClearingRF(PVMCPUCC pVCpu, uint8_t cbInstr,
    2899                                                                               int32_t offNextInstr, int rcNormal) RT_NOEXCEPT
    2900 {
    2901     Assert(IEM_IS_64BIT_CODE(pVCpu));
    2902 
    2903     uint64_t const uNewRip = pVCpu->cpum.GstCtx.rip + cbInstr + (int64_t)offNextInstr;
    2904     if (RT_LIKELY(IEM_IS_CANONICAL(uNewRip)))
    2905         pVCpu->cpum.GstCtx.rip = uNewRip;
    2906     else
    2907         return iemRaiseGeneralProtectionFault0(pVCpu);
    2908 
    2909 #ifndef IEM_WITH_CODE_TLB
    2910     iemOpcodeFlushLight(pVCpu, cbInstr);
    2911 #endif
    2912 
    2913     /*
    2914      * Clear RF and finish the instruction (maybe raise #DB).
    2915      */
    2916     return iemRegFinishClearingRF(pVCpu, rcNormal);
    2917 }
    2918 
    2919 
    2920 /**
    2921  * Adds a 32-bit signed jump offset to RIP from 64-bit code when the caller is
    2922  * sure the target is in the same page.
    2923  *
    2924  * May raise a \#GP(0) if the new RIP is non-canonical or outside the code
    2925  * segment limit.
    2926  *
    2927  * We ASSUME that the effective operand size is 64-bit here, as 16-bit is the
    2928  * only alternative for relative jumps in 64-bit code and that is already
    2929  * handled in the decoder stage.
    2930  *
    2931  * @returns Strict VBox status code.
    2932  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    2933  * @param   cbInstr             Instruction size.
    2934  * @param   offNextInstr        The offset of the next instruction.
    2935  * @param   rcNormal            VINF_SUCCESS to continue TB.
    2936  *                              VINF_IEM_REEXEC_BREAK to force TB exit when
    2937  *                              taking the wrong conditional branhc.
    2938  */
    2939 DECL_FORCE_INLINE(VBOXSTRICTRC)
    2940 iemRegRip64RelativeJumpS32IntraPgAndFinishClearingRF(PVMCPUCC pVCpu, uint8_t cbInstr,
    2941                                                      int32_t offNextInstr, int rcNormal) RT_NOEXCEPT
    2942 {
    2943     Assert(IEM_IS_64BIT_CODE(pVCpu));
    2944 
    2945     uint64_t const uNewRip = pVCpu->cpum.GstCtx.rip + cbInstr + (int64_t)offNextInstr;
    2946     Assert((pVCpu->cpum.GstCtx.rip >> GUEST_PAGE_SHIFT) == (uNewRip >> GUEST_PAGE_SHIFT));
    2947     pVCpu->cpum.GstCtx.rip = uNewRip;
    2948 
    2949 #ifndef IEM_WITH_CODE_TLB
    2950     iemOpcodeFlushLight(pVCpu, cbInstr);
    2951 #endif
    2952 
    2953     /*
    2954      * Clear RF and finish the instruction (maybe raise #DB).
    2955      */
    2956     return iemRegFinishClearingRF(pVCpu, rcNormal);
    2957 }
    2958 
    2959 
    2960 /**
    2961  * Adds a 32-bit signed jump offset to RIP from 64-bit code.
    2962  *
    2963  * May raise a \#GP(0) if the new RIP is non-canonical or outside the code
    2964  * segment limit.
    2965  *
    2966  * We ASSUME that the effective operand size is 32-bit here, as 16-bit is the
    2967  * only alternative for relative jumps in 32-bit code and that is already
    2968  * handled in the decoder stage.
    2969  *
    2970  * @returns Strict VBox status code.
    2971  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    2972  * @param   cbInstr             Instruction size.
    2973  * @param   offNextInstr        The offset of the next instruction.
    2974  * @param   rcNormal            VINF_SUCCESS to continue TB.
    2975  *                              VINF_IEM_REEXEC_BREAK to force TB exit when
    2976  *                              taking the wrong conditional branhc.
    2977  */
    2978 DECL_FORCE_INLINE(VBOXSTRICTRC) iemRegEip32RelativeJumpS32AndFinishClearingRF(PVMCPUCC pVCpu, uint8_t cbInstr,
    2979                                                                               int32_t offNextInstr, int rcNormal) RT_NOEXCEPT
    2980 {
    2981     Assert(!IEM_IS_64BIT_CODE(pVCpu));
    2982     Assert(pVCpu->cpum.GstCtx.rip <= UINT32_MAX);
    2983 
    2984     uint32_t const uNewEip = pVCpu->cpum.GstCtx.eip + cbInstr + offNextInstr;
    2985     if (RT_LIKELY(uNewEip <= pVCpu->cpum.GstCtx.cs.u32Limit))
    2986         pVCpu->cpum.GstCtx.rip = uNewEip;
    2987     else
    2988         return iemRaiseGeneralProtectionFault0(pVCpu);
    2989 
    2990 #ifndef IEM_WITH_CODE_TLB
    2991     iemOpcodeFlushLight(pVCpu, cbInstr);
    2992 #endif
    2993 
    2994     /*
    2995      * Clear RF and finish the instruction (maybe raise #DB).
    2996      */
    2997     return iemRegFinishClearingRF(pVCpu, rcNormal);
    2998 }
    2999 
    3000 
    3001 /**
    3002  * Adds a 32-bit signed jump offset to RIP from FLAT 32-bit code.
    3003  *
    3004  * May raise a \#GP(0) if the new RIP is non-canonical or outside the code
    3005  * segment limit.
    3006  *
    3007  * We ASSUME that the effective operand size is 32-bit here, as 16-bit is the
    3008  * only alternative for relative jumps in 32-bit code and that is already
    3009  * handled in the decoder stage.
    3010  *
    3011  * @returns Strict VBox status code.
    3012  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    3013  * @param   cbInstr             Instruction size.
    3014  * @param   offNextInstr        The offset of the next instruction.
    3015  * @param   rcNormal            VINF_SUCCESS to continue TB.
    3016  *                              VINF_IEM_REEXEC_BREAK to force TB exit when
    3017  *                              taking the wrong conditional branhc.
    3018  */
    3019 DECL_FORCE_INLINE(VBOXSTRICTRC) iemRegEip32RelativeJumpS32FlatAndFinishClearingRF(PVMCPUCC pVCpu, uint8_t cbInstr,
    3020                                                                                   int32_t offNextInstr, int rcNormal) RT_NOEXCEPT
    3021 {
    3022     Assert(!IEM_IS_64BIT_CODE(pVCpu));
    3023     Assert(pVCpu->cpum.GstCtx.rip <= UINT32_MAX);
    3024 
    3025     uint32_t const uNewEip = pVCpu->cpum.GstCtx.eip + cbInstr + offNextInstr;
    3026     pVCpu->cpum.GstCtx.rip = uNewEip;
    3027 
    3028 #ifndef IEM_WITH_CODE_TLB
    3029     iemOpcodeFlushLight(pVCpu, cbInstr);
    3030 #endif
    3031 
    3032     /*
    3033      * Clear RF and finish the instruction (maybe raise #DB).
    3034      */
    3035     return iemRegFinishClearingRF(pVCpu, rcNormal);
    3036 }
    3037 
    3038 
    3039 
    3040 /**
    3041  * Adds a 32-bit signed jump offset to RIP from 64-bit code, no checking or
    3042  * clearing of flags.
    3043  *
    3044  * May raise a \#GP(0) if the new RIP is non-canonical or outside the code
    3045  * segment limit.
    3046  *
    3047  * We ASSUME that the effective operand size is 64-bit here, as 16-bit is the
    3048  * only alternative for relative jumps in 64-bit code and that is already
    3049  * handled in the decoder stage.
    3050  *
    3051  * @returns Strict VBox status code.
    3052  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    3053  * @param   cbInstr             Instruction size.
    3054  * @param   offNextInstr        The offset of the next instruction.
    3055  * @param   rcNormal            VINF_SUCCESS to continue TB.
    3056  *                              VINF_IEM_REEXEC_BREAK to force TB exit when
    3057  *                              taking the wrong conditional branhc.
    3058  */
    3059 DECL_FORCE_INLINE(VBOXSTRICTRC) iemRegRip64RelativeJumpS32AndFinishNoFlags(PVMCPUCC pVCpu, uint8_t cbInstr,
    3060                                                                            int32_t offNextInstr, int rcNormal) RT_NOEXCEPT
    3061 {
    3062     Assert(IEM_IS_64BIT_CODE(pVCpu));
    3063 
    3064     uint64_t const uNewRip = pVCpu->cpum.GstCtx.rip + cbInstr + (int64_t)offNextInstr;
    3065     if (RT_LIKELY(IEM_IS_CANONICAL(uNewRip)))
    3066         pVCpu->cpum.GstCtx.rip = uNewRip;
    3067     else
    3068         return iemRaiseGeneralProtectionFault0(pVCpu);
    3069 
    3070 #ifndef IEM_WITH_CODE_TLB
    3071     iemOpcodeFlushLight(pVCpu, cbInstr);
    3072 #endif
    3073     return iemRegFinishNoFlags(pVCpu, rcNormal);
    3074 }
    3075 
    3076 
    3077 /**
    3078  * Adds a 32-bit signed jump offset to RIP from 64-bit code when the caller is
    3079  * sure it stays within the same page, no checking or clearing of flags.
    3080  *
    3081  * May raise a \#GP(0) if the new RIP is non-canonical or outside the code
    3082  * segment limit.
    3083  *
    3084  * We ASSUME that the effective operand size is 64-bit here, as 16-bit is the
    3085  * only alternative for relative jumps in 64-bit code and that is already
    3086  * handled in the decoder stage.
    3087  *
    3088  * @returns Strict VBox status code.
    3089  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    3090  * @param   cbInstr             Instruction size.
    3091  * @param   offNextInstr        The offset of the next instruction.
    3092  * @param   rcNormal            VINF_SUCCESS to continue TB.
    3093  *                              VINF_IEM_REEXEC_BREAK to force TB exit when
    3094  *                              taking the wrong conditional branhc.
    3095  */
    3096 DECL_FORCE_INLINE(VBOXSTRICTRC)
    3097 iemRegRip64RelativeJumpS32IntraPgAndFinishNoFlags(PVMCPUCC pVCpu, uint8_t cbInstr, int32_t offNextInstr, int rcNormal) RT_NOEXCEPT
    3098 {
    3099     Assert(IEM_IS_64BIT_CODE(pVCpu));
    3100 
    3101     uint64_t const uNewRip = pVCpu->cpum.GstCtx.rip + cbInstr + (int64_t)offNextInstr;
    3102     Assert((pVCpu->cpum.GstCtx.rip >> GUEST_PAGE_SHIFT) == (uNewRip >> GUEST_PAGE_SHIFT));
    3103     pVCpu->cpum.GstCtx.rip = uNewRip;
    3104 
    3105 #ifndef IEM_WITH_CODE_TLB
    3106     iemOpcodeFlushLight(pVCpu, cbInstr);
    3107 #endif
    3108     return iemRegFinishNoFlags(pVCpu, rcNormal);
    3109 }
    3110 
    3111 
    3112 /**
    3113  * Adds a 32-bit signed jump offset to RIP from 32-bit code, no checking or
    3114  * clearing of flags.
    3115  *
    3116  * May raise a \#GP(0) if the new RIP is non-canonical or outside the code
    3117  * segment limit.
    3118  *
    3119  * We ASSUME that the effective operand size is 32-bit here, as 16-bit is the
    3120  * only alternative for relative jumps in 32-bit code and that is already
    3121  * handled in the decoder stage.
    3122  *
    3123  * @returns Strict VBox status code.
    3124  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    3125  * @param   cbInstr             Instruction size.
    3126  * @param   offNextInstr        The offset of the next instruction.
    3127  * @param   rcNormal            VINF_SUCCESS to continue TB.
    3128  *                              VINF_IEM_REEXEC_BREAK to force TB exit when
    3129  *                              taking the wrong conditional branhc.
    3130  */
    3131 DECL_FORCE_INLINE(VBOXSTRICTRC) iemRegEip32RelativeJumpS32AndFinishNoFlags(PVMCPUCC pVCpu, uint8_t cbInstr,
    3132                                                                            int32_t offNextInstr, int rcNormal) RT_NOEXCEPT
    3133 {
    3134     Assert(!IEM_IS_64BIT_CODE(pVCpu));
    3135     Assert(pVCpu->cpum.GstCtx.rip <= UINT32_MAX);
    3136 
    3137     uint32_t const uNewEip = pVCpu->cpum.GstCtx.eip + cbInstr + offNextInstr;
    3138     if (RT_LIKELY(uNewEip <= pVCpu->cpum.GstCtx.cs.u32Limit))
    3139         pVCpu->cpum.GstCtx.rip = uNewEip;
    3140     else
    3141         return iemRaiseGeneralProtectionFault0(pVCpu);
    3142 
    3143 #ifndef IEM_WITH_CODE_TLB
    3144     iemOpcodeFlushLight(pVCpu, cbInstr);
    3145 #endif
    3146     return iemRegFinishNoFlags(pVCpu, rcNormal);
    3147 }
    3148 
    3149 
    3150 /**
    3151  * Adds a 32-bit signed jump offset to RIP from FLAT 32-bit code, no checking or
    3152  * clearing of flags.
    3153  *
    3154  * May raise a \#GP(0) if the new RIP is non-canonical or outside the code
    3155  * segment limit.
    3156  *
    3157  * We ASSUME that the effective operand size is 32-bit here, as 16-bit is the
    3158  * only alternative for relative jumps in 32-bit code and that is already
    3159  * handled in the decoder stage.
    3160  *
    3161  * @returns Strict VBox status code.
    3162  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    3163  * @param   cbInstr             Instruction size.
    3164  * @param   offNextInstr        The offset of the next instruction.
    3165  * @param   rcNormal            VINF_SUCCESS to continue TB.
    3166  *                              VINF_IEM_REEXEC_BREAK to force TB exit when
    3167  *                              taking the wrong conditional branhc.
    3168  */
    3169 DECL_FORCE_INLINE(VBOXSTRICTRC) iemRegEip32RelativeJumpS32FlatAndFinishNoFlags(PVMCPUCC pVCpu, uint8_t cbInstr,
    3170                                                                                int32_t offNextInstr, int rcNormal) RT_NOEXCEPT
    3171 {
    3172     Assert(!IEM_IS_64BIT_CODE(pVCpu));
    3173     Assert(pVCpu->cpum.GstCtx.rip <= UINT32_MAX);
    3174 
    3175     uint32_t const uNewEip = pVCpu->cpum.GstCtx.eip + cbInstr + offNextInstr;
    3176     pVCpu->cpum.GstCtx.rip = uNewEip;
    3177 
    3178 #ifndef IEM_WITH_CODE_TLB
    3179     iemOpcodeFlushLight(pVCpu, cbInstr);
    3180 #endif
    3181     return iemRegFinishNoFlags(pVCpu, rcNormal);
    3182 }
    3183 
    3184 
    3185 /**
    3186  * Extended version of iemFinishInstructionWithFlagsSet that goes with
    3187  * iemRegAddToRipAndFinishingClearingRfEx.
    3188  *
    3189  * See iemFinishInstructionWithFlagsSet() for details.
    3190  */
    3191 static VBOXSTRICTRC iemFinishInstructionWithTfSet(PVMCPUCC pVCpu) RT_NOEXCEPT
    3192 {
    3193     /*
    3194      * Raise a #DB.
    3195      */
    3196     IEM_CTX_IMPORT_RET(pVCpu, CPUMCTX_EXTRN_DR6);
    3197     pVCpu->cpum.GstCtx.dr[6] &= ~X86_DR6_B_MASK;
    3198     pVCpu->cpum.GstCtx.dr[6] |= X86_DR6_BS
    3199                              | (   (pVCpu->cpum.GstCtx.eflags.uBoth & CPUMCTX_DBG_HIT_DRX_MASK_NONSILENT)
    3200                                 >> CPUMCTX_DBG_HIT_DRX_SHIFT);
    3201     /** @todo Do we set all pending \#DB events, or just one? */
    3202     LogFlowFunc(("Guest #DB fired at %04X:%016llX: DR6=%08X, RFLAGS=%16RX64 (popf)\n",
    3203                  pVCpu->cpum.GstCtx.cs.Sel, pVCpu->cpum.GstCtx.rip, (unsigned)pVCpu->cpum.GstCtx.dr[6],
    3204                  pVCpu->cpum.GstCtx.rflags.uBoth));
    3205     pVCpu->cpum.GstCtx.eflags.uBoth &= ~(X86_EFL_RF | CPUMCTX_INHIBIT_SHADOW | CPUMCTX_DBG_HIT_DRX_MASK | CPUMCTX_DBG_DBGF_MASK);
    3206     return iemRaiseDebugException(pVCpu);
    3207 }
    3208 
    3209 
    3210 /**
    3211  * Extended version of iemRegAddToRipAndFinishingClearingRF for use by POPF and
    3212  * others potentially updating EFLAGS.TF.
    3213  *
    3214  * The single step event must be generated using the TF value at the start of
    3215  * the instruction, not the new value set by it.
    3216  *
    3217  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    3218  * @param   cbInstr             The number of bytes to add.
    3219  * @param   fEflOld             The EFLAGS at the start of the instruction
    3220  *                              execution.
    3221  */
    3222 DECLINLINE(VBOXSTRICTRC) iemRegAddToRipAndFinishingClearingRfEx(PVMCPUCC pVCpu, uint8_t cbInstr, uint32_t fEflOld) RT_NOEXCEPT
    3223 {
    3224     iemRegAddToRip(pVCpu, cbInstr);
    3225     if (!(fEflOld & X86_EFL_TF))
    3226     {
    3227         /* Specialized iemRegFinishClearingRF edition here that doesn't check X86_EFL_TF. */
    3228         AssertCompile(CPUMCTX_INHIBIT_SHADOW < UINT32_MAX);
    3229         if (RT_LIKELY(!(  pVCpu->cpum.GstCtx.eflags.uBoth
    3230                         & (X86_EFL_RF | CPUMCTX_INHIBIT_SHADOW | CPUMCTX_DBG_HIT_DRX_MASK | CPUMCTX_DBG_DBGF_MASK)) ))
    3231             return VINF_SUCCESS;
    3232         return iemFinishInstructionWithFlagsSet<0 /*a_fTF*/>(pVCpu, VINF_SUCCESS); /* TF=0, so ignore it.  */
    3233     }
    3234     return iemFinishInstructionWithTfSet(pVCpu);
    3235 }
    3236 
    3237 
    3238 #ifndef IEM_WITH_OPAQUE_DECODER_STATE
    3239 /**
    3240  * Updates the RIP/EIP/IP to point to the next instruction and clears EFLAGS.RF.
    3241  *
    3242  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    3243  */
    3244 DECLINLINE(VBOXSTRICTRC) iemRegUpdateRipAndFinishClearingRF(PVMCPUCC pVCpu) RT_NOEXCEPT
    3245 {
    3246     return iemRegAddToRipAndFinishingClearingRF(pVCpu, IEM_GET_INSTR_LEN(pVCpu));
    3247 }
    3248 #endif
    3249 
    3250 
    3251 #ifdef IEM_WITH_CODE_TLB
    3252 
    3253 /**
    3254  * Performs a near jump to the specified address, no checking or clearing of
    3255  * flags
    3256  *
    3257  * May raise a \#GP(0) if the new IP outside the code segment limit.
    3258  *
    3259  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    3260  * @param   uNewIp              The new IP value.
    3261  */
    3262 DECLINLINE(VBOXSTRICTRC) iemRegRipJumpU16AndFinishNoFlags(PVMCPUCC pVCpu, uint16_t uNewIp) RT_NOEXCEPT
    3263 {
    3264     if (RT_LIKELY(   uNewIp <= pVCpu->cpum.GstCtx.cs.u32Limit
    3265                   || IEM_IS_64BIT_CODE(pVCpu) /* no limit checks in 64-bit mode */))
    3266         pVCpu->cpum.GstCtx.rip = uNewIp;
    3267     else
    3268         return iemRaiseGeneralProtectionFault0(pVCpu);
    3269     return iemRegFinishNoFlags(pVCpu, VINF_SUCCESS);
    3270 }
    3271 
    3272 
    3273 /**
    3274  * Performs a near jump to the specified address, no checking or clearing of
    3275  * flags
    3276  *
    3277  * May raise a \#GP(0) if the new RIP is outside the code segment limit.
    3278  *
    3279  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    3280  * @param   uNewEip             The new EIP value.
    3281  */
    3282 DECLINLINE(VBOXSTRICTRC) iemRegRipJumpU32AndFinishNoFlags(PVMCPUCC pVCpu, uint32_t uNewEip) RT_NOEXCEPT
    3283 {
    3284     Assert(pVCpu->cpum.GstCtx.rip <= UINT32_MAX);
    3285     Assert(!IEM_IS_64BIT_CODE(pVCpu));
    3286     if (RT_LIKELY(uNewEip <= pVCpu->cpum.GstCtx.cs.u32Limit))
    3287         pVCpu->cpum.GstCtx.rip = uNewEip;
    3288     else
    3289         return iemRaiseGeneralProtectionFault0(pVCpu);
    3290     return iemRegFinishNoFlags(pVCpu, VINF_SUCCESS);
    3291 }
    3292 
    3293 
    3294 /**
    3295  * Performs a near jump to the specified address, no checking or clearing of
    3296  * flags.
    3297  *
    3298  * May raise a \#GP(0) if the new RIP is non-canonical or outside the code
    3299  * segment limit.
    3300  *
    3301  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    3302  * @param   uNewRip             The new RIP value.
    3303  */
    3304 DECLINLINE(VBOXSTRICTRC) iemRegRipJumpU64AndFinishNoFlags(PVMCPUCC pVCpu, uint64_t uNewRip) RT_NOEXCEPT
    3305 {
    3306     Assert(IEM_IS_64BIT_CODE(pVCpu));
    3307     if (RT_LIKELY(IEM_IS_CANONICAL(uNewRip)))
    3308         pVCpu->cpum.GstCtx.rip = uNewRip;
    3309     else
    3310         return iemRaiseGeneralProtectionFault0(pVCpu);
    3311     return iemRegFinishNoFlags(pVCpu, VINF_SUCCESS);
    3312 }
    3313 
    3314 #endif /* IEM_WITH_CODE_TLB */
    3315 
    3316 /**
    3317  * Performs a near jump to the specified address.
    3318  *
    3319  * May raise a \#GP(0) if the new IP outside the code segment limit.
    3320  *
    3321  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    3322  * @param   uNewIp              The new IP value.
    3323  * @param   cbInstr             The instruction length, for flushing in the non-TLB case.
    3324  */
    3325 DECLINLINE(VBOXSTRICTRC) iemRegRipJumpU16AndFinishClearingRF(PVMCPUCC pVCpu, uint16_t uNewIp, uint8_t cbInstr) RT_NOEXCEPT
    3326 {
    3327     if (RT_LIKELY(   uNewIp <= pVCpu->cpum.GstCtx.cs.u32Limit
    3328                   || IEM_IS_64BIT_CODE(pVCpu) /* no limit checks in 64-bit mode */))
    3329         pVCpu->cpum.GstCtx.rip = uNewIp;
    3330     else
    3331         return iemRaiseGeneralProtectionFault0(pVCpu);
    3332 #ifndef IEM_WITH_CODE_TLB
    3333     iemOpcodeFlushLight(pVCpu, cbInstr);
    3334 #else
    3335     RT_NOREF_PV(cbInstr);
    3336 #endif
    3337     return iemRegFinishClearingRF(pVCpu, VINF_SUCCESS);
    3338 }
    3339 
    3340 
    3341 /**
    3342  * Performs a near jump to the specified address.
    3343  *
    3344  * May raise a \#GP(0) if the new RIP is outside the code segment limit.
    3345  *
    3346  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    3347  * @param   uNewEip             The new EIP value.
    3348  * @param   cbInstr             The instruction length, for flushing in the non-TLB case.
    3349  */
    3350 DECLINLINE(VBOXSTRICTRC) iemRegRipJumpU32AndFinishClearingRF(PVMCPUCC pVCpu, uint32_t uNewEip, uint8_t cbInstr) RT_NOEXCEPT
    3351 {
    3352     Assert(pVCpu->cpum.GstCtx.rip <= UINT32_MAX);
    3353     Assert(!IEM_IS_64BIT_CODE(pVCpu));
    3354     if (RT_LIKELY(uNewEip <= pVCpu->cpum.GstCtx.cs.u32Limit))
    3355         pVCpu->cpum.GstCtx.rip = uNewEip;
    3356     else
    3357         return iemRaiseGeneralProtectionFault0(pVCpu);
    3358 #ifndef IEM_WITH_CODE_TLB
    3359     iemOpcodeFlushLight(pVCpu, cbInstr);
    3360 #else
    3361     RT_NOREF_PV(cbInstr);
    3362 #endif
    3363     return iemRegFinishClearingRF(pVCpu, VINF_SUCCESS);
    3364 }
    3365 
    3366 
    3367 /**
    3368  * Performs a near jump to the specified address.
    3369  *
    3370  * May raise a \#GP(0) if the new RIP is non-canonical or outside the code
    3371  * segment limit.
    3372  *
    3373  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    3374  * @param   uNewRip             The new RIP value.
    3375  * @param   cbInstr             The instruction length, for flushing in the non-TLB case.
    3376  */
    3377 DECLINLINE(VBOXSTRICTRC) iemRegRipJumpU64AndFinishClearingRF(PVMCPUCC pVCpu, uint64_t uNewRip, uint8_t cbInstr) RT_NOEXCEPT
    3378 {
    3379     Assert(IEM_IS_64BIT_CODE(pVCpu));
    3380     if (RT_LIKELY(IEM_IS_CANONICAL(uNewRip)))
    3381         pVCpu->cpum.GstCtx.rip = uNewRip;
    3382     else
    3383         return iemRaiseGeneralProtectionFault0(pVCpu);
    3384 #ifndef IEM_WITH_CODE_TLB
    3385     iemOpcodeFlushLight(pVCpu, cbInstr);
    3386 #else
    3387     RT_NOREF_PV(cbInstr);
    3388 #endif
    3389     return iemRegFinishClearingRF(pVCpu, VINF_SUCCESS);
    3390 }
    3391 
    3392 
    3393 /**
    3394  * Implements a 16-bit relative call, no checking or clearing of
    3395  * flags.
    3396  *
    3397  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    3398  * @param   cbInstr             The instruction length.
    3399  * @param   offDisp             The 16-bit displacement.
    3400  */
    3401 DECL_FORCE_INLINE(VBOXSTRICTRC)
    3402 iemRegRipRelativeCallS16AndFinishNoFlags(PVMCPUCC pVCpu, uint8_t cbInstr, int16_t offDisp) RT_NOEXCEPT
    3403 {
    3404     uint16_t const uOldIp = pVCpu->cpum.GstCtx.ip + cbInstr;
    3405     uint16_t const uNewIp = uOldIp + offDisp;
    3406     if (   uNewIp <= pVCpu->cpum.GstCtx.cs.u32Limit
    3407         || IEM_IS_64BIT_CODE(pVCpu) /* no CS limit checks in 64-bit mode */)
    3408     { /* likely */ }
    3409     else
    3410         return iemRaiseGeneralProtectionFault0(pVCpu);
    3411 
    3412     VBOXSTRICTRC rcStrict = iemMemStackPushU16(pVCpu, uOldIp);
    3413     if (rcStrict == VINF_SUCCESS)
    3414     { /* likely */ }
    3415     else
    3416         return rcStrict;
    3417 
    3418     pVCpu->cpum.GstCtx.rip = uNewIp;
    3419 #ifndef IEM_WITH_CODE_TLB
    3420     iemOpcodeFlushLight(pVCpu, cbInstr);
    3421 #endif
    3422     return iemRegFinishNoFlags(pVCpu, VINF_SUCCESS);
    3423 }
    3424 
    3425 
    3426 /**
    3427  * Implements a 16-bit relative call.
    3428  *
    3429  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    3430  * @param   cbInstr             The instruction length.
    3431  * @param   offDisp             The 16-bit displacement.
    3432  */
    3433 DECL_FORCE_INLINE(VBOXSTRICTRC)
    3434 iemRegRipRelativeCallS16AndFinishClearingRF(PVMCPUCC pVCpu, uint8_t cbInstr, int16_t offDisp) RT_NOEXCEPT
    3435 {
    3436     uint16_t const uOldIp = pVCpu->cpum.GstCtx.ip + cbInstr;
    3437     uint16_t const uNewIp = uOldIp + offDisp;
    3438     if (   uNewIp <= pVCpu->cpum.GstCtx.cs.u32Limit
    3439         || IEM_IS_64BIT_CODE(pVCpu) /* no CS limit checks in 64-bit mode */)
    3440     { /* likely */ }
    3441     else
    3442         return iemRaiseGeneralProtectionFault0(pVCpu);
    3443 
    3444     VBOXSTRICTRC rcStrict = iemMemStackPushU16(pVCpu, uOldIp);
    3445     if (rcStrict == VINF_SUCCESS)
    3446     { /* likely */ }
    3447     else
    3448         return rcStrict;
    3449 
    3450     pVCpu->cpum.GstCtx.rip = uNewIp;
    3451 #ifndef IEM_WITH_CODE_TLB
    3452     iemOpcodeFlushLight(pVCpu, cbInstr);
    3453 #endif
    3454     return iemRegFinishClearingRF(pVCpu, VINF_SUCCESS);
    3455 }
    3456 
    3457 
    3458 /**
    3459  * Implements a 32-bit relative call, no checking or clearing of flags.
    3460  *
    3461  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    3462  * @param   cbInstr             The instruction length.
    3463  * @param   offDisp             The 32-bit displacement.
    3464  */
    3465 DECL_FORCE_INLINE(VBOXSTRICTRC)
    3466 iemRegEip32RelativeCallS32AndFinishNoFlags(PVMCPUCC pVCpu, uint8_t cbInstr, int32_t offDisp) RT_NOEXCEPT
    3467 {
    3468     Assert(pVCpu->cpum.GstCtx.rip <= UINT32_MAX); Assert(!IEM_IS_64BIT_CODE(pVCpu));
    3469 
    3470     uint32_t const uOldRip = pVCpu->cpum.GstCtx.eip + cbInstr;
    3471     uint32_t const uNewRip = uOldRip + offDisp;
    3472     if (uNewRip <= pVCpu->cpum.GstCtx.cs.u32Limit)
    3473     { /* likely */ }
    3474     else
    3475         return iemRaiseGeneralProtectionFault0(pVCpu);
    3476 
    3477     VBOXSTRICTRC rcStrict = iemMemStackPushU32(pVCpu, uOldRip);
    3478     if (rcStrict == VINF_SUCCESS)
    3479     { /* likely */ }
    3480     else
    3481         return rcStrict;
    3482 
    3483     pVCpu->cpum.GstCtx.rip = uNewRip;
    3484 #ifndef IEM_WITH_CODE_TLB
    3485     iemOpcodeFlushLight(pVCpu, cbInstr);
    3486 #endif
    3487     return iemRegFinishNoFlags(pVCpu, VINF_SUCCESS);
    3488 }
    3489 
    3490 
    3491 /**
    3492  * Implements a 32-bit relative call.
    3493  *
    3494  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    3495  * @param   cbInstr             The instruction length.
    3496  * @param   offDisp             The 32-bit displacement.
    3497  */
    3498 DECL_FORCE_INLINE(VBOXSTRICTRC)
    3499 iemRegEip32RelativeCallS32AndFinishClearingRF(PVMCPUCC pVCpu, uint8_t cbInstr, int32_t offDisp) RT_NOEXCEPT
    3500 {
    3501     Assert(pVCpu->cpum.GstCtx.rip <= UINT32_MAX); Assert(!IEM_IS_64BIT_CODE(pVCpu));
    3502 
    3503     uint32_t const uOldRip = pVCpu->cpum.GstCtx.eip + cbInstr;
    3504     uint32_t const uNewRip = uOldRip + offDisp;
    3505     if (uNewRip <= pVCpu->cpum.GstCtx.cs.u32Limit)
    3506     { /* likely */ }
    3507     else
    3508         return iemRaiseGeneralProtectionFault0(pVCpu);
    3509 
    3510     VBOXSTRICTRC rcStrict = iemMemStackPushU32(pVCpu, uOldRip);
    3511     if (rcStrict == VINF_SUCCESS)
    3512     { /* likely */ }
    3513     else
    3514         return rcStrict;
    3515 
    3516     pVCpu->cpum.GstCtx.rip = uNewRip;
    3517 #ifndef IEM_WITH_CODE_TLB
    3518     iemOpcodeFlushLight(pVCpu, cbInstr);
    3519 #endif
    3520     return iemRegFinishClearingRF(pVCpu, VINF_SUCCESS);
    3521 }
    3522 
    3523 
    3524 /**
    3525  * Implements a 64-bit relative call, no checking or clearing of flags.
    3526  *
    3527  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    3528  * @param   cbInstr             The instruction length.
    3529  * @param   offDisp             The 64-bit displacement.
    3530  */
    3531 DECL_FORCE_INLINE(VBOXSTRICTRC)
    3532 iemRegRip64RelativeCallS64AndFinishNoFlags(PVMCPUCC pVCpu, uint8_t cbInstr, int64_t offDisp) RT_NOEXCEPT
    3533 {
    3534     uint64_t const uOldRip = pVCpu->cpum.GstCtx.rip + cbInstr;
    3535     uint64_t const uNewRip = uOldRip + (int64_t)offDisp;
    3536     if (IEM_IS_CANONICAL(uNewRip))
    3537     { /* likely */ }
    3538     else
    3539         return iemRaiseNotCanonical(pVCpu);
    3540 
    3541     VBOXSTRICTRC rcStrict = iemMemStackPushU64(pVCpu, uOldRip);
    3542     if (rcStrict == VINF_SUCCESS)
    3543     { /* likely */ }
    3544     else
    3545         return rcStrict;
    3546 
    3547     pVCpu->cpum.GstCtx.rip = uNewRip;
    3548 #ifndef IEM_WITH_CODE_TLB
    3549     iemOpcodeFlushLight(pVCpu, cbInstr);
    3550 #endif
    3551     return iemRegFinishNoFlags(pVCpu, VINF_SUCCESS);
    3552 }
    3553 
    3554 
    3555 /**
    3556  * Implements a 64-bit relative call.
    3557  *
    3558  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    3559  * @param   cbInstr             The instruction length.
    3560  * @param   offDisp             The 64-bit displacement.
    3561  */
    3562 DECL_FORCE_INLINE(VBOXSTRICTRC)
    3563 iemRegRip64RelativeCallS64AndFinishClearingRF(PVMCPUCC pVCpu, uint8_t cbInstr, int64_t offDisp) RT_NOEXCEPT
    3564 {
    3565     uint64_t const uOldRip = pVCpu->cpum.GstCtx.rip + cbInstr;
    3566     uint64_t const uNewRip = uOldRip + (int64_t)offDisp;
    3567     if (IEM_IS_CANONICAL(uNewRip))
    3568     { /* likely */ }
    3569     else
    3570         return iemRaiseNotCanonical(pVCpu);
    3571 
    3572     VBOXSTRICTRC rcStrict = iemMemStackPushU64(pVCpu, uOldRip);
    3573     if (rcStrict == VINF_SUCCESS)
    3574     { /* likely */ }
    3575     else
    3576         return rcStrict;
    3577 
    3578     pVCpu->cpum.GstCtx.rip = uNewRip;
    3579 #ifndef IEM_WITH_CODE_TLB
    3580     iemOpcodeFlushLight(pVCpu, cbInstr);
    3581 #endif
    3582     return iemRegFinishClearingRF(pVCpu, VINF_SUCCESS);
    3583 }
    3584 
    3585 
    3586 /**
    3587  * Implements an 16-bit indirect call, no checking or clearing of
    3588  * flags.
    3589  *
    3590  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    3591  * @param   cbInstr             The instruction length.
    3592  * @param   uNewRip             The new RIP value.
    3593  */
    3594 DECL_FORCE_INLINE(VBOXSTRICTRC)
    3595 iemRegIp16IndirectCallU16AndFinishNoFlags(PVMCPUCC pVCpu, uint8_t cbInstr, uint16_t uNewRip) RT_NOEXCEPT
    3596 {
    3597     uint16_t const uOldRip = pVCpu->cpum.GstCtx.ip + cbInstr;
    3598     if (uNewRip <= pVCpu->cpum.GstCtx.cs.u32Limit)
    3599     { /* likely */ }
    3600     else
    3601         return iemRaiseGeneralProtectionFault0(pVCpu);
    3602 
    3603     VBOXSTRICTRC rcStrict = iemMemStackPushU16(pVCpu, uOldRip);
    3604     if (rcStrict == VINF_SUCCESS)
    3605     { /* likely */ }
    3606     else
    3607         return rcStrict;
    3608 
    3609     pVCpu->cpum.GstCtx.rip = uNewRip;
    3610 #ifndef IEM_WITH_CODE_TLB
    3611     iemOpcodeFlushLight(pVCpu, cbInstr);
    3612 #endif
    3613     return iemRegFinishNoFlags(pVCpu, VINF_SUCCESS);
    3614 }
    3615 
    3616 
    3617 /**
    3618  * Implements an 16-bit indirect call, no checking or clearing of
    3619  * flags.
    3620  *
    3621  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    3622  * @param   cbInstr             The instruction length.
    3623  * @param   uNewRip             The new RIP value.
    3624  */
    3625 DECL_FORCE_INLINE(VBOXSTRICTRC)
    3626 iemRegEip32IndirectCallU16AndFinishNoFlags(PVMCPUCC pVCpu, uint8_t cbInstr, uint16_t uNewRip) RT_NOEXCEPT
    3627 {
    3628     uint16_t const uOldRip = pVCpu->cpum.GstCtx.ip + cbInstr;
    3629     if (uNewRip <= pVCpu->cpum.GstCtx.cs.u32Limit)
    3630     { /* likely */ }
    3631     else
    3632         return iemRaiseGeneralProtectionFault0(pVCpu);
    3633 
    3634     VBOXSTRICTRC rcStrict = iemMemStackPushU16(pVCpu, uOldRip);
    3635     if (rcStrict == VINF_SUCCESS)
    3636     { /* likely */ }
    3637     else
    3638         return rcStrict;
    3639 
    3640     pVCpu->cpum.GstCtx.rip = uNewRip;
    3641 #ifndef IEM_WITH_CODE_TLB
    3642     iemOpcodeFlushLight(pVCpu, cbInstr);
    3643 #endif
    3644     return iemRegFinishNoFlags(pVCpu, VINF_SUCCESS);
    3645 }
    3646 
    3647 
    3648 /**
    3649  * Implements an 16-bit indirect call.
    3650  *
    3651  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    3652  * @param   cbInstr             The instruction length.
    3653  * @param   uNewRip             The new RIP value.
    3654  */
    3655 DECL_FORCE_INLINE(VBOXSTRICTRC)
    3656 iemRegIp16IndirectCallU16AndFinishClearingRF(PVMCPUCC pVCpu, uint8_t cbInstr, uint16_t uNewRip) RT_NOEXCEPT
    3657 {
    3658     uint16_t const uOldRip = pVCpu->cpum.GstCtx.ip + cbInstr;
    3659     if (uNewRip <= pVCpu->cpum.GstCtx.cs.u32Limit)
    3660     { /* likely */ }
    3661     else
    3662         return iemRaiseGeneralProtectionFault0(pVCpu);
    3663 
    3664     VBOXSTRICTRC rcStrict = iemMemStackPushU16(pVCpu, uOldRip);
    3665     if (rcStrict == VINF_SUCCESS)
    3666     { /* likely */ }
    3667     else
    3668         return rcStrict;
    3669 
    3670     pVCpu->cpum.GstCtx.rip = uNewRip;
    3671 #ifndef IEM_WITH_CODE_TLB
    3672     iemOpcodeFlushLight(pVCpu, cbInstr);
    3673 #endif
    3674     return iemRegFinishClearingRF(pVCpu, VINF_SUCCESS);
    3675 }
    3676 
    3677 
    3678 /**
    3679  * Implements an 16-bit indirect call.
    3680  *
    3681  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    3682  * @param   cbInstr             The instruction length.
    3683  * @param   uNewRip             The new RIP value.
    3684  */
    3685 DECL_FORCE_INLINE(VBOXSTRICTRC)
    3686 iemRegEip32IndirectCallU16AndFinishClearingRF(PVMCPUCC pVCpu, uint8_t cbInstr, uint16_t uNewRip) RT_NOEXCEPT
    3687 {
    3688     uint16_t const uOldRip = pVCpu->cpum.GstCtx.ip + cbInstr;
    3689     if (uNewRip <= pVCpu->cpum.GstCtx.cs.u32Limit)
    3690     { /* likely */ }
    3691     else
    3692         return iemRaiseGeneralProtectionFault0(pVCpu);
    3693 
    3694     VBOXSTRICTRC rcStrict = iemMemStackPushU16(pVCpu, uOldRip);
    3695     if (rcStrict == VINF_SUCCESS)
    3696     { /* likely */ }
    3697     else
    3698         return rcStrict;
    3699 
    3700     pVCpu->cpum.GstCtx.rip = uNewRip;
    3701 #ifndef IEM_WITH_CODE_TLB
    3702     iemOpcodeFlushLight(pVCpu, cbInstr);
    3703 #endif
    3704     return iemRegFinishClearingRF(pVCpu, VINF_SUCCESS);
    3705 }
    3706 
    3707 
    3708 /**
    3709  * Implements an 32-bit indirect call, no checking or clearing of
    3710  * flags.
    3711  *
    3712  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    3713  * @param   cbInstr             The instruction length.
    3714  * @param   uNewRip             The new RIP value.
    3715  */
    3716 DECL_FORCE_INLINE(VBOXSTRICTRC)
    3717 iemRegEip32IndirectCallU32AndFinishNoFlags(PVMCPUCC pVCpu, uint8_t cbInstr, uint32_t uNewRip) RT_NOEXCEPT
    3718 {
    3719     uint32_t const uOldRip = pVCpu->cpum.GstCtx.eip + cbInstr;
    3720     if (uNewRip <= pVCpu->cpum.GstCtx.cs.u32Limit)
    3721     { /* likely */ }
    3722     else
    3723         return iemRaiseGeneralProtectionFault0(pVCpu);
    3724 
    3725     VBOXSTRICTRC rcStrict = iemMemStackPushU32(pVCpu, uOldRip);
    3726     if (rcStrict == VINF_SUCCESS)
    3727     { /* likely */ }
    3728     else
    3729         return rcStrict;
    3730 
    3731     pVCpu->cpum.GstCtx.rip = uNewRip;
    3732 #ifndef IEM_WITH_CODE_TLB
    3733     iemOpcodeFlushLight(pVCpu, cbInstr);
    3734 #endif
    3735     return iemRegFinishNoFlags(pVCpu, VINF_SUCCESS);
    3736 }
    3737 
    3738 
    3739 /**
    3740  * Implements an 32-bit indirect call.
    3741  *
    3742  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    3743  * @param   cbInstr             The instruction length.
    3744  * @param   uNewRip             The new RIP value.
    3745  */
    3746 DECL_FORCE_INLINE(VBOXSTRICTRC)
    3747 iemRegEip32IndirectCallU32AndFinishClearingRF(PVMCPUCC pVCpu, uint8_t cbInstr, uint32_t uNewRip) RT_NOEXCEPT
    3748 {
    3749     uint32_t const uOldRip = pVCpu->cpum.GstCtx.eip + cbInstr;
    3750     if (uNewRip <= pVCpu->cpum.GstCtx.cs.u32Limit)
    3751     { /* likely */ }
    3752     else
    3753         return iemRaiseGeneralProtectionFault0(pVCpu);
    3754 
    3755     VBOXSTRICTRC rcStrict = iemMemStackPushU32(pVCpu, uOldRip);
    3756     if (rcStrict == VINF_SUCCESS)
    3757     { /* likely */ }
    3758     else
    3759         return rcStrict;
    3760 
    3761     pVCpu->cpum.GstCtx.rip = uNewRip;
    3762 #ifndef IEM_WITH_CODE_TLB
    3763     iemOpcodeFlushLight(pVCpu, cbInstr);
    3764 #endif
    3765     return iemRegFinishClearingRF(pVCpu, VINF_SUCCESS);
    3766 }
    3767 
    3768 
    3769 /**
    3770  * Implements an 64-bit indirect call, no checking or clearing of
    3771  * flags.
    3772  *
    3773  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    3774  * @param   cbInstr             The instruction length.
    3775  * @param   uNewRip             The new RIP value.
    3776  */
    3777 DECL_FORCE_INLINE(VBOXSTRICTRC)
    3778 iemRegRip64IndirectCallU64AndFinishNoFlags(PVMCPUCC pVCpu, uint8_t cbInstr, uint64_t uNewRip) RT_NOEXCEPT
    3779 {
    3780     uint64_t const uOldRip = pVCpu->cpum.GstCtx.rip + cbInstr;
    3781     if (IEM_IS_CANONICAL(uNewRip))
    3782     { /* likely */ }
    3783     else
    3784         return iemRaiseGeneralProtectionFault0(pVCpu);
    3785 
    3786     VBOXSTRICTRC rcStrict = iemMemStackPushU64(pVCpu, uOldRip);
    3787     if (rcStrict == VINF_SUCCESS)
    3788     { /* likely */ }
    3789     else
    3790         return rcStrict;
    3791 
    3792     pVCpu->cpum.GstCtx.rip = uNewRip;
    3793 #ifndef IEM_WITH_CODE_TLB
    3794     iemOpcodeFlushLight(pVCpu, cbInstr);
    3795 #endif
    3796     return iemRegFinishNoFlags(pVCpu, VINF_SUCCESS);
    3797 }
    3798 
    3799 
    3800 /**
    3801  * Implements an 64-bit indirect call.
    3802  *
    3803  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    3804  * @param   cbInstr             The instruction length.
    3805  * @param   uNewRip             The new RIP value.
    3806  */
    3807 DECL_FORCE_INLINE(VBOXSTRICTRC)
    3808 iemRegRip64IndirectCallU64AndFinishClearingRF(PVMCPUCC pVCpu, uint8_t cbInstr, uint64_t uNewRip) RT_NOEXCEPT
    3809 {
    3810     uint64_t const uOldRip = pVCpu->cpum.GstCtx.rip + cbInstr;
    3811     if (IEM_IS_CANONICAL(uNewRip))
    3812     { /* likely */ }
    3813     else
    3814         return iemRaiseGeneralProtectionFault0(pVCpu);
    3815 
    3816     VBOXSTRICTRC rcStrict = iemMemStackPushU64(pVCpu, uOldRip);
    3817     if (rcStrict == VINF_SUCCESS)
    3818     { /* likely */ }
    3819     else
    3820         return rcStrict;
    3821 
    3822     pVCpu->cpum.GstCtx.rip = uNewRip;
    3823 #ifndef IEM_WITH_CODE_TLB
    3824     iemOpcodeFlushLight(pVCpu, cbInstr);
    3825 #endif
    3826     return iemRegFinishClearingRF(pVCpu, VINF_SUCCESS);
    3827 }
    3828 
    3829 
    3830 
    3831 /**
    3832  * Adds to the stack pointer.
    3833  *
    3834  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    3835  * @param   cbToAdd             The number of bytes to add (8-bit!).
    3836  */
    3837 DECLINLINE(void) iemRegAddToRsp(PVMCPUCC pVCpu, uint8_t cbToAdd) RT_NOEXCEPT
    3838 {
    3839     if (IEM_IS_64BIT_CODE(pVCpu))
    3840         pVCpu->cpum.GstCtx.rsp += cbToAdd;
    3841     else if (pVCpu->cpum.GstCtx.ss.Attr.n.u1DefBig)
    3842         pVCpu->cpum.GstCtx.esp += cbToAdd;
    3843     else
    3844         pVCpu->cpum.GstCtx.sp  += cbToAdd;
    3845 }
    3846 
    3847 
    3848 /**
    3849  * Subtracts from the stack pointer.
    3850  *
    3851  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    3852  * @param   cbToSub             The number of bytes to subtract (8-bit!).
    3853  */
    3854 DECLINLINE(void) iemRegSubFromRsp(PVMCPUCC pVCpu, uint8_t cbToSub) RT_NOEXCEPT
    3855 {
    3856     if (IEM_IS_64BIT_CODE(pVCpu))
    3857         pVCpu->cpum.GstCtx.rsp -= cbToSub;
    3858     else if (pVCpu->cpum.GstCtx.ss.Attr.n.u1DefBig)
    3859         pVCpu->cpum.GstCtx.esp -= cbToSub;
    3860     else
    3861         pVCpu->cpum.GstCtx.sp  -= cbToSub;
    3862 }
    3863 
    3864 
    3865 /**
    3866  * Adds to the temporary stack pointer.
    3867  *
    3868  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    3869  * @param   pTmpRsp             The temporary SP/ESP/RSP to update.
    3870  * @param   cbToAdd             The number of bytes to add (16-bit).
    3871  */
    3872 DECLINLINE(void) iemRegAddToRspEx(PCVMCPU pVCpu, PRTUINT64U pTmpRsp, uint16_t cbToAdd) RT_NOEXCEPT
    3873 {
    3874     if (IEM_IS_64BIT_CODE(pVCpu))
    3875         pTmpRsp->u           += cbToAdd;
    3876     else if (pVCpu->cpum.GstCtx.ss.Attr.n.u1DefBig)
    3877         pTmpRsp->DWords.dw0  += cbToAdd;
    3878     else
    3879         pTmpRsp->Words.w0    += cbToAdd;
    3880 }
    3881 
    3882 
    3883 /**
    3884  * Subtracts from the temporary stack pointer.
    3885  *
    3886  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    3887  * @param   pTmpRsp             The temporary SP/ESP/RSP to update.
    3888  * @param   cbToSub             The number of bytes to subtract.
    3889  * @remarks The @a cbToSub argument *MUST* be 16-bit, iemCImpl_enter is
    3890  *          expecting that.
    3891  */
    3892 DECLINLINE(void) iemRegSubFromRspEx(PCVMCPU pVCpu, PRTUINT64U pTmpRsp, uint16_t cbToSub) RT_NOEXCEPT
    3893 {
    3894     if (IEM_IS_64BIT_CODE(pVCpu))
    3895         pTmpRsp->u          -= cbToSub;
    3896     else if (pVCpu->cpum.GstCtx.ss.Attr.n.u1DefBig)
    3897         pTmpRsp->DWords.dw0 -= cbToSub;
    3898     else
    3899         pTmpRsp->Words.w0   -= cbToSub;
    3900 }
    3901 
    3902 
    3903 /**
    3904  * Calculates the effective stack address for a push of the specified size as
    3905  * well as the new RSP value (upper bits may be masked).
    3906  *
    3907  * @returns Effective stack addressf for the push.
    3908  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    3909  * @param   cbItem              The size of the stack item to pop.
    3910  * @param   puNewRsp            Where to return the new RSP value.
    3911  */
    3912 DECLINLINE(RTGCPTR) iemRegGetRspForPush(PCVMCPU pVCpu, uint8_t cbItem, uint64_t *puNewRsp) RT_NOEXCEPT
    3913 {
    3914     RTUINT64U   uTmpRsp;
    3915     RTGCPTR     GCPtrTop;
    3916     uTmpRsp.u = pVCpu->cpum.GstCtx.rsp;
    3917 
    3918     if (IEM_IS_64BIT_CODE(pVCpu))
    3919         GCPtrTop = uTmpRsp.u            -= cbItem;
    3920     else if (pVCpu->cpum.GstCtx.ss.Attr.n.u1DefBig)
    3921         GCPtrTop = uTmpRsp.DWords.dw0   -= cbItem;
    3922     else
    3923         GCPtrTop = uTmpRsp.Words.w0     -= cbItem;
    3924     *puNewRsp = uTmpRsp.u;
    3925     return GCPtrTop;
    3926 }
    3927 
    3928 
    3929 /**
    3930  * Gets the current stack pointer and calculates the value after a pop of the
    3931  * specified size.
    3932  *
    3933  * @returns Current stack pointer.
    3934  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    3935  * @param   cbItem              The size of the stack item to pop.
    3936  * @param   puNewRsp            Where to return the new RSP value.
    3937  */
    3938 DECLINLINE(RTGCPTR) iemRegGetRspForPop(PCVMCPU pVCpu, uint8_t cbItem, uint64_t *puNewRsp) RT_NOEXCEPT
    3939 {
    3940     RTUINT64U   uTmpRsp;
    3941     RTGCPTR     GCPtrTop;
    3942     uTmpRsp.u = pVCpu->cpum.GstCtx.rsp;
    3943 
    3944     if (IEM_IS_64BIT_CODE(pVCpu))
    3945     {
    3946         GCPtrTop = uTmpRsp.u;
    3947         uTmpRsp.u += cbItem;
    3948     }
    3949     else if (pVCpu->cpum.GstCtx.ss.Attr.n.u1DefBig)
    3950     {
    3951         GCPtrTop = uTmpRsp.DWords.dw0;
    3952         uTmpRsp.DWords.dw0 += cbItem;
    3953     }
    3954     else
    3955     {
    3956         GCPtrTop = uTmpRsp.Words.w0;
    3957         uTmpRsp.Words.w0 += cbItem;
    3958     }
    3959     *puNewRsp = uTmpRsp.u;
    3960     return GCPtrTop;
    3961 }
    3962 
    3963 
    3964 /**
    3965  * Calculates the effective stack address for a push of the specified size as
    3966  * well as the new temporary RSP value (upper bits may be masked).
    3967  *
    3968  * @returns Effective stack addressf for the push.
    3969  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    3970  * @param   pTmpRsp             The temporary stack pointer.  This is updated.
    3971  * @param   cbItem              The size of the stack item to pop.
    3972  */
    3973 DECLINLINE(RTGCPTR) iemRegGetRspForPushEx(PCVMCPU pVCpu, PRTUINT64U pTmpRsp, uint8_t cbItem) RT_NOEXCEPT
    3974 {
    3975     RTGCPTR GCPtrTop;
    3976 
    3977     if (IEM_IS_64BIT_CODE(pVCpu))
    3978         GCPtrTop = pTmpRsp->u          -= cbItem;
    3979     else if (pVCpu->cpum.GstCtx.ss.Attr.n.u1DefBig)
    3980         GCPtrTop = pTmpRsp->DWords.dw0 -= cbItem;
    3981     else
    3982         GCPtrTop = pTmpRsp->Words.w0   -= cbItem;
    3983     return GCPtrTop;
    3984 }
    3985 
    3986 
    3987 /**
    3988  * Gets the effective stack address for a pop of the specified size and
    3989  * calculates and updates the temporary RSP.
    3990  *
    3991  * @returns Current stack pointer.
    3992  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    3993  * @param   pTmpRsp             The temporary stack pointer.  This is updated.
    3994  * @param   cbItem              The size of the stack item to pop.
    3995  */
    3996 DECLINLINE(RTGCPTR) iemRegGetRspForPopEx(PCVMCPU pVCpu, PRTUINT64U pTmpRsp, uint8_t cbItem) RT_NOEXCEPT
    3997 {
    3998     RTGCPTR GCPtrTop;
    3999     if (IEM_IS_64BIT_CODE(pVCpu))
    4000     {
    4001         GCPtrTop = pTmpRsp->u;
    4002         pTmpRsp->u          += cbItem;
    4003     }
    4004     else if (pVCpu->cpum.GstCtx.ss.Attr.n.u1DefBig)
    4005     {
    4006         GCPtrTop = pTmpRsp->DWords.dw0;
    4007         pTmpRsp->DWords.dw0 += cbItem;
    4008     }
    4009     else
    4010     {
    4011         GCPtrTop = pTmpRsp->Words.w0;
    4012         pTmpRsp->Words.w0   += cbItem;
    4013     }
    4014     return GCPtrTop;
    4015 }
    4016 
    4017 
    4018 /** Common body for iemRegRipNearReturnAndFinishClearingRF()
    4019  * and iemRegRipNearReturnAndFinishNoFlags(). */
    4020 template<bool a_fWithFlags>
    4021 DECL_FORCE_INLINE(VBOXSTRICTRC)
    4022 iemRegRipNearReturnCommon(PVMCPUCC pVCpu, uint8_t cbInstr, uint16_t cbPop, IEMMODE enmEffOpSize) RT_NOEXCEPT
    4023 {
    4024     /* Fetch the new RIP from the stack. */
    4025     VBOXSTRICTRC    rcStrict;
    4026     RTUINT64U       NewRip;
    4027     RTUINT64U       NewRsp;
    4028     NewRsp.u = pVCpu->cpum.GstCtx.rsp;
    4029     switch (enmEffOpSize)
    4030     {
    4031         case IEMMODE_16BIT:
    4032             NewRip.u = 0;
    4033             rcStrict = iemMemStackPopU16Ex(pVCpu, &NewRip.Words.w0, &NewRsp);
    4034             break;
    4035         case IEMMODE_32BIT:
    4036             NewRip.u = 0;
    4037             rcStrict = iemMemStackPopU32Ex(pVCpu, &NewRip.DWords.dw0, &NewRsp);
    4038             break;
    4039         case IEMMODE_64BIT:
    4040             rcStrict = iemMemStackPopU64Ex(pVCpu, &NewRip.u, &NewRsp);
    4041             break;
    4042         IEM_NOT_REACHED_DEFAULT_CASE_RET();
    4043     }
    4044     if (rcStrict != VINF_SUCCESS)
    4045         return rcStrict;
    4046 
    4047     /* Check the new ew RIP before loading it. */
    4048     /** @todo Should test this as the intel+amd pseudo code doesn't mention half
    4049      *        of it.  The canonical test is performed here and for call. */
    4050     if (enmEffOpSize != IEMMODE_64BIT)
    4051     {
    4052         if (RT_LIKELY(NewRip.DWords.dw0 <= pVCpu->cpum.GstCtx.cs.u32Limit))
    4053         { /* likely */ }
    4054         else
    4055         {
    4056             Log(("retn newrip=%llx - out of bounds (%x) -> #GP\n", NewRip.u, pVCpu->cpum.GstCtx.cs.u32Limit));
    4057             return iemRaiseSelectorBounds(pVCpu, X86_SREG_CS, IEM_ACCESS_INSTRUCTION);
    4058         }
    4059     }
    4060     else
    4061     {
    4062         if (RT_LIKELY(IEM_IS_CANONICAL(NewRip.u)))
    4063         { /* likely */ }
    4064         else
    4065         {
    4066             Log(("retn newrip=%llx - not canonical -> #GP\n", NewRip.u));
    4067             return iemRaiseNotCanonical(pVCpu);
    4068         }
    4069     }
    4070 
    4071     /* Apply cbPop */
    4072     if (cbPop)
    4073         iemRegAddToRspEx(pVCpu, &NewRsp, cbPop);
    4074 
    4075     /* Commit it. */
    4076     pVCpu->cpum.GstCtx.rip = NewRip.u;
    4077     pVCpu->cpum.GstCtx.rsp = NewRsp.u;
    4078 
    4079     /* Flush the prefetch buffer. */
    4080 #ifndef IEM_WITH_CODE_TLB
    4081     iemOpcodeFlushLight(pVCpu, cbInstr);
    4082 #endif
    4083     RT_NOREF(cbInstr);
    4084 
    4085 
    4086     if (a_fWithFlags)
    4087         return iemRegFinishClearingRF(pVCpu, VINF_SUCCESS);
    4088     return iemRegFinishNoFlags(pVCpu, VINF_SUCCESS);
    4089 }
    4090 
    4091 
    4092 /**
    4093  * Implements retn and retn imm16.
    4094  *
    4095  * @param   pVCpu           The cross context virtual CPU structure of the
    4096  *                          calling thread.
    4097  * @param   cbInstr         The current instruction length.
    4098  * @param   enmEffOpSize    The effective operand size.  This is constant.
    4099  * @param   cbPop           The amount of arguments to pop from the stack
    4100  *                          (bytes).  This can be constant (zero).
    4101  */
    4102 DECL_FORCE_INLINE(VBOXSTRICTRC)
    4103 iemRegRipNearReturnAndFinishClearingRF(PVMCPUCC pVCpu, uint8_t cbInstr, uint16_t cbPop, IEMMODE enmEffOpSize) RT_NOEXCEPT
    4104 {
    4105     return iemRegRipNearReturnCommon<true /*a_fWithFlags*/>(pVCpu, cbInstr, cbPop, enmEffOpSize);
    4106 }
    4107 
    4108 
    4109 /**
    4110  * Implements retn and retn imm16, no checking or clearing of
    4111  * flags.
    4112  *
    4113  * @param   pVCpu           The cross context virtual CPU structure of the
    4114  *                          calling thread.
    4115  * @param   cbInstr         The current instruction length.
    4116  * @param   enmEffOpSize    The effective operand size.  This is constant.
    4117  * @param   cbPop           The amount of arguments to pop from the stack
    4118  *                          (bytes).  This can be constant (zero).
    4119  */
    4120 DECL_FORCE_INLINE(VBOXSTRICTRC)
    4121 iemRegRipNearReturnAndFinishNoFlags(PVMCPUCC pVCpu, uint8_t cbInstr, uint16_t cbPop, IEMMODE enmEffOpSize) RT_NOEXCEPT
    4122 {
    4123     return iemRegRipNearReturnCommon<false /*a_fWithFlags*/>(pVCpu, cbInstr, cbPop, enmEffOpSize);
    4124 }
    4125 
    4126 /** @}  */
    4127 
    4128 
    4129 /** @name   FPU access and helpers.
    4130  *
    4131  * @{
    4132  */
    4133 
    4134 
    4135 /**
    4136  * Hook for preparing to use the host FPU.
    4137  *
    4138  * This is necessary in ring-0 and raw-mode context (nop in ring-3).
    4139  *
    4140  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    4141  */
    4142 DECLINLINE(void) iemFpuPrepareUsage(PVMCPUCC pVCpu) RT_NOEXCEPT
    4143 {
    4144 #ifdef IN_RING3
    4145     CPUMSetChangedFlags(pVCpu, CPUM_CHANGED_FPU_REM);
    4146 #else
    4147     CPUMRZFpuStatePrepareHostCpuForUse(pVCpu);
    4148 #endif
    4149     IEM_CTX_IMPORT_NORET(pVCpu, CPUMCTX_EXTRN_X87 | CPUMCTX_EXTRN_SSE_AVX | CPUMCTX_EXTRN_OTHER_XSAVE | CPUMCTX_EXTRN_XCRx);
    4150 }
    4151 
    4152 
    4153 /**
    4154  * Hook for preparing to use the host FPU for SSE.
    4155  *
    4156  * This is necessary in ring-0 and raw-mode context (nop in ring-3).
    4157  *
    4158  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    4159  */
    4160 DECLINLINE(void) iemFpuPrepareUsageSse(PVMCPUCC pVCpu) RT_NOEXCEPT
    4161 {
    4162     iemFpuPrepareUsage(pVCpu);
    4163 }
    4164 
    4165 
    4166 /**
    4167  * Hook for preparing to use the host FPU for AVX.
    4168  *
    4169  * This is necessary in ring-0 and raw-mode context (nop in ring-3).
    4170  *
    4171  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    4172  */
    4173 DECLINLINE(void) iemFpuPrepareUsageAvx(PVMCPUCC pVCpu) RT_NOEXCEPT
    4174 {
    4175     iemFpuPrepareUsage(pVCpu);
    4176 }
    4177 
    4178 
    4179 /**
    4180  * Hook for actualizing the guest FPU state before the interpreter reads it.
    4181  *
    4182  * This is necessary in ring-0 and raw-mode context (nop in ring-3).
    4183  *
    4184  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    4185  */
    4186 DECLINLINE(void) iemFpuActualizeStateForRead(PVMCPUCC pVCpu) RT_NOEXCEPT
    4187 {
    4188 #ifdef IN_RING3
    4189     NOREF(pVCpu);
    4190 #else
    4191     CPUMRZFpuStateActualizeForRead(pVCpu);
    4192 #endif
    4193     IEM_CTX_IMPORT_NORET(pVCpu, CPUMCTX_EXTRN_X87 | CPUMCTX_EXTRN_SSE_AVX | CPUMCTX_EXTRN_OTHER_XSAVE | CPUMCTX_EXTRN_XCRx);
    4194 }
    4195 
    4196 
    4197 /**
    4198  * Hook for actualizing the guest FPU state before the interpreter changes it.
    4199  *
    4200  * This is necessary in ring-0 and raw-mode context (nop in ring-3).
    4201  *
    4202  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    4203  */
    4204 DECLINLINE(void) iemFpuActualizeStateForChange(PVMCPUCC pVCpu) RT_NOEXCEPT
    4205 {
    4206 #ifdef IN_RING3
    4207     CPUMSetChangedFlags(pVCpu, CPUM_CHANGED_FPU_REM);
    4208 #else
    4209     CPUMRZFpuStateActualizeForChange(pVCpu);
    4210 #endif
    4211     IEM_CTX_IMPORT_NORET(pVCpu, CPUMCTX_EXTRN_X87 | CPUMCTX_EXTRN_SSE_AVX | CPUMCTX_EXTRN_OTHER_XSAVE | CPUMCTX_EXTRN_XCRx);
    4212 }
    4213 
    4214 
    4215 /**
    4216  * Hook for actualizing the guest XMM0..15 and MXCSR register state for read
    4217  * only.
    4218  *
    4219  * This is necessary in ring-0 and raw-mode context (nop in ring-3).
    4220  *
    4221  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    4222  */
    4223 DECLINLINE(void) iemFpuActualizeSseStateForRead(PVMCPUCC pVCpu) RT_NOEXCEPT
    4224 {
    4225 #if defined(IN_RING3) || defined(VBOX_WITH_KERNEL_USING_XMM)
    4226     NOREF(pVCpu);
    4227 #else
    4228     CPUMRZFpuStateActualizeSseForRead(pVCpu);
    4229 #endif
    4230     IEM_CTX_IMPORT_NORET(pVCpu, CPUMCTX_EXTRN_X87 | CPUMCTX_EXTRN_SSE_AVX | CPUMCTX_EXTRN_OTHER_XSAVE | CPUMCTX_EXTRN_XCRx);
    4231 }
    4232 
    4233 
    4234 /**
    4235  * Hook for actualizing the guest XMM0..15 and MXCSR register state for
    4236  * read+write.
    4237  *
    4238  * This is necessary in ring-0 and raw-mode context (nop in ring-3).
    4239  *
    4240  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    4241  */
    4242 DECLINLINE(void) iemFpuActualizeSseStateForChange(PVMCPUCC pVCpu) RT_NOEXCEPT
    4243 {
    4244 #if defined(IN_RING3) || defined(VBOX_WITH_KERNEL_USING_XMM)
    4245     CPUMSetChangedFlags(pVCpu, CPUM_CHANGED_FPU_REM);
    4246 #else
    4247     CPUMRZFpuStateActualizeForChange(pVCpu);
    4248 #endif
    4249     IEM_CTX_IMPORT_NORET(pVCpu, CPUMCTX_EXTRN_X87 | CPUMCTX_EXTRN_SSE_AVX | CPUMCTX_EXTRN_OTHER_XSAVE | CPUMCTX_EXTRN_XCRx);
    4250 
    4251     /* Make sure any changes are loaded the next time around. */
    4252     pVCpu->cpum.GstCtx.XState.Hdr.bmXState |= XSAVE_C_SSE;
    4253 }
    4254 
    4255 
    4256 /**
    4257  * Hook for actualizing the guest YMM0..15 and MXCSR register state for read
    4258  * only.
    4259  *
    4260  * This is necessary in ring-0 and raw-mode context (nop in ring-3).
    4261  *
    4262  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    4263  */
    4264 DECLINLINE(void) iemFpuActualizeAvxStateForRead(PVMCPUCC pVCpu) RT_NOEXCEPT
    4265 {
    4266 #ifdef IN_RING3
    4267     NOREF(pVCpu);
    4268 #else
    4269     CPUMRZFpuStateActualizeAvxForRead(pVCpu);
    4270 #endif
    4271     IEM_CTX_IMPORT_NORET(pVCpu, CPUMCTX_EXTRN_X87 | CPUMCTX_EXTRN_SSE_AVX | CPUMCTX_EXTRN_OTHER_XSAVE | CPUMCTX_EXTRN_XCRx);
    4272 }
    4273 
    4274 
    4275 /**
    4276  * Hook for actualizing the guest YMM0..15 and MXCSR register state for
    4277  * read+write.
    4278  *
    4279  * This is necessary in ring-0 and raw-mode context (nop in ring-3).
    4280  *
    4281  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    4282  */
    4283 DECLINLINE(void) iemFpuActualizeAvxStateForChange(PVMCPUCC pVCpu) RT_NOEXCEPT
    4284 {
    4285 #ifdef IN_RING3
    4286     CPUMSetChangedFlags(pVCpu, CPUM_CHANGED_FPU_REM);
    4287 #else
    4288     CPUMRZFpuStateActualizeForChange(pVCpu);
    4289 #endif
    4290     IEM_CTX_IMPORT_NORET(pVCpu, CPUMCTX_EXTRN_X87 | CPUMCTX_EXTRN_SSE_AVX | CPUMCTX_EXTRN_OTHER_XSAVE | CPUMCTX_EXTRN_XCRx);
    4291 
    4292     /* Just assume we're going to make changes to the SSE and YMM_HI parts. */
    4293     pVCpu->cpum.GstCtx.XState.Hdr.bmXState |= XSAVE_C_YMM | XSAVE_C_SSE;
    4294 }
    4295 
    4296 
    4297 /**
    4298  * Stores a QNaN value into a FPU register.
    4299  *
    4300  * @param   pReg                Pointer to the register.
    4301  */
    4302 DECLINLINE(void) iemFpuStoreQNan(PRTFLOAT80U pReg) RT_NOEXCEPT
    4303 {
    4304     pReg->au32[0] = UINT32_C(0x00000000);
    4305     pReg->au32[1] = UINT32_C(0xc0000000);
    4306     pReg->au16[4] = UINT16_C(0xffff);
    4307 }
    4308 
    4309 
    4310 /**
    4311  * Updates the FOP, FPU.CS and FPUIP registers, extended version.
    4312  *
    4313  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    4314  * @param   pFpuCtx             The FPU context.
    4315  * @param   uFpuOpcode          The FPU opcode value (see IEMCPU::uFpuOpcode).
    4316  */
    4317 DECLINLINE(void) iemFpuUpdateOpcodeAndIpWorkerEx(PVMCPUCC pVCpu, PX86FXSTATE pFpuCtx, uint16_t uFpuOpcode) RT_NOEXCEPT
    4318 {
    4319     Assert(uFpuOpcode != UINT16_MAX);
    4320     pFpuCtx->FOP = uFpuOpcode;
    4321     /** @todo x87.CS and FPUIP needs to be kept seperately. */
    4322     if (IEM_IS_REAL_OR_V86_MODE(pVCpu))
    4323     {
    4324         /** @todo Testcase: making assumptions about how FPUIP and FPUDP are handled
    4325          *        happens in real mode here based on the fnsave and fnstenv images. */
    4326         pFpuCtx->CS    = 0;
    4327         pFpuCtx->FPUIP = pVCpu->cpum.GstCtx.eip | ((uint32_t)pVCpu->cpum.GstCtx.cs.Sel << 4);
    4328     }
    4329     else if (!IEM_IS_LONG_MODE(pVCpu))
    4330     {
    4331         pFpuCtx->CS    = pVCpu->cpum.GstCtx.cs.Sel;
    4332         pFpuCtx->FPUIP = pVCpu->cpum.GstCtx.rip;
    4333     }
    4334     else
    4335         *(uint64_t *)&pFpuCtx->FPUIP = pVCpu->cpum.GstCtx.rip;
    4336 }
    4337 
    4338 
    4339 /**
    4340  * Marks the specified stack register as free (for FFREE).
    4341  *
    4342  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    4343  * @param   iStReg              The register to free.
    4344  */
    4345 DECLINLINE(void) iemFpuStackFree(PVMCPUCC pVCpu, uint8_t iStReg) RT_NOEXCEPT
    4346 {
    4347     Assert(iStReg < 8);
    4348     PX86FXSTATE pFpuCtx = &pVCpu->cpum.GstCtx.XState.x87;
    4349     uint8_t     iReg    = (X86_FSW_TOP_GET(pFpuCtx->FSW) + iStReg) & X86_FSW_TOP_SMASK;
    4350     pFpuCtx->FTW &= ~RT_BIT(iReg);
    4351 }
    4352 
    4353 
    4354 /**
    4355  * Increments FSW.TOP, i.e. pops an item off the stack without freeing it.
    4356  *
    4357  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    4358  */
    4359 DECLINLINE(void) iemFpuStackIncTop(PVMCPUCC pVCpu) RT_NOEXCEPT
    4360 {
    4361     PX86FXSTATE pFpuCtx = &pVCpu->cpum.GstCtx.XState.x87;
    4362     uint16_t    uFsw    = pFpuCtx->FSW;
    4363     uint16_t    uTop    = uFsw & X86_FSW_TOP_MASK;
    4364     uTop  = (uTop + (1 << X86_FSW_TOP_SHIFT)) & X86_FSW_TOP_MASK;
    4365     uFsw &= ~X86_FSW_TOP_MASK;
    4366     uFsw |= uTop;
    4367     pFpuCtx->FSW = uFsw;
    4368 }
    4369 
    4370 
    4371 /**
    4372  * Decrements FSW.TOP, i.e. push an item off the stack without storing anything.
    4373  *
    4374  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    4375  */
    4376 DECLINLINE(void) iemFpuStackDecTop(PVMCPUCC pVCpu) RT_NOEXCEPT
    4377 {
    4378     PX86FXSTATE pFpuCtx = &pVCpu->cpum.GstCtx.XState.x87;
    4379     uint16_t    uFsw    = pFpuCtx->FSW;
    4380     uint16_t    uTop    = uFsw & X86_FSW_TOP_MASK;
    4381     uTop  = (uTop + (7 << X86_FSW_TOP_SHIFT)) & X86_FSW_TOP_MASK;
    4382     uFsw &= ~X86_FSW_TOP_MASK;
    4383     uFsw |= uTop;
    4384     pFpuCtx->FSW = uFsw;
    4385 }
    4386 
    4387 
    4388 
    4389 
    4390 DECLINLINE(int) iemFpuStRegNotEmpty(PVMCPUCC pVCpu, uint8_t iStReg) RT_NOEXCEPT
    4391 {
    4392     PX86FXSTATE pFpuCtx = &pVCpu->cpum.GstCtx.XState.x87;
    4393     uint16_t    iReg    = (X86_FSW_TOP_GET(pFpuCtx->FSW) + iStReg) & X86_FSW_TOP_SMASK;
    4394     if (pFpuCtx->FTW & RT_BIT(iReg))
    4395         return VINF_SUCCESS;
    4396     return VERR_NOT_FOUND;
    4397 }
    4398 
    4399 
    4400 DECLINLINE(int) iemFpuStRegNotEmptyRef(PVMCPUCC pVCpu, uint8_t iStReg, PCRTFLOAT80U *ppRef) RT_NOEXCEPT
    4401 {
    4402     PX86FXSTATE pFpuCtx = &pVCpu->cpum.GstCtx.XState.x87;
    4403     uint16_t    iReg    = (X86_FSW_TOP_GET(pFpuCtx->FSW) + iStReg) & X86_FSW_TOP_SMASK;
    4404     if (pFpuCtx->FTW & RT_BIT(iReg))
    4405     {
    4406         *ppRef = &pFpuCtx->aRegs[iStReg].r80;
    4407         return VINF_SUCCESS;
    4408     }
    4409     return VERR_NOT_FOUND;
    4410 }
    4411 
    4412 
    4413 DECLINLINE(int) iemFpu2StRegsNotEmptyRef(PVMCPUCC pVCpu, uint8_t iStReg0, PCRTFLOAT80U *ppRef0,
    4414                                         uint8_t iStReg1, PCRTFLOAT80U *ppRef1) RT_NOEXCEPT
    4415 {
    4416     PX86FXSTATE pFpuCtx = &pVCpu->cpum.GstCtx.XState.x87;
    4417     uint16_t    iTop    = X86_FSW_TOP_GET(pFpuCtx->FSW);
    4418     uint16_t    iReg0   = (iTop + iStReg0) & X86_FSW_TOP_SMASK;
    4419     uint16_t    iReg1   = (iTop + iStReg1) & X86_FSW_TOP_SMASK;
    4420     if ((pFpuCtx->FTW & (RT_BIT(iReg0) | RT_BIT(iReg1))) == (RT_BIT(iReg0) | RT_BIT(iReg1)))
    4421     {
    4422         *ppRef0 = &pFpuCtx->aRegs[iStReg0].r80;
    4423         *ppRef1 = &pFpuCtx->aRegs[iStReg1].r80;
    4424         return VINF_SUCCESS;
    4425     }
    4426     return VERR_NOT_FOUND;
    4427 }
    4428 
    4429 
    4430 DECLINLINE(int) iemFpu2StRegsNotEmptyRefFirst(PVMCPUCC pVCpu, uint8_t iStReg0, PCRTFLOAT80U *ppRef0, uint8_t iStReg1) RT_NOEXCEPT
    4431 {
    4432     PX86FXSTATE pFpuCtx = &pVCpu->cpum.GstCtx.XState.x87;
    4433     uint16_t    iTop    = X86_FSW_TOP_GET(pFpuCtx->FSW);
    4434     uint16_t    iReg0   = (iTop + iStReg0) & X86_FSW_TOP_SMASK;
    4435     uint16_t    iReg1   = (iTop + iStReg1) & X86_FSW_TOP_SMASK;
    4436     if ((pFpuCtx->FTW & (RT_BIT(iReg0) | RT_BIT(iReg1))) == (RT_BIT(iReg0) | RT_BIT(iReg1)))
    4437     {
    4438         *ppRef0 = &pFpuCtx->aRegs[iStReg0].r80;
    4439         return VINF_SUCCESS;
    4440     }
    4441     return VERR_NOT_FOUND;
    4442 }
    4443 
    4444 
    4445 /**
    4446  * Rotates the stack registers when setting new TOS.
    4447  *
    4448  * @param   pFpuCtx             The FPU context.
    4449  * @param   iNewTop             New TOS value.
    4450  * @remarks We only do this to speed up fxsave/fxrstor which
    4451  *          arrange the FP registers in stack order.
    4452  *          MUST be done before writing the new TOS (FSW).
    4453  */
    4454 DECLINLINE(void) iemFpuRotateStackSetTop(PX86FXSTATE pFpuCtx, uint16_t iNewTop) RT_NOEXCEPT
    4455 {
    4456     uint16_t iOldTop = X86_FSW_TOP_GET(pFpuCtx->FSW);
    4457     RTFLOAT80U ar80Temp[8];
    4458 
    4459     if (iOldTop == iNewTop)
    4460         return;
    4461 
    4462     /* Unscrew the stack and get it into 'native' order. */
    4463     ar80Temp[0] = pFpuCtx->aRegs[(8 - iOldTop + 0) & X86_FSW_TOP_SMASK].r80;
    4464     ar80Temp[1] = pFpuCtx->aRegs[(8 - iOldTop + 1) & X86_FSW_TOP_SMASK].r80;
    4465     ar80Temp[2] = pFpuCtx->aRegs[(8 - iOldTop + 2) & X86_FSW_TOP_SMASK].r80;
    4466     ar80Temp[3] = pFpuCtx->aRegs[(8 - iOldTop + 3) & X86_FSW_TOP_SMASK].r80;
    4467     ar80Temp[4] = pFpuCtx->aRegs[(8 - iOldTop + 4) & X86_FSW_TOP_SMASK].r80;
    4468     ar80Temp[5] = pFpuCtx->aRegs[(8 - iOldTop + 5) & X86_FSW_TOP_SMASK].r80;
    4469     ar80Temp[6] = pFpuCtx->aRegs[(8 - iOldTop + 6) & X86_FSW_TOP_SMASK].r80;
    4470     ar80Temp[7] = pFpuCtx->aRegs[(8 - iOldTop + 7) & X86_FSW_TOP_SMASK].r80;
    4471 
    4472     /* Now rotate the stack to the new position. */
    4473     pFpuCtx->aRegs[0].r80 = ar80Temp[(iNewTop + 0) & X86_FSW_TOP_SMASK];
    4474     pFpuCtx->aRegs[1].r80 = ar80Temp[(iNewTop + 1) & X86_FSW_TOP_SMASK];
    4475     pFpuCtx->aRegs[2].r80 = ar80Temp[(iNewTop + 2) & X86_FSW_TOP_SMASK];
    4476     pFpuCtx->aRegs[3].r80 = ar80Temp[(iNewTop + 3) & X86_FSW_TOP_SMASK];
    4477     pFpuCtx->aRegs[4].r80 = ar80Temp[(iNewTop + 4) & X86_FSW_TOP_SMASK];
    4478     pFpuCtx->aRegs[5].r80 = ar80Temp[(iNewTop + 5) & X86_FSW_TOP_SMASK];
    4479     pFpuCtx->aRegs[6].r80 = ar80Temp[(iNewTop + 6) & X86_FSW_TOP_SMASK];
    4480     pFpuCtx->aRegs[7].r80 = ar80Temp[(iNewTop + 7) & X86_FSW_TOP_SMASK];
    4481 }
    4482 
    4483 
    4484 /**
    4485  * Updates the FPU exception status after FCW is changed.
    4486  *
    4487  * @param   pFpuCtx             The FPU context.
    4488  */
    4489 DECLINLINE(void) iemFpuRecalcExceptionStatus(PX86FXSTATE pFpuCtx) RT_NOEXCEPT
    4490 {
    4491     uint16_t u16Fsw = pFpuCtx->FSW;
    4492     if ((u16Fsw & X86_FSW_XCPT_MASK) & ~(pFpuCtx->FCW & X86_FCW_XCPT_MASK))
    4493         u16Fsw |= X86_FSW_ES | X86_FSW_B;
    4494     else
    4495         u16Fsw &= ~(X86_FSW_ES | X86_FSW_B);
    4496     pFpuCtx->FSW = u16Fsw;
    4497 }
    4498 
    4499 
    4500 /**
    4501  * Calculates the full FTW (FPU tag word) for use in FNSTENV and FNSAVE.
    4502  *
    4503  * @returns The full FTW.
    4504  * @param   pFpuCtx             The FPU context.
    4505  */
    4506 DECLINLINE(uint16_t) iemFpuCalcFullFtw(PCX86FXSTATE pFpuCtx) RT_NOEXCEPT
    4507 {
    4508     uint8_t const   u8Ftw  = (uint8_t)pFpuCtx->FTW;
    4509     uint16_t        u16Ftw = 0;
    4510     unsigned const  iTop   = X86_FSW_TOP_GET(pFpuCtx->FSW);
    4511     for (unsigned iSt = 0; iSt < 8; iSt++)
    4512     {
    4513         unsigned const iReg = (iSt + iTop) & 7;
    4514         if (!(u8Ftw & RT_BIT(iReg)))
    4515             u16Ftw |= 3 << (iReg * 2); /* empty */
    4516         else
    4517         {
    4518             uint16_t uTag;
    4519             PCRTFLOAT80U const pr80Reg = &pFpuCtx->aRegs[iSt].r80;
    4520             if (pr80Reg->s.uExponent == 0x7fff)
    4521                 uTag = 2; /* Exponent is all 1's => Special. */
    4522             else if (pr80Reg->s.uExponent == 0x0000)
    4523             {
    4524                 if (pr80Reg->s.uMantissa == 0x0000)
    4525                     uTag = 1; /* All bits are zero => Zero. */
    4526                 else
    4527                     uTag = 2; /* Must be special. */
    4528             }
    4529             else if (pr80Reg->s.uMantissa & RT_BIT_64(63)) /* The J bit. */
    4530                 uTag = 0; /* Valid. */
    4531             else
    4532                 uTag = 2; /* Must be special. */
    4533 
    4534             u16Ftw |= uTag << (iReg * 2);
    4535         }
    4536     }
    4537 
    4538     return u16Ftw;
    4539 }
    4540 
    4541 
    4542 /**
    4543  * Converts a full FTW to a compressed one (for use in FLDENV and FRSTOR).
    4544  *
    4545  * @returns The compressed FTW.
    4546  * @param   u16FullFtw      The full FTW to convert.
    4547  */
    4548 DECLINLINE(uint16_t) iemFpuCompressFtw(uint16_t u16FullFtw) RT_NOEXCEPT
    4549 {
    4550     uint8_t u8Ftw = 0;
    4551     for (unsigned i = 0; i < 8; i++)
    4552     {
    4553         if ((u16FullFtw & 3) != 3 /*empty*/)
    4554             u8Ftw |= RT_BIT(i);
    4555         u16FullFtw >>= 2;
    4556     }
    4557 
    4558     return u8Ftw;
    4559 }
    4560 
    4561 /** @}  */
    4562 
    4563 
    4564 /** @name   Memory access.
    4565  *
    4566  * @{
    4567  */
    4568 
    4569 
    4570 /**
    4571  * Checks whether alignment checks are enabled or not.
    4572  *
    4573  * @returns true if enabled, false if not.
    4574  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    4575  */
    4576 DECLINLINE(bool) iemMemAreAlignmentChecksEnabled(PVMCPUCC pVCpu) RT_NOEXCEPT
    4577 {
    4578 #if 0
    4579     AssertCompile(X86_CR0_AM == X86_EFL_AC);
    4580     return IEM_GET_CPL(pVCpu) == 3
    4581         && (((uint32_t)pVCpu->cpum.GstCtx.cr0 & pVCpu->cpum.GstCtx.eflags.u) & X86_CR0_AM);
    4582 #else
    4583     return RT_BOOL(pVCpu->iem.s.fExec & IEM_F_X86_AC);
    4584 #endif
    4585 }
    4586 
    4587 /**
    4588  * Checks if the given segment can be written to, raise the appropriate
    4589  * exception if not.
    4590  *
    4591  * @returns VBox strict status code.
    4592  *
    4593  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    4594  * @param   pHid                Pointer to the hidden register.
    4595  * @param   iSegReg             The register number.
    4596  * @param   pu64BaseAddr        Where to return the base address to use for the
    4597  *                              segment. (In 64-bit code it may differ from the
    4598  *                              base in the hidden segment.)
    4599  */
    4600 DECLINLINE(VBOXSTRICTRC) iemMemSegCheckWriteAccessEx(PVMCPUCC pVCpu, PCCPUMSELREGHID pHid,
    4601                                                      uint8_t iSegReg, uint64_t *pu64BaseAddr) RT_NOEXCEPT
    4602 {
    4603     IEM_CTX_ASSERT(pVCpu, CPUMCTX_EXTRN_SREG_FROM_IDX(iSegReg));
    4604 
    4605     if (IEM_IS_64BIT_CODE(pVCpu))
    4606         *pu64BaseAddr = iSegReg < X86_SREG_FS ? 0 : pHid->u64Base;
    4607     else
    4608     {
    4609         if (!pHid->Attr.n.u1Present)
    4610         {
    4611             uint16_t    uSel = iemSRegFetchU16(pVCpu, iSegReg);
    4612             AssertRelease(uSel == 0);
    4613             LogEx(LOG_GROUP_IEM,("iemMemSegCheckWriteAccessEx: %#x (index %u) - bad selector -> #GP\n", uSel, iSegReg));
    4614             return iemRaiseGeneralProtectionFault0(pVCpu);
    4615         }
    4616 
    4617         if (   (   (pHid->Attr.n.u4Type & X86_SEL_TYPE_CODE)
    4618                 || !(pHid->Attr.n.u4Type & X86_SEL_TYPE_WRITE) )
    4619             && !IEM_IS_64BIT_CODE(pVCpu) )
    4620             return iemRaiseSelectorInvalidAccess(pVCpu, iSegReg, IEM_ACCESS_DATA_W);
    4621         *pu64BaseAddr = pHid->u64Base;
    4622     }
    4623     return VINF_SUCCESS;
    4624 }
    4625 
    4626 
    4627 /**
    4628  * Checks if the given segment can be read from, raise the appropriate
    4629  * exception if not.
    4630  *
    4631  * @returns VBox strict status code.
    4632  *
    4633  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    4634  * @param   pHid                Pointer to the hidden register.
    4635  * @param   iSegReg             The register number.
    4636  * @param   pu64BaseAddr        Where to return the base address to use for the
    4637  *                              segment. (In 64-bit code it may differ from the
    4638  *                              base in the hidden segment.)
    4639  */
    4640 DECLINLINE(VBOXSTRICTRC) iemMemSegCheckReadAccessEx(PVMCPUCC pVCpu, PCCPUMSELREGHID pHid,
    4641                                                     uint8_t iSegReg, uint64_t *pu64BaseAddr) RT_NOEXCEPT
    4642 {
    4643     IEM_CTX_ASSERT(pVCpu, CPUMCTX_EXTRN_SREG_FROM_IDX(iSegReg));
    4644 
    4645     if (IEM_IS_64BIT_CODE(pVCpu))
    4646         *pu64BaseAddr = iSegReg < X86_SREG_FS ? 0 : pHid->u64Base;
    4647     else
    4648     {
    4649         if (!pHid->Attr.n.u1Present)
    4650         {
    4651             uint16_t    uSel = iemSRegFetchU16(pVCpu, iSegReg);
    4652             AssertRelease(uSel == 0);
    4653             LogEx(LOG_GROUP_IEM,("iemMemSegCheckReadAccessEx: %#x (index %u) - bad selector -> #GP\n", uSel, iSegReg));
    4654             return iemRaiseGeneralProtectionFault0(pVCpu);
    4655         }
    4656 
    4657         if ((pHid->Attr.n.u4Type & (X86_SEL_TYPE_CODE | X86_SEL_TYPE_READ)) == X86_SEL_TYPE_CODE)
    4658             return iemRaiseSelectorInvalidAccess(pVCpu, iSegReg, IEM_ACCESS_DATA_R);
    4659         *pu64BaseAddr = pHid->u64Base;
    4660     }
    4661     return VINF_SUCCESS;
    4662 }
    4663 
    4664 
    4665 /**
    4666  * Maps a physical page.
    4667  *
    4668  * @returns VBox status code (see PGMR3PhysTlbGCPhys2Ptr).
    4669  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    4670  * @param   GCPhysMem           The physical address.
    4671  * @param   fAccess             The intended access.
    4672  * @param   ppvMem              Where to return the mapping address.
    4673  * @param   pLock               The PGM lock.
    4674  */
    4675 DECLINLINE(int) iemMemPageMap(PVMCPUCC pVCpu, RTGCPHYS GCPhysMem, uint32_t fAccess,
    4676                               void **ppvMem, PPGMPAGEMAPLOCK pLock) RT_NOEXCEPT
    4677 {
    4678 #ifdef IEM_LOG_MEMORY_WRITES
    4679     if (fAccess & IEM_ACCESS_TYPE_WRITE)
    4680         return VERR_PGM_PHYS_TLB_CATCH_ALL;
    4681 #endif
    4682 
    4683     /** @todo This API may require some improving later.  A private deal with PGM
    4684      *        regarding locking and unlocking needs to be struct.  A couple of TLBs
    4685      *        living in PGM, but with publicly accessible inlined access methods
    4686      *        could perhaps be an even better solution. */
    4687     int rc = PGMPhysIemGCPhys2Ptr(pVCpu->CTX_SUFF(pVM), pVCpu,
    4688                                   GCPhysMem,
    4689                                   RT_BOOL(fAccess & IEM_ACCESS_TYPE_WRITE),
    4690                                   RT_BOOL(pVCpu->iem.s.fExec & IEM_F_BYPASS_HANDLERS),
    4691                                   ppvMem,
    4692                                   pLock);
    4693     /*Log(("PGMPhysIemGCPhys2Ptr %Rrc pLock=%.*Rhxs\n", rc, sizeof(*pLock), pLock));*/
    4694     AssertMsg(rc == VINF_SUCCESS || RT_FAILURE_NP(rc), ("%Rrc\n", rc));
    4695 
    4696     return rc;
    4697 }
    4698 
    4699 
    4700 /**
    4701  * Unmap a page previously mapped by iemMemPageMap.
    4702  *
    4703  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    4704  * @param   GCPhysMem           The physical address.
    4705  * @param   fAccess             The intended access.
    4706  * @param   pvMem               What iemMemPageMap returned.
    4707  * @param   pLock               The PGM lock.
    4708  */
    4709 DECLINLINE(void) iemMemPageUnmap(PVMCPUCC pVCpu, RTGCPHYS GCPhysMem, uint32_t fAccess,
    4710                                  const void *pvMem, PPGMPAGEMAPLOCK pLock) RT_NOEXCEPT
    4711 {
    4712     NOREF(pVCpu);
    4713     NOREF(GCPhysMem);
    4714     NOREF(fAccess);
    4715     NOREF(pvMem);
    4716     PGMPhysReleasePageMappingLock(pVCpu->CTX_SUFF(pVM), pLock);
    4717 }
    4718 
    4719 #ifdef IEM_WITH_SETJMP
    4720 
    4721 /** @todo slim this down   */
    4722 DECL_INLINE_THROW(RTGCPTR) iemMemApplySegmentToReadJmp(PVMCPUCC pVCpu, uint8_t iSegReg,
    4723                                                        size_t cbMem, RTGCPTR GCPtrMem) IEM_NOEXCEPT_MAY_LONGJMP
    4724 {
    4725     Assert(cbMem >= 1);
    4726     Assert(iSegReg < X86_SREG_COUNT);
    4727 
    4728     /*
    4729      * 64-bit mode is simpler.
    4730      */
    4731     if (IEM_IS_64BIT_CODE(pVCpu))
    4732     {
    4733         if (iSegReg >= X86_SREG_FS && iSegReg != UINT8_MAX)
    4734         {
    4735             IEM_CTX_IMPORT_JMP(pVCpu, CPUMCTX_EXTRN_SREG_FROM_IDX(iSegReg));
    4736             PCPUMSELREGHID const pSel = iemSRegGetHid(pVCpu, iSegReg);
    4737             GCPtrMem += pSel->u64Base;
    4738         }
    4739 
    4740         if (RT_LIKELY(X86_IS_CANONICAL(GCPtrMem) && X86_IS_CANONICAL(GCPtrMem + cbMem - 1)))
    4741             return GCPtrMem;
    4742         iemRaiseGeneralProtectionFault0Jmp(pVCpu);
    4743     }
    4744     /*
    4745      * 16-bit and 32-bit segmentation.
    4746      */
    4747     else if (iSegReg != UINT8_MAX)
    4748     {
    4749         /** @todo Does this apply to segments with 4G-1 limit? */
    4750         uint32_t const GCPtrLast32 = (uint32_t)GCPtrMem + (uint32_t)cbMem - 1;
    4751         if (RT_LIKELY(GCPtrLast32 >= (uint32_t)GCPtrMem))
    4752         {
    4753             IEM_CTX_IMPORT_JMP(pVCpu, CPUMCTX_EXTRN_SREG_FROM_IDX(iSegReg));
    4754             PCPUMSELREGHID const pSel = iemSRegGetHid(pVCpu, iSegReg);
    4755             switch (pSel->Attr.u & (  X86DESCATTR_P     | X86DESCATTR_UNUSABLE
    4756                                     | X86_SEL_TYPE_READ | X86_SEL_TYPE_WRITE /* same as read */
    4757                                     | X86_SEL_TYPE_DOWN | X86_SEL_TYPE_CONF  /* same as down */
    4758                                     | X86_SEL_TYPE_CODE))
    4759             {
    4760                 case X86DESCATTR_P:                                         /* readonly data, expand up */
    4761                 case X86DESCATTR_P | X86_SEL_TYPE_WRITE:                    /* writable data, expand up */
    4762                 case X86DESCATTR_P | X86_SEL_TYPE_CODE | X86_SEL_TYPE_READ: /* code, read-only */
    4763                 case X86DESCATTR_P | X86_SEL_TYPE_CODE | X86_SEL_TYPE_READ | X86_SEL_TYPE_CONF: /* conforming code, read-only */
    4764                     /* expand up */
    4765                     if (RT_LIKELY(GCPtrLast32 <= pSel->u32Limit))
    4766                         return (uint32_t)GCPtrMem + (uint32_t)pSel->u64Base;
    4767                     Log10(("iemMemApplySegmentToReadJmp: out of bounds %#x..%#x vs %#x\n",
    4768                            (uint32_t)GCPtrMem, GCPtrLast32, pSel->u32Limit));
    4769                     break;
    4770 
    4771                 case X86DESCATTR_P | X86_SEL_TYPE_DOWN:                         /* readonly data, expand down */
    4772                 case X86DESCATTR_P | X86_SEL_TYPE_DOWN | X86_SEL_TYPE_WRITE:    /* writable data, expand down */
    4773                     /* expand down */
    4774                     if (RT_LIKELY(   (uint32_t)GCPtrMem > pSel->u32Limit
    4775                                   && (   pSel->Attr.n.u1DefBig
    4776                                       || GCPtrLast32 <= UINT32_C(0xffff)) ))
    4777                         return (uint32_t)GCPtrMem + (uint32_t)pSel->u64Base;
    4778                     Log10(("iemMemApplySegmentToReadJmp: expand down out of bounds %#x..%#x vs %#x..%#x\n",
    4779                            (uint32_t)GCPtrMem, GCPtrLast32, pSel->u32Limit, pSel->Attr.n.u1DefBig ? UINT32_MAX : UINT16_MAX));
    4780                     break;
    4781 
    4782                 default:
    4783                     Log10(("iemMemApplySegmentToReadJmp: bad selector %#x\n", pSel->Attr.u));
    4784                     iemRaiseSelectorInvalidAccessJmp(pVCpu, iSegReg, IEM_ACCESS_DATA_R);
    4785                     break;
    4786             }
    4787         }
    4788         Log10(("iemMemApplySegmentToReadJmp: out of bounds %#x..%#x\n",(uint32_t)GCPtrMem, GCPtrLast32));
    4789         iemRaiseSelectorBoundsJmp(pVCpu, iSegReg, IEM_ACCESS_DATA_R);
    4790     }
    4791     /*
    4792      * 32-bit flat address.
    4793      */
    4794     else
    4795         return GCPtrMem;
    4796 }
    4797 
    4798 
    4799 /** @todo slim this down   */
    4800 DECL_INLINE_THROW(RTGCPTR) iemMemApplySegmentToWriteJmp(PVMCPUCC pVCpu, uint8_t iSegReg, size_t cbMem,
    4801                                                         RTGCPTR GCPtrMem) IEM_NOEXCEPT_MAY_LONGJMP
    4802 {
    4803     Assert(cbMem >= 1);
    4804     Assert(iSegReg < X86_SREG_COUNT);
    4805 
    4806     /*
    4807      * 64-bit mode is simpler.
    4808      */
    4809     if (IEM_IS_64BIT_CODE(pVCpu))
    4810     {
    4811         if (iSegReg >= X86_SREG_FS)
    4812         {
    4813             IEM_CTX_IMPORT_JMP(pVCpu, CPUMCTX_EXTRN_SREG_FROM_IDX(iSegReg));
    4814             PCPUMSELREGHID pSel = iemSRegGetHid(pVCpu, iSegReg);
    4815             GCPtrMem += pSel->u64Base;
    4816         }
    4817 
    4818         if (RT_LIKELY(X86_IS_CANONICAL(GCPtrMem) && X86_IS_CANONICAL(GCPtrMem + cbMem - 1)))
    4819             return GCPtrMem;
    4820     }
    4821     /*
    4822      * 16-bit and 32-bit segmentation.
    4823      */
    4824     else
    4825     {
    4826         Assert(GCPtrMem <= UINT32_MAX);
    4827         IEM_CTX_IMPORT_JMP(pVCpu, CPUMCTX_EXTRN_SREG_FROM_IDX(iSegReg));
    4828         PCPUMSELREGHID pSel           = iemSRegGetHid(pVCpu, iSegReg);
    4829         uint32_t const fRelevantAttrs = pSel->Attr.u & (  X86DESCATTR_P     | X86DESCATTR_UNUSABLE
    4830                                                         | X86_SEL_TYPE_CODE | X86_SEL_TYPE_WRITE | X86_SEL_TYPE_DOWN);
    4831         if (   fRelevantAttrs == (X86DESCATTR_P | X86_SEL_TYPE_WRITE) /* data, expand up */
    4832                /** @todo explore exactly how the CS stuff works in real mode. See also
    4833                 *        http://www.rcollins.org/Productivity/DescriptorCache.html and
    4834                 *        http://www.rcollins.org/ddj/Aug98/Aug98.html for some insight. */
    4835             || (iSegReg == X86_SREG_CS && IEM_IS_REAL_OR_V86_MODE(pVCpu)) ) /* Ignored for CS. */ /** @todo testcase! */
    4836         {
    4837             /* expand up */
    4838             uint32_t const GCPtrLast32 = (uint32_t)GCPtrMem + (uint32_t)cbMem - 1;
    4839             if (RT_LIKELY(   GCPtrLast32 <= pSel->u32Limit
    4840                           && GCPtrLast32 >= (uint32_t)GCPtrMem))
    4841                 return (uint32_t)GCPtrMem + (uint32_t)pSel->u64Base;
    4842             iemRaiseSelectorBoundsJmp(pVCpu, iSegReg, IEM_ACCESS_DATA_W);
    4843         }
    4844         else if (fRelevantAttrs == (X86DESCATTR_P | X86_SEL_TYPE_WRITE | X86_SEL_TYPE_DOWN)) /* data, expand up */
    4845         {
    4846             /* expand down - the uppger boundary is defined by the B bit, not G. */
    4847             uint32_t GCPtrLast32 = (uint32_t)GCPtrMem + (uint32_t)cbMem - 1;
    4848             if (RT_LIKELY(   (uint32_t)GCPtrMem >= pSel->u32Limit
    4849                           && (pSel->Attr.n.u1DefBig || GCPtrLast32 <= UINT32_C(0xffff))
    4850                           && GCPtrLast32 >= (uint32_t)GCPtrMem))
    4851                 return (uint32_t)GCPtrMem + (uint32_t)pSel->u64Base;
    4852             iemRaiseSelectorBoundsJmp(pVCpu, iSegReg, IEM_ACCESS_DATA_W);
    4853         }
    4854         else
    4855             iemRaiseSelectorInvalidAccessJmp(pVCpu, iSegReg, IEM_ACCESS_DATA_W);
    4856     }
    4857     iemRaiseGeneralProtectionFault0Jmp(pVCpu);
    4858 }
    4859 
    4860 #endif /* IEM_WITH_SETJMP */
    4861 
    4862 /**
    4863  * Fakes a long mode stack selector for SS = 0.
    4864  *
    4865  * @param   pDescSs             Where to return the fake stack descriptor.
    4866  * @param   uDpl                The DPL we want.
    4867  */
    4868 DECLINLINE(void) iemMemFakeStackSelDesc(PIEMSELDESC pDescSs, uint32_t uDpl) RT_NOEXCEPT
    4869 {
    4870     pDescSs->Long.au64[0] = 0;
    4871     pDescSs->Long.au64[1] = 0;
    4872     pDescSs->Long.Gen.u4Type     = X86_SEL_TYPE_RW_ACC;
    4873     pDescSs->Long.Gen.u1DescType = 1; /* 1 = code / data, 0 = system. */
    4874     pDescSs->Long.Gen.u2Dpl      = uDpl;
    4875     pDescSs->Long.Gen.u1Present  = 1;
    4876     pDescSs->Long.Gen.u1Long     = 1;
    4877 }
    4878 
    4879 
    4880 /*
    4881  * Unmap helpers.
    4882  */
    4883 
    4884 #ifdef IEM_WITH_SETJMP
    4885 
    4886 DECL_INLINE_THROW(void) iemMemCommitAndUnmapRwJmp(PVMCPUCC pVCpu, uint8_t bMapInfo) IEM_NOEXCEPT_MAY_LONGJMP
    4887 {
    4888 # if defined(IEM_WITH_DATA_TLB) && defined(IN_RING3)
    4889     if (RT_LIKELY(bMapInfo == 0))
    4890         return;
    4891 # endif
    4892     iemMemCommitAndUnmapRwSafeJmp(pVCpu, bMapInfo);
    4893 }
    4894 
    4895 
    4896 DECL_INLINE_THROW(void) iemMemCommitAndUnmapAtJmp(PVMCPUCC pVCpu, uint8_t bMapInfo) IEM_NOEXCEPT_MAY_LONGJMP
    4897 {
    4898 # if defined(IEM_WITH_DATA_TLB) && defined(IN_RING3)
    4899     if (RT_LIKELY(bMapInfo == 0))
    4900         return;
    4901 # endif
    4902     iemMemCommitAndUnmapAtSafeJmp(pVCpu, bMapInfo);
    4903 }
    4904 
    4905 
    4906 DECL_INLINE_THROW(void) iemMemCommitAndUnmapWoJmp(PVMCPUCC pVCpu, uint8_t bMapInfo) IEM_NOEXCEPT_MAY_LONGJMP
    4907 {
    4908 # if defined(IEM_WITH_DATA_TLB) && defined(IN_RING3)
    4909     if (RT_LIKELY(bMapInfo == 0))
    4910         return;
    4911 # endif
    4912     iemMemCommitAndUnmapWoSafeJmp(pVCpu, bMapInfo);
    4913 }
    4914 
    4915 
    4916 DECL_INLINE_THROW(void) iemMemCommitAndUnmapRoJmp(PVMCPUCC pVCpu, uint8_t bMapInfo) IEM_NOEXCEPT_MAY_LONGJMP
    4917 {
    4918 # if defined(IEM_WITH_DATA_TLB) && defined(IN_RING3)
    4919     if (RT_LIKELY(bMapInfo == 0))
    4920         return;
    4921 # endif
    4922     iemMemCommitAndUnmapRoSafeJmp(pVCpu, bMapInfo);
    4923 }
    4924 
    4925 DECLINLINE(void) iemMemRollbackAndUnmapWo(PVMCPUCC pVCpu, uint8_t bMapInfo) RT_NOEXCEPT
    4926 {
    4927 # if defined(IEM_WITH_DATA_TLB) && defined(IN_RING3)
    4928     if (RT_LIKELY(bMapInfo == 0))
    4929         return;
    4930 # endif
    4931     iemMemRollbackAndUnmapWoSafe(pVCpu, bMapInfo);
    4932 }
    4933 
    4934 #endif /* IEM_WITH_SETJMP */
    4935 
    4936 
    4937 /*
    4938  * Instantiate R/W inline templates.
    4939  */
    4940 
    4941 /** @def TMPL_MEM_CHECK_UNALIGNED_WITHIN_PAGE_OK
    4942  * Used to check if an unaligned access is if within the page and won't
    4943  * trigger an \#AC.
    4944  *
    4945  * This can also be used to deal with misaligned accesses on platforms that are
    4946  * senstive to such if desires.
    4947  */
    4948 #if 1
    4949 # define TMPL_MEM_CHECK_UNALIGNED_WITHIN_PAGE_OK(a_pVCpu, a_GCPtrEff, a_TmplMemType) \
    4950     (   ((a_GCPtrEff) & GUEST_PAGE_OFFSET_MASK) <= GUEST_PAGE_SIZE - sizeof(a_TmplMemType) \
    4951      && !((a_pVCpu)->iem.s.fExec & IEM_F_X86_AC) )
    4952 #else
    4953 # define TMPL_MEM_CHECK_UNALIGNED_WITHIN_PAGE_OK(a_pVCpu, a_GCPtrEff, a_TmplMemType) 0
    4954 #endif
    4955 
    4956 #define TMPL_MEM_WITH_ATOMIC_MAPPING
    4957 
    4958 #define TMPL_MEM_TYPE       uint8_t
    4959 #define TMPL_MEM_TYPE_ALIGN 0
    4960 #define TMPL_MEM_TYPE_SIZE  1
    4961 #define TMPL_MEM_FN_SUFF    U8
    4962 #define TMPL_MEM_FMT_TYPE   "%#04x"
    4963 #define TMPL_MEM_FMT_DESC   "byte"
    4964 #include "../VMMAll/IEMAllMemRWTmplInline.cpp.h"
    4965 
    4966 #define TMPL_MEM_WITH_STACK
    4967 
    4968 #define TMPL_MEM_TYPE       uint16_t
    4969 #define TMPL_MEM_TYPE_ALIGN 1
    4970 #define TMPL_MEM_TYPE_SIZE  2
    4971 #define TMPL_MEM_FN_SUFF    U16
    4972 #define TMPL_MEM_FMT_TYPE   "%#06x"
    4973 #define TMPL_MEM_FMT_DESC   "word"
    4974 #include "../VMMAll/IEMAllMemRWTmplInline.cpp.h"
    4975 
    4976 #define TMPL_WITH_PUSH_SREG
    4977 #define TMPL_MEM_TYPE       uint32_t
    4978 #define TMPL_MEM_TYPE_ALIGN 3
    4979 #define TMPL_MEM_TYPE_SIZE  4
    4980 #define TMPL_MEM_FN_SUFF    U32
    4981 #define TMPL_MEM_FMT_TYPE   "%#010x"
    4982 #define TMPL_MEM_FMT_DESC   "dword"
    4983 #include "../VMMAll/IEMAllMemRWTmplInline.cpp.h"
    4984 #undef  TMPL_WITH_PUSH_SREG
    4985 
    4986 #define TMPL_MEM_TYPE       uint64_t
    4987 #define TMPL_MEM_TYPE_ALIGN 7
    4988 #define TMPL_MEM_TYPE_SIZE  8
    4989 #define TMPL_MEM_FN_SUFF    U64
    4990 #define TMPL_MEM_FMT_TYPE   "%#018RX64"
    4991 #define TMPL_MEM_FMT_DESC   "qword"
    4992 #include "../VMMAll/IEMAllMemRWTmplInline.cpp.h"
    4993 
    4994 #undef TMPL_MEM_WITH_STACK
    4995 #undef TMPL_MEM_WITH_ATOMIC_MAPPING
    4996 
    4997 #define TMPL_MEM_NO_MAPPING /* currently sticky */
    4998 
    4999 #define TMPL_MEM_NO_STORE
    5000 #define TMPL_MEM_TYPE       uint32_t
    5001 #define TMPL_MEM_TYPE_ALIGN 0
    5002 #define TMPL_MEM_TYPE_SIZE  4
    5003 #define TMPL_MEM_FN_SUFF    U32NoAc
    5004 #define TMPL_MEM_FMT_TYPE   "%#010x"
    5005 #define TMPL_MEM_FMT_DESC   "dword"
    5006 #include "../VMMAll/IEMAllMemRWTmplInline.cpp.h"
    5007 
    5008 #define TMPL_MEM_NO_STORE
    5009 #define TMPL_MEM_TYPE       uint64_t
    5010 #define TMPL_MEM_TYPE_ALIGN 0
    5011 #define TMPL_MEM_TYPE_SIZE  8
    5012 #define TMPL_MEM_FN_SUFF    U64NoAc
    5013 #define TMPL_MEM_FMT_TYPE   "%#018RX64"
    5014 #define TMPL_MEM_FMT_DESC   "qword"
    5015 #include "../VMMAll/IEMAllMemRWTmplInline.cpp.h"
    5016 
    5017 #define TMPL_MEM_NO_STORE
    5018 #define TMPL_MEM_TYPE       uint64_t
    5019 #define TMPL_MEM_TYPE_ALIGN 15
    5020 #define TMPL_MEM_TYPE_SIZE  8
    5021 #define TMPL_MEM_FN_SUFF    U64AlignedU128
    5022 #define TMPL_MEM_FMT_TYPE   "%#018RX64"
    5023 #define TMPL_MEM_FMT_DESC   "qword"
    5024 #include "../VMMAll/IEMAllMemRWTmplInline.cpp.h"
    5025 
    5026 #undef TMPL_MEM_NO_MAPPING
    5027 
    5028 #define TMPL_MEM_TYPE       RTFLOAT80U
    5029 #define TMPL_MEM_TYPE_ALIGN 7
    5030 #define TMPL_MEM_TYPE_SIZE  10
    5031 #define TMPL_MEM_FN_SUFF    R80
    5032 #define TMPL_MEM_FMT_TYPE   "%.10Rhxs"
    5033 #define TMPL_MEM_FMT_DESC   "tword"
    5034 #include "../VMMAll/IEMAllMemRWTmplInline.cpp.h"
    5035 
    5036 #define TMPL_MEM_TYPE       RTPBCD80U
    5037 #define TMPL_MEM_TYPE_ALIGN 7           /** @todo RTPBCD80U alignment testcase */
    5038 #define TMPL_MEM_TYPE_SIZE  10
    5039 #define TMPL_MEM_FN_SUFF    D80
    5040 #define TMPL_MEM_FMT_TYPE   "%.10Rhxs"
    5041 #define TMPL_MEM_FMT_DESC   "tword"
    5042 #include "../VMMAll/IEMAllMemRWTmplInline.cpp.h"
    5043 
    5044 #define TMPL_MEM_WITH_ATOMIC_MAPPING
    5045 #define TMPL_MEM_TYPE       RTUINT128U
    5046 #define TMPL_MEM_TYPE_ALIGN 15
    5047 #define TMPL_MEM_TYPE_SIZE  16
    5048 #define TMPL_MEM_FN_SUFF    U128
    5049 #define TMPL_MEM_FMT_TYPE   "%.16Rhxs"
    5050 #define TMPL_MEM_FMT_DESC   "dqword"
    5051 #include "../VMMAll/IEMAllMemRWTmplInline.cpp.h"
    5052 #undef  TMPL_MEM_WITH_ATOMIC_MAPPING
    5053 
    5054 #define TMPL_MEM_NO_MAPPING
    5055 #define TMPL_MEM_TYPE       RTUINT128U
    5056 #define TMPL_MEM_TYPE_ALIGN 0
    5057 #define TMPL_MEM_TYPE_SIZE  16
    5058 #define TMPL_MEM_FN_SUFF    U128NoAc
    5059 #define TMPL_MEM_FMT_TYPE   "%.16Rhxs"
    5060 #define TMPL_MEM_FMT_DESC   "dqword"
    5061 #include "../VMMAll/IEMAllMemRWTmplInline.cpp.h"
    5062 #undef TMPL_MEM_NO_MAPPING
    5063 
    5064 
    5065 /* Every template relying on unaligned accesses inside a page not being okay should go below. */
    5066 #undef TMPL_MEM_CHECK_UNALIGNED_WITHIN_PAGE_OK
    5067 #define TMPL_MEM_CHECK_UNALIGNED_WITHIN_PAGE_OK(a_pVCpu, a_GCPtrEff, a_TmplMemType) 0
    5068 
    5069 #define TMPL_MEM_NO_MAPPING
    5070 #define TMPL_MEM_TYPE       RTUINT128U
    5071 #define TMPL_MEM_TYPE_ALIGN 15
    5072 #define TMPL_MEM_TYPE_SIZE  16
    5073 #define TMPL_MEM_FN_SUFF    U128AlignedSse
    5074 #define TMPL_MEM_FMT_TYPE   "%.16Rhxs"
    5075 #define TMPL_MEM_FMT_DESC   "dqword"
    5076 #include "../VMMAll/IEMAllMemRWTmplInline.cpp.h"
    5077 #undef  TMPL_MEM_NO_MAPPING
    5078 
    5079 #define TMPL_MEM_NO_MAPPING
    5080 #define TMPL_MEM_TYPE       RTUINT256U
    5081 #define TMPL_MEM_TYPE_ALIGN 0
    5082 #define TMPL_MEM_TYPE_SIZE  32
    5083 #define TMPL_MEM_FN_SUFF    U256NoAc
    5084 #define TMPL_MEM_FMT_TYPE   "%.32Rhxs"
    5085 #define TMPL_MEM_FMT_DESC   "qqword"
    5086 #include "../VMMAll/IEMAllMemRWTmplInline.cpp.h"
    5087 #undef TMPL_MEM_NO_MAPPING
    5088 
    5089 #define TMPL_MEM_NO_MAPPING
    5090 #define TMPL_MEM_TYPE       RTUINT256U
    5091 #define TMPL_MEM_TYPE_ALIGN 31
    5092 #define TMPL_MEM_TYPE_SIZE  32
    5093 #define TMPL_MEM_FN_SUFF    U256AlignedAvx
    5094 #define TMPL_MEM_FMT_TYPE   "%.32Rhxs"
    5095 #define TMPL_MEM_FMT_DESC   "qqword"
    5096 #include "../VMMAll/IEMAllMemRWTmplInline.cpp.h"
    5097 #undef TMPL_MEM_NO_MAPPING
    5098 
    5099 #undef TMPL_MEM_CHECK_UNALIGNED_WITHIN_PAGE_OK
    5100 
    5101 /** @} */
    5102 
    5103 
    5104 #ifdef VBOX_WITH_NESTED_HWVIRT_VMX
    5105 
    5106 /**
    5107  * Gets CR0 fixed-0 bits in VMX operation.
    5108  *
    5109  * We do this rather than fetching what we report to the guest (in
    5110  * IA32_VMX_CR0_FIXED0 MSR) because real hardware (and so do we) report the same
    5111  * values regardless of whether unrestricted-guest feature is available on the CPU.
    5112  *
    5113  * @returns CR0 fixed-0 bits.
    5114  * @param   pVCpu               The cross context virtual CPU structure.
    5115  * @param   fVmxNonRootMode     Whether the CR0 fixed-0 bits for VMX non-root mode
    5116  *                              must be returned. When @c false, the CR0 fixed-0
    5117  *                              bits for VMX root mode is returned.
    5118  *
    5119  */
    5120 DECLINLINE(uint64_t) iemVmxGetCr0Fixed0(PCVMCPUCC pVCpu, bool fVmxNonRootMode) RT_NOEXCEPT
    5121 {
    5122     Assert(IEM_VMX_IS_ROOT_MODE(pVCpu));
    5123 
    5124     PCVMXMSRS  pMsrs = &pVCpu->cpum.GstCtx.hwvirt.vmx.Msrs;
    5125     if (    fVmxNonRootMode
    5126         && (pMsrs->ProcCtls2.n.allowed1 & VMX_PROC_CTLS2_UNRESTRICTED_GUEST))
    5127         return VMX_V_CR0_FIXED0_UX;
    5128     return VMX_V_CR0_FIXED0;
    5129 }
    5130 
    5131 
    5132 # ifdef XAPIC_OFF_END /* Requires VBox/apic.h to be included before IEMInline.h. */
    5133 /**
    5134  * Sets virtual-APIC write emulation as pending.
    5135  *
    5136  * @param   pVCpu       The cross context virtual CPU structure.
    5137  * @param   offApic     The offset in the virtual-APIC page that was written.
    5138  */
    5139 DECLINLINE(void) iemVmxVirtApicSetPendingWrite(PVMCPUCC pVCpu, uint16_t offApic) RT_NOEXCEPT
    5140 {
    5141     Assert(offApic < XAPIC_OFF_END + 4);
    5142 
    5143     /*
    5144      * Record the currently updated APIC offset, as we need this later for figuring
    5145      * out whether to perform TPR, EOI or self-IPI virtualization as well as well
    5146      * as for supplying the exit qualification when causing an APIC-write VM-exit.
    5147      */
    5148     pVCpu->cpum.GstCtx.hwvirt.vmx.offVirtApicWrite = offApic;
    5149 
    5150     /*
    5151      * Flag that we need to perform virtual-APIC write emulation (TPR/PPR/EOI/Self-IPI
    5152      * virtualization or APIC-write emulation).
    5153      */
    5154     if (!VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_VMX_APIC_WRITE))
    5155         VMCPU_FF_SET(pVCpu, VMCPU_FF_VMX_APIC_WRITE);
    5156 }
    5157 # endif /* XAPIC_OFF_END */
    5158 
    5159 #endif /* VBOX_WITH_NESTED_HWVIRT_VMX */
    5160 
    5161 #if defined(IEM_WITH_TLB_TRACE) && defined(IN_RING3)
    5162 /**
    5163  * Adds an entry to the TLB trace buffer.
    5164  *
    5165  * @note Don't use directly, only via the IEMTLBTRACE_XXX macros.
    5166  */
    5167 DECLINLINE(void) iemTlbTrace(PVMCPU pVCpu, IEMTLBTRACETYPE enmType, uint64_t u64Param, uint64_t u64Param2 = 0,
    5168                              uint8_t bParam = 0, uint32_t u32Param = 0/*, uint16_t u16Param = 0 */)
    5169 {
    5170     uint32_t const          fMask  = RT_BIT_32(pVCpu->iem.s.cTlbTraceEntriesShift) - 1;
    5171     PIEMTLBTRACEENTRY const pEntry = &pVCpu->iem.s.paTlbTraceEntries[pVCpu->iem.s.idxTlbTraceEntry++ & fMask];
    5172     pEntry->u64Param  = u64Param;
    5173     pEntry->u64Param2 = u64Param2;
    5174     pEntry->u16Param  = 0; //u16Param;
    5175     pEntry->u32Param  = u32Param;
    5176     pEntry->bParam    = bParam;
    5177     pEntry->enmType   = enmType;
    5178     pEntry->rip       = pVCpu->cpum.GstCtx.rip + pVCpu->cpum.GstCtx.cs.u64Base;
    5179 }
    5180 #endif
    5181 
    5182 #endif /* !VMM_INCLUDED_SRC_include_IEMInline_h */
     1092#endif /* !VMM_INCLUDED_SRC_VMMAll_target_x86_IEMInlineDecode_x86_h */
  • trunk/src/VBox/VMM/VMMAll/target-x86/IEMInlineMem-x86.h

    r108255 r108260  
    11/* $Id$ */
    22/** @file
    3  * IEM - Interpreted Execution Manager - Inlined Functions.
     3 * IEM - Interpreted Execution Manager - Inlined Memory Functions, x86 target.
    44 */
    55
     
    2626 */
    2727
    28 #ifndef VMM_INCLUDED_SRC_include_IEMInline_h
    29 #define VMM_INCLUDED_SRC_include_IEMInline_h
     28#ifndef VMM_INCLUDED_SRC_VMMAll_target_x86_IEMInlineMem_x86_h
     29#define VMM_INCLUDED_SRC_VMMAll_target_x86_IEMInlineMem_x86_h
    3030#ifndef RT_WITHOUT_PRAGMA_ONCE
    3131# pragma once
    3232#endif
    3333
    34 #include <VBox/err.h>
    35 
    36 
    37 /**
    38  * Makes status code addjustments (pass up from I/O and access handler)
    39  * as well as maintaining statistics.
    40  *
    41  * @returns Strict VBox status code to pass up.
    42  * @param   pVCpu       The cross context virtual CPU structure of the calling thread.
    43  * @param   rcStrict    The status from executing an instruction.
    44  */
    45 DECL_FORCE_INLINE(VBOXSTRICTRC) iemExecStatusCodeFiddling(PVMCPUCC pVCpu, VBOXSTRICTRC rcStrict) RT_NOEXCEPT
    46 {
    47     if (rcStrict != VINF_SUCCESS)
    48     {
    49         /* Deal with the cases that should be treated as VINF_SUCCESS first. */
    50         if (   rcStrict == VINF_IEM_YIELD_PENDING_FF
    51 #ifdef VBOX_WITH_NESTED_HWVIRT_VMX /** @todo r=bird: Why do we need TWO status codes here? */
    52             || rcStrict == VINF_VMX_VMEXIT
    53 #endif
    54 #ifdef VBOX_WITH_NESTED_HWVIRT_SVM
    55             || rcStrict == VINF_SVM_VMEXIT
    56 #endif
    57             )
    58         {
    59             rcStrict = pVCpu->iem.s.rcPassUp;
    60             if (RT_LIKELY(rcStrict == VINF_SUCCESS))
    61             { /* likely */ }
    62             else
    63                 pVCpu->iem.s.cRetPassUpStatus++;
    64         }
    65         else if (RT_SUCCESS(rcStrict))
    66         {
    67             AssertMsg(   (rcStrict >= VINF_EM_FIRST && rcStrict <= VINF_EM_LAST)
    68                       || rcStrict == VINF_IOM_R3_IOPORT_READ
    69                       || rcStrict == VINF_IOM_R3_IOPORT_WRITE
    70                       || rcStrict == VINF_IOM_R3_IOPORT_COMMIT_WRITE
    71                       || rcStrict == VINF_IOM_R3_MMIO_READ
    72                       || rcStrict == VINF_IOM_R3_MMIO_READ_WRITE
    73                       || rcStrict == VINF_IOM_R3_MMIO_WRITE
    74                       || rcStrict == VINF_IOM_R3_MMIO_COMMIT_WRITE
    75                       || rcStrict == VINF_CPUM_R3_MSR_READ
    76                       || rcStrict == VINF_CPUM_R3_MSR_WRITE
    77                       || rcStrict == VINF_EM_RAW_EMULATE_INSTR
    78                       || rcStrict == VINF_EM_RAW_TO_R3
    79                       || rcStrict == VINF_EM_TRIPLE_FAULT
    80                       || rcStrict == VINF_EM_EMULATE_SPLIT_LOCK
    81                       || rcStrict == VINF_GIM_R3_HYPERCALL
    82                       /* raw-mode / virt handlers only: */
    83                       || rcStrict == VINF_EM_RAW_EMULATE_INSTR_GDT_FAULT
    84                       || rcStrict == VINF_EM_RAW_EMULATE_INSTR_TSS_FAULT
    85                       || rcStrict == VINF_EM_RAW_EMULATE_INSTR_LDT_FAULT
    86                       || rcStrict == VINF_EM_RAW_EMULATE_INSTR_IDT_FAULT
    87                       || rcStrict == VINF_SELM_SYNC_GDT
    88                       || rcStrict == VINF_CSAM_PENDING_ACTION
    89                       || rcStrict == VINF_PATM_CHECK_PATCH_PAGE
    90                       /* nested hw.virt codes: */
    91                       || rcStrict == VINF_VMX_INTERCEPT_NOT_ACTIVE
    92                       || rcStrict == VINF_VMX_MODIFIES_BEHAVIOR
    93                       , ("rcStrict=%Rrc\n", VBOXSTRICTRC_VAL(rcStrict)));
    94 /** @todo adjust for VINF_EM_RAW_EMULATE_INSTR. */
    95             int32_t const rcPassUp = pVCpu->iem.s.rcPassUp;
    96             if (rcPassUp == VINF_SUCCESS)
    97                 pVCpu->iem.s.cRetInfStatuses++;
    98             else if (   rcPassUp < VINF_EM_FIRST
    99                      || rcPassUp > VINF_EM_LAST
    100                      || rcPassUp < VBOXSTRICTRC_VAL(rcStrict))
    101             {
    102                 LogEx(LOG_GROUP_IEM,("IEM: rcPassUp=%Rrc! rcStrict=%Rrc\n", rcPassUp, VBOXSTRICTRC_VAL(rcStrict)));
    103                 pVCpu->iem.s.cRetPassUpStatus++;
    104                 rcStrict = rcPassUp;
    105             }
    106             else
    107             {
    108                 LogEx(LOG_GROUP_IEM,("IEM: rcPassUp=%Rrc  rcStrict=%Rrc!\n", rcPassUp, VBOXSTRICTRC_VAL(rcStrict)));
    109                 pVCpu->iem.s.cRetInfStatuses++;
    110             }
    111         }
    112         else if (rcStrict == VERR_IEM_ASPECT_NOT_IMPLEMENTED)
    113             pVCpu->iem.s.cRetAspectNotImplemented++;
    114         else if (rcStrict == VERR_IEM_INSTR_NOT_IMPLEMENTED)
    115             pVCpu->iem.s.cRetInstrNotImplemented++;
    116         else
    117             pVCpu->iem.s.cRetErrStatuses++;
    118     }
    119     else
    120     {
    121         rcStrict = pVCpu->iem.s.rcPassUp;
    122         if (rcStrict != VINF_SUCCESS)
    123             pVCpu->iem.s.cRetPassUpStatus++;
    124     }
    125 
    126     /* Just clear it here as well. */
    127     pVCpu->iem.s.rcPassUp = VINF_SUCCESS;
    128 
    129     return rcStrict;
    130 }
    131 
    132 
    133 /**
    134  * Sets the pass up status.
    135  *
    136  * @returns VINF_SUCCESS.
    137  * @param   pVCpu               The cross context virtual CPU structure of the
    138  *                              calling thread.
    139  * @param   rcPassUp            The pass up status.  Must be informational.
    140  *                              VINF_SUCCESS is not allowed.
    141  */
    142 DECLINLINE(int) iemSetPassUpStatus(PVMCPUCC pVCpu, VBOXSTRICTRC rcPassUp) RT_NOEXCEPT
    143 {
    144     AssertRC(VBOXSTRICTRC_VAL(rcPassUp)); Assert(rcPassUp != VINF_SUCCESS);
    145 
    146     int32_t const rcOldPassUp = pVCpu->iem.s.rcPassUp;
    147     if (rcOldPassUp == VINF_SUCCESS)
    148         pVCpu->iem.s.rcPassUp = VBOXSTRICTRC_VAL(rcPassUp);
    149     /* If both are EM scheduling codes, use EM priority rules. */
    150     else if (   rcOldPassUp >= VINF_EM_FIRST && rcOldPassUp <= VINF_EM_LAST
    151              && rcPassUp    >= VINF_EM_FIRST && rcPassUp    <= VINF_EM_LAST)
    152     {
    153         if (rcPassUp < rcOldPassUp)
    154         {
    155             LogEx(LOG_GROUP_IEM,("IEM: rcPassUp=%Rrc! rcOldPassUp=%Rrc\n", VBOXSTRICTRC_VAL(rcPassUp), rcOldPassUp));
    156             pVCpu->iem.s.rcPassUp = VBOXSTRICTRC_VAL(rcPassUp);
    157         }
    158         else
    159             LogEx(LOG_GROUP_IEM,("IEM: rcPassUp=%Rrc  rcOldPassUp=%Rrc!\n", VBOXSTRICTRC_VAL(rcPassUp), rcOldPassUp));
    160     }
    161     /* Override EM scheduling with specific status code. */
    162     else if (rcOldPassUp >= VINF_EM_FIRST && rcOldPassUp <= VINF_EM_LAST)
    163     {
    164         LogEx(LOG_GROUP_IEM,("IEM: rcPassUp=%Rrc! rcOldPassUp=%Rrc\n", VBOXSTRICTRC_VAL(rcPassUp), rcOldPassUp));
    165         pVCpu->iem.s.rcPassUp = VBOXSTRICTRC_VAL(rcPassUp);
    166     }
    167     /* Don't override specific status code, first come first served. */
    168     else
    169         LogEx(LOG_GROUP_IEM,("IEM: rcPassUp=%Rrc  rcOldPassUp=%Rrc!\n", VBOXSTRICTRC_VAL(rcPassUp), rcOldPassUp));
    170     return VINF_SUCCESS;
    171 }
    172 
    173 
    174 /**
    175  * Calculates the IEM_F_X86_AC flags.
    176  *
    177  * @returns IEM_F_X86_AC or zero
    178  * @param   pVCpu               The cross context virtual CPU structure of the
    179  *                              calling thread.
    180  */
    181 DECL_FORCE_INLINE(uint32_t) iemCalcExecAcFlag(PVMCPUCC pVCpu) RT_NOEXCEPT
    182 {
    183     IEM_CTX_ASSERT(pVCpu, CPUMCTX_EXTRN_CR0 | CPUMCTX_EXTRN_RFLAGS);
    184     Assert(CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pVCpu, &pVCpu->cpum.GstCtx.ss));
    185 
    186     if (   !pVCpu->cpum.GstCtx.eflags.Bits.u1AC
    187         || (pVCpu->cpum.GstCtx.cr0 & (X86_CR0_AM | X86_CR0_PE)) != (X86_CR0_AM | X86_CR0_PE)
    188         || (   !pVCpu->cpum.GstCtx.eflags.Bits.u1VM
    189             && pVCpu->cpum.GstCtx.ss.Attr.n.u2Dpl != 3))
    190         return 0;
    191     return IEM_F_X86_AC;
    192 }
    193 
    194 
    195 /**
    196  * Calculates the IEM_F_MODE_X86_32BIT_FLAT flag.
    197  *
    198  * Checks if CS, SS, DS and SS are all wide open flat 32-bit segments. This will
    199  * reject expand down data segments and conforming code segments.
    200  *
    201  * ASSUMES that the CPU is in 32-bit mode.
    202  *
    203  * @note    Will return zero when if any of the segment register state is marked
    204  *          external, this must be factored into assertions checking fExec
    205  *          consistency.
    206  *
    207  * @returns IEM_F_MODE_X86_32BIT_FLAT or zero.
    208  * @param   pVCpu               The cross context virtual CPU structure of the
    209  *                              calling thread.
    210  * @sa      iemCalc32BitFlatIndicatorEsDs
    211  */
    212 DECL_FORCE_INLINE(uint32_t) iemCalc32BitFlatIndicator(PVMCPUCC pVCpu) RT_NOEXCEPT
    213 {
    214     AssertCompile(X86_SEL_TYPE_DOWN == X86_SEL_TYPE_CONF);
    215     return (  (    pVCpu->cpum.GstCtx.es.Attr.u
    216                  | pVCpu->cpum.GstCtx.cs.Attr.u
    217                  | pVCpu->cpum.GstCtx.ss.Attr.u
    218                  | pVCpu->cpum.GstCtx.ds.Attr.u)
    219               & (X86_SEL_TYPE_ACCESSED | X86DESCATTR_G | X86DESCATTR_D | X86DESCATTR_P | X86_SEL_TYPE_DOWN | X86DESCATTR_UNUSABLE))
    220            ==   (X86_SEL_TYPE_ACCESSED | X86DESCATTR_G | X86DESCATTR_D | X86DESCATTR_P)
    221         &&    (  (pVCpu->cpum.GstCtx.es.u32Limit + 1)
    222                | (pVCpu->cpum.GstCtx.cs.u32Limit + 1)
    223                | (pVCpu->cpum.GstCtx.ss.u32Limit + 1)
    224                | (pVCpu->cpum.GstCtx.ds.u32Limit + 1))
    225            == 0
    226         &&    (  pVCpu->cpum.GstCtx.es.u64Base
    227                | pVCpu->cpum.GstCtx.cs.u64Base
    228                | pVCpu->cpum.GstCtx.ss.u64Base
    229                | pVCpu->cpum.GstCtx.ds.u64Base)
    230            == 0
    231         && !(pVCpu->cpum.GstCtx.fExtrn & (CPUMCTX_EXTRN_ES | CPUMCTX_EXTRN_CS | CPUMCTX_EXTRN_SS | CPUMCTX_EXTRN_ES))
    232         ? IEM_F_MODE_X86_32BIT_FLAT : 0;
    233 }
    234 
    235 
    236 /**
    237  * Calculates the IEM_F_MODE_X86_32BIT_FLAT flag, ASSUMING the CS and SS are
    238  * flat already.
    239  *
    240  * This is used by sysenter.
    241  *
    242  * @note    Will return zero when if any of the segment register state is marked
    243  *          external, this must be factored into assertions checking fExec
    244  *          consistency.
    245  *
    246  * @returns IEM_F_MODE_X86_32BIT_FLAT or zero.
    247  * @param   pVCpu               The cross context virtual CPU structure of the
    248  *                              calling thread.
    249  * @sa      iemCalc32BitFlatIndicator
    250  */
    251 DECL_FORCE_INLINE(uint32_t) iemCalc32BitFlatIndicatorEsDs(PVMCPUCC pVCpu) RT_NOEXCEPT
    252 {
    253     AssertCompile(X86_SEL_TYPE_DOWN == X86_SEL_TYPE_CONF);
    254     return (  (    pVCpu->cpum.GstCtx.es.Attr.u
    255                  | pVCpu->cpum.GstCtx.ds.Attr.u)
    256               & (X86_SEL_TYPE_ACCESSED | X86DESCATTR_G | X86DESCATTR_D | X86DESCATTR_P | X86_SEL_TYPE_DOWN | X86DESCATTR_UNUSABLE))
    257            ==   (X86_SEL_TYPE_ACCESSED | X86DESCATTR_G | X86DESCATTR_D | X86DESCATTR_P)
    258         &&    (  (pVCpu->cpum.GstCtx.es.u32Limit + 1)
    259                | (pVCpu->cpum.GstCtx.ds.u32Limit + 1))
    260            == 0
    261         &&    (  pVCpu->cpum.GstCtx.es.u64Base
    262                | pVCpu->cpum.GstCtx.ds.u64Base)
    263            == 0
    264         && !(pVCpu->cpum.GstCtx.fExtrn & (CPUMCTX_EXTRN_ES | CPUMCTX_EXTRN_CS | CPUMCTX_EXTRN_SS | CPUMCTX_EXTRN_ES))
    265         ? IEM_F_MODE_X86_32BIT_FLAT : 0;
    266 }
    267 
    268 
    269 /**
    270  * Calculates the IEM_F_MODE_XXX, CPL and AC flags.
    271  *
    272  * @returns IEM_F_MODE_XXX, IEM_F_X86_CPL_MASK and IEM_F_X86_AC.
    273  * @param   pVCpu               The cross context virtual CPU structure of the
    274  *                              calling thread.
    275  */
    276 DECL_FORCE_INLINE(uint32_t) iemCalcExecModeAndCplFlags(PVMCPUCC pVCpu) RT_NOEXCEPT
    277 {
    278     /*
    279      * We're duplicates code from CPUMGetGuestCPL and CPUMIsGuestIn64BitCodeEx
    280      * here to try get this done as efficiently as possible.
    281      */
    282     IEM_CTX_ASSERT(pVCpu, CPUMCTX_EXTRN_CR0 | CPUMCTX_EXTRN_EFER | CPUMCTX_EXTRN_RFLAGS | CPUMCTX_EXTRN_SS | CPUMCTX_EXTRN_CS);
    283 
    284     if (pVCpu->cpum.GstCtx.cr0 & X86_CR0_PE)
    285     {
    286         if (!pVCpu->cpum.GstCtx.eflags.Bits.u1VM)
    287         {
    288             Assert(CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pVCpu, &pVCpu->cpum.GstCtx.ss));
    289             uint32_t fExec = ((uint32_t)pVCpu->cpum.GstCtx.ss.Attr.n.u2Dpl << IEM_F_X86_CPL_SHIFT);
    290             if (   !pVCpu->cpum.GstCtx.eflags.Bits.u1AC
    291                 || !(pVCpu->cpum.GstCtx.cr0 & X86_CR0_AM)
    292                 || fExec != (3U << IEM_F_X86_CPL_SHIFT))
    293             { /* likely */ }
    294             else
    295                 fExec |= IEM_F_X86_AC;
    296 
    297             if (pVCpu->cpum.GstCtx.cs.Attr.n.u1DefBig)
    298             {
    299                 Assert(!pVCpu->cpum.GstCtx.cs.Attr.n.u1Long || !(pVCpu->cpum.GstCtx.msrEFER & MSR_K6_EFER_LMA));
    300                 fExec |= IEM_F_MODE_X86_32BIT_PROT | iemCalc32BitFlatIndicator(pVCpu);
    301             }
    302             else if (   pVCpu->cpum.GstCtx.cs.Attr.n.u1Long
    303                      && (pVCpu->cpum.GstCtx.msrEFER & MSR_K6_EFER_LMA))
    304                 fExec |= IEM_F_MODE_X86_64BIT;
    305             else if (IEM_GET_TARGET_CPU(pVCpu) >= IEMTARGETCPU_386)
    306                 fExec |= IEM_F_MODE_X86_16BIT_PROT;
    307             else
    308                 fExec |= IEM_F_MODE_X86_16BIT_PROT_PRE_386;
    309             return fExec;
    310         }
    311         if (   !pVCpu->cpum.GstCtx.eflags.Bits.u1AC
    312             || !(pVCpu->cpum.GstCtx.cr0 & X86_CR0_AM))
    313             return IEM_F_MODE_X86_16BIT_PROT_V86 | (UINT32_C(3) << IEM_F_X86_CPL_SHIFT);
    314         return IEM_F_MODE_X86_16BIT_PROT_V86 | (UINT32_C(3) << IEM_F_X86_CPL_SHIFT) | IEM_F_X86_AC;
    315     }
    316 
    317     /* Real mode is zero; CPL set to 3 for VT-x real-mode emulation. */
    318     if (RT_LIKELY(!pVCpu->cpum.GstCtx.cs.Attr.n.u1DefBig))
    319     {
    320         if (IEM_GET_TARGET_CPU(pVCpu) >= IEMTARGETCPU_386)
    321             return IEM_F_MODE_X86_16BIT;
    322         return IEM_F_MODE_X86_16BIT_PRE_386;
    323     }
    324 
    325     /* 32-bit unreal mode. */
    326     return IEM_F_MODE_X86_32BIT | iemCalc32BitFlatIndicator(pVCpu);
    327 }
    328 
    329 
    330 /**
    331  * Calculates the AMD-V and VT-x related context flags.
    332  *
    333  * @returns 0 or a combination of IEM_F_X86_CTX_IN_GUEST, IEM_F_X86_CTX_SVM and
    334  *          IEM_F_X86_CTX_VMX.
    335  * @param   pVCpu               The cross context virtual CPU structure of the
    336  *                              calling thread.
    337  */
    338 DECL_FORCE_INLINE(uint32_t) iemCalcExecHwVirtFlags(PVMCPUCC pVCpu) RT_NOEXCEPT
    339 {
    340     /*
    341      * This duplicates code from CPUMIsGuestVmxEnabled, CPUMIsGuestSvmEnabled
    342      * and CPUMIsGuestInNestedHwvirtMode to some extent.
    343      */
    344     IEM_CTX_ASSERT(pVCpu, CPUMCTX_EXTRN_CR4 | CPUMCTX_EXTRN_EFER);
    345 
    346     AssertCompile(X86_CR4_VMXE != MSR_K6_EFER_SVME);
    347     uint64_t const fTmp = (pVCpu->cpum.GstCtx.cr4     & X86_CR4_VMXE)
    348                         | (pVCpu->cpum.GstCtx.msrEFER & MSR_K6_EFER_SVME);
    349     if (RT_LIKELY(!fTmp))
    350         return 0; /* likely */
    351 
    352     if (fTmp & X86_CR4_VMXE)
    353     {
    354         Assert(pVCpu->cpum.GstCtx.hwvirt.enmHwvirt == CPUMHWVIRT_VMX);
    355         if (pVCpu->cpum.GstCtx.hwvirt.vmx.fInVmxNonRootMode)
    356             return IEM_F_X86_CTX_VMX | IEM_F_X86_CTX_IN_GUEST;
    357         return IEM_F_X86_CTX_VMX;
    358     }
    359 
    360     Assert(pVCpu->cpum.GstCtx.hwvirt.enmHwvirt == CPUMHWVIRT_SVM);
    361     if (pVCpu->cpum.GstCtx.hwvirt.svm.Vmcb.ctrl.u64InterceptCtrl & SVM_CTRL_INTERCEPT_VMRUN)
    362         return IEM_F_X86_CTX_SVM | IEM_F_X86_CTX_IN_GUEST;
    363     return IEM_F_X86_CTX_SVM;
    364 }
    365 
    366 #ifdef VBOX_INCLUDED_vmm_dbgf_h /* VM::dbgf.ro.cEnabledHwBreakpoints is only accessible if VBox/vmm/dbgf.h is included. */
    367 
    368 /**
    369  * Calculates IEM_F_BRK_PENDING_XXX (IEM_F_PENDING_BRK_MASK) flags.
    370  *
    371  * @returns IEM_F_BRK_PENDING_XXX or zero.
    372  * @param   pVCpu               The cross context virtual CPU structure of the
    373  *                              calling thread.
    374  */
    375 DECL_FORCE_INLINE(uint32_t) iemCalcExecDbgFlags(PVMCPUCC pVCpu) RT_NOEXCEPT
    376 {
    377     IEM_CTX_ASSERT(pVCpu, CPUMCTX_EXTRN_DR7);
    378 
    379     if (RT_LIKELY(   !(pVCpu->cpum.GstCtx.dr[7] & X86_DR7_ENABLED_MASK)
    380                   && pVCpu->CTX_SUFF(pVM)->dbgf.ro.cEnabledHwBreakpoints == 0))
    381         return 0;
    382     return iemCalcExecDbgFlagsSlow(pVCpu);
    383 }
    384 
    385 /**
    386  * Calculates the the IEM_F_XXX flags.
    387  *
    388  * @returns IEM_F_XXX combination match the current CPU state.
    389  * @param   pVCpu               The cross context virtual CPU structure of the
    390  *                              calling thread.
    391  */
    392 DECL_FORCE_INLINE(uint32_t) iemCalcExecFlags(PVMCPUCC pVCpu) RT_NOEXCEPT
    393 {
    394     return iemCalcExecModeAndCplFlags(pVCpu)
    395          | iemCalcExecHwVirtFlags(pVCpu)
    396          /* SMM is not yet implemented */
    397          | iemCalcExecDbgFlags(pVCpu)
    398          ;
    399 }
    400 
    401 
    402 /**
    403  * Re-calculates the MODE and CPL parts of IEMCPU::fExec.
    404  *
    405  * @param   pVCpu               The cross context virtual CPU structure of the
    406  *                              calling thread.
    407  */
    408 DECL_FORCE_INLINE(void) iemRecalcExecModeAndCplAndAcFlags(PVMCPUCC pVCpu)
    409 {
    410     pVCpu->iem.s.fExec = (pVCpu->iem.s.fExec & ~(IEM_F_MODE_MASK | IEM_F_X86_CPL_MASK | IEM_F_X86_AC))
    411                        | iemCalcExecModeAndCplFlags(pVCpu);
    412 }
    413 
    414 
    415 /**
    416  * Re-calculates the IEM_F_PENDING_BRK_MASK part of IEMCPU::fExec.
    417  *
    418  * @param   pVCpu               The cross context virtual CPU structure of the
    419  *                              calling thread.
    420  */
    421 DECL_FORCE_INLINE(void) iemRecalcExecDbgFlags(PVMCPUCC pVCpu)
    422 {
    423     pVCpu->iem.s.fExec = (pVCpu->iem.s.fExec & ~IEM_F_PENDING_BRK_MASK)
    424                        | iemCalcExecDbgFlags(pVCpu);
    425 }
    426 
    427 #endif /* VBOX_INCLUDED_vmm_dbgf_h */
    428 
    429 
    430 #ifndef IEM_WITH_OPAQUE_DECODER_STATE
    431 
    432 # if defined(VBOX_INCLUDED_vmm_dbgf_h) || defined(DOXYGEN_RUNNING) /* dbgf.ro.cEnabledHwBreakpoints */
    433 
    434 /**
    435  * Initializes the execution state.
    436  *
    437  * @param   pVCpu               The cross context virtual CPU structure of the
    438  *                              calling thread.
    439  * @param   fExecOpts           Optional execution flags:
    440  *                                  - IEM_F_BYPASS_HANDLERS
    441  *                                  - IEM_F_X86_DISREGARD_LOCK
    442  *
    443  * @remarks Callers of this must call iemUninitExec() to undo potentially fatal
    444  *          side-effects in strict builds.
    445  */
    446 DECLINLINE(void) iemInitExec(PVMCPUCC pVCpu, uint32_t fExecOpts) RT_NOEXCEPT
    447 {
    448     IEM_CTX_ASSERT(pVCpu, IEM_CPUMCTX_EXTRN_EXEC_DECODED_NO_MEM_MASK);
    449     Assert(!VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_IEM));
    450     Assert(CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pVCpu, &pVCpu->cpum.GstCtx.cs));
    451     Assert(CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pVCpu, &pVCpu->cpum.GstCtx.ss));
    452     Assert(CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pVCpu, &pVCpu->cpum.GstCtx.es));
    453     Assert(CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pVCpu, &pVCpu->cpum.GstCtx.ds));
    454     Assert(CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pVCpu, &pVCpu->cpum.GstCtx.fs));
    455     Assert(CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pVCpu, &pVCpu->cpum.GstCtx.gs));
    456     Assert(CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pVCpu, &pVCpu->cpum.GstCtx.ldtr));
    457     Assert(CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pVCpu, &pVCpu->cpum.GstCtx.tr));
    458 
    459     pVCpu->iem.s.rcPassUp           = VINF_SUCCESS;
    460     pVCpu->iem.s.fExec              = iemCalcExecFlags(pVCpu) | fExecOpts;
    461     pVCpu->iem.s.cActiveMappings    = 0;
    462     pVCpu->iem.s.iNextMapping       = 0;
    463 
    464 #  ifdef VBOX_STRICT
    465     pVCpu->iem.s.enmDefAddrMode     = (IEMMODE)0xfe;
    466     pVCpu->iem.s.enmEffAddrMode     = (IEMMODE)0xfe;
    467     pVCpu->iem.s.enmDefOpSize       = (IEMMODE)0xfe;
    468     pVCpu->iem.s.enmEffOpSize       = (IEMMODE)0xfe;
    469     pVCpu->iem.s.fPrefixes          = 0xfeedbeef;
    470     pVCpu->iem.s.uRexReg            = 127;
    471     pVCpu->iem.s.uRexB              = 127;
    472     pVCpu->iem.s.offModRm           = 127;
    473     pVCpu->iem.s.uRexIndex          = 127;
    474     pVCpu->iem.s.iEffSeg            = 127;
    475     pVCpu->iem.s.idxPrefix          = 127;
    476     pVCpu->iem.s.uVex3rdReg         = 127;
    477     pVCpu->iem.s.uVexLength         = 127;
    478     pVCpu->iem.s.fEvexStuff         = 127;
    479     pVCpu->iem.s.uFpuOpcode         = UINT16_MAX;
    480 #   ifdef IEM_WITH_CODE_TLB
    481     pVCpu->iem.s.offInstrNextByte   = UINT16_MAX;
    482     pVCpu->iem.s.pbInstrBuf         = NULL;
    483     pVCpu->iem.s.cbInstrBuf         = UINT16_MAX;
    484     pVCpu->iem.s.cbInstrBufTotal    = UINT16_MAX;
    485     pVCpu->iem.s.offCurInstrStart   = INT16_MAX;
    486     pVCpu->iem.s.uInstrBufPc        = UINT64_C(0xc0ffc0ffcff0c0ff);
    487 #    ifdef IEM_WITH_CODE_TLB_AND_OPCODE_BUF
    488     pVCpu->iem.s.offOpcode          = 127;
    489 #    endif
    490 #   else
    491     pVCpu->iem.s.offOpcode          = 127;
    492     pVCpu->iem.s.cbOpcode           = 127;
    493 #   endif
    494 #  endif /* VBOX_STRICT */
    495 }
    496 
    497 
    498 #  if defined(VBOX_WITH_NESTED_HWVIRT_SVM) || defined(VBOX_WITH_NESTED_HWVIRT_VMX)
    499 /**
    500  * Performs a minimal reinitialization of the execution state.
    501  *
    502  * This is intended to be used by VM-exits, SMM, LOADALL and other similar
    503  * 'world-switch' types operations on the CPU. Currently only nested
    504  * hardware-virtualization uses it.
    505  *
    506  * @param   pVCpu               The cross context virtual CPU structure of the calling EMT.
    507  * @param   cbInstr             The instruction length (for flushing).
    508  */
    509 DECLINLINE(void) iemReInitExec(PVMCPUCC pVCpu, uint8_t cbInstr) RT_NOEXCEPT
    510 {
    511     pVCpu->iem.s.fExec = iemCalcExecFlags(pVCpu) | (pVCpu->iem.s.fExec & IEM_F_USER_OPTS);
    512     iemOpcodeFlushHeavy(pVCpu, cbInstr);
    513 }
    514 #  endif
    515 
    516 # endif /* VBOX_INCLUDED_vmm_dbgf_h || DOXYGEN_RUNNING */
    517 
    518 /**
    519  * Counterpart to #iemInitExec that undoes evil strict-build stuff.
    520  *
    521  * @param   pVCpu               The cross context virtual CPU structure of the
    522  *                              calling thread.
    523  */
    524 DECLINLINE(void) iemUninitExec(PVMCPUCC pVCpu) RT_NOEXCEPT
    525 {
    526     /* Note! do not touch fInPatchCode here! (see iemUninitExecAndFiddleStatusAndMaybeReenter) */
    527 # ifdef VBOX_STRICT
    528 #  ifdef IEM_WITH_CODE_TLB
    529     NOREF(pVCpu);
    530 #  else
    531     pVCpu->iem.s.cbOpcode = 0;
    532 #  endif
    533 # else
    534     NOREF(pVCpu);
    535 # endif
    536 }
    537 
    538 
    539 /**
    540  * Calls iemUninitExec, iemExecStatusCodeFiddling and iemRCRawMaybeReenter.
    541  *
    542  * Only calling iemRCRawMaybeReenter in raw-mode, obviously.
    543  *
    544  * @returns Fiddled strict vbox status code, ready to return to non-IEM caller.
    545  * @param   pVCpu       The cross context virtual CPU structure of the calling thread.
    546  * @param   rcStrict    The status code to fiddle.
    547  */
    548 DECLINLINE(VBOXSTRICTRC) iemUninitExecAndFiddleStatusAndMaybeReenter(PVMCPUCC pVCpu, VBOXSTRICTRC rcStrict) RT_NOEXCEPT
    549 {
    550     iemUninitExec(pVCpu);
    551     return iemExecStatusCodeFiddling(pVCpu, rcStrict);
    552 }
    553 
    554 
    555 /**
    556  * Macro used by the IEMExec* method to check the given instruction length.
    557  *
    558  * Will return on failure!
    559  *
    560  * @param   a_cbInstr   The given instruction length.
    561  * @param   a_cbMin     The minimum length.
    562  */
    563 # define IEMEXEC_ASSERT_INSTR_LEN_RETURN(a_cbInstr, a_cbMin) \
    564     AssertMsgReturn((unsigned)(a_cbInstr) - (unsigned)(a_cbMin) <= (unsigned)15 - (unsigned)(a_cbMin), \
    565                     ("cbInstr=%u cbMin=%u\n", (a_cbInstr), (a_cbMin)), VERR_IEM_INVALID_INSTR_LENGTH)
    566 
    567 
    568 # ifndef IEM_WITH_SETJMP
    569 
    570 /**
    571  * Fetches the first opcode byte.
    572  *
    573  * @returns Strict VBox status code.
    574  * @param   pVCpu               The cross context virtual CPU structure of the
    575  *                              calling thread.
    576  * @param   pu8                 Where to return the opcode byte.
    577  */
    578 DECLINLINE(VBOXSTRICTRC) iemOpcodeGetFirstU8(PVMCPUCC pVCpu, uint8_t *pu8) RT_NOEXCEPT
    579 {
    580     /*
    581      * Check for hardware instruction breakpoints.
    582      * Note! Guest breakpoints are only checked after POP SS or MOV SS on AMD CPUs.
    583      */
    584     if (RT_LIKELY(!(pVCpu->iem.s.fExec & IEM_F_PENDING_BRK_INSTR)))
    585     { /* likely */ }
    586     else
    587     {
    588         VBOXSTRICTRC rcStrict = DBGFBpCheckInstruction(pVCpu->CTX_SUFF(pVM), pVCpu,
    589                                                        pVCpu->cpum.GstCtx.rip + pVCpu->cpum.GstCtx.cs.u64Base,
    590                                                           !(pVCpu->cpum.GstCtx.rflags.uBoth & CPUMCTX_INHIBIT_SHADOW_SS)
    591                                                        || IEM_IS_GUEST_CPU_AMD(pVCpu));
    592         if (RT_LIKELY(rcStrict == VINF_SUCCESS))
    593         { /* likely */ }
    594         else
    595         {
    596             *pu8 = 0xff; /* shut up gcc. sigh */
    597             if (rcStrict == VINF_EM_RAW_GUEST_TRAP)
    598                 return iemRaiseDebugException(pVCpu);
    599             return rcStrict;
    600         }
    601     }
    602 
    603     /*
    604      * Fetch the first opcode byte.
    605      */
    606     uintptr_t const offOpcode = pVCpu->iem.s.offOpcode;
    607     if (RT_LIKELY((uint8_t)offOpcode < pVCpu->iem.s.cbOpcode))
    608     {
    609         pVCpu->iem.s.offOpcode = (uint8_t)offOpcode + 1;
    610         *pu8 = pVCpu->iem.s.abOpcode[offOpcode];
    611         return VINF_SUCCESS;
    612     }
    613     return iemOpcodeGetNextU8Slow(pVCpu, pu8);
    614 }
    615 
    616 # else  /* IEM_WITH_SETJMP */
    617 
    618 /**
    619  * Fetches the first opcode byte, longjmp on error.
    620  *
    621  * @returns The opcode byte.
    622  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    623  */
    624 DECL_INLINE_THROW(uint8_t) iemOpcodeGetFirstU8Jmp(PVMCPUCC pVCpu) IEM_NOEXCEPT_MAY_LONGJMP
    625 {
    626     /*
    627      * Check for hardware instruction breakpoints.
    628     * Note! Guest breakpoints are only checked after POP SS or MOV SS on AMD CPUs.
    629      */
    630     if (RT_LIKELY(!(pVCpu->iem.s.fExec & IEM_F_PENDING_BRK_INSTR)))
    631     { /* likely */ }
    632     else
    633     {
    634         VBOXSTRICTRC rcStrict = DBGFBpCheckInstruction(pVCpu->CTX_SUFF(pVM), pVCpu,
    635                                                        pVCpu->cpum.GstCtx.rip + pVCpu->cpum.GstCtx.cs.u64Base,
    636                                                           !(pVCpu->cpum.GstCtx.rflags.uBoth & CPUMCTX_INHIBIT_SHADOW_SS)
    637                                                        || IEM_IS_GUEST_CPU_AMD(pVCpu));
    638         if (RT_LIKELY(rcStrict == VINF_SUCCESS))
    639         { /* likely */ }
    640         else
    641         {
    642             if (rcStrict == VINF_EM_RAW_GUEST_TRAP)
    643                 rcStrict = iemRaiseDebugException(pVCpu);
    644             IEM_DO_LONGJMP(pVCpu, VBOXSTRICTRC_VAL(rcStrict));
    645         }
    646     }
    647 
    648     /*
    649      * Fetch the first opcode byte.
    650      */
    651 #  ifdef IEM_WITH_CODE_TLB
    652     uint8_t         bRet;
    653     uintptr_t       offBuf = pVCpu->iem.s.offInstrNextByte;
    654     uint8_t const  *pbBuf  = pVCpu->iem.s.pbInstrBuf;
    655     if (RT_LIKELY(   pbBuf != NULL
    656                   && offBuf < pVCpu->iem.s.cbInstrBuf))
    657     {
    658         pVCpu->iem.s.offInstrNextByte = (uint32_t)offBuf + 1;
    659         bRet = pbBuf[offBuf];
    660     }
    661     else
    662         bRet = iemOpcodeGetNextU8SlowJmp(pVCpu);
    663 #   ifdef IEM_WITH_CODE_TLB_AND_OPCODE_BUF
    664     Assert(pVCpu->iem.s.offOpcode == 0);
    665     pVCpu->iem.s.abOpcode[pVCpu->iem.s.offOpcode++] = bRet;
    666 #   endif
    667     return bRet;
    668 
    669 #  else /* !IEM_WITH_CODE_TLB */
    670     uintptr_t offOpcode = pVCpu->iem.s.offOpcode;
    671     if (RT_LIKELY((uint8_t)offOpcode < pVCpu->iem.s.cbOpcode))
    672     {
    673         pVCpu->iem.s.offOpcode = (uint8_t)offOpcode + 1;
    674         return pVCpu->iem.s.abOpcode[offOpcode];
    675     }
    676     return iemOpcodeGetNextU8SlowJmp(pVCpu);
    677 #  endif
    678 }
    679 
    680 # endif /* IEM_WITH_SETJMP */
    681 
    682 /**
    683  * Fetches the first opcode byte, returns/throws automatically on failure.
    684  *
    685  * @param   a_pu8               Where to return the opcode byte.
    686  * @remark Implicitly references pVCpu.
    687  */
    688 # ifndef IEM_WITH_SETJMP
    689 #  define IEM_OPCODE_GET_FIRST_U8(a_pu8) \
    690     do \
    691     { \
    692         VBOXSTRICTRC rcStrict2 = iemOpcodeGetFirstU8(pVCpu, (a_pu8)); \
    693         if (rcStrict2 == VINF_SUCCESS) \
    694         { /* likely */ } \
    695         else \
    696             return rcStrict2; \
    697     } while (0)
    698 # else
    699 #  define IEM_OPCODE_GET_FIRST_U8(a_pu8) (*(a_pu8) = iemOpcodeGetFirstU8Jmp(pVCpu))
    700 # endif /* IEM_WITH_SETJMP */
    701 
    702 
    703 # ifndef IEM_WITH_SETJMP
    704 
    705 /**
    706  * Fetches the next opcode byte.
    707  *
    708  * @returns Strict VBox status code.
    709  * @param   pVCpu               The cross context virtual CPU structure of the
    710  *                              calling thread.
    711  * @param   pu8                 Where to return the opcode byte.
    712  */
    713 DECLINLINE(VBOXSTRICTRC) iemOpcodeGetNextU8(PVMCPUCC pVCpu, uint8_t *pu8) RT_NOEXCEPT
    714 {
    715     uintptr_t const offOpcode = pVCpu->iem.s.offOpcode;
    716     if (RT_LIKELY((uint8_t)offOpcode < pVCpu->iem.s.cbOpcode))
    717     {
    718         pVCpu->iem.s.offOpcode = (uint8_t)offOpcode + 1;
    719         *pu8 = pVCpu->iem.s.abOpcode[offOpcode];
    720         return VINF_SUCCESS;
    721     }
    722     return iemOpcodeGetNextU8Slow(pVCpu, pu8);
    723 }
    724 
    725 # else  /* IEM_WITH_SETJMP */
    726 
    727 /**
    728  * Fetches the next opcode byte, longjmp on error.
    729  *
    730  * @returns The opcode byte.
    731  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    732  */
    733 DECL_INLINE_THROW(uint8_t) iemOpcodeGetNextU8Jmp(PVMCPUCC pVCpu) IEM_NOEXCEPT_MAY_LONGJMP
    734 {
    735 #  ifdef IEM_WITH_CODE_TLB
    736     uint8_t         bRet;
    737     uintptr_t       offBuf = pVCpu->iem.s.offInstrNextByte;
    738     uint8_t const  *pbBuf  = pVCpu->iem.s.pbInstrBuf;
    739     if (RT_LIKELY(   pbBuf != NULL
    740                   && offBuf < pVCpu->iem.s.cbInstrBuf))
    741     {
    742         pVCpu->iem.s.offInstrNextByte = (uint32_t)offBuf + 1;
    743         bRet = pbBuf[offBuf];
    744     }
    745     else
    746         bRet = iemOpcodeGetNextU8SlowJmp(pVCpu);
    747 #   ifdef IEM_WITH_CODE_TLB_AND_OPCODE_BUF
    748     Assert(pVCpu->iem.s.offOpcode < sizeof(pVCpu->iem.s.abOpcode));
    749     pVCpu->iem.s.abOpcode[pVCpu->iem.s.offOpcode++] = bRet;
    750 #   endif
    751     return bRet;
    752 
    753 #  else /* !IEM_WITH_CODE_TLB */
    754     uintptr_t offOpcode = pVCpu->iem.s.offOpcode;
    755     if (RT_LIKELY((uint8_t)offOpcode < pVCpu->iem.s.cbOpcode))
    756     {
    757         pVCpu->iem.s.offOpcode = (uint8_t)offOpcode + 1;
    758         return pVCpu->iem.s.abOpcode[offOpcode];
    759     }
    760     return iemOpcodeGetNextU8SlowJmp(pVCpu);
    761 #  endif
    762 }
    763 
    764 # endif /* IEM_WITH_SETJMP */
    765 
    766 /**
    767  * Fetches the next opcode byte, returns automatically on failure.
    768  *
    769  * @param   a_pu8               Where to return the opcode byte.
    770  * @remark Implicitly references pVCpu.
    771  */
    772 # ifndef IEM_WITH_SETJMP
    773 #  define IEM_OPCODE_GET_NEXT_U8(a_pu8) \
    774     do \
    775     { \
    776         VBOXSTRICTRC rcStrict2 = iemOpcodeGetNextU8(pVCpu, (a_pu8)); \
    777         if (rcStrict2 == VINF_SUCCESS) \
    778         { /* likely */ } \
    779         else \
    780             return rcStrict2; \
    781     } while (0)
    782 # else
    783 #  define IEM_OPCODE_GET_NEXT_U8(a_pu8) (*(a_pu8) = iemOpcodeGetNextU8Jmp(pVCpu))
    784 # endif /* IEM_WITH_SETJMP */
    785 
    786 
    787 # ifndef IEM_WITH_SETJMP
    788 /**
    789  * Fetches the next signed byte from the opcode stream.
    790  *
    791  * @returns Strict VBox status code.
    792  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    793  * @param   pi8                 Where to return the signed byte.
    794  */
    795 DECLINLINE(VBOXSTRICTRC) iemOpcodeGetNextS8(PVMCPUCC pVCpu, int8_t *pi8) RT_NOEXCEPT
    796 {
    797     return iemOpcodeGetNextU8(pVCpu, (uint8_t *)pi8);
    798 }
    799 # endif /* !IEM_WITH_SETJMP */
    800 
    801 
    802 /**
    803  * Fetches the next signed byte from the opcode stream, returning automatically
    804  * on failure.
    805  *
    806  * @param   a_pi8               Where to return the signed byte.
    807  * @remark Implicitly references pVCpu.
    808  */
    809 # ifndef IEM_WITH_SETJMP
    810 #  define IEM_OPCODE_GET_NEXT_S8(a_pi8) \
    811     do \
    812     { \
    813         VBOXSTRICTRC rcStrict2 = iemOpcodeGetNextS8(pVCpu, (a_pi8)); \
    814         if (rcStrict2 != VINF_SUCCESS) \
    815             return rcStrict2; \
    816     } while (0)
    817 # else /* IEM_WITH_SETJMP */
    818 #  define IEM_OPCODE_GET_NEXT_S8(a_pi8) (*(a_pi8) = (int8_t)iemOpcodeGetNextU8Jmp(pVCpu))
    819 
    820 # endif /* IEM_WITH_SETJMP */
    821 
    822 
    823 # ifndef IEM_WITH_SETJMP
    824 /**
    825  * Fetches the next signed byte from the opcode stream, extending it to
    826  * unsigned 16-bit.
    827  *
    828  * @returns Strict VBox status code.
    829  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    830  * @param   pu16                Where to return the unsigned word.
    831  */
    832 DECLINLINE(VBOXSTRICTRC) iemOpcodeGetNextS8SxU16(PVMCPUCC pVCpu, uint16_t *pu16) RT_NOEXCEPT
    833 {
    834     uint8_t const offOpcode = pVCpu->iem.s.offOpcode;
    835     if (RT_UNLIKELY(offOpcode >= pVCpu->iem.s.cbOpcode))
    836         return iemOpcodeGetNextS8SxU16Slow(pVCpu, pu16);
    837 
    838     *pu16 = (uint16_t)(int16_t)(int8_t)pVCpu->iem.s.abOpcode[offOpcode];
    839     pVCpu->iem.s.offOpcode = offOpcode + 1;
    840     return VINF_SUCCESS;
    841 }
    842 # endif /* !IEM_WITH_SETJMP */
    843 
    844 /**
    845  * Fetches the next signed byte from the opcode stream and sign-extending it to
    846  * a word, returning automatically on failure.
    847  *
    848  * @param   a_pu16              Where to return the word.
    849  * @remark Implicitly references pVCpu.
    850  */
    851 # ifndef IEM_WITH_SETJMP
    852 #  define IEM_OPCODE_GET_NEXT_S8_SX_U16(a_pu16) \
    853     do \
    854     { \
    855         VBOXSTRICTRC rcStrict2 = iemOpcodeGetNextS8SxU16(pVCpu, (a_pu16)); \
    856         if (rcStrict2 != VINF_SUCCESS) \
    857             return rcStrict2; \
    858     } while (0)
    859 # else
    860 #  define IEM_OPCODE_GET_NEXT_S8_SX_U16(a_pu16) (*(a_pu16) = (uint16_t)(int16_t)(int8_t)iemOpcodeGetNextU8Jmp(pVCpu))
    861 # endif
    862 
    863 # ifndef IEM_WITH_SETJMP
    864 /**
    865  * Fetches the next signed byte from the opcode stream, extending it to
    866  * unsigned 32-bit.
    867  *
    868  * @returns Strict VBox status code.
    869  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    870  * @param   pu32                Where to return the unsigned dword.
    871  */
    872 DECLINLINE(VBOXSTRICTRC) iemOpcodeGetNextS8SxU32(PVMCPUCC pVCpu, uint32_t *pu32) RT_NOEXCEPT
    873 {
    874     uint8_t const offOpcode = pVCpu->iem.s.offOpcode;
    875     if (RT_UNLIKELY(offOpcode >= pVCpu->iem.s.cbOpcode))
    876         return iemOpcodeGetNextS8SxU32Slow(pVCpu, pu32);
    877 
    878     *pu32 = (uint32_t)(int32_t)(int8_t)pVCpu->iem.s.abOpcode[offOpcode];
    879     pVCpu->iem.s.offOpcode = offOpcode + 1;
    880     return VINF_SUCCESS;
    881 }
    882 # endif /* !IEM_WITH_SETJMP */
    883 
    884 /**
    885  * Fetches the next signed byte from the opcode stream and sign-extending it to
    886  * a word, returning automatically on failure.
    887  *
    888  * @param   a_pu32              Where to return the word.
    889  * @remark Implicitly references pVCpu.
    890  */
    891 # ifndef IEM_WITH_SETJMP
    892 #  define IEM_OPCODE_GET_NEXT_S8_SX_U32(a_pu32) \
    893     do \
    894     { \
    895         VBOXSTRICTRC rcStrict2 = iemOpcodeGetNextS8SxU32(pVCpu, (a_pu32)); \
    896         if (rcStrict2 != VINF_SUCCESS) \
    897             return rcStrict2; \
    898     } while (0)
    899 # else
    900 #  define IEM_OPCODE_GET_NEXT_S8_SX_U32(a_pu32) (*(a_pu32) = (uint32_t)(int32_t)(int8_t)iemOpcodeGetNextU8Jmp(pVCpu))
    901 # endif
    902 
    903 
    904 # ifndef IEM_WITH_SETJMP
    905 /**
    906  * Fetches the next signed byte from the opcode stream, extending it to
    907  * unsigned 64-bit.
    908  *
    909  * @returns Strict VBox status code.
    910  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    911  * @param   pu64                Where to return the unsigned qword.
    912  */
    913 DECLINLINE(VBOXSTRICTRC) iemOpcodeGetNextS8SxU64(PVMCPUCC pVCpu, uint64_t *pu64) RT_NOEXCEPT
    914 {
    915     uint8_t const offOpcode = pVCpu->iem.s.offOpcode;
    916     if (RT_UNLIKELY(offOpcode >= pVCpu->iem.s.cbOpcode))
    917         return iemOpcodeGetNextS8SxU64Slow(pVCpu, pu64);
    918 
    919     *pu64 = (uint64_t)(int64_t)(int8_t)pVCpu->iem.s.abOpcode[offOpcode];
    920     pVCpu->iem.s.offOpcode = offOpcode + 1;
    921     return VINF_SUCCESS;
    922 }
    923 # endif /* !IEM_WITH_SETJMP */
    924 
    925 /**
    926  * Fetches the next signed byte from the opcode stream and sign-extending it to
    927  * a word, returning automatically on failure.
    928  *
    929  * @param   a_pu64              Where to return the word.
    930  * @remark Implicitly references pVCpu.
    931  */
    932 # ifndef IEM_WITH_SETJMP
    933 #  define IEM_OPCODE_GET_NEXT_S8_SX_U64(a_pu64) \
    934     do \
    935     { \
    936         VBOXSTRICTRC rcStrict2 = iemOpcodeGetNextS8SxU64(pVCpu, (a_pu64)); \
    937         if (rcStrict2 != VINF_SUCCESS) \
    938             return rcStrict2; \
    939     } while (0)
    940 # else
    941 #  define IEM_OPCODE_GET_NEXT_S8_SX_U64(a_pu64) (*(a_pu64) = (uint64_t)(int64_t)(int8_t)iemOpcodeGetNextU8Jmp(pVCpu))
    942 # endif
    943 
    944 
    945 # ifndef IEM_WITH_SETJMP
    946 
    947 /**
    948  * Fetches the next opcode word.
    949  *
    950  * @returns Strict VBox status code.
    951  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    952  * @param   pu16                Where to return the opcode word.
    953  */
    954 DECLINLINE(VBOXSTRICTRC) iemOpcodeGetNextU16(PVMCPUCC pVCpu, uint16_t *pu16) RT_NOEXCEPT
    955 {
    956     uintptr_t const offOpcode = pVCpu->iem.s.offOpcode;
    957     if (RT_LIKELY((uint8_t)offOpcode + 2 <= pVCpu->iem.s.cbOpcode))
    958     {
    959         pVCpu->iem.s.offOpcode = (uint8_t)offOpcode + 2;
    960 #  ifdef IEM_USE_UNALIGNED_DATA_ACCESS
    961         *pu16 = *(uint16_t const *)&pVCpu->iem.s.abOpcode[offOpcode];
    962 #  else
    963         *pu16 = RT_MAKE_U16(pVCpu->iem.s.abOpcode[offOpcode], pVCpu->iem.s.abOpcode[offOpcode + 1]);
    964 #  endif
    965         return VINF_SUCCESS;
    966     }
    967     return iemOpcodeGetNextU16Slow(pVCpu, pu16);
    968 }
    969 
    970 # else  /* IEM_WITH_SETJMP */
    971 
    972 /**
    973  * Fetches the next opcode word, longjmp on error.
    974  *
    975  * @returns The opcode word.
    976  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    977  */
    978 DECL_INLINE_THROW(uint16_t) iemOpcodeGetNextU16Jmp(PVMCPUCC pVCpu) IEM_NOEXCEPT_MAY_LONGJMP
    979 {
    980 #  ifdef IEM_WITH_CODE_TLB
    981     uint16_t        u16Ret;
    982     uintptr_t       offBuf = pVCpu->iem.s.offInstrNextByte;
    983     uint8_t const  *pbBuf  = pVCpu->iem.s.pbInstrBuf;
    984     if (RT_LIKELY(   pbBuf != NULL
    985                   && offBuf + 2 <= pVCpu->iem.s.cbInstrBuf))
    986     {
    987         pVCpu->iem.s.offInstrNextByte = (uint32_t)offBuf + 2;
    988 #   ifdef IEM_USE_UNALIGNED_DATA_ACCESS
    989         u16Ret = *(uint16_t const *)&pbBuf[offBuf];
    990 #   else
    991         u16Ret = RT_MAKE_U16(pbBuf[offBuf], pbBuf[offBuf + 1]);
    992 #   endif
    993     }
    994     else
    995         u16Ret = iemOpcodeGetNextU16SlowJmp(pVCpu);
    996 
    997 #   ifdef IEM_WITH_CODE_TLB_AND_OPCODE_BUF
    998     uintptr_t const offOpcode = pVCpu->iem.s.offOpcode;
    999     Assert(offOpcode + 1 < sizeof(pVCpu->iem.s.abOpcode));
    1000 #    ifdef IEM_USE_UNALIGNED_DATA_ACCESS
    1001     *(uint16_t *)&pVCpu->iem.s.abOpcode[offOpcode] = u16Ret;
    1002 #    else
    1003     pVCpu->iem.s.abOpcode[offOpcode]     = RT_LO_U8(u16Ret);
    1004     pVCpu->iem.s.abOpcode[offOpcode + 1] = RT_HI_U8(u16Ret);
    1005 #    endif
    1006     pVCpu->iem.s.offOpcode = (uint8_t)offOpcode + (uint8_t)2;
    1007 #   endif
    1008 
    1009     return u16Ret;
    1010 
    1011 #  else /* !IEM_WITH_CODE_TLB */
    1012     uintptr_t const offOpcode = pVCpu->iem.s.offOpcode;
    1013     if (RT_LIKELY((uint8_t)offOpcode + 2 <= pVCpu->iem.s.cbOpcode))
    1014     {
    1015         pVCpu->iem.s.offOpcode = (uint8_t)offOpcode + 2;
    1016 #   ifdef IEM_USE_UNALIGNED_DATA_ACCESS
    1017         return *(uint16_t const *)&pVCpu->iem.s.abOpcode[offOpcode];
    1018 #   else
    1019         return RT_MAKE_U16(pVCpu->iem.s.abOpcode[offOpcode], pVCpu->iem.s.abOpcode[offOpcode + 1]);
    1020 #   endif
    1021     }
    1022     return iemOpcodeGetNextU16SlowJmp(pVCpu);
    1023 #  endif /* !IEM_WITH_CODE_TLB */
    1024 }
    1025 
    1026 # endif /* IEM_WITH_SETJMP */
    1027 
    1028 /**
    1029  * Fetches the next opcode word, returns automatically on failure.
    1030  *
    1031  * @param   a_pu16              Where to return the opcode word.
    1032  * @remark Implicitly references pVCpu.
    1033  */
    1034 # ifndef IEM_WITH_SETJMP
    1035 #  define IEM_OPCODE_GET_NEXT_U16(a_pu16) \
    1036     do \
    1037     { \
    1038         VBOXSTRICTRC rcStrict2 = iemOpcodeGetNextU16(pVCpu, (a_pu16)); \
    1039         if (rcStrict2 != VINF_SUCCESS) \
    1040             return rcStrict2; \
    1041     } while (0)
    1042 # else
    1043 #  define IEM_OPCODE_GET_NEXT_U16(a_pu16) (*(a_pu16) = iemOpcodeGetNextU16Jmp(pVCpu))
    1044 # endif
    1045 
    1046 # ifndef IEM_WITH_SETJMP
    1047 /**
    1048  * Fetches the next opcode word, zero extending it to a double word.
    1049  *
    1050  * @returns Strict VBox status code.
    1051  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    1052  * @param   pu32                Where to return the opcode double word.
    1053  */
    1054 DECLINLINE(VBOXSTRICTRC) iemOpcodeGetNextU16ZxU32(PVMCPUCC pVCpu, uint32_t *pu32) RT_NOEXCEPT
    1055 {
    1056     uint8_t const offOpcode = pVCpu->iem.s.offOpcode;
    1057     if (RT_UNLIKELY(offOpcode + 2 > pVCpu->iem.s.cbOpcode))
    1058         return iemOpcodeGetNextU16ZxU32Slow(pVCpu, pu32);
    1059 
    1060     *pu32 = RT_MAKE_U16(pVCpu->iem.s.abOpcode[offOpcode], pVCpu->iem.s.abOpcode[offOpcode + 1]);
    1061     pVCpu->iem.s.offOpcode = offOpcode + 2;
    1062     return VINF_SUCCESS;
    1063 }
    1064 # endif /* !IEM_WITH_SETJMP */
    1065 
    1066 /**
    1067  * Fetches the next opcode word and zero extends it to a double word, returns
    1068  * automatically on failure.
    1069  *
    1070  * @param   a_pu32              Where to return the opcode double word.
    1071  * @remark Implicitly references pVCpu.
    1072  */
    1073 # ifndef IEM_WITH_SETJMP
    1074 #  define IEM_OPCODE_GET_NEXT_U16_ZX_U32(a_pu32) \
    1075     do \
    1076     { \
    1077         VBOXSTRICTRC rcStrict2 = iemOpcodeGetNextU16ZxU32(pVCpu, (a_pu32)); \
    1078         if (rcStrict2 != VINF_SUCCESS) \
    1079             return rcStrict2; \
    1080     } while (0)
    1081 # else
    1082 #  define IEM_OPCODE_GET_NEXT_U16_ZX_U32(a_pu32) (*(a_pu32) = iemOpcodeGetNextU16Jmp(pVCpu))
    1083 # endif
    1084 
    1085 # ifndef IEM_WITH_SETJMP
    1086 /**
    1087  * Fetches the next opcode word, zero extending it to a quad word.
    1088  *
    1089  * @returns Strict VBox status code.
    1090  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    1091  * @param   pu64                Where to return the opcode quad word.
    1092  */
    1093 DECLINLINE(VBOXSTRICTRC) iemOpcodeGetNextU16ZxU64(PVMCPUCC pVCpu, uint64_t *pu64) RT_NOEXCEPT
    1094 {
    1095     uint8_t const offOpcode = pVCpu->iem.s.offOpcode;
    1096     if (RT_UNLIKELY(offOpcode + 2 > pVCpu->iem.s.cbOpcode))
    1097         return iemOpcodeGetNextU16ZxU64Slow(pVCpu, pu64);
    1098 
    1099     *pu64 = RT_MAKE_U16(pVCpu->iem.s.abOpcode[offOpcode], pVCpu->iem.s.abOpcode[offOpcode + 1]);
    1100     pVCpu->iem.s.offOpcode = offOpcode + 2;
    1101     return VINF_SUCCESS;
    1102 }
    1103 # endif /* !IEM_WITH_SETJMP */
    1104 
    1105 /**
    1106  * Fetches the next opcode word and zero extends it to a quad word, returns
    1107  * automatically on failure.
    1108  *
    1109  * @param   a_pu64              Where to return the opcode quad word.
    1110  * @remark Implicitly references pVCpu.
    1111  */
    1112 # ifndef IEM_WITH_SETJMP
    1113 #  define IEM_OPCODE_GET_NEXT_U16_ZX_U64(a_pu64) \
    1114     do \
    1115     { \
    1116         VBOXSTRICTRC rcStrict2 = iemOpcodeGetNextU16ZxU64(pVCpu, (a_pu64)); \
    1117         if (rcStrict2 != VINF_SUCCESS) \
    1118             return rcStrict2; \
    1119     } while (0)
    1120 # else
    1121 #  define IEM_OPCODE_GET_NEXT_U16_ZX_U64(a_pu64)  (*(a_pu64) = iemOpcodeGetNextU16Jmp(pVCpu))
    1122 # endif
    1123 
    1124 
    1125 # ifndef IEM_WITH_SETJMP
    1126 /**
    1127  * Fetches the next signed word from the opcode stream.
    1128  *
    1129  * @returns Strict VBox status code.
    1130  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    1131  * @param   pi16                Where to return the signed word.
    1132  */
    1133 DECLINLINE(VBOXSTRICTRC) iemOpcodeGetNextS16(PVMCPUCC pVCpu, int16_t *pi16) RT_NOEXCEPT
    1134 {
    1135     return iemOpcodeGetNextU16(pVCpu, (uint16_t *)pi16);
    1136 }
    1137 # endif /* !IEM_WITH_SETJMP */
    1138 
    1139 
    1140 /**
    1141  * Fetches the next signed word from the opcode stream, returning automatically
    1142  * on failure.
    1143  *
    1144  * @param   a_pi16              Where to return the signed word.
    1145  * @remark Implicitly references pVCpu.
    1146  */
    1147 # ifndef IEM_WITH_SETJMP
    1148 #  define IEM_OPCODE_GET_NEXT_S16(a_pi16) \
    1149     do \
    1150     { \
    1151         VBOXSTRICTRC rcStrict2 = iemOpcodeGetNextS16(pVCpu, (a_pi16)); \
    1152         if (rcStrict2 != VINF_SUCCESS) \
    1153             return rcStrict2; \
    1154     } while (0)
    1155 # else
    1156 #  define IEM_OPCODE_GET_NEXT_S16(a_pi16) (*(a_pi16) = (int16_t)iemOpcodeGetNextU16Jmp(pVCpu))
    1157 # endif
    1158 
    1159 # ifndef IEM_WITH_SETJMP
    1160 
    1161 /**
    1162  * Fetches the next opcode dword.
    1163  *
    1164  * @returns Strict VBox status code.
    1165  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    1166  * @param   pu32                Where to return the opcode double word.
    1167  */
    1168 DECLINLINE(VBOXSTRICTRC) iemOpcodeGetNextU32(PVMCPUCC pVCpu, uint32_t *pu32) RT_NOEXCEPT
    1169 {
    1170     uintptr_t const offOpcode = pVCpu->iem.s.offOpcode;
    1171     if (RT_LIKELY((uint8_t)offOpcode + 4 <= pVCpu->iem.s.cbOpcode))
    1172     {
    1173         pVCpu->iem.s.offOpcode = (uint8_t)offOpcode + 4;
    1174 #  ifdef IEM_USE_UNALIGNED_DATA_ACCESS
    1175         *pu32 = *(uint32_t const *)&pVCpu->iem.s.abOpcode[offOpcode];
    1176 #  else
    1177         *pu32 = RT_MAKE_U32_FROM_U8(pVCpu->iem.s.abOpcode[offOpcode],
    1178                                     pVCpu->iem.s.abOpcode[offOpcode + 1],
    1179                                     pVCpu->iem.s.abOpcode[offOpcode + 2],
    1180                                     pVCpu->iem.s.abOpcode[offOpcode + 3]);
    1181 #  endif
    1182         return VINF_SUCCESS;
    1183     }
    1184     return iemOpcodeGetNextU32Slow(pVCpu, pu32);
    1185 }
    1186 
    1187 # else  /* IEM_WITH_SETJMP */
    1188 
    1189 /**
    1190  * Fetches the next opcode dword, longjmp on error.
    1191  *
    1192  * @returns The opcode dword.
    1193  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    1194  */
    1195 DECL_INLINE_THROW(uint32_t) iemOpcodeGetNextU32Jmp(PVMCPUCC pVCpu) IEM_NOEXCEPT_MAY_LONGJMP
    1196 {
    1197 #  ifdef IEM_WITH_CODE_TLB
    1198     uint32_t u32Ret;
    1199     uintptr_t       offBuf = pVCpu->iem.s.offInstrNextByte;
    1200     uint8_t const  *pbBuf  = pVCpu->iem.s.pbInstrBuf;
    1201     if (RT_LIKELY(   pbBuf != NULL
    1202                   && offBuf + 4 <= pVCpu->iem.s.cbInstrBuf))
    1203     {
    1204         pVCpu->iem.s.offInstrNextByte = (uint32_t)offBuf + 4;
    1205 #   ifdef IEM_USE_UNALIGNED_DATA_ACCESS
    1206         u32Ret = *(uint32_t const *)&pbBuf[offBuf];
    1207 #   else
    1208         u32Ret = RT_MAKE_U32_FROM_U8(pbBuf[offBuf],
    1209                                      pbBuf[offBuf + 1],
    1210                                      pbBuf[offBuf + 2],
    1211                                      pbBuf[offBuf + 3]);
    1212 #   endif
    1213     }
    1214     else
    1215         u32Ret = iemOpcodeGetNextU32SlowJmp(pVCpu);
    1216 
    1217 #   ifdef IEM_WITH_CODE_TLB_AND_OPCODE_BUF
    1218     uintptr_t const offOpcode = pVCpu->iem.s.offOpcode;
    1219     Assert(offOpcode + 3 < sizeof(pVCpu->iem.s.abOpcode));
    1220 #    ifdef IEM_USE_UNALIGNED_DATA_ACCESS
    1221     *(uint32_t *)&pVCpu->iem.s.abOpcode[offOpcode] = u32Ret;
    1222 #    else
    1223     pVCpu->iem.s.abOpcode[offOpcode]     = RT_BYTE1(u32Ret);
    1224     pVCpu->iem.s.abOpcode[offOpcode + 1] = RT_BYTE2(u32Ret);
    1225     pVCpu->iem.s.abOpcode[offOpcode + 2] = RT_BYTE3(u32Ret);
    1226     pVCpu->iem.s.abOpcode[offOpcode + 3] = RT_BYTE4(u32Ret);
    1227 #    endif
    1228     pVCpu->iem.s.offOpcode = (uint8_t)offOpcode + (uint8_t)4;
    1229 #   endif /* IEM_WITH_CODE_TLB_AND_OPCODE_BUF */
    1230 
    1231     return u32Ret;
    1232 
    1233 #  else  /* !IEM_WITH_CODE_TLB */
    1234     uintptr_t const offOpcode = pVCpu->iem.s.offOpcode;
    1235     if (RT_LIKELY((uint8_t)offOpcode + 4 <= pVCpu->iem.s.cbOpcode))
    1236     {
    1237         pVCpu->iem.s.offOpcode = (uint8_t)offOpcode + 4;
    1238 #   ifdef IEM_USE_UNALIGNED_DATA_ACCESS
    1239         return *(uint32_t const *)&pVCpu->iem.s.abOpcode[offOpcode];
    1240 #   else
    1241         return RT_MAKE_U32_FROM_U8(pVCpu->iem.s.abOpcode[offOpcode],
    1242                                    pVCpu->iem.s.abOpcode[offOpcode + 1],
    1243                                    pVCpu->iem.s.abOpcode[offOpcode + 2],
    1244                                    pVCpu->iem.s.abOpcode[offOpcode + 3]);
    1245 #   endif
    1246     }
    1247     return iemOpcodeGetNextU32SlowJmp(pVCpu);
    1248 #  endif
    1249 }
    1250 
    1251 # endif /* IEM_WITH_SETJMP */
    1252 
    1253 /**
    1254  * Fetches the next opcode dword, returns automatically on failure.
    1255  *
    1256  * @param   a_pu32              Where to return the opcode dword.
    1257  * @remark Implicitly references pVCpu.
    1258  */
    1259 # ifndef IEM_WITH_SETJMP
    1260 #  define IEM_OPCODE_GET_NEXT_U32(a_pu32) \
    1261     do \
    1262     { \
    1263         VBOXSTRICTRC rcStrict2 = iemOpcodeGetNextU32(pVCpu, (a_pu32)); \
    1264         if (rcStrict2 != VINF_SUCCESS) \
    1265             return rcStrict2; \
    1266     } while (0)
    1267 # else
    1268 #  define IEM_OPCODE_GET_NEXT_U32(a_pu32) (*(a_pu32) = iemOpcodeGetNextU32Jmp(pVCpu))
    1269 # endif
    1270 
    1271 # ifndef IEM_WITH_SETJMP
    1272 /**
    1273  * Fetches the next opcode dword, zero extending it to a quad word.
    1274  *
    1275  * @returns Strict VBox status code.
    1276  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    1277  * @param   pu64                Where to return the opcode quad word.
    1278  */
    1279 DECLINLINE(VBOXSTRICTRC) iemOpcodeGetNextU32ZxU64(PVMCPUCC pVCpu, uint64_t *pu64) RT_NOEXCEPT
    1280 {
    1281     uint8_t const offOpcode = pVCpu->iem.s.offOpcode;
    1282     if (RT_UNLIKELY(offOpcode + 4 > pVCpu->iem.s.cbOpcode))
    1283         return iemOpcodeGetNextU32ZxU64Slow(pVCpu, pu64);
    1284 
    1285     *pu64 = RT_MAKE_U32_FROM_U8(pVCpu->iem.s.abOpcode[offOpcode],
    1286                                 pVCpu->iem.s.abOpcode[offOpcode + 1],
    1287                                 pVCpu->iem.s.abOpcode[offOpcode + 2],
    1288                                 pVCpu->iem.s.abOpcode[offOpcode + 3]);
    1289     pVCpu->iem.s.offOpcode = offOpcode + 4;
    1290     return VINF_SUCCESS;
    1291 }
    1292 # endif /* !IEM_WITH_SETJMP */
    1293 
    1294 /**
    1295  * Fetches the next opcode dword and zero extends it to a quad word, returns
    1296  * automatically on failure.
    1297  *
    1298  * @param   a_pu64              Where to return the opcode quad word.
    1299  * @remark Implicitly references pVCpu.
    1300  */
    1301 # ifndef IEM_WITH_SETJMP
    1302 #  define IEM_OPCODE_GET_NEXT_U32_ZX_U64(a_pu64) \
    1303     do \
    1304     { \
    1305         VBOXSTRICTRC rcStrict2 = iemOpcodeGetNextU32ZxU64(pVCpu, (a_pu64)); \
    1306         if (rcStrict2 != VINF_SUCCESS) \
    1307             return rcStrict2; \
    1308     } while (0)
    1309 # else
    1310 #  define IEM_OPCODE_GET_NEXT_U32_ZX_U64(a_pu64) (*(a_pu64) = iemOpcodeGetNextU32Jmp(pVCpu))
    1311 # endif
    1312 
    1313 
    1314 # ifndef IEM_WITH_SETJMP
    1315 /**
    1316  * Fetches the next signed double word from the opcode stream.
    1317  *
    1318  * @returns Strict VBox status code.
    1319  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    1320  * @param   pi32                Where to return the signed double word.
    1321  */
    1322 DECLINLINE(VBOXSTRICTRC) iemOpcodeGetNextS32(PVMCPUCC pVCpu, int32_t *pi32) RT_NOEXCEPT
    1323 {
    1324     return iemOpcodeGetNextU32(pVCpu, (uint32_t *)pi32);
    1325 }
    1326 # endif
    1327 
    1328 /**
    1329  * Fetches the next signed double word from the opcode stream, returning
    1330  * automatically on failure.
    1331  *
    1332  * @param   a_pi32              Where to return the signed double word.
    1333  * @remark Implicitly references pVCpu.
    1334  */
    1335 # ifndef IEM_WITH_SETJMP
    1336 #  define IEM_OPCODE_GET_NEXT_S32(a_pi32) \
    1337     do \
    1338     { \
    1339         VBOXSTRICTRC rcStrict2 = iemOpcodeGetNextS32(pVCpu, (a_pi32)); \
    1340         if (rcStrict2 != VINF_SUCCESS) \
    1341             return rcStrict2; \
    1342     } while (0)
    1343 # else
    1344 #  define IEM_OPCODE_GET_NEXT_S32(a_pi32)    (*(a_pi32) = (int32_t)iemOpcodeGetNextU32Jmp(pVCpu))
    1345 # endif
    1346 
    1347 # ifndef IEM_WITH_SETJMP
    1348 /**
    1349  * Fetches the next opcode dword, sign extending it into a quad word.
    1350  *
    1351  * @returns Strict VBox status code.
    1352  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    1353  * @param   pu64                Where to return the opcode quad word.
    1354  */
    1355 DECLINLINE(VBOXSTRICTRC) iemOpcodeGetNextS32SxU64(PVMCPUCC pVCpu, uint64_t *pu64) RT_NOEXCEPT
    1356 {
    1357     uint8_t const offOpcode = pVCpu->iem.s.offOpcode;
    1358     if (RT_UNLIKELY(offOpcode + 4 > pVCpu->iem.s.cbOpcode))
    1359         return iemOpcodeGetNextS32SxU64Slow(pVCpu, pu64);
    1360 
    1361     int32_t i32 = RT_MAKE_U32_FROM_U8(pVCpu->iem.s.abOpcode[offOpcode],
    1362                                       pVCpu->iem.s.abOpcode[offOpcode + 1],
    1363                                       pVCpu->iem.s.abOpcode[offOpcode + 2],
    1364                                       pVCpu->iem.s.abOpcode[offOpcode + 3]);
    1365     *pu64 = (uint64_t)(int64_t)i32;
    1366     pVCpu->iem.s.offOpcode = offOpcode + 4;
    1367     return VINF_SUCCESS;
    1368 }
    1369 # endif /* !IEM_WITH_SETJMP */
    1370 
    1371 /**
    1372  * Fetches the next opcode double word and sign extends it to a quad word,
    1373  * returns automatically on failure.
    1374  *
    1375  * @param   a_pu64              Where to return the opcode quad word.
    1376  * @remark Implicitly references pVCpu.
    1377  */
    1378 # ifndef IEM_WITH_SETJMP
    1379 #  define IEM_OPCODE_GET_NEXT_S32_SX_U64(a_pu64) \
    1380     do \
    1381     { \
    1382         VBOXSTRICTRC rcStrict2 = iemOpcodeGetNextS32SxU64(pVCpu, (a_pu64)); \
    1383         if (rcStrict2 != VINF_SUCCESS) \
    1384             return rcStrict2; \
    1385     } while (0)
    1386 # else
    1387 #  define IEM_OPCODE_GET_NEXT_S32_SX_U64(a_pu64) (*(a_pu64) = (uint64_t)(int64_t)(int32_t)iemOpcodeGetNextU32Jmp(pVCpu))
    1388 # endif
    1389 
    1390 # ifndef IEM_WITH_SETJMP
    1391 
    1392 /**
    1393  * Fetches the next opcode qword.
    1394  *
    1395  * @returns Strict VBox status code.
    1396  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    1397  * @param   pu64                Where to return the opcode qword.
    1398  */
    1399 DECLINLINE(VBOXSTRICTRC) iemOpcodeGetNextU64(PVMCPUCC pVCpu, uint64_t *pu64) RT_NOEXCEPT
    1400 {
    1401     uintptr_t const offOpcode = pVCpu->iem.s.offOpcode;
    1402     if (RT_LIKELY((uint8_t)offOpcode + 8 <= pVCpu->iem.s.cbOpcode))
    1403     {
    1404 #  ifdef IEM_USE_UNALIGNED_DATA_ACCESS
    1405         *pu64 = *(uint64_t const *)&pVCpu->iem.s.abOpcode[offOpcode];
    1406 #  else
    1407         *pu64 = RT_MAKE_U64_FROM_U8(pVCpu->iem.s.abOpcode[offOpcode],
    1408                                     pVCpu->iem.s.abOpcode[offOpcode + 1],
    1409                                     pVCpu->iem.s.abOpcode[offOpcode + 2],
    1410                                     pVCpu->iem.s.abOpcode[offOpcode + 3],
    1411                                     pVCpu->iem.s.abOpcode[offOpcode + 4],
    1412                                     pVCpu->iem.s.abOpcode[offOpcode + 5],
    1413                                     pVCpu->iem.s.abOpcode[offOpcode + 6],
    1414                                     pVCpu->iem.s.abOpcode[offOpcode + 7]);
    1415 #  endif
    1416         pVCpu->iem.s.offOpcode = (uint8_t)offOpcode + 8;
    1417         return VINF_SUCCESS;
    1418     }
    1419     return iemOpcodeGetNextU64Slow(pVCpu, pu64);
    1420 }
    1421 
    1422 # else  /* IEM_WITH_SETJMP */
    1423 
    1424 /**
    1425  * Fetches the next opcode qword, longjmp on error.
    1426  *
    1427  * @returns The opcode qword.
    1428  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    1429  */
    1430 DECL_INLINE_THROW(uint64_t) iemOpcodeGetNextU64Jmp(PVMCPUCC pVCpu) IEM_NOEXCEPT_MAY_LONGJMP
    1431 {
    1432 #  ifdef IEM_WITH_CODE_TLB
    1433     uint64_t        u64Ret;
    1434     uintptr_t       offBuf = pVCpu->iem.s.offInstrNextByte;
    1435     uint8_t const  *pbBuf  = pVCpu->iem.s.pbInstrBuf;
    1436     if (RT_LIKELY(   pbBuf != NULL
    1437                   && offBuf + 8 <= pVCpu->iem.s.cbInstrBuf))
    1438     {
    1439         pVCpu->iem.s.offInstrNextByte = (uint32_t)offBuf + 8;
    1440 #   ifdef IEM_USE_UNALIGNED_DATA_ACCESS
    1441         u64Ret = *(uint64_t const *)&pbBuf[offBuf];
    1442 #   else
    1443         u64Ret = RT_MAKE_U64_FROM_U8(pbBuf[offBuf],
    1444                                      pbBuf[offBuf + 1],
    1445                                      pbBuf[offBuf + 2],
    1446                                      pbBuf[offBuf + 3],
    1447                                      pbBuf[offBuf + 4],
    1448                                      pbBuf[offBuf + 5],
    1449                                      pbBuf[offBuf + 6],
    1450                                      pbBuf[offBuf + 7]);
    1451 #   endif
    1452     }
    1453     else
    1454         u64Ret = iemOpcodeGetNextU64SlowJmp(pVCpu);
    1455 
    1456 #   ifdef IEM_WITH_CODE_TLB_AND_OPCODE_BUF
    1457     uintptr_t const offOpcode = pVCpu->iem.s.offOpcode;
    1458     Assert(offOpcode + 7 < sizeof(pVCpu->iem.s.abOpcode));
    1459 #    ifdef IEM_USE_UNALIGNED_DATA_ACCESS
    1460     *(uint64_t *)&pVCpu->iem.s.abOpcode[offOpcode] = u64Ret;
    1461 #    else
    1462     pVCpu->iem.s.abOpcode[offOpcode]     = RT_BYTE1(u64Ret);
    1463     pVCpu->iem.s.abOpcode[offOpcode + 1] = RT_BYTE2(u64Ret);
    1464     pVCpu->iem.s.abOpcode[offOpcode + 2] = RT_BYTE3(u64Ret);
    1465     pVCpu->iem.s.abOpcode[offOpcode + 3] = RT_BYTE4(u64Ret);
    1466     pVCpu->iem.s.abOpcode[offOpcode + 4] = RT_BYTE5(u64Ret);
    1467     pVCpu->iem.s.abOpcode[offOpcode + 5] = RT_BYTE6(u64Ret);
    1468     pVCpu->iem.s.abOpcode[offOpcode + 6] = RT_BYTE7(u64Ret);
    1469     pVCpu->iem.s.abOpcode[offOpcode + 7] = RT_BYTE8(u64Ret);
    1470 #    endif
    1471     pVCpu->iem.s.offOpcode = (uint8_t)offOpcode + (uint8_t)8;
    1472 #   endif /* IEM_WITH_CODE_TLB_AND_OPCODE_BUF */
    1473 
    1474     return u64Ret;
    1475 
    1476 #  else /* !IEM_WITH_CODE_TLB */
    1477     uintptr_t const offOpcode = pVCpu->iem.s.offOpcode;
    1478     if (RT_LIKELY((uint8_t)offOpcode + 8 <= pVCpu->iem.s.cbOpcode))
    1479     {
    1480         pVCpu->iem.s.offOpcode = (uint8_t)offOpcode + 8;
    1481 #   ifdef IEM_USE_UNALIGNED_DATA_ACCESS
    1482         return *(uint64_t const *)&pVCpu->iem.s.abOpcode[offOpcode];
    1483 #   else
    1484         return RT_MAKE_U64_FROM_U8(pVCpu->iem.s.abOpcode[offOpcode],
    1485                                    pVCpu->iem.s.abOpcode[offOpcode + 1],
    1486                                    pVCpu->iem.s.abOpcode[offOpcode + 2],
    1487                                    pVCpu->iem.s.abOpcode[offOpcode + 3],
    1488                                    pVCpu->iem.s.abOpcode[offOpcode + 4],
    1489                                    pVCpu->iem.s.abOpcode[offOpcode + 5],
    1490                                    pVCpu->iem.s.abOpcode[offOpcode + 6],
    1491                                    pVCpu->iem.s.abOpcode[offOpcode + 7]);
    1492 #   endif
    1493     }
    1494     return iemOpcodeGetNextU64SlowJmp(pVCpu);
    1495 #  endif /* !IEM_WITH_CODE_TLB */
    1496 }
    1497 
    1498 # endif /* IEM_WITH_SETJMP */
    1499 
    1500 /**
    1501  * Fetches the next opcode quad word, returns automatically on failure.
    1502  *
    1503  * @param   a_pu64              Where to return the opcode quad word.
    1504  * @remark Implicitly references pVCpu.
    1505  */
    1506 # ifndef IEM_WITH_SETJMP
    1507 #  define IEM_OPCODE_GET_NEXT_U64(a_pu64) \
    1508     do \
    1509     { \
    1510         VBOXSTRICTRC rcStrict2 = iemOpcodeGetNextU64(pVCpu, (a_pu64)); \
    1511         if (rcStrict2 != VINF_SUCCESS) \
    1512             return rcStrict2; \
    1513     } while (0)
    1514 # else
    1515 #  define IEM_OPCODE_GET_NEXT_U64(a_pu64)    ( *(a_pu64) = iemOpcodeGetNextU64Jmp(pVCpu) )
    1516 # endif
    1517 
    1518 /**
    1519  * For fetching the opcode bytes for an ModR/M effective address, but throw
    1520  * away the result.
    1521  *
    1522  * This is used when decoding undefined opcodes and such where we want to avoid
    1523  * unnecessary MC blocks.
    1524  *
    1525  * @note The recompiler code overrides this one so iemOpHlpCalcRmEffAddrJmpEx is
    1526  *       used instead.  At least for now...
    1527  */
    1528 # ifndef IEM_WITH_SETJMP
    1529 #  define IEM_OPCODE_SKIP_RM_EFF_ADDR_BYTES(a_bRm) do { \
    1530         RTGCPTR      GCPtrEff; \
    1531         VBOXSTRICTRC rcStrict = iemOpHlpCalcRmEffAddr(pVCpu, bRm, 0, &GCPtrEff); \
    1532         if (rcStrict != VINF_SUCCESS) \
    1533             return rcStrict; \
    1534     } while (0)
    1535 # else
    1536 #  define IEM_OPCODE_SKIP_RM_EFF_ADDR_BYTES(a_bRm) do { \
    1537         (void)iemOpHlpCalcRmEffAddrJmp(pVCpu, bRm, 0); \
    1538     } while (0)
    1539 # endif
    1540 
    1541 #endif /* !IEM_WITH_OPAQUE_DECODER_STATE */
    1542 
    1543 
    1544 /** @name  Misc Worker Functions.
     34#include <iprt/errcore.h>
     35
     36
     37
     38
     39/** @name   Memory access.
     40 *
    154541 * @{
    154642 */
    1547 
    1548 /**
    1549  * Gets the correct EFLAGS regardless of whether PATM stores parts of them or
    1550  * not (kind of obsolete now).
    1551  *
    1552  * @param   a_pVCpu The cross context virtual CPU structure of the calling thread.
    1553  */
    1554 #define IEMMISC_GET_EFL(a_pVCpu)            ( (a_pVCpu)->cpum.GstCtx.eflags.u  )
    1555 
    1556 /**
    1557  * Updates the EFLAGS in the correct manner wrt. PATM (kind of obsolete).
    1558  *
    1559  * @param   a_pVCpu The cross context virtual CPU structure of the calling thread.
    1560  * @param   a_fEfl  The new EFLAGS.
    1561  */
    1562 #define IEMMISC_SET_EFL(a_pVCpu, a_fEfl)    do { (a_pVCpu)->cpum.GstCtx.eflags.u = (a_fEfl); } while (0)
    1563 
    1564 
    1565 /**
    1566  * Loads a NULL data selector into a selector register, both the hidden and
    1567  * visible parts, in protected mode.
    1568  *
    1569  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    1570  * @param   pSReg               Pointer to the segment register.
    1571  * @param   uRpl                The RPL.
    1572  */
    1573 DECLINLINE(void) iemHlpLoadNullDataSelectorProt(PVMCPUCC pVCpu, PCPUMSELREG pSReg, RTSEL uRpl) RT_NOEXCEPT
    1574 {
    1575     /** @todo Testcase: write a testcase checking what happends when loading a NULL
    1576      *        data selector in protected mode. */
    1577     pSReg->Sel      = uRpl;
    1578     pSReg->ValidSel = uRpl;
    1579     pSReg->fFlags   = CPUMSELREG_FLAGS_VALID;
    1580     if (IEM_IS_GUEST_CPU_INTEL(pVCpu))
    1581     {
    1582         /* VT-x (Intel 3960x) observed doing something like this. */
    1583         pSReg->Attr.u   = X86DESCATTR_UNUSABLE | X86DESCATTR_G | X86DESCATTR_D | (IEM_GET_CPL(pVCpu) << X86DESCATTR_DPL_SHIFT);
    1584         pSReg->u32Limit = UINT32_MAX;
    1585         pSReg->u64Base  = 0;
    1586     }
    1587     else
    1588     {
    1589         pSReg->Attr.u   = X86DESCATTR_UNUSABLE;
    1590         pSReg->u32Limit = 0;
    1591         pSReg->u64Base  = 0;
    1592     }
    1593 }
    1594 
    1595 /** @} */
    1596 
    1597 
    1598 /*
    1599  *
    1600  * Helpers routines.
    1601  * Helpers routines.
    1602  * Helpers routines.
    1603  *
    1604  */
    1605 
    1606 #ifndef IEM_WITH_OPAQUE_DECODER_STATE
    1607 
    1608 /**
    1609  * Recalculates the effective operand size.
    1610  *
    1611  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    1612  */
    1613 DECLINLINE(void) iemRecalEffOpSize(PVMCPUCC pVCpu) RT_NOEXCEPT
    1614 {
    1615     switch (IEM_GET_CPU_MODE(pVCpu))
    1616     {
    1617         case IEMMODE_16BIT:
    1618             pVCpu->iem.s.enmEffOpSize = pVCpu->iem.s.fPrefixes & IEM_OP_PRF_SIZE_OP ? IEMMODE_32BIT : IEMMODE_16BIT;
    1619             break;
    1620         case IEMMODE_32BIT:
    1621             pVCpu->iem.s.enmEffOpSize = pVCpu->iem.s.fPrefixes & IEM_OP_PRF_SIZE_OP ? IEMMODE_16BIT : IEMMODE_32BIT;
    1622             break;
    1623         case IEMMODE_64BIT:
    1624             switch (pVCpu->iem.s.fPrefixes & (IEM_OP_PRF_SIZE_REX_W | IEM_OP_PRF_SIZE_OP))
    1625             {
    1626                 case 0:
    1627                     pVCpu->iem.s.enmEffOpSize = pVCpu->iem.s.enmDefOpSize;
    1628                     break;
    1629                 case IEM_OP_PRF_SIZE_OP:
    1630                     pVCpu->iem.s.enmEffOpSize = IEMMODE_16BIT;
    1631                     break;
    1632                 case IEM_OP_PRF_SIZE_REX_W:
    1633                 case IEM_OP_PRF_SIZE_REX_W | IEM_OP_PRF_SIZE_OP:
    1634                     pVCpu->iem.s.enmEffOpSize = IEMMODE_64BIT;
    1635                     break;
    1636             }
    1637             break;
    1638         default:
    1639             AssertFailed();
    1640     }
    1641 }
    1642 
    1643 
    1644 /**
    1645  * Sets the default operand size to 64-bit and recalculates the effective
    1646  * operand size.
    1647  *
    1648  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    1649  */
    1650 DECLINLINE(void) iemRecalEffOpSize64Default(PVMCPUCC pVCpu) RT_NOEXCEPT
    1651 {
    1652     Assert(IEM_IS_64BIT_CODE(pVCpu));
    1653     pVCpu->iem.s.enmDefOpSize = IEMMODE_64BIT;
    1654     if ((pVCpu->iem.s.fPrefixes & (IEM_OP_PRF_SIZE_REX_W | IEM_OP_PRF_SIZE_OP)) != IEM_OP_PRF_SIZE_OP)
    1655         pVCpu->iem.s.enmEffOpSize = IEMMODE_64BIT;
    1656     else
    1657         pVCpu->iem.s.enmEffOpSize = IEMMODE_16BIT;
    1658 }
    1659 
    1660 
    1661 /**
    1662  * Sets the default operand size to 64-bit and recalculates the effective
    1663  * operand size, with intel ignoring any operand size prefix (AMD respects it).
    1664  *
    1665  * This is for the relative jumps.
    1666  *
    1667  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    1668  */
    1669 DECLINLINE(void) iemRecalEffOpSize64DefaultAndIntelIgnoresOpSizePrefix(PVMCPUCC pVCpu) RT_NOEXCEPT
    1670 {
    1671     Assert(IEM_IS_64BIT_CODE(pVCpu));
    1672     pVCpu->iem.s.enmDefOpSize = IEMMODE_64BIT;
    1673     if (   (pVCpu->iem.s.fPrefixes & (IEM_OP_PRF_SIZE_REX_W | IEM_OP_PRF_SIZE_OP)) != IEM_OP_PRF_SIZE_OP
    1674         || pVCpu->iem.s.enmCpuVendor == CPUMCPUVENDOR_INTEL)
    1675         pVCpu->iem.s.enmEffOpSize = IEMMODE_64BIT;
    1676     else
    1677         pVCpu->iem.s.enmEffOpSize = IEMMODE_16BIT;
    1678 }
    1679 
    1680 #endif /* !IEM_WITH_OPAQUE_DECODER_STATE */
    1681 
    1682 
    1683 
    1684 /** @name   Register Access.
    1685  * @{
    1686  */
    1687 
    1688 /**
    1689  * Gets a reference (pointer) to the specified hidden segment register.
    1690  *
    1691  * @returns Hidden register reference.
    1692  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    1693  * @param   iSegReg             The segment register.
    1694  */
    1695 DECL_FORCE_INLINE(PCPUMSELREG) iemSRegGetHid(PVMCPUCC pVCpu, uint8_t iSegReg) RT_NOEXCEPT
    1696 {
    1697     Assert(iSegReg < X86_SREG_COUNT);
    1698     IEM_CTX_ASSERT(pVCpu, CPUMCTX_EXTRN_SREG_FROM_IDX(iSegReg));
    1699     PCPUMSELREG pSReg = &pVCpu->cpum.GstCtx.aSRegs[iSegReg];
    1700 
    1701     Assert(CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pVCpu, pSReg));
    1702     return pSReg;
    1703 }
    1704 
    1705 
    1706 /**
    1707  * Ensures that the given hidden segment register is up to date.
    1708  *
    1709  * @returns Hidden register reference.
    1710  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    1711  * @param   pSReg               The segment register.
    1712  */
    1713 DECL_FORCE_INLINE(PCPUMSELREG) iemSRegUpdateHid(PVMCPUCC pVCpu, PCPUMSELREG pSReg) RT_NOEXCEPT
    1714 {
    1715     Assert(CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pVCpu, pSReg));
    1716     NOREF(pVCpu);
    1717     return pSReg;
    1718 }
    1719 
    1720 
    1721 /**
    1722  * Gets a reference (pointer) to the specified segment register (the selector
    1723  * value).
    1724  *
    1725  * @returns Pointer to the selector variable.
    1726  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    1727  * @param   iSegReg             The segment register.
    1728  */
    1729 DECL_FORCE_INLINE(uint16_t *) iemSRegRef(PVMCPUCC pVCpu, uint8_t iSegReg) RT_NOEXCEPT
    1730 {
    1731     Assert(iSegReg < X86_SREG_COUNT);
    1732     IEM_CTX_ASSERT(pVCpu, CPUMCTX_EXTRN_SREG_FROM_IDX(iSegReg));
    1733     return &pVCpu->cpum.GstCtx.aSRegs[iSegReg].Sel;
    1734 }
    1735 
    1736 
    1737 /**
    1738  * Fetches the selector value of a segment register.
    1739  *
    1740  * @returns The selector value.
    1741  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    1742  * @param   iSegReg             The segment register.
    1743  */
    1744 DECL_FORCE_INLINE(uint16_t) iemSRegFetchU16(PVMCPUCC pVCpu, uint8_t iSegReg) RT_NOEXCEPT
    1745 {
    1746     Assert(iSegReg < X86_SREG_COUNT);
    1747     IEM_CTX_ASSERT(pVCpu, CPUMCTX_EXTRN_SREG_FROM_IDX(iSegReg));
    1748     return pVCpu->cpum.GstCtx.aSRegs[iSegReg].Sel;
    1749 }
    1750 
    1751 
    1752 /**
    1753  * Fetches the base address value of a segment register.
    1754  *
    1755  * @returns The selector value.
    1756  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    1757  * @param   iSegReg             The segment register.
    1758  */
    1759 DECL_FORCE_INLINE(uint64_t) iemSRegBaseFetchU64(PVMCPUCC pVCpu, uint8_t iSegReg) RT_NOEXCEPT
    1760 {
    1761     Assert(iSegReg < X86_SREG_COUNT);
    1762     IEM_CTX_ASSERT(pVCpu, CPUMCTX_EXTRN_SREG_FROM_IDX(iSegReg));
    1763     return pVCpu->cpum.GstCtx.aSRegs[iSegReg].u64Base;
    1764 }
    1765 
    1766 
    1767 /**
    1768  * Gets a reference (pointer) to the specified general purpose register.
    1769  *
    1770  * @returns Register reference.
    1771  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    1772  * @param   iReg                The general purpose register.
    1773  */
    1774 DECL_FORCE_INLINE(void *) iemGRegRef(PVMCPUCC pVCpu, uint8_t iReg) RT_NOEXCEPT
    1775 {
    1776     Assert(iReg < 16);
    1777     return &pVCpu->cpum.GstCtx.aGRegs[iReg];
    1778 }
    1779 
    1780 
    1781 #ifndef IEM_WITH_OPAQUE_DECODER_STATE
    1782 /**
    1783  * Gets a reference (pointer) to the specified 8-bit general purpose register.
    1784  *
    1785  * Because of AH, CH, DH and BH we cannot use iemGRegRef directly here.
    1786  *
    1787  * @returns Register reference.
    1788  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    1789  * @param   iReg                The register.
    1790  */
    1791 DECL_FORCE_INLINE(uint8_t *) iemGRegRefU8(PVMCPUCC pVCpu, uint8_t iReg) RT_NOEXCEPT
    1792 {
    1793     if (iReg < 4 || (pVCpu->iem.s.fPrefixes & (IEM_OP_PRF_REX | IEM_OP_PRF_VEX)))
    1794     {
    1795         Assert(iReg < 16);
    1796         return &pVCpu->cpum.GstCtx.aGRegs[iReg].u8;
    1797     }
    1798     /* high 8-bit register. */
    1799     Assert(iReg < 8);
    1800     return &pVCpu->cpum.GstCtx.aGRegs[iReg & 3].bHi;
    1801 }
    1802 #endif
    1803 
    1804 
    1805 /**
    1806  * Gets a reference (pointer) to the specified 8-bit general purpose register,
    1807  * alternative version with extended (20) register index.
    1808  *
    1809  * @returns Register reference.
    1810  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    1811  * @param   iRegEx              The register.  The 16 first are regular ones,
    1812  *                              whereas 16 thru 19 maps to AH, CH, DH and BH.
    1813  */
    1814 DECL_FORCE_INLINE(uint8_t *) iemGRegRefU8Ex(PVMCPUCC pVCpu, uint8_t iRegEx) RT_NOEXCEPT
    1815 {
    1816     /** @todo This could be done by double indexing on little endian hosts:
    1817      *  return &pVCpu->cpum.GstCtx.aGRegs[iRegEx & 15].ab[iRegEx >> 4]; */
    1818     if (iRegEx < 16)
    1819         return &pVCpu->cpum.GstCtx.aGRegs[iRegEx].u8;
    1820 
    1821     /* high 8-bit register. */
    1822     Assert(iRegEx < 20);
    1823     return &pVCpu->cpum.GstCtx.aGRegs[iRegEx & 3].bHi;
    1824 }
    1825 
    1826 
    1827 /**
    1828  * Gets a reference (pointer) to the specified 16-bit general purpose register.
    1829  *
    1830  * @returns Register reference.
    1831  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    1832  * @param   iReg                The register.
    1833  */
    1834 DECL_FORCE_INLINE(uint16_t *) iemGRegRefU16(PVMCPUCC pVCpu, uint8_t iReg) RT_NOEXCEPT
    1835 {
    1836     Assert(iReg < 16);
    1837     return &pVCpu->cpum.GstCtx.aGRegs[iReg].u16;
    1838 }
    1839 
    1840 
    1841 /**
    1842  * Gets a reference (pointer) to the specified 32-bit general purpose register.
    1843  *
    1844  * @returns Register reference.
    1845  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    1846  * @param   iReg                The register.
    1847  */
    1848 DECL_FORCE_INLINE(uint32_t *) iemGRegRefU32(PVMCPUCC pVCpu, uint8_t iReg) RT_NOEXCEPT
    1849 {
    1850     Assert(iReg < 16);
    1851     return &pVCpu->cpum.GstCtx.aGRegs[iReg].u32;
    1852 }
    1853 
    1854 
    1855 /**
    1856  * Gets a reference (pointer) to the specified signed 32-bit general purpose register.
    1857  *
    1858  * @returns Register reference.
    1859  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    1860  * @param   iReg                The register.
    1861  */
    1862 DECL_FORCE_INLINE(int32_t *) iemGRegRefI32(PVMCPUCC pVCpu, uint8_t iReg) RT_NOEXCEPT
    1863 {
    1864     Assert(iReg < 16);
    1865     return (int32_t *)&pVCpu->cpum.GstCtx.aGRegs[iReg].u32;
    1866 }
    1867 
    1868 
    1869 /**
    1870  * Gets a reference (pointer) to the specified 64-bit general purpose register.
    1871  *
    1872  * @returns Register reference.
    1873  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    1874  * @param   iReg                The register.
    1875  */
    1876 DECL_FORCE_INLINE(uint64_t *) iemGRegRefU64(PVMCPUCC pVCpu, uint8_t iReg) RT_NOEXCEPT
    1877 {
    1878     Assert(iReg < 64);
    1879     return &pVCpu->cpum.GstCtx.aGRegs[iReg].u64;
    1880 }
    1881 
    1882 
    1883 /**
    1884  * Gets a reference (pointer) to the specified signed 64-bit general purpose register.
    1885  *
    1886  * @returns Register reference.
    1887  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    1888  * @param   iReg                The register.
    1889  */
    1890 DECL_FORCE_INLINE(int64_t *) iemGRegRefI64(PVMCPUCC pVCpu, uint8_t iReg) RT_NOEXCEPT
    1891 {
    1892     Assert(iReg < 16);
    1893     return (int64_t *)&pVCpu->cpum.GstCtx.aGRegs[iReg].u64;
    1894 }
    1895 
    1896 
    1897 /**
    1898  * Gets a reference (pointer) to the specified segment register's base address.
    1899  *
    1900  * @returns Segment register base address reference.
    1901  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    1902  * @param   iSegReg             The segment selector.
    1903  */
    1904 DECL_FORCE_INLINE(uint64_t *) iemSRegBaseRefU64(PVMCPUCC pVCpu, uint8_t iSegReg) RT_NOEXCEPT
    1905 {
    1906     Assert(iSegReg < X86_SREG_COUNT);
    1907     IEM_CTX_ASSERT(pVCpu, CPUMCTX_EXTRN_SREG_FROM_IDX(iSegReg));
    1908     return &pVCpu->cpum.GstCtx.aSRegs[iSegReg].u64Base;
    1909 }
    1910 
    1911 
    1912 #ifndef IEM_WITH_OPAQUE_DECODER_STATE
    1913 /**
    1914  * Fetches the value of a 8-bit general purpose register.
    1915  *
    1916  * @returns The register value.
    1917  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    1918  * @param   iReg                The register.
    1919  */
    1920 DECL_FORCE_INLINE(uint8_t) iemGRegFetchU8(PVMCPUCC pVCpu, uint8_t iReg) RT_NOEXCEPT
    1921 {
    1922     return *iemGRegRefU8(pVCpu, iReg);
    1923 }
    1924 #endif
    1925 
    1926 
    1927 /**
    1928  * Fetches the value of a 8-bit general purpose register, alternative version
    1929  * with extended (20) register index.
    1930 
    1931  * @returns The register value.
    1932  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    1933  * @param   iRegEx              The register.  The 16 first are regular ones,
    1934  *                              whereas 16 thru 19 maps to AH, CH, DH and BH.
    1935  */
    1936 DECL_FORCE_INLINE(uint8_t) iemGRegFetchU8Ex(PVMCPUCC pVCpu, uint8_t iRegEx) RT_NOEXCEPT
    1937 {
    1938     return *iemGRegRefU8Ex(pVCpu, iRegEx);
    1939 }
    1940 
    1941 
    1942 /**
    1943  * Fetches the value of a 16-bit general purpose register.
    1944  *
    1945  * @returns The register value.
    1946  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    1947  * @param   iReg                The register.
    1948  */
    1949 DECL_FORCE_INLINE(uint16_t) iemGRegFetchU16(PVMCPUCC pVCpu, uint8_t iReg) RT_NOEXCEPT
    1950 {
    1951     Assert(iReg < 16);
    1952     return pVCpu->cpum.GstCtx.aGRegs[iReg].u16;
    1953 }
    1954 
    1955 
    1956 /**
    1957  * Fetches the value of a 32-bit general purpose register.
    1958  *
    1959  * @returns The register value.
    1960  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    1961  * @param   iReg                The register.
    1962  */
    1963 DECL_FORCE_INLINE(uint32_t) iemGRegFetchU32(PVMCPUCC pVCpu, uint8_t iReg) RT_NOEXCEPT
    1964 {
    1965     Assert(iReg < 16);
    1966     return pVCpu->cpum.GstCtx.aGRegs[iReg].u32;
    1967 }
    1968 
    1969 
    1970 /**
    1971  * Fetches the value of a 64-bit general purpose register.
    1972  *
    1973  * @returns The register value.
    1974  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    1975  * @param   iReg                The register.
    1976  */
    1977 DECL_FORCE_INLINE(uint64_t) iemGRegFetchU64(PVMCPUCC pVCpu, uint8_t iReg) RT_NOEXCEPT
    1978 {
    1979     Assert(iReg < 16);
    1980     return pVCpu->cpum.GstCtx.aGRegs[iReg].u64;
    1981 }
    1982 
    1983 
    1984 /**
    1985  * Stores a 16-bit value to a general purpose register.
    1986  *
    1987  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    1988  * @param   iReg                The register.
    1989  * @param   uValue              The value to store.
    1990  */
    1991 DECL_FORCE_INLINE(void) iemGRegStoreU16(PVMCPUCC pVCpu, uint8_t iReg, uint16_t uValue) RT_NOEXCEPT
    1992 {
    1993     Assert(iReg < 16);
    1994     pVCpu->cpum.GstCtx.aGRegs[iReg].u16 = uValue;
    1995 }
    1996 
    1997 
    1998 /**
    1999  * Stores a 32-bit value to a general purpose register, implicitly clearing high
    2000  * values.
    2001  *
    2002  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    2003  * @param   iReg                The register.
    2004  * @param   uValue              The value to store.
    2005  */
    2006 DECL_FORCE_INLINE(void) iemGRegStoreU32(PVMCPUCC pVCpu, uint8_t iReg, uint32_t uValue) RT_NOEXCEPT
    2007 {
    2008     Assert(iReg < 16);
    2009     pVCpu->cpum.GstCtx.aGRegs[iReg].u64 = uValue;
    2010 }
    2011 
    2012 
    2013 /**
    2014  * Stores a 64-bit value to a general purpose register.
    2015  *
    2016  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    2017  * @param   iReg                The register.
    2018  * @param   uValue              The value to store.
    2019  */
    2020 DECL_FORCE_INLINE(void) iemGRegStoreU64(PVMCPUCC pVCpu, uint8_t iReg, uint64_t uValue) RT_NOEXCEPT
    2021 {
    2022     Assert(iReg < 16);
    2023     pVCpu->cpum.GstCtx.aGRegs[iReg].u64 = uValue;
    2024 }
    2025 
    2026 
    2027 /**
    2028  * Get the address of the top of the stack.
    2029  *
    2030  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    2031  */
    2032 DECL_FORCE_INLINE(RTGCPTR) iemRegGetEffRsp(PCVMCPU pVCpu) RT_NOEXCEPT
    2033 {
    2034     if (IEM_IS_64BIT_CODE(pVCpu))
    2035         return pVCpu->cpum.GstCtx.rsp;
    2036     if (pVCpu->cpum.GstCtx.ss.Attr.n.u1DefBig)
    2037         return pVCpu->cpum.GstCtx.esp;
    2038     return pVCpu->cpum.GstCtx.sp;
    2039 }
    2040 
    2041 
    2042 /**
    2043  * Updates the RIP/EIP/IP to point to the next instruction.
    2044  *
    2045  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    2046  * @param   cbInstr             The number of bytes to add.
    2047  */
    2048 DECL_FORCE_INLINE(void) iemRegAddToRip(PVMCPUCC pVCpu, uint8_t cbInstr) RT_NOEXCEPT
    2049 {
    2050     /*
    2051      * Advance RIP.
    2052      *
    2053      * When we're targetting 8086/8, 80186/8 or 80286 mode the updates are 16-bit,
    2054      * while in all other modes except LM64 the updates are 32-bit.  This means
    2055      * we need to watch for both 32-bit and 16-bit "carry" situations, i.e.
    2056      * 4GB and 64KB rollovers, and decide whether anything needs masking.
    2057      *
    2058      * See PC wrap around tests in bs3-cpu-weird-1.
    2059      */
    2060     uint64_t const uRipPrev = pVCpu->cpum.GstCtx.rip;
    2061     uint64_t const uRipNext = uRipPrev + cbInstr;
    2062     if (RT_LIKELY(   !((uRipNext ^ uRipPrev) & (RT_BIT_64(32) | RT_BIT_64(16)))
    2063                   || IEM_IS_64BIT_CODE(pVCpu)))
    2064         pVCpu->cpum.GstCtx.rip = uRipNext;
    2065     else if (IEM_GET_TARGET_CPU(pVCpu) >= IEMTARGETCPU_386)
    2066         pVCpu->cpum.GstCtx.rip = (uint32_t)uRipNext;
    2067     else
    2068         pVCpu->cpum.GstCtx.rip = (uint16_t)uRipNext;
    2069 }
    2070 
    2071 
    2072 /**
    2073  * Called by iemRegAddToRipAndFinishingClearingRF and others when any of the
    2074  * following EFLAGS bits are set:
    2075  *      - X86_EFL_RF - clear it.
    2076  *      - CPUMCTX_INHIBIT_SHADOW (_SS/_STI) - clear them.
    2077  *      - X86_EFL_TF - generate single step \#DB trap.
    2078  *      - CPUMCTX_DBG_HIT_DR0/1/2/3 - generate \#DB trap (data or I/O, not
    2079  *        instruction).
    2080  *
    2081  * According to @sdmv3{077,200,Table 6-2,Priority Among Concurrent Events},
    2082  * a \#DB due to TF (single stepping) or a DRx non-instruction breakpoint
    2083  * takes priority over both NMIs and hardware interrupts.  So, neither is
    2084  * considered here.  (The RESET, \#MC, SMI, INIT, STOPCLK and FLUSH events are
    2085  * either unsupported will be triggered on-top of any \#DB raised here.)
    2086  *
    2087  * The RF flag only needs to be cleared here as it only suppresses instruction
    2088  * breakpoints which are not raised here (happens synchronously during
    2089  * instruction fetching).
    2090  *
    2091  * The CPUMCTX_INHIBIT_SHADOW_SS flag will be cleared by this function, so its
    2092  * status has no bearing on whether \#DB exceptions are raised.
    2093  *
    2094  * @note This must *NOT* be called by the two instructions setting the
    2095  *       CPUMCTX_INHIBIT_SHADOW_SS flag.
    2096  *
    2097  * @see  @sdmv3{077,200,Table 6-2,Priority Among Concurrent Events}
    2098  * @see  @sdmv3{077,200,6.8.3,Masking Exceptions and Interrupts When Switching
    2099  *              Stacks}
    2100  */
    2101 template<uint32_t const a_fTF = X86_EFL_TF>
    2102 static VBOXSTRICTRC iemFinishInstructionWithFlagsSet(PVMCPUCC pVCpu, int rcNormal) RT_NOEXCEPT
    2103 {
    2104     /*
    2105      * Normally we're just here to clear RF and/or interrupt shadow bits.
    2106      */
    2107     if (RT_LIKELY((pVCpu->cpum.GstCtx.eflags.uBoth & (a_fTF | CPUMCTX_DBG_HIT_DRX_MASK | CPUMCTX_DBG_DBGF_MASK)) == 0))
    2108         pVCpu->cpum.GstCtx.eflags.uBoth &= ~(X86_EFL_RF | CPUMCTX_INHIBIT_SHADOW);
    2109     else
    2110     {
    2111         /*
    2112          * Raise a #DB or/and DBGF event.
    2113          */
    2114         VBOXSTRICTRC rcStrict;
    2115         if (pVCpu->cpum.GstCtx.eflags.uBoth & (a_fTF | CPUMCTX_DBG_HIT_DRX_MASK))
    2116         {
    2117             IEM_CTX_IMPORT_RET(pVCpu, CPUMCTX_EXTRN_DR6);
    2118             pVCpu->cpum.GstCtx.dr[6] &= ~X86_DR6_B_MASK;
    2119             if (pVCpu->cpum.GstCtx.eflags.uBoth & a_fTF)
    2120                 pVCpu->cpum.GstCtx.dr[6] |= X86_DR6_BS;
    2121             pVCpu->cpum.GstCtx.dr[6] |= (pVCpu->cpum.GstCtx.eflags.uBoth & CPUMCTX_DBG_HIT_DRX_MASK_NONSILENT)
    2122                                      >> CPUMCTX_DBG_HIT_DRX_SHIFT;
    2123             LogFlowFunc(("Guest #DB fired at %04X:%016llX: DR6=%08X, RFLAGS=%16RX64\n",
    2124                          pVCpu->cpum.GstCtx.cs.Sel, pVCpu->cpum.GstCtx.rip, (unsigned)pVCpu->cpum.GstCtx.dr[6],
    2125                          pVCpu->cpum.GstCtx.rflags.uBoth));
    2126 
    2127             pVCpu->cpum.GstCtx.eflags.uBoth &= ~(X86_EFL_RF | CPUMCTX_INHIBIT_SHADOW | CPUMCTX_DBG_HIT_DRX_MASK);
    2128             rcStrict = iemRaiseDebugException(pVCpu);
    2129 
    2130             /* A DBGF event/breakpoint trumps the iemRaiseDebugException informational status code. */
    2131             if ((pVCpu->cpum.GstCtx.eflags.uBoth & CPUMCTX_DBG_DBGF_MASK) && RT_FAILURE(rcStrict))
    2132             {
    2133                 rcStrict = pVCpu->cpum.GstCtx.eflags.uBoth & CPUMCTX_DBG_DBGF_BP ? VINF_EM_DBG_BREAKPOINT : VINF_EM_DBG_EVENT;
    2134                 LogFlowFunc(("dbgf at %04X:%016llX: %Rrc\n", pVCpu->cpum.GstCtx.cs.Sel, pVCpu->cpum.GstCtx.rip, VBOXSTRICTRC_VAL(rcStrict)));
    2135             }
    2136         }
    2137         else
    2138         {
    2139             Assert(pVCpu->cpum.GstCtx.eflags.uBoth & CPUMCTX_DBG_DBGF_MASK);
    2140             rcStrict = pVCpu->cpum.GstCtx.eflags.uBoth & CPUMCTX_DBG_DBGF_BP ? VINF_EM_DBG_BREAKPOINT : VINF_EM_DBG_EVENT;
    2141             LogFlowFunc(("dbgf at %04X:%016llX: %Rrc\n", pVCpu->cpum.GstCtx.cs.Sel, pVCpu->cpum.GstCtx.rip, VBOXSTRICTRC_VAL(rcStrict)));
    2142         }
    2143         pVCpu->cpum.GstCtx.eflags.uBoth &= ~CPUMCTX_DBG_DBGF_MASK;
    2144         Assert(rcStrict != VINF_SUCCESS);
    2145         return rcStrict;
    2146     }
    2147     return rcNormal;
    2148 }
    2149 
    2150 
    2151 /**
    2152  * Clears the RF and CPUMCTX_INHIBIT_SHADOW, triggering \#DB if pending.
    2153  *
    2154  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    2155  * @param   rcNormal            VINF_SUCCESS to continue TB.
    2156  *                              VINF_IEM_REEXEC_BREAK to force TB exit when
    2157  *                              taking the wrong conditional branhc.
    2158  */
    2159 DECL_FORCE_INLINE(VBOXSTRICTRC) iemRegFinishClearingRF(PVMCPUCC pVCpu, int rcNormal) RT_NOEXCEPT
    2160 {
    2161     /*
    2162      * We assume that most of the time nothing actually needs doing here.
    2163      */
    2164     AssertCompile(CPUMCTX_INHIBIT_SHADOW < UINT32_MAX);
    2165     if (RT_LIKELY(!(  pVCpu->cpum.GstCtx.eflags.uBoth
    2166                     & (X86_EFL_TF | X86_EFL_RF | CPUMCTX_INHIBIT_SHADOW | CPUMCTX_DBG_HIT_DRX_MASK | CPUMCTX_DBG_DBGF_MASK)) ))
    2167         return rcNormal;
    2168     return iemFinishInstructionWithFlagsSet(pVCpu, rcNormal);
    2169 }
    2170 
    2171 
    2172 /**
    2173  * Updates the RIP/EIP/IP to point to the next instruction and clears EFLAGS.RF
    2174  * and CPUMCTX_INHIBIT_SHADOW.
    2175  *
    2176  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    2177  * @param   cbInstr             The number of bytes to add.
    2178  */
    2179 DECL_FORCE_INLINE(VBOXSTRICTRC) iemRegAddToRipAndFinishingClearingRF(PVMCPUCC pVCpu, uint8_t cbInstr) RT_NOEXCEPT
    2180 {
    2181     iemRegAddToRip(pVCpu, cbInstr);
    2182     return iemRegFinishClearingRF(pVCpu, VINF_SUCCESS);
    2183 }
    2184 
    2185 
    2186 /**
    2187  * Updates the RIP to point to the next instruction and clears EFLAGS.RF
    2188  * and CPUMCTX_INHIBIT_SHADOW.
    2189  *
    2190  * Only called from 64-bit code.
    2191  *
    2192  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    2193  * @param   cbInstr             The number of bytes to add.
    2194  * @param   rcNormal            VINF_SUCCESS to continue TB.
    2195  *                              VINF_IEM_REEXEC_BREAK to force TB exit when
    2196  *                              taking the wrong conditional branhc.
    2197  */
    2198 DECL_FORCE_INLINE(VBOXSTRICTRC) iemRegAddToRip64AndFinishingClearingRF(PVMCPUCC pVCpu, uint8_t cbInstr, int rcNormal) RT_NOEXCEPT
    2199 {
    2200     pVCpu->cpum.GstCtx.rip = pVCpu->cpum.GstCtx.rip + cbInstr;
    2201     return iemRegFinishClearingRF(pVCpu, rcNormal);
    2202 }
    2203 
    2204 
    2205 /**
    2206  * Updates the EIP to point to the next instruction and clears EFLAGS.RF and
    2207  * CPUMCTX_INHIBIT_SHADOW.
    2208  *
    2209  * This is never from 64-bit code.
    2210  *
    2211  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    2212  * @param   cbInstr             The number of bytes to add.
    2213  * @param   rcNormal            VINF_SUCCESS to continue TB.
    2214  *                              VINF_IEM_REEXEC_BREAK to force TB exit when
    2215  *                              taking the wrong conditional branhc.
    2216  */
    2217 DECL_FORCE_INLINE(VBOXSTRICTRC) iemRegAddToEip32AndFinishingClearingRF(PVMCPUCC pVCpu, uint8_t cbInstr, int rcNormal) RT_NOEXCEPT
    2218 {
    2219     pVCpu->cpum.GstCtx.rip = (uint32_t)(pVCpu->cpum.GstCtx.eip + cbInstr);
    2220     return iemRegFinishClearingRF(pVCpu, rcNormal);
    2221 }
    2222 
    2223 
    2224 /**
    2225  * Updates the IP to point to the next instruction and clears EFLAGS.RF and
    2226  * CPUMCTX_INHIBIT_SHADOW.
    2227  *
    2228  * This is only ever used from 16-bit code on a pre-386 CPU.
    2229  *
    2230  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    2231  * @param   cbInstr             The number of bytes to add.
    2232  * @param   rcNormal            VINF_SUCCESS to continue TB.
    2233  *                              VINF_IEM_REEXEC_BREAK to force TB exit when
    2234  *                              taking the wrong conditional branhc.
    2235  */
    2236 DECL_FORCE_INLINE(VBOXSTRICTRC) iemRegAddToIp16AndFinishingClearingRF(PVMCPUCC pVCpu, uint8_t cbInstr, int rcNormal) RT_NOEXCEPT
    2237 {
    2238     pVCpu->cpum.GstCtx.rip = (uint16_t)(pVCpu->cpum.GstCtx.ip + cbInstr);
    2239     return iemRegFinishClearingRF(pVCpu, rcNormal);
    2240 }
    2241 
    2242 
    2243 /**
    2244  * Tail method for a finish function that does't clear flags or raise \#DB.
    2245  *
    2246  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    2247  * @param   rcNormal            VINF_SUCCESS to continue TB.
    2248  *                              VINF_IEM_REEXEC_BREAK to force TB exit when
    2249  *                              taking the wrong conditional branhc.
    2250  */
    2251 DECL_FORCE_INLINE(VBOXSTRICTRC) iemRegFinishNoFlags(PVMCPUCC pVCpu, int rcNormal) RT_NOEXCEPT
    2252 {
    2253     AssertCompile(CPUMCTX_INHIBIT_SHADOW < UINT32_MAX);
    2254     Assert(!(  pVCpu->cpum.GstCtx.eflags.uBoth
    2255              & (X86_EFL_TF | X86_EFL_RF | CPUMCTX_INHIBIT_SHADOW | CPUMCTX_DBG_HIT_DRX_MASK | CPUMCTX_DBG_DBGF_MASK)) );
    2256     RT_NOREF(pVCpu);
    2257     return rcNormal;
    2258 }
    2259 
    2260 
    2261 /**
    2262  * Updates the RIP to point to the next instruction, but does not need to clear
    2263  * EFLAGS.RF or CPUMCTX_INHIBIT_SHADOW nor check for debug flags.
    2264  *
    2265  * Only called from 64-bit code.
    2266  *
    2267  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    2268  * @param   cbInstr             The number of bytes to add.
    2269  * @param   rcNormal            VINF_SUCCESS to continue TB.
    2270  *                              VINF_IEM_REEXEC_BREAK to force TB exit when
    2271  *                              taking the wrong conditional branhc.
    2272  */
    2273 DECL_FORCE_INLINE(VBOXSTRICTRC) iemRegAddToRip64AndFinishingNoFlags(PVMCPUCC pVCpu, uint8_t cbInstr, int rcNormal) RT_NOEXCEPT
    2274 {
    2275     pVCpu->cpum.GstCtx.rip = pVCpu->cpum.GstCtx.rip + cbInstr;
    2276     return iemRegFinishNoFlags(pVCpu, rcNormal);
    2277 }
    2278 
    2279 
    2280 /**
    2281  * Updates the EIP to point to the next instruction, but does not need to clear
    2282  * EFLAGS.RF or CPUMCTX_INHIBIT_SHADOW nor check for debug flags.
    2283  *
    2284  * This is never from 64-bit code.
    2285  *
    2286  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    2287  * @param   cbInstr             The number of bytes to add.
    2288  * @param   rcNormal            VINF_SUCCESS to continue TB.
    2289  *                              VINF_IEM_REEXEC_BREAK to force TB exit when
    2290  *                              taking the wrong conditional branhc.
    2291  */
    2292 DECL_FORCE_INLINE(VBOXSTRICTRC) iemRegAddToEip32AndFinishingNoFlags(PVMCPUCC pVCpu, uint8_t cbInstr, int rcNormal) RT_NOEXCEPT
    2293 {
    2294     pVCpu->cpum.GstCtx.rip = (uint32_t)(pVCpu->cpum.GstCtx.eip + cbInstr);
    2295     return iemRegFinishNoFlags(pVCpu, rcNormal);
    2296 }
    2297 
    2298 
    2299 /**
    2300  * Updates the IP to point to the next instruction, but does not need to clear
    2301  * EFLAGS.RF or CPUMCTX_INHIBIT_SHADOW nor check for debug flags.
    2302  *
    2303  * This is only ever used from 16-bit code on a pre-386 CPU.
    2304  *
    2305  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    2306  * @param   cbInstr             The number of bytes to add.
    2307  * @param   rcNormal            VINF_SUCCESS to continue TB.
    2308  *                              VINF_IEM_REEXEC_BREAK to force TB exit when
    2309  *                              taking the wrong conditional branhc.
    2310  *
    2311  */
    2312 DECL_FORCE_INLINE(VBOXSTRICTRC) iemRegAddToIp16AndFinishingNoFlags(PVMCPUCC pVCpu, uint8_t cbInstr, int rcNormal) RT_NOEXCEPT
    2313 {
    2314     pVCpu->cpum.GstCtx.rip = (uint16_t)(pVCpu->cpum.GstCtx.ip + cbInstr);
    2315     return iemRegFinishNoFlags(pVCpu, rcNormal);
    2316 }
    2317 
    2318 
    2319 /**
    2320  * Adds a 8-bit signed jump offset to RIP from 64-bit code.
    2321  *
    2322  * May raise a \#GP(0) if the new RIP is non-canonical or outside the code
    2323  * segment limit.
    2324  *
    2325  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    2326  * @param   cbInstr             Instruction size.
    2327  * @param   offNextInstr        The offset of the next instruction.
    2328  * @param   enmEffOpSize        Effective operand size.
    2329  * @param   rcNormal            VINF_SUCCESS to continue TB.
    2330  *                              VINF_IEM_REEXEC_BREAK to force TB exit when
    2331  *                              taking the wrong conditional branhc.
    2332  */
    2333 DECL_FORCE_INLINE(VBOXSTRICTRC) iemRegRip64RelativeJumpS8AndFinishClearingRF(PVMCPUCC pVCpu, uint8_t cbInstr, int8_t offNextInstr,
    2334                                                                              IEMMODE enmEffOpSize, int rcNormal) RT_NOEXCEPT
    2335 {
    2336     Assert(IEM_IS_64BIT_CODE(pVCpu));
    2337     Assert(enmEffOpSize == IEMMODE_64BIT || enmEffOpSize == IEMMODE_16BIT);
    2338 
    2339     uint64_t uNewRip = pVCpu->cpum.GstCtx.rip + cbInstr + (int64_t)offNextInstr;
    2340     if (enmEffOpSize == IEMMODE_16BIT)
    2341         uNewRip &= UINT16_MAX;
    2342 
    2343     if (RT_LIKELY(IEM_IS_CANONICAL(uNewRip)))
    2344         pVCpu->cpum.GstCtx.rip = uNewRip;
    2345     else
    2346         return iemRaiseGeneralProtectionFault0(pVCpu);
    2347 
    2348 #ifndef IEM_WITH_CODE_TLB
    2349     iemOpcodeFlushLight(pVCpu, cbInstr);
    2350 #endif
    2351 
    2352     /*
    2353      * Clear RF and finish the instruction (maybe raise #DB).
    2354      */
    2355     return iemRegFinishClearingRF(pVCpu, rcNormal);
    2356 }
    2357 
    2358 
    2359 /**
    2360  * Adds a 8-bit signed jump offset to RIP from 64-bit code when the caller is
    2361  * sure it stays within the same page.
    2362  *
    2363  * May raise a \#GP(0) if the new RIP is non-canonical or outside the code
    2364  * segment limit.
    2365  *
    2366  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    2367  * @param   cbInstr             Instruction size.
    2368  * @param   offNextInstr        The offset of the next instruction.
    2369  * @param   enmEffOpSize        Effective operand size.
    2370  * @param   rcNormal            VINF_SUCCESS to continue TB.
    2371  *                              VINF_IEM_REEXEC_BREAK to force TB exit when
    2372  *                              taking the wrong conditional branhc.
    2373  */
    2374 DECL_FORCE_INLINE(VBOXSTRICTRC)
    2375 iemRegRip64RelativeJumpS8IntraPgAndFinishClearingRF(PVMCPUCC pVCpu, uint8_t cbInstr, int8_t offNextInstr,
    2376                                                     IEMMODE enmEffOpSize, int rcNormal) RT_NOEXCEPT
    2377 {
    2378     Assert(IEM_IS_64BIT_CODE(pVCpu));
    2379     Assert(enmEffOpSize == IEMMODE_64BIT); RT_NOREF(enmEffOpSize);
    2380 
    2381     uint64_t const uNewRip = pVCpu->cpum.GstCtx.rip + cbInstr + (int64_t)offNextInstr;
    2382     Assert((pVCpu->cpum.GstCtx.rip >> GUEST_PAGE_SHIFT) == (uNewRip >> GUEST_PAGE_SHIFT));
    2383     pVCpu->cpum.GstCtx.rip = uNewRip;
    2384 
    2385 #ifndef IEM_WITH_CODE_TLB
    2386     iemOpcodeFlushLight(pVCpu, cbInstr);
    2387 #endif
    2388 
    2389     /*
    2390      * Clear RF and finish the instruction (maybe raise #DB).
    2391      */
    2392     return iemRegFinishClearingRF(pVCpu, rcNormal);
    2393 }
    2394 
    2395 
    2396 /**
    2397  * Adds a 8-bit signed jump offset to EIP, on 386 or later from 16-bit or 32-bit
    2398  * code (never 64-bit).
    2399  *
    2400  * May raise a \#GP(0) if the new RIP is non-canonical or outside the code
    2401  * segment limit.
    2402  *
    2403  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    2404  * @param   cbInstr             Instruction size.
    2405  * @param   offNextInstr        The offset of the next instruction.
    2406  * @param   enmEffOpSize        Effective operand size.
    2407  * @param   rcNormal            VINF_SUCCESS to continue TB.
    2408  *                              VINF_IEM_REEXEC_BREAK to force TB exit when
    2409  *                              taking the wrong conditional branhc.
    2410  */
    2411 DECL_FORCE_INLINE(VBOXSTRICTRC) iemRegEip32RelativeJumpS8AndFinishClearingRF(PVMCPUCC pVCpu, uint8_t cbInstr, int8_t offNextInstr,
    2412                                                                              IEMMODE enmEffOpSize, int rcNormal) RT_NOEXCEPT
    2413 {
    2414     Assert(!IEM_IS_64BIT_CODE(pVCpu));
    2415     Assert(enmEffOpSize == IEMMODE_32BIT || enmEffOpSize == IEMMODE_16BIT);
    2416 
    2417     uint32_t uNewEip = pVCpu->cpum.GstCtx.eip + cbInstr + (int32_t)offNextInstr;
    2418     if (enmEffOpSize == IEMMODE_16BIT)
    2419         uNewEip &= UINT16_MAX;
    2420     if (RT_LIKELY(uNewEip <= pVCpu->cpum.GstCtx.cs.u32Limit))
    2421         pVCpu->cpum.GstCtx.rip = uNewEip;
    2422     else
    2423         return iemRaiseGeneralProtectionFault0(pVCpu);
    2424 
    2425 #ifndef IEM_WITH_CODE_TLB
    2426     iemOpcodeFlushLight(pVCpu, cbInstr);
    2427 #endif
    2428 
    2429     /*
    2430      * Clear RF and finish the instruction (maybe raise #DB).
    2431      */
    2432     return iemRegFinishClearingRF(pVCpu, rcNormal);
    2433 }
    2434 
    2435 
    2436 /**
    2437  * Adds a 8-bit signed jump offset to EIP, on 386 or later from FLAT 32-bit code
    2438  * (never 64-bit).
    2439  *
    2440  * May raise a \#GP(0) if the new RIP is non-canonical or outside the code
    2441  * segment limit.
    2442  *
    2443  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    2444  * @param   cbInstr             Instruction size.
    2445  * @param   offNextInstr        The offset of the next instruction.
    2446  * @param   enmEffOpSize        Effective operand size.
    2447  * @param   rcNormal            VINF_SUCCESS to continue TB.
    2448  *                              VINF_IEM_REEXEC_BREAK to force TB exit when
    2449  *                              taking the wrong conditional branhc.
    2450  */
    2451 DECL_FORCE_INLINE(VBOXSTRICTRC)
    2452  iemRegEip32RelativeJumpS8FlatAndFinishClearingRF(PVMCPUCC pVCpu, uint8_t cbInstr, int8_t offNextInstr,
    2453                                                   IEMMODE enmEffOpSize, int rcNormal) RT_NOEXCEPT
    2454 {
    2455     Assert(!IEM_IS_64BIT_CODE(pVCpu));
    2456     Assert(enmEffOpSize == IEMMODE_32BIT || enmEffOpSize == IEMMODE_16BIT);
    2457 
    2458     uint32_t uNewEip = pVCpu->cpum.GstCtx.eip + cbInstr + (int32_t)offNextInstr;
    2459     if (enmEffOpSize == IEMMODE_16BIT)
    2460         uNewEip &= UINT16_MAX;
    2461     pVCpu->cpum.GstCtx.rip = uNewEip;
    2462 
    2463 #ifndef IEM_WITH_CODE_TLB
    2464     iemOpcodeFlushLight(pVCpu, cbInstr);
    2465 #endif
    2466 
    2467     /*
    2468      * Clear RF and finish the instruction (maybe raise #DB).
    2469      */
    2470     return iemRegFinishClearingRF(pVCpu, rcNormal);
    2471 }
    2472 
    2473 
    2474 /**
    2475  * Adds a 8-bit signed jump offset to IP, on a pre-386 CPU.
    2476  *
    2477  * May raise a \#GP(0) if the new RIP is non-canonical or outside the code
    2478  * segment limit.
    2479  *
    2480  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    2481  * @param   cbInstr             Instruction size.
    2482  * @param   offNextInstr        The offset of the next instruction.
    2483  * @param   rcNormal            VINF_SUCCESS to continue TB.
    2484  *                              VINF_IEM_REEXEC_BREAK to force TB exit when
    2485  *                              taking the wrong conditional branhc.
    2486  */
    2487 DECL_FORCE_INLINE(VBOXSTRICTRC) iemRegIp16RelativeJumpS8AndFinishClearingRF(PVMCPUCC pVCpu, uint8_t cbInstr,
    2488                                                                             int8_t offNextInstr, int rcNormal) RT_NOEXCEPT
    2489 {
    2490     Assert(!IEM_IS_64BIT_CODE(pVCpu));
    2491 
    2492     uint16_t const uNewIp = pVCpu->cpum.GstCtx.ip + cbInstr + (int16_t)offNextInstr;
    2493     if (RT_LIKELY(uNewIp <= pVCpu->cpum.GstCtx.cs.u32Limit))
    2494         pVCpu->cpum.GstCtx.rip = uNewIp;
    2495     else
    2496         return iemRaiseGeneralProtectionFault0(pVCpu);
    2497 
    2498 #ifndef IEM_WITH_CODE_TLB
    2499     iemOpcodeFlushLight(pVCpu, cbInstr);
    2500 #endif
    2501 
    2502     /*
    2503      * Clear RF and finish the instruction (maybe raise #DB).
    2504      */
    2505     return iemRegFinishClearingRF(pVCpu, rcNormal);
    2506 }
    2507 
    2508 
    2509 /**
    2510  * Adds a 8-bit signed jump offset to RIP from 64-bit code, no checking or
    2511  * clearing of flags.
    2512  *
    2513  * May raise a \#GP(0) if the new RIP is non-canonical or outside the code
    2514  * segment limit.
    2515  *
    2516  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    2517  * @param   cbInstr             Instruction size.
    2518  * @param   offNextInstr        The offset of the next instruction.
    2519  * @param   enmEffOpSize        Effective operand size.
    2520  * @param   rcNormal            VINF_SUCCESS to continue TB.
    2521  *                              VINF_IEM_REEXEC_BREAK to force TB exit when
    2522  *                              taking the wrong conditional branhc.
    2523  */
    2524 DECL_FORCE_INLINE(VBOXSTRICTRC) iemRegRip64RelativeJumpS8AndFinishNoFlags(PVMCPUCC pVCpu, uint8_t cbInstr, int8_t offNextInstr,
    2525                                                                           IEMMODE enmEffOpSize, int rcNormal) RT_NOEXCEPT
    2526 {
    2527     Assert(IEM_IS_64BIT_CODE(pVCpu));
    2528     Assert(enmEffOpSize == IEMMODE_64BIT || enmEffOpSize == IEMMODE_16BIT);
    2529 
    2530     uint64_t uNewRip = pVCpu->cpum.GstCtx.rip + cbInstr + (int64_t)offNextInstr;
    2531     if (enmEffOpSize == IEMMODE_16BIT)
    2532         uNewRip &= UINT16_MAX;
    2533 
    2534     if (RT_LIKELY(IEM_IS_CANONICAL(uNewRip)))
    2535         pVCpu->cpum.GstCtx.rip = uNewRip;
    2536     else
    2537         return iemRaiseGeneralProtectionFault0(pVCpu);
    2538 
    2539 #ifndef IEM_WITH_CODE_TLB
    2540     iemOpcodeFlushLight(pVCpu, cbInstr);
    2541 #endif
    2542     return iemRegFinishNoFlags(pVCpu, rcNormal);
    2543 }
    2544 
    2545 
    2546 /**
    2547  * Adds a 8-bit signed jump offset to RIP from 64-bit code when caller is sure
    2548  * it stays within the same page, no checking or clearing of flags.
    2549  *
    2550  * May raise a \#GP(0) if the new RIP is non-canonical or outside the code
    2551  * segment limit.
    2552  *
    2553  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    2554  * @param   cbInstr             Instruction size.
    2555  * @param   offNextInstr        The offset of the next instruction.
    2556  * @param   enmEffOpSize        Effective operand size.
    2557  * @param   rcNormal            VINF_SUCCESS to continue TB.
    2558  *                              VINF_IEM_REEXEC_BREAK to force TB exit when
    2559  *                              taking the wrong conditional branhc.
    2560  */
    2561 DECL_FORCE_INLINE(VBOXSTRICTRC)
    2562 iemRegRip64RelativeJumpS8IntraPgAndFinishNoFlags(PVMCPUCC pVCpu, uint8_t cbInstr, int8_t offNextInstr,
    2563                                                  IEMMODE enmEffOpSize, int rcNormal) RT_NOEXCEPT
    2564 {
    2565     Assert(IEM_IS_64BIT_CODE(pVCpu));
    2566     Assert(enmEffOpSize == IEMMODE_64BIT); RT_NOREF(enmEffOpSize);
    2567 
    2568     uint64_t const uNewRip = pVCpu->cpum.GstCtx.rip + cbInstr + (int64_t)offNextInstr;
    2569     Assert((pVCpu->cpum.GstCtx.rip >> GUEST_PAGE_SHIFT) == (uNewRip >> GUEST_PAGE_SHIFT));
    2570     pVCpu->cpum.GstCtx.rip = uNewRip;
    2571 
    2572 #ifndef IEM_WITH_CODE_TLB
    2573     iemOpcodeFlushLight(pVCpu, cbInstr);
    2574 #endif
    2575     return iemRegFinishNoFlags(pVCpu, rcNormal);
    2576 }
    2577 
    2578 
    2579 /**
    2580  * Adds a 8-bit signed jump offset to EIP, on 386 or later from 16-bit or 32-bit
    2581  * code (never 64-bit), no checking or clearing of flags.
    2582  *
    2583  * May raise a \#GP(0) if the new RIP is non-canonical or outside the code
    2584  * segment limit.
    2585  *
    2586  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    2587  * @param   cbInstr             Instruction size.
    2588  * @param   offNextInstr        The offset of the next instruction.
    2589  * @param   enmEffOpSize        Effective operand size.
    2590  * @param   rcNormal            VINF_SUCCESS to continue TB.
    2591  *                              VINF_IEM_REEXEC_BREAK to force TB exit when
    2592  *                              taking the wrong conditional branhc.
    2593  */
    2594 DECL_FORCE_INLINE(VBOXSTRICTRC) iemRegEip32RelativeJumpS8AndFinishNoFlags(PVMCPUCC pVCpu, uint8_t cbInstr, int8_t offNextInstr,
    2595                                                                           IEMMODE enmEffOpSize, int rcNormal) RT_NOEXCEPT
    2596 {
    2597     Assert(!IEM_IS_64BIT_CODE(pVCpu));
    2598     Assert(enmEffOpSize == IEMMODE_32BIT || enmEffOpSize == IEMMODE_16BIT);
    2599 
    2600     uint32_t uNewEip = pVCpu->cpum.GstCtx.eip + cbInstr + (int32_t)offNextInstr;
    2601     if (enmEffOpSize == IEMMODE_16BIT)
    2602         uNewEip &= UINT16_MAX;
    2603     if (RT_LIKELY(uNewEip <= pVCpu->cpum.GstCtx.cs.u32Limit))
    2604         pVCpu->cpum.GstCtx.rip = uNewEip;
    2605     else
    2606         return iemRaiseGeneralProtectionFault0(pVCpu);
    2607 
    2608 #ifndef IEM_WITH_CODE_TLB
    2609     iemOpcodeFlushLight(pVCpu, cbInstr);
    2610 #endif
    2611     return iemRegFinishNoFlags(pVCpu, rcNormal);
    2612 }
    2613 
    2614 
    2615 /**
    2616  * Adds a 8-bit signed jump offset to EIP, on 386 or later from flat 32-bit code
    2617  * (never 64-bit), no checking or clearing of flags.
    2618  *
    2619  * May raise a \#GP(0) if the new RIP is non-canonical or outside the code
    2620  * segment limit.
    2621  *
    2622  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    2623  * @param   cbInstr             Instruction size.
    2624  * @param   offNextInstr        The offset of the next instruction.
    2625  * @param   enmEffOpSize        Effective operand size.
    2626  * @param   rcNormal            VINF_SUCCESS to continue TB.
    2627  *                              VINF_IEM_REEXEC_BREAK to force TB exit when
    2628  *                              taking the wrong conditional branhc.
    2629  */
    2630 DECL_FORCE_INLINE(VBOXSTRICTRC)
    2631 iemRegEip32RelativeJumpS8FlatAndFinishNoFlags(PVMCPUCC pVCpu, uint8_t cbInstr, int8_t offNextInstr,
    2632                                               IEMMODE enmEffOpSize, int rcNormal) RT_NOEXCEPT
    2633 {
    2634     Assert(!IEM_IS_64BIT_CODE(pVCpu));
    2635     Assert(enmEffOpSize == IEMMODE_32BIT || enmEffOpSize == IEMMODE_16BIT);
    2636 
    2637     uint32_t uNewEip = pVCpu->cpum.GstCtx.eip + cbInstr + (int32_t)offNextInstr;
    2638     if (enmEffOpSize == IEMMODE_16BIT)
    2639         uNewEip &= UINT16_MAX;
    2640     pVCpu->cpum.GstCtx.rip = uNewEip;
    2641 
    2642 #ifndef IEM_WITH_CODE_TLB
    2643     iemOpcodeFlushLight(pVCpu, cbInstr);
    2644 #endif
    2645     return iemRegFinishNoFlags(pVCpu, rcNormal);
    2646 }
    2647 
    2648 
    2649 /**
    2650  * Adds a 8-bit signed jump offset to IP, on a pre-386 CPU, no checking or
    2651  * clearing of flags.
    2652  *
    2653  * May raise a \#GP(0) if the new RIP is non-canonical or outside the code
    2654  * segment limit.
    2655  *
    2656  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    2657  * @param   cbInstr             Instruction size.
    2658  * @param   offNextInstr        The offset of the next instruction.
    2659  * @param   rcNormal            VINF_SUCCESS to continue TB.
    2660  *                              VINF_IEM_REEXEC_BREAK to force TB exit when
    2661  *                              taking the wrong conditional branhc.
    2662  */
    2663 DECL_FORCE_INLINE(VBOXSTRICTRC) iemRegIp16RelativeJumpS8AndFinishNoFlags(PVMCPUCC pVCpu, uint8_t cbInstr,
    2664                                                                          int8_t offNextInstr, int rcNormal) RT_NOEXCEPT
    2665 {
    2666     Assert(!IEM_IS_64BIT_CODE(pVCpu));
    2667 
    2668     uint16_t const uNewIp = pVCpu->cpum.GstCtx.ip + cbInstr + (int16_t)offNextInstr;
    2669     if (RT_LIKELY(uNewIp <= pVCpu->cpum.GstCtx.cs.u32Limit))
    2670         pVCpu->cpum.GstCtx.rip = uNewIp;
    2671     else
    2672         return iemRaiseGeneralProtectionFault0(pVCpu);
    2673 
    2674 #ifndef IEM_WITH_CODE_TLB
    2675     iemOpcodeFlushLight(pVCpu, cbInstr);
    2676 #endif
    2677     return iemRegFinishNoFlags(pVCpu, rcNormal);
    2678 }
    2679 
    2680 
    2681 /**
    2682  * Adds a 16-bit signed jump offset to RIP from 64-bit code.
    2683  *
    2684  * @returns Strict VBox status code.
    2685  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    2686  * @param   cbInstr             Instruction size.
    2687  * @param   offNextInstr        The offset of the next instruction.
    2688  * @param   rcNormal            VINF_SUCCESS to continue TB.
    2689  *                              VINF_IEM_REEXEC_BREAK to force TB exit when
    2690  *                              taking the wrong conditional branhc.
    2691  */
    2692 DECL_FORCE_INLINE(VBOXSTRICTRC) iemRegRip64RelativeJumpS16AndFinishClearingRF(PVMCPUCC pVCpu, uint8_t cbInstr,
    2693                                                                               int16_t offNextInstr, int rcNormal) RT_NOEXCEPT
    2694 {
    2695     Assert(IEM_IS_64BIT_CODE(pVCpu));
    2696 
    2697     pVCpu->cpum.GstCtx.rip = (uint16_t)(pVCpu->cpum.GstCtx.ip + cbInstr + offNextInstr);
    2698 
    2699 #ifndef IEM_WITH_CODE_TLB
    2700     iemOpcodeFlushLight(pVCpu, cbInstr);
    2701 #endif
    2702 
    2703     /*
    2704      * Clear RF and finish the instruction (maybe raise #DB).
    2705      */
    2706     return iemRegFinishClearingRF(pVCpu, rcNormal);
    2707 }
    2708 
    2709 
    2710 /**
    2711  * Adds a 16-bit signed jump offset to EIP from 16-bit or 32-bit code.
    2712  *
    2713  * May raise a \#GP(0) if the new RIP is non-canonical or outside the code
    2714  * segment limit.
    2715  *
    2716  * @returns Strict VBox status code.
    2717  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    2718  * @param   cbInstr             Instruction size.
    2719  * @param   offNextInstr        The offset of the next instruction.
    2720  * @param   rcNormal            VINF_SUCCESS to continue TB.
    2721  *                              VINF_IEM_REEXEC_BREAK to force TB exit when
    2722  *                              taking the wrong conditional branhc.
    2723  *
    2724  * @note    This is also used by 16-bit code in pre-386 mode, as the code is
    2725  *          identical.
    2726  */
    2727 DECL_FORCE_INLINE(VBOXSTRICTRC) iemRegEip32RelativeJumpS16AndFinishClearingRF(PVMCPUCC pVCpu, uint8_t cbInstr,
    2728                                                                               int16_t offNextInstr, int rcNormal) RT_NOEXCEPT
    2729 {
    2730     Assert(!IEM_IS_64BIT_CODE(pVCpu));
    2731 
    2732     uint16_t const uNewIp = pVCpu->cpum.GstCtx.ip + cbInstr + offNextInstr;
    2733     if (RT_LIKELY(uNewIp <= pVCpu->cpum.GstCtx.cs.u32Limit))
    2734         pVCpu->cpum.GstCtx.rip = uNewIp;
    2735     else
    2736         return iemRaiseGeneralProtectionFault0(pVCpu);
    2737 
    2738 #ifndef IEM_WITH_CODE_TLB
    2739     iemOpcodeFlushLight(pVCpu, cbInstr);
    2740 #endif
    2741 
    2742     /*
    2743      * Clear RF and finish the instruction (maybe raise #DB).
    2744      */
    2745     return iemRegFinishClearingRF(pVCpu, rcNormal);
    2746 }
    2747 
    2748 
    2749 /**
    2750  * Adds a 16-bit signed jump offset to EIP from FLAT 32-bit code.
    2751  *
    2752  * May raise a \#GP(0) if the new RIP is non-canonical or outside the code
    2753  * segment limit.
    2754  *
    2755  * @returns Strict VBox status code.
    2756  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    2757  * @param   cbInstr             Instruction size.
    2758  * @param   offNextInstr        The offset of the next instruction.
    2759  * @param   rcNormal            VINF_SUCCESS to continue TB.
    2760  *                              VINF_IEM_REEXEC_BREAK to force TB exit when
    2761  *                              taking the wrong conditional branhc.
    2762  *
    2763  * @note    This is also used by 16-bit code in pre-386 mode, as the code is
    2764  *          identical.
    2765  */
    2766 DECL_FORCE_INLINE(VBOXSTRICTRC) iemRegEip32RelativeJumpS16FlatAndFinishClearingRF(PVMCPUCC pVCpu, uint8_t cbInstr,
    2767                                                                                   int16_t offNextInstr, int rcNormal) RT_NOEXCEPT
    2768 {
    2769     Assert(!IEM_IS_64BIT_CODE(pVCpu));
    2770 
    2771     uint16_t const uNewIp = pVCpu->cpum.GstCtx.ip + cbInstr + offNextInstr;
    2772     pVCpu->cpum.GstCtx.rip = uNewIp;
    2773 
    2774 #ifndef IEM_WITH_CODE_TLB
    2775     iemOpcodeFlushLight(pVCpu, cbInstr);
    2776 #endif
    2777 
    2778     /*
    2779      * Clear RF and finish the instruction (maybe raise #DB).
    2780      */
    2781     return iemRegFinishClearingRF(pVCpu, rcNormal);
    2782 }
    2783 
    2784 
    2785 /**
    2786  * Adds a 16-bit signed jump offset to RIP from 64-bit code, no checking or
    2787  * clearing of flags.
    2788  *
    2789  * @returns Strict VBox status code.
    2790  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    2791  * @param   cbInstr             Instruction size.
    2792  * @param   offNextInstr        The offset of the next instruction.
    2793  * @param   rcNormal            VINF_SUCCESS to continue TB.
    2794  *                              VINF_IEM_REEXEC_BREAK to force TB exit when
    2795  *                              taking the wrong conditional branhc.
    2796  */
    2797 DECL_FORCE_INLINE(VBOXSTRICTRC) iemRegRip64RelativeJumpS16AndFinishNoFlags(PVMCPUCC pVCpu, uint8_t cbInstr,
    2798                                                                            int16_t offNextInstr, int rcNormal) RT_NOEXCEPT
    2799 {
    2800     Assert(IEM_IS_64BIT_CODE(pVCpu));
    2801 
    2802     pVCpu->cpum.GstCtx.rip = (uint16_t)(pVCpu->cpum.GstCtx.ip + cbInstr + offNextInstr);
    2803 
    2804 #ifndef IEM_WITH_CODE_TLB
    2805     iemOpcodeFlushLight(pVCpu, cbInstr);
    2806 #endif
    2807     return iemRegFinishNoFlags(pVCpu, rcNormal);
    2808 }
    2809 
    2810 
    2811 /**
    2812  * Adds a 16-bit signed jump offset to EIP from 16-bit or 32-bit code,
    2813  * no checking or clearing of flags.
    2814  *
    2815  * May raise a \#GP(0) if the new RIP is non-canonical or outside the code
    2816  * segment limit.
    2817  *
    2818  * @returns Strict VBox status code.
    2819  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    2820  * @param   cbInstr             Instruction size.
    2821  * @param   offNextInstr        The offset of the next instruction.
    2822  * @param   rcNormal            VINF_SUCCESS to continue TB.
    2823  *                              VINF_IEM_REEXEC_BREAK to force TB exit when
    2824  *                              taking the wrong conditional branhc.
    2825  *
    2826  * @note    This is also used by 16-bit code in pre-386 mode, as the code is
    2827  *          identical.
    2828  */
    2829 DECL_FORCE_INLINE(VBOXSTRICTRC) iemRegEip32RelativeJumpS16AndFinishNoFlags(PVMCPUCC pVCpu, uint8_t cbInstr,
    2830                                                                            int16_t offNextInstr, int rcNormal) RT_NOEXCEPT
    2831 {
    2832     Assert(!IEM_IS_64BIT_CODE(pVCpu));
    2833 
    2834     uint16_t const uNewIp = pVCpu->cpum.GstCtx.ip + cbInstr + offNextInstr;
    2835     if (RT_LIKELY(uNewIp <= pVCpu->cpum.GstCtx.cs.u32Limit))
    2836         pVCpu->cpum.GstCtx.rip = uNewIp;
    2837     else
    2838         return iemRaiseGeneralProtectionFault0(pVCpu);
    2839 
    2840 #ifndef IEM_WITH_CODE_TLB
    2841     iemOpcodeFlushLight(pVCpu, cbInstr);
    2842 #endif
    2843     return iemRegFinishNoFlags(pVCpu, rcNormal);
    2844 }
    2845 
    2846 
    2847 /**
    2848  * Adds a 16-bit signed jump offset to EIP from FLAT 32-bit code, no checking or
    2849  * clearing of flags.
    2850  *
    2851  * May raise a \#GP(0) if the new RIP is non-canonical or outside the code
    2852  * segment limit.
    2853  *
    2854  * @returns Strict VBox status code.
    2855  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    2856  * @param   cbInstr             Instruction size.
    2857  * @param   offNextInstr        The offset of the next instruction.
    2858  * @param   rcNormal            VINF_SUCCESS to continue TB.
    2859  *                              VINF_IEM_REEXEC_BREAK to force TB exit when
    2860  *                              taking the wrong conditional branhc.
    2861  *
    2862  * @note    This is also used by 16-bit code in pre-386 mode, as the code is
    2863  *          identical.
    2864  */
    2865 DECL_FORCE_INLINE(VBOXSTRICTRC) iemRegEip32RelativeJumpS16FlatAndFinishNoFlags(PVMCPUCC pVCpu, uint8_t cbInstr,
    2866                                                                                int16_t offNextInstr, int rcNormal) RT_NOEXCEPT
    2867 {
    2868     Assert(!IEM_IS_64BIT_CODE(pVCpu));
    2869 
    2870     uint16_t const uNewIp = pVCpu->cpum.GstCtx.ip + cbInstr + offNextInstr;
    2871     pVCpu->cpum.GstCtx.rip = uNewIp;
    2872 
    2873 #ifndef IEM_WITH_CODE_TLB
    2874     iemOpcodeFlushLight(pVCpu, cbInstr);
    2875 #endif
    2876     return iemRegFinishNoFlags(pVCpu, rcNormal);
    2877 }
    2878 
    2879 
    2880 /**
    2881  * Adds a 32-bit signed jump offset to RIP from 64-bit code.
    2882  *
    2883  * May raise a \#GP(0) if the new RIP is non-canonical or outside the code
    2884  * segment limit.
    2885  *
    2886  * We ASSUME that the effective operand size is 64-bit here, as 16-bit is the
    2887  * only alternative for relative jumps in 64-bit code and that is already
    2888  * handled in the decoder stage.
    2889  *
    2890  * @returns Strict VBox status code.
    2891  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    2892  * @param   cbInstr             Instruction size.
    2893  * @param   offNextInstr        The offset of the next instruction.
    2894  * @param   rcNormal            VINF_SUCCESS to continue TB.
    2895  *                              VINF_IEM_REEXEC_BREAK to force TB exit when
    2896  *                              taking the wrong conditional branhc.
    2897  */
    2898 DECL_FORCE_INLINE(VBOXSTRICTRC) iemRegRip64RelativeJumpS32AndFinishClearingRF(PVMCPUCC pVCpu, uint8_t cbInstr,
    2899                                                                               int32_t offNextInstr, int rcNormal) RT_NOEXCEPT
    2900 {
    2901     Assert(IEM_IS_64BIT_CODE(pVCpu));
    2902 
    2903     uint64_t const uNewRip = pVCpu->cpum.GstCtx.rip + cbInstr + (int64_t)offNextInstr;
    2904     if (RT_LIKELY(IEM_IS_CANONICAL(uNewRip)))
    2905         pVCpu->cpum.GstCtx.rip = uNewRip;
    2906     else
    2907         return iemRaiseGeneralProtectionFault0(pVCpu);
    2908 
    2909 #ifndef IEM_WITH_CODE_TLB
    2910     iemOpcodeFlushLight(pVCpu, cbInstr);
    2911 #endif
    2912 
    2913     /*
    2914      * Clear RF and finish the instruction (maybe raise #DB).
    2915      */
    2916     return iemRegFinishClearingRF(pVCpu, rcNormal);
    2917 }
    2918 
    2919 
    2920 /**
    2921  * Adds a 32-bit signed jump offset to RIP from 64-bit code when the caller is
    2922  * sure the target is in the same page.
    2923  *
    2924  * May raise a \#GP(0) if the new RIP is non-canonical or outside the code
    2925  * segment limit.
    2926  *
    2927  * We ASSUME that the effective operand size is 64-bit here, as 16-bit is the
    2928  * only alternative for relative jumps in 64-bit code and that is already
    2929  * handled in the decoder stage.
    2930  *
    2931  * @returns Strict VBox status code.
    2932  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    2933  * @param   cbInstr             Instruction size.
    2934  * @param   offNextInstr        The offset of the next instruction.
    2935  * @param   rcNormal            VINF_SUCCESS to continue TB.
    2936  *                              VINF_IEM_REEXEC_BREAK to force TB exit when
    2937  *                              taking the wrong conditional branhc.
    2938  */
    2939 DECL_FORCE_INLINE(VBOXSTRICTRC)
    2940 iemRegRip64RelativeJumpS32IntraPgAndFinishClearingRF(PVMCPUCC pVCpu, uint8_t cbInstr,
    2941                                                      int32_t offNextInstr, int rcNormal) RT_NOEXCEPT
    2942 {
    2943     Assert(IEM_IS_64BIT_CODE(pVCpu));
    2944 
    2945     uint64_t const uNewRip = pVCpu->cpum.GstCtx.rip + cbInstr + (int64_t)offNextInstr;
    2946     Assert((pVCpu->cpum.GstCtx.rip >> GUEST_PAGE_SHIFT) == (uNewRip >> GUEST_PAGE_SHIFT));
    2947     pVCpu->cpum.GstCtx.rip = uNewRip;
    2948 
    2949 #ifndef IEM_WITH_CODE_TLB
    2950     iemOpcodeFlushLight(pVCpu, cbInstr);
    2951 #endif
    2952 
    2953     /*
    2954      * Clear RF and finish the instruction (maybe raise #DB).
    2955      */
    2956     return iemRegFinishClearingRF(pVCpu, rcNormal);
    2957 }
    2958 
    2959 
    2960 /**
    2961  * Adds a 32-bit signed jump offset to RIP from 64-bit code.
    2962  *
    2963  * May raise a \#GP(0) if the new RIP is non-canonical or outside the code
    2964  * segment limit.
    2965  *
    2966  * We ASSUME that the effective operand size is 32-bit here, as 16-bit is the
    2967  * only alternative for relative jumps in 32-bit code and that is already
    2968  * handled in the decoder stage.
    2969  *
    2970  * @returns Strict VBox status code.
    2971  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    2972  * @param   cbInstr             Instruction size.
    2973  * @param   offNextInstr        The offset of the next instruction.
    2974  * @param   rcNormal            VINF_SUCCESS to continue TB.
    2975  *                              VINF_IEM_REEXEC_BREAK to force TB exit when
    2976  *                              taking the wrong conditional branhc.
    2977  */
    2978 DECL_FORCE_INLINE(VBOXSTRICTRC) iemRegEip32RelativeJumpS32AndFinishClearingRF(PVMCPUCC pVCpu, uint8_t cbInstr,
    2979                                                                               int32_t offNextInstr, int rcNormal) RT_NOEXCEPT
    2980 {
    2981     Assert(!IEM_IS_64BIT_CODE(pVCpu));
    2982     Assert(pVCpu->cpum.GstCtx.rip <= UINT32_MAX);
    2983 
    2984     uint32_t const uNewEip = pVCpu->cpum.GstCtx.eip + cbInstr + offNextInstr;
    2985     if (RT_LIKELY(uNewEip <= pVCpu->cpum.GstCtx.cs.u32Limit))
    2986         pVCpu->cpum.GstCtx.rip = uNewEip;
    2987     else
    2988         return iemRaiseGeneralProtectionFault0(pVCpu);
    2989 
    2990 #ifndef IEM_WITH_CODE_TLB
    2991     iemOpcodeFlushLight(pVCpu, cbInstr);
    2992 #endif
    2993 
    2994     /*
    2995      * Clear RF and finish the instruction (maybe raise #DB).
    2996      */
    2997     return iemRegFinishClearingRF(pVCpu, rcNormal);
    2998 }
    2999 
    3000 
    3001 /**
    3002  * Adds a 32-bit signed jump offset to RIP from FLAT 32-bit code.
    3003  *
    3004  * May raise a \#GP(0) if the new RIP is non-canonical or outside the code
    3005  * segment limit.
    3006  *
    3007  * We ASSUME that the effective operand size is 32-bit here, as 16-bit is the
    3008  * only alternative for relative jumps in 32-bit code and that is already
    3009  * handled in the decoder stage.
    3010  *
    3011  * @returns Strict VBox status code.
    3012  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    3013  * @param   cbInstr             Instruction size.
    3014  * @param   offNextInstr        The offset of the next instruction.
    3015  * @param   rcNormal            VINF_SUCCESS to continue TB.
    3016  *                              VINF_IEM_REEXEC_BREAK to force TB exit when
    3017  *                              taking the wrong conditional branhc.
    3018  */
    3019 DECL_FORCE_INLINE(VBOXSTRICTRC) iemRegEip32RelativeJumpS32FlatAndFinishClearingRF(PVMCPUCC pVCpu, uint8_t cbInstr,
    3020                                                                                   int32_t offNextInstr, int rcNormal) RT_NOEXCEPT
    3021 {
    3022     Assert(!IEM_IS_64BIT_CODE(pVCpu));
    3023     Assert(pVCpu->cpum.GstCtx.rip <= UINT32_MAX);
    3024 
    3025     uint32_t const uNewEip = pVCpu->cpum.GstCtx.eip + cbInstr + offNextInstr;
    3026     pVCpu->cpum.GstCtx.rip = uNewEip;
    3027 
    3028 #ifndef IEM_WITH_CODE_TLB
    3029     iemOpcodeFlushLight(pVCpu, cbInstr);
    3030 #endif
    3031 
    3032     /*
    3033      * Clear RF and finish the instruction (maybe raise #DB).
    3034      */
    3035     return iemRegFinishClearingRF(pVCpu, rcNormal);
    3036 }
    3037 
    3038 
    3039 
    3040 /**
    3041  * Adds a 32-bit signed jump offset to RIP from 64-bit code, no checking or
    3042  * clearing of flags.
    3043  *
    3044  * May raise a \#GP(0) if the new RIP is non-canonical or outside the code
    3045  * segment limit.
    3046  *
    3047  * We ASSUME that the effective operand size is 64-bit here, as 16-bit is the
    3048  * only alternative for relative jumps in 64-bit code and that is already
    3049  * handled in the decoder stage.
    3050  *
    3051  * @returns Strict VBox status code.
    3052  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    3053  * @param   cbInstr             Instruction size.
    3054  * @param   offNextInstr        The offset of the next instruction.
    3055  * @param   rcNormal            VINF_SUCCESS to continue TB.
    3056  *                              VINF_IEM_REEXEC_BREAK to force TB exit when
    3057  *                              taking the wrong conditional branhc.
    3058  */
    3059 DECL_FORCE_INLINE(VBOXSTRICTRC) iemRegRip64RelativeJumpS32AndFinishNoFlags(PVMCPUCC pVCpu, uint8_t cbInstr,
    3060                                                                            int32_t offNextInstr, int rcNormal) RT_NOEXCEPT
    3061 {
    3062     Assert(IEM_IS_64BIT_CODE(pVCpu));
    3063 
    3064     uint64_t const uNewRip = pVCpu->cpum.GstCtx.rip + cbInstr + (int64_t)offNextInstr;
    3065     if (RT_LIKELY(IEM_IS_CANONICAL(uNewRip)))
    3066         pVCpu->cpum.GstCtx.rip = uNewRip;
    3067     else
    3068         return iemRaiseGeneralProtectionFault0(pVCpu);
    3069 
    3070 #ifndef IEM_WITH_CODE_TLB
    3071     iemOpcodeFlushLight(pVCpu, cbInstr);
    3072 #endif
    3073     return iemRegFinishNoFlags(pVCpu, rcNormal);
    3074 }
    3075 
    3076 
    3077 /**
    3078  * Adds a 32-bit signed jump offset to RIP from 64-bit code when the caller is
    3079  * sure it stays within the same page, no checking or clearing of flags.
    3080  *
    3081  * May raise a \#GP(0) if the new RIP is non-canonical or outside the code
    3082  * segment limit.
    3083  *
    3084  * We ASSUME that the effective operand size is 64-bit here, as 16-bit is the
    3085  * only alternative for relative jumps in 64-bit code and that is already
    3086  * handled in the decoder stage.
    3087  *
    3088  * @returns Strict VBox status code.
    3089  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    3090  * @param   cbInstr             Instruction size.
    3091  * @param   offNextInstr        The offset of the next instruction.
    3092  * @param   rcNormal            VINF_SUCCESS to continue TB.
    3093  *                              VINF_IEM_REEXEC_BREAK to force TB exit when
    3094  *                              taking the wrong conditional branhc.
    3095  */
    3096 DECL_FORCE_INLINE(VBOXSTRICTRC)
    3097 iemRegRip64RelativeJumpS32IntraPgAndFinishNoFlags(PVMCPUCC pVCpu, uint8_t cbInstr, int32_t offNextInstr, int rcNormal) RT_NOEXCEPT
    3098 {
    3099     Assert(IEM_IS_64BIT_CODE(pVCpu));
    3100 
    3101     uint64_t const uNewRip = pVCpu->cpum.GstCtx.rip + cbInstr + (int64_t)offNextInstr;
    3102     Assert((pVCpu->cpum.GstCtx.rip >> GUEST_PAGE_SHIFT) == (uNewRip >> GUEST_PAGE_SHIFT));
    3103     pVCpu->cpum.GstCtx.rip = uNewRip;
    3104 
    3105 #ifndef IEM_WITH_CODE_TLB
    3106     iemOpcodeFlushLight(pVCpu, cbInstr);
    3107 #endif
    3108     return iemRegFinishNoFlags(pVCpu, rcNormal);
    3109 }
    3110 
    3111 
    3112 /**
    3113  * Adds a 32-bit signed jump offset to RIP from 32-bit code, no checking or
    3114  * clearing of flags.
    3115  *
    3116  * May raise a \#GP(0) if the new RIP is non-canonical or outside the code
    3117  * segment limit.
    3118  *
    3119  * We ASSUME that the effective operand size is 32-bit here, as 16-bit is the
    3120  * only alternative for relative jumps in 32-bit code and that is already
    3121  * handled in the decoder stage.
    3122  *
    3123  * @returns Strict VBox status code.
    3124  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    3125  * @param   cbInstr             Instruction size.
    3126  * @param   offNextInstr        The offset of the next instruction.
    3127  * @param   rcNormal            VINF_SUCCESS to continue TB.
    3128  *                              VINF_IEM_REEXEC_BREAK to force TB exit when
    3129  *                              taking the wrong conditional branhc.
    3130  */
    3131 DECL_FORCE_INLINE(VBOXSTRICTRC) iemRegEip32RelativeJumpS32AndFinishNoFlags(PVMCPUCC pVCpu, uint8_t cbInstr,
    3132                                                                            int32_t offNextInstr, int rcNormal) RT_NOEXCEPT
    3133 {
    3134     Assert(!IEM_IS_64BIT_CODE(pVCpu));
    3135     Assert(pVCpu->cpum.GstCtx.rip <= UINT32_MAX);
    3136 
    3137     uint32_t const uNewEip = pVCpu->cpum.GstCtx.eip + cbInstr + offNextInstr;
    3138     if (RT_LIKELY(uNewEip <= pVCpu->cpum.GstCtx.cs.u32Limit))
    3139         pVCpu->cpum.GstCtx.rip = uNewEip;
    3140     else
    3141         return iemRaiseGeneralProtectionFault0(pVCpu);
    3142 
    3143 #ifndef IEM_WITH_CODE_TLB
    3144     iemOpcodeFlushLight(pVCpu, cbInstr);
    3145 #endif
    3146     return iemRegFinishNoFlags(pVCpu, rcNormal);
    3147 }
    3148 
    3149 
    3150 /**
    3151  * Adds a 32-bit signed jump offset to RIP from FLAT 32-bit code, no checking or
    3152  * clearing of flags.
    3153  *
    3154  * May raise a \#GP(0) if the new RIP is non-canonical or outside the code
    3155  * segment limit.
    3156  *
    3157  * We ASSUME that the effective operand size is 32-bit here, as 16-bit is the
    3158  * only alternative for relative jumps in 32-bit code and that is already
    3159  * handled in the decoder stage.
    3160  *
    3161  * @returns Strict VBox status code.
    3162  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    3163  * @param   cbInstr             Instruction size.
    3164  * @param   offNextInstr        The offset of the next instruction.
    3165  * @param   rcNormal            VINF_SUCCESS to continue TB.
    3166  *                              VINF_IEM_REEXEC_BREAK to force TB exit when
    3167  *                              taking the wrong conditional branhc.
    3168  */
    3169 DECL_FORCE_INLINE(VBOXSTRICTRC) iemRegEip32RelativeJumpS32FlatAndFinishNoFlags(PVMCPUCC pVCpu, uint8_t cbInstr,
    3170                                                                                int32_t offNextInstr, int rcNormal) RT_NOEXCEPT
    3171 {
    3172     Assert(!IEM_IS_64BIT_CODE(pVCpu));
    3173     Assert(pVCpu->cpum.GstCtx.rip <= UINT32_MAX);
    3174 
    3175     uint32_t const uNewEip = pVCpu->cpum.GstCtx.eip + cbInstr + offNextInstr;
    3176     pVCpu->cpum.GstCtx.rip = uNewEip;
    3177 
    3178 #ifndef IEM_WITH_CODE_TLB
    3179     iemOpcodeFlushLight(pVCpu, cbInstr);
    3180 #endif
    3181     return iemRegFinishNoFlags(pVCpu, rcNormal);
    3182 }
    3183 
    3184 
    3185 /**
    3186  * Extended version of iemFinishInstructionWithFlagsSet that goes with
    3187  * iemRegAddToRipAndFinishingClearingRfEx.
    3188  *
    3189  * See iemFinishInstructionWithFlagsSet() for details.
    3190  */
    3191 static VBOXSTRICTRC iemFinishInstructionWithTfSet(PVMCPUCC pVCpu) RT_NOEXCEPT
    3192 {
    3193     /*
    3194      * Raise a #DB.
    3195      */
    3196     IEM_CTX_IMPORT_RET(pVCpu, CPUMCTX_EXTRN_DR6);
    3197     pVCpu->cpum.GstCtx.dr[6] &= ~X86_DR6_B_MASK;
    3198     pVCpu->cpum.GstCtx.dr[6] |= X86_DR6_BS
    3199                              | (   (pVCpu->cpum.GstCtx.eflags.uBoth & CPUMCTX_DBG_HIT_DRX_MASK_NONSILENT)
    3200                                 >> CPUMCTX_DBG_HIT_DRX_SHIFT);
    3201     /** @todo Do we set all pending \#DB events, or just one? */
    3202     LogFlowFunc(("Guest #DB fired at %04X:%016llX: DR6=%08X, RFLAGS=%16RX64 (popf)\n",
    3203                  pVCpu->cpum.GstCtx.cs.Sel, pVCpu->cpum.GstCtx.rip, (unsigned)pVCpu->cpum.GstCtx.dr[6],
    3204                  pVCpu->cpum.GstCtx.rflags.uBoth));
    3205     pVCpu->cpum.GstCtx.eflags.uBoth &= ~(X86_EFL_RF | CPUMCTX_INHIBIT_SHADOW | CPUMCTX_DBG_HIT_DRX_MASK | CPUMCTX_DBG_DBGF_MASK);
    3206     return iemRaiseDebugException(pVCpu);
    3207 }
    3208 
    3209 
    3210 /**
    3211  * Extended version of iemRegAddToRipAndFinishingClearingRF for use by POPF and
    3212  * others potentially updating EFLAGS.TF.
    3213  *
    3214  * The single step event must be generated using the TF value at the start of
    3215  * the instruction, not the new value set by it.
    3216  *
    3217  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    3218  * @param   cbInstr             The number of bytes to add.
    3219  * @param   fEflOld             The EFLAGS at the start of the instruction
    3220  *                              execution.
    3221  */
    3222 DECLINLINE(VBOXSTRICTRC) iemRegAddToRipAndFinishingClearingRfEx(PVMCPUCC pVCpu, uint8_t cbInstr, uint32_t fEflOld) RT_NOEXCEPT
    3223 {
    3224     iemRegAddToRip(pVCpu, cbInstr);
    3225     if (!(fEflOld & X86_EFL_TF))
    3226     {
    3227         /* Specialized iemRegFinishClearingRF edition here that doesn't check X86_EFL_TF. */
    3228         AssertCompile(CPUMCTX_INHIBIT_SHADOW < UINT32_MAX);
    3229         if (RT_LIKELY(!(  pVCpu->cpum.GstCtx.eflags.uBoth
    3230                         & (X86_EFL_RF | CPUMCTX_INHIBIT_SHADOW | CPUMCTX_DBG_HIT_DRX_MASK | CPUMCTX_DBG_DBGF_MASK)) ))
    3231             return VINF_SUCCESS;
    3232         return iemFinishInstructionWithFlagsSet<0 /*a_fTF*/>(pVCpu, VINF_SUCCESS); /* TF=0, so ignore it.  */
    3233     }
    3234     return iemFinishInstructionWithTfSet(pVCpu);
    3235 }
    3236 
    3237 
    3238 #ifndef IEM_WITH_OPAQUE_DECODER_STATE
    3239 /**
    3240  * Updates the RIP/EIP/IP to point to the next instruction and clears EFLAGS.RF.
    3241  *
    3242  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    3243  */
    3244 DECLINLINE(VBOXSTRICTRC) iemRegUpdateRipAndFinishClearingRF(PVMCPUCC pVCpu) RT_NOEXCEPT
    3245 {
    3246     return iemRegAddToRipAndFinishingClearingRF(pVCpu, IEM_GET_INSTR_LEN(pVCpu));
    3247 }
    3248 #endif
    3249 
    3250 
    3251 #ifdef IEM_WITH_CODE_TLB
    3252 
    3253 /**
    3254  * Performs a near jump to the specified address, no checking or clearing of
    3255  * flags
    3256  *
    3257  * May raise a \#GP(0) if the new IP outside the code segment limit.
    3258  *
    3259  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    3260  * @param   uNewIp              The new IP value.
    3261  */
    3262 DECLINLINE(VBOXSTRICTRC) iemRegRipJumpU16AndFinishNoFlags(PVMCPUCC pVCpu, uint16_t uNewIp) RT_NOEXCEPT
    3263 {
    3264     if (RT_LIKELY(   uNewIp <= pVCpu->cpum.GstCtx.cs.u32Limit
    3265                   || IEM_IS_64BIT_CODE(pVCpu) /* no limit checks in 64-bit mode */))
    3266         pVCpu->cpum.GstCtx.rip = uNewIp;
    3267     else
    3268         return iemRaiseGeneralProtectionFault0(pVCpu);
    3269     return iemRegFinishNoFlags(pVCpu, VINF_SUCCESS);
    3270 }
    3271 
    3272 
    3273 /**
    3274  * Performs a near jump to the specified address, no checking or clearing of
    3275  * flags
    3276  *
    3277  * May raise a \#GP(0) if the new RIP is outside the code segment limit.
    3278  *
    3279  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    3280  * @param   uNewEip             The new EIP value.
    3281  */
    3282 DECLINLINE(VBOXSTRICTRC) iemRegRipJumpU32AndFinishNoFlags(PVMCPUCC pVCpu, uint32_t uNewEip) RT_NOEXCEPT
    3283 {
    3284     Assert(pVCpu->cpum.GstCtx.rip <= UINT32_MAX);
    3285     Assert(!IEM_IS_64BIT_CODE(pVCpu));
    3286     if (RT_LIKELY(uNewEip <= pVCpu->cpum.GstCtx.cs.u32Limit))
    3287         pVCpu->cpum.GstCtx.rip = uNewEip;
    3288     else
    3289         return iemRaiseGeneralProtectionFault0(pVCpu);
    3290     return iemRegFinishNoFlags(pVCpu, VINF_SUCCESS);
    3291 }
    3292 
    3293 
    3294 /**
    3295  * Performs a near jump to the specified address, no checking or clearing of
    3296  * flags.
    3297  *
    3298  * May raise a \#GP(0) if the new RIP is non-canonical or outside the code
    3299  * segment limit.
    3300  *
    3301  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    3302  * @param   uNewRip             The new RIP value.
    3303  */
    3304 DECLINLINE(VBOXSTRICTRC) iemRegRipJumpU64AndFinishNoFlags(PVMCPUCC pVCpu, uint64_t uNewRip) RT_NOEXCEPT
    3305 {
    3306     Assert(IEM_IS_64BIT_CODE(pVCpu));
    3307     if (RT_LIKELY(IEM_IS_CANONICAL(uNewRip)))
    3308         pVCpu->cpum.GstCtx.rip = uNewRip;
    3309     else
    3310         return iemRaiseGeneralProtectionFault0(pVCpu);
    3311     return iemRegFinishNoFlags(pVCpu, VINF_SUCCESS);
    3312 }
    3313 
    3314 #endif /* IEM_WITH_CODE_TLB */
    3315 
    3316 /**
    3317  * Performs a near jump to the specified address.
    3318  *
    3319  * May raise a \#GP(0) if the new IP outside the code segment limit.
    3320  *
    3321  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    3322  * @param   uNewIp              The new IP value.
    3323  * @param   cbInstr             The instruction length, for flushing in the non-TLB case.
    3324  */
    3325 DECLINLINE(VBOXSTRICTRC) iemRegRipJumpU16AndFinishClearingRF(PVMCPUCC pVCpu, uint16_t uNewIp, uint8_t cbInstr) RT_NOEXCEPT
    3326 {
    3327     if (RT_LIKELY(   uNewIp <= pVCpu->cpum.GstCtx.cs.u32Limit
    3328                   || IEM_IS_64BIT_CODE(pVCpu) /* no limit checks in 64-bit mode */))
    3329         pVCpu->cpum.GstCtx.rip = uNewIp;
    3330     else
    3331         return iemRaiseGeneralProtectionFault0(pVCpu);
    3332 #ifndef IEM_WITH_CODE_TLB
    3333     iemOpcodeFlushLight(pVCpu, cbInstr);
    3334 #else
    3335     RT_NOREF_PV(cbInstr);
    3336 #endif
    3337     return iemRegFinishClearingRF(pVCpu, VINF_SUCCESS);
    3338 }
    3339 
    3340 
    3341 /**
    3342  * Performs a near jump to the specified address.
    3343  *
    3344  * May raise a \#GP(0) if the new RIP is outside the code segment limit.
    3345  *
    3346  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    3347  * @param   uNewEip             The new EIP value.
    3348  * @param   cbInstr             The instruction length, for flushing in the non-TLB case.
    3349  */
    3350 DECLINLINE(VBOXSTRICTRC) iemRegRipJumpU32AndFinishClearingRF(PVMCPUCC pVCpu, uint32_t uNewEip, uint8_t cbInstr) RT_NOEXCEPT
    3351 {
    3352     Assert(pVCpu->cpum.GstCtx.rip <= UINT32_MAX);
    3353     Assert(!IEM_IS_64BIT_CODE(pVCpu));
    3354     if (RT_LIKELY(uNewEip <= pVCpu->cpum.GstCtx.cs.u32Limit))
    3355         pVCpu->cpum.GstCtx.rip = uNewEip;
    3356     else
    3357         return iemRaiseGeneralProtectionFault0(pVCpu);
    3358 #ifndef IEM_WITH_CODE_TLB
    3359     iemOpcodeFlushLight(pVCpu, cbInstr);
    3360 #else
    3361     RT_NOREF_PV(cbInstr);
    3362 #endif
    3363     return iemRegFinishClearingRF(pVCpu, VINF_SUCCESS);
    3364 }
    3365 
    3366 
    3367 /**
    3368  * Performs a near jump to the specified address.
    3369  *
    3370  * May raise a \#GP(0) if the new RIP is non-canonical or outside the code
    3371  * segment limit.
    3372  *
    3373  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    3374  * @param   uNewRip             The new RIP value.
    3375  * @param   cbInstr             The instruction length, for flushing in the non-TLB case.
    3376  */
    3377 DECLINLINE(VBOXSTRICTRC) iemRegRipJumpU64AndFinishClearingRF(PVMCPUCC pVCpu, uint64_t uNewRip, uint8_t cbInstr) RT_NOEXCEPT
    3378 {
    3379     Assert(IEM_IS_64BIT_CODE(pVCpu));
    3380     if (RT_LIKELY(IEM_IS_CANONICAL(uNewRip)))
    3381         pVCpu->cpum.GstCtx.rip = uNewRip;
    3382     else
    3383         return iemRaiseGeneralProtectionFault0(pVCpu);
    3384 #ifndef IEM_WITH_CODE_TLB
    3385     iemOpcodeFlushLight(pVCpu, cbInstr);
    3386 #else
    3387     RT_NOREF_PV(cbInstr);
    3388 #endif
    3389     return iemRegFinishClearingRF(pVCpu, VINF_SUCCESS);
    3390 }
    3391 
    3392 
    3393 /**
    3394  * Implements a 16-bit relative call, no checking or clearing of
    3395  * flags.
    3396  *
    3397  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    3398  * @param   cbInstr             The instruction length.
    3399  * @param   offDisp             The 16-bit displacement.
    3400  */
    3401 DECL_FORCE_INLINE(VBOXSTRICTRC)
    3402 iemRegRipRelativeCallS16AndFinishNoFlags(PVMCPUCC pVCpu, uint8_t cbInstr, int16_t offDisp) RT_NOEXCEPT
    3403 {
    3404     uint16_t const uOldIp = pVCpu->cpum.GstCtx.ip + cbInstr;
    3405     uint16_t const uNewIp = uOldIp + offDisp;
    3406     if (   uNewIp <= pVCpu->cpum.GstCtx.cs.u32Limit
    3407         || IEM_IS_64BIT_CODE(pVCpu) /* no CS limit checks in 64-bit mode */)
    3408     { /* likely */ }
    3409     else
    3410         return iemRaiseGeneralProtectionFault0(pVCpu);
    3411 
    3412     VBOXSTRICTRC rcStrict = iemMemStackPushU16(pVCpu, uOldIp);
    3413     if (rcStrict == VINF_SUCCESS)
    3414     { /* likely */ }
    3415     else
    3416         return rcStrict;
    3417 
    3418     pVCpu->cpum.GstCtx.rip = uNewIp;
    3419 #ifndef IEM_WITH_CODE_TLB
    3420     iemOpcodeFlushLight(pVCpu, cbInstr);
    3421 #endif
    3422     return iemRegFinishNoFlags(pVCpu, VINF_SUCCESS);
    3423 }
    3424 
    3425 
    3426 /**
    3427  * Implements a 16-bit relative call.
    3428  *
    3429  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    3430  * @param   cbInstr             The instruction length.
    3431  * @param   offDisp             The 16-bit displacement.
    3432  */
    3433 DECL_FORCE_INLINE(VBOXSTRICTRC)
    3434 iemRegRipRelativeCallS16AndFinishClearingRF(PVMCPUCC pVCpu, uint8_t cbInstr, int16_t offDisp) RT_NOEXCEPT
    3435 {
    3436     uint16_t const uOldIp = pVCpu->cpum.GstCtx.ip + cbInstr;
    3437     uint16_t const uNewIp = uOldIp + offDisp;
    3438     if (   uNewIp <= pVCpu->cpum.GstCtx.cs.u32Limit
    3439         || IEM_IS_64BIT_CODE(pVCpu) /* no CS limit checks in 64-bit mode */)
    3440     { /* likely */ }
    3441     else
    3442         return iemRaiseGeneralProtectionFault0(pVCpu);
    3443 
    3444     VBOXSTRICTRC rcStrict = iemMemStackPushU16(pVCpu, uOldIp);
    3445     if (rcStrict == VINF_SUCCESS)
    3446     { /* likely */ }
    3447     else
    3448         return rcStrict;
    3449 
    3450     pVCpu->cpum.GstCtx.rip = uNewIp;
    3451 #ifndef IEM_WITH_CODE_TLB
    3452     iemOpcodeFlushLight(pVCpu, cbInstr);
    3453 #endif
    3454     return iemRegFinishClearingRF(pVCpu, VINF_SUCCESS);
    3455 }
    3456 
    3457 
    3458 /**
    3459  * Implements a 32-bit relative call, no checking or clearing of flags.
    3460  *
    3461  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    3462  * @param   cbInstr             The instruction length.
    3463  * @param   offDisp             The 32-bit displacement.
    3464  */
    3465 DECL_FORCE_INLINE(VBOXSTRICTRC)
    3466 iemRegEip32RelativeCallS32AndFinishNoFlags(PVMCPUCC pVCpu, uint8_t cbInstr, int32_t offDisp) RT_NOEXCEPT
    3467 {
    3468     Assert(pVCpu->cpum.GstCtx.rip <= UINT32_MAX); Assert(!IEM_IS_64BIT_CODE(pVCpu));
    3469 
    3470     uint32_t const uOldRip = pVCpu->cpum.GstCtx.eip + cbInstr;
    3471     uint32_t const uNewRip = uOldRip + offDisp;
    3472     if (uNewRip <= pVCpu->cpum.GstCtx.cs.u32Limit)
    3473     { /* likely */ }
    3474     else
    3475         return iemRaiseGeneralProtectionFault0(pVCpu);
    3476 
    3477     VBOXSTRICTRC rcStrict = iemMemStackPushU32(pVCpu, uOldRip);
    3478     if (rcStrict == VINF_SUCCESS)
    3479     { /* likely */ }
    3480     else
    3481         return rcStrict;
    3482 
    3483     pVCpu->cpum.GstCtx.rip = uNewRip;
    3484 #ifndef IEM_WITH_CODE_TLB
    3485     iemOpcodeFlushLight(pVCpu, cbInstr);
    3486 #endif
    3487     return iemRegFinishNoFlags(pVCpu, VINF_SUCCESS);
    3488 }
    3489 
    3490 
    3491 /**
    3492  * Implements a 32-bit relative call.
    3493  *
    3494  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    3495  * @param   cbInstr             The instruction length.
    3496  * @param   offDisp             The 32-bit displacement.
    3497  */
    3498 DECL_FORCE_INLINE(VBOXSTRICTRC)
    3499 iemRegEip32RelativeCallS32AndFinishClearingRF(PVMCPUCC pVCpu, uint8_t cbInstr, int32_t offDisp) RT_NOEXCEPT
    3500 {
    3501     Assert(pVCpu->cpum.GstCtx.rip <= UINT32_MAX); Assert(!IEM_IS_64BIT_CODE(pVCpu));
    3502 
    3503     uint32_t const uOldRip = pVCpu->cpum.GstCtx.eip + cbInstr;
    3504     uint32_t const uNewRip = uOldRip + offDisp;
    3505     if (uNewRip <= pVCpu->cpum.GstCtx.cs.u32Limit)
    3506     { /* likely */ }
    3507     else
    3508         return iemRaiseGeneralProtectionFault0(pVCpu);
    3509 
    3510     VBOXSTRICTRC rcStrict = iemMemStackPushU32(pVCpu, uOldRip);
    3511     if (rcStrict == VINF_SUCCESS)
    3512     { /* likely */ }
    3513     else
    3514         return rcStrict;
    3515 
    3516     pVCpu->cpum.GstCtx.rip = uNewRip;
    3517 #ifndef IEM_WITH_CODE_TLB
    3518     iemOpcodeFlushLight(pVCpu, cbInstr);
    3519 #endif
    3520     return iemRegFinishClearingRF(pVCpu, VINF_SUCCESS);
    3521 }
    3522 
    3523 
    3524 /**
    3525  * Implements a 64-bit relative call, no checking or clearing of flags.
    3526  *
    3527  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    3528  * @param   cbInstr             The instruction length.
    3529  * @param   offDisp             The 64-bit displacement.
    3530  */
    3531 DECL_FORCE_INLINE(VBOXSTRICTRC)
    3532 iemRegRip64RelativeCallS64AndFinishNoFlags(PVMCPUCC pVCpu, uint8_t cbInstr, int64_t offDisp) RT_NOEXCEPT
    3533 {
    3534     uint64_t const uOldRip = pVCpu->cpum.GstCtx.rip + cbInstr;
    3535     uint64_t const uNewRip = uOldRip + (int64_t)offDisp;
    3536     if (IEM_IS_CANONICAL(uNewRip))
    3537     { /* likely */ }
    3538     else
    3539         return iemRaiseNotCanonical(pVCpu);
    3540 
    3541     VBOXSTRICTRC rcStrict = iemMemStackPushU64(pVCpu, uOldRip);
    3542     if (rcStrict == VINF_SUCCESS)
    3543     { /* likely */ }
    3544     else
    3545         return rcStrict;
    3546 
    3547     pVCpu->cpum.GstCtx.rip = uNewRip;
    3548 #ifndef IEM_WITH_CODE_TLB
    3549     iemOpcodeFlushLight(pVCpu, cbInstr);
    3550 #endif
    3551     return iemRegFinishNoFlags(pVCpu, VINF_SUCCESS);
    3552 }
    3553 
    3554 
    3555 /**
    3556  * Implements a 64-bit relative call.
    3557  *
    3558  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    3559  * @param   cbInstr             The instruction length.
    3560  * @param   offDisp             The 64-bit displacement.
    3561  */
    3562 DECL_FORCE_INLINE(VBOXSTRICTRC)
    3563 iemRegRip64RelativeCallS64AndFinishClearingRF(PVMCPUCC pVCpu, uint8_t cbInstr, int64_t offDisp) RT_NOEXCEPT
    3564 {
    3565     uint64_t const uOldRip = pVCpu->cpum.GstCtx.rip + cbInstr;
    3566     uint64_t const uNewRip = uOldRip + (int64_t)offDisp;
    3567     if (IEM_IS_CANONICAL(uNewRip))
    3568     { /* likely */ }
    3569     else
    3570         return iemRaiseNotCanonical(pVCpu);
    3571 
    3572     VBOXSTRICTRC rcStrict = iemMemStackPushU64(pVCpu, uOldRip);
    3573     if (rcStrict == VINF_SUCCESS)
    3574     { /* likely */ }
    3575     else
    3576         return rcStrict;
    3577 
    3578     pVCpu->cpum.GstCtx.rip = uNewRip;
    3579 #ifndef IEM_WITH_CODE_TLB
    3580     iemOpcodeFlushLight(pVCpu, cbInstr);
    3581 #endif
    3582     return iemRegFinishClearingRF(pVCpu, VINF_SUCCESS);
    3583 }
    3584 
    3585 
    3586 /**
    3587  * Implements an 16-bit indirect call, no checking or clearing of
    3588  * flags.
    3589  *
    3590  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    3591  * @param   cbInstr             The instruction length.
    3592  * @param   uNewRip             The new RIP value.
    3593  */
    3594 DECL_FORCE_INLINE(VBOXSTRICTRC)
    3595 iemRegIp16IndirectCallU16AndFinishNoFlags(PVMCPUCC pVCpu, uint8_t cbInstr, uint16_t uNewRip) RT_NOEXCEPT
    3596 {
    3597     uint16_t const uOldRip = pVCpu->cpum.GstCtx.ip + cbInstr;
    3598     if (uNewRip <= pVCpu->cpum.GstCtx.cs.u32Limit)
    3599     { /* likely */ }
    3600     else
    3601         return iemRaiseGeneralProtectionFault0(pVCpu);
    3602 
    3603     VBOXSTRICTRC rcStrict = iemMemStackPushU16(pVCpu, uOldRip);
    3604     if (rcStrict == VINF_SUCCESS)
    3605     { /* likely */ }
    3606     else
    3607         return rcStrict;
    3608 
    3609     pVCpu->cpum.GstCtx.rip = uNewRip;
    3610 #ifndef IEM_WITH_CODE_TLB
    3611     iemOpcodeFlushLight(pVCpu, cbInstr);
    3612 #endif
    3613     return iemRegFinishNoFlags(pVCpu, VINF_SUCCESS);
    3614 }
    3615 
    3616 
    3617 /**
    3618  * Implements an 16-bit indirect call, no checking or clearing of
    3619  * flags.
    3620  *
    3621  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    3622  * @param   cbInstr             The instruction length.
    3623  * @param   uNewRip             The new RIP value.
    3624  */
    3625 DECL_FORCE_INLINE(VBOXSTRICTRC)
    3626 iemRegEip32IndirectCallU16AndFinishNoFlags(PVMCPUCC pVCpu, uint8_t cbInstr, uint16_t uNewRip) RT_NOEXCEPT
    3627 {
    3628     uint16_t const uOldRip = pVCpu->cpum.GstCtx.ip + cbInstr;
    3629     if (uNewRip <= pVCpu->cpum.GstCtx.cs.u32Limit)
    3630     { /* likely */ }
    3631     else
    3632         return iemRaiseGeneralProtectionFault0(pVCpu);
    3633 
    3634     VBOXSTRICTRC rcStrict = iemMemStackPushU16(pVCpu, uOldRip);
    3635     if (rcStrict == VINF_SUCCESS)
    3636     { /* likely */ }
    3637     else
    3638         return rcStrict;
    3639 
    3640     pVCpu->cpum.GstCtx.rip = uNewRip;
    3641 #ifndef IEM_WITH_CODE_TLB
    3642     iemOpcodeFlushLight(pVCpu, cbInstr);
    3643 #endif
    3644     return iemRegFinishNoFlags(pVCpu, VINF_SUCCESS);
    3645 }
    3646 
    3647 
    3648 /**
    3649  * Implements an 16-bit indirect call.
    3650  *
    3651  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    3652  * @param   cbInstr             The instruction length.
    3653  * @param   uNewRip             The new RIP value.
    3654  */
    3655 DECL_FORCE_INLINE(VBOXSTRICTRC)
    3656 iemRegIp16IndirectCallU16AndFinishClearingRF(PVMCPUCC pVCpu, uint8_t cbInstr, uint16_t uNewRip) RT_NOEXCEPT
    3657 {
    3658     uint16_t const uOldRip = pVCpu->cpum.GstCtx.ip + cbInstr;
    3659     if (uNewRip <= pVCpu->cpum.GstCtx.cs.u32Limit)
    3660     { /* likely */ }
    3661     else
    3662         return iemRaiseGeneralProtectionFault0(pVCpu);
    3663 
    3664     VBOXSTRICTRC rcStrict = iemMemStackPushU16(pVCpu, uOldRip);
    3665     if (rcStrict == VINF_SUCCESS)
    3666     { /* likely */ }
    3667     else
    3668         return rcStrict;
    3669 
    3670     pVCpu->cpum.GstCtx.rip = uNewRip;
    3671 #ifndef IEM_WITH_CODE_TLB
    3672     iemOpcodeFlushLight(pVCpu, cbInstr);
    3673 #endif
    3674     return iemRegFinishClearingRF(pVCpu, VINF_SUCCESS);
    3675 }
    3676 
    3677 
    3678 /**
    3679  * Implements an 16-bit indirect call.
    3680  *
    3681  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    3682  * @param   cbInstr             The instruction length.
    3683  * @param   uNewRip             The new RIP value.
    3684  */
    3685 DECL_FORCE_INLINE(VBOXSTRICTRC)
    3686 iemRegEip32IndirectCallU16AndFinishClearingRF(PVMCPUCC pVCpu, uint8_t cbInstr, uint16_t uNewRip) RT_NOEXCEPT
    3687 {
    3688     uint16_t const uOldRip = pVCpu->cpum.GstCtx.ip + cbInstr;
    3689     if (uNewRip <= pVCpu->cpum.GstCtx.cs.u32Limit)
    3690     { /* likely */ }
    3691     else
    3692         return iemRaiseGeneralProtectionFault0(pVCpu);
    3693 
    3694     VBOXSTRICTRC rcStrict = iemMemStackPushU16(pVCpu, uOldRip);
    3695     if (rcStrict == VINF_SUCCESS)
    3696     { /* likely */ }
    3697     else
    3698         return rcStrict;
    3699 
    3700     pVCpu->cpum.GstCtx.rip = uNewRip;
    3701 #ifndef IEM_WITH_CODE_TLB
    3702     iemOpcodeFlushLight(pVCpu, cbInstr);
    3703 #endif
    3704     return iemRegFinishClearingRF(pVCpu, VINF_SUCCESS);
    3705 }
    3706 
    3707 
    3708 /**
    3709  * Implements an 32-bit indirect call, no checking or clearing of
    3710  * flags.
    3711  *
    3712  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    3713  * @param   cbInstr             The instruction length.
    3714  * @param   uNewRip             The new RIP value.
    3715  */
    3716 DECL_FORCE_INLINE(VBOXSTRICTRC)
    3717 iemRegEip32IndirectCallU32AndFinishNoFlags(PVMCPUCC pVCpu, uint8_t cbInstr, uint32_t uNewRip) RT_NOEXCEPT
    3718 {
    3719     uint32_t const uOldRip = pVCpu->cpum.GstCtx.eip + cbInstr;
    3720     if (uNewRip <= pVCpu->cpum.GstCtx.cs.u32Limit)
    3721     { /* likely */ }
    3722     else
    3723         return iemRaiseGeneralProtectionFault0(pVCpu);
    3724 
    3725     VBOXSTRICTRC rcStrict = iemMemStackPushU32(pVCpu, uOldRip);
    3726     if (rcStrict == VINF_SUCCESS)
    3727     { /* likely */ }
    3728     else
    3729         return rcStrict;
    3730 
    3731     pVCpu->cpum.GstCtx.rip = uNewRip;
    3732 #ifndef IEM_WITH_CODE_TLB
    3733     iemOpcodeFlushLight(pVCpu, cbInstr);
    3734 #endif
    3735     return iemRegFinishNoFlags(pVCpu, VINF_SUCCESS);
    3736 }
    3737 
    3738 
    3739 /**
    3740  * Implements an 32-bit indirect call.
    3741  *
    3742  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    3743  * @param   cbInstr             The instruction length.
    3744  * @param   uNewRip             The new RIP value.
    3745  */
    3746 DECL_FORCE_INLINE(VBOXSTRICTRC)
    3747 iemRegEip32IndirectCallU32AndFinishClearingRF(PVMCPUCC pVCpu, uint8_t cbInstr, uint32_t uNewRip) RT_NOEXCEPT
    3748 {
    3749     uint32_t const uOldRip = pVCpu->cpum.GstCtx.eip + cbInstr;
    3750     if (uNewRip <= pVCpu->cpum.GstCtx.cs.u32Limit)
    3751     { /* likely */ }
    3752     else
    3753         return iemRaiseGeneralProtectionFault0(pVCpu);
    3754 
    3755     VBOXSTRICTRC rcStrict = iemMemStackPushU32(pVCpu, uOldRip);
    3756     if (rcStrict == VINF_SUCCESS)
    3757     { /* likely */ }
    3758     else
    3759         return rcStrict;
    3760 
    3761     pVCpu->cpum.GstCtx.rip = uNewRip;
    3762 #ifndef IEM_WITH_CODE_TLB
    3763     iemOpcodeFlushLight(pVCpu, cbInstr);
    3764 #endif
    3765     return iemRegFinishClearingRF(pVCpu, VINF_SUCCESS);
    3766 }
    3767 
    3768 
    3769 /**
    3770  * Implements an 64-bit indirect call, no checking or clearing of
    3771  * flags.
    3772  *
    3773  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    3774  * @param   cbInstr             The instruction length.
    3775  * @param   uNewRip             The new RIP value.
    3776  */
    3777 DECL_FORCE_INLINE(VBOXSTRICTRC)
    3778 iemRegRip64IndirectCallU64AndFinishNoFlags(PVMCPUCC pVCpu, uint8_t cbInstr, uint64_t uNewRip) RT_NOEXCEPT
    3779 {
    3780     uint64_t const uOldRip = pVCpu->cpum.GstCtx.rip + cbInstr;
    3781     if (IEM_IS_CANONICAL(uNewRip))
    3782     { /* likely */ }
    3783     else
    3784         return iemRaiseGeneralProtectionFault0(pVCpu);
    3785 
    3786     VBOXSTRICTRC rcStrict = iemMemStackPushU64(pVCpu, uOldRip);
    3787     if (rcStrict == VINF_SUCCESS)
    3788     { /* likely */ }
    3789     else
    3790         return rcStrict;
    3791 
    3792     pVCpu->cpum.GstCtx.rip = uNewRip;
    3793 #ifndef IEM_WITH_CODE_TLB
    3794     iemOpcodeFlushLight(pVCpu, cbInstr);
    3795 #endif
    3796     return iemRegFinishNoFlags(pVCpu, VINF_SUCCESS);
    3797 }
    3798 
    3799 
    3800 /**
    3801  * Implements an 64-bit indirect call.
    3802  *
    3803  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    3804  * @param   cbInstr             The instruction length.
    3805  * @param   uNewRip             The new RIP value.
    3806  */
    3807 DECL_FORCE_INLINE(VBOXSTRICTRC)
    3808 iemRegRip64IndirectCallU64AndFinishClearingRF(PVMCPUCC pVCpu, uint8_t cbInstr, uint64_t uNewRip) RT_NOEXCEPT
    3809 {
    3810     uint64_t const uOldRip = pVCpu->cpum.GstCtx.rip + cbInstr;
    3811     if (IEM_IS_CANONICAL(uNewRip))
    3812     { /* likely */ }
    3813     else
    3814         return iemRaiseGeneralProtectionFault0(pVCpu);
    3815 
    3816     VBOXSTRICTRC rcStrict = iemMemStackPushU64(pVCpu, uOldRip);
    3817     if (rcStrict == VINF_SUCCESS)
    3818     { /* likely */ }
    3819     else
    3820         return rcStrict;
    3821 
    3822     pVCpu->cpum.GstCtx.rip = uNewRip;
    3823 #ifndef IEM_WITH_CODE_TLB
    3824     iemOpcodeFlushLight(pVCpu, cbInstr);
    3825 #endif
    3826     return iemRegFinishClearingRF(pVCpu, VINF_SUCCESS);
    3827 }
    3828 
    3829 
    3830 
    3831 /**
    3832  * Adds to the stack pointer.
    3833  *
    3834  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    3835  * @param   cbToAdd             The number of bytes to add (8-bit!).
    3836  */
    3837 DECLINLINE(void) iemRegAddToRsp(PVMCPUCC pVCpu, uint8_t cbToAdd) RT_NOEXCEPT
    3838 {
    3839     if (IEM_IS_64BIT_CODE(pVCpu))
    3840         pVCpu->cpum.GstCtx.rsp += cbToAdd;
    3841     else if (pVCpu->cpum.GstCtx.ss.Attr.n.u1DefBig)
    3842         pVCpu->cpum.GstCtx.esp += cbToAdd;
    3843     else
    3844         pVCpu->cpum.GstCtx.sp  += cbToAdd;
    3845 }
    3846 
    3847 
    3848 /**
    3849  * Subtracts from the stack pointer.
    3850  *
    3851  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    3852  * @param   cbToSub             The number of bytes to subtract (8-bit!).
    3853  */
    3854 DECLINLINE(void) iemRegSubFromRsp(PVMCPUCC pVCpu, uint8_t cbToSub) RT_NOEXCEPT
    3855 {
    3856     if (IEM_IS_64BIT_CODE(pVCpu))
    3857         pVCpu->cpum.GstCtx.rsp -= cbToSub;
    3858     else if (pVCpu->cpum.GstCtx.ss.Attr.n.u1DefBig)
    3859         pVCpu->cpum.GstCtx.esp -= cbToSub;
    3860     else
    3861         pVCpu->cpum.GstCtx.sp  -= cbToSub;
    3862 }
    3863 
    3864 
    3865 /**
    3866  * Adds to the temporary stack pointer.
    3867  *
    3868  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    3869  * @param   pTmpRsp             The temporary SP/ESP/RSP to update.
    3870  * @param   cbToAdd             The number of bytes to add (16-bit).
    3871  */
    3872 DECLINLINE(void) iemRegAddToRspEx(PCVMCPU pVCpu, PRTUINT64U pTmpRsp, uint16_t cbToAdd) RT_NOEXCEPT
    3873 {
    3874     if (IEM_IS_64BIT_CODE(pVCpu))
    3875         pTmpRsp->u           += cbToAdd;
    3876     else if (pVCpu->cpum.GstCtx.ss.Attr.n.u1DefBig)
    3877         pTmpRsp->DWords.dw0  += cbToAdd;
    3878     else
    3879         pTmpRsp->Words.w0    += cbToAdd;
    3880 }
    3881 
    3882 
    3883 /**
    3884  * Subtracts from the temporary stack pointer.
    3885  *
    3886  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    3887  * @param   pTmpRsp             The temporary SP/ESP/RSP to update.
    3888  * @param   cbToSub             The number of bytes to subtract.
    3889  * @remarks The @a cbToSub argument *MUST* be 16-bit, iemCImpl_enter is
    3890  *          expecting that.
    3891  */
    3892 DECLINLINE(void) iemRegSubFromRspEx(PCVMCPU pVCpu, PRTUINT64U pTmpRsp, uint16_t cbToSub) RT_NOEXCEPT
    3893 {
    3894     if (IEM_IS_64BIT_CODE(pVCpu))
    3895         pTmpRsp->u          -= cbToSub;
    3896     else if (pVCpu->cpum.GstCtx.ss.Attr.n.u1DefBig)
    3897         pTmpRsp->DWords.dw0 -= cbToSub;
    3898     else
    3899         pTmpRsp->Words.w0   -= cbToSub;
    3900 }
    3901 
    3902 
    3903 /**
    3904  * Calculates the effective stack address for a push of the specified size as
    3905  * well as the new RSP value (upper bits may be masked).
    3906  *
    3907  * @returns Effective stack addressf for the push.
    3908  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    3909  * @param   cbItem              The size of the stack item to pop.
    3910  * @param   puNewRsp            Where to return the new RSP value.
    3911  */
    3912 DECLINLINE(RTGCPTR) iemRegGetRspForPush(PCVMCPU pVCpu, uint8_t cbItem, uint64_t *puNewRsp) RT_NOEXCEPT
    3913 {
    3914     RTUINT64U   uTmpRsp;
    3915     RTGCPTR     GCPtrTop;
    3916     uTmpRsp.u = pVCpu->cpum.GstCtx.rsp;
    3917 
    3918     if (IEM_IS_64BIT_CODE(pVCpu))
    3919         GCPtrTop = uTmpRsp.u            -= cbItem;
    3920     else if (pVCpu->cpum.GstCtx.ss.Attr.n.u1DefBig)
    3921         GCPtrTop = uTmpRsp.DWords.dw0   -= cbItem;
    3922     else
    3923         GCPtrTop = uTmpRsp.Words.w0     -= cbItem;
    3924     *puNewRsp = uTmpRsp.u;
    3925     return GCPtrTop;
    3926 }
    3927 
    3928 
    3929 /**
    3930  * Gets the current stack pointer and calculates the value after a pop of the
    3931  * specified size.
    3932  *
    3933  * @returns Current stack pointer.
    3934  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    3935  * @param   cbItem              The size of the stack item to pop.
    3936  * @param   puNewRsp            Where to return the new RSP value.
    3937  */
    3938 DECLINLINE(RTGCPTR) iemRegGetRspForPop(PCVMCPU pVCpu, uint8_t cbItem, uint64_t *puNewRsp) RT_NOEXCEPT
    3939 {
    3940     RTUINT64U   uTmpRsp;
    3941     RTGCPTR     GCPtrTop;
    3942     uTmpRsp.u = pVCpu->cpum.GstCtx.rsp;
    3943 
    3944     if (IEM_IS_64BIT_CODE(pVCpu))
    3945     {
    3946         GCPtrTop = uTmpRsp.u;
    3947         uTmpRsp.u += cbItem;
    3948     }
    3949     else if (pVCpu->cpum.GstCtx.ss.Attr.n.u1DefBig)
    3950     {
    3951         GCPtrTop = uTmpRsp.DWords.dw0;
    3952         uTmpRsp.DWords.dw0 += cbItem;
    3953     }
    3954     else
    3955     {
    3956         GCPtrTop = uTmpRsp.Words.w0;
    3957         uTmpRsp.Words.w0 += cbItem;
    3958     }
    3959     *puNewRsp = uTmpRsp.u;
    3960     return GCPtrTop;
    3961 }
    3962 
    3963 
    3964 /**
    3965  * Calculates the effective stack address for a push of the specified size as
    3966  * well as the new temporary RSP value (upper bits may be masked).
    3967  *
    3968  * @returns Effective stack addressf for the push.
    3969  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    3970  * @param   pTmpRsp             The temporary stack pointer.  This is updated.
    3971  * @param   cbItem              The size of the stack item to pop.
    3972  */
    3973 DECLINLINE(RTGCPTR) iemRegGetRspForPushEx(PCVMCPU pVCpu, PRTUINT64U pTmpRsp, uint8_t cbItem) RT_NOEXCEPT
    3974 {
    3975     RTGCPTR GCPtrTop;
    3976 
    3977     if (IEM_IS_64BIT_CODE(pVCpu))
    3978         GCPtrTop = pTmpRsp->u          -= cbItem;
    3979     else if (pVCpu->cpum.GstCtx.ss.Attr.n.u1DefBig)
    3980         GCPtrTop = pTmpRsp->DWords.dw0 -= cbItem;
    3981     else
    3982         GCPtrTop = pTmpRsp->Words.w0   -= cbItem;
    3983     return GCPtrTop;
    3984 }
    3985 
    3986 
    3987 /**
    3988  * Gets the effective stack address for a pop of the specified size and
    3989  * calculates and updates the temporary RSP.
    3990  *
    3991  * @returns Current stack pointer.
    3992  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    3993  * @param   pTmpRsp             The temporary stack pointer.  This is updated.
    3994  * @param   cbItem              The size of the stack item to pop.
    3995  */
    3996 DECLINLINE(RTGCPTR) iemRegGetRspForPopEx(PCVMCPU pVCpu, PRTUINT64U pTmpRsp, uint8_t cbItem) RT_NOEXCEPT
    3997 {
    3998     RTGCPTR GCPtrTop;
    3999     if (IEM_IS_64BIT_CODE(pVCpu))
    4000     {
    4001         GCPtrTop = pTmpRsp->u;
    4002         pTmpRsp->u          += cbItem;
    4003     }
    4004     else if (pVCpu->cpum.GstCtx.ss.Attr.n.u1DefBig)
    4005     {
    4006         GCPtrTop = pTmpRsp->DWords.dw0;
    4007         pTmpRsp->DWords.dw0 += cbItem;
    4008     }
    4009     else
    4010     {
    4011         GCPtrTop = pTmpRsp->Words.w0;
    4012         pTmpRsp->Words.w0   += cbItem;
    4013     }
    4014     return GCPtrTop;
    4015 }
    4016 
    4017 
    4018 /** Common body for iemRegRipNearReturnAndFinishClearingRF()
    4019  * and iemRegRipNearReturnAndFinishNoFlags(). */
    4020 template<bool a_fWithFlags>
    4021 DECL_FORCE_INLINE(VBOXSTRICTRC)
    4022 iemRegRipNearReturnCommon(PVMCPUCC pVCpu, uint8_t cbInstr, uint16_t cbPop, IEMMODE enmEffOpSize) RT_NOEXCEPT
    4023 {
    4024     /* Fetch the new RIP from the stack. */
    4025     VBOXSTRICTRC    rcStrict;
    4026     RTUINT64U       NewRip;
    4027     RTUINT64U       NewRsp;
    4028     NewRsp.u = pVCpu->cpum.GstCtx.rsp;
    4029     switch (enmEffOpSize)
    4030     {
    4031         case IEMMODE_16BIT:
    4032             NewRip.u = 0;
    4033             rcStrict = iemMemStackPopU16Ex(pVCpu, &NewRip.Words.w0, &NewRsp);
    4034             break;
    4035         case IEMMODE_32BIT:
    4036             NewRip.u = 0;
    4037             rcStrict = iemMemStackPopU32Ex(pVCpu, &NewRip.DWords.dw0, &NewRsp);
    4038             break;
    4039         case IEMMODE_64BIT:
    4040             rcStrict = iemMemStackPopU64Ex(pVCpu, &NewRip.u, &NewRsp);
    4041             break;
    4042         IEM_NOT_REACHED_DEFAULT_CASE_RET();
    4043     }
    4044     if (rcStrict != VINF_SUCCESS)
    4045         return rcStrict;
    4046 
    4047     /* Check the new ew RIP before loading it. */
    4048     /** @todo Should test this as the intel+amd pseudo code doesn't mention half
    4049      *        of it.  The canonical test is performed here and for call. */
    4050     if (enmEffOpSize != IEMMODE_64BIT)
    4051     {
    4052         if (RT_LIKELY(NewRip.DWords.dw0 <= pVCpu->cpum.GstCtx.cs.u32Limit))
    4053         { /* likely */ }
    4054         else
    4055         {
    4056             Log(("retn newrip=%llx - out of bounds (%x) -> #GP\n", NewRip.u, pVCpu->cpum.GstCtx.cs.u32Limit));
    4057             return iemRaiseSelectorBounds(pVCpu, X86_SREG_CS, IEM_ACCESS_INSTRUCTION);
    4058         }
    4059     }
    4060     else
    4061     {
    4062         if (RT_LIKELY(IEM_IS_CANONICAL(NewRip.u)))
    4063         { /* likely */ }
    4064         else
    4065         {
    4066             Log(("retn newrip=%llx - not canonical -> #GP\n", NewRip.u));
    4067             return iemRaiseNotCanonical(pVCpu);
    4068         }
    4069     }
    4070 
    4071     /* Apply cbPop */
    4072     if (cbPop)
    4073         iemRegAddToRspEx(pVCpu, &NewRsp, cbPop);
    4074 
    4075     /* Commit it. */
    4076     pVCpu->cpum.GstCtx.rip = NewRip.u;
    4077     pVCpu->cpum.GstCtx.rsp = NewRsp.u;
    4078 
    4079     /* Flush the prefetch buffer. */
    4080 #ifndef IEM_WITH_CODE_TLB
    4081     iemOpcodeFlushLight(pVCpu, cbInstr);
    4082 #endif
    4083     RT_NOREF(cbInstr);
    4084 
    4085 
    4086     if (a_fWithFlags)
    4087         return iemRegFinishClearingRF(pVCpu, VINF_SUCCESS);
    4088     return iemRegFinishNoFlags(pVCpu, VINF_SUCCESS);
    4089 }
    4090 
    4091 
    4092 /**
    4093  * Implements retn and retn imm16.
    4094  *
    4095  * @param   pVCpu           The cross context virtual CPU structure of the
    4096  *                          calling thread.
    4097  * @param   cbInstr         The current instruction length.
    4098  * @param   enmEffOpSize    The effective operand size.  This is constant.
    4099  * @param   cbPop           The amount of arguments to pop from the stack
    4100  *                          (bytes).  This can be constant (zero).
    4101  */
    4102 DECL_FORCE_INLINE(VBOXSTRICTRC)
    4103 iemRegRipNearReturnAndFinishClearingRF(PVMCPUCC pVCpu, uint8_t cbInstr, uint16_t cbPop, IEMMODE enmEffOpSize) RT_NOEXCEPT
    4104 {
    4105     return iemRegRipNearReturnCommon<true /*a_fWithFlags*/>(pVCpu, cbInstr, cbPop, enmEffOpSize);
    4106 }
    4107 
    4108 
    4109 /**
    4110  * Implements retn and retn imm16, no checking or clearing of
    4111  * flags.
    4112  *
    4113  * @param   pVCpu           The cross context virtual CPU structure of the
    4114  *                          calling thread.
    4115  * @param   cbInstr         The current instruction length.
    4116  * @param   enmEffOpSize    The effective operand size.  This is constant.
    4117  * @param   cbPop           The amount of arguments to pop from the stack
    4118  *                          (bytes).  This can be constant (zero).
    4119  */
    4120 DECL_FORCE_INLINE(VBOXSTRICTRC)
    4121 iemRegRipNearReturnAndFinishNoFlags(PVMCPUCC pVCpu, uint8_t cbInstr, uint16_t cbPop, IEMMODE enmEffOpSize) RT_NOEXCEPT
    4122 {
    4123     return iemRegRipNearReturnCommon<false /*a_fWithFlags*/>(pVCpu, cbInstr, cbPop, enmEffOpSize);
    4124 }
    4125 
    4126 /** @}  */
    4127 
    4128 
    4129 /** @name   FPU access and helpers.
    4130  *
    4131  * @{
    4132  */
    4133 
    4134 
    4135 /**
    4136  * Hook for preparing to use the host FPU.
    4137  *
    4138  * This is necessary in ring-0 and raw-mode context (nop in ring-3).
    4139  *
    4140  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    4141  */
    4142 DECLINLINE(void) iemFpuPrepareUsage(PVMCPUCC pVCpu) RT_NOEXCEPT
    4143 {
    4144 #ifdef IN_RING3
    4145     CPUMSetChangedFlags(pVCpu, CPUM_CHANGED_FPU_REM);
    4146 #else
    4147     CPUMRZFpuStatePrepareHostCpuForUse(pVCpu);
    4148 #endif
    4149     IEM_CTX_IMPORT_NORET(pVCpu, CPUMCTX_EXTRN_X87 | CPUMCTX_EXTRN_SSE_AVX | CPUMCTX_EXTRN_OTHER_XSAVE | CPUMCTX_EXTRN_XCRx);
    4150 }
    4151 
    4152 
    4153 /**
    4154  * Hook for preparing to use the host FPU for SSE.
    4155  *
    4156  * This is necessary in ring-0 and raw-mode context (nop in ring-3).
    4157  *
    4158  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    4159  */
    4160 DECLINLINE(void) iemFpuPrepareUsageSse(PVMCPUCC pVCpu) RT_NOEXCEPT
    4161 {
    4162     iemFpuPrepareUsage(pVCpu);
    4163 }
    4164 
    4165 
    4166 /**
    4167  * Hook for preparing to use the host FPU for AVX.
    4168  *
    4169  * This is necessary in ring-0 and raw-mode context (nop in ring-3).
    4170  *
    4171  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    4172  */
    4173 DECLINLINE(void) iemFpuPrepareUsageAvx(PVMCPUCC pVCpu) RT_NOEXCEPT
    4174 {
    4175     iemFpuPrepareUsage(pVCpu);
    4176 }
    4177 
    4178 
    4179 /**
    4180  * Hook for actualizing the guest FPU state before the interpreter reads it.
    4181  *
    4182  * This is necessary in ring-0 and raw-mode context (nop in ring-3).
    4183  *
    4184  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    4185  */
    4186 DECLINLINE(void) iemFpuActualizeStateForRead(PVMCPUCC pVCpu) RT_NOEXCEPT
    4187 {
    4188 #ifdef IN_RING3
    4189     NOREF(pVCpu);
    4190 #else
    4191     CPUMRZFpuStateActualizeForRead(pVCpu);
    4192 #endif
    4193     IEM_CTX_IMPORT_NORET(pVCpu, CPUMCTX_EXTRN_X87 | CPUMCTX_EXTRN_SSE_AVX | CPUMCTX_EXTRN_OTHER_XSAVE | CPUMCTX_EXTRN_XCRx);
    4194 }
    4195 
    4196 
    4197 /**
    4198  * Hook for actualizing the guest FPU state before the interpreter changes it.
    4199  *
    4200  * This is necessary in ring-0 and raw-mode context (nop in ring-3).
    4201  *
    4202  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    4203  */
    4204 DECLINLINE(void) iemFpuActualizeStateForChange(PVMCPUCC pVCpu) RT_NOEXCEPT
    4205 {
    4206 #ifdef IN_RING3
    4207     CPUMSetChangedFlags(pVCpu, CPUM_CHANGED_FPU_REM);
    4208 #else
    4209     CPUMRZFpuStateActualizeForChange(pVCpu);
    4210 #endif
    4211     IEM_CTX_IMPORT_NORET(pVCpu, CPUMCTX_EXTRN_X87 | CPUMCTX_EXTRN_SSE_AVX | CPUMCTX_EXTRN_OTHER_XSAVE | CPUMCTX_EXTRN_XCRx);
    4212 }
    4213 
    4214 
    4215 /**
    4216  * Hook for actualizing the guest XMM0..15 and MXCSR register state for read
    4217  * only.
    4218  *
    4219  * This is necessary in ring-0 and raw-mode context (nop in ring-3).
    4220  *
    4221  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    4222  */
    4223 DECLINLINE(void) iemFpuActualizeSseStateForRead(PVMCPUCC pVCpu) RT_NOEXCEPT
    4224 {
    4225 #if defined(IN_RING3) || defined(VBOX_WITH_KERNEL_USING_XMM)
    4226     NOREF(pVCpu);
    4227 #else
    4228     CPUMRZFpuStateActualizeSseForRead(pVCpu);
    4229 #endif
    4230     IEM_CTX_IMPORT_NORET(pVCpu, CPUMCTX_EXTRN_X87 | CPUMCTX_EXTRN_SSE_AVX | CPUMCTX_EXTRN_OTHER_XSAVE | CPUMCTX_EXTRN_XCRx);
    4231 }
    4232 
    4233 
    4234 /**
    4235  * Hook for actualizing the guest XMM0..15 and MXCSR register state for
    4236  * read+write.
    4237  *
    4238  * This is necessary in ring-0 and raw-mode context (nop in ring-3).
    4239  *
    4240  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    4241  */
    4242 DECLINLINE(void) iemFpuActualizeSseStateForChange(PVMCPUCC pVCpu) RT_NOEXCEPT
    4243 {
    4244 #if defined(IN_RING3) || defined(VBOX_WITH_KERNEL_USING_XMM)
    4245     CPUMSetChangedFlags(pVCpu, CPUM_CHANGED_FPU_REM);
    4246 #else
    4247     CPUMRZFpuStateActualizeForChange(pVCpu);
    4248 #endif
    4249     IEM_CTX_IMPORT_NORET(pVCpu, CPUMCTX_EXTRN_X87 | CPUMCTX_EXTRN_SSE_AVX | CPUMCTX_EXTRN_OTHER_XSAVE | CPUMCTX_EXTRN_XCRx);
    4250 
    4251     /* Make sure any changes are loaded the next time around. */
    4252     pVCpu->cpum.GstCtx.XState.Hdr.bmXState |= XSAVE_C_SSE;
    4253 }
    4254 
    4255 
    4256 /**
    4257  * Hook for actualizing the guest YMM0..15 and MXCSR register state for read
    4258  * only.
    4259  *
    4260  * This is necessary in ring-0 and raw-mode context (nop in ring-3).
    4261  *
    4262  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    4263  */
    4264 DECLINLINE(void) iemFpuActualizeAvxStateForRead(PVMCPUCC pVCpu) RT_NOEXCEPT
    4265 {
    4266 #ifdef IN_RING3
    4267     NOREF(pVCpu);
    4268 #else
    4269     CPUMRZFpuStateActualizeAvxForRead(pVCpu);
    4270 #endif
    4271     IEM_CTX_IMPORT_NORET(pVCpu, CPUMCTX_EXTRN_X87 | CPUMCTX_EXTRN_SSE_AVX | CPUMCTX_EXTRN_OTHER_XSAVE | CPUMCTX_EXTRN_XCRx);
    4272 }
    4273 
    4274 
    4275 /**
    4276  * Hook for actualizing the guest YMM0..15 and MXCSR register state for
    4277  * read+write.
    4278  *
    4279  * This is necessary in ring-0 and raw-mode context (nop in ring-3).
    4280  *
    4281  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    4282  */
    4283 DECLINLINE(void) iemFpuActualizeAvxStateForChange(PVMCPUCC pVCpu) RT_NOEXCEPT
    4284 {
    4285 #ifdef IN_RING3
    4286     CPUMSetChangedFlags(pVCpu, CPUM_CHANGED_FPU_REM);
    4287 #else
    4288     CPUMRZFpuStateActualizeForChange(pVCpu);
    4289 #endif
    4290     IEM_CTX_IMPORT_NORET(pVCpu, CPUMCTX_EXTRN_X87 | CPUMCTX_EXTRN_SSE_AVX | CPUMCTX_EXTRN_OTHER_XSAVE | CPUMCTX_EXTRN_XCRx);
    4291 
    4292     /* Just assume we're going to make changes to the SSE and YMM_HI parts. */
    4293     pVCpu->cpum.GstCtx.XState.Hdr.bmXState |= XSAVE_C_YMM | XSAVE_C_SSE;
    4294 }
    4295 
    4296 
    4297 /**
    4298  * Stores a QNaN value into a FPU register.
    4299  *
    4300  * @param   pReg                Pointer to the register.
    4301  */
    4302 DECLINLINE(void) iemFpuStoreQNan(PRTFLOAT80U pReg) RT_NOEXCEPT
    4303 {
    4304     pReg->au32[0] = UINT32_C(0x00000000);
    4305     pReg->au32[1] = UINT32_C(0xc0000000);
    4306     pReg->au16[4] = UINT16_C(0xffff);
    4307 }
    4308 
    4309 
    4310 /**
    4311  * Updates the FOP, FPU.CS and FPUIP registers, extended version.
    4312  *
    4313  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    4314  * @param   pFpuCtx             The FPU context.
    4315  * @param   uFpuOpcode          The FPU opcode value (see IEMCPU::uFpuOpcode).
    4316  */
    4317 DECLINLINE(void) iemFpuUpdateOpcodeAndIpWorkerEx(PVMCPUCC pVCpu, PX86FXSTATE pFpuCtx, uint16_t uFpuOpcode) RT_NOEXCEPT
    4318 {
    4319     Assert(uFpuOpcode != UINT16_MAX);
    4320     pFpuCtx->FOP = uFpuOpcode;
    4321     /** @todo x87.CS and FPUIP needs to be kept seperately. */
    4322     if (IEM_IS_REAL_OR_V86_MODE(pVCpu))
    4323     {
    4324         /** @todo Testcase: making assumptions about how FPUIP and FPUDP are handled
    4325          *        happens in real mode here based on the fnsave and fnstenv images. */
    4326         pFpuCtx->CS    = 0;
    4327         pFpuCtx->FPUIP = pVCpu->cpum.GstCtx.eip | ((uint32_t)pVCpu->cpum.GstCtx.cs.Sel << 4);
    4328     }
    4329     else if (!IEM_IS_LONG_MODE(pVCpu))
    4330     {
    4331         pFpuCtx->CS    = pVCpu->cpum.GstCtx.cs.Sel;
    4332         pFpuCtx->FPUIP = pVCpu->cpum.GstCtx.rip;
    4333     }
    4334     else
    4335         *(uint64_t *)&pFpuCtx->FPUIP = pVCpu->cpum.GstCtx.rip;
    4336 }
    4337 
    4338 
    4339 /**
    4340  * Marks the specified stack register as free (for FFREE).
    4341  *
    4342  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    4343  * @param   iStReg              The register to free.
    4344  */
    4345 DECLINLINE(void) iemFpuStackFree(PVMCPUCC pVCpu, uint8_t iStReg) RT_NOEXCEPT
    4346 {
    4347     Assert(iStReg < 8);
    4348     PX86FXSTATE pFpuCtx = &pVCpu->cpum.GstCtx.XState.x87;
    4349     uint8_t     iReg    = (X86_FSW_TOP_GET(pFpuCtx->FSW) + iStReg) & X86_FSW_TOP_SMASK;
    4350     pFpuCtx->FTW &= ~RT_BIT(iReg);
    4351 }
    4352 
    4353 
    4354 /**
    4355  * Increments FSW.TOP, i.e. pops an item off the stack without freeing it.
    4356  *
    4357  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    4358  */
    4359 DECLINLINE(void) iemFpuStackIncTop(PVMCPUCC pVCpu) RT_NOEXCEPT
    4360 {
    4361     PX86FXSTATE pFpuCtx = &pVCpu->cpum.GstCtx.XState.x87;
    4362     uint16_t    uFsw    = pFpuCtx->FSW;
    4363     uint16_t    uTop    = uFsw & X86_FSW_TOP_MASK;
    4364     uTop  = (uTop + (1 << X86_FSW_TOP_SHIFT)) & X86_FSW_TOP_MASK;
    4365     uFsw &= ~X86_FSW_TOP_MASK;
    4366     uFsw |= uTop;
    4367     pFpuCtx->FSW = uFsw;
    4368 }
    4369 
    4370 
    4371 /**
    4372  * Decrements FSW.TOP, i.e. push an item off the stack without storing anything.
    4373  *
    4374  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    4375  */
    4376 DECLINLINE(void) iemFpuStackDecTop(PVMCPUCC pVCpu) RT_NOEXCEPT
    4377 {
    4378     PX86FXSTATE pFpuCtx = &pVCpu->cpum.GstCtx.XState.x87;
    4379     uint16_t    uFsw    = pFpuCtx->FSW;
    4380     uint16_t    uTop    = uFsw & X86_FSW_TOP_MASK;
    4381     uTop  = (uTop + (7 << X86_FSW_TOP_SHIFT)) & X86_FSW_TOP_MASK;
    4382     uFsw &= ~X86_FSW_TOP_MASK;
    4383     uFsw |= uTop;
    4384     pFpuCtx->FSW = uFsw;
    4385 }
    4386 
    4387 
    4388 
    4389 
    4390 DECLINLINE(int) iemFpuStRegNotEmpty(PVMCPUCC pVCpu, uint8_t iStReg) RT_NOEXCEPT
    4391 {
    4392     PX86FXSTATE pFpuCtx = &pVCpu->cpum.GstCtx.XState.x87;
    4393     uint16_t    iReg    = (X86_FSW_TOP_GET(pFpuCtx->FSW) + iStReg) & X86_FSW_TOP_SMASK;
    4394     if (pFpuCtx->FTW & RT_BIT(iReg))
    4395         return VINF_SUCCESS;
    4396     return VERR_NOT_FOUND;
    4397 }
    4398 
    4399 
    4400 DECLINLINE(int) iemFpuStRegNotEmptyRef(PVMCPUCC pVCpu, uint8_t iStReg, PCRTFLOAT80U *ppRef) RT_NOEXCEPT
    4401 {
    4402     PX86FXSTATE pFpuCtx = &pVCpu->cpum.GstCtx.XState.x87;
    4403     uint16_t    iReg    = (X86_FSW_TOP_GET(pFpuCtx->FSW) + iStReg) & X86_FSW_TOP_SMASK;
    4404     if (pFpuCtx->FTW & RT_BIT(iReg))
    4405     {
    4406         *ppRef = &pFpuCtx->aRegs[iStReg].r80;
    4407         return VINF_SUCCESS;
    4408     }
    4409     return VERR_NOT_FOUND;
    4410 }
    4411 
    4412 
    4413 DECLINLINE(int) iemFpu2StRegsNotEmptyRef(PVMCPUCC pVCpu, uint8_t iStReg0, PCRTFLOAT80U *ppRef0,
    4414                                         uint8_t iStReg1, PCRTFLOAT80U *ppRef1) RT_NOEXCEPT
    4415 {
    4416     PX86FXSTATE pFpuCtx = &pVCpu->cpum.GstCtx.XState.x87;
    4417     uint16_t    iTop    = X86_FSW_TOP_GET(pFpuCtx->FSW);
    4418     uint16_t    iReg0   = (iTop + iStReg0) & X86_FSW_TOP_SMASK;
    4419     uint16_t    iReg1   = (iTop + iStReg1) & X86_FSW_TOP_SMASK;
    4420     if ((pFpuCtx->FTW & (RT_BIT(iReg0) | RT_BIT(iReg1))) == (RT_BIT(iReg0) | RT_BIT(iReg1)))
    4421     {
    4422         *ppRef0 = &pFpuCtx->aRegs[iStReg0].r80;
    4423         *ppRef1 = &pFpuCtx->aRegs[iStReg1].r80;
    4424         return VINF_SUCCESS;
    4425     }
    4426     return VERR_NOT_FOUND;
    4427 }
    4428 
    4429 
    4430 DECLINLINE(int) iemFpu2StRegsNotEmptyRefFirst(PVMCPUCC pVCpu, uint8_t iStReg0, PCRTFLOAT80U *ppRef0, uint8_t iStReg1) RT_NOEXCEPT
    4431 {
    4432     PX86FXSTATE pFpuCtx = &pVCpu->cpum.GstCtx.XState.x87;
    4433     uint16_t    iTop    = X86_FSW_TOP_GET(pFpuCtx->FSW);
    4434     uint16_t    iReg0   = (iTop + iStReg0) & X86_FSW_TOP_SMASK;
    4435     uint16_t    iReg1   = (iTop + iStReg1) & X86_FSW_TOP_SMASK;
    4436     if ((pFpuCtx->FTW & (RT_BIT(iReg0) | RT_BIT(iReg1))) == (RT_BIT(iReg0) | RT_BIT(iReg1)))
    4437     {
    4438         *ppRef0 = &pFpuCtx->aRegs[iStReg0].r80;
    4439         return VINF_SUCCESS;
    4440     }
    4441     return VERR_NOT_FOUND;
    4442 }
    4443 
    4444 
    4445 /**
    4446  * Rotates the stack registers when setting new TOS.
    4447  *
    4448  * @param   pFpuCtx             The FPU context.
    4449  * @param   iNewTop             New TOS value.
    4450  * @remarks We only do this to speed up fxsave/fxrstor which
    4451  *          arrange the FP registers in stack order.
    4452  *          MUST be done before writing the new TOS (FSW).
    4453  */
    4454 DECLINLINE(void) iemFpuRotateStackSetTop(PX86FXSTATE pFpuCtx, uint16_t iNewTop) RT_NOEXCEPT
    4455 {
    4456     uint16_t iOldTop = X86_FSW_TOP_GET(pFpuCtx->FSW);
    4457     RTFLOAT80U ar80Temp[8];
    4458 
    4459     if (iOldTop == iNewTop)
    4460         return;
    4461 
    4462     /* Unscrew the stack and get it into 'native' order. */
    4463     ar80Temp[0] = pFpuCtx->aRegs[(8 - iOldTop + 0) & X86_FSW_TOP_SMASK].r80;
    4464     ar80Temp[1] = pFpuCtx->aRegs[(8 - iOldTop + 1) & X86_FSW_TOP_SMASK].r80;
    4465     ar80Temp[2] = pFpuCtx->aRegs[(8 - iOldTop + 2) & X86_FSW_TOP_SMASK].r80;
    4466     ar80Temp[3] = pFpuCtx->aRegs[(8 - iOldTop + 3) & X86_FSW_TOP_SMASK].r80;
    4467     ar80Temp[4] = pFpuCtx->aRegs[(8 - iOldTop + 4) & X86_FSW_TOP_SMASK].r80;
    4468     ar80Temp[5] = pFpuCtx->aRegs[(8 - iOldTop + 5) & X86_FSW_TOP_SMASK].r80;
    4469     ar80Temp[6] = pFpuCtx->aRegs[(8 - iOldTop + 6) & X86_FSW_TOP_SMASK].r80;
    4470     ar80Temp[7] = pFpuCtx->aRegs[(8 - iOldTop + 7) & X86_FSW_TOP_SMASK].r80;
    4471 
    4472     /* Now rotate the stack to the new position. */
    4473     pFpuCtx->aRegs[0].r80 = ar80Temp[(iNewTop + 0) & X86_FSW_TOP_SMASK];
    4474     pFpuCtx->aRegs[1].r80 = ar80Temp[(iNewTop + 1) & X86_FSW_TOP_SMASK];
    4475     pFpuCtx->aRegs[2].r80 = ar80Temp[(iNewTop + 2) & X86_FSW_TOP_SMASK];
    4476     pFpuCtx->aRegs[3].r80 = ar80Temp[(iNewTop + 3) & X86_FSW_TOP_SMASK];
    4477     pFpuCtx->aRegs[4].r80 = ar80Temp[(iNewTop + 4) & X86_FSW_TOP_SMASK];
    4478     pFpuCtx->aRegs[5].r80 = ar80Temp[(iNewTop + 5) & X86_FSW_TOP_SMASK];
    4479     pFpuCtx->aRegs[6].r80 = ar80Temp[(iNewTop + 6) & X86_FSW_TOP_SMASK];
    4480     pFpuCtx->aRegs[7].r80 = ar80Temp[(iNewTop + 7) & X86_FSW_TOP_SMASK];
    4481 }
    4482 
    4483 
    4484 /**
    4485  * Updates the FPU exception status after FCW is changed.
    4486  *
    4487  * @param   pFpuCtx             The FPU context.
    4488  */
    4489 DECLINLINE(void) iemFpuRecalcExceptionStatus(PX86FXSTATE pFpuCtx) RT_NOEXCEPT
    4490 {
    4491     uint16_t u16Fsw = pFpuCtx->FSW;
    4492     if ((u16Fsw & X86_FSW_XCPT_MASK) & ~(pFpuCtx->FCW & X86_FCW_XCPT_MASK))
    4493         u16Fsw |= X86_FSW_ES | X86_FSW_B;
    4494     else
    4495         u16Fsw &= ~(X86_FSW_ES | X86_FSW_B);
    4496     pFpuCtx->FSW = u16Fsw;
    4497 }
    4498 
    4499 
    4500 /**
    4501  * Calculates the full FTW (FPU tag word) for use in FNSTENV and FNSAVE.
    4502  *
    4503  * @returns The full FTW.
    4504  * @param   pFpuCtx             The FPU context.
    4505  */
    4506 DECLINLINE(uint16_t) iemFpuCalcFullFtw(PCX86FXSTATE pFpuCtx) RT_NOEXCEPT
    4507 {
    4508     uint8_t const   u8Ftw  = (uint8_t)pFpuCtx->FTW;
    4509     uint16_t        u16Ftw = 0;
    4510     unsigned const  iTop   = X86_FSW_TOP_GET(pFpuCtx->FSW);
    4511     for (unsigned iSt = 0; iSt < 8; iSt++)
    4512     {
    4513         unsigned const iReg = (iSt + iTop) & 7;
    4514         if (!(u8Ftw & RT_BIT(iReg)))
    4515             u16Ftw |= 3 << (iReg * 2); /* empty */
    4516         else
    4517         {
    4518             uint16_t uTag;
    4519             PCRTFLOAT80U const pr80Reg = &pFpuCtx->aRegs[iSt].r80;
    4520             if (pr80Reg->s.uExponent == 0x7fff)
    4521                 uTag = 2; /* Exponent is all 1's => Special. */
    4522             else if (pr80Reg->s.uExponent == 0x0000)
    4523             {
    4524                 if (pr80Reg->s.uMantissa == 0x0000)
    4525                     uTag = 1; /* All bits are zero => Zero. */
    4526                 else
    4527                     uTag = 2; /* Must be special. */
    4528             }
    4529             else if (pr80Reg->s.uMantissa & RT_BIT_64(63)) /* The J bit. */
    4530                 uTag = 0; /* Valid. */
    4531             else
    4532                 uTag = 2; /* Must be special. */
    4533 
    4534             u16Ftw |= uTag << (iReg * 2);
    4535         }
    4536     }
    4537 
    4538     return u16Ftw;
    4539 }
    4540 
    4541 
    4542 /**
    4543  * Converts a full FTW to a compressed one (for use in FLDENV and FRSTOR).
    4544  *
    4545  * @returns The compressed FTW.
    4546  * @param   u16FullFtw      The full FTW to convert.
    4547  */
    4548 DECLINLINE(uint16_t) iemFpuCompressFtw(uint16_t u16FullFtw) RT_NOEXCEPT
    4549 {
    4550     uint8_t u8Ftw = 0;
    4551     for (unsigned i = 0; i < 8; i++)
    4552     {
    4553         if ((u16FullFtw & 3) != 3 /*empty*/)
    4554             u8Ftw |= RT_BIT(i);
    4555         u16FullFtw >>= 2;
    4556     }
    4557 
    4558     return u8Ftw;
    4559 }
    4560 
    4561 /** @}  */
    4562 
    4563 
    4564 /** @name   Memory access.
    4565  *
    4566  * @{
    4567  */
    4568 
    456943
    457044/**
     
    4662136}
    4663137
    4664 
    4665 /**
    4666  * Maps a physical page.
    4667  *
    4668  * @returns VBox status code (see PGMR3PhysTlbGCPhys2Ptr).
    4669  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    4670  * @param   GCPhysMem           The physical address.
    4671  * @param   fAccess             The intended access.
    4672  * @param   ppvMem              Where to return the mapping address.
    4673  * @param   pLock               The PGM lock.
    4674  */
    4675 DECLINLINE(int) iemMemPageMap(PVMCPUCC pVCpu, RTGCPHYS GCPhysMem, uint32_t fAccess,
    4676                               void **ppvMem, PPGMPAGEMAPLOCK pLock) RT_NOEXCEPT
    4677 {
    4678 #ifdef IEM_LOG_MEMORY_WRITES
    4679     if (fAccess & IEM_ACCESS_TYPE_WRITE)
    4680         return VERR_PGM_PHYS_TLB_CATCH_ALL;
    4681 #endif
    4682 
    4683     /** @todo This API may require some improving later.  A private deal with PGM
    4684      *        regarding locking and unlocking needs to be struct.  A couple of TLBs
    4685      *        living in PGM, but with publicly accessible inlined access methods
    4686      *        could perhaps be an even better solution. */
    4687     int rc = PGMPhysIemGCPhys2Ptr(pVCpu->CTX_SUFF(pVM), pVCpu,
    4688                                   GCPhysMem,
    4689                                   RT_BOOL(fAccess & IEM_ACCESS_TYPE_WRITE),
    4690                                   RT_BOOL(pVCpu->iem.s.fExec & IEM_F_BYPASS_HANDLERS),
    4691                                   ppvMem,
    4692                                   pLock);
    4693     /*Log(("PGMPhysIemGCPhys2Ptr %Rrc pLock=%.*Rhxs\n", rc, sizeof(*pLock), pLock));*/
    4694     AssertMsg(rc == VINF_SUCCESS || RT_FAILURE_NP(rc), ("%Rrc\n", rc));
    4695 
    4696     return rc;
    4697 }
    4698 
    4699 
    4700 /**
    4701  * Unmap a page previously mapped by iemMemPageMap.
    4702  *
    4703  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    4704  * @param   GCPhysMem           The physical address.
    4705  * @param   fAccess             The intended access.
    4706  * @param   pvMem               What iemMemPageMap returned.
    4707  * @param   pLock               The PGM lock.
    4708  */
    4709 DECLINLINE(void) iemMemPageUnmap(PVMCPUCC pVCpu, RTGCPHYS GCPhysMem, uint32_t fAccess,
    4710                                  const void *pvMem, PPGMPAGEMAPLOCK pLock) RT_NOEXCEPT
    4711 {
    4712     NOREF(pVCpu);
    4713     NOREF(GCPhysMem);
    4714     NOREF(fAccess);
    4715     NOREF(pvMem);
    4716     PGMPhysReleasePageMappingLock(pVCpu->CTX_SUFF(pVM), pLock);
    4717 }
    4718138
    4719139#ifdef IEM_WITH_SETJMP
     
    4879299
    4880300/*
    4881  * Unmap helpers.
    4882  */
    4883 
    4884 #ifdef IEM_WITH_SETJMP
    4885 
    4886 DECL_INLINE_THROW(void) iemMemCommitAndUnmapRwJmp(PVMCPUCC pVCpu, uint8_t bMapInfo) IEM_NOEXCEPT_MAY_LONGJMP
    4887 {
    4888 # if defined(IEM_WITH_DATA_TLB) && defined(IN_RING3)
    4889     if (RT_LIKELY(bMapInfo == 0))
    4890         return;
    4891 # endif
    4892     iemMemCommitAndUnmapRwSafeJmp(pVCpu, bMapInfo);
    4893 }
    4894 
    4895 
    4896 DECL_INLINE_THROW(void) iemMemCommitAndUnmapAtJmp(PVMCPUCC pVCpu, uint8_t bMapInfo) IEM_NOEXCEPT_MAY_LONGJMP
    4897 {
    4898 # if defined(IEM_WITH_DATA_TLB) && defined(IN_RING3)
    4899     if (RT_LIKELY(bMapInfo == 0))
    4900         return;
    4901 # endif
    4902     iemMemCommitAndUnmapAtSafeJmp(pVCpu, bMapInfo);
    4903 }
    4904 
    4905 
    4906 DECL_INLINE_THROW(void) iemMemCommitAndUnmapWoJmp(PVMCPUCC pVCpu, uint8_t bMapInfo) IEM_NOEXCEPT_MAY_LONGJMP
    4907 {
    4908 # if defined(IEM_WITH_DATA_TLB) && defined(IN_RING3)
    4909     if (RT_LIKELY(bMapInfo == 0))
    4910         return;
    4911 # endif
    4912     iemMemCommitAndUnmapWoSafeJmp(pVCpu, bMapInfo);
    4913 }
    4914 
    4915 
    4916 DECL_INLINE_THROW(void) iemMemCommitAndUnmapRoJmp(PVMCPUCC pVCpu, uint8_t bMapInfo) IEM_NOEXCEPT_MAY_LONGJMP
    4917 {
    4918 # if defined(IEM_WITH_DATA_TLB) && defined(IN_RING3)
    4919     if (RT_LIKELY(bMapInfo == 0))
    4920         return;
    4921 # endif
    4922     iemMemCommitAndUnmapRoSafeJmp(pVCpu, bMapInfo);
    4923 }
    4924 
    4925 DECLINLINE(void) iemMemRollbackAndUnmapWo(PVMCPUCC pVCpu, uint8_t bMapInfo) RT_NOEXCEPT
    4926 {
    4927 # if defined(IEM_WITH_DATA_TLB) && defined(IN_RING3)
    4928     if (RT_LIKELY(bMapInfo == 0))
    4929         return;
    4930 # endif
    4931     iemMemRollbackAndUnmapWoSafe(pVCpu, bMapInfo);
    4932 }
    4933 
    4934 #endif /* IEM_WITH_SETJMP */
    4935 
    4936 
    4937 /*
    4938301 * Instantiate R/W inline templates.
    4939302 */
     
    5101464/** @} */
    5102465
    5103 
    5104 #ifdef VBOX_WITH_NESTED_HWVIRT_VMX
    5105 
    5106 /**
    5107  * Gets CR0 fixed-0 bits in VMX operation.
    5108  *
    5109  * We do this rather than fetching what we report to the guest (in
    5110  * IA32_VMX_CR0_FIXED0 MSR) because real hardware (and so do we) report the same
    5111  * values regardless of whether unrestricted-guest feature is available on the CPU.
    5112  *
    5113  * @returns CR0 fixed-0 bits.
    5114  * @param   pVCpu               The cross context virtual CPU structure.
    5115  * @param   fVmxNonRootMode     Whether the CR0 fixed-0 bits for VMX non-root mode
    5116  *                              must be returned. When @c false, the CR0 fixed-0
    5117  *                              bits for VMX root mode is returned.
    5118  *
    5119  */
    5120 DECLINLINE(uint64_t) iemVmxGetCr0Fixed0(PCVMCPUCC pVCpu, bool fVmxNonRootMode) RT_NOEXCEPT
    5121 {
    5122     Assert(IEM_VMX_IS_ROOT_MODE(pVCpu));
    5123 
    5124     PCVMXMSRS  pMsrs = &pVCpu->cpum.GstCtx.hwvirt.vmx.Msrs;
    5125     if (    fVmxNonRootMode
    5126         && (pMsrs->ProcCtls2.n.allowed1 & VMX_PROC_CTLS2_UNRESTRICTED_GUEST))
    5127         return VMX_V_CR0_FIXED0_UX;
    5128     return VMX_V_CR0_FIXED0;
    5129 }
    5130 
    5131 
    5132 # ifdef XAPIC_OFF_END /* Requires VBox/apic.h to be included before IEMInline.h. */
    5133 /**
    5134  * Sets virtual-APIC write emulation as pending.
    5135  *
    5136  * @param   pVCpu       The cross context virtual CPU structure.
    5137  * @param   offApic     The offset in the virtual-APIC page that was written.
    5138  */
    5139 DECLINLINE(void) iemVmxVirtApicSetPendingWrite(PVMCPUCC pVCpu, uint16_t offApic) RT_NOEXCEPT
    5140 {
    5141     Assert(offApic < XAPIC_OFF_END + 4);
    5142 
    5143     /*
    5144      * Record the currently updated APIC offset, as we need this later for figuring
    5145      * out whether to perform TPR, EOI or self-IPI virtualization as well as well
    5146      * as for supplying the exit qualification when causing an APIC-write VM-exit.
    5147      */
    5148     pVCpu->cpum.GstCtx.hwvirt.vmx.offVirtApicWrite = offApic;
    5149 
    5150     /*
    5151      * Flag that we need to perform virtual-APIC write emulation (TPR/PPR/EOI/Self-IPI
    5152      * virtualization or APIC-write emulation).
    5153      */
    5154     if (!VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_VMX_APIC_WRITE))
    5155         VMCPU_FF_SET(pVCpu, VMCPU_FF_VMX_APIC_WRITE);
    5156 }
    5157 # endif /* XAPIC_OFF_END */
    5158 
    5159 #endif /* VBOX_WITH_NESTED_HWVIRT_VMX */
    5160 
    5161 #if defined(IEM_WITH_TLB_TRACE) && defined(IN_RING3)
    5162 /**
    5163  * Adds an entry to the TLB trace buffer.
    5164  *
    5165  * @note Don't use directly, only via the IEMTLBTRACE_XXX macros.
    5166  */
    5167 DECLINLINE(void) iemTlbTrace(PVMCPU pVCpu, IEMTLBTRACETYPE enmType, uint64_t u64Param, uint64_t u64Param2 = 0,
    5168                              uint8_t bParam = 0, uint32_t u32Param = 0/*, uint16_t u16Param = 0 */)
    5169 {
    5170     uint32_t const          fMask  = RT_BIT_32(pVCpu->iem.s.cTlbTraceEntriesShift) - 1;
    5171     PIEMTLBTRACEENTRY const pEntry = &pVCpu->iem.s.paTlbTraceEntries[pVCpu->iem.s.idxTlbTraceEntry++ & fMask];
    5172     pEntry->u64Param  = u64Param;
    5173     pEntry->u64Param2 = u64Param2;
    5174     pEntry->u16Param  = 0; //u16Param;
    5175     pEntry->u32Param  = u32Param;
    5176     pEntry->bParam    = bParam;
    5177     pEntry->enmType   = enmType;
    5178     pEntry->rip       = pVCpu->cpum.GstCtx.rip + pVCpu->cpum.GstCtx.cs.u64Base;
    5179 }
    5180 #endif
    5181 
    5182 #endif /* !VMM_INCLUDED_SRC_include_IEMInline_h */
     466#endif /* !VMM_INCLUDED_SRC_VMMAll_target_x86_IEMInlineMem_x86_h */
  • trunk/src/VBox/VMM/VMMR3/IEMR3.cpp

    r108186 r108260  
    6161# include "IEMThreadedFunctions.h"
    6262# include "IEMInline.h"
     63# ifdef VBOX_VMM_TARGET_X86
     64#  include "VMMAll/target-x86/IEMInline-x86.h"
     65# endif
    6366#endif
    6467
  • trunk/src/VBox/VMM/include/IEMInline.h

    r108246 r108260  
    11/* $Id$ */
    22/** @file
    3  * IEM - Interpreted Execution Manager - Inlined Functions.
     3 * IEM - Interpreted Execution Manager - Inlined Functions, Common.
    44 */
    55
     
    3333
    3434#include <VBox/err.h>
     35
     36
     37/* Documentation and forward declarations for target specific inline functions: */
     38
     39/**
     40 * Calculates the the IEM_F_XXX flags.
     41 *
     42 * @returns IEM_F_XXX combination match the current CPU state.
     43 * @param   pVCpu               The cross context virtual CPU structure of the
     44 *                              calling thread.
     45 */
     46DECL_FORCE_INLINE(uint32_t) iemCalcExecFlags(PVMCPUCC pVCpu) RT_NOEXCEPT;
     47
     48#if defined(VBOX_STRICT) || defined(DOXYGEN_RUNNING)
     49/**
     50 * Invalidates the decoder state and asserts various stuff - strict builds only.
     51 *
     52 * @param   pVCpu               The cross context virtual CPU structure of the
     53 *                              calling thread.
     54 */
     55DECLINLINE(void)            iemInitExecTargetStrict(PVMCPUCC pVCpu) RT_NOEXCEPT;
     56#endif
     57
    3558
    3659
     
    172195
    173196
    174 /**
    175  * Calculates the IEM_F_X86_AC flags.
    176  *
    177  * @returns IEM_F_X86_AC or zero
    178  * @param   pVCpu               The cross context virtual CPU structure of the
    179  *                              calling thread.
    180  */
    181 DECL_FORCE_INLINE(uint32_t) iemCalcExecAcFlag(PVMCPUCC pVCpu) RT_NOEXCEPT
    182 {
    183     IEM_CTX_ASSERT(pVCpu, CPUMCTX_EXTRN_CR0 | CPUMCTX_EXTRN_RFLAGS);
    184     Assert(CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pVCpu, &pVCpu->cpum.GstCtx.ss));
    185 
    186     if (   !pVCpu->cpum.GstCtx.eflags.Bits.u1AC
    187         || (pVCpu->cpum.GstCtx.cr0 & (X86_CR0_AM | X86_CR0_PE)) != (X86_CR0_AM | X86_CR0_PE)
    188         || (   !pVCpu->cpum.GstCtx.eflags.Bits.u1VM
    189             && pVCpu->cpum.GstCtx.ss.Attr.n.u2Dpl != 3))
    190         return 0;
    191     return IEM_F_X86_AC;
    192 }
    193 
    194 
    195 /**
    196  * Calculates the IEM_F_MODE_X86_32BIT_FLAT flag.
    197  *
    198  * Checks if CS, SS, DS and SS are all wide open flat 32-bit segments. This will
    199  * reject expand down data segments and conforming code segments.
    200  *
    201  * ASSUMES that the CPU is in 32-bit mode.
    202  *
    203  * @note    Will return zero when if any of the segment register state is marked
    204  *          external, this must be factored into assertions checking fExec
    205  *          consistency.
    206  *
    207  * @returns IEM_F_MODE_X86_32BIT_FLAT or zero.
    208  * @param   pVCpu               The cross context virtual CPU structure of the
    209  *                              calling thread.
    210  * @sa      iemCalc32BitFlatIndicatorEsDs
    211  */
    212 DECL_FORCE_INLINE(uint32_t) iemCalc32BitFlatIndicator(PVMCPUCC pVCpu) RT_NOEXCEPT
    213 {
    214     AssertCompile(X86_SEL_TYPE_DOWN == X86_SEL_TYPE_CONF);
    215     return (  (    pVCpu->cpum.GstCtx.es.Attr.u
    216                  | pVCpu->cpum.GstCtx.cs.Attr.u
    217                  | pVCpu->cpum.GstCtx.ss.Attr.u
    218                  | pVCpu->cpum.GstCtx.ds.Attr.u)
    219               & (X86_SEL_TYPE_ACCESSED | X86DESCATTR_G | X86DESCATTR_D | X86DESCATTR_P | X86_SEL_TYPE_DOWN | X86DESCATTR_UNUSABLE))
    220            ==   (X86_SEL_TYPE_ACCESSED | X86DESCATTR_G | X86DESCATTR_D | X86DESCATTR_P)
    221         &&    (  (pVCpu->cpum.GstCtx.es.u32Limit + 1)
    222                | (pVCpu->cpum.GstCtx.cs.u32Limit + 1)
    223                | (pVCpu->cpum.GstCtx.ss.u32Limit + 1)
    224                | (pVCpu->cpum.GstCtx.ds.u32Limit + 1))
    225            == 0
    226         &&    (  pVCpu->cpum.GstCtx.es.u64Base
    227                | pVCpu->cpum.GstCtx.cs.u64Base
    228                | pVCpu->cpum.GstCtx.ss.u64Base
    229                | pVCpu->cpum.GstCtx.ds.u64Base)
    230            == 0
    231         && !(pVCpu->cpum.GstCtx.fExtrn & (CPUMCTX_EXTRN_ES | CPUMCTX_EXTRN_CS | CPUMCTX_EXTRN_SS | CPUMCTX_EXTRN_ES))
    232         ? IEM_F_MODE_X86_32BIT_FLAT : 0;
    233 }
    234 
    235 
    236 /**
    237  * Calculates the IEM_F_MODE_X86_32BIT_FLAT flag, ASSUMING the CS and SS are
    238  * flat already.
    239  *
    240  * This is used by sysenter.
    241  *
    242  * @note    Will return zero when if any of the segment register state is marked
    243  *          external, this must be factored into assertions checking fExec
    244  *          consistency.
    245  *
    246  * @returns IEM_F_MODE_X86_32BIT_FLAT or zero.
    247  * @param   pVCpu               The cross context virtual CPU structure of the
    248  *                              calling thread.
    249  * @sa      iemCalc32BitFlatIndicator
    250  */
    251 DECL_FORCE_INLINE(uint32_t) iemCalc32BitFlatIndicatorEsDs(PVMCPUCC pVCpu) RT_NOEXCEPT
    252 {
    253     AssertCompile(X86_SEL_TYPE_DOWN == X86_SEL_TYPE_CONF);
    254     return (  (    pVCpu->cpum.GstCtx.es.Attr.u
    255                  | pVCpu->cpum.GstCtx.ds.Attr.u)
    256               & (X86_SEL_TYPE_ACCESSED | X86DESCATTR_G | X86DESCATTR_D | X86DESCATTR_P | X86_SEL_TYPE_DOWN | X86DESCATTR_UNUSABLE))
    257            ==   (X86_SEL_TYPE_ACCESSED | X86DESCATTR_G | X86DESCATTR_D | X86DESCATTR_P)
    258         &&    (  (pVCpu->cpum.GstCtx.es.u32Limit + 1)
    259                | (pVCpu->cpum.GstCtx.ds.u32Limit + 1))
    260            == 0
    261         &&    (  pVCpu->cpum.GstCtx.es.u64Base
    262                | pVCpu->cpum.GstCtx.ds.u64Base)
    263            == 0
    264         && !(pVCpu->cpum.GstCtx.fExtrn & (CPUMCTX_EXTRN_ES | CPUMCTX_EXTRN_CS | CPUMCTX_EXTRN_SS | CPUMCTX_EXTRN_ES))
    265         ? IEM_F_MODE_X86_32BIT_FLAT : 0;
    266 }
    267 
    268 
    269 /**
    270  * Calculates the IEM_F_MODE_XXX, CPL and AC flags.
    271  *
    272  * @returns IEM_F_MODE_XXX, IEM_F_X86_CPL_MASK and IEM_F_X86_AC.
    273  * @param   pVCpu               The cross context virtual CPU structure of the
    274  *                              calling thread.
    275  */
    276 DECL_FORCE_INLINE(uint32_t) iemCalcExecModeAndCplFlags(PVMCPUCC pVCpu) RT_NOEXCEPT
    277 {
    278     /*
    279      * We're duplicates code from CPUMGetGuestCPL and CPUMIsGuestIn64BitCodeEx
    280      * here to try get this done as efficiently as possible.
    281      */
    282     IEM_CTX_ASSERT(pVCpu, CPUMCTX_EXTRN_CR0 | CPUMCTX_EXTRN_EFER | CPUMCTX_EXTRN_RFLAGS | CPUMCTX_EXTRN_SS | CPUMCTX_EXTRN_CS);
    283 
    284     if (pVCpu->cpum.GstCtx.cr0 & X86_CR0_PE)
    285     {
    286         if (!pVCpu->cpum.GstCtx.eflags.Bits.u1VM)
    287         {
    288             Assert(CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pVCpu, &pVCpu->cpum.GstCtx.ss));
    289             uint32_t fExec = ((uint32_t)pVCpu->cpum.GstCtx.ss.Attr.n.u2Dpl << IEM_F_X86_CPL_SHIFT);
    290             if (   !pVCpu->cpum.GstCtx.eflags.Bits.u1AC
    291                 || !(pVCpu->cpum.GstCtx.cr0 & X86_CR0_AM)
    292                 || fExec != (3U << IEM_F_X86_CPL_SHIFT))
    293             { /* likely */ }
    294             else
    295                 fExec |= IEM_F_X86_AC;
    296 
    297             if (pVCpu->cpum.GstCtx.cs.Attr.n.u1DefBig)
    298             {
    299                 Assert(!pVCpu->cpum.GstCtx.cs.Attr.n.u1Long || !(pVCpu->cpum.GstCtx.msrEFER & MSR_K6_EFER_LMA));
    300                 fExec |= IEM_F_MODE_X86_32BIT_PROT | iemCalc32BitFlatIndicator(pVCpu);
    301             }
    302             else if (   pVCpu->cpum.GstCtx.cs.Attr.n.u1Long
    303                      && (pVCpu->cpum.GstCtx.msrEFER & MSR_K6_EFER_LMA))
    304                 fExec |= IEM_F_MODE_X86_64BIT;
    305             else if (IEM_GET_TARGET_CPU(pVCpu) >= IEMTARGETCPU_386)
    306                 fExec |= IEM_F_MODE_X86_16BIT_PROT;
    307             else
    308                 fExec |= IEM_F_MODE_X86_16BIT_PROT_PRE_386;
    309             return fExec;
    310         }
    311         if (   !pVCpu->cpum.GstCtx.eflags.Bits.u1AC
    312             || !(pVCpu->cpum.GstCtx.cr0 & X86_CR0_AM))
    313             return IEM_F_MODE_X86_16BIT_PROT_V86 | (UINT32_C(3) << IEM_F_X86_CPL_SHIFT);
    314         return IEM_F_MODE_X86_16BIT_PROT_V86 | (UINT32_C(3) << IEM_F_X86_CPL_SHIFT) | IEM_F_X86_AC;
    315     }
    316 
    317     /* Real mode is zero; CPL set to 3 for VT-x real-mode emulation. */
    318     if (RT_LIKELY(!pVCpu->cpum.GstCtx.cs.Attr.n.u1DefBig))
    319     {
    320         if (IEM_GET_TARGET_CPU(pVCpu) >= IEMTARGETCPU_386)
    321             return IEM_F_MODE_X86_16BIT;
    322         return IEM_F_MODE_X86_16BIT_PRE_386;
    323     }
    324 
    325     /* 32-bit unreal mode. */
    326     return IEM_F_MODE_X86_32BIT | iemCalc32BitFlatIndicator(pVCpu);
    327 }
    328 
    329 
    330 /**
    331  * Calculates the AMD-V and VT-x related context flags.
    332  *
    333  * @returns 0 or a combination of IEM_F_X86_CTX_IN_GUEST, IEM_F_X86_CTX_SVM and
    334  *          IEM_F_X86_CTX_VMX.
    335  * @param   pVCpu               The cross context virtual CPU structure of the
    336  *                              calling thread.
    337  */
    338 DECL_FORCE_INLINE(uint32_t) iemCalcExecHwVirtFlags(PVMCPUCC pVCpu) RT_NOEXCEPT
    339 {
    340     /*
    341      * This duplicates code from CPUMIsGuestVmxEnabled, CPUMIsGuestSvmEnabled
    342      * and CPUMIsGuestInNestedHwvirtMode to some extent.
    343      */
    344     IEM_CTX_ASSERT(pVCpu, CPUMCTX_EXTRN_CR4 | CPUMCTX_EXTRN_EFER);
    345 
    346     AssertCompile(X86_CR4_VMXE != MSR_K6_EFER_SVME);
    347     uint64_t const fTmp = (pVCpu->cpum.GstCtx.cr4     & X86_CR4_VMXE)
    348                         | (pVCpu->cpum.GstCtx.msrEFER & MSR_K6_EFER_SVME);
    349     if (RT_LIKELY(!fTmp))
    350         return 0; /* likely */
    351 
    352     if (fTmp & X86_CR4_VMXE)
    353     {
    354         Assert(pVCpu->cpum.GstCtx.hwvirt.enmHwvirt == CPUMHWVIRT_VMX);
    355         if (pVCpu->cpum.GstCtx.hwvirt.vmx.fInVmxNonRootMode)
    356             return IEM_F_X86_CTX_VMX | IEM_F_X86_CTX_IN_GUEST;
    357         return IEM_F_X86_CTX_VMX;
    358     }
    359 
    360     Assert(pVCpu->cpum.GstCtx.hwvirt.enmHwvirt == CPUMHWVIRT_SVM);
    361     if (pVCpu->cpum.GstCtx.hwvirt.svm.Vmcb.ctrl.u64InterceptCtrl & SVM_CTRL_INTERCEPT_VMRUN)
    362         return IEM_F_X86_CTX_SVM | IEM_F_X86_CTX_IN_GUEST;
    363     return IEM_F_X86_CTX_SVM;
    364 }
    365 
    366 #ifdef VBOX_INCLUDED_vmm_dbgf_h /* VM::dbgf.ro.cEnabledHwBreakpoints is only accessible if VBox/vmm/dbgf.h is included. */
    367 
    368 /**
    369  * Calculates IEM_F_BRK_PENDING_XXX (IEM_F_PENDING_BRK_MASK) flags.
    370  *
    371  * @returns IEM_F_BRK_PENDING_XXX or zero.
    372  * @param   pVCpu               The cross context virtual CPU structure of the
    373  *                              calling thread.
    374  */
    375 DECL_FORCE_INLINE(uint32_t) iemCalcExecDbgFlags(PVMCPUCC pVCpu) RT_NOEXCEPT
    376 {
    377     IEM_CTX_ASSERT(pVCpu, CPUMCTX_EXTRN_DR7);
    378 
    379     if (RT_LIKELY(   !(pVCpu->cpum.GstCtx.dr[7] & X86_DR7_ENABLED_MASK)
    380                   && pVCpu->CTX_SUFF(pVM)->dbgf.ro.cEnabledHwBreakpoints == 0))
    381         return 0;
    382     return iemCalcExecDbgFlagsSlow(pVCpu);
    383 }
    384 
    385 /**
    386  * Calculates the the IEM_F_XXX flags.
    387  *
    388  * @returns IEM_F_XXX combination match the current CPU state.
    389  * @param   pVCpu               The cross context virtual CPU structure of the
    390  *                              calling thread.
    391  */
    392 DECL_FORCE_INLINE(uint32_t) iemCalcExecFlags(PVMCPUCC pVCpu) RT_NOEXCEPT
    393 {
    394     return iemCalcExecModeAndCplFlags(pVCpu)
    395          | iemCalcExecHwVirtFlags(pVCpu)
    396          /* SMM is not yet implemented */
    397          | iemCalcExecDbgFlags(pVCpu)
    398          ;
    399 }
    400 
    401 
    402 /**
    403  * Re-calculates the MODE and CPL parts of IEMCPU::fExec.
    404  *
    405  * @param   pVCpu               The cross context virtual CPU structure of the
    406  *                              calling thread.
    407  */
    408 DECL_FORCE_INLINE(void) iemRecalcExecModeAndCplAndAcFlags(PVMCPUCC pVCpu)
    409 {
    410     pVCpu->iem.s.fExec = (pVCpu->iem.s.fExec & ~(IEM_F_MODE_MASK | IEM_F_X86_CPL_MASK | IEM_F_X86_AC))
    411                        | iemCalcExecModeAndCplFlags(pVCpu);
    412 }
    413 
    414 
    415 /**
    416  * Re-calculates the IEM_F_PENDING_BRK_MASK part of IEMCPU::fExec.
    417  *
    418  * @param   pVCpu               The cross context virtual CPU structure of the
    419  *                              calling thread.
    420  */
    421 DECL_FORCE_INLINE(void) iemRecalcExecDbgFlags(PVMCPUCC pVCpu)
    422 {
    423     pVCpu->iem.s.fExec = (pVCpu->iem.s.fExec & ~IEM_F_PENDING_BRK_MASK)
    424                        | iemCalcExecDbgFlags(pVCpu);
    425 }
    426 
    427 #endif /* VBOX_INCLUDED_vmm_dbgf_h */
    428 
    429 
    430197#ifndef IEM_WITH_OPAQUE_DECODER_STATE
    431198
     
    448215    IEM_CTX_ASSERT(pVCpu, IEM_CPUMCTX_EXTRN_EXEC_DECODED_NO_MEM_MASK);
    449216    Assert(!VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_IEM));
    450     Assert(CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pVCpu, &pVCpu->cpum.GstCtx.cs));
    451     Assert(CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pVCpu, &pVCpu->cpum.GstCtx.ss));
    452     Assert(CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pVCpu, &pVCpu->cpum.GstCtx.es));
    453     Assert(CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pVCpu, &pVCpu->cpum.GstCtx.ds));
    454     Assert(CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pVCpu, &pVCpu->cpum.GstCtx.fs));
    455     Assert(CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pVCpu, &pVCpu->cpum.GstCtx.gs));
    456     Assert(CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pVCpu, &pVCpu->cpum.GstCtx.ldtr));
    457     Assert(CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pVCpu, &pVCpu->cpum.GstCtx.tr));
    458217
    459218    pVCpu->iem.s.rcPassUp           = VINF_SUCCESS;
     
    463222
    464223#  ifdef VBOX_STRICT
    465     pVCpu->iem.s.enmDefAddrMode     = (IEMMODE)0xfe;
    466     pVCpu->iem.s.enmEffAddrMode     = (IEMMODE)0xfe;
    467     pVCpu->iem.s.enmDefOpSize       = (IEMMODE)0xfe;
    468     pVCpu->iem.s.enmEffOpSize       = (IEMMODE)0xfe;
    469     pVCpu->iem.s.fPrefixes          = 0xfeedbeef;
    470     pVCpu->iem.s.uRexReg            = 127;
    471     pVCpu->iem.s.uRexB              = 127;
    472     pVCpu->iem.s.offModRm           = 127;
    473     pVCpu->iem.s.uRexIndex          = 127;
    474     pVCpu->iem.s.iEffSeg            = 127;
    475     pVCpu->iem.s.idxPrefix          = 127;
    476     pVCpu->iem.s.uVex3rdReg         = 127;
    477     pVCpu->iem.s.uVexLength         = 127;
    478     pVCpu->iem.s.fEvexStuff         = 127;
    479     pVCpu->iem.s.uFpuOpcode         = UINT16_MAX;
    480 #   ifdef IEM_WITH_CODE_TLB
    481     pVCpu->iem.s.offInstrNextByte   = UINT16_MAX;
    482     pVCpu->iem.s.pbInstrBuf         = NULL;
    483     pVCpu->iem.s.cbInstrBuf         = UINT16_MAX;
    484     pVCpu->iem.s.cbInstrBufTotal    = UINT16_MAX;
    485     pVCpu->iem.s.offCurInstrStart   = INT16_MAX;
    486     pVCpu->iem.s.uInstrBufPc        = UINT64_C(0xc0ffc0ffcff0c0ff);
    487 #    ifdef IEM_WITH_CODE_TLB_AND_OPCODE_BUF
    488     pVCpu->iem.s.offOpcode          = 127;
    489 #    endif
    490 #   else
    491     pVCpu->iem.s.offOpcode          = 127;
    492     pVCpu->iem.s.cbOpcode           = 127;
    493 #   endif
    494 #  endif /* VBOX_STRICT */
     224    iemInitExecTargetStrict(pVCpu);
     225#  endif
    495226}
    496227
     
    552283}
    553284
    554 
    555 /**
    556  * Macro used by the IEMExec* method to check the given instruction length.
    557  *
    558  * Will return on failure!
    559  *
    560  * @param   a_cbInstr   The given instruction length.
    561  * @param   a_cbMin     The minimum length.
    562  */
    563 # define IEMEXEC_ASSERT_INSTR_LEN_RETURN(a_cbInstr, a_cbMin) \
    564     AssertMsgReturn((unsigned)(a_cbInstr) - (unsigned)(a_cbMin) <= (unsigned)15 - (unsigned)(a_cbMin), \
    565                     ("cbInstr=%u cbMin=%u\n", (a_cbInstr), (a_cbMin)), VERR_IEM_INVALID_INSTR_LENGTH)
    566 
    567 
    568 # ifndef IEM_WITH_SETJMP
    569 
    570 /**
    571  * Fetches the first opcode byte.
    572  *
    573  * @returns Strict VBox status code.
    574  * @param   pVCpu               The cross context virtual CPU structure of the
    575  *                              calling thread.
    576  * @param   pu8                 Where to return the opcode byte.
    577  */
    578 DECLINLINE(VBOXSTRICTRC) iemOpcodeGetFirstU8(PVMCPUCC pVCpu, uint8_t *pu8) RT_NOEXCEPT
    579 {
    580     /*
    581      * Check for hardware instruction breakpoints.
    582      * Note! Guest breakpoints are only checked after POP SS or MOV SS on AMD CPUs.
    583      */
    584     if (RT_LIKELY(!(pVCpu->iem.s.fExec & IEM_F_PENDING_BRK_INSTR)))
    585     { /* likely */ }
    586     else
    587     {
    588         VBOXSTRICTRC rcStrict = DBGFBpCheckInstruction(pVCpu->CTX_SUFF(pVM), pVCpu,
    589                                                        pVCpu->cpum.GstCtx.rip + pVCpu->cpum.GstCtx.cs.u64Base,
    590                                                           !(pVCpu->cpum.GstCtx.rflags.uBoth & CPUMCTX_INHIBIT_SHADOW_SS)
    591                                                        || IEM_IS_GUEST_CPU_AMD(pVCpu));
    592         if (RT_LIKELY(rcStrict == VINF_SUCCESS))
    593         { /* likely */ }
    594         else
    595         {
    596             *pu8 = 0xff; /* shut up gcc. sigh */
    597             if (rcStrict == VINF_EM_RAW_GUEST_TRAP)
    598                 return iemRaiseDebugException(pVCpu);
    599             return rcStrict;
    600         }
    601     }
    602 
    603     /*
    604      * Fetch the first opcode byte.
    605      */
    606     uintptr_t const offOpcode = pVCpu->iem.s.offOpcode;
    607     if (RT_LIKELY((uint8_t)offOpcode < pVCpu->iem.s.cbOpcode))
    608     {
    609         pVCpu->iem.s.offOpcode = (uint8_t)offOpcode + 1;
    610         *pu8 = pVCpu->iem.s.abOpcode[offOpcode];
    611         return VINF_SUCCESS;
    612     }
    613     return iemOpcodeGetNextU8Slow(pVCpu, pu8);
    614 }
    615 
    616 # else  /* IEM_WITH_SETJMP */
    617 
    618 /**
    619  * Fetches the first opcode byte, longjmp on error.
    620  *
    621  * @returns The opcode byte.
    622  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    623  */
    624 DECL_INLINE_THROW(uint8_t) iemOpcodeGetFirstU8Jmp(PVMCPUCC pVCpu) IEM_NOEXCEPT_MAY_LONGJMP
    625 {
    626     /*
    627      * Check for hardware instruction breakpoints.
    628     * Note! Guest breakpoints are only checked after POP SS or MOV SS on AMD CPUs.
    629      */
    630     if (RT_LIKELY(!(pVCpu->iem.s.fExec & IEM_F_PENDING_BRK_INSTR)))
    631     { /* likely */ }
    632     else
    633     {
    634         VBOXSTRICTRC rcStrict = DBGFBpCheckInstruction(pVCpu->CTX_SUFF(pVM), pVCpu,
    635                                                        pVCpu->cpum.GstCtx.rip + pVCpu->cpum.GstCtx.cs.u64Base,
    636                                                           !(pVCpu->cpum.GstCtx.rflags.uBoth & CPUMCTX_INHIBIT_SHADOW_SS)
    637                                                        || IEM_IS_GUEST_CPU_AMD(pVCpu));
    638         if (RT_LIKELY(rcStrict == VINF_SUCCESS))
    639         { /* likely */ }
    640         else
    641         {
    642             if (rcStrict == VINF_EM_RAW_GUEST_TRAP)
    643                 rcStrict = iemRaiseDebugException(pVCpu);
    644             IEM_DO_LONGJMP(pVCpu, VBOXSTRICTRC_VAL(rcStrict));
    645         }
    646     }
    647 
    648     /*
    649      * Fetch the first opcode byte.
    650      */
    651 #  ifdef IEM_WITH_CODE_TLB
    652     uint8_t         bRet;
    653     uintptr_t       offBuf = pVCpu->iem.s.offInstrNextByte;
    654     uint8_t const  *pbBuf  = pVCpu->iem.s.pbInstrBuf;
    655     if (RT_LIKELY(   pbBuf != NULL
    656                   && offBuf < pVCpu->iem.s.cbInstrBuf))
    657     {
    658         pVCpu->iem.s.offInstrNextByte = (uint32_t)offBuf + 1;
    659         bRet = pbBuf[offBuf];
    660     }
    661     else
    662         bRet = iemOpcodeGetNextU8SlowJmp(pVCpu);
    663 #   ifdef IEM_WITH_CODE_TLB_AND_OPCODE_BUF
    664     Assert(pVCpu->iem.s.offOpcode == 0);
    665     pVCpu->iem.s.abOpcode[pVCpu->iem.s.offOpcode++] = bRet;
    666 #   endif
    667     return bRet;
    668 
    669 #  else /* !IEM_WITH_CODE_TLB */
    670     uintptr_t offOpcode = pVCpu->iem.s.offOpcode;
    671     if (RT_LIKELY((uint8_t)offOpcode < pVCpu->iem.s.cbOpcode))
    672     {
    673         pVCpu->iem.s.offOpcode = (uint8_t)offOpcode + 1;
    674         return pVCpu->iem.s.abOpcode[offOpcode];
    675     }
    676     return iemOpcodeGetNextU8SlowJmp(pVCpu);
    677 #  endif
    678 }
    679 
    680 # endif /* IEM_WITH_SETJMP */
    681 
    682 /**
    683  * Fetches the first opcode byte, returns/throws automatically on failure.
    684  *
    685  * @param   a_pu8               Where to return the opcode byte.
    686  * @remark Implicitly references pVCpu.
    687  */
    688 # ifndef IEM_WITH_SETJMP
    689 #  define IEM_OPCODE_GET_FIRST_U8(a_pu8) \
    690     do \
    691     { \
    692         VBOXSTRICTRC rcStrict2 = iemOpcodeGetFirstU8(pVCpu, (a_pu8)); \
    693         if (rcStrict2 == VINF_SUCCESS) \
    694         { /* likely */ } \
    695         else \
    696             return rcStrict2; \
    697     } while (0)
    698 # else
    699 #  define IEM_OPCODE_GET_FIRST_U8(a_pu8) (*(a_pu8) = iemOpcodeGetFirstU8Jmp(pVCpu))
    700 # endif /* IEM_WITH_SETJMP */
    701 
    702 
    703 # ifndef IEM_WITH_SETJMP
    704 
    705 /**
    706  * Fetches the next opcode byte.
    707  *
    708  * @returns Strict VBox status code.
    709  * @param   pVCpu               The cross context virtual CPU structure of the
    710  *                              calling thread.
    711  * @param   pu8                 Where to return the opcode byte.
    712  */
    713 DECLINLINE(VBOXSTRICTRC) iemOpcodeGetNextU8(PVMCPUCC pVCpu, uint8_t *pu8) RT_NOEXCEPT
    714 {
    715     uintptr_t const offOpcode = pVCpu->iem.s.offOpcode;
    716     if (RT_LIKELY((uint8_t)offOpcode < pVCpu->iem.s.cbOpcode))
    717     {
    718         pVCpu->iem.s.offOpcode = (uint8_t)offOpcode + 1;
    719         *pu8 = pVCpu->iem.s.abOpcode[offOpcode];
    720         return VINF_SUCCESS;
    721     }
    722     return iemOpcodeGetNextU8Slow(pVCpu, pu8);
    723 }
    724 
    725 # else  /* IEM_WITH_SETJMP */
    726 
    727 /**
    728  * Fetches the next opcode byte, longjmp on error.
    729  *
    730  * @returns The opcode byte.
    731  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    732  */
    733 DECL_INLINE_THROW(uint8_t) iemOpcodeGetNextU8Jmp(PVMCPUCC pVCpu) IEM_NOEXCEPT_MAY_LONGJMP
    734 {
    735 #  ifdef IEM_WITH_CODE_TLB
    736     uint8_t         bRet;
    737     uintptr_t       offBuf = pVCpu->iem.s.offInstrNextByte;
    738     uint8_t const  *pbBuf  = pVCpu->iem.s.pbInstrBuf;
    739     if (RT_LIKELY(   pbBuf != NULL
    740                   && offBuf < pVCpu->iem.s.cbInstrBuf))
    741     {
    742         pVCpu->iem.s.offInstrNextByte = (uint32_t)offBuf + 1;
    743         bRet = pbBuf[offBuf];
    744     }
    745     else
    746         bRet = iemOpcodeGetNextU8SlowJmp(pVCpu);
    747 #   ifdef IEM_WITH_CODE_TLB_AND_OPCODE_BUF
    748     Assert(pVCpu->iem.s.offOpcode < sizeof(pVCpu->iem.s.abOpcode));
    749     pVCpu->iem.s.abOpcode[pVCpu->iem.s.offOpcode++] = bRet;
    750 #   endif
    751     return bRet;
    752 
    753 #  else /* !IEM_WITH_CODE_TLB */
    754     uintptr_t offOpcode = pVCpu->iem.s.offOpcode;
    755     if (RT_LIKELY((uint8_t)offOpcode < pVCpu->iem.s.cbOpcode))
    756     {
    757         pVCpu->iem.s.offOpcode = (uint8_t)offOpcode + 1;
    758         return pVCpu->iem.s.abOpcode[offOpcode];
    759     }
    760     return iemOpcodeGetNextU8SlowJmp(pVCpu);
    761 #  endif
    762 }
    763 
    764 # endif /* IEM_WITH_SETJMP */
    765 
    766 /**
    767  * Fetches the next opcode byte, returns automatically on failure.
    768  *
    769  * @param   a_pu8               Where to return the opcode byte.
    770  * @remark Implicitly references pVCpu.
    771  */
    772 # ifndef IEM_WITH_SETJMP
    773 #  define IEM_OPCODE_GET_NEXT_U8(a_pu8) \
    774     do \
    775     { \
    776         VBOXSTRICTRC rcStrict2 = iemOpcodeGetNextU8(pVCpu, (a_pu8)); \
    777         if (rcStrict2 == VINF_SUCCESS) \
    778         { /* likely */ } \
    779         else \
    780             return rcStrict2; \
    781     } while (0)
    782 # else
    783 #  define IEM_OPCODE_GET_NEXT_U8(a_pu8) (*(a_pu8) = iemOpcodeGetNextU8Jmp(pVCpu))
    784 # endif /* IEM_WITH_SETJMP */
    785 
    786 
    787 # ifndef IEM_WITH_SETJMP
    788 /**
    789  * Fetches the next signed byte from the opcode stream.
    790  *
    791  * @returns Strict VBox status code.
    792  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    793  * @param   pi8                 Where to return the signed byte.
    794  */
    795 DECLINLINE(VBOXSTRICTRC) iemOpcodeGetNextS8(PVMCPUCC pVCpu, int8_t *pi8) RT_NOEXCEPT
    796 {
    797     return iemOpcodeGetNextU8(pVCpu, (uint8_t *)pi8);
    798 }
    799 # endif /* !IEM_WITH_SETJMP */
    800 
    801 
    802 /**
    803  * Fetches the next signed byte from the opcode stream, returning automatically
    804  * on failure.
    805  *
    806  * @param   a_pi8               Where to return the signed byte.
    807  * @remark Implicitly references pVCpu.
    808  */
    809 # ifndef IEM_WITH_SETJMP
    810 #  define IEM_OPCODE_GET_NEXT_S8(a_pi8) \
    811     do \
    812     { \
    813         VBOXSTRICTRC rcStrict2 = iemOpcodeGetNextS8(pVCpu, (a_pi8)); \
    814         if (rcStrict2 != VINF_SUCCESS) \
    815             return rcStrict2; \
    816     } while (0)
    817 # else /* IEM_WITH_SETJMP */
    818 #  define IEM_OPCODE_GET_NEXT_S8(a_pi8) (*(a_pi8) = (int8_t)iemOpcodeGetNextU8Jmp(pVCpu))
    819 
    820 # endif /* IEM_WITH_SETJMP */
    821 
    822 
    823 # ifndef IEM_WITH_SETJMP
    824 /**
    825  * Fetches the next signed byte from the opcode stream, extending it to
    826  * unsigned 16-bit.
    827  *
    828  * @returns Strict VBox status code.
    829  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    830  * @param   pu16                Where to return the unsigned word.
    831  */
    832 DECLINLINE(VBOXSTRICTRC) iemOpcodeGetNextS8SxU16(PVMCPUCC pVCpu, uint16_t *pu16) RT_NOEXCEPT
    833 {
    834     uint8_t const offOpcode = pVCpu->iem.s.offOpcode;
    835     if (RT_UNLIKELY(offOpcode >= pVCpu->iem.s.cbOpcode))
    836         return iemOpcodeGetNextS8SxU16Slow(pVCpu, pu16);
    837 
    838     *pu16 = (uint16_t)(int16_t)(int8_t)pVCpu->iem.s.abOpcode[offOpcode];
    839     pVCpu->iem.s.offOpcode = offOpcode + 1;
    840     return VINF_SUCCESS;
    841 }
    842 # endif /* !IEM_WITH_SETJMP */
    843 
    844 /**
    845  * Fetches the next signed byte from the opcode stream and sign-extending it to
    846  * a word, returning automatically on failure.
    847  *
    848  * @param   a_pu16              Where to return the word.
    849  * @remark Implicitly references pVCpu.
    850  */
    851 # ifndef IEM_WITH_SETJMP
    852 #  define IEM_OPCODE_GET_NEXT_S8_SX_U16(a_pu16) \
    853     do \
    854     { \
    855         VBOXSTRICTRC rcStrict2 = iemOpcodeGetNextS8SxU16(pVCpu, (a_pu16)); \
    856         if (rcStrict2 != VINF_SUCCESS) \
    857             return rcStrict2; \
    858     } while (0)
    859 # else
    860 #  define IEM_OPCODE_GET_NEXT_S8_SX_U16(a_pu16) (*(a_pu16) = (uint16_t)(int16_t)(int8_t)iemOpcodeGetNextU8Jmp(pVCpu))
    861 # endif
    862 
    863 # ifndef IEM_WITH_SETJMP
    864 /**
    865  * Fetches the next signed byte from the opcode stream, extending it to
    866  * unsigned 32-bit.
    867  *
    868  * @returns Strict VBox status code.
    869  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    870  * @param   pu32                Where to return the unsigned dword.
    871  */
    872 DECLINLINE(VBOXSTRICTRC) iemOpcodeGetNextS8SxU32(PVMCPUCC pVCpu, uint32_t *pu32) RT_NOEXCEPT
    873 {
    874     uint8_t const offOpcode = pVCpu->iem.s.offOpcode;
    875     if (RT_UNLIKELY(offOpcode >= pVCpu->iem.s.cbOpcode))
    876         return iemOpcodeGetNextS8SxU32Slow(pVCpu, pu32);
    877 
    878     *pu32 = (uint32_t)(int32_t)(int8_t)pVCpu->iem.s.abOpcode[offOpcode];
    879     pVCpu->iem.s.offOpcode = offOpcode + 1;
    880     return VINF_SUCCESS;
    881 }
    882 # endif /* !IEM_WITH_SETJMP */
    883 
    884 /**
    885  * Fetches the next signed byte from the opcode stream and sign-extending it to
    886  * a word, returning automatically on failure.
    887  *
    888  * @param   a_pu32              Where to return the word.
    889  * @remark Implicitly references pVCpu.
    890  */
    891 # ifndef IEM_WITH_SETJMP
    892 #  define IEM_OPCODE_GET_NEXT_S8_SX_U32(a_pu32) \
    893     do \
    894     { \
    895         VBOXSTRICTRC rcStrict2 = iemOpcodeGetNextS8SxU32(pVCpu, (a_pu32)); \
    896         if (rcStrict2 != VINF_SUCCESS) \
    897             return rcStrict2; \
    898     } while (0)
    899 # else
    900 #  define IEM_OPCODE_GET_NEXT_S8_SX_U32(a_pu32) (*(a_pu32) = (uint32_t)(int32_t)(int8_t)iemOpcodeGetNextU8Jmp(pVCpu))
    901 # endif
    902 
    903 
    904 # ifndef IEM_WITH_SETJMP
    905 /**
    906  * Fetches the next signed byte from the opcode stream, extending it to
    907  * unsigned 64-bit.
    908  *
    909  * @returns Strict VBox status code.
    910  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    911  * @param   pu64                Where to return the unsigned qword.
    912  */
    913 DECLINLINE(VBOXSTRICTRC) iemOpcodeGetNextS8SxU64(PVMCPUCC pVCpu, uint64_t *pu64) RT_NOEXCEPT
    914 {
    915     uint8_t const offOpcode = pVCpu->iem.s.offOpcode;
    916     if (RT_UNLIKELY(offOpcode >= pVCpu->iem.s.cbOpcode))
    917         return iemOpcodeGetNextS8SxU64Slow(pVCpu, pu64);
    918 
    919     *pu64 = (uint64_t)(int64_t)(int8_t)pVCpu->iem.s.abOpcode[offOpcode];
    920     pVCpu->iem.s.offOpcode = offOpcode + 1;
    921     return VINF_SUCCESS;
    922 }
    923 # endif /* !IEM_WITH_SETJMP */
    924 
    925 /**
    926  * Fetches the next signed byte from the opcode stream and sign-extending it to
    927  * a word, returning automatically on failure.
    928  *
    929  * @param   a_pu64              Where to return the word.
    930  * @remark Implicitly references pVCpu.
    931  */
    932 # ifndef IEM_WITH_SETJMP
    933 #  define IEM_OPCODE_GET_NEXT_S8_SX_U64(a_pu64) \
    934     do \
    935     { \
    936         VBOXSTRICTRC rcStrict2 = iemOpcodeGetNextS8SxU64(pVCpu, (a_pu64)); \
    937         if (rcStrict2 != VINF_SUCCESS) \
    938             return rcStrict2; \
    939     } while (0)
    940 # else
    941 #  define IEM_OPCODE_GET_NEXT_S8_SX_U64(a_pu64) (*(a_pu64) = (uint64_t)(int64_t)(int8_t)iemOpcodeGetNextU8Jmp(pVCpu))
    942 # endif
    943 
    944 
    945 # ifndef IEM_WITH_SETJMP
    946 
    947 /**
    948  * Fetches the next opcode word.
    949  *
    950  * @returns Strict VBox status code.
    951  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    952  * @param   pu16                Where to return the opcode word.
    953  */
    954 DECLINLINE(VBOXSTRICTRC) iemOpcodeGetNextU16(PVMCPUCC pVCpu, uint16_t *pu16) RT_NOEXCEPT
    955 {
    956     uintptr_t const offOpcode = pVCpu->iem.s.offOpcode;
    957     if (RT_LIKELY((uint8_t)offOpcode + 2 <= pVCpu->iem.s.cbOpcode))
    958     {
    959         pVCpu->iem.s.offOpcode = (uint8_t)offOpcode + 2;
    960 #  ifdef IEM_USE_UNALIGNED_DATA_ACCESS
    961         *pu16 = *(uint16_t const *)&pVCpu->iem.s.abOpcode[offOpcode];
    962 #  else
    963         *pu16 = RT_MAKE_U16(pVCpu->iem.s.abOpcode[offOpcode], pVCpu->iem.s.abOpcode[offOpcode + 1]);
    964 #  endif
    965         return VINF_SUCCESS;
    966     }
    967     return iemOpcodeGetNextU16Slow(pVCpu, pu16);
    968 }
    969 
    970 # else  /* IEM_WITH_SETJMP */
    971 
    972 /**
    973  * Fetches the next opcode word, longjmp on error.
    974  *
    975  * @returns The opcode word.
    976  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    977  */
    978 DECL_INLINE_THROW(uint16_t) iemOpcodeGetNextU16Jmp(PVMCPUCC pVCpu) IEM_NOEXCEPT_MAY_LONGJMP
    979 {
    980 #  ifdef IEM_WITH_CODE_TLB
    981     uint16_t        u16Ret;
    982     uintptr_t       offBuf = pVCpu->iem.s.offInstrNextByte;
    983     uint8_t const  *pbBuf  = pVCpu->iem.s.pbInstrBuf;
    984     if (RT_LIKELY(   pbBuf != NULL
    985                   && offBuf + 2 <= pVCpu->iem.s.cbInstrBuf))
    986     {
    987         pVCpu->iem.s.offInstrNextByte = (uint32_t)offBuf + 2;
    988 #   ifdef IEM_USE_UNALIGNED_DATA_ACCESS
    989         u16Ret = *(uint16_t const *)&pbBuf[offBuf];
    990 #   else
    991         u16Ret = RT_MAKE_U16(pbBuf[offBuf], pbBuf[offBuf + 1]);
    992 #   endif
    993     }
    994     else
    995         u16Ret = iemOpcodeGetNextU16SlowJmp(pVCpu);
    996 
    997 #   ifdef IEM_WITH_CODE_TLB_AND_OPCODE_BUF
    998     uintptr_t const offOpcode = pVCpu->iem.s.offOpcode;
    999     Assert(offOpcode + 1 < sizeof(pVCpu->iem.s.abOpcode));
    1000 #    ifdef IEM_USE_UNALIGNED_DATA_ACCESS
    1001     *(uint16_t *)&pVCpu->iem.s.abOpcode[offOpcode] = u16Ret;
    1002 #    else
    1003     pVCpu->iem.s.abOpcode[offOpcode]     = RT_LO_U8(u16Ret);
    1004     pVCpu->iem.s.abOpcode[offOpcode + 1] = RT_HI_U8(u16Ret);
    1005 #    endif
    1006     pVCpu->iem.s.offOpcode = (uint8_t)offOpcode + (uint8_t)2;
    1007 #   endif
    1008 
    1009     return u16Ret;
    1010 
    1011 #  else /* !IEM_WITH_CODE_TLB */
    1012     uintptr_t const offOpcode = pVCpu->iem.s.offOpcode;
    1013     if (RT_LIKELY((uint8_t)offOpcode + 2 <= pVCpu->iem.s.cbOpcode))
    1014     {
    1015         pVCpu->iem.s.offOpcode = (uint8_t)offOpcode + 2;
    1016 #   ifdef IEM_USE_UNALIGNED_DATA_ACCESS
    1017         return *(uint16_t const *)&pVCpu->iem.s.abOpcode[offOpcode];
    1018 #   else
    1019         return RT_MAKE_U16(pVCpu->iem.s.abOpcode[offOpcode], pVCpu->iem.s.abOpcode[offOpcode + 1]);
    1020 #   endif
    1021     }
    1022     return iemOpcodeGetNextU16SlowJmp(pVCpu);
    1023 #  endif /* !IEM_WITH_CODE_TLB */
    1024 }
    1025 
    1026 # endif /* IEM_WITH_SETJMP */
    1027 
    1028 /**
    1029  * Fetches the next opcode word, returns automatically on failure.
    1030  *
    1031  * @param   a_pu16              Where to return the opcode word.
    1032  * @remark Implicitly references pVCpu.
    1033  */
    1034 # ifndef IEM_WITH_SETJMP
    1035 #  define IEM_OPCODE_GET_NEXT_U16(a_pu16) \
    1036     do \
    1037     { \
    1038         VBOXSTRICTRC rcStrict2 = iemOpcodeGetNextU16(pVCpu, (a_pu16)); \
    1039         if (rcStrict2 != VINF_SUCCESS) \
    1040             return rcStrict2; \
    1041     } while (0)
    1042 # else
    1043 #  define IEM_OPCODE_GET_NEXT_U16(a_pu16) (*(a_pu16) = iemOpcodeGetNextU16Jmp(pVCpu))
    1044 # endif
    1045 
    1046 # ifndef IEM_WITH_SETJMP
    1047 /**
    1048  * Fetches the next opcode word, zero extending it to a double word.
    1049  *
    1050  * @returns Strict VBox status code.
    1051  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    1052  * @param   pu32                Where to return the opcode double word.
    1053  */
    1054 DECLINLINE(VBOXSTRICTRC) iemOpcodeGetNextU16ZxU32(PVMCPUCC pVCpu, uint32_t *pu32) RT_NOEXCEPT
    1055 {
    1056     uint8_t const offOpcode = pVCpu->iem.s.offOpcode;
    1057     if (RT_UNLIKELY(offOpcode + 2 > pVCpu->iem.s.cbOpcode))
    1058         return iemOpcodeGetNextU16ZxU32Slow(pVCpu, pu32);
    1059 
    1060     *pu32 = RT_MAKE_U16(pVCpu->iem.s.abOpcode[offOpcode], pVCpu->iem.s.abOpcode[offOpcode + 1]);
    1061     pVCpu->iem.s.offOpcode = offOpcode + 2;
    1062     return VINF_SUCCESS;
    1063 }
    1064 # endif /* !IEM_WITH_SETJMP */
    1065 
    1066 /**
    1067  * Fetches the next opcode word and zero extends it to a double word, returns
    1068  * automatically on failure.
    1069  *
    1070  * @param   a_pu32              Where to return the opcode double word.
    1071  * @remark Implicitly references pVCpu.
    1072  */
    1073 # ifndef IEM_WITH_SETJMP
    1074 #  define IEM_OPCODE_GET_NEXT_U16_ZX_U32(a_pu32) \
    1075     do \
    1076     { \
    1077         VBOXSTRICTRC rcStrict2 = iemOpcodeGetNextU16ZxU32(pVCpu, (a_pu32)); \
    1078         if (rcStrict2 != VINF_SUCCESS) \
    1079             return rcStrict2; \
    1080     } while (0)
    1081 # else
    1082 #  define IEM_OPCODE_GET_NEXT_U16_ZX_U32(a_pu32) (*(a_pu32) = iemOpcodeGetNextU16Jmp(pVCpu))
    1083 # endif
    1084 
    1085 # ifndef IEM_WITH_SETJMP
    1086 /**
    1087  * Fetches the next opcode word, zero extending it to a quad word.
    1088  *
    1089  * @returns Strict VBox status code.
    1090  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    1091  * @param   pu64                Where to return the opcode quad word.
    1092  */
    1093 DECLINLINE(VBOXSTRICTRC) iemOpcodeGetNextU16ZxU64(PVMCPUCC pVCpu, uint64_t *pu64) RT_NOEXCEPT
    1094 {
    1095     uint8_t const offOpcode = pVCpu->iem.s.offOpcode;
    1096     if (RT_UNLIKELY(offOpcode + 2 > pVCpu->iem.s.cbOpcode))
    1097         return iemOpcodeGetNextU16ZxU64Slow(pVCpu, pu64);
    1098 
    1099     *pu64 = RT_MAKE_U16(pVCpu->iem.s.abOpcode[offOpcode], pVCpu->iem.s.abOpcode[offOpcode + 1]);
    1100     pVCpu->iem.s.offOpcode = offOpcode + 2;
    1101     return VINF_SUCCESS;
    1102 }
    1103 # endif /* !IEM_WITH_SETJMP */
    1104 
    1105 /**
    1106  * Fetches the next opcode word and zero extends it to a quad word, returns
    1107  * automatically on failure.
    1108  *
    1109  * @param   a_pu64              Where to return the opcode quad word.
    1110  * @remark Implicitly references pVCpu.
    1111  */
    1112 # ifndef IEM_WITH_SETJMP
    1113 #  define IEM_OPCODE_GET_NEXT_U16_ZX_U64(a_pu64) \
    1114     do \
    1115     { \
    1116         VBOXSTRICTRC rcStrict2 = iemOpcodeGetNextU16ZxU64(pVCpu, (a_pu64)); \
    1117         if (rcStrict2 != VINF_SUCCESS) \
    1118             return rcStrict2; \
    1119     } while (0)
    1120 # else
    1121 #  define IEM_OPCODE_GET_NEXT_U16_ZX_U64(a_pu64)  (*(a_pu64) = iemOpcodeGetNextU16Jmp(pVCpu))
    1122 # endif
    1123 
    1124 
    1125 # ifndef IEM_WITH_SETJMP
    1126 /**
    1127  * Fetches the next signed word from the opcode stream.
    1128  *
    1129  * @returns Strict VBox status code.
    1130  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    1131  * @param   pi16                Where to return the signed word.
    1132  */
    1133 DECLINLINE(VBOXSTRICTRC) iemOpcodeGetNextS16(PVMCPUCC pVCpu, int16_t *pi16) RT_NOEXCEPT
    1134 {
    1135     return iemOpcodeGetNextU16(pVCpu, (uint16_t *)pi16);
    1136 }
    1137 # endif /* !IEM_WITH_SETJMP */
    1138 
    1139 
    1140 /**
    1141  * Fetches the next signed word from the opcode stream, returning automatically
    1142  * on failure.
    1143  *
    1144  * @param   a_pi16              Where to return the signed word.
    1145  * @remark Implicitly references pVCpu.
    1146  */
    1147 # ifndef IEM_WITH_SETJMP
    1148 #  define IEM_OPCODE_GET_NEXT_S16(a_pi16) \
    1149     do \
    1150     { \
    1151         VBOXSTRICTRC rcStrict2 = iemOpcodeGetNextS16(pVCpu, (a_pi16)); \
    1152         if (rcStrict2 != VINF_SUCCESS) \
    1153             return rcStrict2; \
    1154     } while (0)
    1155 # else
    1156 #  define IEM_OPCODE_GET_NEXT_S16(a_pi16) (*(a_pi16) = (int16_t)iemOpcodeGetNextU16Jmp(pVCpu))
    1157 # endif
    1158 
    1159 # ifndef IEM_WITH_SETJMP
    1160 
    1161 /**
    1162  * Fetches the next opcode dword.
    1163  *
    1164  * @returns Strict VBox status code.
    1165  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    1166  * @param   pu32                Where to return the opcode double word.
    1167  */
    1168 DECLINLINE(VBOXSTRICTRC) iemOpcodeGetNextU32(PVMCPUCC pVCpu, uint32_t *pu32) RT_NOEXCEPT
    1169 {
    1170     uintptr_t const offOpcode = pVCpu->iem.s.offOpcode;
    1171     if (RT_LIKELY((uint8_t)offOpcode + 4 <= pVCpu->iem.s.cbOpcode))
    1172     {
    1173         pVCpu->iem.s.offOpcode = (uint8_t)offOpcode + 4;
    1174 #  ifdef IEM_USE_UNALIGNED_DATA_ACCESS
    1175         *pu32 = *(uint32_t const *)&pVCpu->iem.s.abOpcode[offOpcode];
    1176 #  else
    1177         *pu32 = RT_MAKE_U32_FROM_U8(pVCpu->iem.s.abOpcode[offOpcode],
    1178                                     pVCpu->iem.s.abOpcode[offOpcode + 1],
    1179                                     pVCpu->iem.s.abOpcode[offOpcode + 2],
    1180                                     pVCpu->iem.s.abOpcode[offOpcode + 3]);
    1181 #  endif
    1182         return VINF_SUCCESS;
    1183     }
    1184     return iemOpcodeGetNextU32Slow(pVCpu, pu32);
    1185 }
    1186 
    1187 # else  /* IEM_WITH_SETJMP */
    1188 
    1189 /**
    1190  * Fetches the next opcode dword, longjmp on error.
    1191  *
    1192  * @returns The opcode dword.
    1193  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    1194  */
    1195 DECL_INLINE_THROW(uint32_t) iemOpcodeGetNextU32Jmp(PVMCPUCC pVCpu) IEM_NOEXCEPT_MAY_LONGJMP
    1196 {
    1197 #  ifdef IEM_WITH_CODE_TLB
    1198     uint32_t u32Ret;
    1199     uintptr_t       offBuf = pVCpu->iem.s.offInstrNextByte;
    1200     uint8_t const  *pbBuf  = pVCpu->iem.s.pbInstrBuf;
    1201     if (RT_LIKELY(   pbBuf != NULL
    1202                   && offBuf + 4 <= pVCpu->iem.s.cbInstrBuf))
    1203     {
    1204         pVCpu->iem.s.offInstrNextByte = (uint32_t)offBuf + 4;
    1205 #   ifdef IEM_USE_UNALIGNED_DATA_ACCESS
    1206         u32Ret = *(uint32_t const *)&pbBuf[offBuf];
    1207 #   else
    1208         u32Ret = RT_MAKE_U32_FROM_U8(pbBuf[offBuf],
    1209                                      pbBuf[offBuf + 1],
    1210                                      pbBuf[offBuf + 2],
    1211                                      pbBuf[offBuf + 3]);
    1212 #   endif
    1213     }
    1214     else
    1215         u32Ret = iemOpcodeGetNextU32SlowJmp(pVCpu);
    1216 
    1217 #   ifdef IEM_WITH_CODE_TLB_AND_OPCODE_BUF
    1218     uintptr_t const offOpcode = pVCpu->iem.s.offOpcode;
    1219     Assert(offOpcode + 3 < sizeof(pVCpu->iem.s.abOpcode));
    1220 #    ifdef IEM_USE_UNALIGNED_DATA_ACCESS
    1221     *(uint32_t *)&pVCpu->iem.s.abOpcode[offOpcode] = u32Ret;
    1222 #    else
    1223     pVCpu->iem.s.abOpcode[offOpcode]     = RT_BYTE1(u32Ret);
    1224     pVCpu->iem.s.abOpcode[offOpcode + 1] = RT_BYTE2(u32Ret);
    1225     pVCpu->iem.s.abOpcode[offOpcode + 2] = RT_BYTE3(u32Ret);
    1226     pVCpu->iem.s.abOpcode[offOpcode + 3] = RT_BYTE4(u32Ret);
    1227 #    endif
    1228     pVCpu->iem.s.offOpcode = (uint8_t)offOpcode + (uint8_t)4;
    1229 #   endif /* IEM_WITH_CODE_TLB_AND_OPCODE_BUF */
    1230 
    1231     return u32Ret;
    1232 
    1233 #  else  /* !IEM_WITH_CODE_TLB */
    1234     uintptr_t const offOpcode = pVCpu->iem.s.offOpcode;
    1235     if (RT_LIKELY((uint8_t)offOpcode + 4 <= pVCpu->iem.s.cbOpcode))
    1236     {
    1237         pVCpu->iem.s.offOpcode = (uint8_t)offOpcode + 4;
    1238 #   ifdef IEM_USE_UNALIGNED_DATA_ACCESS
    1239         return *(uint32_t const *)&pVCpu->iem.s.abOpcode[offOpcode];
    1240 #   else
    1241         return RT_MAKE_U32_FROM_U8(pVCpu->iem.s.abOpcode[offOpcode],
    1242                                    pVCpu->iem.s.abOpcode[offOpcode + 1],
    1243                                    pVCpu->iem.s.abOpcode[offOpcode + 2],
    1244                                    pVCpu->iem.s.abOpcode[offOpcode + 3]);
    1245 #   endif
    1246     }
    1247     return iemOpcodeGetNextU32SlowJmp(pVCpu);
    1248 #  endif
    1249 }
    1250 
    1251 # endif /* IEM_WITH_SETJMP */
    1252 
    1253 /**
    1254  * Fetches the next opcode dword, returns automatically on failure.
    1255  *
    1256  * @param   a_pu32              Where to return the opcode dword.
    1257  * @remark Implicitly references pVCpu.
    1258  */
    1259 # ifndef IEM_WITH_SETJMP
    1260 #  define IEM_OPCODE_GET_NEXT_U32(a_pu32) \
    1261     do \
    1262     { \
    1263         VBOXSTRICTRC rcStrict2 = iemOpcodeGetNextU32(pVCpu, (a_pu32)); \
    1264         if (rcStrict2 != VINF_SUCCESS) \
    1265             return rcStrict2; \
    1266     } while (0)
    1267 # else
    1268 #  define IEM_OPCODE_GET_NEXT_U32(a_pu32) (*(a_pu32) = iemOpcodeGetNextU32Jmp(pVCpu))
    1269 # endif
    1270 
    1271 # ifndef IEM_WITH_SETJMP
    1272 /**
    1273  * Fetches the next opcode dword, zero extending it to a quad word.
    1274  *
    1275  * @returns Strict VBox status code.
    1276  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    1277  * @param   pu64                Where to return the opcode quad word.
    1278  */
    1279 DECLINLINE(VBOXSTRICTRC) iemOpcodeGetNextU32ZxU64(PVMCPUCC pVCpu, uint64_t *pu64) RT_NOEXCEPT
    1280 {
    1281     uint8_t const offOpcode = pVCpu->iem.s.offOpcode;
    1282     if (RT_UNLIKELY(offOpcode + 4 > pVCpu->iem.s.cbOpcode))
    1283         return iemOpcodeGetNextU32ZxU64Slow(pVCpu, pu64);
    1284 
    1285     *pu64 = RT_MAKE_U32_FROM_U8(pVCpu->iem.s.abOpcode[offOpcode],
    1286                                 pVCpu->iem.s.abOpcode[offOpcode + 1],
    1287                                 pVCpu->iem.s.abOpcode[offOpcode + 2],
    1288                                 pVCpu->iem.s.abOpcode[offOpcode + 3]);
    1289     pVCpu->iem.s.offOpcode = offOpcode + 4;
    1290     return VINF_SUCCESS;
    1291 }
    1292 # endif /* !IEM_WITH_SETJMP */
    1293 
    1294 /**
    1295  * Fetches the next opcode dword and zero extends it to a quad word, returns
    1296  * automatically on failure.
    1297  *
    1298  * @param   a_pu64              Where to return the opcode quad word.
    1299  * @remark Implicitly references pVCpu.
    1300  */
    1301 # ifndef IEM_WITH_SETJMP
    1302 #  define IEM_OPCODE_GET_NEXT_U32_ZX_U64(a_pu64) \
    1303     do \
    1304     { \
    1305         VBOXSTRICTRC rcStrict2 = iemOpcodeGetNextU32ZxU64(pVCpu, (a_pu64)); \
    1306         if (rcStrict2 != VINF_SUCCESS) \
    1307             return rcStrict2; \
    1308     } while (0)
    1309 # else
    1310 #  define IEM_OPCODE_GET_NEXT_U32_ZX_U64(a_pu64) (*(a_pu64) = iemOpcodeGetNextU32Jmp(pVCpu))
    1311 # endif
    1312 
    1313 
    1314 # ifndef IEM_WITH_SETJMP
    1315 /**
    1316  * Fetches the next signed double word from the opcode stream.
    1317  *
    1318  * @returns Strict VBox status code.
    1319  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    1320  * @param   pi32                Where to return the signed double word.
    1321  */
    1322 DECLINLINE(VBOXSTRICTRC) iemOpcodeGetNextS32(PVMCPUCC pVCpu, int32_t *pi32) RT_NOEXCEPT
    1323 {
    1324     return iemOpcodeGetNextU32(pVCpu, (uint32_t *)pi32);
    1325 }
    1326 # endif
    1327 
    1328 /**
    1329  * Fetches the next signed double word from the opcode stream, returning
    1330  * automatically on failure.
    1331  *
    1332  * @param   a_pi32              Where to return the signed double word.
    1333  * @remark Implicitly references pVCpu.
    1334  */
    1335 # ifndef IEM_WITH_SETJMP
    1336 #  define IEM_OPCODE_GET_NEXT_S32(a_pi32) \
    1337     do \
    1338     { \
    1339         VBOXSTRICTRC rcStrict2 = iemOpcodeGetNextS32(pVCpu, (a_pi32)); \
    1340         if (rcStrict2 != VINF_SUCCESS) \
    1341             return rcStrict2; \
    1342     } while (0)
    1343 # else
    1344 #  define IEM_OPCODE_GET_NEXT_S32(a_pi32)    (*(a_pi32) = (int32_t)iemOpcodeGetNextU32Jmp(pVCpu))
    1345 # endif
    1346 
    1347 # ifndef IEM_WITH_SETJMP
    1348 /**
    1349  * Fetches the next opcode dword, sign extending it into a quad word.
    1350  *
    1351  * @returns Strict VBox status code.
    1352  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    1353  * @param   pu64                Where to return the opcode quad word.
    1354  */
    1355 DECLINLINE(VBOXSTRICTRC) iemOpcodeGetNextS32SxU64(PVMCPUCC pVCpu, uint64_t *pu64) RT_NOEXCEPT
    1356 {
    1357     uint8_t const offOpcode = pVCpu->iem.s.offOpcode;
    1358     if (RT_UNLIKELY(offOpcode + 4 > pVCpu->iem.s.cbOpcode))
    1359         return iemOpcodeGetNextS32SxU64Slow(pVCpu, pu64);
    1360 
    1361     int32_t i32 = RT_MAKE_U32_FROM_U8(pVCpu->iem.s.abOpcode[offOpcode],
    1362                                       pVCpu->iem.s.abOpcode[offOpcode + 1],
    1363                                       pVCpu->iem.s.abOpcode[offOpcode + 2],
    1364                                       pVCpu->iem.s.abOpcode[offOpcode + 3]);
    1365     *pu64 = (uint64_t)(int64_t)i32;
    1366     pVCpu->iem.s.offOpcode = offOpcode + 4;
    1367     return VINF_SUCCESS;
    1368 }
    1369 # endif /* !IEM_WITH_SETJMP */
    1370 
    1371 /**
    1372  * Fetches the next opcode double word and sign extends it to a quad word,
    1373  * returns automatically on failure.
    1374  *
    1375  * @param   a_pu64              Where to return the opcode quad word.
    1376  * @remark Implicitly references pVCpu.
    1377  */
    1378 # ifndef IEM_WITH_SETJMP
    1379 #  define IEM_OPCODE_GET_NEXT_S32_SX_U64(a_pu64) \
    1380     do \
    1381     { \
    1382         VBOXSTRICTRC rcStrict2 = iemOpcodeGetNextS32SxU64(pVCpu, (a_pu64)); \
    1383         if (rcStrict2 != VINF_SUCCESS) \
    1384             return rcStrict2; \
    1385     } while (0)
    1386 # else
    1387 #  define IEM_OPCODE_GET_NEXT_S32_SX_U64(a_pu64) (*(a_pu64) = (uint64_t)(int64_t)(int32_t)iemOpcodeGetNextU32Jmp(pVCpu))
    1388 # endif
    1389 
    1390 # ifndef IEM_WITH_SETJMP
    1391 
    1392 /**
    1393  * Fetches the next opcode qword.
    1394  *
    1395  * @returns Strict VBox status code.
    1396  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    1397  * @param   pu64                Where to return the opcode qword.
    1398  */
    1399 DECLINLINE(VBOXSTRICTRC) iemOpcodeGetNextU64(PVMCPUCC pVCpu, uint64_t *pu64) RT_NOEXCEPT
    1400 {
    1401     uintptr_t const offOpcode = pVCpu->iem.s.offOpcode;
    1402     if (RT_LIKELY((uint8_t)offOpcode + 8 <= pVCpu->iem.s.cbOpcode))
    1403     {
    1404 #  ifdef IEM_USE_UNALIGNED_DATA_ACCESS
    1405         *pu64 = *(uint64_t const *)&pVCpu->iem.s.abOpcode[offOpcode];
    1406 #  else
    1407         *pu64 = RT_MAKE_U64_FROM_U8(pVCpu->iem.s.abOpcode[offOpcode],
    1408                                     pVCpu->iem.s.abOpcode[offOpcode + 1],
    1409                                     pVCpu->iem.s.abOpcode[offOpcode + 2],
    1410                                     pVCpu->iem.s.abOpcode[offOpcode + 3],
    1411                                     pVCpu->iem.s.abOpcode[offOpcode + 4],
    1412                                     pVCpu->iem.s.abOpcode[offOpcode + 5],
    1413                                     pVCpu->iem.s.abOpcode[offOpcode + 6],
    1414                                     pVCpu->iem.s.abOpcode[offOpcode + 7]);
    1415 #  endif
    1416         pVCpu->iem.s.offOpcode = (uint8_t)offOpcode + 8;
    1417         return VINF_SUCCESS;
    1418     }
    1419     return iemOpcodeGetNextU64Slow(pVCpu, pu64);
    1420 }
    1421 
    1422 # else  /* IEM_WITH_SETJMP */
    1423 
    1424 /**
    1425  * Fetches the next opcode qword, longjmp on error.
    1426  *
    1427  * @returns The opcode qword.
    1428  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    1429  */
    1430 DECL_INLINE_THROW(uint64_t) iemOpcodeGetNextU64Jmp(PVMCPUCC pVCpu) IEM_NOEXCEPT_MAY_LONGJMP
    1431 {
    1432 #  ifdef IEM_WITH_CODE_TLB
    1433     uint64_t        u64Ret;
    1434     uintptr_t       offBuf = pVCpu->iem.s.offInstrNextByte;
    1435     uint8_t const  *pbBuf  = pVCpu->iem.s.pbInstrBuf;
    1436     if (RT_LIKELY(   pbBuf != NULL
    1437                   && offBuf + 8 <= pVCpu->iem.s.cbInstrBuf))
    1438     {
    1439         pVCpu->iem.s.offInstrNextByte = (uint32_t)offBuf + 8;
    1440 #   ifdef IEM_USE_UNALIGNED_DATA_ACCESS
    1441         u64Ret = *(uint64_t const *)&pbBuf[offBuf];
    1442 #   else
    1443         u64Ret = RT_MAKE_U64_FROM_U8(pbBuf[offBuf],
    1444                                      pbBuf[offBuf + 1],
    1445                                      pbBuf[offBuf + 2],
    1446                                      pbBuf[offBuf + 3],
    1447                                      pbBuf[offBuf + 4],
    1448                                      pbBuf[offBuf + 5],
    1449                                      pbBuf[offBuf + 6],
    1450                                      pbBuf[offBuf + 7]);
    1451 #   endif
    1452     }
    1453     else
    1454         u64Ret = iemOpcodeGetNextU64SlowJmp(pVCpu);
    1455 
    1456 #   ifdef IEM_WITH_CODE_TLB_AND_OPCODE_BUF
    1457     uintptr_t const offOpcode = pVCpu->iem.s.offOpcode;
    1458     Assert(offOpcode + 7 < sizeof(pVCpu->iem.s.abOpcode));
    1459 #    ifdef IEM_USE_UNALIGNED_DATA_ACCESS
    1460     *(uint64_t *)&pVCpu->iem.s.abOpcode[offOpcode] = u64Ret;
    1461 #    else
    1462     pVCpu->iem.s.abOpcode[offOpcode]     = RT_BYTE1(u64Ret);
    1463     pVCpu->iem.s.abOpcode[offOpcode + 1] = RT_BYTE2(u64Ret);
    1464     pVCpu->iem.s.abOpcode[offOpcode + 2] = RT_BYTE3(u64Ret);
    1465     pVCpu->iem.s.abOpcode[offOpcode + 3] = RT_BYTE4(u64Ret);
    1466     pVCpu->iem.s.abOpcode[offOpcode + 4] = RT_BYTE5(u64Ret);
    1467     pVCpu->iem.s.abOpcode[offOpcode + 5] = RT_BYTE6(u64Ret);
    1468     pVCpu->iem.s.abOpcode[offOpcode + 6] = RT_BYTE7(u64Ret);
    1469     pVCpu->iem.s.abOpcode[offOpcode + 7] = RT_BYTE8(u64Ret);
    1470 #    endif
    1471     pVCpu->iem.s.offOpcode = (uint8_t)offOpcode + (uint8_t)8;
    1472 #   endif /* IEM_WITH_CODE_TLB_AND_OPCODE_BUF */
    1473 
    1474     return u64Ret;
    1475 
    1476 #  else /* !IEM_WITH_CODE_TLB */
    1477     uintptr_t const offOpcode = pVCpu->iem.s.offOpcode;
    1478     if (RT_LIKELY((uint8_t)offOpcode + 8 <= pVCpu->iem.s.cbOpcode))
    1479     {
    1480         pVCpu->iem.s.offOpcode = (uint8_t)offOpcode + 8;
    1481 #   ifdef IEM_USE_UNALIGNED_DATA_ACCESS
    1482         return *(uint64_t const *)&pVCpu->iem.s.abOpcode[offOpcode];
    1483 #   else
    1484         return RT_MAKE_U64_FROM_U8(pVCpu->iem.s.abOpcode[offOpcode],
    1485                                    pVCpu->iem.s.abOpcode[offOpcode + 1],
    1486                                    pVCpu->iem.s.abOpcode[offOpcode + 2],
    1487                                    pVCpu->iem.s.abOpcode[offOpcode + 3],
    1488                                    pVCpu->iem.s.abOpcode[offOpcode + 4],
    1489                                    pVCpu->iem.s.abOpcode[offOpcode + 5],
    1490                                    pVCpu->iem.s.abOpcode[offOpcode + 6],
    1491                                    pVCpu->iem.s.abOpcode[offOpcode + 7]);
    1492 #   endif
    1493     }
    1494     return iemOpcodeGetNextU64SlowJmp(pVCpu);
    1495 #  endif /* !IEM_WITH_CODE_TLB */
    1496 }
    1497 
    1498 # endif /* IEM_WITH_SETJMP */
    1499 
    1500 /**
    1501  * Fetches the next opcode quad word, returns automatically on failure.
    1502  *
    1503  * @param   a_pu64              Where to return the opcode quad word.
    1504  * @remark Implicitly references pVCpu.
    1505  */
    1506 # ifndef IEM_WITH_SETJMP
    1507 #  define IEM_OPCODE_GET_NEXT_U64(a_pu64) \
    1508     do \
    1509     { \
    1510         VBOXSTRICTRC rcStrict2 = iemOpcodeGetNextU64(pVCpu, (a_pu64)); \
    1511         if (rcStrict2 != VINF_SUCCESS) \
    1512             return rcStrict2; \
    1513     } while (0)
    1514 # else
    1515 #  define IEM_OPCODE_GET_NEXT_U64(a_pu64)    ( *(a_pu64) = iemOpcodeGetNextU64Jmp(pVCpu) )
    1516 # endif
    1517 
    1518 /**
    1519  * For fetching the opcode bytes for an ModR/M effective address, but throw
    1520  * away the result.
    1521  *
    1522  * This is used when decoding undefined opcodes and such where we want to avoid
    1523  * unnecessary MC blocks.
    1524  *
    1525  * @note The recompiler code overrides this one so iemOpHlpCalcRmEffAddrJmpEx is
    1526  *       used instead.  At least for now...
    1527  */
    1528 # ifndef IEM_WITH_SETJMP
    1529 #  define IEM_OPCODE_SKIP_RM_EFF_ADDR_BYTES(a_bRm) do { \
    1530         RTGCPTR      GCPtrEff; \
    1531         VBOXSTRICTRC rcStrict = iemOpHlpCalcRmEffAddr(pVCpu, bRm, 0, &GCPtrEff); \
    1532         if (rcStrict != VINF_SUCCESS) \
    1533             return rcStrict; \
    1534     } while (0)
    1535 # else
    1536 #  define IEM_OPCODE_SKIP_RM_EFF_ADDR_BYTES(a_bRm) do { \
    1537         (void)iemOpHlpCalcRmEffAddrJmp(pVCpu, bRm, 0); \
    1538     } while (0)
    1539 # endif
    1540 
    1541285#endif /* !IEM_WITH_OPAQUE_DECODER_STATE */
    1542286
    1543287
    1544 /** @name  Misc Worker Functions.
     288
     289/** @name   Memory access.
     290 *
    1545291 * @{
    1546292 */
    1547 
    1548 /**
    1549  * Gets the correct EFLAGS regardless of whether PATM stores parts of them or
    1550  * not (kind of obsolete now).
    1551  *
    1552  * @param   a_pVCpu The cross context virtual CPU structure of the calling thread.
    1553  */
    1554 #define IEMMISC_GET_EFL(a_pVCpu)            ( (a_pVCpu)->cpum.GstCtx.eflags.u  )
    1555 
    1556 /**
    1557  * Updates the EFLAGS in the correct manner wrt. PATM (kind of obsolete).
    1558  *
    1559  * @param   a_pVCpu The cross context virtual CPU structure of the calling thread.
    1560  * @param   a_fEfl  The new EFLAGS.
    1561  */
    1562 #define IEMMISC_SET_EFL(a_pVCpu, a_fEfl)    do { (a_pVCpu)->cpum.GstCtx.eflags.u = (a_fEfl); } while (0)
    1563 
    1564 
    1565 /**
    1566  * Loads a NULL data selector into a selector register, both the hidden and
    1567  * visible parts, in protected mode.
    1568  *
    1569  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    1570  * @param   pSReg               Pointer to the segment register.
    1571  * @param   uRpl                The RPL.
    1572  */
    1573 DECLINLINE(void) iemHlpLoadNullDataSelectorProt(PVMCPUCC pVCpu, PCPUMSELREG pSReg, RTSEL uRpl) RT_NOEXCEPT
    1574 {
    1575     /** @todo Testcase: write a testcase checking what happends when loading a NULL
    1576      *        data selector in protected mode. */
    1577     pSReg->Sel      = uRpl;
    1578     pSReg->ValidSel = uRpl;
    1579     pSReg->fFlags   = CPUMSELREG_FLAGS_VALID;
    1580     if (IEM_IS_GUEST_CPU_INTEL(pVCpu))
    1581     {
    1582         /* VT-x (Intel 3960x) observed doing something like this. */
    1583         pSReg->Attr.u   = X86DESCATTR_UNUSABLE | X86DESCATTR_G | X86DESCATTR_D | (IEM_GET_CPL(pVCpu) << X86DESCATTR_DPL_SHIFT);
    1584         pSReg->u32Limit = UINT32_MAX;
    1585         pSReg->u64Base  = 0;
    1586     }
    1587     else
    1588     {
    1589         pSReg->Attr.u   = X86DESCATTR_UNUSABLE;
    1590         pSReg->u32Limit = 0;
    1591         pSReg->u64Base  = 0;
    1592     }
    1593 }
    1594 
    1595 /** @} */
    1596 
    1597 
    1598 /*
    1599  *
    1600  * Helpers routines.
    1601  * Helpers routines.
    1602  * Helpers routines.
    1603  *
    1604  */
    1605 
    1606 #ifndef IEM_WITH_OPAQUE_DECODER_STATE
    1607 
    1608 /**
    1609  * Recalculates the effective operand size.
    1610  *
    1611  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    1612  */
    1613 DECLINLINE(void) iemRecalEffOpSize(PVMCPUCC pVCpu) RT_NOEXCEPT
    1614 {
    1615     switch (IEM_GET_CPU_MODE(pVCpu))
    1616     {
    1617         case IEMMODE_16BIT:
    1618             pVCpu->iem.s.enmEffOpSize = pVCpu->iem.s.fPrefixes & IEM_OP_PRF_SIZE_OP ? IEMMODE_32BIT : IEMMODE_16BIT;
    1619             break;
    1620         case IEMMODE_32BIT:
    1621             pVCpu->iem.s.enmEffOpSize = pVCpu->iem.s.fPrefixes & IEM_OP_PRF_SIZE_OP ? IEMMODE_16BIT : IEMMODE_32BIT;
    1622             break;
    1623         case IEMMODE_64BIT:
    1624             switch (pVCpu->iem.s.fPrefixes & (IEM_OP_PRF_SIZE_REX_W | IEM_OP_PRF_SIZE_OP))
    1625             {
    1626                 case 0:
    1627                     pVCpu->iem.s.enmEffOpSize = pVCpu->iem.s.enmDefOpSize;
    1628                     break;
    1629                 case IEM_OP_PRF_SIZE_OP:
    1630                     pVCpu->iem.s.enmEffOpSize = IEMMODE_16BIT;
    1631                     break;
    1632                 case IEM_OP_PRF_SIZE_REX_W:
    1633                 case IEM_OP_PRF_SIZE_REX_W | IEM_OP_PRF_SIZE_OP:
    1634                     pVCpu->iem.s.enmEffOpSize = IEMMODE_64BIT;
    1635                     break;
    1636             }
    1637             break;
    1638         default:
    1639             AssertFailed();
    1640     }
    1641 }
    1642 
    1643 
    1644 /**
    1645  * Sets the default operand size to 64-bit and recalculates the effective
    1646  * operand size.
    1647  *
    1648  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    1649  */
    1650 DECLINLINE(void) iemRecalEffOpSize64Default(PVMCPUCC pVCpu) RT_NOEXCEPT
    1651 {
    1652     Assert(IEM_IS_64BIT_CODE(pVCpu));
    1653     pVCpu->iem.s.enmDefOpSize = IEMMODE_64BIT;
    1654     if ((pVCpu->iem.s.fPrefixes & (IEM_OP_PRF_SIZE_REX_W | IEM_OP_PRF_SIZE_OP)) != IEM_OP_PRF_SIZE_OP)
    1655         pVCpu->iem.s.enmEffOpSize = IEMMODE_64BIT;
    1656     else
    1657         pVCpu->iem.s.enmEffOpSize = IEMMODE_16BIT;
    1658 }
    1659 
    1660 
    1661 /**
    1662  * Sets the default operand size to 64-bit and recalculates the effective
    1663  * operand size, with intel ignoring any operand size prefix (AMD respects it).
    1664  *
    1665  * This is for the relative jumps.
    1666  *
    1667  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    1668  */
    1669 DECLINLINE(void) iemRecalEffOpSize64DefaultAndIntelIgnoresOpSizePrefix(PVMCPUCC pVCpu) RT_NOEXCEPT
    1670 {
    1671     Assert(IEM_IS_64BIT_CODE(pVCpu));
    1672     pVCpu->iem.s.enmDefOpSize = IEMMODE_64BIT;
    1673     if (   (pVCpu->iem.s.fPrefixes & (IEM_OP_PRF_SIZE_REX_W | IEM_OP_PRF_SIZE_OP)) != IEM_OP_PRF_SIZE_OP
    1674         || pVCpu->iem.s.enmCpuVendor == CPUMCPUVENDOR_INTEL)
    1675         pVCpu->iem.s.enmEffOpSize = IEMMODE_64BIT;
    1676     else
    1677         pVCpu->iem.s.enmEffOpSize = IEMMODE_16BIT;
    1678 }
    1679 
    1680 #endif /* !IEM_WITH_OPAQUE_DECODER_STATE */
    1681 
    1682 
    1683 
    1684 /** @name   Register Access.
    1685  * @{
    1686  */
    1687 
    1688 /**
    1689  * Gets a reference (pointer) to the specified hidden segment register.
    1690  *
    1691  * @returns Hidden register reference.
    1692  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    1693  * @param   iSegReg             The segment register.
    1694  */
    1695 DECL_FORCE_INLINE(PCPUMSELREG) iemSRegGetHid(PVMCPUCC pVCpu, uint8_t iSegReg) RT_NOEXCEPT
    1696 {
    1697     Assert(iSegReg < X86_SREG_COUNT);
    1698     IEM_CTX_ASSERT(pVCpu, CPUMCTX_EXTRN_SREG_FROM_IDX(iSegReg));
    1699     PCPUMSELREG pSReg = &pVCpu->cpum.GstCtx.aSRegs[iSegReg];
    1700 
    1701     Assert(CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pVCpu, pSReg));
    1702     return pSReg;
    1703 }
    1704 
    1705 
    1706 /**
    1707  * Ensures that the given hidden segment register is up to date.
    1708  *
    1709  * @returns Hidden register reference.
    1710  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    1711  * @param   pSReg               The segment register.
    1712  */
    1713 DECL_FORCE_INLINE(PCPUMSELREG) iemSRegUpdateHid(PVMCPUCC pVCpu, PCPUMSELREG pSReg) RT_NOEXCEPT
    1714 {
    1715     Assert(CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pVCpu, pSReg));
    1716     NOREF(pVCpu);
    1717     return pSReg;
    1718 }
    1719 
    1720 
    1721 /**
    1722  * Gets a reference (pointer) to the specified segment register (the selector
    1723  * value).
    1724  *
    1725  * @returns Pointer to the selector variable.
    1726  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    1727  * @param   iSegReg             The segment register.
    1728  */
    1729 DECL_FORCE_INLINE(uint16_t *) iemSRegRef(PVMCPUCC pVCpu, uint8_t iSegReg) RT_NOEXCEPT
    1730 {
    1731     Assert(iSegReg < X86_SREG_COUNT);
    1732     IEM_CTX_ASSERT(pVCpu, CPUMCTX_EXTRN_SREG_FROM_IDX(iSegReg));
    1733     return &pVCpu->cpum.GstCtx.aSRegs[iSegReg].Sel;
    1734 }
    1735 
    1736 
    1737 /**
    1738  * Fetches the selector value of a segment register.
    1739  *
    1740  * @returns The selector value.
    1741  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    1742  * @param   iSegReg             The segment register.
    1743  */
    1744 DECL_FORCE_INLINE(uint16_t) iemSRegFetchU16(PVMCPUCC pVCpu, uint8_t iSegReg) RT_NOEXCEPT
    1745 {
    1746     Assert(iSegReg < X86_SREG_COUNT);
    1747     IEM_CTX_ASSERT(pVCpu, CPUMCTX_EXTRN_SREG_FROM_IDX(iSegReg));
    1748     return pVCpu->cpum.GstCtx.aSRegs[iSegReg].Sel;
    1749 }
    1750 
    1751 
    1752 /**
    1753  * Fetches the base address value of a segment register.
    1754  *
    1755  * @returns The selector value.
    1756  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    1757  * @param   iSegReg             The segment register.
    1758  */
    1759 DECL_FORCE_INLINE(uint64_t) iemSRegBaseFetchU64(PVMCPUCC pVCpu, uint8_t iSegReg) RT_NOEXCEPT
    1760 {
    1761     Assert(iSegReg < X86_SREG_COUNT);
    1762     IEM_CTX_ASSERT(pVCpu, CPUMCTX_EXTRN_SREG_FROM_IDX(iSegReg));
    1763     return pVCpu->cpum.GstCtx.aSRegs[iSegReg].u64Base;
    1764 }
    1765 
    1766 
    1767 /**
    1768  * Gets a reference (pointer) to the specified general purpose register.
    1769  *
    1770  * @returns Register reference.
    1771  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    1772  * @param   iReg                The general purpose register.
    1773  */
    1774 DECL_FORCE_INLINE(void *) iemGRegRef(PVMCPUCC pVCpu, uint8_t iReg) RT_NOEXCEPT
    1775 {
    1776     Assert(iReg < 16);
    1777     return &pVCpu->cpum.GstCtx.aGRegs[iReg];
    1778 }
    1779 
    1780 
    1781 #ifndef IEM_WITH_OPAQUE_DECODER_STATE
    1782 /**
    1783  * Gets a reference (pointer) to the specified 8-bit general purpose register.
    1784  *
    1785  * Because of AH, CH, DH and BH we cannot use iemGRegRef directly here.
    1786  *
    1787  * @returns Register reference.
    1788  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    1789  * @param   iReg                The register.
    1790  */
    1791 DECL_FORCE_INLINE(uint8_t *) iemGRegRefU8(PVMCPUCC pVCpu, uint8_t iReg) RT_NOEXCEPT
    1792 {
    1793     if (iReg < 4 || (pVCpu->iem.s.fPrefixes & (IEM_OP_PRF_REX | IEM_OP_PRF_VEX)))
    1794     {
    1795         Assert(iReg < 16);
    1796         return &pVCpu->cpum.GstCtx.aGRegs[iReg].u8;
    1797     }
    1798     /* high 8-bit register. */
    1799     Assert(iReg < 8);
    1800     return &pVCpu->cpum.GstCtx.aGRegs[iReg & 3].bHi;
    1801 }
    1802 #endif
    1803 
    1804 
    1805 /**
    1806  * Gets a reference (pointer) to the specified 8-bit general purpose register,
    1807  * alternative version with extended (20) register index.
    1808  *
    1809  * @returns Register reference.
    1810  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    1811  * @param   iRegEx              The register.  The 16 first are regular ones,
    1812  *                              whereas 16 thru 19 maps to AH, CH, DH and BH.
    1813  */
    1814 DECL_FORCE_INLINE(uint8_t *) iemGRegRefU8Ex(PVMCPUCC pVCpu, uint8_t iRegEx) RT_NOEXCEPT
    1815 {
    1816     /** @todo This could be done by double indexing on little endian hosts:
    1817      *  return &pVCpu->cpum.GstCtx.aGRegs[iRegEx & 15].ab[iRegEx >> 4]; */
    1818     if (iRegEx < 16)
    1819         return &pVCpu->cpum.GstCtx.aGRegs[iRegEx].u8;
    1820 
    1821     /* high 8-bit register. */
    1822     Assert(iRegEx < 20);
    1823     return &pVCpu->cpum.GstCtx.aGRegs[iRegEx & 3].bHi;
    1824 }
    1825 
    1826 
    1827 /**
    1828  * Gets a reference (pointer) to the specified 16-bit general purpose register.
    1829  *
    1830  * @returns Register reference.
    1831  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    1832  * @param   iReg                The register.
    1833  */
    1834 DECL_FORCE_INLINE(uint16_t *) iemGRegRefU16(PVMCPUCC pVCpu, uint8_t iReg) RT_NOEXCEPT
    1835 {
    1836     Assert(iReg < 16);
    1837     return &pVCpu->cpum.GstCtx.aGRegs[iReg].u16;
    1838 }
    1839 
    1840 
    1841 /**
    1842  * Gets a reference (pointer) to the specified 32-bit general purpose register.
    1843  *
    1844  * @returns Register reference.
    1845  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    1846  * @param   iReg                The register.
    1847  */
    1848 DECL_FORCE_INLINE(uint32_t *) iemGRegRefU32(PVMCPUCC pVCpu, uint8_t iReg) RT_NOEXCEPT
    1849 {
    1850     Assert(iReg < 16);
    1851     return &pVCpu->cpum.GstCtx.aGRegs[iReg].u32;
    1852 }
    1853 
    1854 
    1855 /**
    1856  * Gets a reference (pointer) to the specified signed 32-bit general purpose register.
    1857  *
    1858  * @returns Register reference.
    1859  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    1860  * @param   iReg                The register.
    1861  */
    1862 DECL_FORCE_INLINE(int32_t *) iemGRegRefI32(PVMCPUCC pVCpu, uint8_t iReg) RT_NOEXCEPT
    1863 {
    1864     Assert(iReg < 16);
    1865     return (int32_t *)&pVCpu->cpum.GstCtx.aGRegs[iReg].u32;
    1866 }
    1867 
    1868 
    1869 /**
    1870  * Gets a reference (pointer) to the specified 64-bit general purpose register.
    1871  *
    1872  * @returns Register reference.
    1873  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    1874  * @param   iReg                The register.
    1875  */
    1876 DECL_FORCE_INLINE(uint64_t *) iemGRegRefU64(PVMCPUCC pVCpu, uint8_t iReg) RT_NOEXCEPT
    1877 {
    1878     Assert(iReg < 64);
    1879     return &pVCpu->cpum.GstCtx.aGRegs[iReg].u64;
    1880 }
    1881 
    1882 
    1883 /**
    1884  * Gets a reference (pointer) to the specified signed 64-bit general purpose register.
    1885  *
    1886  * @returns Register reference.
    1887  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    1888  * @param   iReg                The register.
    1889  */
    1890 DECL_FORCE_INLINE(int64_t *) iemGRegRefI64(PVMCPUCC pVCpu, uint8_t iReg) RT_NOEXCEPT
    1891 {
    1892     Assert(iReg < 16);
    1893     return (int64_t *)&pVCpu->cpum.GstCtx.aGRegs[iReg].u64;
    1894 }
    1895 
    1896 
    1897 /**
    1898  * Gets a reference (pointer) to the specified segment register's base address.
    1899  *
    1900  * @returns Segment register base address reference.
    1901  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    1902  * @param   iSegReg             The segment selector.
    1903  */
    1904 DECL_FORCE_INLINE(uint64_t *) iemSRegBaseRefU64(PVMCPUCC pVCpu, uint8_t iSegReg) RT_NOEXCEPT
    1905 {
    1906     Assert(iSegReg < X86_SREG_COUNT);
    1907     IEM_CTX_ASSERT(pVCpu, CPUMCTX_EXTRN_SREG_FROM_IDX(iSegReg));
    1908     return &pVCpu->cpum.GstCtx.aSRegs[iSegReg].u64Base;
    1909 }
    1910 
    1911 
    1912 #ifndef IEM_WITH_OPAQUE_DECODER_STATE
    1913 /**
    1914  * Fetches the value of a 8-bit general purpose register.
    1915  *
    1916  * @returns The register value.
    1917  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    1918  * @param   iReg                The register.
    1919  */
    1920 DECL_FORCE_INLINE(uint8_t) iemGRegFetchU8(PVMCPUCC pVCpu, uint8_t iReg) RT_NOEXCEPT
    1921 {
    1922     return *iemGRegRefU8(pVCpu, iReg);
    1923 }
    1924 #endif
    1925 
    1926 
    1927 /**
    1928  * Fetches the value of a 8-bit general purpose register, alternative version
    1929  * with extended (20) register index.
    1930 
    1931  * @returns The register value.
    1932  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    1933  * @param   iRegEx              The register.  The 16 first are regular ones,
    1934  *                              whereas 16 thru 19 maps to AH, CH, DH and BH.
    1935  */
    1936 DECL_FORCE_INLINE(uint8_t) iemGRegFetchU8Ex(PVMCPUCC pVCpu, uint8_t iRegEx) RT_NOEXCEPT
    1937 {
    1938     return *iemGRegRefU8Ex(pVCpu, iRegEx);
    1939 }
    1940 
    1941 
    1942 /**
    1943  * Fetches the value of a 16-bit general purpose register.
    1944  *
    1945  * @returns The register value.
    1946  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    1947  * @param   iReg                The register.
    1948  */
    1949 DECL_FORCE_INLINE(uint16_t) iemGRegFetchU16(PVMCPUCC pVCpu, uint8_t iReg) RT_NOEXCEPT
    1950 {
    1951     Assert(iReg < 16);
    1952     return pVCpu->cpum.GstCtx.aGRegs[iReg].u16;
    1953 }
    1954 
    1955 
    1956 /**
    1957  * Fetches the value of a 32-bit general purpose register.
    1958  *
    1959  * @returns The register value.
    1960  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    1961  * @param   iReg                The register.
    1962  */
    1963 DECL_FORCE_INLINE(uint32_t) iemGRegFetchU32(PVMCPUCC pVCpu, uint8_t iReg) RT_NOEXCEPT
    1964 {
    1965     Assert(iReg < 16);
    1966     return pVCpu->cpum.GstCtx.aGRegs[iReg].u32;
    1967 }
    1968 
    1969 
    1970 /**
    1971  * Fetches the value of a 64-bit general purpose register.
    1972  *
    1973  * @returns The register value.
    1974  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    1975  * @param   iReg                The register.
    1976  */
    1977 DECL_FORCE_INLINE(uint64_t) iemGRegFetchU64(PVMCPUCC pVCpu, uint8_t iReg) RT_NOEXCEPT
    1978 {
    1979     Assert(iReg < 16);
    1980     return pVCpu->cpum.GstCtx.aGRegs[iReg].u64;
    1981 }
    1982 
    1983 
    1984 /**
    1985  * Stores a 16-bit value to a general purpose register.
    1986  *
    1987  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    1988  * @param   iReg                The register.
    1989  * @param   uValue              The value to store.
    1990  */
    1991 DECL_FORCE_INLINE(void) iemGRegStoreU16(PVMCPUCC pVCpu, uint8_t iReg, uint16_t uValue) RT_NOEXCEPT
    1992 {
    1993     Assert(iReg < 16);
    1994     pVCpu->cpum.GstCtx.aGRegs[iReg].u16 = uValue;
    1995 }
    1996 
    1997 
    1998 /**
    1999  * Stores a 32-bit value to a general purpose register, implicitly clearing high
    2000  * values.
    2001  *
    2002  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    2003  * @param   iReg                The register.
    2004  * @param   uValue              The value to store.
    2005  */
    2006 DECL_FORCE_INLINE(void) iemGRegStoreU32(PVMCPUCC pVCpu, uint8_t iReg, uint32_t uValue) RT_NOEXCEPT
    2007 {
    2008     Assert(iReg < 16);
    2009     pVCpu->cpum.GstCtx.aGRegs[iReg].u64 = uValue;
    2010 }
    2011 
    2012 
    2013 /**
    2014  * Stores a 64-bit value to a general purpose register.
    2015  *
    2016  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    2017  * @param   iReg                The register.
    2018  * @param   uValue              The value to store.
    2019  */
    2020 DECL_FORCE_INLINE(void) iemGRegStoreU64(PVMCPUCC pVCpu, uint8_t iReg, uint64_t uValue) RT_NOEXCEPT
    2021 {
    2022     Assert(iReg < 16);
    2023     pVCpu->cpum.GstCtx.aGRegs[iReg].u64 = uValue;
    2024 }
    2025 
    2026 
    2027 /**
    2028  * Get the address of the top of the stack.
    2029  *
    2030  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    2031  */
    2032 DECL_FORCE_INLINE(RTGCPTR) iemRegGetEffRsp(PCVMCPU pVCpu) RT_NOEXCEPT
    2033 {
    2034     if (IEM_IS_64BIT_CODE(pVCpu))
    2035         return pVCpu->cpum.GstCtx.rsp;
    2036     if (pVCpu->cpum.GstCtx.ss.Attr.n.u1DefBig)
    2037         return pVCpu->cpum.GstCtx.esp;
    2038     return pVCpu->cpum.GstCtx.sp;
    2039 }
    2040 
    2041 
    2042 /**
    2043  * Updates the RIP/EIP/IP to point to the next instruction.
    2044  *
    2045  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    2046  * @param   cbInstr             The number of bytes to add.
    2047  */
    2048 DECL_FORCE_INLINE(void) iemRegAddToRip(PVMCPUCC pVCpu, uint8_t cbInstr) RT_NOEXCEPT
    2049 {
    2050     /*
    2051      * Advance RIP.
    2052      *
    2053      * When we're targetting 8086/8, 80186/8 or 80286 mode the updates are 16-bit,
    2054      * while in all other modes except LM64 the updates are 32-bit.  This means
    2055      * we need to watch for both 32-bit and 16-bit "carry" situations, i.e.
    2056      * 4GB and 64KB rollovers, and decide whether anything needs masking.
    2057      *
    2058      * See PC wrap around tests in bs3-cpu-weird-1.
    2059      */
    2060     uint64_t const uRipPrev = pVCpu->cpum.GstCtx.rip;
    2061     uint64_t const uRipNext = uRipPrev + cbInstr;
    2062     if (RT_LIKELY(   !((uRipNext ^ uRipPrev) & (RT_BIT_64(32) | RT_BIT_64(16)))
    2063                   || IEM_IS_64BIT_CODE(pVCpu)))
    2064         pVCpu->cpum.GstCtx.rip = uRipNext;
    2065     else if (IEM_GET_TARGET_CPU(pVCpu) >= IEMTARGETCPU_386)
    2066         pVCpu->cpum.GstCtx.rip = (uint32_t)uRipNext;
    2067     else
    2068         pVCpu->cpum.GstCtx.rip = (uint16_t)uRipNext;
    2069 }
    2070 
    2071 
    2072 /**
    2073  * Called by iemRegAddToRipAndFinishingClearingRF and others when any of the
    2074  * following EFLAGS bits are set:
    2075  *      - X86_EFL_RF - clear it.
    2076  *      - CPUMCTX_INHIBIT_SHADOW (_SS/_STI) - clear them.
    2077  *      - X86_EFL_TF - generate single step \#DB trap.
    2078  *      - CPUMCTX_DBG_HIT_DR0/1/2/3 - generate \#DB trap (data or I/O, not
    2079  *        instruction).
    2080  *
    2081  * According to @sdmv3{077,200,Table 6-2,Priority Among Concurrent Events},
    2082  * a \#DB due to TF (single stepping) or a DRx non-instruction breakpoint
    2083  * takes priority over both NMIs and hardware interrupts.  So, neither is
    2084  * considered here.  (The RESET, \#MC, SMI, INIT, STOPCLK and FLUSH events are
    2085  * either unsupported will be triggered on-top of any \#DB raised here.)
    2086  *
    2087  * The RF flag only needs to be cleared here as it only suppresses instruction
    2088  * breakpoints which are not raised here (happens synchronously during
    2089  * instruction fetching).
    2090  *
    2091  * The CPUMCTX_INHIBIT_SHADOW_SS flag will be cleared by this function, so its
    2092  * status has no bearing on whether \#DB exceptions are raised.
    2093  *
    2094  * @note This must *NOT* be called by the two instructions setting the
    2095  *       CPUMCTX_INHIBIT_SHADOW_SS flag.
    2096  *
    2097  * @see  @sdmv3{077,200,Table 6-2,Priority Among Concurrent Events}
    2098  * @see  @sdmv3{077,200,6.8.3,Masking Exceptions and Interrupts When Switching
    2099  *              Stacks}
    2100  */
    2101 template<uint32_t const a_fTF = X86_EFL_TF>
    2102 static VBOXSTRICTRC iemFinishInstructionWithFlagsSet(PVMCPUCC pVCpu, int rcNormal) RT_NOEXCEPT
    2103 {
    2104     /*
    2105      * Normally we're just here to clear RF and/or interrupt shadow bits.
    2106      */
    2107     if (RT_LIKELY((pVCpu->cpum.GstCtx.eflags.uBoth & (a_fTF | CPUMCTX_DBG_HIT_DRX_MASK | CPUMCTX_DBG_DBGF_MASK)) == 0))
    2108         pVCpu->cpum.GstCtx.eflags.uBoth &= ~(X86_EFL_RF | CPUMCTX_INHIBIT_SHADOW);
    2109     else
    2110     {
    2111         /*
    2112          * Raise a #DB or/and DBGF event.
    2113          */
    2114         VBOXSTRICTRC rcStrict;
    2115         if (pVCpu->cpum.GstCtx.eflags.uBoth & (a_fTF | CPUMCTX_DBG_HIT_DRX_MASK))
    2116         {
    2117             IEM_CTX_IMPORT_RET(pVCpu, CPUMCTX_EXTRN_DR6);
    2118             pVCpu->cpum.GstCtx.dr[6] &= ~X86_DR6_B_MASK;
    2119             if (pVCpu->cpum.GstCtx.eflags.uBoth & a_fTF)
    2120                 pVCpu->cpum.GstCtx.dr[6] |= X86_DR6_BS;
    2121             pVCpu->cpum.GstCtx.dr[6] |= (pVCpu->cpum.GstCtx.eflags.uBoth & CPUMCTX_DBG_HIT_DRX_MASK_NONSILENT)
    2122                                      >> CPUMCTX_DBG_HIT_DRX_SHIFT;
    2123             LogFlowFunc(("Guest #DB fired at %04X:%016llX: DR6=%08X, RFLAGS=%16RX64\n",
    2124                          pVCpu->cpum.GstCtx.cs.Sel, pVCpu->cpum.GstCtx.rip, (unsigned)pVCpu->cpum.GstCtx.dr[6],
    2125                          pVCpu->cpum.GstCtx.rflags.uBoth));
    2126 
    2127             pVCpu->cpum.GstCtx.eflags.uBoth &= ~(X86_EFL_RF | CPUMCTX_INHIBIT_SHADOW | CPUMCTX_DBG_HIT_DRX_MASK);
    2128             rcStrict = iemRaiseDebugException(pVCpu);
    2129 
    2130             /* A DBGF event/breakpoint trumps the iemRaiseDebugException informational status code. */
    2131             if ((pVCpu->cpum.GstCtx.eflags.uBoth & CPUMCTX_DBG_DBGF_MASK) && RT_FAILURE(rcStrict))
    2132             {
    2133                 rcStrict = pVCpu->cpum.GstCtx.eflags.uBoth & CPUMCTX_DBG_DBGF_BP ? VINF_EM_DBG_BREAKPOINT : VINF_EM_DBG_EVENT;
    2134                 LogFlowFunc(("dbgf at %04X:%016llX: %Rrc\n", pVCpu->cpum.GstCtx.cs.Sel, pVCpu->cpum.GstCtx.rip, VBOXSTRICTRC_VAL(rcStrict)));
    2135             }
    2136         }
    2137         else
    2138         {
    2139             Assert(pVCpu->cpum.GstCtx.eflags.uBoth & CPUMCTX_DBG_DBGF_MASK);
    2140             rcStrict = pVCpu->cpum.GstCtx.eflags.uBoth & CPUMCTX_DBG_DBGF_BP ? VINF_EM_DBG_BREAKPOINT : VINF_EM_DBG_EVENT;
    2141             LogFlowFunc(("dbgf at %04X:%016llX: %Rrc\n", pVCpu->cpum.GstCtx.cs.Sel, pVCpu->cpum.GstCtx.rip, VBOXSTRICTRC_VAL(rcStrict)));
    2142         }
    2143         pVCpu->cpum.GstCtx.eflags.uBoth &= ~CPUMCTX_DBG_DBGF_MASK;
    2144         Assert(rcStrict != VINF_SUCCESS);
    2145         return rcStrict;
    2146     }
    2147     return rcNormal;
    2148 }
    2149 
    2150 
    2151 /**
    2152  * Clears the RF and CPUMCTX_INHIBIT_SHADOW, triggering \#DB if pending.
    2153  *
    2154  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    2155  * @param   rcNormal            VINF_SUCCESS to continue TB.
    2156  *                              VINF_IEM_REEXEC_BREAK to force TB exit when
    2157  *                              taking the wrong conditional branhc.
    2158  */
    2159 DECL_FORCE_INLINE(VBOXSTRICTRC) iemRegFinishClearingRF(PVMCPUCC pVCpu, int rcNormal) RT_NOEXCEPT
    2160 {
    2161     /*
    2162      * We assume that most of the time nothing actually needs doing here.
    2163      */
    2164     AssertCompile(CPUMCTX_INHIBIT_SHADOW < UINT32_MAX);
    2165     if (RT_LIKELY(!(  pVCpu->cpum.GstCtx.eflags.uBoth
    2166                     & (X86_EFL_TF | X86_EFL_RF | CPUMCTX_INHIBIT_SHADOW | CPUMCTX_DBG_HIT_DRX_MASK | CPUMCTX_DBG_DBGF_MASK)) ))
    2167         return rcNormal;
    2168     return iemFinishInstructionWithFlagsSet(pVCpu, rcNormal);
    2169 }
    2170 
    2171 
    2172 /**
    2173  * Updates the RIP/EIP/IP to point to the next instruction and clears EFLAGS.RF
    2174  * and CPUMCTX_INHIBIT_SHADOW.
    2175  *
    2176  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    2177  * @param   cbInstr             The number of bytes to add.
    2178  */
    2179 DECL_FORCE_INLINE(VBOXSTRICTRC) iemRegAddToRipAndFinishingClearingRF(PVMCPUCC pVCpu, uint8_t cbInstr) RT_NOEXCEPT
    2180 {
    2181     iemRegAddToRip(pVCpu, cbInstr);
    2182     return iemRegFinishClearingRF(pVCpu, VINF_SUCCESS);
    2183 }
    2184 
    2185 
    2186 /**
    2187  * Updates the RIP to point to the next instruction and clears EFLAGS.RF
    2188  * and CPUMCTX_INHIBIT_SHADOW.
    2189  *
    2190  * Only called from 64-bit code.
    2191  *
    2192  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    2193  * @param   cbInstr             The number of bytes to add.
    2194  * @param   rcNormal            VINF_SUCCESS to continue TB.
    2195  *                              VINF_IEM_REEXEC_BREAK to force TB exit when
    2196  *                              taking the wrong conditional branhc.
    2197  */
    2198 DECL_FORCE_INLINE(VBOXSTRICTRC) iemRegAddToRip64AndFinishingClearingRF(PVMCPUCC pVCpu, uint8_t cbInstr, int rcNormal) RT_NOEXCEPT
    2199 {
    2200     pVCpu->cpum.GstCtx.rip = pVCpu->cpum.GstCtx.rip + cbInstr;
    2201     return iemRegFinishClearingRF(pVCpu, rcNormal);
    2202 }
    2203 
    2204 
    2205 /**
    2206  * Updates the EIP to point to the next instruction and clears EFLAGS.RF and
    2207  * CPUMCTX_INHIBIT_SHADOW.
    2208  *
    2209  * This is never from 64-bit code.
    2210  *
    2211  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    2212  * @param   cbInstr             The number of bytes to add.
    2213  * @param   rcNormal            VINF_SUCCESS to continue TB.
    2214  *                              VINF_IEM_REEXEC_BREAK to force TB exit when
    2215  *                              taking the wrong conditional branhc.
    2216  */
    2217 DECL_FORCE_INLINE(VBOXSTRICTRC) iemRegAddToEip32AndFinishingClearingRF(PVMCPUCC pVCpu, uint8_t cbInstr, int rcNormal) RT_NOEXCEPT
    2218 {
    2219     pVCpu->cpum.GstCtx.rip = (uint32_t)(pVCpu->cpum.GstCtx.eip + cbInstr);
    2220     return iemRegFinishClearingRF(pVCpu, rcNormal);
    2221 }
    2222 
    2223 
    2224 /**
    2225  * Updates the IP to point to the next instruction and clears EFLAGS.RF and
    2226  * CPUMCTX_INHIBIT_SHADOW.
    2227  *
    2228  * This is only ever used from 16-bit code on a pre-386 CPU.
    2229  *
    2230  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    2231  * @param   cbInstr             The number of bytes to add.
    2232  * @param   rcNormal            VINF_SUCCESS to continue TB.
    2233  *                              VINF_IEM_REEXEC_BREAK to force TB exit when
    2234  *                              taking the wrong conditional branhc.
    2235  */
    2236 DECL_FORCE_INLINE(VBOXSTRICTRC) iemRegAddToIp16AndFinishingClearingRF(PVMCPUCC pVCpu, uint8_t cbInstr, int rcNormal) RT_NOEXCEPT
    2237 {
    2238     pVCpu->cpum.GstCtx.rip = (uint16_t)(pVCpu->cpum.GstCtx.ip + cbInstr);
    2239     return iemRegFinishClearingRF(pVCpu, rcNormal);
    2240 }
    2241 
    2242 
    2243 /**
    2244  * Tail method for a finish function that does't clear flags or raise \#DB.
    2245  *
    2246  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    2247  * @param   rcNormal            VINF_SUCCESS to continue TB.
    2248  *                              VINF_IEM_REEXEC_BREAK to force TB exit when
    2249  *                              taking the wrong conditional branhc.
    2250  */
    2251 DECL_FORCE_INLINE(VBOXSTRICTRC) iemRegFinishNoFlags(PVMCPUCC pVCpu, int rcNormal) RT_NOEXCEPT
    2252 {
    2253     AssertCompile(CPUMCTX_INHIBIT_SHADOW < UINT32_MAX);
    2254     Assert(!(  pVCpu->cpum.GstCtx.eflags.uBoth
    2255              & (X86_EFL_TF | X86_EFL_RF | CPUMCTX_INHIBIT_SHADOW | CPUMCTX_DBG_HIT_DRX_MASK | CPUMCTX_DBG_DBGF_MASK)) );
    2256     RT_NOREF(pVCpu);
    2257     return rcNormal;
    2258 }
    2259 
    2260 
    2261 /**
    2262  * Updates the RIP to point to the next instruction, but does not need to clear
    2263  * EFLAGS.RF or CPUMCTX_INHIBIT_SHADOW nor check for debug flags.
    2264  *
    2265  * Only called from 64-bit code.
    2266  *
    2267  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    2268  * @param   cbInstr             The number of bytes to add.
    2269  * @param   rcNormal            VINF_SUCCESS to continue TB.
    2270  *                              VINF_IEM_REEXEC_BREAK to force TB exit when
    2271  *                              taking the wrong conditional branhc.
    2272  */
    2273 DECL_FORCE_INLINE(VBOXSTRICTRC) iemRegAddToRip64AndFinishingNoFlags(PVMCPUCC pVCpu, uint8_t cbInstr, int rcNormal) RT_NOEXCEPT
    2274 {
    2275     pVCpu->cpum.GstCtx.rip = pVCpu->cpum.GstCtx.rip + cbInstr;
    2276     return iemRegFinishNoFlags(pVCpu, rcNormal);
    2277 }
    2278 
    2279 
    2280 /**
    2281  * Updates the EIP to point to the next instruction, but does not need to clear
    2282  * EFLAGS.RF or CPUMCTX_INHIBIT_SHADOW nor check for debug flags.
    2283  *
    2284  * This is never from 64-bit code.
    2285  *
    2286  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    2287  * @param   cbInstr             The number of bytes to add.
    2288  * @param   rcNormal            VINF_SUCCESS to continue TB.
    2289  *                              VINF_IEM_REEXEC_BREAK to force TB exit when
    2290  *                              taking the wrong conditional branhc.
    2291  */
    2292 DECL_FORCE_INLINE(VBOXSTRICTRC) iemRegAddToEip32AndFinishingNoFlags(PVMCPUCC pVCpu, uint8_t cbInstr, int rcNormal) RT_NOEXCEPT
    2293 {
    2294     pVCpu->cpum.GstCtx.rip = (uint32_t)(pVCpu->cpum.GstCtx.eip + cbInstr);
    2295     return iemRegFinishNoFlags(pVCpu, rcNormal);
    2296 }
    2297 
    2298 
    2299 /**
    2300  * Updates the IP to point to the next instruction, but does not need to clear
    2301  * EFLAGS.RF or CPUMCTX_INHIBIT_SHADOW nor check for debug flags.
    2302  *
    2303  * This is only ever used from 16-bit code on a pre-386 CPU.
    2304  *
    2305  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    2306  * @param   cbInstr             The number of bytes to add.
    2307  * @param   rcNormal            VINF_SUCCESS to continue TB.
    2308  *                              VINF_IEM_REEXEC_BREAK to force TB exit when
    2309  *                              taking the wrong conditional branhc.
    2310  *
    2311  */
    2312 DECL_FORCE_INLINE(VBOXSTRICTRC) iemRegAddToIp16AndFinishingNoFlags(PVMCPUCC pVCpu, uint8_t cbInstr, int rcNormal) RT_NOEXCEPT
    2313 {
    2314     pVCpu->cpum.GstCtx.rip = (uint16_t)(pVCpu->cpum.GstCtx.ip + cbInstr);
    2315     return iemRegFinishNoFlags(pVCpu, rcNormal);
    2316 }
    2317 
    2318 
    2319 /**
    2320  * Adds a 8-bit signed jump offset to RIP from 64-bit code.
    2321  *
    2322  * May raise a \#GP(0) if the new RIP is non-canonical or outside the code
    2323  * segment limit.
    2324  *
    2325  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    2326  * @param   cbInstr             Instruction size.
    2327  * @param   offNextInstr        The offset of the next instruction.
    2328  * @param   enmEffOpSize        Effective operand size.
    2329  * @param   rcNormal            VINF_SUCCESS to continue TB.
    2330  *                              VINF_IEM_REEXEC_BREAK to force TB exit when
    2331  *                              taking the wrong conditional branhc.
    2332  */
    2333 DECL_FORCE_INLINE(VBOXSTRICTRC) iemRegRip64RelativeJumpS8AndFinishClearingRF(PVMCPUCC pVCpu, uint8_t cbInstr, int8_t offNextInstr,
    2334                                                                              IEMMODE enmEffOpSize, int rcNormal) RT_NOEXCEPT
    2335 {
    2336     Assert(IEM_IS_64BIT_CODE(pVCpu));
    2337     Assert(enmEffOpSize == IEMMODE_64BIT || enmEffOpSize == IEMMODE_16BIT);
    2338 
    2339     uint64_t uNewRip = pVCpu->cpum.GstCtx.rip + cbInstr + (int64_t)offNextInstr;
    2340     if (enmEffOpSize == IEMMODE_16BIT)
    2341         uNewRip &= UINT16_MAX;
    2342 
    2343     if (RT_LIKELY(IEM_IS_CANONICAL(uNewRip)))
    2344         pVCpu->cpum.GstCtx.rip = uNewRip;
    2345     else
    2346         return iemRaiseGeneralProtectionFault0(pVCpu);
    2347 
    2348 #ifndef IEM_WITH_CODE_TLB
    2349     iemOpcodeFlushLight(pVCpu, cbInstr);
    2350 #endif
    2351 
    2352     /*
    2353      * Clear RF and finish the instruction (maybe raise #DB).
    2354      */
    2355     return iemRegFinishClearingRF(pVCpu, rcNormal);
    2356 }
    2357 
    2358 
    2359 /**
    2360  * Adds a 8-bit signed jump offset to RIP from 64-bit code when the caller is
    2361  * sure it stays within the same page.
    2362  *
    2363  * May raise a \#GP(0) if the new RIP is non-canonical or outside the code
    2364  * segment limit.
    2365  *
    2366  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    2367  * @param   cbInstr             Instruction size.
    2368  * @param   offNextInstr        The offset of the next instruction.
    2369  * @param   enmEffOpSize        Effective operand size.
    2370  * @param   rcNormal            VINF_SUCCESS to continue TB.
    2371  *                              VINF_IEM_REEXEC_BREAK to force TB exit when
    2372  *                              taking the wrong conditional branhc.
    2373  */
    2374 DECL_FORCE_INLINE(VBOXSTRICTRC)
    2375 iemRegRip64RelativeJumpS8IntraPgAndFinishClearingRF(PVMCPUCC pVCpu, uint8_t cbInstr, int8_t offNextInstr,
    2376                                                     IEMMODE enmEffOpSize, int rcNormal) RT_NOEXCEPT
    2377 {
    2378     Assert(IEM_IS_64BIT_CODE(pVCpu));
    2379     Assert(enmEffOpSize == IEMMODE_64BIT); RT_NOREF(enmEffOpSize);
    2380 
    2381     uint64_t const uNewRip = pVCpu->cpum.GstCtx.rip + cbInstr + (int64_t)offNextInstr;
    2382     Assert((pVCpu->cpum.GstCtx.rip >> GUEST_PAGE_SHIFT) == (uNewRip >> GUEST_PAGE_SHIFT));
    2383     pVCpu->cpum.GstCtx.rip = uNewRip;
    2384 
    2385 #ifndef IEM_WITH_CODE_TLB
    2386     iemOpcodeFlushLight(pVCpu, cbInstr);
    2387 #endif
    2388 
    2389     /*
    2390      * Clear RF and finish the instruction (maybe raise #DB).
    2391      */
    2392     return iemRegFinishClearingRF(pVCpu, rcNormal);
    2393 }
    2394 
    2395 
    2396 /**
    2397  * Adds a 8-bit signed jump offset to EIP, on 386 or later from 16-bit or 32-bit
    2398  * code (never 64-bit).
    2399  *
    2400  * May raise a \#GP(0) if the new RIP is non-canonical or outside the code
    2401  * segment limit.
    2402  *
    2403  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    2404  * @param   cbInstr             Instruction size.
    2405  * @param   offNextInstr        The offset of the next instruction.
    2406  * @param   enmEffOpSize        Effective operand size.
    2407  * @param   rcNormal            VINF_SUCCESS to continue TB.
    2408  *                              VINF_IEM_REEXEC_BREAK to force TB exit when
    2409  *                              taking the wrong conditional branhc.
    2410  */
    2411 DECL_FORCE_INLINE(VBOXSTRICTRC) iemRegEip32RelativeJumpS8AndFinishClearingRF(PVMCPUCC pVCpu, uint8_t cbInstr, int8_t offNextInstr,
    2412                                                                              IEMMODE enmEffOpSize, int rcNormal) RT_NOEXCEPT
    2413 {
    2414     Assert(!IEM_IS_64BIT_CODE(pVCpu));
    2415     Assert(enmEffOpSize == IEMMODE_32BIT || enmEffOpSize == IEMMODE_16BIT);
    2416 
    2417     uint32_t uNewEip = pVCpu->cpum.GstCtx.eip + cbInstr + (int32_t)offNextInstr;
    2418     if (enmEffOpSize == IEMMODE_16BIT)
    2419         uNewEip &= UINT16_MAX;
    2420     if (RT_LIKELY(uNewEip <= pVCpu->cpum.GstCtx.cs.u32Limit))
    2421         pVCpu->cpum.GstCtx.rip = uNewEip;
    2422     else
    2423         return iemRaiseGeneralProtectionFault0(pVCpu);
    2424 
    2425 #ifndef IEM_WITH_CODE_TLB
    2426     iemOpcodeFlushLight(pVCpu, cbInstr);
    2427 #endif
    2428 
    2429     /*
    2430      * Clear RF and finish the instruction (maybe raise #DB).
    2431      */
    2432     return iemRegFinishClearingRF(pVCpu, rcNormal);
    2433 }
    2434 
    2435 
    2436 /**
    2437  * Adds a 8-bit signed jump offset to EIP, on 386 or later from FLAT 32-bit code
    2438  * (never 64-bit).
    2439  *
    2440  * May raise a \#GP(0) if the new RIP is non-canonical or outside the code
    2441  * segment limit.
    2442  *
    2443  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    2444  * @param   cbInstr             Instruction size.
    2445  * @param   offNextInstr        The offset of the next instruction.
    2446  * @param   enmEffOpSize        Effective operand size.
    2447  * @param   rcNormal            VINF_SUCCESS to continue TB.
    2448  *                              VINF_IEM_REEXEC_BREAK to force TB exit when
    2449  *                              taking the wrong conditional branhc.
    2450  */
    2451 DECL_FORCE_INLINE(VBOXSTRICTRC)
    2452  iemRegEip32RelativeJumpS8FlatAndFinishClearingRF(PVMCPUCC pVCpu, uint8_t cbInstr, int8_t offNextInstr,
    2453                                                   IEMMODE enmEffOpSize, int rcNormal) RT_NOEXCEPT
    2454 {
    2455     Assert(!IEM_IS_64BIT_CODE(pVCpu));
    2456     Assert(enmEffOpSize == IEMMODE_32BIT || enmEffOpSize == IEMMODE_16BIT);
    2457 
    2458     uint32_t uNewEip = pVCpu->cpum.GstCtx.eip + cbInstr + (int32_t)offNextInstr;
    2459     if (enmEffOpSize == IEMMODE_16BIT)
    2460         uNewEip &= UINT16_MAX;
    2461     pVCpu->cpum.GstCtx.rip = uNewEip;
    2462 
    2463 #ifndef IEM_WITH_CODE_TLB
    2464     iemOpcodeFlushLight(pVCpu, cbInstr);
    2465 #endif
    2466 
    2467     /*
    2468      * Clear RF and finish the instruction (maybe raise #DB).
    2469      */
    2470     return iemRegFinishClearingRF(pVCpu, rcNormal);
    2471 }
    2472 
    2473 
    2474 /**
    2475  * Adds a 8-bit signed jump offset to IP, on a pre-386 CPU.
    2476  *
    2477  * May raise a \#GP(0) if the new RIP is non-canonical or outside the code
    2478  * segment limit.
    2479  *
    2480  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    2481  * @param   cbInstr             Instruction size.
    2482  * @param   offNextInstr        The offset of the next instruction.
    2483  * @param   rcNormal            VINF_SUCCESS to continue TB.
    2484  *                              VINF_IEM_REEXEC_BREAK to force TB exit when
    2485  *                              taking the wrong conditional branhc.
    2486  */
    2487 DECL_FORCE_INLINE(VBOXSTRICTRC) iemRegIp16RelativeJumpS8AndFinishClearingRF(PVMCPUCC pVCpu, uint8_t cbInstr,
    2488                                                                             int8_t offNextInstr, int rcNormal) RT_NOEXCEPT
    2489 {
    2490     Assert(!IEM_IS_64BIT_CODE(pVCpu));
    2491 
    2492     uint16_t const uNewIp = pVCpu->cpum.GstCtx.ip + cbInstr + (int16_t)offNextInstr;
    2493     if (RT_LIKELY(uNewIp <= pVCpu->cpum.GstCtx.cs.u32Limit))
    2494         pVCpu->cpum.GstCtx.rip = uNewIp;
    2495     else
    2496         return iemRaiseGeneralProtectionFault0(pVCpu);
    2497 
    2498 #ifndef IEM_WITH_CODE_TLB
    2499     iemOpcodeFlushLight(pVCpu, cbInstr);
    2500 #endif
    2501 
    2502     /*
    2503      * Clear RF and finish the instruction (maybe raise #DB).
    2504      */
    2505     return iemRegFinishClearingRF(pVCpu, rcNormal);
    2506 }
    2507 
    2508 
    2509 /**
    2510  * Adds a 8-bit signed jump offset to RIP from 64-bit code, no checking or
    2511  * clearing of flags.
    2512  *
    2513  * May raise a \#GP(0) if the new RIP is non-canonical or outside the code
    2514  * segment limit.
    2515  *
    2516  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    2517  * @param   cbInstr             Instruction size.
    2518  * @param   offNextInstr        The offset of the next instruction.
    2519  * @param   enmEffOpSize        Effective operand size.
    2520  * @param   rcNormal            VINF_SUCCESS to continue TB.
    2521  *                              VINF_IEM_REEXEC_BREAK to force TB exit when
    2522  *                              taking the wrong conditional branhc.
    2523  */
    2524 DECL_FORCE_INLINE(VBOXSTRICTRC) iemRegRip64RelativeJumpS8AndFinishNoFlags(PVMCPUCC pVCpu, uint8_t cbInstr, int8_t offNextInstr,
    2525                                                                           IEMMODE enmEffOpSize, int rcNormal) RT_NOEXCEPT
    2526 {
    2527     Assert(IEM_IS_64BIT_CODE(pVCpu));
    2528     Assert(enmEffOpSize == IEMMODE_64BIT || enmEffOpSize == IEMMODE_16BIT);
    2529 
    2530     uint64_t uNewRip = pVCpu->cpum.GstCtx.rip + cbInstr + (int64_t)offNextInstr;
    2531     if (enmEffOpSize == IEMMODE_16BIT)
    2532         uNewRip &= UINT16_MAX;
    2533 
    2534     if (RT_LIKELY(IEM_IS_CANONICAL(uNewRip)))
    2535         pVCpu->cpum.GstCtx.rip = uNewRip;
    2536     else
    2537         return iemRaiseGeneralProtectionFault0(pVCpu);
    2538 
    2539 #ifndef IEM_WITH_CODE_TLB
    2540     iemOpcodeFlushLight(pVCpu, cbInstr);
    2541 #endif
    2542     return iemRegFinishNoFlags(pVCpu, rcNormal);
    2543 }
    2544 
    2545 
    2546 /**
    2547  * Adds a 8-bit signed jump offset to RIP from 64-bit code when caller is sure
    2548  * it stays within the same page, no checking or clearing of flags.
    2549  *
    2550  * May raise a \#GP(0) if the new RIP is non-canonical or outside the code
    2551  * segment limit.
    2552  *
    2553  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    2554  * @param   cbInstr             Instruction size.
    2555  * @param   offNextInstr        The offset of the next instruction.
    2556  * @param   enmEffOpSize        Effective operand size.
    2557  * @param   rcNormal            VINF_SUCCESS to continue TB.
    2558  *                              VINF_IEM_REEXEC_BREAK to force TB exit when
    2559  *                              taking the wrong conditional branhc.
    2560  */
    2561 DECL_FORCE_INLINE(VBOXSTRICTRC)
    2562 iemRegRip64RelativeJumpS8IntraPgAndFinishNoFlags(PVMCPUCC pVCpu, uint8_t cbInstr, int8_t offNextInstr,
    2563                                                  IEMMODE enmEffOpSize, int rcNormal) RT_NOEXCEPT
    2564 {
    2565     Assert(IEM_IS_64BIT_CODE(pVCpu));
    2566     Assert(enmEffOpSize == IEMMODE_64BIT); RT_NOREF(enmEffOpSize);
    2567 
    2568     uint64_t const uNewRip = pVCpu->cpum.GstCtx.rip + cbInstr + (int64_t)offNextInstr;
    2569     Assert((pVCpu->cpum.GstCtx.rip >> GUEST_PAGE_SHIFT) == (uNewRip >> GUEST_PAGE_SHIFT));
    2570     pVCpu->cpum.GstCtx.rip = uNewRip;
    2571 
    2572 #ifndef IEM_WITH_CODE_TLB
    2573     iemOpcodeFlushLight(pVCpu, cbInstr);
    2574 #endif
    2575     return iemRegFinishNoFlags(pVCpu, rcNormal);
    2576 }
    2577 
    2578 
    2579 /**
    2580  * Adds a 8-bit signed jump offset to EIP, on 386 or later from 16-bit or 32-bit
    2581  * code (never 64-bit), no checking or clearing of flags.
    2582  *
    2583  * May raise a \#GP(0) if the new RIP is non-canonical or outside the code
    2584  * segment limit.
    2585  *
    2586  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    2587  * @param   cbInstr             Instruction size.
    2588  * @param   offNextInstr        The offset of the next instruction.
    2589  * @param   enmEffOpSize        Effective operand size.
    2590  * @param   rcNormal            VINF_SUCCESS to continue TB.
    2591  *                              VINF_IEM_REEXEC_BREAK to force TB exit when
    2592  *                              taking the wrong conditional branhc.
    2593  */
    2594 DECL_FORCE_INLINE(VBOXSTRICTRC) iemRegEip32RelativeJumpS8AndFinishNoFlags(PVMCPUCC pVCpu, uint8_t cbInstr, int8_t offNextInstr,
    2595                                                                           IEMMODE enmEffOpSize, int rcNormal) RT_NOEXCEPT
    2596 {
    2597     Assert(!IEM_IS_64BIT_CODE(pVCpu));
    2598     Assert(enmEffOpSize == IEMMODE_32BIT || enmEffOpSize == IEMMODE_16BIT);
    2599 
    2600     uint32_t uNewEip = pVCpu->cpum.GstCtx.eip + cbInstr + (int32_t)offNextInstr;
    2601     if (enmEffOpSize == IEMMODE_16BIT)
    2602         uNewEip &= UINT16_MAX;
    2603     if (RT_LIKELY(uNewEip <= pVCpu->cpum.GstCtx.cs.u32Limit))
    2604         pVCpu->cpum.GstCtx.rip = uNewEip;
    2605     else
    2606         return iemRaiseGeneralProtectionFault0(pVCpu);
    2607 
    2608 #ifndef IEM_WITH_CODE_TLB
    2609     iemOpcodeFlushLight(pVCpu, cbInstr);
    2610 #endif
    2611     return iemRegFinishNoFlags(pVCpu, rcNormal);
    2612 }
    2613 
    2614 
    2615 /**
    2616  * Adds a 8-bit signed jump offset to EIP, on 386 or later from flat 32-bit code
    2617  * (never 64-bit), no checking or clearing of flags.
    2618  *
    2619  * May raise a \#GP(0) if the new RIP is non-canonical or outside the code
    2620  * segment limit.
    2621  *
    2622  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    2623  * @param   cbInstr             Instruction size.
    2624  * @param   offNextInstr        The offset of the next instruction.
    2625  * @param   enmEffOpSize        Effective operand size.
    2626  * @param   rcNormal            VINF_SUCCESS to continue TB.
    2627  *                              VINF_IEM_REEXEC_BREAK to force TB exit when
    2628  *                              taking the wrong conditional branhc.
    2629  */
    2630 DECL_FORCE_INLINE(VBOXSTRICTRC)
    2631 iemRegEip32RelativeJumpS8FlatAndFinishNoFlags(PVMCPUCC pVCpu, uint8_t cbInstr, int8_t offNextInstr,
    2632                                               IEMMODE enmEffOpSize, int rcNormal) RT_NOEXCEPT
    2633 {
    2634     Assert(!IEM_IS_64BIT_CODE(pVCpu));
    2635     Assert(enmEffOpSize == IEMMODE_32BIT || enmEffOpSize == IEMMODE_16BIT);
    2636 
    2637     uint32_t uNewEip = pVCpu->cpum.GstCtx.eip + cbInstr + (int32_t)offNextInstr;
    2638     if (enmEffOpSize == IEMMODE_16BIT)
    2639         uNewEip &= UINT16_MAX;
    2640     pVCpu->cpum.GstCtx.rip = uNewEip;
    2641 
    2642 #ifndef IEM_WITH_CODE_TLB
    2643     iemOpcodeFlushLight(pVCpu, cbInstr);
    2644 #endif
    2645     return iemRegFinishNoFlags(pVCpu, rcNormal);
    2646 }
    2647 
    2648 
    2649 /**
    2650  * Adds a 8-bit signed jump offset to IP, on a pre-386 CPU, no checking or
    2651  * clearing of flags.
    2652  *
    2653  * May raise a \#GP(0) if the new RIP is non-canonical or outside the code
    2654  * segment limit.
    2655  *
    2656  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    2657  * @param   cbInstr             Instruction size.
    2658  * @param   offNextInstr        The offset of the next instruction.
    2659  * @param   rcNormal            VINF_SUCCESS to continue TB.
    2660  *                              VINF_IEM_REEXEC_BREAK to force TB exit when
    2661  *                              taking the wrong conditional branhc.
    2662  */
    2663 DECL_FORCE_INLINE(VBOXSTRICTRC) iemRegIp16RelativeJumpS8AndFinishNoFlags(PVMCPUCC pVCpu, uint8_t cbInstr,
    2664                                                                          int8_t offNextInstr, int rcNormal) RT_NOEXCEPT
    2665 {
    2666     Assert(!IEM_IS_64BIT_CODE(pVCpu));
    2667 
    2668     uint16_t const uNewIp = pVCpu->cpum.GstCtx.ip + cbInstr + (int16_t)offNextInstr;
    2669     if (RT_LIKELY(uNewIp <= pVCpu->cpum.GstCtx.cs.u32Limit))
    2670         pVCpu->cpum.GstCtx.rip = uNewIp;
    2671     else
    2672         return iemRaiseGeneralProtectionFault0(pVCpu);
    2673 
    2674 #ifndef IEM_WITH_CODE_TLB
    2675     iemOpcodeFlushLight(pVCpu, cbInstr);
    2676 #endif
    2677     return iemRegFinishNoFlags(pVCpu, rcNormal);
    2678 }
    2679 
    2680 
    2681 /**
    2682  * Adds a 16-bit signed jump offset to RIP from 64-bit code.
    2683  *
    2684  * @returns Strict VBox status code.
    2685  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    2686  * @param   cbInstr             Instruction size.
    2687  * @param   offNextInstr        The offset of the next instruction.
    2688  * @param   rcNormal            VINF_SUCCESS to continue TB.
    2689  *                              VINF_IEM_REEXEC_BREAK to force TB exit when
    2690  *                              taking the wrong conditional branhc.
    2691  */
    2692 DECL_FORCE_INLINE(VBOXSTRICTRC) iemRegRip64RelativeJumpS16AndFinishClearingRF(PVMCPUCC pVCpu, uint8_t cbInstr,
    2693                                                                               int16_t offNextInstr, int rcNormal) RT_NOEXCEPT
    2694 {
    2695     Assert(IEM_IS_64BIT_CODE(pVCpu));
    2696 
    2697     pVCpu->cpum.GstCtx.rip = (uint16_t)(pVCpu->cpum.GstCtx.ip + cbInstr + offNextInstr);
    2698 
    2699 #ifndef IEM_WITH_CODE_TLB
    2700     iemOpcodeFlushLight(pVCpu, cbInstr);
    2701 #endif
    2702 
    2703     /*
    2704      * Clear RF and finish the instruction (maybe raise #DB).
    2705      */
    2706     return iemRegFinishClearingRF(pVCpu, rcNormal);
    2707 }
    2708 
    2709 
    2710 /**
    2711  * Adds a 16-bit signed jump offset to EIP from 16-bit or 32-bit code.
    2712  *
    2713  * May raise a \#GP(0) if the new RIP is non-canonical or outside the code
    2714  * segment limit.
    2715  *
    2716  * @returns Strict VBox status code.
    2717  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    2718  * @param   cbInstr             Instruction size.
    2719  * @param   offNextInstr        The offset of the next instruction.
    2720  * @param   rcNormal            VINF_SUCCESS to continue TB.
    2721  *                              VINF_IEM_REEXEC_BREAK to force TB exit when
    2722  *                              taking the wrong conditional branhc.
    2723  *
    2724  * @note    This is also used by 16-bit code in pre-386 mode, as the code is
    2725  *          identical.
    2726  */
    2727 DECL_FORCE_INLINE(VBOXSTRICTRC) iemRegEip32RelativeJumpS16AndFinishClearingRF(PVMCPUCC pVCpu, uint8_t cbInstr,
    2728                                                                               int16_t offNextInstr, int rcNormal) RT_NOEXCEPT
    2729 {
    2730     Assert(!IEM_IS_64BIT_CODE(pVCpu));
    2731 
    2732     uint16_t const uNewIp = pVCpu->cpum.GstCtx.ip + cbInstr + offNextInstr;
    2733     if (RT_LIKELY(uNewIp <= pVCpu->cpum.GstCtx.cs.u32Limit))
    2734         pVCpu->cpum.GstCtx.rip = uNewIp;
    2735     else
    2736         return iemRaiseGeneralProtectionFault0(pVCpu);
    2737 
    2738 #ifndef IEM_WITH_CODE_TLB
    2739     iemOpcodeFlushLight(pVCpu, cbInstr);
    2740 #endif
    2741 
    2742     /*
    2743      * Clear RF and finish the instruction (maybe raise #DB).
    2744      */
    2745     return iemRegFinishClearingRF(pVCpu, rcNormal);
    2746 }
    2747 
    2748 
    2749 /**
    2750  * Adds a 16-bit signed jump offset to EIP from FLAT 32-bit code.
    2751  *
    2752  * May raise a \#GP(0) if the new RIP is non-canonical or outside the code
    2753  * segment limit.
    2754  *
    2755  * @returns Strict VBox status code.
    2756  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    2757  * @param   cbInstr             Instruction size.
    2758  * @param   offNextInstr        The offset of the next instruction.
    2759  * @param   rcNormal            VINF_SUCCESS to continue TB.
    2760  *                              VINF_IEM_REEXEC_BREAK to force TB exit when
    2761  *                              taking the wrong conditional branhc.
    2762  *
    2763  * @note    This is also used by 16-bit code in pre-386 mode, as the code is
    2764  *          identical.
    2765  */
    2766 DECL_FORCE_INLINE(VBOXSTRICTRC) iemRegEip32RelativeJumpS16FlatAndFinishClearingRF(PVMCPUCC pVCpu, uint8_t cbInstr,
    2767                                                                                   int16_t offNextInstr, int rcNormal) RT_NOEXCEPT
    2768 {
    2769     Assert(!IEM_IS_64BIT_CODE(pVCpu));
    2770 
    2771     uint16_t const uNewIp = pVCpu->cpum.GstCtx.ip + cbInstr + offNextInstr;
    2772     pVCpu->cpum.GstCtx.rip = uNewIp;
    2773 
    2774 #ifndef IEM_WITH_CODE_TLB
    2775     iemOpcodeFlushLight(pVCpu, cbInstr);
    2776 #endif
    2777 
    2778     /*
    2779      * Clear RF and finish the instruction (maybe raise #DB).
    2780      */
    2781     return iemRegFinishClearingRF(pVCpu, rcNormal);
    2782 }
    2783 
    2784 
    2785 /**
    2786  * Adds a 16-bit signed jump offset to RIP from 64-bit code, no checking or
    2787  * clearing of flags.
    2788  *
    2789  * @returns Strict VBox status code.
    2790  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    2791  * @param   cbInstr             Instruction size.
    2792  * @param   offNextInstr        The offset of the next instruction.
    2793  * @param   rcNormal            VINF_SUCCESS to continue TB.
    2794  *                              VINF_IEM_REEXEC_BREAK to force TB exit when
    2795  *                              taking the wrong conditional branhc.
    2796  */
    2797 DECL_FORCE_INLINE(VBOXSTRICTRC) iemRegRip64RelativeJumpS16AndFinishNoFlags(PVMCPUCC pVCpu, uint8_t cbInstr,
    2798                                                                            int16_t offNextInstr, int rcNormal) RT_NOEXCEPT
    2799 {
    2800     Assert(IEM_IS_64BIT_CODE(pVCpu));
    2801 
    2802     pVCpu->cpum.GstCtx.rip = (uint16_t)(pVCpu->cpum.GstCtx.ip + cbInstr + offNextInstr);
    2803 
    2804 #ifndef IEM_WITH_CODE_TLB
    2805     iemOpcodeFlushLight(pVCpu, cbInstr);
    2806 #endif
    2807     return iemRegFinishNoFlags(pVCpu, rcNormal);
    2808 }
    2809 
    2810 
    2811 /**
    2812  * Adds a 16-bit signed jump offset to EIP from 16-bit or 32-bit code,
    2813  * no checking or clearing of flags.
    2814  *
    2815  * May raise a \#GP(0) if the new RIP is non-canonical or outside the code
    2816  * segment limit.
    2817  *
    2818  * @returns Strict VBox status code.
    2819  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    2820  * @param   cbInstr             Instruction size.
    2821  * @param   offNextInstr        The offset of the next instruction.
    2822  * @param   rcNormal            VINF_SUCCESS to continue TB.
    2823  *                              VINF_IEM_REEXEC_BREAK to force TB exit when
    2824  *                              taking the wrong conditional branhc.
    2825  *
    2826  * @note    This is also used by 16-bit code in pre-386 mode, as the code is
    2827  *          identical.
    2828  */
    2829 DECL_FORCE_INLINE(VBOXSTRICTRC) iemRegEip32RelativeJumpS16AndFinishNoFlags(PVMCPUCC pVCpu, uint8_t cbInstr,
    2830                                                                            int16_t offNextInstr, int rcNormal) RT_NOEXCEPT
    2831 {
    2832     Assert(!IEM_IS_64BIT_CODE(pVCpu));
    2833 
    2834     uint16_t const uNewIp = pVCpu->cpum.GstCtx.ip + cbInstr + offNextInstr;
    2835     if (RT_LIKELY(uNewIp <= pVCpu->cpum.GstCtx.cs.u32Limit))
    2836         pVCpu->cpum.GstCtx.rip = uNewIp;
    2837     else
    2838         return iemRaiseGeneralProtectionFault0(pVCpu);
    2839 
    2840 #ifndef IEM_WITH_CODE_TLB
    2841     iemOpcodeFlushLight(pVCpu, cbInstr);
    2842 #endif
    2843     return iemRegFinishNoFlags(pVCpu, rcNormal);
    2844 }
    2845 
    2846 
    2847 /**
    2848  * Adds a 16-bit signed jump offset to EIP from FLAT 32-bit code, no checking or
    2849  * clearing of flags.
    2850  *
    2851  * May raise a \#GP(0) if the new RIP is non-canonical or outside the code
    2852  * segment limit.
    2853  *
    2854  * @returns Strict VBox status code.
    2855  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    2856  * @param   cbInstr             Instruction size.
    2857  * @param   offNextInstr        The offset of the next instruction.
    2858  * @param   rcNormal            VINF_SUCCESS to continue TB.
    2859  *                              VINF_IEM_REEXEC_BREAK to force TB exit when
    2860  *                              taking the wrong conditional branhc.
    2861  *
    2862  * @note    This is also used by 16-bit code in pre-386 mode, as the code is
    2863  *          identical.
    2864  */
    2865 DECL_FORCE_INLINE(VBOXSTRICTRC) iemRegEip32RelativeJumpS16FlatAndFinishNoFlags(PVMCPUCC pVCpu, uint8_t cbInstr,
    2866                                                                                int16_t offNextInstr, int rcNormal) RT_NOEXCEPT
    2867 {
    2868     Assert(!IEM_IS_64BIT_CODE(pVCpu));
    2869 
    2870     uint16_t const uNewIp = pVCpu->cpum.GstCtx.ip + cbInstr + offNextInstr;
    2871     pVCpu->cpum.GstCtx.rip = uNewIp;
    2872 
    2873 #ifndef IEM_WITH_CODE_TLB
    2874     iemOpcodeFlushLight(pVCpu, cbInstr);
    2875 #endif
    2876     return iemRegFinishNoFlags(pVCpu, rcNormal);
    2877 }
    2878 
    2879 
    2880 /**
    2881  * Adds a 32-bit signed jump offset to RIP from 64-bit code.
    2882  *
    2883  * May raise a \#GP(0) if the new RIP is non-canonical or outside the code
    2884  * segment limit.
    2885  *
    2886  * We ASSUME that the effective operand size is 64-bit here, as 16-bit is the
    2887  * only alternative for relative jumps in 64-bit code and that is already
    2888  * handled in the decoder stage.
    2889  *
    2890  * @returns Strict VBox status code.
    2891  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    2892  * @param   cbInstr             Instruction size.
    2893  * @param   offNextInstr        The offset of the next instruction.
    2894  * @param   rcNormal            VINF_SUCCESS to continue TB.
    2895  *                              VINF_IEM_REEXEC_BREAK to force TB exit when
    2896  *                              taking the wrong conditional branhc.
    2897  */
    2898 DECL_FORCE_INLINE(VBOXSTRICTRC) iemRegRip64RelativeJumpS32AndFinishClearingRF(PVMCPUCC pVCpu, uint8_t cbInstr,
    2899                                                                               int32_t offNextInstr, int rcNormal) RT_NOEXCEPT
    2900 {
    2901     Assert(IEM_IS_64BIT_CODE(pVCpu));
    2902 
    2903     uint64_t const uNewRip = pVCpu->cpum.GstCtx.rip + cbInstr + (int64_t)offNextInstr;
    2904     if (RT_LIKELY(IEM_IS_CANONICAL(uNewRip)))
    2905         pVCpu->cpum.GstCtx.rip = uNewRip;
    2906     else
    2907         return iemRaiseGeneralProtectionFault0(pVCpu);
    2908 
    2909 #ifndef IEM_WITH_CODE_TLB
    2910     iemOpcodeFlushLight(pVCpu, cbInstr);
    2911 #endif
    2912 
    2913     /*
    2914      * Clear RF and finish the instruction (maybe raise #DB).
    2915      */
    2916     return iemRegFinishClearingRF(pVCpu, rcNormal);
    2917 }
    2918 
    2919 
    2920 /**
    2921  * Adds a 32-bit signed jump offset to RIP from 64-bit code when the caller is
    2922  * sure the target is in the same page.
    2923  *
    2924  * May raise a \#GP(0) if the new RIP is non-canonical or outside the code
    2925  * segment limit.
    2926  *
    2927  * We ASSUME that the effective operand size is 64-bit here, as 16-bit is the
    2928  * only alternative for relative jumps in 64-bit code and that is already
    2929  * handled in the decoder stage.
    2930  *
    2931  * @returns Strict VBox status code.
    2932  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    2933  * @param   cbInstr             Instruction size.
    2934  * @param   offNextInstr        The offset of the next instruction.
    2935  * @param   rcNormal            VINF_SUCCESS to continue TB.
    2936  *                              VINF_IEM_REEXEC_BREAK to force TB exit when
    2937  *                              taking the wrong conditional branhc.
    2938  */
    2939 DECL_FORCE_INLINE(VBOXSTRICTRC)
    2940 iemRegRip64RelativeJumpS32IntraPgAndFinishClearingRF(PVMCPUCC pVCpu, uint8_t cbInstr,
    2941                                                      int32_t offNextInstr, int rcNormal) RT_NOEXCEPT
    2942 {
    2943     Assert(IEM_IS_64BIT_CODE(pVCpu));
    2944 
    2945     uint64_t const uNewRip = pVCpu->cpum.GstCtx.rip + cbInstr + (int64_t)offNextInstr;
    2946     Assert((pVCpu->cpum.GstCtx.rip >> GUEST_PAGE_SHIFT) == (uNewRip >> GUEST_PAGE_SHIFT));
    2947     pVCpu->cpum.GstCtx.rip = uNewRip;
    2948 
    2949 #ifndef IEM_WITH_CODE_TLB
    2950     iemOpcodeFlushLight(pVCpu, cbInstr);
    2951 #endif
    2952 
    2953     /*
    2954      * Clear RF and finish the instruction (maybe raise #DB).
    2955      */
    2956     return iemRegFinishClearingRF(pVCpu, rcNormal);
    2957 }
    2958 
    2959 
    2960 /**
    2961  * Adds a 32-bit signed jump offset to RIP from 64-bit code.
    2962  *
    2963  * May raise a \#GP(0) if the new RIP is non-canonical or outside the code
    2964  * segment limit.
    2965  *
    2966  * We ASSUME that the effective operand size is 32-bit here, as 16-bit is the
    2967  * only alternative for relative jumps in 32-bit code and that is already
    2968  * handled in the decoder stage.
    2969  *
    2970  * @returns Strict VBox status code.
    2971  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    2972  * @param   cbInstr             Instruction size.
    2973  * @param   offNextInstr        The offset of the next instruction.
    2974  * @param   rcNormal            VINF_SUCCESS to continue TB.
    2975  *                              VINF_IEM_REEXEC_BREAK to force TB exit when
    2976  *                              taking the wrong conditional branhc.
    2977  */
    2978 DECL_FORCE_INLINE(VBOXSTRICTRC) iemRegEip32RelativeJumpS32AndFinishClearingRF(PVMCPUCC pVCpu, uint8_t cbInstr,
    2979                                                                               int32_t offNextInstr, int rcNormal) RT_NOEXCEPT
    2980 {
    2981     Assert(!IEM_IS_64BIT_CODE(pVCpu));
    2982     Assert(pVCpu->cpum.GstCtx.rip <= UINT32_MAX);
    2983 
    2984     uint32_t const uNewEip = pVCpu->cpum.GstCtx.eip + cbInstr + offNextInstr;
    2985     if (RT_LIKELY(uNewEip <= pVCpu->cpum.GstCtx.cs.u32Limit))
    2986         pVCpu->cpum.GstCtx.rip = uNewEip;
    2987     else
    2988         return iemRaiseGeneralProtectionFault0(pVCpu);
    2989 
    2990 #ifndef IEM_WITH_CODE_TLB
    2991     iemOpcodeFlushLight(pVCpu, cbInstr);
    2992 #endif
    2993 
    2994     /*
    2995      * Clear RF and finish the instruction (maybe raise #DB).
    2996      */
    2997     return iemRegFinishClearingRF(pVCpu, rcNormal);
    2998 }
    2999 
    3000 
    3001 /**
    3002  * Adds a 32-bit signed jump offset to RIP from FLAT 32-bit code.
    3003  *
    3004  * May raise a \#GP(0) if the new RIP is non-canonical or outside the code
    3005  * segment limit.
    3006  *
    3007  * We ASSUME that the effective operand size is 32-bit here, as 16-bit is the
    3008  * only alternative for relative jumps in 32-bit code and that is already
    3009  * handled in the decoder stage.
    3010  *
    3011  * @returns Strict VBox status code.
    3012  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    3013  * @param   cbInstr             Instruction size.
    3014  * @param   offNextInstr        The offset of the next instruction.
    3015  * @param   rcNormal            VINF_SUCCESS to continue TB.
    3016  *                              VINF_IEM_REEXEC_BREAK to force TB exit when
    3017  *                              taking the wrong conditional branhc.
    3018  */
    3019 DECL_FORCE_INLINE(VBOXSTRICTRC) iemRegEip32RelativeJumpS32FlatAndFinishClearingRF(PVMCPUCC pVCpu, uint8_t cbInstr,
    3020                                                                                   int32_t offNextInstr, int rcNormal) RT_NOEXCEPT
    3021 {
    3022     Assert(!IEM_IS_64BIT_CODE(pVCpu));
    3023     Assert(pVCpu->cpum.GstCtx.rip <= UINT32_MAX);
    3024 
    3025     uint32_t const uNewEip = pVCpu->cpum.GstCtx.eip + cbInstr + offNextInstr;
    3026     pVCpu->cpum.GstCtx.rip = uNewEip;
    3027 
    3028 #ifndef IEM_WITH_CODE_TLB
    3029     iemOpcodeFlushLight(pVCpu, cbInstr);
    3030 #endif
    3031 
    3032     /*
    3033      * Clear RF and finish the instruction (maybe raise #DB).
    3034      */
    3035     return iemRegFinishClearingRF(pVCpu, rcNormal);
    3036 }
    3037 
    3038 
    3039 
    3040 /**
    3041  * Adds a 32-bit signed jump offset to RIP from 64-bit code, no checking or
    3042  * clearing of flags.
    3043  *
    3044  * May raise a \#GP(0) if the new RIP is non-canonical or outside the code
    3045  * segment limit.
    3046  *
    3047  * We ASSUME that the effective operand size is 64-bit here, as 16-bit is the
    3048  * only alternative for relative jumps in 64-bit code and that is already
    3049  * handled in the decoder stage.
    3050  *
    3051  * @returns Strict VBox status code.
    3052  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    3053  * @param   cbInstr             Instruction size.
    3054  * @param   offNextInstr        The offset of the next instruction.
    3055  * @param   rcNormal            VINF_SUCCESS to continue TB.
    3056  *                              VINF_IEM_REEXEC_BREAK to force TB exit when
    3057  *                              taking the wrong conditional branhc.
    3058  */
    3059 DECL_FORCE_INLINE(VBOXSTRICTRC) iemRegRip64RelativeJumpS32AndFinishNoFlags(PVMCPUCC pVCpu, uint8_t cbInstr,
    3060                                                                            int32_t offNextInstr, int rcNormal) RT_NOEXCEPT
    3061 {
    3062     Assert(IEM_IS_64BIT_CODE(pVCpu));
    3063 
    3064     uint64_t const uNewRip = pVCpu->cpum.GstCtx.rip + cbInstr + (int64_t)offNextInstr;
    3065     if (RT_LIKELY(IEM_IS_CANONICAL(uNewRip)))
    3066         pVCpu->cpum.GstCtx.rip = uNewRip;
    3067     else
    3068         return iemRaiseGeneralProtectionFault0(pVCpu);
    3069 
    3070 #ifndef IEM_WITH_CODE_TLB
    3071     iemOpcodeFlushLight(pVCpu, cbInstr);
    3072 #endif
    3073     return iemRegFinishNoFlags(pVCpu, rcNormal);
    3074 }
    3075 
    3076 
    3077 /**
    3078  * Adds a 32-bit signed jump offset to RIP from 64-bit code when the caller is
    3079  * sure it stays within the same page, no checking or clearing of flags.
    3080  *
    3081  * May raise a \#GP(0) if the new RIP is non-canonical or outside the code
    3082  * segment limit.
    3083  *
    3084  * We ASSUME that the effective operand size is 64-bit here, as 16-bit is the
    3085  * only alternative for relative jumps in 64-bit code and that is already
    3086  * handled in the decoder stage.
    3087  *
    3088  * @returns Strict VBox status code.
    3089  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    3090  * @param   cbInstr             Instruction size.
    3091  * @param   offNextInstr        The offset of the next instruction.
    3092  * @param   rcNormal            VINF_SUCCESS to continue TB.
    3093  *                              VINF_IEM_REEXEC_BREAK to force TB exit when
    3094  *                              taking the wrong conditional branhc.
    3095  */
    3096 DECL_FORCE_INLINE(VBOXSTRICTRC)
    3097 iemRegRip64RelativeJumpS32IntraPgAndFinishNoFlags(PVMCPUCC pVCpu, uint8_t cbInstr, int32_t offNextInstr, int rcNormal) RT_NOEXCEPT
    3098 {
    3099     Assert(IEM_IS_64BIT_CODE(pVCpu));
    3100 
    3101     uint64_t const uNewRip = pVCpu->cpum.GstCtx.rip + cbInstr + (int64_t)offNextInstr;
    3102     Assert((pVCpu->cpum.GstCtx.rip >> GUEST_PAGE_SHIFT) == (uNewRip >> GUEST_PAGE_SHIFT));
    3103     pVCpu->cpum.GstCtx.rip = uNewRip;
    3104 
    3105 #ifndef IEM_WITH_CODE_TLB
    3106     iemOpcodeFlushLight(pVCpu, cbInstr);
    3107 #endif
    3108     return iemRegFinishNoFlags(pVCpu, rcNormal);
    3109 }
    3110 
    3111 
    3112 /**
    3113  * Adds a 32-bit signed jump offset to RIP from 32-bit code, no checking or
    3114  * clearing of flags.
    3115  *
    3116  * May raise a \#GP(0) if the new RIP is non-canonical or outside the code
    3117  * segment limit.
    3118  *
    3119  * We ASSUME that the effective operand size is 32-bit here, as 16-bit is the
    3120  * only alternative for relative jumps in 32-bit code and that is already
    3121  * handled in the decoder stage.
    3122  *
    3123  * @returns Strict VBox status code.
    3124  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    3125  * @param   cbInstr             Instruction size.
    3126  * @param   offNextInstr        The offset of the next instruction.
    3127  * @param   rcNormal            VINF_SUCCESS to continue TB.
    3128  *                              VINF_IEM_REEXEC_BREAK to force TB exit when
    3129  *                              taking the wrong conditional branhc.
    3130  */
    3131 DECL_FORCE_INLINE(VBOXSTRICTRC) iemRegEip32RelativeJumpS32AndFinishNoFlags(PVMCPUCC pVCpu, uint8_t cbInstr,
    3132                                                                            int32_t offNextInstr, int rcNormal) RT_NOEXCEPT
    3133 {
    3134     Assert(!IEM_IS_64BIT_CODE(pVCpu));
    3135     Assert(pVCpu->cpum.GstCtx.rip <= UINT32_MAX);
    3136 
    3137     uint32_t const uNewEip = pVCpu->cpum.GstCtx.eip + cbInstr + offNextInstr;
    3138     if (RT_LIKELY(uNewEip <= pVCpu->cpum.GstCtx.cs.u32Limit))
    3139         pVCpu->cpum.GstCtx.rip = uNewEip;
    3140     else
    3141         return iemRaiseGeneralProtectionFault0(pVCpu);
    3142 
    3143 #ifndef IEM_WITH_CODE_TLB
    3144     iemOpcodeFlushLight(pVCpu, cbInstr);
    3145 #endif
    3146     return iemRegFinishNoFlags(pVCpu, rcNormal);
    3147 }
    3148 
    3149 
    3150 /**
    3151  * Adds a 32-bit signed jump offset to RIP from FLAT 32-bit code, no checking or
    3152  * clearing of flags.
    3153  *
    3154  * May raise a \#GP(0) if the new RIP is non-canonical or outside the code
    3155  * segment limit.
    3156  *
    3157  * We ASSUME that the effective operand size is 32-bit here, as 16-bit is the
    3158  * only alternative for relative jumps in 32-bit code and that is already
    3159  * handled in the decoder stage.
    3160  *
    3161  * @returns Strict VBox status code.
    3162  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    3163  * @param   cbInstr             Instruction size.
    3164  * @param   offNextInstr        The offset of the next instruction.
    3165  * @param   rcNormal            VINF_SUCCESS to continue TB.
    3166  *                              VINF_IEM_REEXEC_BREAK to force TB exit when
    3167  *                              taking the wrong conditional branhc.
    3168  */
    3169 DECL_FORCE_INLINE(VBOXSTRICTRC) iemRegEip32RelativeJumpS32FlatAndFinishNoFlags(PVMCPUCC pVCpu, uint8_t cbInstr,
    3170                                                                                int32_t offNextInstr, int rcNormal) RT_NOEXCEPT
    3171 {
    3172     Assert(!IEM_IS_64BIT_CODE(pVCpu));
    3173     Assert(pVCpu->cpum.GstCtx.rip <= UINT32_MAX);
    3174 
    3175     uint32_t const uNewEip = pVCpu->cpum.GstCtx.eip + cbInstr + offNextInstr;
    3176     pVCpu->cpum.GstCtx.rip = uNewEip;
    3177 
    3178 #ifndef IEM_WITH_CODE_TLB
    3179     iemOpcodeFlushLight(pVCpu, cbInstr);
    3180 #endif
    3181     return iemRegFinishNoFlags(pVCpu, rcNormal);
    3182 }
    3183 
    3184 
    3185 /**
    3186  * Extended version of iemFinishInstructionWithFlagsSet that goes with
    3187  * iemRegAddToRipAndFinishingClearingRfEx.
    3188  *
    3189  * See iemFinishInstructionWithFlagsSet() for details.
    3190  */
    3191 static VBOXSTRICTRC iemFinishInstructionWithTfSet(PVMCPUCC pVCpu) RT_NOEXCEPT
    3192 {
    3193     /*
    3194      * Raise a #DB.
    3195      */
    3196     IEM_CTX_IMPORT_RET(pVCpu, CPUMCTX_EXTRN_DR6);
    3197     pVCpu->cpum.GstCtx.dr[6] &= ~X86_DR6_B_MASK;
    3198     pVCpu->cpum.GstCtx.dr[6] |= X86_DR6_BS
    3199                              | (   (pVCpu->cpum.GstCtx.eflags.uBoth & CPUMCTX_DBG_HIT_DRX_MASK_NONSILENT)
    3200                                 >> CPUMCTX_DBG_HIT_DRX_SHIFT);
    3201     /** @todo Do we set all pending \#DB events, or just one? */
    3202     LogFlowFunc(("Guest #DB fired at %04X:%016llX: DR6=%08X, RFLAGS=%16RX64 (popf)\n",
    3203                  pVCpu->cpum.GstCtx.cs.Sel, pVCpu->cpum.GstCtx.rip, (unsigned)pVCpu->cpum.GstCtx.dr[6],
    3204                  pVCpu->cpum.GstCtx.rflags.uBoth));
    3205     pVCpu->cpum.GstCtx.eflags.uBoth &= ~(X86_EFL_RF | CPUMCTX_INHIBIT_SHADOW | CPUMCTX_DBG_HIT_DRX_MASK | CPUMCTX_DBG_DBGF_MASK);
    3206     return iemRaiseDebugException(pVCpu);
    3207 }
    3208 
    3209 
    3210 /**
    3211  * Extended version of iemRegAddToRipAndFinishingClearingRF for use by POPF and
    3212  * others potentially updating EFLAGS.TF.
    3213  *
    3214  * The single step event must be generated using the TF value at the start of
    3215  * the instruction, not the new value set by it.
    3216  *
    3217  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    3218  * @param   cbInstr             The number of bytes to add.
    3219  * @param   fEflOld             The EFLAGS at the start of the instruction
    3220  *                              execution.
    3221  */
    3222 DECLINLINE(VBOXSTRICTRC) iemRegAddToRipAndFinishingClearingRfEx(PVMCPUCC pVCpu, uint8_t cbInstr, uint32_t fEflOld) RT_NOEXCEPT
    3223 {
    3224     iemRegAddToRip(pVCpu, cbInstr);
    3225     if (!(fEflOld & X86_EFL_TF))
    3226     {
    3227         /* Specialized iemRegFinishClearingRF edition here that doesn't check X86_EFL_TF. */
    3228         AssertCompile(CPUMCTX_INHIBIT_SHADOW < UINT32_MAX);
    3229         if (RT_LIKELY(!(  pVCpu->cpum.GstCtx.eflags.uBoth
    3230                         & (X86_EFL_RF | CPUMCTX_INHIBIT_SHADOW | CPUMCTX_DBG_HIT_DRX_MASK | CPUMCTX_DBG_DBGF_MASK)) ))
    3231             return VINF_SUCCESS;
    3232         return iemFinishInstructionWithFlagsSet<0 /*a_fTF*/>(pVCpu, VINF_SUCCESS); /* TF=0, so ignore it.  */
    3233     }
    3234     return iemFinishInstructionWithTfSet(pVCpu);
    3235 }
    3236 
    3237 
    3238 #ifndef IEM_WITH_OPAQUE_DECODER_STATE
    3239 /**
    3240  * Updates the RIP/EIP/IP to point to the next instruction and clears EFLAGS.RF.
    3241  *
    3242  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    3243  */
    3244 DECLINLINE(VBOXSTRICTRC) iemRegUpdateRipAndFinishClearingRF(PVMCPUCC pVCpu) RT_NOEXCEPT
    3245 {
    3246     return iemRegAddToRipAndFinishingClearingRF(pVCpu, IEM_GET_INSTR_LEN(pVCpu));
    3247 }
    3248 #endif
    3249 
    3250 
    3251 #ifdef IEM_WITH_CODE_TLB
    3252 
    3253 /**
    3254  * Performs a near jump to the specified address, no checking or clearing of
    3255  * flags
    3256  *
    3257  * May raise a \#GP(0) if the new IP outside the code segment limit.
    3258  *
    3259  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    3260  * @param   uNewIp              The new IP value.
    3261  */
    3262 DECLINLINE(VBOXSTRICTRC) iemRegRipJumpU16AndFinishNoFlags(PVMCPUCC pVCpu, uint16_t uNewIp) RT_NOEXCEPT
    3263 {
    3264     if (RT_LIKELY(   uNewIp <= pVCpu->cpum.GstCtx.cs.u32Limit
    3265                   || IEM_IS_64BIT_CODE(pVCpu) /* no limit checks in 64-bit mode */))
    3266         pVCpu->cpum.GstCtx.rip = uNewIp;
    3267     else
    3268         return iemRaiseGeneralProtectionFault0(pVCpu);
    3269     return iemRegFinishNoFlags(pVCpu, VINF_SUCCESS);
    3270 }
    3271 
    3272 
    3273 /**
    3274  * Performs a near jump to the specified address, no checking or clearing of
    3275  * flags
    3276  *
    3277  * May raise a \#GP(0) if the new RIP is outside the code segment limit.
    3278  *
    3279  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    3280  * @param   uNewEip             The new EIP value.
    3281  */
    3282 DECLINLINE(VBOXSTRICTRC) iemRegRipJumpU32AndFinishNoFlags(PVMCPUCC pVCpu, uint32_t uNewEip) RT_NOEXCEPT
    3283 {
    3284     Assert(pVCpu->cpum.GstCtx.rip <= UINT32_MAX);
    3285     Assert(!IEM_IS_64BIT_CODE(pVCpu));
    3286     if (RT_LIKELY(uNewEip <= pVCpu->cpum.GstCtx.cs.u32Limit))
    3287         pVCpu->cpum.GstCtx.rip = uNewEip;
    3288     else
    3289         return iemRaiseGeneralProtectionFault0(pVCpu);
    3290     return iemRegFinishNoFlags(pVCpu, VINF_SUCCESS);
    3291 }
    3292 
    3293 
    3294 /**
    3295  * Performs a near jump to the specified address, no checking or clearing of
    3296  * flags.
    3297  *
    3298  * May raise a \#GP(0) if the new RIP is non-canonical or outside the code
    3299  * segment limit.
    3300  *
    3301  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    3302  * @param   uNewRip             The new RIP value.
    3303  */
    3304 DECLINLINE(VBOXSTRICTRC) iemRegRipJumpU64AndFinishNoFlags(PVMCPUCC pVCpu, uint64_t uNewRip) RT_NOEXCEPT
    3305 {
    3306     Assert(IEM_IS_64BIT_CODE(pVCpu));
    3307     if (RT_LIKELY(IEM_IS_CANONICAL(uNewRip)))
    3308         pVCpu->cpum.GstCtx.rip = uNewRip;
    3309     else
    3310         return iemRaiseGeneralProtectionFault0(pVCpu);
    3311     return iemRegFinishNoFlags(pVCpu, VINF_SUCCESS);
    3312 }
    3313 
    3314 #endif /* IEM_WITH_CODE_TLB */
    3315 
    3316 /**
    3317  * Performs a near jump to the specified address.
    3318  *
    3319  * May raise a \#GP(0) if the new IP outside the code segment limit.
    3320  *
    3321  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    3322  * @param   uNewIp              The new IP value.
    3323  * @param   cbInstr             The instruction length, for flushing in the non-TLB case.
    3324  */
    3325 DECLINLINE(VBOXSTRICTRC) iemRegRipJumpU16AndFinishClearingRF(PVMCPUCC pVCpu, uint16_t uNewIp, uint8_t cbInstr) RT_NOEXCEPT
    3326 {
    3327     if (RT_LIKELY(   uNewIp <= pVCpu->cpum.GstCtx.cs.u32Limit
    3328                   || IEM_IS_64BIT_CODE(pVCpu) /* no limit checks in 64-bit mode */))
    3329         pVCpu->cpum.GstCtx.rip = uNewIp;
    3330     else
    3331         return iemRaiseGeneralProtectionFault0(pVCpu);
    3332 #ifndef IEM_WITH_CODE_TLB
    3333     iemOpcodeFlushLight(pVCpu, cbInstr);
    3334 #else
    3335     RT_NOREF_PV(cbInstr);
    3336 #endif
    3337     return iemRegFinishClearingRF(pVCpu, VINF_SUCCESS);
    3338 }
    3339 
    3340 
    3341 /**
    3342  * Performs a near jump to the specified address.
    3343  *
    3344  * May raise a \#GP(0) if the new RIP is outside the code segment limit.
    3345  *
    3346  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    3347  * @param   uNewEip             The new EIP value.
    3348  * @param   cbInstr             The instruction length, for flushing in the non-TLB case.
    3349  */
    3350 DECLINLINE(VBOXSTRICTRC) iemRegRipJumpU32AndFinishClearingRF(PVMCPUCC pVCpu, uint32_t uNewEip, uint8_t cbInstr) RT_NOEXCEPT
    3351 {
    3352     Assert(pVCpu->cpum.GstCtx.rip <= UINT32_MAX);
    3353     Assert(!IEM_IS_64BIT_CODE(pVCpu));
    3354     if (RT_LIKELY(uNewEip <= pVCpu->cpum.GstCtx.cs.u32Limit))
    3355         pVCpu->cpum.GstCtx.rip = uNewEip;
    3356     else
    3357         return iemRaiseGeneralProtectionFault0(pVCpu);
    3358 #ifndef IEM_WITH_CODE_TLB
    3359     iemOpcodeFlushLight(pVCpu, cbInstr);
    3360 #else
    3361     RT_NOREF_PV(cbInstr);
    3362 #endif
    3363     return iemRegFinishClearingRF(pVCpu, VINF_SUCCESS);
    3364 }
    3365 
    3366 
    3367 /**
    3368  * Performs a near jump to the specified address.
    3369  *
    3370  * May raise a \#GP(0) if the new RIP is non-canonical or outside the code
    3371  * segment limit.
    3372  *
    3373  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    3374  * @param   uNewRip             The new RIP value.
    3375  * @param   cbInstr             The instruction length, for flushing in the non-TLB case.
    3376  */
    3377 DECLINLINE(VBOXSTRICTRC) iemRegRipJumpU64AndFinishClearingRF(PVMCPUCC pVCpu, uint64_t uNewRip, uint8_t cbInstr) RT_NOEXCEPT
    3378 {
    3379     Assert(IEM_IS_64BIT_CODE(pVCpu));
    3380     if (RT_LIKELY(IEM_IS_CANONICAL(uNewRip)))
    3381         pVCpu->cpum.GstCtx.rip = uNewRip;
    3382     else
    3383         return iemRaiseGeneralProtectionFault0(pVCpu);
    3384 #ifndef IEM_WITH_CODE_TLB
    3385     iemOpcodeFlushLight(pVCpu, cbInstr);
    3386 #else
    3387     RT_NOREF_PV(cbInstr);
    3388 #endif
    3389     return iemRegFinishClearingRF(pVCpu, VINF_SUCCESS);
    3390 }
    3391 
    3392 
    3393 /**
    3394  * Implements a 16-bit relative call, no checking or clearing of
    3395  * flags.
    3396  *
    3397  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    3398  * @param   cbInstr             The instruction length.
    3399  * @param   offDisp             The 16-bit displacement.
    3400  */
    3401 DECL_FORCE_INLINE(VBOXSTRICTRC)
    3402 iemRegRipRelativeCallS16AndFinishNoFlags(PVMCPUCC pVCpu, uint8_t cbInstr, int16_t offDisp) RT_NOEXCEPT
    3403 {
    3404     uint16_t const uOldIp = pVCpu->cpum.GstCtx.ip + cbInstr;
    3405     uint16_t const uNewIp = uOldIp + offDisp;
    3406     if (   uNewIp <= pVCpu->cpum.GstCtx.cs.u32Limit
    3407         || IEM_IS_64BIT_CODE(pVCpu) /* no CS limit checks in 64-bit mode */)
    3408     { /* likely */ }
    3409     else
    3410         return iemRaiseGeneralProtectionFault0(pVCpu);
    3411 
    3412     VBOXSTRICTRC rcStrict = iemMemStackPushU16(pVCpu, uOldIp);
    3413     if (rcStrict == VINF_SUCCESS)
    3414     { /* likely */ }
    3415     else
    3416         return rcStrict;
    3417 
    3418     pVCpu->cpum.GstCtx.rip = uNewIp;
    3419 #ifndef IEM_WITH_CODE_TLB
    3420     iemOpcodeFlushLight(pVCpu, cbInstr);
    3421 #endif
    3422     return iemRegFinishNoFlags(pVCpu, VINF_SUCCESS);
    3423 }
    3424 
    3425 
    3426 /**
    3427  * Implements a 16-bit relative call.
    3428  *
    3429  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    3430  * @param   cbInstr             The instruction length.
    3431  * @param   offDisp             The 16-bit displacement.
    3432  */
    3433 DECL_FORCE_INLINE(VBOXSTRICTRC)
    3434 iemRegRipRelativeCallS16AndFinishClearingRF(PVMCPUCC pVCpu, uint8_t cbInstr, int16_t offDisp) RT_NOEXCEPT
    3435 {
    3436     uint16_t const uOldIp = pVCpu->cpum.GstCtx.ip + cbInstr;
    3437     uint16_t const uNewIp = uOldIp + offDisp;
    3438     if (   uNewIp <= pVCpu->cpum.GstCtx.cs.u32Limit
    3439         || IEM_IS_64BIT_CODE(pVCpu) /* no CS limit checks in 64-bit mode */)
    3440     { /* likely */ }
    3441     else
    3442         return iemRaiseGeneralProtectionFault0(pVCpu);
    3443 
    3444     VBOXSTRICTRC rcStrict = iemMemStackPushU16(pVCpu, uOldIp);
    3445     if (rcStrict == VINF_SUCCESS)
    3446     { /* likely */ }
    3447     else
    3448         return rcStrict;
    3449 
    3450     pVCpu->cpum.GstCtx.rip = uNewIp;
    3451 #ifndef IEM_WITH_CODE_TLB
    3452     iemOpcodeFlushLight(pVCpu, cbInstr);
    3453 #endif
    3454     return iemRegFinishClearingRF(pVCpu, VINF_SUCCESS);
    3455 }
    3456 
    3457 
    3458 /**
    3459  * Implements a 32-bit relative call, no checking or clearing of flags.
    3460  *
    3461  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    3462  * @param   cbInstr             The instruction length.
    3463  * @param   offDisp             The 32-bit displacement.
    3464  */
    3465 DECL_FORCE_INLINE(VBOXSTRICTRC)
    3466 iemRegEip32RelativeCallS32AndFinishNoFlags(PVMCPUCC pVCpu, uint8_t cbInstr, int32_t offDisp) RT_NOEXCEPT
    3467 {
    3468     Assert(pVCpu->cpum.GstCtx.rip <= UINT32_MAX); Assert(!IEM_IS_64BIT_CODE(pVCpu));
    3469 
    3470     uint32_t const uOldRip = pVCpu->cpum.GstCtx.eip + cbInstr;
    3471     uint32_t const uNewRip = uOldRip + offDisp;
    3472     if (uNewRip <= pVCpu->cpum.GstCtx.cs.u32Limit)
    3473     { /* likely */ }
    3474     else
    3475         return iemRaiseGeneralProtectionFault0(pVCpu);
    3476 
    3477     VBOXSTRICTRC rcStrict = iemMemStackPushU32(pVCpu, uOldRip);
    3478     if (rcStrict == VINF_SUCCESS)
    3479     { /* likely */ }
    3480     else
    3481         return rcStrict;
    3482 
    3483     pVCpu->cpum.GstCtx.rip = uNewRip;
    3484 #ifndef IEM_WITH_CODE_TLB
    3485     iemOpcodeFlushLight(pVCpu, cbInstr);
    3486 #endif
    3487     return iemRegFinishNoFlags(pVCpu, VINF_SUCCESS);
    3488 }
    3489 
    3490 
    3491 /**
    3492  * Implements a 32-bit relative call.
    3493  *
    3494  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    3495  * @param   cbInstr             The instruction length.
    3496  * @param   offDisp             The 32-bit displacement.
    3497  */
    3498 DECL_FORCE_INLINE(VBOXSTRICTRC)
    3499 iemRegEip32RelativeCallS32AndFinishClearingRF(PVMCPUCC pVCpu, uint8_t cbInstr, int32_t offDisp) RT_NOEXCEPT
    3500 {
    3501     Assert(pVCpu->cpum.GstCtx.rip <= UINT32_MAX); Assert(!IEM_IS_64BIT_CODE(pVCpu));
    3502 
    3503     uint32_t const uOldRip = pVCpu->cpum.GstCtx.eip + cbInstr;
    3504     uint32_t const uNewRip = uOldRip + offDisp;
    3505     if (uNewRip <= pVCpu->cpum.GstCtx.cs.u32Limit)
    3506     { /* likely */ }
    3507     else
    3508         return iemRaiseGeneralProtectionFault0(pVCpu);
    3509 
    3510     VBOXSTRICTRC rcStrict = iemMemStackPushU32(pVCpu, uOldRip);
    3511     if (rcStrict == VINF_SUCCESS)
    3512     { /* likely */ }
    3513     else
    3514         return rcStrict;
    3515 
    3516     pVCpu->cpum.GstCtx.rip = uNewRip;
    3517 #ifndef IEM_WITH_CODE_TLB
    3518     iemOpcodeFlushLight(pVCpu, cbInstr);
    3519 #endif
    3520     return iemRegFinishClearingRF(pVCpu, VINF_SUCCESS);
    3521 }
    3522 
    3523 
    3524 /**
    3525  * Implements a 64-bit relative call, no checking or clearing of flags.
    3526  *
    3527  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    3528  * @param   cbInstr             The instruction length.
    3529  * @param   offDisp             The 64-bit displacement.
    3530  */
    3531 DECL_FORCE_INLINE(VBOXSTRICTRC)
    3532 iemRegRip64RelativeCallS64AndFinishNoFlags(PVMCPUCC pVCpu, uint8_t cbInstr, int64_t offDisp) RT_NOEXCEPT
    3533 {
    3534     uint64_t const uOldRip = pVCpu->cpum.GstCtx.rip + cbInstr;
    3535     uint64_t const uNewRip = uOldRip + (int64_t)offDisp;
    3536     if (IEM_IS_CANONICAL(uNewRip))
    3537     { /* likely */ }
    3538     else
    3539         return iemRaiseNotCanonical(pVCpu);
    3540 
    3541     VBOXSTRICTRC rcStrict = iemMemStackPushU64(pVCpu, uOldRip);
    3542     if (rcStrict == VINF_SUCCESS)
    3543     { /* likely */ }
    3544     else
    3545         return rcStrict;
    3546 
    3547     pVCpu->cpum.GstCtx.rip = uNewRip;
    3548 #ifndef IEM_WITH_CODE_TLB
    3549     iemOpcodeFlushLight(pVCpu, cbInstr);
    3550 #endif
    3551     return iemRegFinishNoFlags(pVCpu, VINF_SUCCESS);
    3552 }
    3553 
    3554 
    3555 /**
    3556  * Implements a 64-bit relative call.
    3557  *
    3558  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    3559  * @param   cbInstr             The instruction length.
    3560  * @param   offDisp             The 64-bit displacement.
    3561  */
    3562 DECL_FORCE_INLINE(VBOXSTRICTRC)
    3563 iemRegRip64RelativeCallS64AndFinishClearingRF(PVMCPUCC pVCpu, uint8_t cbInstr, int64_t offDisp) RT_NOEXCEPT
    3564 {
    3565     uint64_t const uOldRip = pVCpu->cpum.GstCtx.rip + cbInstr;
    3566     uint64_t const uNewRip = uOldRip + (int64_t)offDisp;
    3567     if (IEM_IS_CANONICAL(uNewRip))
    3568     { /* likely */ }
    3569     else
    3570         return iemRaiseNotCanonical(pVCpu);
    3571 
    3572     VBOXSTRICTRC rcStrict = iemMemStackPushU64(pVCpu, uOldRip);
    3573     if (rcStrict == VINF_SUCCESS)
    3574     { /* likely */ }
    3575     else
    3576         return rcStrict;
    3577 
    3578     pVCpu->cpum.GstCtx.rip = uNewRip;
    3579 #ifndef IEM_WITH_CODE_TLB
    3580     iemOpcodeFlushLight(pVCpu, cbInstr);
    3581 #endif
    3582     return iemRegFinishClearingRF(pVCpu, VINF_SUCCESS);
    3583 }
    3584 
    3585 
    3586 /**
    3587  * Implements an 16-bit indirect call, no checking or clearing of
    3588  * flags.
    3589  *
    3590  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    3591  * @param   cbInstr             The instruction length.
    3592  * @param   uNewRip             The new RIP value.
    3593  */
    3594 DECL_FORCE_INLINE(VBOXSTRICTRC)
    3595 iemRegIp16IndirectCallU16AndFinishNoFlags(PVMCPUCC pVCpu, uint8_t cbInstr, uint16_t uNewRip) RT_NOEXCEPT
    3596 {
    3597     uint16_t const uOldRip = pVCpu->cpum.GstCtx.ip + cbInstr;
    3598     if (uNewRip <= pVCpu->cpum.GstCtx.cs.u32Limit)
    3599     { /* likely */ }
    3600     else
    3601         return iemRaiseGeneralProtectionFault0(pVCpu);
    3602 
    3603     VBOXSTRICTRC rcStrict = iemMemStackPushU16(pVCpu, uOldRip);
    3604     if (rcStrict == VINF_SUCCESS)
    3605     { /* likely */ }
    3606     else
    3607         return rcStrict;
    3608 
    3609     pVCpu->cpum.GstCtx.rip = uNewRip;
    3610 #ifndef IEM_WITH_CODE_TLB
    3611     iemOpcodeFlushLight(pVCpu, cbInstr);
    3612 #endif
    3613     return iemRegFinishNoFlags(pVCpu, VINF_SUCCESS);
    3614 }
    3615 
    3616 
    3617 /**
    3618  * Implements an 16-bit indirect call, no checking or clearing of
    3619  * flags.
    3620  *
    3621  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    3622  * @param   cbInstr             The instruction length.
    3623  * @param   uNewRip             The new RIP value.
    3624  */
    3625 DECL_FORCE_INLINE(VBOXSTRICTRC)
    3626 iemRegEip32IndirectCallU16AndFinishNoFlags(PVMCPUCC pVCpu, uint8_t cbInstr, uint16_t uNewRip) RT_NOEXCEPT
    3627 {
    3628     uint16_t const uOldRip = pVCpu->cpum.GstCtx.ip + cbInstr;
    3629     if (uNewRip <= pVCpu->cpum.GstCtx.cs.u32Limit)
    3630     { /* likely */ }
    3631     else
    3632         return iemRaiseGeneralProtectionFault0(pVCpu);
    3633 
    3634     VBOXSTRICTRC rcStrict = iemMemStackPushU16(pVCpu, uOldRip);
    3635     if (rcStrict == VINF_SUCCESS)
    3636     { /* likely */ }
    3637     else
    3638         return rcStrict;
    3639 
    3640     pVCpu->cpum.GstCtx.rip = uNewRip;
    3641 #ifndef IEM_WITH_CODE_TLB
    3642     iemOpcodeFlushLight(pVCpu, cbInstr);
    3643 #endif
    3644     return iemRegFinishNoFlags(pVCpu, VINF_SUCCESS);
    3645 }
    3646 
    3647 
    3648 /**
    3649  * Implements an 16-bit indirect call.
    3650  *
    3651  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    3652  * @param   cbInstr             The instruction length.
    3653  * @param   uNewRip             The new RIP value.
    3654  */
    3655 DECL_FORCE_INLINE(VBOXSTRICTRC)
    3656 iemRegIp16IndirectCallU16AndFinishClearingRF(PVMCPUCC pVCpu, uint8_t cbInstr, uint16_t uNewRip) RT_NOEXCEPT
    3657 {
    3658     uint16_t const uOldRip = pVCpu->cpum.GstCtx.ip + cbInstr;
    3659     if (uNewRip <= pVCpu->cpum.GstCtx.cs.u32Limit)
    3660     { /* likely */ }
    3661     else
    3662         return iemRaiseGeneralProtectionFault0(pVCpu);
    3663 
    3664     VBOXSTRICTRC rcStrict = iemMemStackPushU16(pVCpu, uOldRip);
    3665     if (rcStrict == VINF_SUCCESS)
    3666     { /* likely */ }
    3667     else
    3668         return rcStrict;
    3669 
    3670     pVCpu->cpum.GstCtx.rip = uNewRip;
    3671 #ifndef IEM_WITH_CODE_TLB
    3672     iemOpcodeFlushLight(pVCpu, cbInstr);
    3673 #endif
    3674     return iemRegFinishClearingRF(pVCpu, VINF_SUCCESS);
    3675 }
    3676 
    3677 
    3678 /**
    3679  * Implements an 16-bit indirect call.
    3680  *
    3681  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    3682  * @param   cbInstr             The instruction length.
    3683  * @param   uNewRip             The new RIP value.
    3684  */
    3685 DECL_FORCE_INLINE(VBOXSTRICTRC)
    3686 iemRegEip32IndirectCallU16AndFinishClearingRF(PVMCPUCC pVCpu, uint8_t cbInstr, uint16_t uNewRip) RT_NOEXCEPT
    3687 {
    3688     uint16_t const uOldRip = pVCpu->cpum.GstCtx.ip + cbInstr;
    3689     if (uNewRip <= pVCpu->cpum.GstCtx.cs.u32Limit)
    3690     { /* likely */ }
    3691     else
    3692         return iemRaiseGeneralProtectionFault0(pVCpu);
    3693 
    3694     VBOXSTRICTRC rcStrict = iemMemStackPushU16(pVCpu, uOldRip);
    3695     if (rcStrict == VINF_SUCCESS)
    3696     { /* likely */ }
    3697     else
    3698         return rcStrict;
    3699 
    3700     pVCpu->cpum.GstCtx.rip = uNewRip;
    3701 #ifndef IEM_WITH_CODE_TLB
    3702     iemOpcodeFlushLight(pVCpu, cbInstr);
    3703 #endif
    3704     return iemRegFinishClearingRF(pVCpu, VINF_SUCCESS);
    3705 }
    3706 
    3707 
    3708 /**
    3709  * Implements an 32-bit indirect call, no checking or clearing of
    3710  * flags.
    3711  *
    3712  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    3713  * @param   cbInstr             The instruction length.
    3714  * @param   uNewRip             The new RIP value.
    3715  */
    3716 DECL_FORCE_INLINE(VBOXSTRICTRC)
    3717 iemRegEip32IndirectCallU32AndFinishNoFlags(PVMCPUCC pVCpu, uint8_t cbInstr, uint32_t uNewRip) RT_NOEXCEPT
    3718 {
    3719     uint32_t const uOldRip = pVCpu->cpum.GstCtx.eip + cbInstr;
    3720     if (uNewRip <= pVCpu->cpum.GstCtx.cs.u32Limit)
    3721     { /* likely */ }
    3722     else
    3723         return iemRaiseGeneralProtectionFault0(pVCpu);
    3724 
    3725     VBOXSTRICTRC rcStrict = iemMemStackPushU32(pVCpu, uOldRip);
    3726     if (rcStrict == VINF_SUCCESS)
    3727     { /* likely */ }
    3728     else
    3729         return rcStrict;
    3730 
    3731     pVCpu->cpum.GstCtx.rip = uNewRip;
    3732 #ifndef IEM_WITH_CODE_TLB
    3733     iemOpcodeFlushLight(pVCpu, cbInstr);
    3734 #endif
    3735     return iemRegFinishNoFlags(pVCpu, VINF_SUCCESS);
    3736 }
    3737 
    3738 
    3739 /**
    3740  * Implements an 32-bit indirect call.
    3741  *
    3742  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    3743  * @param   cbInstr             The instruction length.
    3744  * @param   uNewRip             The new RIP value.
    3745  */
    3746 DECL_FORCE_INLINE(VBOXSTRICTRC)
    3747 iemRegEip32IndirectCallU32AndFinishClearingRF(PVMCPUCC pVCpu, uint8_t cbInstr, uint32_t uNewRip) RT_NOEXCEPT
    3748 {
    3749     uint32_t const uOldRip = pVCpu->cpum.GstCtx.eip + cbInstr;
    3750     if (uNewRip <= pVCpu->cpum.GstCtx.cs.u32Limit)
    3751     { /* likely */ }
    3752     else
    3753         return iemRaiseGeneralProtectionFault0(pVCpu);
    3754 
    3755     VBOXSTRICTRC rcStrict = iemMemStackPushU32(pVCpu, uOldRip);
    3756     if (rcStrict == VINF_SUCCESS)
    3757     { /* likely */ }
    3758     else
    3759         return rcStrict;
    3760 
    3761     pVCpu->cpum.GstCtx.rip = uNewRip;
    3762 #ifndef IEM_WITH_CODE_TLB
    3763     iemOpcodeFlushLight(pVCpu, cbInstr);
    3764 #endif
    3765     return iemRegFinishClearingRF(pVCpu, VINF_SUCCESS);
    3766 }
    3767 
    3768 
    3769 /**
    3770  * Implements an 64-bit indirect call, no checking or clearing of
    3771  * flags.
    3772  *
    3773  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    3774  * @param   cbInstr             The instruction length.
    3775  * @param   uNewRip             The new RIP value.
    3776  */
    3777 DECL_FORCE_INLINE(VBOXSTRICTRC)
    3778 iemRegRip64IndirectCallU64AndFinishNoFlags(PVMCPUCC pVCpu, uint8_t cbInstr, uint64_t uNewRip) RT_NOEXCEPT
    3779 {
    3780     uint64_t const uOldRip = pVCpu->cpum.GstCtx.rip + cbInstr;
    3781     if (IEM_IS_CANONICAL(uNewRip))
    3782     { /* likely */ }
    3783     else
    3784         return iemRaiseGeneralProtectionFault0(pVCpu);
    3785 
    3786     VBOXSTRICTRC rcStrict = iemMemStackPushU64(pVCpu, uOldRip);
    3787     if (rcStrict == VINF_SUCCESS)
    3788     { /* likely */ }
    3789     else
    3790         return rcStrict;
    3791 
    3792     pVCpu->cpum.GstCtx.rip = uNewRip;
    3793 #ifndef IEM_WITH_CODE_TLB
    3794     iemOpcodeFlushLight(pVCpu, cbInstr);
    3795 #endif
    3796     return iemRegFinishNoFlags(pVCpu, VINF_SUCCESS);
    3797 }
    3798 
    3799 
    3800 /**
    3801  * Implements an 64-bit indirect call.
    3802  *
    3803  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    3804  * @param   cbInstr             The instruction length.
    3805  * @param   uNewRip             The new RIP value.
    3806  */
    3807 DECL_FORCE_INLINE(VBOXSTRICTRC)
    3808 iemRegRip64IndirectCallU64AndFinishClearingRF(PVMCPUCC pVCpu, uint8_t cbInstr, uint64_t uNewRip) RT_NOEXCEPT
    3809 {
    3810     uint64_t const uOldRip = pVCpu->cpum.GstCtx.rip + cbInstr;
    3811     if (IEM_IS_CANONICAL(uNewRip))
    3812     { /* likely */ }
    3813     else
    3814         return iemRaiseGeneralProtectionFault0(pVCpu);
    3815 
    3816     VBOXSTRICTRC rcStrict = iemMemStackPushU64(pVCpu, uOldRip);
    3817     if (rcStrict == VINF_SUCCESS)
    3818     { /* likely */ }
    3819     else
    3820         return rcStrict;
    3821 
    3822     pVCpu->cpum.GstCtx.rip = uNewRip;
    3823 #ifndef IEM_WITH_CODE_TLB
    3824     iemOpcodeFlushLight(pVCpu, cbInstr);
    3825 #endif
    3826     return iemRegFinishClearingRF(pVCpu, VINF_SUCCESS);
    3827 }
    3828 
    3829 
    3830 
    3831 /**
    3832  * Adds to the stack pointer.
    3833  *
    3834  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    3835  * @param   cbToAdd             The number of bytes to add (8-bit!).
    3836  */
    3837 DECLINLINE(void) iemRegAddToRsp(PVMCPUCC pVCpu, uint8_t cbToAdd) RT_NOEXCEPT
    3838 {
    3839     if (IEM_IS_64BIT_CODE(pVCpu))
    3840         pVCpu->cpum.GstCtx.rsp += cbToAdd;
    3841     else if (pVCpu->cpum.GstCtx.ss.Attr.n.u1DefBig)
    3842         pVCpu->cpum.GstCtx.esp += cbToAdd;
    3843     else
    3844         pVCpu->cpum.GstCtx.sp  += cbToAdd;
    3845 }
    3846 
    3847 
    3848 /**
    3849  * Subtracts from the stack pointer.
    3850  *
    3851  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    3852  * @param   cbToSub             The number of bytes to subtract (8-bit!).
    3853  */
    3854 DECLINLINE(void) iemRegSubFromRsp(PVMCPUCC pVCpu, uint8_t cbToSub) RT_NOEXCEPT
    3855 {
    3856     if (IEM_IS_64BIT_CODE(pVCpu))
    3857         pVCpu->cpum.GstCtx.rsp -= cbToSub;
    3858     else if (pVCpu->cpum.GstCtx.ss.Attr.n.u1DefBig)
    3859         pVCpu->cpum.GstCtx.esp -= cbToSub;
    3860     else
    3861         pVCpu->cpum.GstCtx.sp  -= cbToSub;
    3862 }
    3863 
    3864 
    3865 /**
    3866  * Adds to the temporary stack pointer.
    3867  *
    3868  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    3869  * @param   pTmpRsp             The temporary SP/ESP/RSP to update.
    3870  * @param   cbToAdd             The number of bytes to add (16-bit).
    3871  */
    3872 DECLINLINE(void) iemRegAddToRspEx(PCVMCPU pVCpu, PRTUINT64U pTmpRsp, uint16_t cbToAdd) RT_NOEXCEPT
    3873 {
    3874     if (IEM_IS_64BIT_CODE(pVCpu))
    3875         pTmpRsp->u           += cbToAdd;
    3876     else if (pVCpu->cpum.GstCtx.ss.Attr.n.u1DefBig)
    3877         pTmpRsp->DWords.dw0  += cbToAdd;
    3878     else
    3879         pTmpRsp->Words.w0    += cbToAdd;
    3880 }
    3881 
    3882 
    3883 /**
    3884  * Subtracts from the temporary stack pointer.
    3885  *
    3886  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    3887  * @param   pTmpRsp             The temporary SP/ESP/RSP to update.
    3888  * @param   cbToSub             The number of bytes to subtract.
    3889  * @remarks The @a cbToSub argument *MUST* be 16-bit, iemCImpl_enter is
    3890  *          expecting that.
    3891  */
    3892 DECLINLINE(void) iemRegSubFromRspEx(PCVMCPU pVCpu, PRTUINT64U pTmpRsp, uint16_t cbToSub) RT_NOEXCEPT
    3893 {
    3894     if (IEM_IS_64BIT_CODE(pVCpu))
    3895         pTmpRsp->u          -= cbToSub;
    3896     else if (pVCpu->cpum.GstCtx.ss.Attr.n.u1DefBig)
    3897         pTmpRsp->DWords.dw0 -= cbToSub;
    3898     else
    3899         pTmpRsp->Words.w0   -= cbToSub;
    3900 }
    3901 
    3902 
    3903 /**
    3904  * Calculates the effective stack address for a push of the specified size as
    3905  * well as the new RSP value (upper bits may be masked).
    3906  *
    3907  * @returns Effective stack addressf for the push.
    3908  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    3909  * @param   cbItem              The size of the stack item to pop.
    3910  * @param   puNewRsp            Where to return the new RSP value.
    3911  */
    3912 DECLINLINE(RTGCPTR) iemRegGetRspForPush(PCVMCPU pVCpu, uint8_t cbItem, uint64_t *puNewRsp) RT_NOEXCEPT
    3913 {
    3914     RTUINT64U   uTmpRsp;
    3915     RTGCPTR     GCPtrTop;
    3916     uTmpRsp.u = pVCpu->cpum.GstCtx.rsp;
    3917 
    3918     if (IEM_IS_64BIT_CODE(pVCpu))
    3919         GCPtrTop = uTmpRsp.u            -= cbItem;
    3920     else if (pVCpu->cpum.GstCtx.ss.Attr.n.u1DefBig)
    3921         GCPtrTop = uTmpRsp.DWords.dw0   -= cbItem;
    3922     else
    3923         GCPtrTop = uTmpRsp.Words.w0     -= cbItem;
    3924     *puNewRsp = uTmpRsp.u;
    3925     return GCPtrTop;
    3926 }
    3927 
    3928 
    3929 /**
    3930  * Gets the current stack pointer and calculates the value after a pop of the
    3931  * specified size.
    3932  *
    3933  * @returns Current stack pointer.
    3934  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    3935  * @param   cbItem              The size of the stack item to pop.
    3936  * @param   puNewRsp            Where to return the new RSP value.
    3937  */
    3938 DECLINLINE(RTGCPTR) iemRegGetRspForPop(PCVMCPU pVCpu, uint8_t cbItem, uint64_t *puNewRsp) RT_NOEXCEPT
    3939 {
    3940     RTUINT64U   uTmpRsp;
    3941     RTGCPTR     GCPtrTop;
    3942     uTmpRsp.u = pVCpu->cpum.GstCtx.rsp;
    3943 
    3944     if (IEM_IS_64BIT_CODE(pVCpu))
    3945     {
    3946         GCPtrTop = uTmpRsp.u;
    3947         uTmpRsp.u += cbItem;
    3948     }
    3949     else if (pVCpu->cpum.GstCtx.ss.Attr.n.u1DefBig)
    3950     {
    3951         GCPtrTop = uTmpRsp.DWords.dw0;
    3952         uTmpRsp.DWords.dw0 += cbItem;
    3953     }
    3954     else
    3955     {
    3956         GCPtrTop = uTmpRsp.Words.w0;
    3957         uTmpRsp.Words.w0 += cbItem;
    3958     }
    3959     *puNewRsp = uTmpRsp.u;
    3960     return GCPtrTop;
    3961 }
    3962 
    3963 
    3964 /**
    3965  * Calculates the effective stack address for a push of the specified size as
    3966  * well as the new temporary RSP value (upper bits may be masked).
    3967  *
    3968  * @returns Effective stack addressf for the push.
    3969  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    3970  * @param   pTmpRsp             The temporary stack pointer.  This is updated.
    3971  * @param   cbItem              The size of the stack item to pop.
    3972  */
    3973 DECLINLINE(RTGCPTR) iemRegGetRspForPushEx(PCVMCPU pVCpu, PRTUINT64U pTmpRsp, uint8_t cbItem) RT_NOEXCEPT
    3974 {
    3975     RTGCPTR GCPtrTop;
    3976 
    3977     if (IEM_IS_64BIT_CODE(pVCpu))
    3978         GCPtrTop = pTmpRsp->u          -= cbItem;
    3979     else if (pVCpu->cpum.GstCtx.ss.Attr.n.u1DefBig)
    3980         GCPtrTop = pTmpRsp->DWords.dw0 -= cbItem;
    3981     else
    3982         GCPtrTop = pTmpRsp->Words.w0   -= cbItem;
    3983     return GCPtrTop;
    3984 }
    3985 
    3986 
    3987 /**
    3988  * Gets the effective stack address for a pop of the specified size and
    3989  * calculates and updates the temporary RSP.
    3990  *
    3991  * @returns Current stack pointer.
    3992  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    3993  * @param   pTmpRsp             The temporary stack pointer.  This is updated.
    3994  * @param   cbItem              The size of the stack item to pop.
    3995  */
    3996 DECLINLINE(RTGCPTR) iemRegGetRspForPopEx(PCVMCPU pVCpu, PRTUINT64U pTmpRsp, uint8_t cbItem) RT_NOEXCEPT
    3997 {
    3998     RTGCPTR GCPtrTop;
    3999     if (IEM_IS_64BIT_CODE(pVCpu))
    4000     {
    4001         GCPtrTop = pTmpRsp->u;
    4002         pTmpRsp->u          += cbItem;
    4003     }
    4004     else if (pVCpu->cpum.GstCtx.ss.Attr.n.u1DefBig)
    4005     {
    4006         GCPtrTop = pTmpRsp->DWords.dw0;
    4007         pTmpRsp->DWords.dw0 += cbItem;
    4008     }
    4009     else
    4010     {
    4011         GCPtrTop = pTmpRsp->Words.w0;
    4012         pTmpRsp->Words.w0   += cbItem;
    4013     }
    4014     return GCPtrTop;
    4015 }
    4016 
    4017 
    4018 /** Common body for iemRegRipNearReturnAndFinishClearingRF()
    4019  * and iemRegRipNearReturnAndFinishNoFlags(). */
    4020 template<bool a_fWithFlags>
    4021 DECL_FORCE_INLINE(VBOXSTRICTRC)
    4022 iemRegRipNearReturnCommon(PVMCPUCC pVCpu, uint8_t cbInstr, uint16_t cbPop, IEMMODE enmEffOpSize) RT_NOEXCEPT
    4023 {
    4024     /* Fetch the new RIP from the stack. */
    4025     VBOXSTRICTRC    rcStrict;
    4026     RTUINT64U       NewRip;
    4027     RTUINT64U       NewRsp;
    4028     NewRsp.u = pVCpu->cpum.GstCtx.rsp;
    4029     switch (enmEffOpSize)
    4030     {
    4031         case IEMMODE_16BIT:
    4032             NewRip.u = 0;
    4033             rcStrict = iemMemStackPopU16Ex(pVCpu, &NewRip.Words.w0, &NewRsp);
    4034             break;
    4035         case IEMMODE_32BIT:
    4036             NewRip.u = 0;
    4037             rcStrict = iemMemStackPopU32Ex(pVCpu, &NewRip.DWords.dw0, &NewRsp);
    4038             break;
    4039         case IEMMODE_64BIT:
    4040             rcStrict = iemMemStackPopU64Ex(pVCpu, &NewRip.u, &NewRsp);
    4041             break;
    4042         IEM_NOT_REACHED_DEFAULT_CASE_RET();
    4043     }
    4044     if (rcStrict != VINF_SUCCESS)
    4045         return rcStrict;
    4046 
    4047     /* Check the new ew RIP before loading it. */
    4048     /** @todo Should test this as the intel+amd pseudo code doesn't mention half
    4049      *        of it.  The canonical test is performed here and for call. */
    4050     if (enmEffOpSize != IEMMODE_64BIT)
    4051     {
    4052         if (RT_LIKELY(NewRip.DWords.dw0 <= pVCpu->cpum.GstCtx.cs.u32Limit))
    4053         { /* likely */ }
    4054         else
    4055         {
    4056             Log(("retn newrip=%llx - out of bounds (%x) -> #GP\n", NewRip.u, pVCpu->cpum.GstCtx.cs.u32Limit));
    4057             return iemRaiseSelectorBounds(pVCpu, X86_SREG_CS, IEM_ACCESS_INSTRUCTION);
    4058         }
    4059     }
    4060     else
    4061     {
    4062         if (RT_LIKELY(IEM_IS_CANONICAL(NewRip.u)))
    4063         { /* likely */ }
    4064         else
    4065         {
    4066             Log(("retn newrip=%llx - not canonical -> #GP\n", NewRip.u));
    4067             return iemRaiseNotCanonical(pVCpu);
    4068         }
    4069     }
    4070 
    4071     /* Apply cbPop */
    4072     if (cbPop)
    4073         iemRegAddToRspEx(pVCpu, &NewRsp, cbPop);
    4074 
    4075     /* Commit it. */
    4076     pVCpu->cpum.GstCtx.rip = NewRip.u;
    4077     pVCpu->cpum.GstCtx.rsp = NewRsp.u;
    4078 
    4079     /* Flush the prefetch buffer. */
    4080 #ifndef IEM_WITH_CODE_TLB
    4081     iemOpcodeFlushLight(pVCpu, cbInstr);
    4082 #endif
    4083     RT_NOREF(cbInstr);
    4084 
    4085 
    4086     if (a_fWithFlags)
    4087         return iemRegFinishClearingRF(pVCpu, VINF_SUCCESS);
    4088     return iemRegFinishNoFlags(pVCpu, VINF_SUCCESS);
    4089 }
    4090 
    4091 
    4092 /**
    4093  * Implements retn and retn imm16.
    4094  *
    4095  * @param   pVCpu           The cross context virtual CPU structure of the
    4096  *                          calling thread.
    4097  * @param   cbInstr         The current instruction length.
    4098  * @param   enmEffOpSize    The effective operand size.  This is constant.
    4099  * @param   cbPop           The amount of arguments to pop from the stack
    4100  *                          (bytes).  This can be constant (zero).
    4101  */
    4102 DECL_FORCE_INLINE(VBOXSTRICTRC)
    4103 iemRegRipNearReturnAndFinishClearingRF(PVMCPUCC pVCpu, uint8_t cbInstr, uint16_t cbPop, IEMMODE enmEffOpSize) RT_NOEXCEPT
    4104 {
    4105     return iemRegRipNearReturnCommon<true /*a_fWithFlags*/>(pVCpu, cbInstr, cbPop, enmEffOpSize);
    4106 }
    4107 
    4108 
    4109 /**
    4110  * Implements retn and retn imm16, no checking or clearing of
    4111  * flags.
    4112  *
    4113  * @param   pVCpu           The cross context virtual CPU structure of the
    4114  *                          calling thread.
    4115  * @param   cbInstr         The current instruction length.
    4116  * @param   enmEffOpSize    The effective operand size.  This is constant.
    4117  * @param   cbPop           The amount of arguments to pop from the stack
    4118  *                          (bytes).  This can be constant (zero).
    4119  */
    4120 DECL_FORCE_INLINE(VBOXSTRICTRC)
    4121 iemRegRipNearReturnAndFinishNoFlags(PVMCPUCC pVCpu, uint8_t cbInstr, uint16_t cbPop, IEMMODE enmEffOpSize) RT_NOEXCEPT
    4122 {
    4123     return iemRegRipNearReturnCommon<false /*a_fWithFlags*/>(pVCpu, cbInstr, cbPop, enmEffOpSize);
    4124 }
    4125 
    4126 /** @}  */
    4127 
    4128 
    4129 /** @name   FPU access and helpers.
    4130  *
    4131  * @{
    4132  */
    4133 
    4134 
    4135 /**
    4136  * Hook for preparing to use the host FPU.
    4137  *
    4138  * This is necessary in ring-0 and raw-mode context (nop in ring-3).
    4139  *
    4140  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    4141  */
    4142 DECLINLINE(void) iemFpuPrepareUsage(PVMCPUCC pVCpu) RT_NOEXCEPT
    4143 {
    4144 #ifdef IN_RING3
    4145     CPUMSetChangedFlags(pVCpu, CPUM_CHANGED_FPU_REM);
    4146 #else
    4147     CPUMRZFpuStatePrepareHostCpuForUse(pVCpu);
    4148 #endif
    4149     IEM_CTX_IMPORT_NORET(pVCpu, CPUMCTX_EXTRN_X87 | CPUMCTX_EXTRN_SSE_AVX | CPUMCTX_EXTRN_OTHER_XSAVE | CPUMCTX_EXTRN_XCRx);
    4150 }
    4151 
    4152 
    4153 /**
    4154  * Hook for preparing to use the host FPU for SSE.
    4155  *
    4156  * This is necessary in ring-0 and raw-mode context (nop in ring-3).
    4157  *
    4158  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    4159  */
    4160 DECLINLINE(void) iemFpuPrepareUsageSse(PVMCPUCC pVCpu) RT_NOEXCEPT
    4161 {
    4162     iemFpuPrepareUsage(pVCpu);
    4163 }
    4164 
    4165 
    4166 /**
    4167  * Hook for preparing to use the host FPU for AVX.
    4168  *
    4169  * This is necessary in ring-0 and raw-mode context (nop in ring-3).
    4170  *
    4171  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    4172  */
    4173 DECLINLINE(void) iemFpuPrepareUsageAvx(PVMCPUCC pVCpu) RT_NOEXCEPT
    4174 {
    4175     iemFpuPrepareUsage(pVCpu);
    4176 }
    4177 
    4178 
    4179 /**
    4180  * Hook for actualizing the guest FPU state before the interpreter reads it.
    4181  *
    4182  * This is necessary in ring-0 and raw-mode context (nop in ring-3).
    4183  *
    4184  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    4185  */
    4186 DECLINLINE(void) iemFpuActualizeStateForRead(PVMCPUCC pVCpu) RT_NOEXCEPT
    4187 {
    4188 #ifdef IN_RING3
    4189     NOREF(pVCpu);
    4190 #else
    4191     CPUMRZFpuStateActualizeForRead(pVCpu);
    4192 #endif
    4193     IEM_CTX_IMPORT_NORET(pVCpu, CPUMCTX_EXTRN_X87 | CPUMCTX_EXTRN_SSE_AVX | CPUMCTX_EXTRN_OTHER_XSAVE | CPUMCTX_EXTRN_XCRx);
    4194 }
    4195 
    4196 
    4197 /**
    4198  * Hook for actualizing the guest FPU state before the interpreter changes it.
    4199  *
    4200  * This is necessary in ring-0 and raw-mode context (nop in ring-3).
    4201  *
    4202  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    4203  */
    4204 DECLINLINE(void) iemFpuActualizeStateForChange(PVMCPUCC pVCpu) RT_NOEXCEPT
    4205 {
    4206 #ifdef IN_RING3
    4207     CPUMSetChangedFlags(pVCpu, CPUM_CHANGED_FPU_REM);
    4208 #else
    4209     CPUMRZFpuStateActualizeForChange(pVCpu);
    4210 #endif
    4211     IEM_CTX_IMPORT_NORET(pVCpu, CPUMCTX_EXTRN_X87 | CPUMCTX_EXTRN_SSE_AVX | CPUMCTX_EXTRN_OTHER_XSAVE | CPUMCTX_EXTRN_XCRx);
    4212 }
    4213 
    4214 
    4215 /**
    4216  * Hook for actualizing the guest XMM0..15 and MXCSR register state for read
    4217  * only.
    4218  *
    4219  * This is necessary in ring-0 and raw-mode context (nop in ring-3).
    4220  *
    4221  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    4222  */
    4223 DECLINLINE(void) iemFpuActualizeSseStateForRead(PVMCPUCC pVCpu) RT_NOEXCEPT
    4224 {
    4225 #if defined(IN_RING3) || defined(VBOX_WITH_KERNEL_USING_XMM)
    4226     NOREF(pVCpu);
    4227 #else
    4228     CPUMRZFpuStateActualizeSseForRead(pVCpu);
    4229 #endif
    4230     IEM_CTX_IMPORT_NORET(pVCpu, CPUMCTX_EXTRN_X87 | CPUMCTX_EXTRN_SSE_AVX | CPUMCTX_EXTRN_OTHER_XSAVE | CPUMCTX_EXTRN_XCRx);
    4231 }
    4232 
    4233 
    4234 /**
    4235  * Hook for actualizing the guest XMM0..15 and MXCSR register state for
    4236  * read+write.
    4237  *
    4238  * This is necessary in ring-0 and raw-mode context (nop in ring-3).
    4239  *
    4240  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    4241  */
    4242 DECLINLINE(void) iemFpuActualizeSseStateForChange(PVMCPUCC pVCpu) RT_NOEXCEPT
    4243 {
    4244 #if defined(IN_RING3) || defined(VBOX_WITH_KERNEL_USING_XMM)
    4245     CPUMSetChangedFlags(pVCpu, CPUM_CHANGED_FPU_REM);
    4246 #else
    4247     CPUMRZFpuStateActualizeForChange(pVCpu);
    4248 #endif
    4249     IEM_CTX_IMPORT_NORET(pVCpu, CPUMCTX_EXTRN_X87 | CPUMCTX_EXTRN_SSE_AVX | CPUMCTX_EXTRN_OTHER_XSAVE | CPUMCTX_EXTRN_XCRx);
    4250 
    4251     /* Make sure any changes are loaded the next time around. */
    4252     pVCpu->cpum.GstCtx.XState.Hdr.bmXState |= XSAVE_C_SSE;
    4253 }
    4254 
    4255 
    4256 /**
    4257  * Hook for actualizing the guest YMM0..15 and MXCSR register state for read
    4258  * only.
    4259  *
    4260  * This is necessary in ring-0 and raw-mode context (nop in ring-3).
    4261  *
    4262  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    4263  */
    4264 DECLINLINE(void) iemFpuActualizeAvxStateForRead(PVMCPUCC pVCpu) RT_NOEXCEPT
    4265 {
    4266 #ifdef IN_RING3
    4267     NOREF(pVCpu);
    4268 #else
    4269     CPUMRZFpuStateActualizeAvxForRead(pVCpu);
    4270 #endif
    4271     IEM_CTX_IMPORT_NORET(pVCpu, CPUMCTX_EXTRN_X87 | CPUMCTX_EXTRN_SSE_AVX | CPUMCTX_EXTRN_OTHER_XSAVE | CPUMCTX_EXTRN_XCRx);
    4272 }
    4273 
    4274 
    4275 /**
    4276  * Hook for actualizing the guest YMM0..15 and MXCSR register state for
    4277  * read+write.
    4278  *
    4279  * This is necessary in ring-0 and raw-mode context (nop in ring-3).
    4280  *
    4281  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    4282  */
    4283 DECLINLINE(void) iemFpuActualizeAvxStateForChange(PVMCPUCC pVCpu) RT_NOEXCEPT
    4284 {
    4285 #ifdef IN_RING3
    4286     CPUMSetChangedFlags(pVCpu, CPUM_CHANGED_FPU_REM);
    4287 #else
    4288     CPUMRZFpuStateActualizeForChange(pVCpu);
    4289 #endif
    4290     IEM_CTX_IMPORT_NORET(pVCpu, CPUMCTX_EXTRN_X87 | CPUMCTX_EXTRN_SSE_AVX | CPUMCTX_EXTRN_OTHER_XSAVE | CPUMCTX_EXTRN_XCRx);
    4291 
    4292     /* Just assume we're going to make changes to the SSE and YMM_HI parts. */
    4293     pVCpu->cpum.GstCtx.XState.Hdr.bmXState |= XSAVE_C_YMM | XSAVE_C_SSE;
    4294 }
    4295 
    4296 
    4297 /**
    4298  * Stores a QNaN value into a FPU register.
    4299  *
    4300  * @param   pReg                Pointer to the register.
    4301  */
    4302 DECLINLINE(void) iemFpuStoreQNan(PRTFLOAT80U pReg) RT_NOEXCEPT
    4303 {
    4304     pReg->au32[0] = UINT32_C(0x00000000);
    4305     pReg->au32[1] = UINT32_C(0xc0000000);
    4306     pReg->au16[4] = UINT16_C(0xffff);
    4307 }
    4308 
    4309 
    4310 /**
    4311  * Updates the FOP, FPU.CS and FPUIP registers, extended version.
    4312  *
    4313  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    4314  * @param   pFpuCtx             The FPU context.
    4315  * @param   uFpuOpcode          The FPU opcode value (see IEMCPU::uFpuOpcode).
    4316  */
    4317 DECLINLINE(void) iemFpuUpdateOpcodeAndIpWorkerEx(PVMCPUCC pVCpu, PX86FXSTATE pFpuCtx, uint16_t uFpuOpcode) RT_NOEXCEPT
    4318 {
    4319     Assert(uFpuOpcode != UINT16_MAX);
    4320     pFpuCtx->FOP = uFpuOpcode;
    4321     /** @todo x87.CS and FPUIP needs to be kept seperately. */
    4322     if (IEM_IS_REAL_OR_V86_MODE(pVCpu))
    4323     {
    4324         /** @todo Testcase: making assumptions about how FPUIP and FPUDP are handled
    4325          *        happens in real mode here based on the fnsave and fnstenv images. */
    4326         pFpuCtx->CS    = 0;
    4327         pFpuCtx->FPUIP = pVCpu->cpum.GstCtx.eip | ((uint32_t)pVCpu->cpum.GstCtx.cs.Sel << 4);
    4328     }
    4329     else if (!IEM_IS_LONG_MODE(pVCpu))
    4330     {
    4331         pFpuCtx->CS    = pVCpu->cpum.GstCtx.cs.Sel;
    4332         pFpuCtx->FPUIP = pVCpu->cpum.GstCtx.rip;
    4333     }
    4334     else
    4335         *(uint64_t *)&pFpuCtx->FPUIP = pVCpu->cpum.GstCtx.rip;
    4336 }
    4337 
    4338 
    4339 /**
    4340  * Marks the specified stack register as free (for FFREE).
    4341  *
    4342  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    4343  * @param   iStReg              The register to free.
    4344  */
    4345 DECLINLINE(void) iemFpuStackFree(PVMCPUCC pVCpu, uint8_t iStReg) RT_NOEXCEPT
    4346 {
    4347     Assert(iStReg < 8);
    4348     PX86FXSTATE pFpuCtx = &pVCpu->cpum.GstCtx.XState.x87;
    4349     uint8_t     iReg    = (X86_FSW_TOP_GET(pFpuCtx->FSW) + iStReg) & X86_FSW_TOP_SMASK;
    4350     pFpuCtx->FTW &= ~RT_BIT(iReg);
    4351 }
    4352 
    4353 
    4354 /**
    4355  * Increments FSW.TOP, i.e. pops an item off the stack without freeing it.
    4356  *
    4357  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    4358  */
    4359 DECLINLINE(void) iemFpuStackIncTop(PVMCPUCC pVCpu) RT_NOEXCEPT
    4360 {
    4361     PX86FXSTATE pFpuCtx = &pVCpu->cpum.GstCtx.XState.x87;
    4362     uint16_t    uFsw    = pFpuCtx->FSW;
    4363     uint16_t    uTop    = uFsw & X86_FSW_TOP_MASK;
    4364     uTop  = (uTop + (1 << X86_FSW_TOP_SHIFT)) & X86_FSW_TOP_MASK;
    4365     uFsw &= ~X86_FSW_TOP_MASK;
    4366     uFsw |= uTop;
    4367     pFpuCtx->FSW = uFsw;
    4368 }
    4369 
    4370 
    4371 /**
    4372  * Decrements FSW.TOP, i.e. push an item off the stack without storing anything.
    4373  *
    4374  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    4375  */
    4376 DECLINLINE(void) iemFpuStackDecTop(PVMCPUCC pVCpu) RT_NOEXCEPT
    4377 {
    4378     PX86FXSTATE pFpuCtx = &pVCpu->cpum.GstCtx.XState.x87;
    4379     uint16_t    uFsw    = pFpuCtx->FSW;
    4380     uint16_t    uTop    = uFsw & X86_FSW_TOP_MASK;
    4381     uTop  = (uTop + (7 << X86_FSW_TOP_SHIFT)) & X86_FSW_TOP_MASK;
    4382     uFsw &= ~X86_FSW_TOP_MASK;
    4383     uFsw |= uTop;
    4384     pFpuCtx->FSW = uFsw;
    4385 }
    4386 
    4387 
    4388 
    4389 
    4390 DECLINLINE(int) iemFpuStRegNotEmpty(PVMCPUCC pVCpu, uint8_t iStReg) RT_NOEXCEPT
    4391 {
    4392     PX86FXSTATE pFpuCtx = &pVCpu->cpum.GstCtx.XState.x87;
    4393     uint16_t    iReg    = (X86_FSW_TOP_GET(pFpuCtx->FSW) + iStReg) & X86_FSW_TOP_SMASK;
    4394     if (pFpuCtx->FTW & RT_BIT(iReg))
    4395         return VINF_SUCCESS;
    4396     return VERR_NOT_FOUND;
    4397 }
    4398 
    4399 
    4400 DECLINLINE(int) iemFpuStRegNotEmptyRef(PVMCPUCC pVCpu, uint8_t iStReg, PCRTFLOAT80U *ppRef) RT_NOEXCEPT
    4401 {
    4402     PX86FXSTATE pFpuCtx = &pVCpu->cpum.GstCtx.XState.x87;
    4403     uint16_t    iReg    = (X86_FSW_TOP_GET(pFpuCtx->FSW) + iStReg) & X86_FSW_TOP_SMASK;
    4404     if (pFpuCtx->FTW & RT_BIT(iReg))
    4405     {
    4406         *ppRef = &pFpuCtx->aRegs[iStReg].r80;
    4407         return VINF_SUCCESS;
    4408     }
    4409     return VERR_NOT_FOUND;
    4410 }
    4411 
    4412 
    4413 DECLINLINE(int) iemFpu2StRegsNotEmptyRef(PVMCPUCC pVCpu, uint8_t iStReg0, PCRTFLOAT80U *ppRef0,
    4414                                         uint8_t iStReg1, PCRTFLOAT80U *ppRef1) RT_NOEXCEPT
    4415 {
    4416     PX86FXSTATE pFpuCtx = &pVCpu->cpum.GstCtx.XState.x87;
    4417     uint16_t    iTop    = X86_FSW_TOP_GET(pFpuCtx->FSW);
    4418     uint16_t    iReg0   = (iTop + iStReg0) & X86_FSW_TOP_SMASK;
    4419     uint16_t    iReg1   = (iTop + iStReg1) & X86_FSW_TOP_SMASK;
    4420     if ((pFpuCtx->FTW & (RT_BIT(iReg0) | RT_BIT(iReg1))) == (RT_BIT(iReg0) | RT_BIT(iReg1)))
    4421     {
    4422         *ppRef0 = &pFpuCtx->aRegs[iStReg0].r80;
    4423         *ppRef1 = &pFpuCtx->aRegs[iStReg1].r80;
    4424         return VINF_SUCCESS;
    4425     }
    4426     return VERR_NOT_FOUND;
    4427 }
    4428 
    4429 
    4430 DECLINLINE(int) iemFpu2StRegsNotEmptyRefFirst(PVMCPUCC pVCpu, uint8_t iStReg0, PCRTFLOAT80U *ppRef0, uint8_t iStReg1) RT_NOEXCEPT
    4431 {
    4432     PX86FXSTATE pFpuCtx = &pVCpu->cpum.GstCtx.XState.x87;
    4433     uint16_t    iTop    = X86_FSW_TOP_GET(pFpuCtx->FSW);
    4434     uint16_t    iReg0   = (iTop + iStReg0) & X86_FSW_TOP_SMASK;
    4435     uint16_t    iReg1   = (iTop + iStReg1) & X86_FSW_TOP_SMASK;
    4436     if ((pFpuCtx->FTW & (RT_BIT(iReg0) | RT_BIT(iReg1))) == (RT_BIT(iReg0) | RT_BIT(iReg1)))
    4437     {
    4438         *ppRef0 = &pFpuCtx->aRegs[iStReg0].r80;
    4439         return VINF_SUCCESS;
    4440     }
    4441     return VERR_NOT_FOUND;
    4442 }
    4443 
    4444 
    4445 /**
    4446  * Rotates the stack registers when setting new TOS.
    4447  *
    4448  * @param   pFpuCtx             The FPU context.
    4449  * @param   iNewTop             New TOS value.
    4450  * @remarks We only do this to speed up fxsave/fxrstor which
    4451  *          arrange the FP registers in stack order.
    4452  *          MUST be done before writing the new TOS (FSW).
    4453  */
    4454 DECLINLINE(void) iemFpuRotateStackSetTop(PX86FXSTATE pFpuCtx, uint16_t iNewTop) RT_NOEXCEPT
    4455 {
    4456     uint16_t iOldTop = X86_FSW_TOP_GET(pFpuCtx->FSW);
    4457     RTFLOAT80U ar80Temp[8];
    4458 
    4459     if (iOldTop == iNewTop)
    4460         return;
    4461 
    4462     /* Unscrew the stack and get it into 'native' order. */
    4463     ar80Temp[0] = pFpuCtx->aRegs[(8 - iOldTop + 0) & X86_FSW_TOP_SMASK].r80;
    4464     ar80Temp[1] = pFpuCtx->aRegs[(8 - iOldTop + 1) & X86_FSW_TOP_SMASK].r80;
    4465     ar80Temp[2] = pFpuCtx->aRegs[(8 - iOldTop + 2) & X86_FSW_TOP_SMASK].r80;
    4466     ar80Temp[3] = pFpuCtx->aRegs[(8 - iOldTop + 3) & X86_FSW_TOP_SMASK].r80;
    4467     ar80Temp[4] = pFpuCtx->aRegs[(8 - iOldTop + 4) & X86_FSW_TOP_SMASK].r80;
    4468     ar80Temp[5] = pFpuCtx->aRegs[(8 - iOldTop + 5) & X86_FSW_TOP_SMASK].r80;
    4469     ar80Temp[6] = pFpuCtx->aRegs[(8 - iOldTop + 6) & X86_FSW_TOP_SMASK].r80;
    4470     ar80Temp[7] = pFpuCtx->aRegs[(8 - iOldTop + 7) & X86_FSW_TOP_SMASK].r80;
    4471 
    4472     /* Now rotate the stack to the new position. */
    4473     pFpuCtx->aRegs[0].r80 = ar80Temp[(iNewTop + 0) & X86_FSW_TOP_SMASK];
    4474     pFpuCtx->aRegs[1].r80 = ar80Temp[(iNewTop + 1) & X86_FSW_TOP_SMASK];
    4475     pFpuCtx->aRegs[2].r80 = ar80Temp[(iNewTop + 2) & X86_FSW_TOP_SMASK];
    4476     pFpuCtx->aRegs[3].r80 = ar80Temp[(iNewTop + 3) & X86_FSW_TOP_SMASK];
    4477     pFpuCtx->aRegs[4].r80 = ar80Temp[(iNewTop + 4) & X86_FSW_TOP_SMASK];
    4478     pFpuCtx->aRegs[5].r80 = ar80Temp[(iNewTop + 5) & X86_FSW_TOP_SMASK];
    4479     pFpuCtx->aRegs[6].r80 = ar80Temp[(iNewTop + 6) & X86_FSW_TOP_SMASK];
    4480     pFpuCtx->aRegs[7].r80 = ar80Temp[(iNewTop + 7) & X86_FSW_TOP_SMASK];
    4481 }
    4482 
    4483 
    4484 /**
    4485  * Updates the FPU exception status after FCW is changed.
    4486  *
    4487  * @param   pFpuCtx             The FPU context.
    4488  */
    4489 DECLINLINE(void) iemFpuRecalcExceptionStatus(PX86FXSTATE pFpuCtx) RT_NOEXCEPT
    4490 {
    4491     uint16_t u16Fsw = pFpuCtx->FSW;
    4492     if ((u16Fsw & X86_FSW_XCPT_MASK) & ~(pFpuCtx->FCW & X86_FCW_XCPT_MASK))
    4493         u16Fsw |= X86_FSW_ES | X86_FSW_B;
    4494     else
    4495         u16Fsw &= ~(X86_FSW_ES | X86_FSW_B);
    4496     pFpuCtx->FSW = u16Fsw;
    4497 }
    4498 
    4499 
    4500 /**
    4501  * Calculates the full FTW (FPU tag word) for use in FNSTENV and FNSAVE.
    4502  *
    4503  * @returns The full FTW.
    4504  * @param   pFpuCtx             The FPU context.
    4505  */
    4506 DECLINLINE(uint16_t) iemFpuCalcFullFtw(PCX86FXSTATE pFpuCtx) RT_NOEXCEPT
    4507 {
    4508     uint8_t const   u8Ftw  = (uint8_t)pFpuCtx->FTW;
    4509     uint16_t        u16Ftw = 0;
    4510     unsigned const  iTop   = X86_FSW_TOP_GET(pFpuCtx->FSW);
    4511     for (unsigned iSt = 0; iSt < 8; iSt++)
    4512     {
    4513         unsigned const iReg = (iSt + iTop) & 7;
    4514         if (!(u8Ftw & RT_BIT(iReg)))
    4515             u16Ftw |= 3 << (iReg * 2); /* empty */
    4516         else
    4517         {
    4518             uint16_t uTag;
    4519             PCRTFLOAT80U const pr80Reg = &pFpuCtx->aRegs[iSt].r80;
    4520             if (pr80Reg->s.uExponent == 0x7fff)
    4521                 uTag = 2; /* Exponent is all 1's => Special. */
    4522             else if (pr80Reg->s.uExponent == 0x0000)
    4523             {
    4524                 if (pr80Reg->s.uMantissa == 0x0000)
    4525                     uTag = 1; /* All bits are zero => Zero. */
    4526                 else
    4527                     uTag = 2; /* Must be special. */
    4528             }
    4529             else if (pr80Reg->s.uMantissa & RT_BIT_64(63)) /* The J bit. */
    4530                 uTag = 0; /* Valid. */
    4531             else
    4532                 uTag = 2; /* Must be special. */
    4533 
    4534             u16Ftw |= uTag << (iReg * 2);
    4535         }
    4536     }
    4537 
    4538     return u16Ftw;
    4539 }
    4540 
    4541 
    4542 /**
    4543  * Converts a full FTW to a compressed one (for use in FLDENV and FRSTOR).
    4544  *
    4545  * @returns The compressed FTW.
    4546  * @param   u16FullFtw      The full FTW to convert.
    4547  */
    4548 DECLINLINE(uint16_t) iemFpuCompressFtw(uint16_t u16FullFtw) RT_NOEXCEPT
    4549 {
    4550     uint8_t u8Ftw = 0;
    4551     for (unsigned i = 0; i < 8; i++)
    4552     {
    4553         if ((u16FullFtw & 3) != 3 /*empty*/)
    4554             u8Ftw |= RT_BIT(i);
    4555         u16FullFtw >>= 2;
    4556     }
    4557 
    4558     return u8Ftw;
    4559 }
    4560 
    4561 /** @}  */
    4562 
    4563 
    4564 /** @name   Memory access.
    4565  *
    4566  * @{
    4567  */
    4568 
    4569 
    4570 /**
    4571  * Checks whether alignment checks are enabled or not.
    4572  *
    4573  * @returns true if enabled, false if not.
    4574  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    4575  */
    4576 DECLINLINE(bool) iemMemAreAlignmentChecksEnabled(PVMCPUCC pVCpu) RT_NOEXCEPT
    4577 {
    4578 #if 0
    4579     AssertCompile(X86_CR0_AM == X86_EFL_AC);
    4580     return IEM_GET_CPL(pVCpu) == 3
    4581         && (((uint32_t)pVCpu->cpum.GstCtx.cr0 & pVCpu->cpum.GstCtx.eflags.u) & X86_CR0_AM);
    4582 #else
    4583     return RT_BOOL(pVCpu->iem.s.fExec & IEM_F_X86_AC);
    4584 #endif
    4585 }
    4586 
    4587 /**
    4588  * Checks if the given segment can be written to, raise the appropriate
    4589  * exception if not.
    4590  *
    4591  * @returns VBox strict status code.
    4592  *
    4593  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    4594  * @param   pHid                Pointer to the hidden register.
    4595  * @param   iSegReg             The register number.
    4596  * @param   pu64BaseAddr        Where to return the base address to use for the
    4597  *                              segment. (In 64-bit code it may differ from the
    4598  *                              base in the hidden segment.)
    4599  */
    4600 DECLINLINE(VBOXSTRICTRC) iemMemSegCheckWriteAccessEx(PVMCPUCC pVCpu, PCCPUMSELREGHID pHid,
    4601                                                      uint8_t iSegReg, uint64_t *pu64BaseAddr) RT_NOEXCEPT
    4602 {
    4603     IEM_CTX_ASSERT(pVCpu, CPUMCTX_EXTRN_SREG_FROM_IDX(iSegReg));
    4604 
    4605     if (IEM_IS_64BIT_CODE(pVCpu))
    4606         *pu64BaseAddr = iSegReg < X86_SREG_FS ? 0 : pHid->u64Base;
    4607     else
    4608     {
    4609         if (!pHid->Attr.n.u1Present)
    4610         {
    4611             uint16_t    uSel = iemSRegFetchU16(pVCpu, iSegReg);
    4612             AssertRelease(uSel == 0);
    4613             LogEx(LOG_GROUP_IEM,("iemMemSegCheckWriteAccessEx: %#x (index %u) - bad selector -> #GP\n", uSel, iSegReg));
    4614             return iemRaiseGeneralProtectionFault0(pVCpu);
    4615         }
    4616 
    4617         if (   (   (pHid->Attr.n.u4Type & X86_SEL_TYPE_CODE)
    4618                 || !(pHid->Attr.n.u4Type & X86_SEL_TYPE_WRITE) )
    4619             && !IEM_IS_64BIT_CODE(pVCpu) )
    4620             return iemRaiseSelectorInvalidAccess(pVCpu, iSegReg, IEM_ACCESS_DATA_W);
    4621         *pu64BaseAddr = pHid->u64Base;
    4622     }
    4623     return VINF_SUCCESS;
    4624 }
    4625 
    4626 
    4627 /**
    4628  * Checks if the given segment can be read from, raise the appropriate
    4629  * exception if not.
    4630  *
    4631  * @returns VBox strict status code.
    4632  *
    4633  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    4634  * @param   pHid                Pointer to the hidden register.
    4635  * @param   iSegReg             The register number.
    4636  * @param   pu64BaseAddr        Where to return the base address to use for the
    4637  *                              segment. (In 64-bit code it may differ from the
    4638  *                              base in the hidden segment.)
    4639  */
    4640 DECLINLINE(VBOXSTRICTRC) iemMemSegCheckReadAccessEx(PVMCPUCC pVCpu, PCCPUMSELREGHID pHid,
    4641                                                     uint8_t iSegReg, uint64_t *pu64BaseAddr) RT_NOEXCEPT
    4642 {
    4643     IEM_CTX_ASSERT(pVCpu, CPUMCTX_EXTRN_SREG_FROM_IDX(iSegReg));
    4644 
    4645     if (IEM_IS_64BIT_CODE(pVCpu))
    4646         *pu64BaseAddr = iSegReg < X86_SREG_FS ? 0 : pHid->u64Base;
    4647     else
    4648     {
    4649         if (!pHid->Attr.n.u1Present)
    4650         {
    4651             uint16_t    uSel = iemSRegFetchU16(pVCpu, iSegReg);
    4652             AssertRelease(uSel == 0);
    4653             LogEx(LOG_GROUP_IEM,("iemMemSegCheckReadAccessEx: %#x (index %u) - bad selector -> #GP\n", uSel, iSegReg));
    4654             return iemRaiseGeneralProtectionFault0(pVCpu);
    4655         }
    4656 
    4657         if ((pHid->Attr.n.u4Type & (X86_SEL_TYPE_CODE | X86_SEL_TYPE_READ)) == X86_SEL_TYPE_CODE)
    4658             return iemRaiseSelectorInvalidAccess(pVCpu, iSegReg, IEM_ACCESS_DATA_R);
    4659         *pu64BaseAddr = pHid->u64Base;
    4660     }
    4661     return VINF_SUCCESS;
    4662 }
    4663 
    4664293
    4665294/**
     
    4717346}
    4718347
    4719 #ifdef IEM_WITH_SETJMP
    4720 
    4721 /** @todo slim this down   */
    4722 DECL_INLINE_THROW(RTGCPTR) iemMemApplySegmentToReadJmp(PVMCPUCC pVCpu, uint8_t iSegReg,
    4723                                                        size_t cbMem, RTGCPTR GCPtrMem) IEM_NOEXCEPT_MAY_LONGJMP
    4724 {
    4725     Assert(cbMem >= 1);
    4726     Assert(iSegReg < X86_SREG_COUNT);
    4727 
    4728     /*
    4729      * 64-bit mode is simpler.
    4730      */
    4731     if (IEM_IS_64BIT_CODE(pVCpu))
    4732     {
    4733         if (iSegReg >= X86_SREG_FS && iSegReg != UINT8_MAX)
    4734         {
    4735             IEM_CTX_IMPORT_JMP(pVCpu, CPUMCTX_EXTRN_SREG_FROM_IDX(iSegReg));
    4736             PCPUMSELREGHID const pSel = iemSRegGetHid(pVCpu, iSegReg);
    4737             GCPtrMem += pSel->u64Base;
    4738         }
    4739 
    4740         if (RT_LIKELY(X86_IS_CANONICAL(GCPtrMem) && X86_IS_CANONICAL(GCPtrMem + cbMem - 1)))
    4741             return GCPtrMem;
    4742         iemRaiseGeneralProtectionFault0Jmp(pVCpu);
    4743     }
    4744     /*
    4745      * 16-bit and 32-bit segmentation.
    4746      */
    4747     else if (iSegReg != UINT8_MAX)
    4748     {
    4749         /** @todo Does this apply to segments with 4G-1 limit? */
    4750         uint32_t const GCPtrLast32 = (uint32_t)GCPtrMem + (uint32_t)cbMem - 1;
    4751         if (RT_LIKELY(GCPtrLast32 >= (uint32_t)GCPtrMem))
    4752         {
    4753             IEM_CTX_IMPORT_JMP(pVCpu, CPUMCTX_EXTRN_SREG_FROM_IDX(iSegReg));
    4754             PCPUMSELREGHID const pSel = iemSRegGetHid(pVCpu, iSegReg);
    4755             switch (pSel->Attr.u & (  X86DESCATTR_P     | X86DESCATTR_UNUSABLE
    4756                                     | X86_SEL_TYPE_READ | X86_SEL_TYPE_WRITE /* same as read */
    4757                                     | X86_SEL_TYPE_DOWN | X86_SEL_TYPE_CONF  /* same as down */
    4758                                     | X86_SEL_TYPE_CODE))
    4759             {
    4760                 case X86DESCATTR_P:                                         /* readonly data, expand up */
    4761                 case X86DESCATTR_P | X86_SEL_TYPE_WRITE:                    /* writable data, expand up */
    4762                 case X86DESCATTR_P | X86_SEL_TYPE_CODE | X86_SEL_TYPE_READ: /* code, read-only */
    4763                 case X86DESCATTR_P | X86_SEL_TYPE_CODE | X86_SEL_TYPE_READ | X86_SEL_TYPE_CONF: /* conforming code, read-only */
    4764                     /* expand up */
    4765                     if (RT_LIKELY(GCPtrLast32 <= pSel->u32Limit))
    4766                         return (uint32_t)GCPtrMem + (uint32_t)pSel->u64Base;
    4767                     Log10(("iemMemApplySegmentToReadJmp: out of bounds %#x..%#x vs %#x\n",
    4768                            (uint32_t)GCPtrMem, GCPtrLast32, pSel->u32Limit));
    4769                     break;
    4770 
    4771                 case X86DESCATTR_P | X86_SEL_TYPE_DOWN:                         /* readonly data, expand down */
    4772                 case X86DESCATTR_P | X86_SEL_TYPE_DOWN | X86_SEL_TYPE_WRITE:    /* writable data, expand down */
    4773                     /* expand down */
    4774                     if (RT_LIKELY(   (uint32_t)GCPtrMem > pSel->u32Limit
    4775                                   && (   pSel->Attr.n.u1DefBig
    4776                                       || GCPtrLast32 <= UINT32_C(0xffff)) ))
    4777                         return (uint32_t)GCPtrMem + (uint32_t)pSel->u64Base;
    4778                     Log10(("iemMemApplySegmentToReadJmp: expand down out of bounds %#x..%#x vs %#x..%#x\n",
    4779                            (uint32_t)GCPtrMem, GCPtrLast32, pSel->u32Limit, pSel->Attr.n.u1DefBig ? UINT32_MAX : UINT16_MAX));
    4780                     break;
    4781 
    4782                 default:
    4783                     Log10(("iemMemApplySegmentToReadJmp: bad selector %#x\n", pSel->Attr.u));
    4784                     iemRaiseSelectorInvalidAccessJmp(pVCpu, iSegReg, IEM_ACCESS_DATA_R);
    4785                     break;
    4786             }
    4787         }
    4788         Log10(("iemMemApplySegmentToReadJmp: out of bounds %#x..%#x\n",(uint32_t)GCPtrMem, GCPtrLast32));
    4789         iemRaiseSelectorBoundsJmp(pVCpu, iSegReg, IEM_ACCESS_DATA_R);
    4790     }
    4791     /*
    4792      * 32-bit flat address.
    4793      */
    4794     else
    4795         return GCPtrMem;
    4796 }
    4797 
    4798 
    4799 /** @todo slim this down   */
    4800 DECL_INLINE_THROW(RTGCPTR) iemMemApplySegmentToWriteJmp(PVMCPUCC pVCpu, uint8_t iSegReg, size_t cbMem,
    4801                                                         RTGCPTR GCPtrMem) IEM_NOEXCEPT_MAY_LONGJMP
    4802 {
    4803     Assert(cbMem >= 1);
    4804     Assert(iSegReg < X86_SREG_COUNT);
    4805 
    4806     /*
    4807      * 64-bit mode is simpler.
    4808      */
    4809     if (IEM_IS_64BIT_CODE(pVCpu))
    4810     {
    4811         if (iSegReg >= X86_SREG_FS)
    4812         {
    4813             IEM_CTX_IMPORT_JMP(pVCpu, CPUMCTX_EXTRN_SREG_FROM_IDX(iSegReg));
    4814             PCPUMSELREGHID pSel = iemSRegGetHid(pVCpu, iSegReg);
    4815             GCPtrMem += pSel->u64Base;
    4816         }
    4817 
    4818         if (RT_LIKELY(X86_IS_CANONICAL(GCPtrMem) && X86_IS_CANONICAL(GCPtrMem + cbMem - 1)))
    4819             return GCPtrMem;
    4820     }
    4821     /*
    4822      * 16-bit and 32-bit segmentation.
    4823      */
    4824     else
    4825     {
    4826         Assert(GCPtrMem <= UINT32_MAX);
    4827         IEM_CTX_IMPORT_JMP(pVCpu, CPUMCTX_EXTRN_SREG_FROM_IDX(iSegReg));
    4828         PCPUMSELREGHID pSel           = iemSRegGetHid(pVCpu, iSegReg);
    4829         uint32_t const fRelevantAttrs = pSel->Attr.u & (  X86DESCATTR_P     | X86DESCATTR_UNUSABLE
    4830                                                         | X86_SEL_TYPE_CODE | X86_SEL_TYPE_WRITE | X86_SEL_TYPE_DOWN);
    4831         if (   fRelevantAttrs == (X86DESCATTR_P | X86_SEL_TYPE_WRITE) /* data, expand up */
    4832                /** @todo explore exactly how the CS stuff works in real mode. See also
    4833                 *        http://www.rcollins.org/Productivity/DescriptorCache.html and
    4834                 *        http://www.rcollins.org/ddj/Aug98/Aug98.html for some insight. */
    4835             || (iSegReg == X86_SREG_CS && IEM_IS_REAL_OR_V86_MODE(pVCpu)) ) /* Ignored for CS. */ /** @todo testcase! */
    4836         {
    4837             /* expand up */
    4838             uint32_t const GCPtrLast32 = (uint32_t)GCPtrMem + (uint32_t)cbMem - 1;
    4839             if (RT_LIKELY(   GCPtrLast32 <= pSel->u32Limit
    4840                           && GCPtrLast32 >= (uint32_t)GCPtrMem))
    4841                 return (uint32_t)GCPtrMem + (uint32_t)pSel->u64Base;
    4842             iemRaiseSelectorBoundsJmp(pVCpu, iSegReg, IEM_ACCESS_DATA_W);
    4843         }
    4844         else if (fRelevantAttrs == (X86DESCATTR_P | X86_SEL_TYPE_WRITE | X86_SEL_TYPE_DOWN)) /* data, expand up */
    4845         {
    4846             /* expand down - the uppger boundary is defined by the B bit, not G. */
    4847             uint32_t GCPtrLast32 = (uint32_t)GCPtrMem + (uint32_t)cbMem - 1;
    4848             if (RT_LIKELY(   (uint32_t)GCPtrMem >= pSel->u32Limit
    4849                           && (pSel->Attr.n.u1DefBig || GCPtrLast32 <= UINT32_C(0xffff))
    4850                           && GCPtrLast32 >= (uint32_t)GCPtrMem))
    4851                 return (uint32_t)GCPtrMem + (uint32_t)pSel->u64Base;
    4852             iemRaiseSelectorBoundsJmp(pVCpu, iSegReg, IEM_ACCESS_DATA_W);
    4853         }
    4854         else
    4855             iemRaiseSelectorInvalidAccessJmp(pVCpu, iSegReg, IEM_ACCESS_DATA_W);
    4856     }
    4857     iemRaiseGeneralProtectionFault0Jmp(pVCpu);
    4858 }
    4859 
    4860 #endif /* IEM_WITH_SETJMP */
    4861 
    4862 /**
    4863  * Fakes a long mode stack selector for SS = 0.
    4864  *
    4865  * @param   pDescSs             Where to return the fake stack descriptor.
    4866  * @param   uDpl                The DPL we want.
    4867  */
    4868 DECLINLINE(void) iemMemFakeStackSelDesc(PIEMSELDESC pDescSs, uint32_t uDpl) RT_NOEXCEPT
    4869 {
    4870     pDescSs->Long.au64[0] = 0;
    4871     pDescSs->Long.au64[1] = 0;
    4872     pDescSs->Long.Gen.u4Type     = X86_SEL_TYPE_RW_ACC;
    4873     pDescSs->Long.Gen.u1DescType = 1; /* 1 = code / data, 0 = system. */
    4874     pDescSs->Long.Gen.u2Dpl      = uDpl;
    4875     pDescSs->Long.Gen.u1Present  = 1;
    4876     pDescSs->Long.Gen.u1Long     = 1;
    4877 }
    4878 
    4879348
    4880349/*
     
    4935404
    4936405
    4937 /*
    4938  * Instantiate R/W inline templates.
    4939  */
    4940 
    4941 /** @def TMPL_MEM_CHECK_UNALIGNED_WITHIN_PAGE_OK
    4942  * Used to check if an unaligned access is if within the page and won't
    4943  * trigger an \#AC.
    4944  *
    4945  * This can also be used to deal with misaligned accesses on platforms that are
    4946  * senstive to such if desires.
    4947  */
    4948 #if 1
    4949 # define TMPL_MEM_CHECK_UNALIGNED_WITHIN_PAGE_OK(a_pVCpu, a_GCPtrEff, a_TmplMemType) \
    4950     (   ((a_GCPtrEff) & GUEST_PAGE_OFFSET_MASK) <= GUEST_PAGE_SIZE - sizeof(a_TmplMemType) \
    4951      && !((a_pVCpu)->iem.s.fExec & IEM_F_X86_AC) )
    4952 #else
    4953 # define TMPL_MEM_CHECK_UNALIGNED_WITHIN_PAGE_OK(a_pVCpu, a_GCPtrEff, a_TmplMemType) 0
    4954 #endif
    4955 
    4956 #define TMPL_MEM_WITH_ATOMIC_MAPPING
    4957 
    4958 #define TMPL_MEM_TYPE       uint8_t
    4959 #define TMPL_MEM_TYPE_ALIGN 0
    4960 #define TMPL_MEM_TYPE_SIZE  1
    4961 #define TMPL_MEM_FN_SUFF    U8
    4962 #define TMPL_MEM_FMT_TYPE   "%#04x"
    4963 #define TMPL_MEM_FMT_DESC   "byte"
    4964 #include "../VMMAll/IEMAllMemRWTmplInline.cpp.h"
    4965 
    4966 #define TMPL_MEM_WITH_STACK
    4967 
    4968 #define TMPL_MEM_TYPE       uint16_t
    4969 #define TMPL_MEM_TYPE_ALIGN 1
    4970 #define TMPL_MEM_TYPE_SIZE  2
    4971 #define TMPL_MEM_FN_SUFF    U16
    4972 #define TMPL_MEM_FMT_TYPE   "%#06x"
    4973 #define TMPL_MEM_FMT_DESC   "word"
    4974 #include "../VMMAll/IEMAllMemRWTmplInline.cpp.h"
    4975 
    4976 #define TMPL_WITH_PUSH_SREG
    4977 #define TMPL_MEM_TYPE       uint32_t
    4978 #define TMPL_MEM_TYPE_ALIGN 3
    4979 #define TMPL_MEM_TYPE_SIZE  4
    4980 #define TMPL_MEM_FN_SUFF    U32
    4981 #define TMPL_MEM_FMT_TYPE   "%#010x"
    4982 #define TMPL_MEM_FMT_DESC   "dword"
    4983 #include "../VMMAll/IEMAllMemRWTmplInline.cpp.h"
    4984 #undef  TMPL_WITH_PUSH_SREG
    4985 
    4986 #define TMPL_MEM_TYPE       uint64_t
    4987 #define TMPL_MEM_TYPE_ALIGN 7
    4988 #define TMPL_MEM_TYPE_SIZE  8
    4989 #define TMPL_MEM_FN_SUFF    U64
    4990 #define TMPL_MEM_FMT_TYPE   "%#018RX64"
    4991 #define TMPL_MEM_FMT_DESC   "qword"
    4992 #include "../VMMAll/IEMAllMemRWTmplInline.cpp.h"
    4993 
    4994 #undef TMPL_MEM_WITH_STACK
    4995 #undef TMPL_MEM_WITH_ATOMIC_MAPPING
    4996 
    4997 #define TMPL_MEM_NO_MAPPING /* currently sticky */
    4998 
    4999 #define TMPL_MEM_NO_STORE
    5000 #define TMPL_MEM_TYPE       uint32_t
    5001 #define TMPL_MEM_TYPE_ALIGN 0
    5002 #define TMPL_MEM_TYPE_SIZE  4
    5003 #define TMPL_MEM_FN_SUFF    U32NoAc
    5004 #define TMPL_MEM_FMT_TYPE   "%#010x"
    5005 #define TMPL_MEM_FMT_DESC   "dword"
    5006 #include "../VMMAll/IEMAllMemRWTmplInline.cpp.h"
    5007 
    5008 #define TMPL_MEM_NO_STORE
    5009 #define TMPL_MEM_TYPE       uint64_t
    5010 #define TMPL_MEM_TYPE_ALIGN 0
    5011 #define TMPL_MEM_TYPE_SIZE  8
    5012 #define TMPL_MEM_FN_SUFF    U64NoAc
    5013 #define TMPL_MEM_FMT_TYPE   "%#018RX64"
    5014 #define TMPL_MEM_FMT_DESC   "qword"
    5015 #include "../VMMAll/IEMAllMemRWTmplInline.cpp.h"
    5016 
    5017 #define TMPL_MEM_NO_STORE
    5018 #define TMPL_MEM_TYPE       uint64_t
    5019 #define TMPL_MEM_TYPE_ALIGN 15
    5020 #define TMPL_MEM_TYPE_SIZE  8
    5021 #define TMPL_MEM_FN_SUFF    U64AlignedU128
    5022 #define TMPL_MEM_FMT_TYPE   "%#018RX64"
    5023 #define TMPL_MEM_FMT_DESC   "qword"
    5024 #include "../VMMAll/IEMAllMemRWTmplInline.cpp.h"
    5025 
    5026 #undef TMPL_MEM_NO_MAPPING
    5027 
    5028 #define TMPL_MEM_TYPE       RTFLOAT80U
    5029 #define TMPL_MEM_TYPE_ALIGN 7
    5030 #define TMPL_MEM_TYPE_SIZE  10
    5031 #define TMPL_MEM_FN_SUFF    R80
    5032 #define TMPL_MEM_FMT_TYPE   "%.10Rhxs"
    5033 #define TMPL_MEM_FMT_DESC   "tword"
    5034 #include "../VMMAll/IEMAllMemRWTmplInline.cpp.h"
    5035 
    5036 #define TMPL_MEM_TYPE       RTPBCD80U
    5037 #define TMPL_MEM_TYPE_ALIGN 7           /** @todo RTPBCD80U alignment testcase */
    5038 #define TMPL_MEM_TYPE_SIZE  10
    5039 #define TMPL_MEM_FN_SUFF    D80
    5040 #define TMPL_MEM_FMT_TYPE   "%.10Rhxs"
    5041 #define TMPL_MEM_FMT_DESC   "tword"
    5042 #include "../VMMAll/IEMAllMemRWTmplInline.cpp.h"
    5043 
    5044 #define TMPL_MEM_WITH_ATOMIC_MAPPING
    5045 #define TMPL_MEM_TYPE       RTUINT128U
    5046 #define TMPL_MEM_TYPE_ALIGN 15
    5047 #define TMPL_MEM_TYPE_SIZE  16
    5048 #define TMPL_MEM_FN_SUFF    U128
    5049 #define TMPL_MEM_FMT_TYPE   "%.16Rhxs"
    5050 #define TMPL_MEM_FMT_DESC   "dqword"
    5051 #include "../VMMAll/IEMAllMemRWTmplInline.cpp.h"
    5052 #undef  TMPL_MEM_WITH_ATOMIC_MAPPING
    5053 
    5054 #define TMPL_MEM_NO_MAPPING
    5055 #define TMPL_MEM_TYPE       RTUINT128U
    5056 #define TMPL_MEM_TYPE_ALIGN 0
    5057 #define TMPL_MEM_TYPE_SIZE  16
    5058 #define TMPL_MEM_FN_SUFF    U128NoAc
    5059 #define TMPL_MEM_FMT_TYPE   "%.16Rhxs"
    5060 #define TMPL_MEM_FMT_DESC   "dqword"
    5061 #include "../VMMAll/IEMAllMemRWTmplInline.cpp.h"
    5062 #undef TMPL_MEM_NO_MAPPING
    5063 
    5064 
    5065 /* Every template relying on unaligned accesses inside a page not being okay should go below. */
    5066 #undef TMPL_MEM_CHECK_UNALIGNED_WITHIN_PAGE_OK
    5067 #define TMPL_MEM_CHECK_UNALIGNED_WITHIN_PAGE_OK(a_pVCpu, a_GCPtrEff, a_TmplMemType) 0
    5068 
    5069 #define TMPL_MEM_NO_MAPPING
    5070 #define TMPL_MEM_TYPE       RTUINT128U
    5071 #define TMPL_MEM_TYPE_ALIGN 15
    5072 #define TMPL_MEM_TYPE_SIZE  16
    5073 #define TMPL_MEM_FN_SUFF    U128AlignedSse
    5074 #define TMPL_MEM_FMT_TYPE   "%.16Rhxs"
    5075 #define TMPL_MEM_FMT_DESC   "dqword"
    5076 #include "../VMMAll/IEMAllMemRWTmplInline.cpp.h"
    5077 #undef  TMPL_MEM_NO_MAPPING
    5078 
    5079 #define TMPL_MEM_NO_MAPPING
    5080 #define TMPL_MEM_TYPE       RTUINT256U
    5081 #define TMPL_MEM_TYPE_ALIGN 0
    5082 #define TMPL_MEM_TYPE_SIZE  32
    5083 #define TMPL_MEM_FN_SUFF    U256NoAc
    5084 #define TMPL_MEM_FMT_TYPE   "%.32Rhxs"
    5085 #define TMPL_MEM_FMT_DESC   "qqword"
    5086 #include "../VMMAll/IEMAllMemRWTmplInline.cpp.h"
    5087 #undef TMPL_MEM_NO_MAPPING
    5088 
    5089 #define TMPL_MEM_NO_MAPPING
    5090 #define TMPL_MEM_TYPE       RTUINT256U
    5091 #define TMPL_MEM_TYPE_ALIGN 31
    5092 #define TMPL_MEM_TYPE_SIZE  32
    5093 #define TMPL_MEM_FN_SUFF    U256AlignedAvx
    5094 #define TMPL_MEM_FMT_TYPE   "%.32Rhxs"
    5095 #define TMPL_MEM_FMT_DESC   "qqword"
    5096 #include "../VMMAll/IEMAllMemRWTmplInline.cpp.h"
    5097 #undef TMPL_MEM_NO_MAPPING
    5098 
    5099 #undef TMPL_MEM_CHECK_UNALIGNED_WITHIN_PAGE_OK
    5100 
    5101406/** @} */
    5102407
    5103 
    5104 #ifdef VBOX_WITH_NESTED_HWVIRT_VMX
    5105 
    5106 /**
    5107  * Gets CR0 fixed-0 bits in VMX operation.
    5108  *
    5109  * We do this rather than fetching what we report to the guest (in
    5110  * IA32_VMX_CR0_FIXED0 MSR) because real hardware (and so do we) report the same
    5111  * values regardless of whether unrestricted-guest feature is available on the CPU.
    5112  *
    5113  * @returns CR0 fixed-0 bits.
    5114  * @param   pVCpu               The cross context virtual CPU structure.
    5115  * @param   fVmxNonRootMode     Whether the CR0 fixed-0 bits for VMX non-root mode
    5116  *                              must be returned. When @c false, the CR0 fixed-0
    5117  *                              bits for VMX root mode is returned.
    5118  *
    5119  */
    5120 DECLINLINE(uint64_t) iemVmxGetCr0Fixed0(PCVMCPUCC pVCpu, bool fVmxNonRootMode) RT_NOEXCEPT
    5121 {
    5122     Assert(IEM_VMX_IS_ROOT_MODE(pVCpu));
    5123 
    5124     PCVMXMSRS  pMsrs = &pVCpu->cpum.GstCtx.hwvirt.vmx.Msrs;
    5125     if (    fVmxNonRootMode
    5126         && (pMsrs->ProcCtls2.n.allowed1 & VMX_PROC_CTLS2_UNRESTRICTED_GUEST))
    5127         return VMX_V_CR0_FIXED0_UX;
    5128     return VMX_V_CR0_FIXED0;
    5129 }
    5130 
    5131 
    5132 # ifdef XAPIC_OFF_END /* Requires VBox/apic.h to be included before IEMInline.h. */
    5133 /**
    5134  * Sets virtual-APIC write emulation as pending.
    5135  *
    5136  * @param   pVCpu       The cross context virtual CPU structure.
    5137  * @param   offApic     The offset in the virtual-APIC page that was written.
    5138  */
    5139 DECLINLINE(void) iemVmxVirtApicSetPendingWrite(PVMCPUCC pVCpu, uint16_t offApic) RT_NOEXCEPT
    5140 {
    5141     Assert(offApic < XAPIC_OFF_END + 4);
    5142 
    5143     /*
    5144      * Record the currently updated APIC offset, as we need this later for figuring
    5145      * out whether to perform TPR, EOI or self-IPI virtualization as well as well
    5146      * as for supplying the exit qualification when causing an APIC-write VM-exit.
    5147      */
    5148     pVCpu->cpum.GstCtx.hwvirt.vmx.offVirtApicWrite = offApic;
    5149 
    5150     /*
    5151      * Flag that we need to perform virtual-APIC write emulation (TPR/PPR/EOI/Self-IPI
    5152      * virtualization or APIC-write emulation).
    5153      */
    5154     if (!VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_VMX_APIC_WRITE))
    5155         VMCPU_FF_SET(pVCpu, VMCPU_FF_VMX_APIC_WRITE);
    5156 }
    5157 # endif /* XAPIC_OFF_END */
    5158 
    5159 #endif /* VBOX_WITH_NESTED_HWVIRT_VMX */
    5160408
    5161409#if defined(IEM_WITH_TLB_TRACE) && defined(IN_RING3)
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette