diff options
author | Christian Zander <chzander@nvidia.com> | 2010-01-11 12:29:07 -0800 |
---|---|---|
committer | Keith Packard <keithp@keithp.com> | 2010-01-27 13:48:37 -0800 |
commit | f57bc0ede8e018c7e264b917927c42a018cd1d5a (patch) | |
tree | 13667ff117341947d73b86ea8fcac93331a8490e /hw/xfree86/x86emu | |
parent | 2984c18eb994696927a7f3b94d86fd47907334a0 (diff) |
x86emu: Respect the LEA 67h address size prefix.
Signed-off-by: Christian Zander <chzander@nvidia.com>
Signed-off-by: Aaron Plattner <aplattner@nvidia.com>
Tested-by: Tiago Vignatti <tiago.vignatti@nokia.com>
Signed-off-by: Keith Packard <keithp@keithp.com>
Diffstat (limited to 'hw/xfree86/x86emu')
-rw-r--r-- | hw/xfree86/x86emu/ops.c | 70 |
1 files changed, 45 insertions, 25 deletions
diff --git a/hw/xfree86/x86emu/ops.c b/hw/xfree86/x86emu/ops.c index 37ae2c9c9..21a034712 100644 --- a/hw/xfree86/x86emu/ops.c +++ b/hw/xfree86/x86emu/ops.c @@ -6567,42 +6567,62 @@ Handles opcode 0x8d static void x86emuOp_lea_word_R_M(u8 X86EMU_UNUSED(op1)) { int mod, rl, rh; - u16 *srcreg; uint destoffset; -/* - * TODO: Need to handle address size prefix! - * - * lea eax,[eax+ebx*2] ?? - */ - START_OF_INSTR(); DECODE_PRINTF("LEA\t"); FETCH_DECODE_MODRM(mod, rh, rl); switch (mod) { case 0: - srcreg = DECODE_RM_WORD_REGISTER(rh); - DECODE_PRINTF(","); - destoffset = decode_rm00_address(rl); - DECODE_PRINTF("\n"); - TRACE_AND_STEP(); - *srcreg = (u16)destoffset; + if (M.x86.mode & SYSMODE_PREFIX_ADDR) { + u32 *srcreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF(","); + destoffset = decode_rm00_address(rl); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *srcreg = (u32)destoffset; + } else { + u16 *srcreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF(","); + destoffset = decode_rm00_address(rl); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *srcreg = (u16)destoffset; + } break; case 1: - srcreg = DECODE_RM_WORD_REGISTER(rh); - DECODE_PRINTF(","); - destoffset = decode_rm01_address(rl); - DECODE_PRINTF("\n"); - TRACE_AND_STEP(); - *srcreg = (u16)destoffset; + if (M.x86.mode & SYSMODE_PREFIX_ADDR) { + u32 *srcreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF(","); + destoffset = decode_rm01_address(rl); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *srcreg = (u32)destoffset; + } else { + u16 *srcreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF(","); + destoffset = decode_rm01_address(rl); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *srcreg = (u16)destoffset; + } break; case 2: - srcreg = DECODE_RM_WORD_REGISTER(rh); - DECODE_PRINTF(","); - destoffset = decode_rm10_address(rl); - DECODE_PRINTF("\n"); - TRACE_AND_STEP(); - *srcreg = (u16)destoffset; + if (M.x86.mode & SYSMODE_PREFIX_ADDR) { + u32 *srcreg = DECODE_RM_LONG_REGISTER(rh); + DECODE_PRINTF(","); + destoffset = decode_rm10_address(rl); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *srcreg = (u32)destoffset; + } else { + u16 *srcreg = DECODE_RM_WORD_REGISTER(rh); + DECODE_PRINTF(","); + destoffset = decode_rm10_address(rl); + DECODE_PRINTF("\n"); + TRACE_AND_STEP(); + *srcreg = (u16)destoffset; + } break; case 3: /* register to register */ /* undefined. Do nothing. */ |