[PATCH] x86emu: Correctly handle 0x66 prefix for some instructions

Guillem Jover guillem at hadrons.org
Wed Mar 7 05:46:02 PST 2012


Hi!

On Mon, 2012-03-05 at 17:49:08 +0000, Julian Pidancet wrote:
> diff --git a/hw/xfree86/x86emu/ops.c b/hw/xfree86/x86emu/ops.c
> index 5d3cac1..440b8dc 100644
> --- a/hw/xfree86/x86emu/ops.c
> +++ b/hw/xfree86/x86emu/ops.c
> @@ -8787,11 +8795,16 @@ static void x86emuOp_enter(u8 X86EMU_UNUSED(op1))
>      frame_pointer = M.x86.R_SP;
>      if (nesting > 0) {
>          for (i = 1; i < nesting; i++) {
> -            M.x86.R_BP -= 2;
> -            push_word(fetch_data_word_abs(M.x86.R_SS, M.x86.R_BP));
> +            if (M.x86.mode & SYSMODE_PREFIX_DATA) {
> +                M.x86.R_EBP -= 4;
> +                push_long(fetch_data_long_abs(M.x86.R_SS, M.x86.R_BP));

Shouldn't this be:

  push_long(fetch_data_long_abs(M.x86.R_SS, M.x86.R_EBP))

?

> +            } else {
> +                M.x86.R_BP -= 2;
> +                push_word(fetch_data_word_abs(M.x86.R_SS, M.x86.R_BP));
>              }
> -        push_word(frame_pointer);
>          }
> +        push_word(frame_pointer);
> +    }
>      M.x86.R_BP = frame_pointer;
>      M.x86.R_SP = (u16)(M.x86.R_SP - local);
>      DECODE_CLEAR_SEGOVR();


> @@ -8827,8 +8844,13 @@ static void x86emuOp_ret_far_IMM(u8 X86EMU_UNUSED(op1))
>      DECODE_PRINTF2("%x\n", imm);
>  	RETURN_TRACE("RETF",M.x86.saved_cs,M.x86.saved_ip);
>  	TRACE_AND_STEP();
> -    M.x86.R_IP = pop_word();
> -    M.x86.R_CS = pop_word();
> +    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
> +        M.x86.R_IP = pop_long();
> +        M.x86.R_CS = pop_long() & 0xffff;
> +    } else {
> +        M.x86.R_IP = pop_word();
> +        M.x86.R_CS = pop_word();
> +    }
>      M.x86.R_SP += imm;
>      DECODE_CLEAR_SEGOVR();
>      END_OF_INSTR();
> @@ -8844,8 +8866,13 @@ static void x86emuOp_ret_far(u8 X86EMU_UNUSED(op1))
>      DECODE_PRINTF("RETF\n");
>  	RETURN_TRACE("RETF",M.x86.saved_cs,M.x86.saved_ip);
>  	TRACE_AND_STEP();
> -    M.x86.R_IP = pop_word();
> -    M.x86.R_CS = pop_word();
> +    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
> +        M.x86.R_IP = pop_long();
> +        M.x86.R_CS = pop_long() & 0xffff;
> +    } else {
> +        M.x86.R_IP = pop_word();
> +        M.x86.R_CS = pop_word();
> +    }
>      DECODE_CLEAR_SEGOVR();
>      END_OF_INSTR();
>  }
> @@ -8939,9 +8966,15 @@ static void x86emuOp_iret(u8 X86EMU_UNUSED(op1))
>  
>      TRACE_AND_STEP();
>  
> -    M.x86.R_IP = pop_word();
> -    M.x86.R_CS = pop_word();
> -    M.x86.R_FLG = pop_word();
> +    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
> +        M.x86.R_IP = pop_long();
> +        M.x86.R_CS = pop_long() & 0xffff;
> +        M.x86.R_FLG = pop_long();
> +    } else {
> +        M.x86.R_IP = pop_word();
> +        M.x86.R_CS = pop_word();
> +        M.x86.R_FLG = pop_word();
> +    }
>      DECODE_CLEAR_SEGOVR();
>      END_OF_INSTR();
>  }

On these three hunks, when on 32-bit mode shouldn't the registers be
M.x86.R_EIP and M.x86.R_EFLG?

regards,
guillem


More information about the xorg-devel mailing list