VirtualBox

Changeset 100860 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Aug 11, 2023 1:24:02 PM (16 months ago)
Author:
vboxsync
Message:

VMM/IEM: Reworked basic stack push/pop functions for setjmp, though not yet inlining the TLB lookup (next step). bugref:10369

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

Legend:

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

    r100847 r100860  
    69396939 * Instantiate R/W templates.
    69406940 */
     6941#define TMPL_MEM_WITH_STACK
     6942
    69416943#define TMPL_MEM_TYPE       uint8_t
    69426944#define TMPL_MEM_FN_SUFF    U8
     
    69516953#include "IEMAllMemRWTmpl.cpp.h"
    69526954
     6955#define TMPL_WITH_PUSH_SREG
    69536956#define TMPL_MEM_TYPE       uint32_t
    69546957#define TMPL_MEM_FN_SUFF    U32
     
    69566959#define TMPL_MEM_FMT_DESC   "dword"
    69576960#include "IEMAllMemRWTmpl.cpp.h"
     6961#undef TMPL_WITH_PUSH_SREG
    69586962
    69596963#define TMPL_MEM_TYPE       uint64_t
     
    69626966#define TMPL_MEM_FMT_DESC   "qword"
    69636967#include "IEMAllMemRWTmpl.cpp.h"
     6968
     6969#undef TMPL_MEM_WITH_STACK
    69646970
    69656971#define TMPL_MEM_TYPE       uint64_t
     
    76597665            rcStrict = iemMemStoreDataU64(pVCpu, iSegReg, GCPtrMem + 2, GCPtrBase);
    76607666    }
    7661     return rcStrict;
    7662 }
    7663 
    7664 
    7665 /**
    7666  * Pushes a word onto the stack.
    7667  *
    7668  * @returns Strict VBox status code.
    7669  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    7670  * @param   u16Value            The value to push.
    7671  */
    7672 VBOXSTRICTRC iemMemStackPushU16(PVMCPUCC pVCpu, uint16_t u16Value) RT_NOEXCEPT
    7673 {
    7674     /* Increment the stack pointer. */
    7675     uint64_t    uNewRsp;
    7676     RTGCPTR     GCPtrTop = iemRegGetRspForPush(pVCpu, 2, &uNewRsp);
    7677 
    7678     /* Write the word the lazy way. */
    7679     uint16_t *pu16Dst;
    7680     VBOXSTRICTRC rc = iemMemMap(pVCpu, (void **)&pu16Dst, sizeof(*pu16Dst), X86_SREG_SS, GCPtrTop,
    7681                                 IEM_ACCESS_STACK_W, sizeof(*pu16Dst) - 1);
    7682     if (rc == VINF_SUCCESS)
    7683     {
    7684         *pu16Dst = u16Value;
    7685         rc = iemMemCommitAndUnmap(pVCpu, pu16Dst, IEM_ACCESS_STACK_W);
    7686     }
    7687 
    7688     /* Commit the new RSP value unless we an access handler made trouble. */
    7689     if (rc == VINF_SUCCESS)
    7690         pVCpu->cpum.GstCtx.rsp = uNewRsp;
    7691 
    7692     return rc;
    7693 }
    7694 
    7695 
    7696 /**
    7697  * Pushes a dword onto the stack.
    7698  *
    7699  * @returns Strict VBox status code.
    7700  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    7701  * @param   u32Value            The value to push.
    7702  */
    7703 VBOXSTRICTRC iemMemStackPushU32(PVMCPUCC pVCpu, uint32_t u32Value) RT_NOEXCEPT
    7704 {
    7705     /* Increment the stack pointer. */
    7706     uint64_t    uNewRsp;
    7707     RTGCPTR     GCPtrTop = iemRegGetRspForPush(pVCpu, 4, &uNewRsp);
    7708 
    7709     /* Write the dword the lazy way. */
    7710     uint32_t *pu32Dst;
    7711     VBOXSTRICTRC rc = iemMemMap(pVCpu, (void **)&pu32Dst, sizeof(*pu32Dst), X86_SREG_SS, GCPtrTop,
    7712                                 IEM_ACCESS_STACK_W, sizeof(*pu32Dst) - 1);
    7713     if (rc == VINF_SUCCESS)
    7714     {
    7715         *pu32Dst = u32Value;
    7716         rc = iemMemCommitAndUnmap(pVCpu, pu32Dst, IEM_ACCESS_STACK_W);
    7717     }
    7718 
    7719     /* Commit the new RSP value unless we an access handler made trouble. */
    7720     if (rc == VINF_SUCCESS)
    7721         pVCpu->cpum.GstCtx.rsp = uNewRsp;
    7722 
    7723     return rc;
    7724 }
    7725 
    7726 
    7727 /**
    7728  * Pushes a dword segment register value onto the stack.
    7729  *
    7730  * @returns Strict VBox status code.
    7731  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    7732  * @param   u32Value            The value to push.
    7733  */
    7734 VBOXSTRICTRC iemMemStackPushU32SReg(PVMCPUCC pVCpu, uint32_t u32Value) RT_NOEXCEPT
    7735 {
    7736     /* Increment the stack pointer. */
    7737     uint64_t    uNewRsp;
    7738     RTGCPTR     GCPtrTop = iemRegGetRspForPush(pVCpu, 4, &uNewRsp);
    7739 
    7740     /* The intel docs talks about zero extending the selector register
    7741        value.  My actual intel CPU here might be zero extending the value
    7742        but it still only writes the lower word... */
    7743     /** @todo Test this on new HW and on AMD and in 64-bit mode.  Also test what
    7744      * happens when crossing an electric page boundrary, is the high word checked
    7745      * for write accessibility or not? Probably it is.  What about segment limits?
    7746      * It appears this behavior is also shared with trap error codes.
    7747      *
    7748      * Docs indicate the behavior changed maybe in Pentium or Pentium Pro. Check
    7749      * ancient hardware when it actually did change. */
    7750     uint16_t *pu16Dst;
    7751     VBOXSTRICTRC rc = iemMemMap(pVCpu, (void **)&pu16Dst, sizeof(uint32_t), X86_SREG_SS, GCPtrTop,
    7752                                 IEM_ACCESS_STACK_RW, sizeof(*pu16Dst) - 1); /** @todo 2 or 4 alignment check for PUSH SS? */
    7753     if (rc == VINF_SUCCESS)
    7754     {
    7755         *pu16Dst = (uint16_t)u32Value;
    7756         rc = iemMemCommitAndUnmap(pVCpu, pu16Dst, IEM_ACCESS_STACK_RW);
    7757     }
    7758 
    7759     /* Commit the new RSP value unless we an access handler made trouble. */
    7760     if (rc == VINF_SUCCESS)
    7761         pVCpu->cpum.GstCtx.rsp = uNewRsp;
    7762 
    7763     return rc;
    7764 }
    7765 
    7766 
    7767 /**
    7768  * Pushes a qword onto the stack.
    7769  *
    7770  * @returns Strict VBox status code.
    7771  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    7772  * @param   u64Value            The value to push.
    7773  */
    7774 VBOXSTRICTRC iemMemStackPushU64(PVMCPUCC pVCpu, uint64_t u64Value) RT_NOEXCEPT
    7775 {
    7776     /* Increment the stack pointer. */
    7777     uint64_t    uNewRsp;
    7778     RTGCPTR     GCPtrTop = iemRegGetRspForPush(pVCpu, 8, &uNewRsp);
    7779 
    7780     /* Write the word the lazy way. */
    7781     uint64_t *pu64Dst;
    7782     VBOXSTRICTRC rc = iemMemMap(pVCpu, (void **)&pu64Dst, sizeof(*pu64Dst), X86_SREG_SS, GCPtrTop,
    7783                                 IEM_ACCESS_STACK_W, sizeof(*pu64Dst) - 1);
    7784     if (rc == VINF_SUCCESS)
    7785     {
    7786         *pu64Dst = u64Value;
    7787         rc = iemMemCommitAndUnmap(pVCpu, pu64Dst, IEM_ACCESS_STACK_W);
    7788     }
    7789 
    7790     /* Commit the new RSP value unless we an access handler made trouble. */
    7791     if (rc == VINF_SUCCESS)
    7792         pVCpu->cpum.GstCtx.rsp = uNewRsp;
    7793 
    7794     return rc;
    7795 }
    7796 
    7797 
    7798 /**
    7799  * Pops a word from the stack.
    7800  *
    7801  * @returns Strict VBox status code.
    7802  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    7803  * @param   pu16Value           Where to store the popped value.
    7804  */
    7805 VBOXSTRICTRC iemMemStackPopU16(PVMCPUCC pVCpu, uint16_t *pu16Value) RT_NOEXCEPT
    7806 {
    7807     /* Increment the stack pointer. */
    7808     uint64_t    uNewRsp;
    7809     RTGCPTR     GCPtrTop = iemRegGetRspForPop(pVCpu, 2, &uNewRsp);
    7810 
    7811     /* Write the word the lazy way. */
    7812     uint16_t const *pu16Src;
    7813     VBOXSTRICTRC rc = iemMemMap(pVCpu, (void **)&pu16Src, sizeof(*pu16Src), X86_SREG_SS, GCPtrTop,
    7814                                 IEM_ACCESS_STACK_R, sizeof(*pu16Src) - 1);
    7815     if (rc == VINF_SUCCESS)
    7816     {
    7817         *pu16Value = *pu16Src;
    7818         rc = iemMemCommitAndUnmap(pVCpu, (void *)pu16Src, IEM_ACCESS_STACK_R);
    7819 
    7820         /* Commit the new RSP value. */
    7821         if (rc == VINF_SUCCESS)
    7822             pVCpu->cpum.GstCtx.rsp = uNewRsp;
    7823     }
    7824 
    7825     return rc;
    7826 }
    7827 
    7828 
    7829 /**
    7830  * Pops a dword from the stack.
    7831  *
    7832  * @returns Strict VBox status code.
    7833  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    7834  * @param   pu32Value           Where to store the popped value.
    7835  */
    7836 VBOXSTRICTRC iemMemStackPopU32(PVMCPUCC pVCpu, uint32_t *pu32Value) RT_NOEXCEPT
    7837 {
    7838     /* Increment the stack pointer. */
    7839     uint64_t    uNewRsp;
    7840     RTGCPTR     GCPtrTop = iemRegGetRspForPop(pVCpu, 4, &uNewRsp);
    7841 
    7842     /* Write the word the lazy way. */
    7843     uint32_t const *pu32Src;
    7844     VBOXSTRICTRC rc = iemMemMap(pVCpu, (void **)&pu32Src, sizeof(*pu32Src), X86_SREG_SS, GCPtrTop,
    7845                                 IEM_ACCESS_STACK_R, sizeof(*pu32Src) - 1);
    7846     if (rc == VINF_SUCCESS)
    7847     {
    7848         *pu32Value = *pu32Src;
    7849         rc = iemMemCommitAndUnmap(pVCpu, (void *)pu32Src, IEM_ACCESS_STACK_R);
    7850 
    7851         /* Commit the new RSP value. */
    7852         if (rc == VINF_SUCCESS)
    7853             pVCpu->cpum.GstCtx.rsp = uNewRsp;
    7854     }
    7855 
    7856     return rc;
    7857 }
    7858 
    7859 
    7860 /**
    7861  * Pops a qword from the stack.
    7862  *
    7863  * @returns Strict VBox status code.
    7864  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    7865  * @param   pu64Value           Where to store the popped value.
    7866  */
    7867 VBOXSTRICTRC iemMemStackPopU64(PVMCPUCC pVCpu, uint64_t *pu64Value) RT_NOEXCEPT
    7868 {
    7869     /* Increment the stack pointer. */
    7870     uint64_t    uNewRsp;
    7871     RTGCPTR     GCPtrTop = iemRegGetRspForPop(pVCpu, 8, &uNewRsp);
    7872 
    7873     /* Write the word the lazy way. */
    7874     uint64_t const *pu64Src;
    7875     VBOXSTRICTRC rc = iemMemMap(pVCpu, (void **)&pu64Src, sizeof(*pu64Src), X86_SREG_SS, GCPtrTop,
    7876                                 IEM_ACCESS_STACK_R, sizeof(*pu64Src) - 1);
    7877     if (rc == VINF_SUCCESS)
    7878     {
    7879         *pu64Value = *pu64Src;
    7880         rc = iemMemCommitAndUnmap(pVCpu, (void *)pu64Src, IEM_ACCESS_STACK_R);
    7881 
    7882         /* Commit the new RSP value. */
    7883         if (rc == VINF_SUCCESS)
    7884             pVCpu->cpum.GstCtx.rsp = uNewRsp;
    7885     }
    7886 
    7887     return rc;
    7888 }
    7889 
    7890 
    7891 /**
    7892  * Pushes a word onto the stack, using a temporary stack pointer.
    7893  *
    7894  * @returns Strict VBox status code.
    7895  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    7896  * @param   u16Value            The value to push.
    7897  * @param   pTmpRsp             Pointer to the temporary stack pointer.
    7898  */
    7899 VBOXSTRICTRC iemMemStackPushU16Ex(PVMCPUCC pVCpu, uint16_t u16Value, PRTUINT64U pTmpRsp) RT_NOEXCEPT
    7900 {
    7901     /* Increment the stack pointer. */
    7902     RTUINT64U   NewRsp = *pTmpRsp;
    7903     RTGCPTR     GCPtrTop = iemRegGetRspForPushEx(pVCpu, &NewRsp, 2);
    7904 
    7905     /* Write the word the lazy way. */
    7906     uint16_t *pu16Dst;
    7907     VBOXSTRICTRC rc = iemMemMap(pVCpu, (void **)&pu16Dst, sizeof(*pu16Dst), X86_SREG_SS, GCPtrTop,
    7908                                 IEM_ACCESS_STACK_W, sizeof(*pu16Dst) - 1);
    7909     if (rc == VINF_SUCCESS)
    7910     {
    7911         *pu16Dst = u16Value;
    7912         rc = iemMemCommitAndUnmap(pVCpu, pu16Dst, IEM_ACCESS_STACK_W);
    7913     }
    7914 
    7915     /* Commit the new RSP value unless we an access handler made trouble. */
    7916     if (rc == VINF_SUCCESS)
    7917         *pTmpRsp = NewRsp;
    7918 
    7919     return rc;
    7920 }
    7921 
    7922 
    7923 /**
    7924  * Pushes a dword onto the stack, using a temporary stack pointer.
    7925  *
    7926  * @returns Strict VBox status code.
    7927  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    7928  * @param   u32Value            The value to push.
    7929  * @param   pTmpRsp             Pointer to the temporary stack pointer.
    7930  */
    7931 VBOXSTRICTRC iemMemStackPushU32Ex(PVMCPUCC pVCpu, uint32_t u32Value, PRTUINT64U pTmpRsp) RT_NOEXCEPT
    7932 {
    7933     /* Increment the stack pointer. */
    7934     RTUINT64U   NewRsp = *pTmpRsp;
    7935     RTGCPTR     GCPtrTop = iemRegGetRspForPushEx(pVCpu, &NewRsp, 4);
    7936 
    7937     /* Write the word the lazy way. */
    7938     uint32_t *pu32Dst;
    7939     VBOXSTRICTRC rc = iemMemMap(pVCpu, (void **)&pu32Dst, sizeof(*pu32Dst), X86_SREG_SS, GCPtrTop,
    7940                                 IEM_ACCESS_STACK_W, sizeof(*pu32Dst) - 1);
    7941     if (rc == VINF_SUCCESS)
    7942     {
    7943         *pu32Dst = u32Value;
    7944         rc = iemMemCommitAndUnmap(pVCpu, pu32Dst, IEM_ACCESS_STACK_W);
    7945     }
    7946 
    7947     /* Commit the new RSP value unless we an access handler made trouble. */
    7948     if (rc == VINF_SUCCESS)
    7949         *pTmpRsp = NewRsp;
    7950 
    7951     return rc;
    7952 }
    7953 
    7954 
    7955 /**
    7956  * Pushes a dword onto the stack, using a temporary stack pointer.
    7957  *
    7958  * @returns Strict VBox status code.
    7959  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    7960  * @param   u64Value            The value to push.
    7961  * @param   pTmpRsp             Pointer to the temporary stack pointer.
    7962  */
    7963 VBOXSTRICTRC iemMemStackPushU64Ex(PVMCPUCC pVCpu, uint64_t u64Value, PRTUINT64U pTmpRsp) RT_NOEXCEPT
    7964 {
    7965     /* Increment the stack pointer. */
    7966     RTUINT64U   NewRsp = *pTmpRsp;
    7967     RTGCPTR     GCPtrTop = iemRegGetRspForPushEx(pVCpu, &NewRsp, 8);
    7968 
    7969     /* Write the word the lazy way. */
    7970     uint64_t *pu64Dst;
    7971     VBOXSTRICTRC rc = iemMemMap(pVCpu, (void **)&pu64Dst, sizeof(*pu64Dst), X86_SREG_SS, GCPtrTop,
    7972                                 IEM_ACCESS_STACK_W, sizeof(*pu64Dst) - 1);
    7973     if (rc == VINF_SUCCESS)
    7974     {
    7975         *pu64Dst = u64Value;
    7976         rc = iemMemCommitAndUnmap(pVCpu, pu64Dst, IEM_ACCESS_STACK_W);
    7977     }
    7978 
    7979     /* Commit the new RSP value unless we an access handler made trouble. */
    7980     if (rc == VINF_SUCCESS)
    7981         *pTmpRsp = NewRsp;
    7982 
    7983     return rc;
    7984 }
    7985 
    7986 
    7987 /**
    7988  * Pops a word from the stack, using a temporary stack pointer.
    7989  *
    7990  * @returns Strict VBox status code.
    7991  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    7992  * @param   pu16Value           Where to store the popped value.
    7993  * @param   pTmpRsp             Pointer to the temporary stack pointer.
    7994  */
    7995 VBOXSTRICTRC iemMemStackPopU16Ex(PVMCPUCC pVCpu, uint16_t *pu16Value, PRTUINT64U pTmpRsp) RT_NOEXCEPT
    7996 {
    7997     /* Increment the stack pointer. */
    7998     RTUINT64U   NewRsp = *pTmpRsp;
    7999     RTGCPTR     GCPtrTop = iemRegGetRspForPopEx(pVCpu, &NewRsp, 2);
    8000 
    8001     /* Write the word the lazy way. */
    8002     uint16_t const *pu16Src;
    8003     VBOXSTRICTRC rc = iemMemMap(pVCpu, (void **)&pu16Src, sizeof(*pu16Src), X86_SREG_SS, GCPtrTop,
    8004                                 IEM_ACCESS_STACK_R, sizeof(*pu16Src) - 1);
    8005     if (rc == VINF_SUCCESS)
    8006     {
    8007         *pu16Value = *pu16Src;
    8008         rc = iemMemCommitAndUnmap(pVCpu, (void *)pu16Src, IEM_ACCESS_STACK_R);
    8009 
    8010         /* Commit the new RSP value. */
    8011         if (rc == VINF_SUCCESS)
    8012             *pTmpRsp = NewRsp;
    8013     }
    8014 
    8015     return rc;
    8016 }
    8017 
    8018 
    8019 /**
    8020  * Pops a dword from the stack, using a temporary stack pointer.
    8021  *
    8022  * @returns Strict VBox status code.
    8023  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    8024  * @param   pu32Value           Where to store the popped value.
    8025  * @param   pTmpRsp             Pointer to the temporary stack pointer.
    8026  */
    8027 VBOXSTRICTRC iemMemStackPopU32Ex(PVMCPUCC pVCpu, uint32_t *pu32Value, PRTUINT64U pTmpRsp) RT_NOEXCEPT
    8028 {
    8029     /* Increment the stack pointer. */
    8030     RTUINT64U   NewRsp = *pTmpRsp;
    8031     RTGCPTR     GCPtrTop = iemRegGetRspForPopEx(pVCpu, &NewRsp, 4);
    8032 
    8033     /* Write the word the lazy way. */
    8034     uint32_t const *pu32Src;
    8035     VBOXSTRICTRC rc = iemMemMap(pVCpu, (void **)&pu32Src, sizeof(*pu32Src), X86_SREG_SS, GCPtrTop,
    8036                                 IEM_ACCESS_STACK_R, sizeof(*pu32Src) - 1);
    8037     if (rc == VINF_SUCCESS)
    8038     {
    8039         *pu32Value = *pu32Src;
    8040         rc = iemMemCommitAndUnmap(pVCpu, (void *)pu32Src, IEM_ACCESS_STACK_R);
    8041 
    8042         /* Commit the new RSP value. */
    8043         if (rc == VINF_SUCCESS)
    8044             *pTmpRsp = NewRsp;
    8045     }
    8046 
    8047     return rc;
    8048 }
    8049 
    8050 
    8051 /**
    8052  * Pops a qword from the stack, using a temporary stack pointer.
    8053  *
    8054  * @returns Strict VBox status code.
    8055  * @param   pVCpu               The cross context virtual CPU structure of the calling thread.
    8056  * @param   pu64Value           Where to store the popped value.
    8057  * @param   pTmpRsp             Pointer to the temporary stack pointer.
    8058  */
    8059 VBOXSTRICTRC iemMemStackPopU64Ex(PVMCPUCC pVCpu, uint64_t *pu64Value, PRTUINT64U pTmpRsp) RT_NOEXCEPT
    8060 {
    8061     /* Increment the stack pointer. */
    8062     RTUINT64U   NewRsp = *pTmpRsp;
    8063     RTGCPTR     GCPtrTop = iemRegGetRspForPopEx(pVCpu, &NewRsp, 8);
    8064 
    8065     /* Write the word the lazy way. */
    8066     uint64_t const *pu64Src;
    8067     VBOXSTRICTRC rcStrict = iemMemMap(pVCpu, (void **)&pu64Src, sizeof(*pu64Src), X86_SREG_SS, GCPtrTop,
    8068                                       IEM_ACCESS_STACK_R, sizeof(*pu64Src) - 1);
    8069     if (rcStrict == VINF_SUCCESS)
    8070     {
    8071         *pu64Value = *pu64Src;
    8072         rcStrict = iemMemCommitAndUnmap(pVCpu, (void *)pu64Src, IEM_ACCESS_STACK_R);
    8073 
    8074         /* Commit the new RSP value. */
    8075         if (rcStrict == VINF_SUCCESS)
    8076             *pTmpRsp = NewRsp;
    8077     }
    8078 
    80797667    return rcStrict;
    80807668}
  • trunk/src/VBox/VMM/VMMAll/IEMAllMemRWTmpl.cpp.h

    r100848 r100860  
    209209
    210210
     211#ifdef TMPL_MEM_WITH_STACK
     212
     213/**
     214 * Pushes an item onto the stack, regular version.
     215 *
     216 * @returns Strict VBox status code.
     217 * @param   pVCpu               The cross context virtual CPU structure of the
     218 *                              calling thread.
     219 * @param   uValue              The value to push.
     220 */
     221VBOXSTRICTRC RT_CONCAT(iemMemStackPush,TMPL_MEM_FN_SUFF)(PVMCPUCC pVCpu, TMPL_MEM_TYPE uValue) RT_NOEXCEPT
     222{
     223    /* Increment the stack pointer. */
     224    uint64_t    uNewRsp;
     225    RTGCPTR     GCPtrTop = iemRegGetRspForPush(pVCpu, sizeof(TMPL_MEM_TYPE), &uNewRsp);
     226
     227    /* Write the dword the lazy way. */
     228    TMPL_MEM_TYPE *puDst;
     229    VBOXSTRICTRC rc = iemMemMap(pVCpu, (void **)&puDst, sizeof(TMPL_MEM_TYPE), X86_SREG_SS, GCPtrTop,
     230                                IEM_ACCESS_STACK_W, TMPL_MEM_TYPE_ALIGN);
     231    if (rc == VINF_SUCCESS)
     232    {
     233        *puDst = uValue;
     234        rc = iemMemCommitAndUnmap(pVCpu, puDst, IEM_ACCESS_STACK_W);
     235
     236        /* Commit the new RSP value unless we an access handler made trouble. */
     237        if (rc == VINF_SUCCESS)
     238        {
     239            Log8(("IEM WR " TMPL_MEM_FMT_DESC " SS|%RGv (%RX64->%RX64): " TMPL_MEM_FMT_TYPE "\n",
     240                  GCPtrTop, pVCpu->cpum.GstCtx.rsp, uNewRsp, uValue));
     241            pVCpu->cpum.GstCtx.rsp = uNewRsp;
     242            return VINF_SUCCESS;
     243        }
     244    }
     245
     246    return rc;
     247}
     248
     249
     250/**
     251 * Pops an item off the stack.
     252 *
     253 * @returns Strict VBox status code.
     254 * @param   pVCpu               The cross context virtual CPU structure of the
     255 *                              calling thread.
     256 * @param   puValue             Where to store the popped value.
     257 */
     258VBOXSTRICTRC RT_CONCAT(iemMemStackPop,TMPL_MEM_FN_SUFF)(PVMCPUCC pVCpu, TMPL_MEM_TYPE *puValue) RT_NOEXCEPT
     259{
     260    /* Increment the stack pointer. */
     261    uint64_t    uNewRsp;
     262    RTGCPTR     GCPtrTop = iemRegGetRspForPop(pVCpu, sizeof(TMPL_MEM_TYPE), &uNewRsp);
     263
     264    /* Write the word the lazy way. */
     265    TMPL_MEM_TYPE const *puSrc;
     266    VBOXSTRICTRC rc = iemMemMap(pVCpu, (void **)&puSrc, sizeof(TMPL_MEM_TYPE), X86_SREG_SS, GCPtrTop,
     267                                IEM_ACCESS_STACK_R, TMPL_MEM_TYPE_ALIGN);
     268    if (rc == VINF_SUCCESS)
     269    {
     270        *puValue = *puSrc;
     271        rc = iemMemCommitAndUnmap(pVCpu, (void *)puSrc, IEM_ACCESS_STACK_R);
     272
     273        /* Commit the new RSP value. */
     274        if (rc == VINF_SUCCESS)
     275        {
     276            Log9(("IEM RD " TMPL_MEM_FMT_DESC " SS|%RGv (%RX64->%RX64): " TMPL_MEM_FMT_TYPE "\n",
     277                  GCPtrTop, pVCpu->cpum.GstCtx.rsp, uNewRsp, *puValue));
     278            pVCpu->cpum.GstCtx.rsp = uNewRsp;
     279            return VINF_SUCCESS;
     280        }
     281    }
     282    return rc;
     283}
     284
     285
     286/**
     287 * Pushes an item onto the stack, using a temporary stack pointer.
     288 *
     289 * @returns Strict VBox status code.
     290 * @param   pVCpu               The cross context virtual CPU structure of the
     291 *                              calling thread.
     292 * @param   uValue              The value to push.
     293 * @param   pTmpRsp             Pointer to the temporary stack pointer.
     294 */
     295VBOXSTRICTRC RT_CONCAT3(iemMemStackPush,TMPL_MEM_FN_SUFF,Ex)(PVMCPUCC pVCpu, TMPL_MEM_TYPE uValue, PRTUINT64U pTmpRsp) RT_NOEXCEPT
     296{
     297    /* Increment the stack pointer. */
     298    RTUINT64U   NewRsp = *pTmpRsp;
     299    RTGCPTR     GCPtrTop = iemRegGetRspForPushEx(pVCpu, &NewRsp, sizeof(TMPL_MEM_TYPE));
     300
     301    /* Write the word the lazy way. */
     302    TMPL_MEM_TYPE *puDst;
     303    VBOXSTRICTRC rc = iemMemMap(pVCpu, (void **)&puDst, sizeof(TMPL_MEM_TYPE), X86_SREG_SS, GCPtrTop,
     304                                IEM_ACCESS_STACK_W, TMPL_MEM_TYPE_ALIGN);
     305    if (rc == VINF_SUCCESS)
     306    {
     307        *puDst = uValue;
     308        rc = iemMemCommitAndUnmap(pVCpu, puDst, IEM_ACCESS_STACK_W);
     309
     310        /* Commit the new RSP value unless we an access handler made trouble. */
     311        if (rc == VINF_SUCCESS)
     312        {
     313            Log8(("IEM WR " TMPL_MEM_FMT_DESC " SS|%RGv (%RX64->%RX64): " TMPL_MEM_FMT_TYPE " [ex]\n",
     314                  GCPtrTop, pTmpRsp->u, NewRsp.u, uValue));
     315            *pTmpRsp = NewRsp;
     316            return VINF_SUCCESS;
     317        }
     318    }
     319    return rc;
     320}
     321
     322
     323/**
     324 * Pops an item off the stack, using a temporary stack pointer.
     325 *
     326 * @returns Strict VBox status code.
     327 * @param   pVCpu               The cross context virtual CPU structure of the
     328 *                              calling thread.
     329 * @param   puValue             Where to store the popped value.
     330 * @param   pTmpRsp             Pointer to the temporary stack pointer.
     331 */
     332VBOXSTRICTRC
     333RT_CONCAT3(iemMemStackPop,TMPL_MEM_FN_SUFF,Ex)(PVMCPUCC pVCpu, TMPL_MEM_TYPE *puValue, PRTUINT64U pTmpRsp) RT_NOEXCEPT
     334{
     335    /* Increment the stack pointer. */
     336    RTUINT64U   NewRsp = *pTmpRsp;
     337    RTGCPTR     GCPtrTop = iemRegGetRspForPopEx(pVCpu, &NewRsp, sizeof(TMPL_MEM_TYPE));
     338
     339    /* Write the word the lazy way. */
     340    TMPL_MEM_TYPE const *puSrc;
     341    VBOXSTRICTRC rc = iemMemMap(pVCpu, (void **)&puSrc, sizeof(TMPL_MEM_TYPE), X86_SREG_SS, GCPtrTop,
     342                                IEM_ACCESS_STACK_R, TMPL_MEM_TYPE_ALIGN);
     343    if (rc == VINF_SUCCESS)
     344    {
     345        *puValue = *puSrc;
     346        rc = iemMemCommitAndUnmap(pVCpu, (void *)puSrc, IEM_ACCESS_STACK_R);
     347
     348        /* Commit the new RSP value. */
     349        if (rc == VINF_SUCCESS)
     350        {
     351            Log9(("IEM RD " TMPL_MEM_FMT_DESC " SS|%RGv (%RX64->%RX64): " TMPL_MEM_FMT_TYPE " [ex]\n",
     352                  GCPtrTop, pTmpRsp->u, NewRsp.u, *puValue));
     353            *pTmpRsp = NewRsp;
     354            return VINF_SUCCESS;
     355        }
     356    }
     357    return rc;
     358}
     359
     360
     361# ifdef IEM_WITH_SETJMP
     362
     363/**
     364 * Safe/fallback stack push function that longjmps on error.
     365 */
     366void RT_CONCAT3(iemMemStackPush,TMPL_MEM_FN_SUFF,SafeJmp)(PVMCPUCC pVCpu, TMPL_MEM_TYPE uValue) IEM_NOEXCEPT_MAY_LONGJMP
     367{
     368# if defined(IEM_WITH_DATA_TLB) && defined(IN_RING3)
     369    pVCpu->iem.s.DataTlb.cTlbSafeWritePath++;
     370# endif
     371
     372    /* Decrement the stack pointer (prep). */
     373    uint64_t      uNewRsp;
     374    RTGCPTR const GCPtrTop = iemRegGetRspForPush(pVCpu, sizeof(TMPL_MEM_TYPE), &uNewRsp);
     375
     376    /* Write the data. */
     377    TMPL_MEM_TYPE *puDst = (TMPL_MEM_TYPE *)iemMemMapJmp(pVCpu, sizeof(TMPL_MEM_TYPE), X86_SREG_SS, GCPtrTop,
     378                                                         IEM_ACCESS_STACK_W, TMPL_MEM_TYPE_ALIGN);
     379    *puDst = uValue;
     380    iemMemCommitAndUnmapJmp(pVCpu, puDst, IEM_ACCESS_STACK_W);
     381
     382    /* Commit the RSP change. */
     383    Log8(("IEM WR " TMPL_MEM_FMT_DESC " SS|%RGv (%RX64->%RX64): " TMPL_MEM_FMT_TYPE "\n",
     384          GCPtrTop, pVCpu->cpum.GstCtx.rsp, uNewRsp, uValue));
     385    pVCpu->cpum.GstCtx.rsp = uNewRsp;
     386}
     387
     388
     389/**
     390 * Safe/fallback stack pop function that longjmps on error.
     391 */
     392TMPL_MEM_TYPE RT_CONCAT3(iemMemStackPop,TMPL_MEM_FN_SUFF,SafeJmp)(PVMCPUCC pVCpu) IEM_NOEXCEPT_MAY_LONGJMP
     393{
     394# if defined(IEM_WITH_DATA_TLB) && defined(IN_RING3)
     395    pVCpu->iem.s.DataTlb.cTlbSafeReadPath++;
     396# endif
     397
     398    /* Increment the stack pointer. */
     399    uint64_t      uNewRsp;
     400    RTGCPTR const GCPtrTop = iemRegGetRspForPop(pVCpu, sizeof(TMPL_MEM_TYPE), &uNewRsp);
     401
     402    /* Read the data. */
     403    TMPL_MEM_TYPE const *puSrc = (TMPL_MEM_TYPE const *)iemMemMapJmp(pVCpu, sizeof(TMPL_MEM_TYPE), X86_SREG_SS, GCPtrTop,
     404                                                                     IEM_ACCESS_STACK_R, TMPL_MEM_TYPE_ALIGN);
     405    TMPL_MEM_TYPE const  uRet = *puSrc;
     406    iemMemCommitAndUnmapJmp(pVCpu, (void *)puSrc, IEM_ACCESS_STACK_R);
     407
     408    /* Commit the RSP change and return the popped value. */
     409    Log9(("IEM RD " TMPL_MEM_FMT_DESC " SS|%RGv (%RX64->%RX64): " TMPL_MEM_FMT_TYPE "\n",
     410          GCPtrTop, pVCpu->cpum.GstCtx.rsp, uNewRsp, uRet));
     411    pVCpu->cpum.GstCtx.rsp = uNewRsp;
     412
     413    return uRet;
     414}
     415
     416#  ifdef TMPL_WITH_PUSH_SREG
     417/**
     418 * Safe/fallback stack push function that longjmps on error.
     419 */
     420void RT_CONCAT3(iemMemStackPush,TMPL_MEM_FN_SUFF,SRegSafeJmp)(PVMCPUCC pVCpu, TMPL_MEM_TYPE uValue) IEM_NOEXCEPT_MAY_LONGJMP
     421{
     422# if defined(IEM_WITH_DATA_TLB) && defined(IN_RING3)
     423    pVCpu->iem.s.DataTlb.cTlbSafeWritePath++;
     424# endif
     425
     426    /* Decrement the stack pointer (prep). */
     427    uint64_t      uNewRsp;
     428    RTGCPTR const GCPtrTop = iemRegGetRspForPush(pVCpu, sizeof(TMPL_MEM_TYPE), &uNewRsp);
     429
     430    /* Write the data. */
     431    /* The intel docs talks about zero extending the selector register
     432       value.  My actual intel CPU here might be zero extending the value
     433       but it still only writes the lower word... */
     434    /** @todo Test this on new HW and on AMD and in 64-bit mode.  Also test what
     435     * happens when crossing an electric page boundrary, is the high word checked
     436     * for write accessibility or not? Probably it is.  What about segment limits?
     437     * It appears this behavior is also shared with trap error codes.
     438     *
     439     * Docs indicate the behavior changed maybe in Pentium or Pentium Pro. Check
     440     * ancient hardware when it actually did change. */
     441    uint16_t *puDst = (uint16_t *)iemMemMapJmp(pVCpu, sizeof(uint16_t), X86_SREG_SS, GCPtrTop,
     442                                               IEM_ACCESS_STACK_W, sizeof(uint16_t) - 1); /** @todo 2 or 4 alignment check for PUSH SS? */
     443    *puDst = (uint16_t)uValue;
     444    iemMemCommitAndUnmapJmp(pVCpu, puDst, IEM_ACCESS_STACK_W);
     445
     446    /* Commit the RSP change. */
     447    Log8(("IEM WR " TMPL_MEM_FMT_DESC " SS|%RGv (%RX64->%RX64): " TMPL_MEM_FMT_TYPE " [sreg]\n",
     448          GCPtrTop, pVCpu->cpum.GstCtx.rsp, uNewRsp, uValue));
     449    pVCpu->cpum.GstCtx.rsp = uNewRsp;
     450}
     451#  endif /* TMPL_WITH_PUSH_SREG */
     452
     453# endif /* IEM_WITH_SETJMP */
     454
     455#endif /* TMPL_MEM_WITH_STACK */
     456
    211457/* clean up */
    212458#undef TMPL_MEM_TYPE
     
    215461#undef TMPL_MEM_FMT_TYPE
    216462#undef TMPL_MEM_FMT_DESC
    217 
     463#undef TMPL_WITH_PUSH_SREG
     464
  • trunk/src/VBox/VMM/VMMAll/IEMAllMemRWTmplInline.cpp.h

    r100850 r100860  
    634634
    635635
     636# ifdef TMPL_MEM_WITH_STACK
     637#  ifdef IEM_WITH_SETJMP
     638
     639/**
     640 * Stack push function that longjmps on error.
     641 */
     642DECL_INLINE_THROW(void)
     643RT_CONCAT3(iemMemStackPush,TMPL_MEM_FN_SUFF,Jmp)(PVMCPUCC pVCpu, TMPL_MEM_TYPE uValue) IEM_NOEXCEPT_MAY_LONGJMP
     644{
     645    RT_CONCAT3(iemMemStackPush,TMPL_MEM_FN_SUFF,SafeJmp)(pVCpu, uValue);
     646}
     647
     648
     649/**
     650 * Stack pop function that longjmps on error.
     651 */
     652DECL_INLINE_THROW(TMPL_MEM_TYPE)
     653RT_CONCAT3(iemMemStackPop,TMPL_MEM_FN_SUFF,Jmp)(PVMCPUCC pVCpu) IEM_NOEXCEPT_MAY_LONGJMP
     654{
     655    return RT_CONCAT3(iemMemStackPop,TMPL_MEM_FN_SUFF,SafeJmp)(pVCpu);
     656}
     657
     658#   ifdef TMPL_WITH_PUSH_SREG
     659/**
     660 * Stack segment push function that longjmps on error.
     661 */
     662DECL_INLINE_THROW(void)
     663RT_CONCAT3(iemMemStackPush,TMPL_MEM_FN_SUFF,SRegJmp)(PVMCPUCC pVCpu, TMPL_MEM_TYPE uValue) IEM_NOEXCEPT_MAY_LONGJMP
     664{
     665    RT_CONCAT3(iemMemStackPush,TMPL_MEM_FN_SUFF,SRegSafeJmp)(pVCpu, uValue);
     666}
     667
     668#   endif
     669#   if TMPL_MEM_TYPE_SIZE != 8
     670
     671/**
     672 * 32-bit flat stack push function that longjmps on error.
     673 */
     674DECL_INLINE_THROW(void)
     675RT_CONCAT3(iemMemFlat32StackPush,TMPL_MEM_FN_SUFF,Jmp)(PVMCPUCC pVCpu, TMPL_MEM_TYPE uValue) IEM_NOEXCEPT_MAY_LONGJMP
     676{
     677    RT_CONCAT3(iemMemStackPush,TMPL_MEM_FN_SUFF,SafeJmp)(pVCpu, uValue);
     678}
     679
     680
     681/**
     682 * 32-bit flat stack pop function that longjmps on error.
     683 */
     684DECL_INLINE_THROW(TMPL_MEM_TYPE)
     685RT_CONCAT3(iemMemFlat32StackPop,TMPL_MEM_FN_SUFF,Jmp)(PVMCPUCC pVCpu) IEM_NOEXCEPT_MAY_LONGJMP
     686{
     687    return RT_CONCAT3(iemMemStackPop,TMPL_MEM_FN_SUFF,SafeJmp)(pVCpu);
     688}
     689
     690#   endif /* TMPL_MEM_TYPE_SIZE != 8*/
     691#   ifdef TMPL_WITH_PUSH_SREG
     692/**
     693 * 32-bit flat stack segment push function that longjmps on error.
     694 */
     695DECL_INLINE_THROW(void)
     696RT_CONCAT3(iemMemFlat32StackPush,TMPL_MEM_FN_SUFF,SRegJmp)(PVMCPUCC pVCpu, TMPL_MEM_TYPE uValue) IEM_NOEXCEPT_MAY_LONGJMP
     697{
     698    RT_CONCAT3(iemMemStackPush,TMPL_MEM_FN_SUFF,SRegSafeJmp)(pVCpu, uValue);
     699}
     700
     701#   endif
     702#   if TMPL_MEM_TYPE_SIZE != 4
     703
     704/**
     705 * 64-bit flat stack push function that longjmps on error.
     706 */
     707DECL_INLINE_THROW(void)
     708RT_CONCAT3(iemMemFlat64StackPush,TMPL_MEM_FN_SUFF,Jmp)(PVMCPUCC pVCpu, TMPL_MEM_TYPE uValue) IEM_NOEXCEPT_MAY_LONGJMP
     709{
     710    RT_CONCAT3(iemMemStackPush,TMPL_MEM_FN_SUFF,SafeJmp)(pVCpu, uValue);
     711}
     712
     713
     714/**
     715 * 64-bit flat stack pop function that longjmps on error.
     716 */
     717DECL_INLINE_THROW(TMPL_MEM_TYPE)
     718RT_CONCAT3(iemMemFlat64StackPop,TMPL_MEM_FN_SUFF,Jmp)(PVMCPUCC pVCpu) IEM_NOEXCEPT_MAY_LONGJMP
     719{
     720    return RT_CONCAT3(iemMemStackPop,TMPL_MEM_FN_SUFF,SafeJmp)(pVCpu);
     721}
     722
     723#endif /* TMPL_MEM_TYPE_SIZE != 4 */
     724
     725#  endif /* IEM_WITH_SETJMP */
     726# endif /* TMPL_MEM_WITH_STACK */
     727
     728
    636729#endif /* IEM_WITH_SETJMP */
    637730
  • trunk/src/VBox/VMM/include/IEMInline.h

    r100850 r100860  
    34753475#endif
    34763476
    3477 
    34783477#define TMPL_MEM_TYPE       uint8_t
    34793478#define TMPL_MEM_TYPE_ALIGN 0
     
    34843483#include "../VMMAll/IEMAllMemRWTmplInline.cpp.h"
    34853484
     3485#define TMPL_MEM_WITH_STACK
     3486
    34863487#define TMPL_MEM_TYPE       uint16_t
    34873488#define TMPL_MEM_TYPE_ALIGN 1
     
    34923493#include "../VMMAll/IEMAllMemRWTmplInline.cpp.h"
    34933494
     3495#define TMPL_WITH_PUSH_SREG
    34943496#define TMPL_MEM_TYPE       uint32_t
    34953497#define TMPL_MEM_TYPE_ALIGN 3
     
    34993501#define TMPL_MEM_FMT_DESC   "dword"
    35003502#include "../VMMAll/IEMAllMemRWTmplInline.cpp.h"
     3503#undef  TMPL_WITH_PUSH_SREG
    35013504
    35023505#define TMPL_MEM_TYPE       uint64_t
     
    35073510#define TMPL_MEM_FMT_DESC   "qword"
    35083511#include "../VMMAll/IEMAllMemRWTmplInline.cpp.h"
     3512
     3513#undef TMPL_MEM_WITH_STACK
    35093514
    35103515#define TMPL_MEM_NO_STORE
     
    35193524
    35203525#undef TMPL_MEM_CHECK_UNALIGNED_WITHIN_PAGE_OK
     3526
    35213527/** @} */
    35223528
  • trunk/src/VBox/VMM/include/IEMInternal.h

    r100856 r100860  
    47184718VBOXSTRICTRC    iemMemStackPopU32Ex(PVMCPUCC pVCpu, uint32_t *pu32Value, PRTUINT64U pTmpRsp) RT_NOEXCEPT;
    47194719VBOXSTRICTRC    iemMemStackPopU64Ex(PVMCPUCC pVCpu, uint64_t *pu64Value, PRTUINT64U pTmpRsp) RT_NOEXCEPT;
     4720
     4721#ifdef IEM_WITH_SETJMP
     4722void            iemMemStackPushU16SafeJmp(PVMCPUCC pVCpu, uint16_t uValue) IEM_NOEXCEPT_MAY_LONGJMP;
     4723void            iemMemStackPushU32SafeJmp(PVMCPUCC pVCpu, uint32_t uValue) IEM_NOEXCEPT_MAY_LONGJMP;
     4724void            iemMemStackPushU32SRegSafeJmp(PVMCPUCC pVCpu, uint32_t uValue) IEM_NOEXCEPT_MAY_LONGJMP;
     4725void            iemMemStackPushU64SafeJmp(PVMCPUCC pVCpu, uint64_t uValue) IEM_NOEXCEPT_MAY_LONGJMP;
     4726uint16_t        iemMemStackPopU16SafeJmp(PVMCPUCC pVCpu) IEM_NOEXCEPT_MAY_LONGJMP;
     4727uint32_t        iemMemStackPopU32SafeJmp(PVMCPUCC pVCpu) IEM_NOEXCEPT_MAY_LONGJMP;
     4728uint64_t        iemMemStackPopU64SafeJmp(PVMCPUCC pVCpu) IEM_NOEXCEPT_MAY_LONGJMP;
     4729
     4730void            iemMemFlat32StackPushU16SafeJmp(PVMCPUCC pVCpu, uint16_t uValue) IEM_NOEXCEPT_MAY_LONGJMP;
     4731void            iemMemFlat32StackPushU32SafeJmp(PVMCPUCC pVCpu, uint32_t uValue) IEM_NOEXCEPT_MAY_LONGJMP;
     4732void            iemMemFlat32StackPushU32SRegSafeJmp(PVMCPUCC pVCpu, uint32_t uValue) IEM_NOEXCEPT_MAY_LONGJMP;
     4733uint16_t        iemMemFlat32StackPopU16SafeJmp(PVMCPUCC pVCpu) IEM_NOEXCEPT_MAY_LONGJMP;
     4734uint32_t        iemMemFlat32StackPopU32SafeJmp(PVMCPUCC pVCpu) IEM_NOEXCEPT_MAY_LONGJMP;
     4735
     4736void            iemMemFlat64StackPushU16SafeJmp(PVMCPUCC pVCpu, uint16_t uValue) IEM_NOEXCEPT_MAY_LONGJMP;
     4737void            iemMemFlat64StackPushU64SafeJmp(PVMCPUCC pVCpu, uint64_t uValue) IEM_NOEXCEPT_MAY_LONGJMP;
     4738uint16_t        iemMemFlat64StackPopU16SafeJmp(PVMCPUCC pVCpu) IEM_NOEXCEPT_MAY_LONGJMP;
     4739uint64_t        iemMemFlat64StackPopU64SafeJmp(PVMCPUCC pVCpu) IEM_NOEXCEPT_MAY_LONGJMP;
     4740#endif
     4741
    47204742/** @} */
    47214743
  • trunk/src/VBox/VMM/include/IEMMc.h

    r100859 r100860  
    12851285
    12861286/* Regular stack push and pop: */
    1287 #define IEM_MC_PUSH_U16(a_u16Value)             IEM_MC_RETURN_ON_FAILURE(iemMemStackPushU16(pVCpu, (a_u16Value)))
    1288 #define IEM_MC_PUSH_U32(a_u32Value)             IEM_MC_RETURN_ON_FAILURE(iemMemStackPushU32(pVCpu, (a_u32Value)))
    1289 #define IEM_MC_PUSH_U32_SREG(a_u32Value)        IEM_MC_RETURN_ON_FAILURE(iemMemStackPushU32SReg(pVCpu, (a_u32Value)))
    1290 #define IEM_MC_PUSH_U64(a_u64Value)             IEM_MC_RETURN_ON_FAILURE(iemMemStackPushU64(pVCpu, (a_u64Value)))
    1291 
    1292 #define IEM_MC_POP_U16(a_pu16Value)             IEM_MC_RETURN_ON_FAILURE(iemMemStackPopU16(pVCpu, (a_pu16Value)))
    1293 #define IEM_MC_POP_U32(a_pu32Value)             IEM_MC_RETURN_ON_FAILURE(iemMemStackPopU32(pVCpu, (a_pu32Value)))
    1294 #define IEM_MC_POP_U64(a_pu64Value)             IEM_MC_RETURN_ON_FAILURE(iemMemStackPopU64(pVCpu, (a_pu64Value)))
     1287#ifndef IEM_WITH_SETJMP
     1288# define IEM_MC_PUSH_U16(a_u16Value)            IEM_MC_RETURN_ON_FAILURE(iemMemStackPushU16(pVCpu, (a_u16Value)))
     1289# define IEM_MC_PUSH_U32(a_u32Value)            IEM_MC_RETURN_ON_FAILURE(iemMemStackPushU32(pVCpu, (a_u32Value)))
     1290# define IEM_MC_PUSH_U32_SREG(a_uSegVal)        IEM_MC_RETURN_ON_FAILURE(iemMemStackPushU32SReg(pVCpu, (a_uSegVal)))
     1291# define IEM_MC_PUSH_U64(a_u64Value)            IEM_MC_RETURN_ON_FAILURE(iemMemStackPushU64(pVCpu, (a_u64Value)))
     1292
     1293# define IEM_MC_POP_U16(a_pu16Value)            IEM_MC_RETURN_ON_FAILURE(iemMemStackPopU16(pVCpu, (a_pu16Value)))
     1294# define IEM_MC_POP_U32(a_pu32Value)            IEM_MC_RETURN_ON_FAILURE(iemMemStackPopU32(pVCpu, (a_pu32Value)))
     1295# define IEM_MC_POP_U64(a_pu64Value)            IEM_MC_RETURN_ON_FAILURE(iemMemStackPopU64(pVCpu, (a_pu64Value)))
     1296#else
     1297# define IEM_MC_PUSH_U16(a_u16Value)            iemMemStackPushU16Jmp(pVCpu, (a_u16Value))
     1298# define IEM_MC_PUSH_U32(a_u32Value)            iemMemStackPushU32Jmp(pVCpu, (a_u32Value))
     1299# define IEM_MC_PUSH_U32_SREG(a_uSegVal)        iemMemStackPushU32SRegJmp(pVCpu, (a_uSegVal))
     1300# define IEM_MC_PUSH_U64(a_u64Value)            iemMemStackPushU64Jmp(pVCpu, (a_u64Value))
     1301
     1302# define IEM_MC_POP_U16(a_pu16Value)            (*(a_pu16Value) = iemMemStackPopU16Jmp(pVCpu))
     1303# define IEM_MC_POP_U32(a_pu32Value)            (*(a_pu32Value) = iemMemStackPopU32Jmp(pVCpu))
     1304# define IEM_MC_POP_U64(a_pu64Value)            (*(a_pu64Value) = iemMemStackPopU64Jmp(pVCpu))
     1305#endif
    12951306
    12961307/* 32-bit flat stack push and pop: */
    1297 #define IEM_MC_FLAT32_PUSH_U16(a_u16Value)      IEM_MC_RETURN_ON_FAILURE(iemMemStackPushU16(pVCpu, (a_u16Value)))
    1298 #define IEM_MC_FLAT32_PUSH_U32(a_u32Value)      IEM_MC_RETURN_ON_FAILURE(iemMemStackPushU32(pVCpu, (a_u32Value)))
    1299 #define IEM_MC_FLAT32_PUSH_U32_SREG(a_u32Value) IEM_MC_RETURN_ON_FAILURE(iemMemStackPushU32SReg(pVCpu, (a_u32Value)))
    1300 
    1301 #define IEM_MC_FLAT32_POP_U16(a_pu16Value)      IEM_MC_RETURN_ON_FAILURE(iemMemStackPopU16(pVCpu, (a_pu16Value)))
    1302 #define IEM_MC_FLAT32_POP_U32(a_pu32Value)      IEM_MC_RETURN_ON_FAILURE(iemMemStackPopU32(pVCpu, (a_pu32Value)))
     1308#ifndef IEM_WITH_SETJMP
     1309# define IEM_MC_FLAT32_PUSH_U16(a_u16Value)     IEM_MC_RETURN_ON_FAILURE(iemMemStackPushU16(pVCpu, (a_u16Value)))
     1310# define IEM_MC_FLAT32_PUSH_U32(a_u32Value)     IEM_MC_RETURN_ON_FAILURE(iemMemStackPushU32(pVCpu, (a_u32Value)))
     1311# define IEM_MC_FLAT32_PUSH_U32_SREG(a_uSegVal) IEM_MC_RETURN_ON_FAILURE(iemMemStackPushU32SReg(pVCpu, (a_uSegVal)))
     1312
     1313# define IEM_MC_FLAT32_POP_U16(a_pu16Value)     IEM_MC_RETURN_ON_FAILURE(iemMemStackPopU16(pVCpu, (a_pu16Value)))
     1314# define IEM_MC_FLAT32_POP_U32(a_pu32Value)     IEM_MC_RETURN_ON_FAILURE(iemMemStackPopU32(pVCpu, (a_pu32Value)))
     1315#else
     1316# define IEM_MC_FLAT32_PUSH_U16(a_u16Value)     iemMemFlat32StackPushU16Jmp(pVCpu, (a_u16Value))
     1317# define IEM_MC_FLAT32_PUSH_U32(a_u32Value)     iemMemFlat32StackPushU32Jmp(pVCpu, (a_u32Value))
     1318# define IEM_MC_FLAT32_PUSH_U32_SREG(a_uSegVal) iemMemFlat32StackPushU32SRegJmp(pVCpu, (a_uSegVal))
     1319
     1320# define IEM_MC_FLAT32_POP_U16(a_pu16Value)     (*(a_pu16Value) = iemMemFlat32StackPopU16Jmp(pVCpu))
     1321# define IEM_MC_FLAT32_POP_U32(a_pu32Value)     (*(a_pu32Value) = iemMemFlat32StackPopU32Jmp(pVCpu))
     1322#endif
    13031323
    13041324/* 64-bit flat stack push and pop: */
    1305 #define IEM_MC_FLAT64_PUSH_U16(a_u16Value)      IEM_MC_RETURN_ON_FAILURE(iemMemStackPushU16(pVCpu, (a_u16Value)))
    1306 #define IEM_MC_FLAT64_PUSH_U64(a_u64Value)      IEM_MC_RETURN_ON_FAILURE(iemMemStackPushU64(pVCpu, (a_u64Value)))
    1307 
    1308 #define IEM_MC_FLAT64_POP_U16(a_pu16Value)      IEM_MC_RETURN_ON_FAILURE(iemMemStackPopU16(pVCpu, (a_pu16Value)))
    1309 #define IEM_MC_FLAT64_POP_U64(a_pu64Value)      IEM_MC_RETURN_ON_FAILURE(iemMemStackPopU64(pVCpu, (a_pu64Value)))
     1325#ifndef IEM_WITH_SETJMP
     1326# define IEM_MC_FLAT64_PUSH_U16(a_u16Value)     IEM_MC_RETURN_ON_FAILURE(iemMemStackPushU16(pVCpu, (a_u16Value)))
     1327# define IEM_MC_FLAT64_PUSH_U64(a_u64Value)     IEM_MC_RETURN_ON_FAILURE(iemMemStackPushU64(pVCpu, (a_u64Value)))
     1328
     1329# define IEM_MC_FLAT64_POP_U16(a_pu16Value)     IEM_MC_RETURN_ON_FAILURE(iemMemStackPopU16(pVCpu, (a_pu16Value)))
     1330# define IEM_MC_FLAT64_POP_U64(a_pu64Value)     IEM_MC_RETURN_ON_FAILURE(iemMemStackPopU64(pVCpu, (a_pu64Value)))
     1331#else
     1332# define IEM_MC_FLAT64_PUSH_U16(a_u16Value)     iemMemFlat64StackPushU16Jmp(pVCpu, (a_u16Value))
     1333# define IEM_MC_FLAT64_PUSH_U64(a_u64Value)     iemMemFlat64StackPushU64Jmp(pVCpu, (a_u64Value))
     1334
     1335# define IEM_MC_FLAT64_POP_U16(a_pu16Value)     (*(a_pu16Value) = iemMemFlat64StackPopU16Jmp(pVCpu))
     1336# define IEM_MC_FLAT64_POP_U64(a_pu64Value)     (*(a_pu64Value) = iemMemFlat64StackPopU64Jmp(pVCpu))
     1337#endif
    13101338
    13111339
Note: See TracChangeset for help on using the changeset viewer.

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