cc2c73ddcb4370a7c3ad439cda4da825156c26c9's three-cent titanium tax
doesn't go too far enough.  Fix the rest of the call and jmp
instructions to handle the data prefix correctly.

Reference: Intel 64 and IA-32 Architectures Software Developer's Manual
Volume 2A: Instruction Set Reference, A-M

http://www.intel.com/Assets/PDF/manual/253666.pdf

Signed-off-by: Adam Jackson <[email protected]>
---
 hw/xfree86/x86emu/ops.c |   63 +++++++++++++++++++++++++++++++++-------------
 1 files changed, 45 insertions(+), 18 deletions(-)

diff --git a/hw/xfree86/x86emu/ops.c b/hw/xfree86/x86emu/ops.c
index c6b2f0a..5d3cac1 100644
--- a/hw/xfree86/x86emu/ops.c
+++ b/hw/xfree86/x86emu/ops.c
@@ -7065,15 +7065,20 @@ Handles opcode 0x9a
 ****************************************************************************/
 static void x86emuOp_call_far_IMM(u8 X86EMU_UNUSED(op1))
 {
-    u16 farseg, faroff;
+    u32 farseg, faroff;
 
     START_OF_INSTR();
-       DECODE_PRINTF("CALL\t");
+    DECODE_PRINTF("CALL\t");
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+       faroff = fetch_long_imm();
+       farseg = fetch_word_imm();
+    } else {
        faroff = fetch_word_imm();
        farseg = fetch_word_imm();
-       DECODE_PRINTF2("%04x:", farseg);
-       DECODE_PRINTF2("%04x\n", faroff);
-       CALL_TRACE(M.x86.saved_cs, M.x86.saved_ip, farseg, faroff, "FAR ");
+    }
+    DECODE_PRINTF2("%04x:", farseg);
+    DECODE_PRINTF2("%04x\n", faroff);
+    CALL_TRACE(M.x86.saved_cs, M.x86.saved_ip, farseg, faroff, "FAR ");
 
     /* XXX
      * 
@@ -7084,8 +7089,12 @@ static void x86emuOp_call_far_IMM(u8 X86EMU_UNUSED(op1))
     TRACE_AND_STEP();
     push_word(M.x86.R_CS);
     M.x86.R_CS = farseg;
-    push_word(M.x86.R_IP);
-    M.x86.R_IP = faroff;
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+       push_long(M.x86.R_EIP);
+    } else {
+       push_word(M.x86.R_IP);
+    }
+    M.x86.R_EIP = faroff & 0xffff;
     DECODE_CLEAR_SEGOVR();
     END_OF_INSTR();
 }
@@ -9670,17 +9679,30 @@ Handles opcode 0xe8
 ****************************************************************************/
 static void x86emuOp_call_near_IMM(u8 X86EMU_UNUSED(op1))
 {
-    s16 ip;
+    s16 ip16;
+    s32 ip32;
 
     START_OF_INSTR();
-       DECODE_PRINTF("CALL\t");
-       ip = (s16) fetch_word_imm();
-       ip += (s16) M.x86.R_IP;    /* CHECK SIGN */
-       DECODE_PRINTF2("%04x\n", (u16)ip);
-       CALL_TRACE(M.x86.saved_cs, M.x86.saved_ip, M.x86.R_CS, ip, "");
+    DECODE_PRINTF("CALL\t");
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+       ip32 = (s32) fetch_long_imm();
+       ip32 += (s16) M.x86.R_IP;    /* CHECK SIGN */
+       DECODE_PRINTF2("%04x\n", (u16)ip32);
+       CALL_TRACE(M.x86.saved_cs, M.x86.saved_ip, M.x86.R_CS, ip32, "");
+    } else {
+       ip16 = (s16) fetch_word_imm();
+       ip16 += (s16) M.x86.R_IP;    /* CHECK SIGN */
+       DECODE_PRINTF2("%04x\n", (u16)ip16);
+       CALL_TRACE(M.x86.saved_cs, M.x86.saved_ip, M.x86.R_CS, ip16, "");
+    }
     TRACE_AND_STEP();
-    push_word(M.x86.R_IP);
-    M.x86.R_IP = ip;
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+       push_long(M.x86.R_EIP);
+       M.x86.R_EIP = ip32 & 0xffff;
+    } else {
+       push_word(M.x86.R_IP);
+       M.x86.R_EIP = ip16;
+    }
     DECODE_CLEAR_SEGOVR();
     END_OF_INSTR();
 }
@@ -9718,16 +9740,21 @@ Handles opcode 0xea
 ****************************************************************************/
 static void x86emuOp_jump_far_IMM(u8 X86EMU_UNUSED(op1))
 {
-    u16 cs, ip;
+    u16 cs;
+    u32 ip;
 
     START_OF_INSTR();
     DECODE_PRINTF("JMP\tFAR ");
-    ip = fetch_word_imm();
+    if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+       ip = fetch_long_imm();
+    } else {
+       ip = fetch_word_imm();
+    }
     cs = fetch_word_imm();
     DECODE_PRINTF2("%04x:", cs);
     DECODE_PRINTF2("%04x\n", ip);
     TRACE_AND_STEP();
-    M.x86.R_IP = ip;
+    M.x86.R_EIP = ip & 0xffff;
     M.x86.R_CS = cs;
     DECODE_CLEAR_SEGOVR();
     END_OF_INSTR();
-- 
1.7.3.2

_______________________________________________
[email protected]: X.Org development
Archives: http://lists.x.org/archives/xorg-devel
Info: http://lists.x.org/mailman/listinfo/xorg-devel

Reply via email to