Changeset 62083 in vbox for trunk/src/VBox/VMM/VMMAll
- Timestamp:
- Jul 6, 2016 6:13:59 PM (9 years ago)
- svn:sync-xref-src-repo-rev:
- 108555
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/IEMAll.cpp
r62076 r62083 5042 5042 * @param iSegReg The segment register. 5043 5043 */ 5044 IEM_STATIC uint16_t *iemSRegRef(PVMCPU pVCpu, uint8_t iSegReg) 5045 { 5044 DECLINLINE(uint16_t *) iemSRegRef(PVMCPU pVCpu, uint8_t iSegReg) 5045 { 5046 Assert(iSegReg < X86_SREG_COUNT); 5046 5047 PCPUMCTX pCtx = IEM_GET_CTX(pVCpu); 5047 #if 0 5048 return &pCtx->aSRegs[iSegReg].Sel; 5049 } 5050 5051 5052 /** 5053 * Fetches the selector value of a segment register. 5054 * 5055 * @returns The selector value. 5056 * @param pVCpu The cross context virtual CPU structure of the calling thread. 5057 * @param iSegReg The segment register. 5058 */ 5059 DECLINLINE(uint16_t) iemSRegFetchU16(PVMCPU pVCpu, uint8_t iSegReg) 5060 { 5048 5061 Assert(iSegReg < X86_SREG_COUNT); 5049 return &pCtx->aSRegs[iSegReg].Sel; 5050 #else 5051 switch (iSegReg) 5052 { 5053 case X86_SREG_ES: return &pCtx->es.Sel; 5054 case X86_SREG_CS: return &pCtx->cs.Sel; 5055 case X86_SREG_SS: return &pCtx->ss.Sel; 5056 case X86_SREG_DS: return &pCtx->ds.Sel; 5057 case X86_SREG_FS: return &pCtx->fs.Sel; 5058 case X86_SREG_GS: return &pCtx->gs.Sel; 5059 } 5060 AssertFailedReturn(NULL); 5061 #endif 5062 } 5063 5064 5065 /** 5066 * Fetches the selector value of a segment register. 5067 * 5068 * @returns The selector value. 5069 * @param pVCpu The cross context virtual CPU structure of the calling thread. 5070 * @param iSegReg The segment register. 5071 */ 5072 IEM_STATIC uint16_t iemSRegFetchU16(PVMCPU pVCpu, uint8_t iSegReg) 5073 { 5062 return IEM_GET_CTX(pVCpu)->aSRegs[iSegReg].Sel; 5063 } 5064 5065 5066 /** 5067 * Gets a reference (pointer) to the specified general purpose register. 5068 * 5069 * @returns Register reference. 5070 * @param pVCpu The cross context virtual CPU structure of the calling thread. 5071 * @param iReg The general purpose register. 5072 */ 5073 DECLINLINE(void *) iemGRegRef(PVMCPU pVCpu, uint8_t iReg) 5074 { 5075 Assert(iReg < 16); 5074 5076 PCPUMCTX pCtx = IEM_GET_CTX(pVCpu); 5075 #if 0 5076 Assert(iSegReg < X86_SREG_COUNT); 5077 return pCtx->aSRegs[iSegReg].Sel; 5078 #else 5079 switch (iSegReg) 5080 { 5081 case X86_SREG_ES: return pCtx->es.Sel; 5082 case X86_SREG_CS: return pCtx->cs.Sel; 5083 case X86_SREG_SS: return pCtx->ss.Sel; 5084 case X86_SREG_DS: return pCtx->ds.Sel; 5085 case X86_SREG_FS: return pCtx->fs.Sel; 5086 case X86_SREG_GS: return pCtx->gs.Sel; 5087 } 5088 AssertFailedReturn(0xffff); 5089 #endif 5090 } 5091 5092 5093 /** 5094 * Gets a reference (pointer) to the specified general register. 5077 return &pCtx->aGRegs[iReg]; 5078 } 5079 5080 5081 /** 5082 * Gets a reference (pointer) to the specified 8-bit general purpose register. 5083 * 5084 * Because of AH, CH, DH and BH we cannot use iemGRegRef directly here. 5095 5085 * 5096 5086 * @returns Register reference. 5097 5087 * @param pVCpu The cross context virtual CPU structure of the calling thread. 5098 * @param iReg The generalregister.5099 */ 5100 IEM_STATIC void *iemGRegRef(PVMCPU pVCpu, uint8_t iReg)5088 * @param iReg The register. 5089 */ 5090 DECLINLINE(uint8_t *) iemGRegRefU8(PVMCPU pVCpu, uint8_t iReg) 5101 5091 { 5102 5092 PCPUMCTX pCtx = IEM_GET_CTX(pVCpu); 5103 #if 0 5093 if (iReg < 4 || (pVCpu->iem.s.fPrefixes & IEM_OP_PRF_REX)) 5094 { 5095 Assert(iReg < 16); 5096 return &pCtx->aGRegs[iReg].u8; 5097 } 5098 /* high 8-bit register. */ 5099 Assert(iReg < 8); 5100 return &pCtx->aGRegs[iReg & 3].bHi; 5101 } 5102 5103 5104 /** 5105 * Gets a reference (pointer) to the specified 16-bit general purpose register. 5106 * 5107 * @returns Register reference. 5108 * @param pVCpu The cross context virtual CPU structure of the calling thread. 5109 * @param iReg The register. 5110 */ 5111 DECLINLINE(uint16_t *) iemGRegRefU16(PVMCPU pVCpu, uint8_t iReg) 5112 { 5104 5113 Assert(iReg < 16); 5105 return &pCtx->aGRegs[iReg]; 5106 #else 5107 switch (iReg) 5108 { 5109 case X86_GREG_xAX: return &pCtx->rax; 5110 case X86_GREG_xCX: return &pCtx->rcx; 5111 case X86_GREG_xDX: return &pCtx->rdx; 5112 case X86_GREG_xBX: return &pCtx->rbx; 5113 case X86_GREG_xSP: return &pCtx->rsp; 5114 case X86_GREG_xBP: return &pCtx->rbp; 5115 case X86_GREG_xSI: return &pCtx->rsi; 5116 case X86_GREG_xDI: return &pCtx->rdi; 5117 case X86_GREG_x8: return &pCtx->r8; 5118 case X86_GREG_x9: return &pCtx->r9; 5119 case X86_GREG_x10: return &pCtx->r10; 5120 case X86_GREG_x11: return &pCtx->r11; 5121 case X86_GREG_x12: return &pCtx->r12; 5122 case X86_GREG_x13: return &pCtx->r13; 5123 case X86_GREG_x14: return &pCtx->r14; 5124 case X86_GREG_x15: return &pCtx->r15; 5125 } 5126 AssertFailedReturn(NULL); 5127 #endif 5128 } 5129 5130 5131 /** 5132 * Gets a reference (pointer) to the specified 8-bit general register. 5133 * 5134 * Because of AH, CH, DH and BH we cannot use iemGRegRef directly here. 5114 PCPUMCTX pCtx = IEM_GET_CTX(pVCpu); 5115 return &pCtx->aGRegs[iReg].u16; 5116 } 5117 5118 5119 /** 5120 * Gets a reference (pointer) to the specified 32-bit general purpose register. 5135 5121 * 5136 5122 * @returns Register reference. … … 5138 5124 * @param iReg The register. 5139 5125 */ 5140 IEM_STATIC uint8_t *iemGRegRefU8(PVMCPU pVCpu, uint8_t iReg) 5141 { 5142 if (pVCpu->iem.s.fPrefixes & IEM_OP_PRF_REX) 5143 return (uint8_t *)iemGRegRef(pVCpu, iReg); 5144 5145 uint8_t *pu8Reg = (uint8_t *)iemGRegRef(pVCpu, iReg & 3); 5146 if (iReg >= 4) 5147 pu8Reg++; 5148 return pu8Reg; 5149 } 5150 5151 5152 /** 5153 * Fetches the value of a 8-bit general register. 5126 DECLINLINE(uint32_t *) iemGRegRefU32(PVMCPU pVCpu, uint8_t iReg) 5127 { 5128 Assert(iReg < 16); 5129 PCPUMCTX pCtx = IEM_GET_CTX(pVCpu); 5130 return &pCtx->aGRegs[iReg].u32; 5131 } 5132 5133 5134 /** 5135 * Gets a reference (pointer) to the specified 64-bit general purpose register. 5136 * 5137 * @returns Register reference. 5138 * @param pVCpu The cross context virtual CPU structure of the calling thread. 5139 * @param iReg The register. 5140 */ 5141 DECLINLINE(uint64_t *) iemGRegRefU64(PVMCPU pVCpu, uint8_t iReg) 5142 { 5143 Assert(iReg < 64); 5144 PCPUMCTX pCtx = IEM_GET_CTX(pVCpu); 5145 return &pCtx->aGRegs[iReg].u64; 5146 } 5147 5148 5149 /** 5150 * Fetches the value of a 8-bit general purpose register. 5154 5151 * 5155 5152 * @returns The register value. … … 5157 5154 * @param iReg The register. 5158 5155 */ 5159 IEM_STATIC uint8_t iemGRegFetchU8(PVMCPU pVCpu, uint8_t iReg) 5160 { 5161 uint8_t const *pbSrc = iemGRegRefU8(pVCpu, iReg); 5162 return *pbSrc; 5163 } 5164 5165 5166 /** 5167 * Fetches the value of a 16-bit general register. 5156 DECLINLINE(uint8_t) iemGRegFetchU8(PVMCPU pVCpu, uint8_t iReg) 5157 { 5158 return *iemGRegRefU8(pVCpu, iReg); 5159 } 5160 5161 5162 /** 5163 * Fetches the value of a 16-bit general purpose register. 5168 5164 * 5169 5165 * @returns The register value. … … 5171 5167 * @param iReg The register. 5172 5168 */ 5173 IEM_STATIC uint16_t iemGRegFetchU16(PVMCPU pVCpu, uint8_t iReg) 5174 { 5175 return *(uint16_t *)iemGRegRef(pVCpu, iReg); 5176 } 5177 5178 5179 /** 5180 * Fetches the value of a 32-bit general register. 5169 DECLINLINE(uint16_t) iemGRegFetchU16(PVMCPU pVCpu, uint8_t iReg) 5170 { 5171 Assert(iReg < 16); 5172 return IEM_GET_CTX(pVCpu)->aGRegs[iReg].u16; 5173 } 5174 5175 5176 /** 5177 * Fetches the value of a 32-bit general purpose register. 5181 5178 * 5182 5179 * @returns The register value. … … 5184 5181 * @param iReg The register. 5185 5182 */ 5186 IEM_STATIC uint32_t iemGRegFetchU32(PVMCPU pVCpu, uint8_t iReg) 5187 { 5188 return *(uint32_t *)iemGRegRef(pVCpu, iReg); 5189 } 5190 5191 5192 /** 5193 * Fetches the value of a 64-bit general register. 5183 DECLINLINE(uint32_t) iemGRegFetchU32(PVMCPU pVCpu, uint8_t iReg) 5184 { 5185 Assert(iReg < 16); 5186 return IEM_GET_CTX(pVCpu)->aGRegs[iReg].u32; 5187 } 5188 5189 5190 /** 5191 * Fetches the value of a 64-bit general purpose register. 5194 5192 * 5195 5193 * @returns The register value. … … 5197 5195 * @param iReg The register. 5198 5196 */ 5199 IEM_STATIC uint64_t iemGRegFetchU64(PVMCPU pVCpu, uint8_t iReg) 5200 { 5201 return *(uint64_t *)iemGRegRef(pVCpu, iReg); 5197 DECLINLINE(uint64_t) iemGRegFetchU64(PVMCPU pVCpu, uint8_t iReg) 5198 { 5199 Assert(iReg < 16); 5200 return IEM_GET_CTX(pVCpu)->aGRegs[iReg].u64; 5202 5201 } 5203 5202 … … 9785 9784 #define IEM_MC_FETCH_FCW(a_u16Fcw) (a_u16Fcw) = IEM_GET_CTX(pVCpu)->CTX_SUFF(pXState)->x87.FCW 9786 9785 9787 #define IEM_MC_STORE_GREG_U8(a_iGReg, a_u8Value) *iemGRegRefU8( pVCpu, (a_iGReg)) = (a_u8Value)9788 #define IEM_MC_STORE_GREG_U16(a_iGReg, a_u16Value) * (uint16_t *)iemGRegRef(pVCpu, (a_iGReg)) = (a_u16Value)9789 #define IEM_MC_STORE_GREG_U32(a_iGReg, a_u32Value) * (uint64_t *)iemGRegRef(pVCpu, (a_iGReg)) = (uint32_t)(a_u32Value) /* clear high bits. */9790 #define IEM_MC_STORE_GREG_U64(a_iGReg, a_u64Value) * (uint64_t *)iemGRegRef(pVCpu, (a_iGReg)) = (a_u64Value)9786 #define IEM_MC_STORE_GREG_U8(a_iGReg, a_u8Value) *iemGRegRefU8( pVCpu, (a_iGReg)) = (a_u8Value) 9787 #define IEM_MC_STORE_GREG_U16(a_iGReg, a_u16Value) *iemGRegRefU16(pVCpu, (a_iGReg)) = (a_u16Value) 9788 #define IEM_MC_STORE_GREG_U32(a_iGReg, a_u32Value) *iemGRegRefU64(pVCpu, (a_iGReg)) = (uint32_t)(a_u32Value) /* clear high bits. */ 9789 #define IEM_MC_STORE_GREG_U64(a_iGReg, a_u64Value) *iemGRegRefU64(pVCpu, (a_iGReg)) = (a_u64Value) 9791 9790 #define IEM_MC_STORE_GREG_U8_CONST IEM_MC_STORE_GREG_U8 9792 9791 #define IEM_MC_STORE_GREG_U16_CONST IEM_MC_STORE_GREG_U16 9793 9792 #define IEM_MC_STORE_GREG_U32_CONST IEM_MC_STORE_GREG_U32 9794 9793 #define IEM_MC_STORE_GREG_U64_CONST IEM_MC_STORE_GREG_U64 9795 #define IEM_MC_CLEAR_HIGH_GREG_U64(a_iGReg) * (uint64_t *)iemGRegRef(pVCpu, (a_iGReg)) &= UINT32_MAX9794 #define IEM_MC_CLEAR_HIGH_GREG_U64(a_iGReg) *iemGRegRefU64(pVCpu, (a_iGReg)) &= UINT32_MAX 9796 9795 #define IEM_MC_CLEAR_HIGH_GREG_U64_BY_REF(a_pu32Dst) do { (a_pu32Dst)[1] = 0; } while (0) 9797 9796 #define IEM_MC_STORE_FPUREG_R80_SRC_REF(a_iSt, a_pr80Src) \ 9798 9797 do { IEM_GET_CTX(pVCpu)->CTX_SUFF(pXState)->x87.aRegs[a_iSt].r80 = *(a_pr80Src); } while (0) 9799 9798 9800 #define IEM_MC_REF_GREG_U8(a_pu8Dst, a_iGReg) (a_pu8Dst) = iemGRegRefU8(pVCpu, (a_iGReg))9801 #define IEM_MC_REF_GREG_U16(a_pu16Dst, a_iGReg) (a_pu16Dst) = (uint16_t *)iemGRegRef(pVCpu, (a_iGReg))9799 #define IEM_MC_REF_GREG_U8(a_pu8Dst, a_iGReg) (a_pu8Dst) = iemGRegRefU8( pVCpu, (a_iGReg)) 9800 #define IEM_MC_REF_GREG_U16(a_pu16Dst, a_iGReg) (a_pu16Dst) = iemGRegRefU16(pVCpu, (a_iGReg)) 9802 9801 /** @todo User of IEM_MC_REF_GREG_U32 needs to clear the high bits on commit. 9803 9802 * Use IEM_MC_CLEAR_HIGH_GREG_U64_BY_REF! */ 9804 #define IEM_MC_REF_GREG_U32(a_pu32Dst, a_iGReg) (a_pu32Dst) = (uint32_t *)iemGRegRef(pVCpu, (a_iGReg))9805 #define IEM_MC_REF_GREG_U64(a_pu64Dst, a_iGReg) (a_pu64Dst) = (uint64_t *)iemGRegRef(pVCpu, (a_iGReg))9803 #define IEM_MC_REF_GREG_U32(a_pu32Dst, a_iGReg) (a_pu32Dst) = iemGRegRefU32(pVCpu, (a_iGReg)) 9804 #define IEM_MC_REF_GREG_U64(a_pu64Dst, a_iGReg) (a_pu64Dst) = iemGRegRefU64(pVCpu, (a_iGReg)) 9806 9805 /** @note Not for IOPL or IF testing or modification. */ 9807 9806 #define IEM_MC_REF_EFLAGS(a_pEFlags) (a_pEFlags) = &(pVCpu)->iem.s.CTX_SUFF(pCtx)->eflags.u 9808 9807 9809 #define IEM_MC_ADD_GREG_U8(a_iGReg, a_u8Value) * (uint8_t *)iemGRegRef(pVCpu, (a_iGReg)) += (a_u8Value)9810 #define IEM_MC_ADD_GREG_U16(a_iGReg, a_u16Value) * (uint16_t *)iemGRegRef(pVCpu, (a_iGReg)) += (a_u16Value)9808 #define IEM_MC_ADD_GREG_U8(a_iGReg, a_u8Value) *iemGRegRefU8( pVCpu, (a_iGReg)) += (a_u8Value) 9809 #define IEM_MC_ADD_GREG_U16(a_iGReg, a_u16Value) *iemGRegRefU16(pVCpu, (a_iGReg)) += (a_u16Value) 9811 9810 #define IEM_MC_ADD_GREG_U32(a_iGReg, a_u32Value) \ 9812 9811 do { \ 9813 uint32_t *pu32Reg = (uint32_t *)iemGRegRef(pVCpu, (a_iGReg)); \9812 uint32_t *pu32Reg = iemGRegRefU32(pVCpu, (a_iGReg)); \ 9814 9813 *pu32Reg += (a_u32Value); \ 9815 9814 pu32Reg[1] = 0; /* implicitly clear the high bit. */ \ 9816 9815 } while (0) 9817 #define IEM_MC_ADD_GREG_U64(a_iGReg, a_u64Value) * (uint64_t *)iemGRegRef(pVCpu, (a_iGReg)) += (a_u64Value)9818 9819 #define IEM_MC_SUB_GREG_U8(a_iGReg, a_u8Value) * (uint8_t *)iemGRegRef(pVCpu, (a_iGReg)) -= (a_u8Value)9820 #define IEM_MC_SUB_GREG_U16(a_iGReg, a_u16Value) * (uint16_t *)iemGRegRef(pVCpu, (a_iGReg)) -= (a_u16Value)9816 #define IEM_MC_ADD_GREG_U64(a_iGReg, a_u64Value) *iemGRegRefU64(pVCpu, (a_iGReg)) += (a_u64Value) 9817 9818 #define IEM_MC_SUB_GREG_U8(a_iGReg, a_u8Value) *iemGRegRefU8( pVCpu, (a_iGReg)) -= (a_u8Value) 9819 #define IEM_MC_SUB_GREG_U16(a_iGReg, a_u16Value) *iemGRegRefU16(pVCpu, (a_iGReg)) -= (a_u16Value) 9821 9820 #define IEM_MC_SUB_GREG_U32(a_iGReg, a_u32Value) \ 9822 9821 do { \ 9823 uint32_t *pu32Reg = (uint32_t *)iemGRegRef(pVCpu, (a_iGReg)); \9822 uint32_t *pu32Reg = iemGRegRefU32(pVCpu, (a_iGReg)); \ 9824 9823 *pu32Reg -= (a_u32Value); \ 9825 9824 pu32Reg[1] = 0; /* implicitly clear the high bit. */ \ 9826 9825 } while (0) 9827 #define IEM_MC_SUB_GREG_U64(a_iGReg, a_u64Value) * (uint64_t *)iemGRegRef(pVCpu, (a_iGReg)) -= (a_u64Value)9826 #define IEM_MC_SUB_GREG_U64(a_iGReg, a_u64Value) *iemGRegRefU64(pVCpu, (a_iGReg)) -= (a_u64Value) 9828 9827 #define IEM_MC_SUB_LOCAL_U16(a_u16Value, a_u16Const) do { (a_u16Value) -= a_u16Const; } while (0) 9829 9828 … … 9861 9860 #define IEM_MC_OR_2LOCS_U32(a_u32Local, a_u32Mask) do { (a_u32Local) |= (a_u32Mask); } while (0) 9862 9861 9863 #define IEM_MC_AND_GREG_U8(a_iGReg, a_u8Value) * (uint8_t *)iemGRegRef(pVCpu, (a_iGReg)) &= (a_u8Value)9864 #define IEM_MC_AND_GREG_U16(a_iGReg, a_u16Value) * (uint16_t *)iemGRegRef(pVCpu, (a_iGReg)) &= (a_u16Value)9862 #define IEM_MC_AND_GREG_U8(a_iGReg, a_u8Value) *iemGRegRefU8( pVCpu, (a_iGReg)) &= (a_u8Value) 9863 #define IEM_MC_AND_GREG_U16(a_iGReg, a_u16Value) *iemGRegRefU16(pVCpu, (a_iGReg)) &= (a_u16Value) 9865 9864 #define IEM_MC_AND_GREG_U32(a_iGReg, a_u32Value) \ 9866 9865 do { \ 9867 uint32_t *pu32Reg = (uint32_t *)iemGRegRef(pVCpu, (a_iGReg)); \9866 uint32_t *pu32Reg = iemGRegRefU32(pVCpu, (a_iGReg)); \ 9868 9867 *pu32Reg &= (a_u32Value); \ 9869 9868 pu32Reg[1] = 0; /* implicitly clear the high bit. */ \ 9870 9869 } while (0) 9871 #define IEM_MC_AND_GREG_U64(a_iGReg, a_u64Value) * (uint64_t *)iemGRegRef(pVCpu, (a_iGReg)) &= (a_u64Value)9872 9873 #define IEM_MC_OR_GREG_U8(a_iGReg, a_u8Value) * (uint8_t *)iemGRegRef(pVCpu, (a_iGReg)) |= (a_u8Value)9874 #define IEM_MC_OR_GREG_U16(a_iGReg, a_u16Value) * (uint16_t *)iemGRegRef(pVCpu, (a_iGReg)) |= (a_u16Value)9870 #define IEM_MC_AND_GREG_U64(a_iGReg, a_u64Value) *iemGRegRefU64(pVCpu, (a_iGReg)) &= (a_u64Value) 9871 9872 #define IEM_MC_OR_GREG_U8(a_iGReg, a_u8Value) *iemGRegRefU8( pVCpu, (a_iGReg)) |= (a_u8Value) 9873 #define IEM_MC_OR_GREG_U16(a_iGReg, a_u16Value) *iemGRegRefU16(pVCpu, (a_iGReg)) |= (a_u16Value) 9875 9874 #define IEM_MC_OR_GREG_U32(a_iGReg, a_u32Value) \ 9876 9875 do { \ 9877 uint32_t *pu32Reg = (uint32_t *)iemGRegRef(pVCpu, (a_iGReg)); \9876 uint32_t *pu32Reg = iemGRegRefU32(pVCpu, (a_iGReg)); \ 9878 9877 *pu32Reg |= (a_u32Value); \ 9879 9878 pu32Reg[1] = 0; /* implicitly clear the high bit. */ \ 9880 9879 } while (0) 9881 #define IEM_MC_OR_GREG_U64(a_iGReg, a_u64Value) * (uint64_t *)iemGRegRef(pVCpu, (a_iGReg)) |= (a_u64Value)9880 #define IEM_MC_OR_GREG_U64(a_iGReg, a_u64Value) *iemGRegRefU64(pVCpu, (a_iGReg)) |= (a_u64Value) 9882 9881 9883 9882 … … 10651 10650 && !(IEM_GET_CTX(pVCpu)->eflags.u & a_fBit)) { 10652 10651 #define IEM_MC_IF_LOCAL_IS_Z(a_Local) if ((a_Local) == 0) { 10653 #define IEM_MC_IF_GREG_BIT_SET(a_iGReg, a_iBitNo) if ( *(uint64_t *)iemGRegRef(pVCpu, (a_iGReg)) & RT_BIT_64(a_iBitNo)) {10652 #define IEM_MC_IF_GREG_BIT_SET(a_iGReg, a_iBitNo) if (iemGRegFetchU64(pVCpu, (a_iGReg)) & RT_BIT_64(a_iBitNo)) { 10654 10653 10655 10654 #define IEM_MC_IF_FPUREG_NOT_EMPTY(a_iSt) \
Note:
See TracChangeset
for help on using the changeset viewer.