Changeset 108278 in vbox for trunk/src/VBox/VMM/VMMAll/target-x86/IEMAllOpHlp-x86.cpp
- Timestamp:
- Feb 18, 2025 3:46:53 PM (2 months ago)
- svn:sync-xref-src-repo-rev:
- 167608
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/target-x86/IEMAllOpHlp-x86.cpp
r108260 r108278 59 59 * Meant to be used via IEM_MC_CALC_RM_EFF_ADDR. 60 60 * 61 * @return Strict VBox status code.62 * @param pVCpu The cross context virtual CPU structure of the calling thread.63 * @param bRm The ModRM byte.64 * @param cbImmAndRspOffset - First byte: The size of any immediate65 * following the effective address opcode bytes66 * (only for RIP relative addressing).67 * - Second byte: RSP displacement (for POP [ESP]).68 * @param pGCPtrEff Where to return the effective address.69 */70 VBOXSTRICTRC iemOpHlpCalcRmEffAddr(PVMCPUCC pVCpu, uint8_t bRm, uint32_t cbImmAndRspOffset, PRTGCPTR pGCPtrEff) RT_NOEXCEPT71 {72 Log5(("iemOpHlpCalcRmEffAddr: bRm=%#x\n", bRm));73 # define SET_SS_DEF() \74 do \75 { \76 if (!(pVCpu->iem.s.fPrefixes & IEM_OP_PRF_SEG_MASK)) \77 pVCpu->iem.s.iEffSeg = X86_SREG_SS; \78 } while (0)79 80 if (!IEM_IS_64BIT_CODE(pVCpu))81 {82 /** @todo Check the effective address size crap! */83 if (pVCpu->iem.s.enmEffAddrMode == IEMMODE_16BIT)84 {85 uint16_t u16EffAddr;86 87 /* Handle the disp16 form with no registers first. */88 if ((bRm & (X86_MODRM_MOD_MASK | X86_MODRM_RM_MASK)) == 6)89 IEM_OPCODE_GET_NEXT_U16(&u16EffAddr);90 else91 {92 /* Get the displacment. */93 switch ((bRm >> X86_MODRM_MOD_SHIFT) & X86_MODRM_MOD_SMASK)94 {95 case 0: u16EffAddr = 0; break;96 case 1: IEM_OPCODE_GET_NEXT_S8_SX_U16(&u16EffAddr); break;97 case 2: IEM_OPCODE_GET_NEXT_U16(&u16EffAddr); break;98 default: AssertFailedReturn(VERR_IEM_IPE_1); /* (caller checked for these) */99 }100 101 /* Add the base and index registers to the disp. */102 switch (bRm & X86_MODRM_RM_MASK)103 {104 case 0: u16EffAddr += pVCpu->cpum.GstCtx.bx + pVCpu->cpum.GstCtx.si; break;105 case 1: u16EffAddr += pVCpu->cpum.GstCtx.bx + pVCpu->cpum.GstCtx.di; break;106 case 2: u16EffAddr += pVCpu->cpum.GstCtx.bp + pVCpu->cpum.GstCtx.si; SET_SS_DEF(); break;107 case 3: u16EffAddr += pVCpu->cpum.GstCtx.bp + pVCpu->cpum.GstCtx.di; SET_SS_DEF(); break;108 case 4: u16EffAddr += pVCpu->cpum.GstCtx.si; break;109 case 5: u16EffAddr += pVCpu->cpum.GstCtx.di; break;110 case 6: u16EffAddr += pVCpu->cpum.GstCtx.bp; SET_SS_DEF(); break;111 case 7: u16EffAddr += pVCpu->cpum.GstCtx.bx; break;112 }113 }114 115 *pGCPtrEff = u16EffAddr;116 }117 else118 {119 Assert(pVCpu->iem.s.enmEffAddrMode == IEMMODE_32BIT);120 uint32_t u32EffAddr;121 122 /* Handle the disp32 form with no registers first. */123 if ((bRm & (X86_MODRM_MOD_MASK | X86_MODRM_RM_MASK)) == 5)124 IEM_OPCODE_GET_NEXT_U32(&u32EffAddr);125 else126 {127 /* Get the register (or SIB) value. */128 switch ((bRm & X86_MODRM_RM_MASK))129 {130 case 0: u32EffAddr = pVCpu->cpum.GstCtx.eax; break;131 case 1: u32EffAddr = pVCpu->cpum.GstCtx.ecx; break;132 case 2: u32EffAddr = pVCpu->cpum.GstCtx.edx; break;133 case 3: u32EffAddr = pVCpu->cpum.GstCtx.ebx; break;134 case 4: /* SIB */135 {136 uint8_t bSib; IEM_OPCODE_GET_NEXT_U8(&bSib);137 138 /* Get the index and scale it. */139 switch ((bSib >> X86_SIB_INDEX_SHIFT) & X86_SIB_INDEX_SMASK)140 {141 case 0: u32EffAddr = pVCpu->cpum.GstCtx.eax; break;142 case 1: u32EffAddr = pVCpu->cpum.GstCtx.ecx; break;143 case 2: u32EffAddr = pVCpu->cpum.GstCtx.edx; break;144 case 3: u32EffAddr = pVCpu->cpum.GstCtx.ebx; break;145 case 4: u32EffAddr = 0; /*none */ break;146 case 5: u32EffAddr = pVCpu->cpum.GstCtx.ebp; break;147 case 6: u32EffAddr = pVCpu->cpum.GstCtx.esi; break;148 case 7: u32EffAddr = pVCpu->cpum.GstCtx.edi; break;149 IEM_NOT_REACHED_DEFAULT_CASE_RET();150 }151 u32EffAddr <<= (bSib >> X86_SIB_SCALE_SHIFT) & X86_SIB_SCALE_SMASK;152 153 /* add base */154 switch (bSib & X86_SIB_BASE_MASK)155 {156 case 0: u32EffAddr += pVCpu->cpum.GstCtx.eax; break;157 case 1: u32EffAddr += pVCpu->cpum.GstCtx.ecx; break;158 case 2: u32EffAddr += pVCpu->cpum.GstCtx.edx; break;159 case 3: u32EffAddr += pVCpu->cpum.GstCtx.ebx; break;160 case 4: u32EffAddr += pVCpu->cpum.GstCtx.esp + (cbImmAndRspOffset >> 8); SET_SS_DEF(); break;161 case 5:162 if ((bRm & X86_MODRM_MOD_MASK) != 0)163 {164 u32EffAddr += pVCpu->cpum.GstCtx.ebp;165 SET_SS_DEF();166 }167 else168 {169 uint32_t u32Disp;170 IEM_OPCODE_GET_NEXT_U32(&u32Disp);171 u32EffAddr += u32Disp;172 }173 break;174 case 6: u32EffAddr += pVCpu->cpum.GstCtx.esi; break;175 case 7: u32EffAddr += pVCpu->cpum.GstCtx.edi; break;176 IEM_NOT_REACHED_DEFAULT_CASE_RET();177 }178 break;179 }180 case 5: u32EffAddr = pVCpu->cpum.GstCtx.ebp; SET_SS_DEF(); break;181 case 6: u32EffAddr = pVCpu->cpum.GstCtx.esi; break;182 case 7: u32EffAddr = pVCpu->cpum.GstCtx.edi; break;183 IEM_NOT_REACHED_DEFAULT_CASE_RET();184 }185 186 /* Get and add the displacement. */187 switch ((bRm >> X86_MODRM_MOD_SHIFT) & X86_MODRM_MOD_SMASK)188 {189 case 0:190 break;191 case 1:192 {193 int8_t i8Disp; IEM_OPCODE_GET_NEXT_S8(&i8Disp);194 u32EffAddr += i8Disp;195 break;196 }197 case 2:198 {199 uint32_t u32Disp; IEM_OPCODE_GET_NEXT_U32(&u32Disp);200 u32EffAddr += u32Disp;201 break;202 }203 default:204 AssertFailedReturn(VERR_IEM_IPE_2); /* (caller checked for these) */205 }206 207 }208 Assert(pVCpu->iem.s.enmEffAddrMode == IEMMODE_32BIT);209 *pGCPtrEff = u32EffAddr;210 }211 }212 else213 {214 uint64_t u64EffAddr;215 216 /* Handle the rip+disp32 form with no registers first. */217 if ((bRm & (X86_MODRM_MOD_MASK | X86_MODRM_RM_MASK)) == 5)218 {219 IEM_OPCODE_GET_NEXT_S32_SX_U64(&u64EffAddr);220 u64EffAddr += pVCpu->cpum.GstCtx.rip + IEM_GET_INSTR_LEN(pVCpu) + (cbImmAndRspOffset & UINT32_C(0xff));221 }222 else223 {224 /* Get the register (or SIB) value. */225 switch ((bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB)226 {227 case 0: u64EffAddr = pVCpu->cpum.GstCtx.rax; break;228 case 1: u64EffAddr = pVCpu->cpum.GstCtx.rcx; break;229 case 2: u64EffAddr = pVCpu->cpum.GstCtx.rdx; break;230 case 3: u64EffAddr = pVCpu->cpum.GstCtx.rbx; break;231 case 5: u64EffAddr = pVCpu->cpum.GstCtx.rbp; SET_SS_DEF(); break;232 case 6: u64EffAddr = pVCpu->cpum.GstCtx.rsi; break;233 case 7: u64EffAddr = pVCpu->cpum.GstCtx.rdi; break;234 case 8: u64EffAddr = pVCpu->cpum.GstCtx.r8; break;235 case 9: u64EffAddr = pVCpu->cpum.GstCtx.r9; break;236 case 10: u64EffAddr = pVCpu->cpum.GstCtx.r10; break;237 case 11: u64EffAddr = pVCpu->cpum.GstCtx.r11; break;238 case 13: u64EffAddr = pVCpu->cpum.GstCtx.r13; break;239 case 14: u64EffAddr = pVCpu->cpum.GstCtx.r14; break;240 case 15: u64EffAddr = pVCpu->cpum.GstCtx.r15; break;241 /* SIB */242 case 4:243 case 12:244 {245 uint8_t bSib; IEM_OPCODE_GET_NEXT_U8(&bSib);246 247 /* Get the index and scale it. */248 switch (((bSib >> X86_SIB_INDEX_SHIFT) & X86_SIB_INDEX_SMASK) | pVCpu->iem.s.uRexIndex)249 {250 case 0: u64EffAddr = pVCpu->cpum.GstCtx.rax; break;251 case 1: u64EffAddr = pVCpu->cpum.GstCtx.rcx; break;252 case 2: u64EffAddr = pVCpu->cpum.GstCtx.rdx; break;253 case 3: u64EffAddr = pVCpu->cpum.GstCtx.rbx; break;254 case 4: u64EffAddr = 0; /*none */ break;255 case 5: u64EffAddr = pVCpu->cpum.GstCtx.rbp; break;256 case 6: u64EffAddr = pVCpu->cpum.GstCtx.rsi; break;257 case 7: u64EffAddr = pVCpu->cpum.GstCtx.rdi; break;258 case 8: u64EffAddr = pVCpu->cpum.GstCtx.r8; break;259 case 9: u64EffAddr = pVCpu->cpum.GstCtx.r9; break;260 case 10: u64EffAddr = pVCpu->cpum.GstCtx.r10; break;261 case 11: u64EffAddr = pVCpu->cpum.GstCtx.r11; break;262 case 12: u64EffAddr = pVCpu->cpum.GstCtx.r12; break;263 case 13: u64EffAddr = pVCpu->cpum.GstCtx.r13; break;264 case 14: u64EffAddr = pVCpu->cpum.GstCtx.r14; break;265 case 15: u64EffAddr = pVCpu->cpum.GstCtx.r15; break;266 IEM_NOT_REACHED_DEFAULT_CASE_RET();267 }268 u64EffAddr <<= (bSib >> X86_SIB_SCALE_SHIFT) & X86_SIB_SCALE_SMASK;269 270 /* add base */271 switch ((bSib & X86_SIB_BASE_MASK) | pVCpu->iem.s.uRexB)272 {273 case 0: u64EffAddr += pVCpu->cpum.GstCtx.rax; break;274 case 1: u64EffAddr += pVCpu->cpum.GstCtx.rcx; break;275 case 2: u64EffAddr += pVCpu->cpum.GstCtx.rdx; break;276 case 3: u64EffAddr += pVCpu->cpum.GstCtx.rbx; break;277 case 4: u64EffAddr += pVCpu->cpum.GstCtx.rsp + (cbImmAndRspOffset >> 8); SET_SS_DEF(); break;278 case 6: u64EffAddr += pVCpu->cpum.GstCtx.rsi; break;279 case 7: u64EffAddr += pVCpu->cpum.GstCtx.rdi; break;280 case 8: u64EffAddr += pVCpu->cpum.GstCtx.r8; break;281 case 9: u64EffAddr += pVCpu->cpum.GstCtx.r9; break;282 case 10: u64EffAddr += pVCpu->cpum.GstCtx.r10; break;283 case 11: u64EffAddr += pVCpu->cpum.GstCtx.r11; break;284 case 12: u64EffAddr += pVCpu->cpum.GstCtx.r12; break;285 case 14: u64EffAddr += pVCpu->cpum.GstCtx.r14; break;286 case 15: u64EffAddr += pVCpu->cpum.GstCtx.r15; break;287 /* complicated encodings */288 case 5:289 case 13:290 if ((bRm & X86_MODRM_MOD_MASK) != 0)291 {292 if (!pVCpu->iem.s.uRexB)293 {294 u64EffAddr += pVCpu->cpum.GstCtx.rbp;295 SET_SS_DEF();296 }297 else298 u64EffAddr += pVCpu->cpum.GstCtx.r13;299 }300 else301 {302 uint32_t u32Disp;303 IEM_OPCODE_GET_NEXT_U32(&u32Disp);304 u64EffAddr += (int32_t)u32Disp;305 }306 break;307 IEM_NOT_REACHED_DEFAULT_CASE_RET();308 }309 break;310 }311 IEM_NOT_REACHED_DEFAULT_CASE_RET();312 }313 314 /* Get and add the displacement. */315 switch ((bRm >> X86_MODRM_MOD_SHIFT) & X86_MODRM_MOD_SMASK)316 {317 case 0:318 break;319 case 1:320 {321 int8_t i8Disp;322 IEM_OPCODE_GET_NEXT_S8(&i8Disp);323 u64EffAddr += i8Disp;324 break;325 }326 case 2:327 {328 uint32_t u32Disp;329 IEM_OPCODE_GET_NEXT_U32(&u32Disp);330 u64EffAddr += (int32_t)u32Disp;331 break;332 }333 IEM_NOT_REACHED_DEFAULT_CASE_RET(); /* (caller checked for these) */334 }335 336 }337 338 if (pVCpu->iem.s.enmEffAddrMode == IEMMODE_64BIT)339 *pGCPtrEff = u64EffAddr;340 else341 {342 Assert(pVCpu->iem.s.enmEffAddrMode == IEMMODE_32BIT);343 *pGCPtrEff = u64EffAddr & UINT32_MAX;344 }345 }346 347 Log5(("iemOpHlpCalcRmEffAddr: EffAddr=%#010RGv\n", *pGCPtrEff));348 return VINF_SUCCESS;349 }350 351 352 #ifdef IEM_WITH_SETJMP353 /**354 * Calculates the effective address of a ModR/M memory operand.355 *356 * Meant to be used via IEM_MC_CALC_RM_EFF_ADDR.357 *358 61 * May longjmp on internal error. 359 62 * … … 369 72 { 370 73 Log5(("iemOpHlpCalcRmEffAddrJmp: bRm=%#x\n", bRm)); 371 # 74 #define SET_SS_DEF() \ 372 75 do \ 373 76 { \ … … 642 345 return u64EffAddr & UINT32_MAX; 643 346 } 644 #endif /* IEM_WITH_SETJMP */645 646 647 /**648 * Calculates the effective address of a ModR/M memory operand, extended version649 * for use in the recompilers.650 *651 * Meant to be used via IEM_MC_CALC_RM_EFF_ADDR.652 *653 * @return Strict VBox status code.654 * @param pVCpu The cross context virtual CPU structure of the calling thread.655 * @param bRm The ModRM byte.656 * @param cbImmAndRspOffset - First byte: The size of any immediate657 * following the effective address opcode bytes658 * (only for RIP relative addressing).659 * - Second byte: RSP displacement (for POP [ESP]).660 * @param pGCPtrEff Where to return the effective address.661 * @param puInfo Extra info: 32-bit displacement (bits 31:0) and662 * SIB byte (bits 39:32).663 */664 VBOXSTRICTRC iemOpHlpCalcRmEffAddrEx(PVMCPUCC pVCpu, uint8_t bRm, uint32_t cbImmAndRspOffset, PRTGCPTR pGCPtrEff, uint64_t *puInfo) RT_NOEXCEPT665 {666 Log5(("iemOpHlpCalcRmEffAddr: bRm=%#x\n", bRm));667 # define SET_SS_DEF() \668 do \669 { \670 if (!(pVCpu->iem.s.fPrefixes & IEM_OP_PRF_SEG_MASK)) \671 pVCpu->iem.s.iEffSeg = X86_SREG_SS; \672 } while (0)673 674 uint64_t uInfo;675 if (!IEM_IS_64BIT_CODE(pVCpu))676 {677 /** @todo Check the effective address size crap! */678 if (pVCpu->iem.s.enmEffAddrMode == IEMMODE_16BIT)679 {680 uint16_t u16EffAddr;681 682 /* Handle the disp16 form with no registers first. */683 if ((bRm & (X86_MODRM_MOD_MASK | X86_MODRM_RM_MASK)) == 6)684 {685 IEM_OPCODE_GET_NEXT_U16(&u16EffAddr);686 uInfo = u16EffAddr;687 }688 else689 {690 /* Get the displacment. */691 switch ((bRm >> X86_MODRM_MOD_SHIFT) & X86_MODRM_MOD_SMASK)692 {693 case 0: u16EffAddr = 0; break;694 case 1: IEM_OPCODE_GET_NEXT_S8_SX_U16(&u16EffAddr); break;695 case 2: IEM_OPCODE_GET_NEXT_U16(&u16EffAddr); break;696 default: AssertFailedReturn(VERR_IEM_IPE_1); /* (caller checked for these) */697 }698 uInfo = u16EffAddr;699 700 /* Add the base and index registers to the disp. */701 switch (bRm & X86_MODRM_RM_MASK)702 {703 case 0: u16EffAddr += pVCpu->cpum.GstCtx.bx + pVCpu->cpum.GstCtx.si; break;704 case 1: u16EffAddr += pVCpu->cpum.GstCtx.bx + pVCpu->cpum.GstCtx.di; break;705 case 2: u16EffAddr += pVCpu->cpum.GstCtx.bp + pVCpu->cpum.GstCtx.si; SET_SS_DEF(); break;706 case 3: u16EffAddr += pVCpu->cpum.GstCtx.bp + pVCpu->cpum.GstCtx.di; SET_SS_DEF(); break;707 case 4: u16EffAddr += pVCpu->cpum.GstCtx.si; break;708 case 5: u16EffAddr += pVCpu->cpum.GstCtx.di; break;709 case 6: u16EffAddr += pVCpu->cpum.GstCtx.bp; SET_SS_DEF(); break;710 case 7: u16EffAddr += pVCpu->cpum.GstCtx.bx; break;711 }712 }713 714 *pGCPtrEff = u16EffAddr;715 }716 else717 {718 Assert(pVCpu->iem.s.enmEffAddrMode == IEMMODE_32BIT);719 uint32_t u32EffAddr;720 721 /* Handle the disp32 form with no registers first. */722 if ((bRm & (X86_MODRM_MOD_MASK | X86_MODRM_RM_MASK)) == 5)723 {724 IEM_OPCODE_GET_NEXT_U32(&u32EffAddr);725 uInfo = u32EffAddr;726 }727 else728 {729 /* Get the register (or SIB) value. */730 uInfo = 0;731 switch ((bRm & X86_MODRM_RM_MASK))732 {733 case 0: u32EffAddr = pVCpu->cpum.GstCtx.eax; break;734 case 1: u32EffAddr = pVCpu->cpum.GstCtx.ecx; break;735 case 2: u32EffAddr = pVCpu->cpum.GstCtx.edx; break;736 case 3: u32EffAddr = pVCpu->cpum.GstCtx.ebx; break;737 case 4: /* SIB */738 {739 uint8_t bSib; IEM_OPCODE_GET_NEXT_U8(&bSib);740 uInfo = (uint64_t)bSib << 32;741 742 /* Get the index and scale it. */743 switch ((bSib >> X86_SIB_INDEX_SHIFT) & X86_SIB_INDEX_SMASK)744 {745 case 0: u32EffAddr = pVCpu->cpum.GstCtx.eax; break;746 case 1: u32EffAddr = pVCpu->cpum.GstCtx.ecx; break;747 case 2: u32EffAddr = pVCpu->cpum.GstCtx.edx; break;748 case 3: u32EffAddr = pVCpu->cpum.GstCtx.ebx; break;749 case 4: u32EffAddr = 0; /*none */ break;750 case 5: u32EffAddr = pVCpu->cpum.GstCtx.ebp; break;751 case 6: u32EffAddr = pVCpu->cpum.GstCtx.esi; break;752 case 7: u32EffAddr = pVCpu->cpum.GstCtx.edi; break;753 IEM_NOT_REACHED_DEFAULT_CASE_RET();754 }755 u32EffAddr <<= (bSib >> X86_SIB_SCALE_SHIFT) & X86_SIB_SCALE_SMASK;756 757 /* add base */758 switch (bSib & X86_SIB_BASE_MASK)759 {760 case 0: u32EffAddr += pVCpu->cpum.GstCtx.eax; break;761 case 1: u32EffAddr += pVCpu->cpum.GstCtx.ecx; break;762 case 2: u32EffAddr += pVCpu->cpum.GstCtx.edx; break;763 case 3: u32EffAddr += pVCpu->cpum.GstCtx.ebx; break;764 case 4: u32EffAddr += pVCpu->cpum.GstCtx.esp + (cbImmAndRspOffset >> 8); SET_SS_DEF(); break;765 case 5:766 if ((bRm & X86_MODRM_MOD_MASK) != 0)767 {768 u32EffAddr += pVCpu->cpum.GstCtx.ebp;769 SET_SS_DEF();770 }771 else772 {773 uint32_t u32Disp;774 IEM_OPCODE_GET_NEXT_U32(&u32Disp);775 u32EffAddr += u32Disp;776 uInfo |= u32Disp;777 }778 break;779 case 6: u32EffAddr += pVCpu->cpum.GstCtx.esi; break;780 case 7: u32EffAddr += pVCpu->cpum.GstCtx.edi; break;781 IEM_NOT_REACHED_DEFAULT_CASE_RET();782 }783 break;784 }785 case 5: u32EffAddr = pVCpu->cpum.GstCtx.ebp; SET_SS_DEF(); break;786 case 6: u32EffAddr = pVCpu->cpum.GstCtx.esi; break;787 case 7: u32EffAddr = pVCpu->cpum.GstCtx.edi; break;788 IEM_NOT_REACHED_DEFAULT_CASE_RET();789 }790 791 /* Get and add the displacement. */792 switch ((bRm >> X86_MODRM_MOD_SHIFT) & X86_MODRM_MOD_SMASK)793 {794 case 0:795 break;796 case 1:797 {798 int8_t i8Disp; IEM_OPCODE_GET_NEXT_S8(&i8Disp);799 u32EffAddr += i8Disp;800 uInfo |= (uint32_t)(int32_t)i8Disp;801 break;802 }803 case 2:804 {805 uint32_t u32Disp; IEM_OPCODE_GET_NEXT_U32(&u32Disp);806 u32EffAddr += u32Disp;807 uInfo |= (uint32_t)u32Disp;808 break;809 }810 default:811 AssertFailedReturn(VERR_IEM_IPE_2); /* (caller checked for these) */812 }813 814 }815 Assert(pVCpu->iem.s.enmEffAddrMode == IEMMODE_32BIT);816 *pGCPtrEff = u32EffAddr;817 }818 }819 else820 {821 uint64_t u64EffAddr;822 823 /* Handle the rip+disp32 form with no registers first. */824 if ((bRm & (X86_MODRM_MOD_MASK | X86_MODRM_RM_MASK)) == 5)825 {826 IEM_OPCODE_GET_NEXT_S32_SX_U64(&u64EffAddr);827 uInfo = (uint32_t)u64EffAddr;828 u64EffAddr += pVCpu->cpum.GstCtx.rip + IEM_GET_INSTR_LEN(pVCpu) + (cbImmAndRspOffset & UINT32_C(0xff));829 }830 else831 {832 /* Get the register (or SIB) value. */833 uInfo = 0;834 switch ((bRm & X86_MODRM_RM_MASK) | pVCpu->iem.s.uRexB)835 {836 case 0: u64EffAddr = pVCpu->cpum.GstCtx.rax; break;837 case 1: u64EffAddr = pVCpu->cpum.GstCtx.rcx; break;838 case 2: u64EffAddr = pVCpu->cpum.GstCtx.rdx; break;839 case 3: u64EffAddr = pVCpu->cpum.GstCtx.rbx; break;840 case 5: u64EffAddr = pVCpu->cpum.GstCtx.rbp; SET_SS_DEF(); break;841 case 6: u64EffAddr = pVCpu->cpum.GstCtx.rsi; break;842 case 7: u64EffAddr = pVCpu->cpum.GstCtx.rdi; break;843 case 8: u64EffAddr = pVCpu->cpum.GstCtx.r8; break;844 case 9: u64EffAddr = pVCpu->cpum.GstCtx.r9; break;845 case 10: u64EffAddr = pVCpu->cpum.GstCtx.r10; break;846 case 11: u64EffAddr = pVCpu->cpum.GstCtx.r11; break;847 case 13: u64EffAddr = pVCpu->cpum.GstCtx.r13; break;848 case 14: u64EffAddr = pVCpu->cpum.GstCtx.r14; break;849 case 15: u64EffAddr = pVCpu->cpum.GstCtx.r15; break;850 /* SIB */851 case 4:852 case 12:853 {854 uint8_t bSib; IEM_OPCODE_GET_NEXT_U8(&bSib);855 uInfo = (uint64_t)bSib << 32;856 857 /* Get the index and scale it. */858 switch (((bSib >> X86_SIB_INDEX_SHIFT) & X86_SIB_INDEX_SMASK) | pVCpu->iem.s.uRexIndex)859 {860 case 0: u64EffAddr = pVCpu->cpum.GstCtx.rax; break;861 case 1: u64EffAddr = pVCpu->cpum.GstCtx.rcx; break;862 case 2: u64EffAddr = pVCpu->cpum.GstCtx.rdx; break;863 case 3: u64EffAddr = pVCpu->cpum.GstCtx.rbx; break;864 case 4: u64EffAddr = 0; /*none */ break;865 case 5: u64EffAddr = pVCpu->cpum.GstCtx.rbp; break;866 case 6: u64EffAddr = pVCpu->cpum.GstCtx.rsi; break;867 case 7: u64EffAddr = pVCpu->cpum.GstCtx.rdi; break;868 case 8: u64EffAddr = pVCpu->cpum.GstCtx.r8; break;869 case 9: u64EffAddr = pVCpu->cpum.GstCtx.r9; break;870 case 10: u64EffAddr = pVCpu->cpum.GstCtx.r10; break;871 case 11: u64EffAddr = pVCpu->cpum.GstCtx.r11; break;872 case 12: u64EffAddr = pVCpu->cpum.GstCtx.r12; break;873 case 13: u64EffAddr = pVCpu->cpum.GstCtx.r13; break;874 case 14: u64EffAddr = pVCpu->cpum.GstCtx.r14; break;875 case 15: u64EffAddr = pVCpu->cpum.GstCtx.r15; break;876 IEM_NOT_REACHED_DEFAULT_CASE_RET();877 }878 u64EffAddr <<= (bSib >> X86_SIB_SCALE_SHIFT) & X86_SIB_SCALE_SMASK;879 880 /* add base */881 switch ((bSib & X86_SIB_BASE_MASK) | pVCpu->iem.s.uRexB)882 {883 case 0: u64EffAddr += pVCpu->cpum.GstCtx.rax; break;884 case 1: u64EffAddr += pVCpu->cpum.GstCtx.rcx; break;885 case 2: u64EffAddr += pVCpu->cpum.GstCtx.rdx; break;886 case 3: u64EffAddr += pVCpu->cpum.GstCtx.rbx; break;887 case 4: u64EffAddr += pVCpu->cpum.GstCtx.rsp + (cbImmAndRspOffset >> 8); SET_SS_DEF(); break;888 case 6: u64EffAddr += pVCpu->cpum.GstCtx.rsi; break;889 case 7: u64EffAddr += pVCpu->cpum.GstCtx.rdi; break;890 case 8: u64EffAddr += pVCpu->cpum.GstCtx.r8; break;891 case 9: u64EffAddr += pVCpu->cpum.GstCtx.r9; break;892 case 10: u64EffAddr += pVCpu->cpum.GstCtx.r10; break;893 case 11: u64EffAddr += pVCpu->cpum.GstCtx.r11; break;894 case 12: u64EffAddr += pVCpu->cpum.GstCtx.r12; break;895 case 14: u64EffAddr += pVCpu->cpum.GstCtx.r14; break;896 case 15: u64EffAddr += pVCpu->cpum.GstCtx.r15; break;897 /* complicated encodings */898 case 5:899 case 13:900 if ((bRm & X86_MODRM_MOD_MASK) != 0)901 {902 if (!pVCpu->iem.s.uRexB)903 {904 u64EffAddr += pVCpu->cpum.GstCtx.rbp;905 SET_SS_DEF();906 }907 else908 u64EffAddr += pVCpu->cpum.GstCtx.r13;909 }910 else911 {912 uint32_t u32Disp;913 IEM_OPCODE_GET_NEXT_U32(&u32Disp);914 u64EffAddr += (int32_t)u32Disp;915 uInfo |= u32Disp;916 }917 break;918 IEM_NOT_REACHED_DEFAULT_CASE_RET();919 }920 break;921 }922 IEM_NOT_REACHED_DEFAULT_CASE_RET();923 }924 925 /* Get and add the displacement. */926 switch ((bRm >> X86_MODRM_MOD_SHIFT) & X86_MODRM_MOD_SMASK)927 {928 case 0:929 break;930 case 1:931 {932 int8_t i8Disp;933 IEM_OPCODE_GET_NEXT_S8(&i8Disp);934 u64EffAddr += i8Disp;935 uInfo |= (uint32_t)(int32_t)i8Disp;936 break;937 }938 case 2:939 {940 uint32_t u32Disp;941 IEM_OPCODE_GET_NEXT_U32(&u32Disp);942 u64EffAddr += (int32_t)u32Disp;943 uInfo |= u32Disp;944 break;945 }946 IEM_NOT_REACHED_DEFAULT_CASE_RET(); /* (caller checked for these) */947 }948 949 }950 951 if (pVCpu->iem.s.enmEffAddrMode == IEMMODE_64BIT)952 *pGCPtrEff = u64EffAddr;953 else954 {955 Assert(pVCpu->iem.s.enmEffAddrMode == IEMMODE_32BIT);956 *pGCPtrEff = u64EffAddr & UINT32_MAX;957 }958 }959 *puInfo = uInfo;960 961 Log5(("iemOpHlpCalcRmEffAddrEx: EffAddr=%#010RGv uInfo=%RX64\n", *pGCPtrEff, uInfo));962 return VINF_SUCCESS;963 }964 347 965 348 /** @} */
Note:
See TracChangeset
for help on using the changeset viewer.