aboutsummaryrefslogtreecommitdiffstats
path: root/util/vgabios
diff options
context:
space:
mode:
authorLi-Ta Lo <ollie@lanl.gov>2005-01-11 03:18:39 +0000
committerLi-Ta Lo <ollie@lanl.gov>2005-01-11 03:18:39 +0000
commit8b0356c2c9136493f79d9faddbda1bfac7ca687e (patch)
tree87b1de0d55fec22946177cd4d7d73987fca346d5 /util/vgabios
parent3678ad8e38abee296221cd33e2cbc1e5181f715f (diff)
downloadcoreboot-8b0356c2c9136493f79d9faddbda1bfac7ca687e.tar.gz
coreboot-8b0356c2c9136493f79d9faddbda1bfac7ca687e.tar.xz
coreboot-8b0356c2c9136493f79d9faddbda1bfac7ca687e.zip
use Paulo's reduced version
git-svn-id: svn://svn.coreboot.org/coreboot/trunk@1853 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
Diffstat (limited to 'util/vgabios')
-rw-r--r--util/vgabios/helper_exec.c17
-rw-r--r--util/vgabios/int10.c4
-rw-r--r--util/vgabios/int15.c2
-rw-r--r--util/vgabios/int1a.c2
-rw-r--r--util/vgabios/pci-userspace.c14
-rw-r--r--util/vgabios/testbios.c6
-rwxr-xr-xutil/vgabios/x86emu/include/x86emu.h2
-rw-r--r--util/vgabios/x86emu/src/x86emu/debug.c676
-rw-r--r--util/vgabios/x86emu/src/x86emu/decode.c1177
-rw-r--r--util/vgabios/x86emu/src/x86emu/fpu.c1589
-rw-r--r--util/vgabios/x86emu/src/x86emu/makefile2
-rw-r--r--util/vgabios/x86emu/src/x86emu/makefile.linux34
-rw-r--r--util/vgabios/x86emu/src/x86emu/ops.c14321
-rw-r--r--util/vgabios/x86emu/src/x86emu/ops2.c3660
-rw-r--r--util/vgabios/x86emu/src/x86emu/prim_ops.c3628
-rw-r--r--util/vgabios/x86emu/src/x86emu/sys.c2
-rw-r--r--util/vgabios/x86emu/src/x86emu/validate.c398
-rwxr-xr-xutil/vgabios/x86emu/src/x86emu/x86emu/debug.h157
-rwxr-xr-xutil/vgabios/x86emu/src/x86emu/x86emu/decode.h37
-rwxr-xr-xutil/vgabios/x86emu/src/x86emu/x86emu/fpu.h16
-rwxr-xr-xutil/vgabios/x86emu/src/x86emu/x86emu/ops.h12
-rwxr-xr-xutil/vgabios/x86emu/src/x86emu/x86emu/prim_asm.h2598
-rwxr-xr-xutil/vgabios/x86emu/src/x86emu/x86emu/prim_ops.h111
-rwxr-xr-xutil/vgabios/x86emu/src/x86emu/x86emu/x86emui.h54
24 files changed, 10919 insertions, 17600 deletions
diff --git a/util/vgabios/helper_exec.c b/util/vgabios/helper_exec.c
index ee03f4eca..8d18798c4 100644
--- a/util/vgabios/helper_exec.c
+++ b/util/vgabios/helper_exec.c
@@ -50,8 +50,8 @@ int run_bios_int(int num)
X86_CS = MEM_RW((num << 2) + 2);
X86_IP = MEM_RW(num << 2);
- //printf("%s: INT %x CS:IP = %x:%x\n", __FUNCTION__,
- // num, MEM_RW((num << 2) + 2), MEM_RW(num << 2));
+ printf("%s: INT %x CS:IP = %x:%x\n", __FUNCTION__,
+ num, MEM_RW((num << 2) + 2), MEM_RW(num << 2));
return 1;
}
@@ -128,7 +128,7 @@ u8 x_inb(u16 port)
val = inb(port);
- //printf("inb(0x%04x) = 0x%02x\n", port, val);
+ printf("inb(0x%04x) = 0x%02x\n", port, val);
return val;
}
@@ -139,7 +139,7 @@ u16 x_inw(u16 port)
val = inw(port);
- //printf("inw(0x%04x) = 0x%04x\n", port, val);
+ printf("inw(0x%04x) = 0x%04x\n", port, val);
return val;
}
@@ -149,25 +149,26 @@ u32 x_inl(u16 port)
val = inl(port);
- //printf("inl(0x%04x) = 0x%08x\n", port, val);
+ printf("inl(0x%04x) = 0x%08x\n", port, val);
return val;
}
void x_outb(u16 port, u8 val)
{
- //printf("outb(0x%02x, 0x%04x)\n", val, port);
+ printf("outb(0x%02x, 0x%04x)\n",
+ val, port);
outb(val, port);
}
void x_outw(u16 port, u16 val)
{
- //printf("outw(0x%04x, 0x%04x)\n", val, port);
+ printf("outw(0x%04x, 0x%04x)\n", val, port);
outw(val, port);
}
void x_outl(u16 port, u32 val)
{
- //printf("outl(0x%08x, 0x%04x)\n", val, port);
+ printf("outl(0x%08x, 0x%04x)\n", val, port);
outl(val, port);
}
diff --git a/util/vgabios/int10.c b/util/vgabios/int10.c
index 702be4f39..bccb3d995 100644
--- a/util/vgabios/int10.c
+++ b/util/vgabios/int10.c
@@ -18,7 +18,7 @@ extern int verbose;
*/
int int42_handler()
{
-
+#if 0
if (verbose && X86_AH != 0x0e) {
printf("int%x\n", current->num);
x86emu_dump_xregs();
@@ -472,7 +472,7 @@ int int42_handler()
/* Ignored */
break;
}
-
+#endif
return 1;
}
#endif
diff --git a/util/vgabios/int15.c b/util/vgabios/int15.c
index 59af923ad..239b6beef 100644
--- a/util/vgabios/int15.c
+++ b/util/vgabios/int15.c
@@ -6,7 +6,7 @@ void x86emu_dump_xregs();
int int15_handler(void)
{
printf("\nint15 encountered.\n");
- x86emu_dump_xregs();
+ //x86emu_dump_xregs();
X86_EAX = 0;
return 1;
}
diff --git a/util/vgabios/int1a.c b/util/vgabios/int1a.c
index 48aa13e9a..bd9a24c9f 100644
--- a/util/vgabios/int1a.c
+++ b/util/vgabios/int1a.c
@@ -19,7 +19,7 @@ int int1A_handler()
if (verbose) {
printf("\nint1a encountered.\n");
- x86emu_dump_xregs();
+ //x86emu_dump_xregs();
}
switch (X86_AX) {
diff --git a/util/vgabios/pci-userspace.c b/util/vgabios/pci-userspace.c
index aea3f6983..f09c167ce 100644
--- a/util/vgabios/pci-userspace.c
+++ b/util/vgabios/pci-userspace.c
@@ -44,7 +44,7 @@ PCITAG findPci(unsigned short bx)
tag->slot = slot;
tag->func = func;
- if (pci_get_dev(pacc, bus, slot, func))
+ if (pci_get_dev(pacc, 0, bus, slot, func))
return tag;
return NULL;
@@ -58,7 +58,7 @@ u32 pciSlotBX(PCITAG tag)
u8 pciReadByte(PCITAG tag, u32 idx)
{
struct pci_dev *d;
- if ((d = pci_get_dev(pacc, tag->bus, tag->slot, tag->func)))
+ if ((d = pci_get_dev(pacc, 0, tag->bus, tag->slot, tag->func)))
return pci_read_byte(d, idx);
#ifdef DEBUG_PCI
printf("PCI: device not found while read byte (%x:%x.%x)\n",
@@ -70,7 +70,7 @@ u8 pciReadByte(PCITAG tag, u32 idx)
u16 pciReadWord(PCITAG tag, u32 idx)
{
struct pci_dev *d;
- if ((d = pci_get_dev(pacc, tag->bus, tag->slot, tag->func)))
+ if ((d = pci_get_dev(pacc, 0, tag->bus, tag->slot, tag->func)))
return pci_read_word(d, idx);
#ifdef DEBUG_PCI
printf("PCI: device not found while read word (%x:%x.%x)\n",
@@ -82,7 +82,7 @@ u16 pciReadWord(PCITAG tag, u32 idx)
u32 pciReadLong(PCITAG tag, u32 idx)
{
struct pci_dev *d;
- if ((d = pci_get_dev(pacc, tag->bus, tag->slot, tag->func)))
+ if ((d = pci_get_dev(pacc, 0, tag->bus, tag->slot, tag->func)))
return pci_read_long(d, idx);
#ifdef DEBUG_PCI
printf("PCI: device not found while read long (%x:%x.%x)\n",
@@ -95,7 +95,7 @@ u32 pciReadLong(PCITAG tag, u32 idx)
void pciWriteLong(PCITAG tag, u32 idx, u32 data)
{
struct pci_dev *d;
- if ((d = pci_get_dev(pacc, tag->bus, tag->slot, tag->func)))
+ if ((d = pci_get_dev(pacc, 0, tag->bus, tag->slot, tag->func)))
pci_write_long(d, idx, data);
#ifdef DEBUG_PCI
else
@@ -107,7 +107,7 @@ void pciWriteLong(PCITAG tag, u32 idx, u32 data)
void pciWriteWord(PCITAG tag, u32 idx, u16 data)
{
struct pci_dev *d;
- if ((d = pci_get_dev(pacc, tag->bus, tag->slot, tag->func)))
+ if ((d = pci_get_dev(pacc, 0, tag->bus, tag->slot, tag->func)))
pci_write_word(d, idx, data);
#ifdef DEBUG_PCI
else
@@ -120,7 +120,7 @@ void pciWriteWord(PCITAG tag, u32 idx, u16 data)
void pciWriteByte(PCITAG tag, u32 idx, u8 data)
{
struct pci_dev *d;
- if ((d = pci_get_dev(pacc, tag->bus, tag->slot, tag->func)))
+ if ((d = pci_get_dev(pacc, 0, tag->bus, tag->slot, tag->func)))
pci_write_long(d, idx, data);
#ifdef DEBUG_PCI
else
diff --git a/util/vgabios/testbios.c b/util/vgabios/testbios.c
index 541f46058..9ffdd068e 100644
--- a/util/vgabios/testbios.c
+++ b/util/vgabios/testbios.c
@@ -76,7 +76,7 @@ void do_int(int num)
if (!ret) {
printf("\nint%x: not implemented\n", num);
- x86emu_dump_xregs();
+ //x86emu_dump_xregs();
}
}
@@ -317,10 +317,10 @@ int main(int argc, char **argv)
if (trace) {
printf("Switching to single step mode.\n");
- X86EMU_trace_on();
+ //X86EMU_trace_on();
}
if (debugflag) {
- X86EMU_set_debug(debugflag);
+ //X86EMU_set_debug(debugflag);
}
X86EMU_exec();
/* Cleaning up */
diff --git a/util/vgabios/x86emu/include/x86emu.h b/util/vgabios/x86emu/include/x86emu.h
index 24d958899..6ddf39e24 100755
--- a/util/vgabios/x86emu/include/x86emu.h
+++ b/util/vgabios/x86emu/include/x86emu.h
@@ -181,6 +181,8 @@ void X86EMU_halt_sys(void);
#define DEBUG_TRACECALL_REGS_F 0x004000
#define DEBUG_DECODE_NOPRINT_F 0x008000
#define DEBUG_SAVE_IP_CS_F 0x010000
+#define DEBUG_EXIT 0x020000
+#define DEBUG_SAVE_CS_IP 0x040000
#define DEBUG_SYS_F (DEBUG_SVC_F|DEBUG_FS_F|DEBUG_PROC_F)
void X86EMU_trace_regs(void);
diff --git a/util/vgabios/x86emu/src/x86emu/debug.c b/util/vgabios/x86emu/src/x86emu/debug.c
index af2b77a82..b69b86f8b 100644
--- a/util/vgabios/x86emu/src/x86emu/debug.c
+++ b/util/vgabios/x86emu/src/x86emu/debug.c
@@ -1,10 +1,10 @@
/****************************************************************************
*
-* Realmode X86 Emulator Library
+* Realmode X86 Emulator Library
*
-* Copyright (C) 1996-1999 SciTech Software, Inc.
-* Copyright (C) David Mosberger-Tang
-* Copyright (C) 1999 Egbert Eich
+* Copyright (C) 1991-2004 SciTech Software, Inc.
+* Copyright (C) David Mosberger-Tang
+* Copyright (C) 1999 Egbert Eich
*
* ========================================================================
*
@@ -28,444 +28,398 @@
*
* ========================================================================
*
-* Language: ANSI C
-* Environment: Any
+* Language: ANSI C
+* Environment: Any
* Developer: Kendall Bennett
*
* Description: This file contains the code to handle debugging of the
-* emulator.
+* emulator.
*
****************************************************************************/
-/* $XFree86: xc/extras/x86emu/src/x86emu/debug.c,v 1.4 2000/04/17 16:29:45 eich Exp $ */
#include "x86emu/x86emui.h"
-#ifdef IN_MODULE
-#include "xf86_ansic.h"
-#else
#include <stdarg.h>
-#include <stdlib.h>
-#endif
/*----------------------------- Implementation ----------------------------*/
#ifdef DEBUG
-static void print_encoded_bytes(u16 s, u16 o);
-static void print_decoded_instruction(void);
-static int parse_line(char *s, int *ps, int *n);
+static void print_encoded_bytes (u16 s, u16 o);
+static void print_decoded_instruction (void);
+static int parse_line (char *s, int *ps, int *n);
/* should look something like debug's output. */
-void X86EMU_trace_regs(void)
+void X86EMU_trace_regs (void)
{
- if (DEBUG_TRACE()) {
- x86emu_dump_regs();
- }
- if (DEBUG_DECODE() && !DEBUG_DECODE_NOPRINT()) {
- printk("%04x:%04x ", M.x86.saved_cs, M.x86.saved_ip);
- print_encoded_bytes(M.x86.saved_cs, M.x86.saved_ip);
- print_decoded_instruction();
- }
+ if (DEBUG_TRACE()) {
+ x86emu_dump_regs();
+ }
+ if (DEBUG_DECODE() && ! DEBUG_DECODE_NOPRINT()) {
+ printk("%04x:%04x ",M.x86.saved_cs, M.x86.saved_ip);
+ print_encoded_bytes( M.x86.saved_cs, M.x86.saved_ip);
+ print_decoded_instruction();
+ }
}
-void X86EMU_trace_xregs(void)
+void X86EMU_trace_xregs (void)
{
- if (DEBUG_TRACE()) {
- x86emu_dump_xregs();
- }
+ if (DEBUG_TRACE()) {
+ x86emu_dump_xregs();
+ }
}
-void x86emu_just_disassemble(void)
+void x86emu_just_disassemble (void)
{
- /*
- * This routine called if the flag DEBUG_DISASSEMBLE is set kind
- * of a hack!
- */
- printk("%04x:%04x ", M.x86.saved_cs, M.x86.saved_ip);
- print_encoded_bytes(M.x86.saved_cs, M.x86.saved_ip);
- print_decoded_instruction();
+ /*
+ * This routine called if the flag DEBUG_DISASSEMBLE is set kind
+ * of a hack!
+ */
+ printk("%04x:%04x ",M.x86.saved_cs, M.x86.saved_ip);
+ print_encoded_bytes( M.x86.saved_cs, M.x86.saved_ip);
+ print_decoded_instruction();
}
-static void disassemble_forward(u16 seg, u16 off, int n)
+static void disassemble_forward (u16 seg, u16 off, int n)
{
- X86EMU_sysEnv tregs;
- int i;
- u8 op1;
- /*
- * hack, hack, hack. What we do is use the exact machinery set up
- * for execution, except that now there is an additional state
- * flag associated with the "execution", and we are using a copy
- * of the register struct. All the major opcodes, once fully
- * decoded, have the following two steps: TRACE_REGS(r,m);
- * SINGLE_STEP(r,m); which disappear if DEBUG is not defined to
- * the preprocessor. The TRACE_REGS macro expands to:
- *
- * if (debug&DEBUG_DISASSEMBLE)
- * {just_disassemble(); goto EndOfInstruction;}
- * if (debug&DEBUG_TRACE) trace_regs(r,m);
- *
- * ...... and at the last line of the routine.
- *
- * EndOfInstruction: end_instr();
- *
- * Up to the point where TRACE_REG is expanded, NO modifications
- * are done to any register EXCEPT the IP register, for fetch and
- * decoding purposes.
- *
- * This was done for an entirely different reason, but makes a
- * nice way to get the system to help debug codes.
- */
- tregs = M;
- tregs.x86.R_IP = off;
- tregs.x86.R_CS = seg;
-
- /* reset the decoding buffers */
- tregs.x86.enc_str_pos = 0;
- tregs.x86.enc_pos = 0;
-
- /* turn on the "disassemble only, no execute" flag */
- tregs.x86.debug |= DEBUG_DISASSEMBLE_F;
-
- /* DUMP NEXT n instructions to screen in straight_line fashion */
- /*
- * This looks like the regular instruction fetch stream, except
- * that when this occurs, each fetched opcode, upon seeing the
- * DEBUG_DISASSEMBLE flag set, exits immediately after decoding
- * the instruction. XXX --- CHECK THAT MEM IS NOT AFFECTED!!!
- * Note the use of a copy of the register structure...
- */
- for (i = 0; i < n; i++) {
- op1 = (*sys_rdb) (((u32) M.x86.R_CS << 4) + (M.x86.R_IP++));
- (x86emu_optab[op1]) (op1);
- }
- /* end major hack mode. */
+ X86EMU_sysEnv tregs;
+ int i;
+ u8 op1;
+ /*
+ * hack, hack, hack. What we do is use the exact machinery set up
+ * for execution, except that now there is an additional state
+ * flag associated with the "execution", and we are using a copy
+ * of the register struct. All the major opcodes, once fully
+ * decoded, have the following two steps: TRACE_REGS(r,m);
+ * SINGLE_STEP(r,m); which disappear if DEBUG is not defined to
+ * the preprocessor. The TRACE_REGS macro expands to:
+ *
+ * if (debug&DEBUG_DISASSEMBLE)
+ * {just_disassemble(); goto EndOfInstruction;}
+ * if (debug&DEBUG_TRACE) trace_regs(r,m);
+ *
+ * ...... and at the last line of the routine.
+ *
+ * EndOfInstruction: end_instr();
+ *
+ * Up to the point where TRACE_REG is expanded, NO modifications
+ * are done to any register EXCEPT the IP register, for fetch and
+ * decoding purposes.
+ *
+ * This was done for an entirely different reason, but makes a
+ * nice way to get the system to help debug codes.
+ */
+ tregs = M;
+ tregs.x86.R_IP = off;
+ tregs.x86.R_CS = seg;
+
+ /* reset the decoding buffers */
+ tregs.x86.enc_str_pos = 0;
+ tregs.x86.enc_pos = 0;
+
+ /* turn on the "disassemble only, no execute" flag */
+ tregs.x86.debug |= DEBUG_DISASSEMBLE_F;
+
+ /* DUMP NEXT n instructions to screen in straight_line fashion */
+ /*
+ * This looks like the regular instruction fetch stream, except
+ * that when this occurs, each fetched opcode, upon seeing the
+ * DEBUG_DISASSEMBLE flag set, exits immediately after decoding
+ * the instruction. XXX --- CHECK THAT MEM IS NOT AFFECTED!!!
+ * Note the use of a copy of the register structure...
+ */
+ for (i=0; i<n; i++) {
+ op1 = (*sys_rdb)(((u32)M.x86.R_CS<<4) + (M.x86.R_IP++));
+ (x86emu_optab[op1])(op1);
+ }
+ /* end major hack mode. */
}
-void x86emu_check_ip_access(void)
+void x86emu_check_ip_access (void)
{
- /* NULL as of now */
+ /* NULL as of now */
}
-void x86emu_check_sp_access(void)
+void x86emu_check_sp_access (void)
{
}
-void x86emu_check_mem_access(u32 dummy)
+void x86emu_check_mem_access (u32 dummy)
{
- /* check bounds, etc */
+ /* check bounds, etc */
}
-void x86emu_check_data_access(uint dummy1, uint dummy2)
+void x86emu_check_data_access (uint dummy1, uint dummy2)
{
- /* check bounds, etc */
+ /* check bounds, etc */
}
-void x86emu_inc_decoded_inst_len(int x)
+void x86emu_inc_decoded_inst_len (int x)
{
- M.x86.enc_pos += x;
+ M.x86.enc_pos += x;
}
-void x86emu_decode_printf(char *x)
+void x86emu_decode_printf (char *x)
{
- sprintf(M.x86.decoded_buf + M.x86.enc_str_pos, "%s", x);
- M.x86.enc_str_pos += strlen(x);
+ sprintf(M.x86.decoded_buf+M.x86.enc_str_pos,"%s",x);
+ M.x86.enc_str_pos += strlen(x);
}
-void x86emu_decode_printf2(char *x, int y)
+void x86emu_decode_printf2 (char *x, int y)
{
- char temp[100];
- sprintf(temp, x, y);
- sprintf(M.x86.decoded_buf + M.x86.enc_str_pos, "%s", temp);
- M.x86.enc_str_pos += strlen(temp);
+ char temp[100];
+ sprintf(temp,x,y);
+ sprintf(M.x86.decoded_buf+M.x86.enc_str_pos,"%s",temp);
+ M.x86.enc_str_pos += strlen(temp);
}
-void x86emu_end_instr(void)
+void x86emu_end_instr (void)
{
- M.x86.enc_str_pos = 0;
- M.x86.enc_pos = 0;
+ M.x86.enc_str_pos = 0;
+ M.x86.enc_pos = 0;
}
-static void print_encoded_bytes(u16 s, u16 o)
+static void print_encoded_bytes (u16 s, u16 o)
{
- int i;
- char buf1[64];
- for (i = 0; i < M.x86.enc_pos; i++) {
- sprintf(buf1 + 2 * i, "%02x", fetch_data_byte_abs(s, o + i));
- }
- printk("%-20s", buf1);
+ int i;
+ char buf1[64];
+ for (i=0; i< M.x86.enc_pos; i++) {
+ sprintf(buf1+2*i,"%02x", fetch_data_byte_abs(s,o+i));
+ }
+ printk("%-20s",buf1);
}
-static void print_decoded_instruction(void)
+static void print_decoded_instruction (void)
{
- printk("%s", M.x86.decoded_buf);
+ printk("%s", M.x86.decoded_buf);
}
-void x86emu_print_int_vect(u16 iv)
+void x86emu_print_int_vect (u16 iv)
{
- u16 seg, off;
+ u16 seg,off;
- if (iv > 256)
- return;
- seg = fetch_data_word_abs(0, iv * 4);
- off = fetch_data_word_abs(0, iv * 4 + 2);
- printk("%04x:%04x ", seg, off);
+ if (iv > 256) return;
+ seg = fetch_data_word_abs(0,iv*4);
+ off = fetch_data_word_abs(0,iv*4+2);
+ printk("%04x:%04x ", seg, off);
}
-void X86EMU_dump_memory(u16 seg, u16 off, u32 amt)
+void X86EMU_dump_memory (u16 seg, u16 off, u32 amt)
{
- u32 start = off & 0xfffffff0;
- u32 end = (off + 16) & 0xfffffff0;
- u32 i;
- u32 current;
-
- current = start;
- while (end <= off + amt) {
- printk("%04x:%04x ", seg, start);
- for (i = start; i < off; i++)
- printk(" ");
- for (; i < end; i++)
- printk("%02x ", fetch_data_byte_abs(seg, i));
- printk("\n");
- start = end;
- end = start + 16;
- }
+ u32 start = off & 0xfffffff0;
+ u32 end = (off+16) & 0xfffffff0;
+ u32 i;
+ u32 current;
+
+ current = start;
+ while (end <= off + amt) {
+ printk("%04x:%04x ", seg, start);
+ for (i=start; i< off; i++)
+ printk(" ");
+ for ( ; i< end; i++)
+ printk("%02x ", fetch_data_byte_abs(seg,i));
+ printk("\n");
+ start = end;
+ end = start + 16;
+ }
}
-void x86emu_single_step(void)
+void x86emu_single_step (void)
{
- char s[1024];
- int ps[10];
- int ntok;
- int cmd;
- int done;
- int segment;
- int offset;
- static int breakpoint;
- static int noDecode = 1;
-
- char *p;
-
- if (DEBUG_BREAK()) {
- if (M.x86.saved_ip != breakpoint) {
- return;
- } else {
- M.x86.debug &= ~DEBUG_DECODE_NOPRINT_F;
- M.x86.debug |= DEBUG_TRACE_F;
- M.x86.debug &= ~DEBUG_BREAK_F;
- print_decoded_instruction();
- X86EMU_trace_regs();
- }
- }
- done = 0;
- offset = M.x86.saved_ip;
- while (!done) {
- printk("%x:%x -", M.x86.saved_cs, offset);
- p = fgets(s, 1023, stdin);
- cmd = parse_line(s, ps, &ntok);
- switch (cmd) {
- case 'u':
- disassemble_forward(M.x86.saved_cs, (u16) offset, 10);
- break;
- case 'd':
- if (ntok == 2) {
- segment = M.x86.saved_cs;
- offset = ps[1];
- X86EMU_dump_memory(segment, (u16) offset, 16);
- offset += 16;
- } else if (ntok == 3) {
- segment = ps[1];
- offset = ps[2];
- X86EMU_dump_memory(segment, (u16) offset, 16);
- offset += 16;
- } else {
- segment = M.x86.saved_cs;
- X86EMU_dump_memory(segment, (u16) offset, 16);
- offset += 16;
- }
- break;
- case 'c':
- M.x86.debug ^= DEBUG_TRACECALL_F;
- break;
- case 's':
- M.x86.debug ^= DEBUG_SVC_F | DEBUG_SYS_F | DEBUG_SYSINT_F;
- break;
- case 'r':
- X86EMU_trace_regs();
- break;
- case 'x':
- X86EMU_trace_xregs();
- break;
- case 'g':
- if (ntok == 2) {
- breakpoint = ps[1];
- if (noDecode) {
- M.x86.debug |= DEBUG_DECODE_NOPRINT_F;
- } else {
- M.x86.debug &= ~DEBUG_DECODE_NOPRINT_F;
- }
- M.x86.debug &= ~DEBUG_TRACE_F;
- M.x86.debug |= DEBUG_BREAK_F;
- done = 1;
- }
- break;
- case 'q':
- exit(1);
- case 'P':
- noDecode = (noDecode) ? 0 : 1;
- printk("Toggled decoding to %s\n", (noDecode) ? "FALSE" : "TRUE");
- break;
- case 't':
- case 0:
- done = 1;
- break;
- }
- }
+ char s[1024];
+ int ps[10];
+ int ntok;
+ int cmd;
+ int done;
+ int segment;
+ int offset;
+ static int breakpoint;
+ static int noDecode = 1;
+
+ char *p;
+
+ if (DEBUG_BREAK()) {
+ if (M.x86.saved_ip != breakpoint) {
+ return;
+ } else {
+ M.x86.debug &= ~DEBUG_DECODE_NOPRINT_F;
+ M.x86.debug |= DEBUG_TRACE_F;
+ M.x86.debug &= ~DEBUG_BREAK_F;
+ print_decoded_instruction ();
+ X86EMU_trace_regs();
+ }
+ }
+ done=0;
+ offset = M.x86.saved_ip;
+ while (!done) {
+ printk("-");
+ p = fgets(s, 1023, stdin);
+ cmd = parse_line(s, ps, &ntok);
+ switch(cmd) {
+ case 'u':
+ disassemble_forward(M.x86.saved_cs,(u16)offset,10);
+ break;
+ case 'd':
+ if (ntok == 2) {
+ segment = M.x86.saved_cs;
+ offset = ps[1];
+ X86EMU_dump_memory(segment,(u16)offset,16);
+ offset += 16;
+ } else if (ntok == 3) {
+ segment = ps[1];
+ offset = ps[2];
+ X86EMU_dump_memory(segment,(u16)offset,16);
+ offset += 16;
+ } else {
+ segment = M.x86.saved_cs;
+ X86EMU_dump_memory(segment,(u16)offset,16);
+ offset += 16;
+ }
+ break;
+ case 'c':
+ M.x86.debug ^= DEBUG_TRACECALL_F;
+ break;
+ case 's':
+ M.x86.debug ^= DEBUG_SVC_F | DEBUG_SYS_F | DEBUG_SYSINT_F;
+ break;
+ case 'r':
+ X86EMU_trace_regs();
+ break;
+ case 'x':
+ X86EMU_trace_xregs();
+ break;
+ case 'g':
+ if (ntok == 2) {
+ breakpoint = ps[1];
+ if (noDecode) {
+ M.x86.debug |= DEBUG_DECODE_NOPRINT_F;
+ } else {
+ M.x86.debug &= ~DEBUG_DECODE_NOPRINT_F;
+ }
+ M.x86.debug &= ~DEBUG_TRACE_F;
+ M.x86.debug |= DEBUG_BREAK_F;
+ done = 1;
+ }
+ break;
+ case 'q':
+ M.x86.debug |= DEBUG_EXIT;
+ return;
+ case 'P':
+ noDecode = (noDecode)?0:1;
+ printk("Toggled decoding to %s\n",(noDecode)?"FALSE":"TRUE");
+ break;
+ case 't':
+ case 0:
+ done = 1;
+ break;
+ }
+ }
}
int X86EMU_trace_on(void)
{
- return M.x86.debug |= /*DEBUG_STEP_F | */ DEBUG_DECODE_F | DEBUG_TRACE_F;
+ return M.x86.debug |= DEBUG_STEP_F | DEBUG_DECODE_F | DEBUG_TRACE_F;
}
int X86EMU_trace_off(void)
{
- return M.x86.debug &= ~(DEBUG_STEP_F | DEBUG_DECODE_F | DEBUG_TRACE_F);
+ return M.x86.debug &= ~(DEBUG_STEP_F | DEBUG_DECODE_F | DEBUG_TRACE_F);
}
-int X86EMU_set_debug(int debug)
+static int parse_line (char *s, int *ps, int *n)
{
- return M.x86.debug = debug;
+ int cmd;
+
+ *n = 0;
+ while(*s == ' ' || *s == '\t') s++;
+ ps[*n] = *s;
+ switch (*s) {
+ case '\n':
+ *n += 1;
+ return 0;
+ default:
+ cmd = *s;
+ *n += 1;
+ }
+
+ while (1) {
+ while (*s != ' ' && *s != '\t' && *s != '\n') s++;
+
+ if (*s == '\n')
+ return cmd;
+
+ while(*s == ' ' || *s == '\t') s++;
+
+ sscanf(s,"%x",&ps[*n]);
+ *n += 1;
+ }
}
-static int parse_line(char *s, int *ps, int *n)
-{
- int cmd;
-
- *n = 0;
- while (*s == ' ' || *s == '\t')
- s++;
- ps[*n] = *s;
- switch (*s) {
- case '\n':
- *n += 1;
- return 0;
- default:
- cmd = *s;
- *n += 1;
- }
-
- while (1) {
- while (*s != ' ' && *s != '\t' && *s != '\n')
- s++;
-
- if (*s == '\n')
- return cmd;
-
- while (*s == ' ' || *s == '\t')
- s++;
-
- sscanf(s, "%x", &ps[*n]);
- *n += 1;
- }
-}
-
-#endif /* DEBUG */
+#endif /* DEBUG */
-void x86emu_dump_regs(void)
+void x86emu_dump_regs (void)
{
- printk("\tAX=%04x ", M.x86.R_AX);
- printk("BX=%04x ", M.x86.R_BX);
- printk("CX=%04x ", M.x86.R_CX);
- printk("DX=%04x ", M.x86.R_DX);
- printk("SP=%04x ", M.x86.R_SP);
- printk("BP=%04x ", M.x86.R_BP);
- printk("SI=%04x ", M.x86.R_SI);
- printk("DI=%04x\n", M.x86.R_DI);
- printk("\tDS=%04x ", M.x86.R_DS);
- printk("ES=%04x ", M.x86.R_ES);
- printk("SS=%04x ", M.x86.R_SS);
- printk("CS=%04x ", M.x86.R_CS);
- printk("IP=%04x ", M.x86.R_IP);
- if (ACCESS_FLAG(F_OF))
- printk("OV "); /* CHECKED... */
- else
- printk("NV ");
- if (ACCESS_FLAG(F_DF))
- printk("DN ");
- else
- printk("UP ");
- if (ACCESS_FLAG(F_IF))
- printk("EI ");
- else
- printk("DI ");
- if (ACCESS_FLAG(F_SF))
- printk("NG ");
- else
- printk("PL ");
- if (ACCESS_FLAG(F_ZF))
- printk("ZR ");
- else
- printk("NZ ");
- if (ACCESS_FLAG(F_AF))
- printk("AC ");
- else
- printk("NA ");
- if (ACCESS_FLAG(F_PF))
- printk("PE ");
- else
- printk("PO ");
- if (ACCESS_FLAG(F_CF))
- printk("CY ");
- else
- printk("NC ");
- printk("\n");
+ printk("\tAX=%04x ", M.x86.R_AX );
+ printk("BX=%04x ", M.x86.R_BX );
+ printk("CX=%04x ", M.x86.R_CX );
+ printk("DX=%04x ", M.x86.R_DX );
+ printk("SP=%04x ", M.x86.R_SP );
+ printk("BP=%04x ", M.x86.R_BP );
+ printk("SI=%04x ", M.x86.R_SI );
+ printk("DI=%04x\n", M.x86.R_DI );
+ printk("\tDS=%04x ", M.x86.R_DS );
+ printk("ES=%04x ", M.x86.R_ES );
+ printk("SS=%04x ", M.x86.R_SS );
+ printk("CS=%04x ", M.x86.R_CS );
+ printk("IP=%04x ", M.x86.R_IP );
+ if (ACCESS_FLAG(F_OF)) printk("OV "); /* CHECKED... */
+ else printk("NV ");
+ if (ACCESS_FLAG(F_DF)) printk("DN ");
+ else printk("UP ");
+ if (ACCESS_FLAG(F_IF)) printk("EI ");
+ else printk("DI ");
+ if (ACCESS_FLAG(F_SF)) printk("NG ");
+ else printk("PL ");
+ if (ACCESS_FLAG(F_ZF)) printk("ZR ");
+ else printk("NZ ");
+ if (ACCESS_FLAG(F_AF)) printk("AC ");
+ else printk("NA ");
+ if (ACCESS_FLAG(F_PF)) printk("PE ");
+ else printk("PO ");
+ if (ACCESS_FLAG(F_CF)) printk("CY ");
+ else printk("NC ");
+ printk("\n");
}
-void x86emu_dump_xregs(void)
+void x86emu_dump_xregs (void)
{
- printk("\tEAX=%08x ", M.x86.R_EAX);
- printk("EBX=%08x ", M.x86.R_EBX);
- printk("ECX=%08x ", M.x86.R_ECX);
- printk("EDX=%08x \n", M.x86.R_EDX);
- printk("\tESP=%08x ", M.x86.R_ESP);
- printk("EBP=%08x ", M.x86.R_EBP);
- printk("ESI=%08x ", M.x86.R_ESI);
- printk("EDI=%08x\n", M.x86.R_EDI);
- printk("\tDS=%04x ", M.x86.R_DS);
- printk("ES=%04x ", M.x86.R_ES);
- printk("SS=%04x ", M.x86.R_SS);
- printk("CS=%04x ", M.x86.R_CS);
- printk("EIP=%08x\n\t", M.x86.R_EIP);
- if (ACCESS_FLAG(F_OF))
- printk("OV "); /* CHECKED... */
- else
- printk("NV ");
- if (ACCESS_FLAG(F_DF))
- printk("DN ");
- else
- printk("UP ");
- if (ACCESS_FLAG(F_IF))
- printk("EI ");
- else
- printk("DI ");
- if (ACCESS_FLAG(F_SF))
- printk("NG ");
- else
- printk("PL ");
- if (ACCESS_FLAG(F_ZF))
- printk("ZR ");
- else
- printk("NZ ");
- if (ACCESS_FLAG(F_AF))
- printk("AC ");
- else
- printk("NA ");
- if (ACCESS_FLAG(F_PF))
- printk("PE ");
- else
- printk("PO ");
- if (ACCESS_FLAG(F_CF))
- printk("CY ");
- else
- printk("NC ");
- printk("\n");
+ printk("\tEAX=%08x ", M.x86.R_EAX );
+ printk("EBX=%08x ", M.x86.R_EBX );
+ printk("ECX=%08x ", M.x86.R_ECX );
+ printk("EDX=%08x \n", M.x86.R_EDX );
+ printk("\tESP=%08x ", M.x86.R_ESP );
+ printk("EBP=%08x ", M.x86.R_EBP );
+ printk("ESI=%08x ", M.x86.R_ESI );
+ printk("EDI=%08x\n", M.x86.R_EDI );
+ printk("\tDS=%04x ", M.x86.R_DS );
+ printk("ES=%04x ", M.x86.R_ES );
+ printk("SS=%04x ", M.x86.R_SS );
+ printk("CS=%04x ", M.x86.R_CS );
+ printk("EIP=%08x\n\t", M.x86.R_EIP );
+ if (ACCESS_FLAG(F_OF)) printk("OV "); /* CHECKED... */
+ else printk("NV ");
+ if (ACCESS_FLAG(F_DF)) printk("DN ");
+ else printk("UP ");
+ if (ACCESS_FLAG(F_IF)) printk("EI ");
+ else printk("DI ");
+ if (ACCESS_FLAG(F_SF)) printk("NG ");
+ else printk("PL ");
+ if (ACCESS_FLAG(F_ZF)) printk("ZR ");
+ else printk("NZ ");
+ if (ACCESS_FLAG(F_AF)) printk("AC ");
+ else printk("NA ");
+ if (ACCESS_FLAG(F_PF)) printk("PE ");
+ else printk("PO ");
+ if (ACCESS_FLAG(F_CF)) printk("CY ");
+ else printk("NC ");
+ printk("\n");
}
diff --git a/util/vgabios/x86emu/src/x86emu/decode.c b/util/vgabios/x86emu/src/x86emu/decode.c
index a97edd92a..910d1e979 100644
--- a/util/vgabios/x86emu/src/x86emu/decode.c
+++ b/util/vgabios/x86emu/src/x86emu/decode.c
@@ -1,10 +1,10 @@
/****************************************************************************
*
-* Realmode X86 Emulator Library
+* Realmode X86 Emulator Library
*
-* Copyright (C) 1996-1999 SciTech Software, Inc.
-* Copyright (C) David Mosberger-Tang
-* Copyright (C) 1999 Egbert Eich
+* Copyright (C) 1991-2004 SciTech Software, Inc.
+* Copyright (C) David Mosberger-Tang
+* Copyright (C) 1999 Egbert Eich
*
* ========================================================================
*
@@ -28,17 +28,15 @@
*
* ========================================================================
*
-* Language: ANSI C
-* Environment: Any
+* Language: ANSI C
+* Environment: Any
* Developer: Kendall Bennett
*
* Description: This file includes subroutines which are related to
-* instruction decoding and accessess of immediate data via IP. etc.
+* instruction decoding and accessess of immediate data via IP. etc.
*
****************************************************************************/
-/* $XFree86: xc/extras/x86emu/src/x86emu/decode.c,v 1.9 2001/01/06 20:19:03 tsi Exp $ */
-
#include "x86emu/x86emui.h"
/*----------------------------- Implementation ----------------------------*/
@@ -49,23 +47,23 @@ Handles any pending asychronous interrupts.
****************************************************************************/
static void x86emu_intr_handle(void)
{
- u8 intno;
-
- if (M.x86.intr & INTR_SYNCH) {
- intno = M.x86.intno;
- if (_X86EMU_intrTab[intno]) {
- (*_X86EMU_intrTab[intno]) (intno);
- } else {
- push_word((u16) M.x86.R_FLG);
- CLEAR_FLAG(F_IF);
- CLEAR_FLAG(F_TF);
- push_word(M.x86.R_CS);
- M.x86.R_CS = mem_access_word(intno * 4 + 2);
- push_word(M.x86.R_IP);
- M.x86.R_IP = mem_access_word(intno * 4);
- M.x86.intr = 0;
- }
- }
+ u8 intno;
+
+ if (M.x86.intr & INTR_SYNCH) {
+ intno = M.x86.intno;
+ if (_X86EMU_intrTab[intno]) {
+ (*_X86EMU_intrTab[intno])(intno);
+ } else {
+ push_word((u16)M.x86.R_FLG);
+ CLEAR_FLAG(F_IF);
+ CLEAR_FLAG(F_TF);
+ push_word(M.x86.R_CS);
+ M.x86.R_CS = mem_access_word(intno * 4 + 2);
+ push_word(M.x86.R_IP);
+ M.x86.R_IP = mem_access_word(intno * 4);
+ M.x86.intr = 0;
+ }
+ }
}
/****************************************************************************
@@ -76,10 +74,11 @@ REMARKS:
Raise the specified interrupt to be handled before the execution of the
next instruction.
****************************************************************************/
-void x86emu_intr_raise(u8 intrnum)
+void x86emu_intr_raise(
+ u8 intrnum)
{
- M.x86.intno = intrnum;
- M.x86.intr |= INTR_SYNCH;
+ M.x86.intno = intrnum;
+ M.x86.intr |= INTR_SYNCH;
}
/****************************************************************************
@@ -90,33 +89,41 @@ original real mode call.
****************************************************************************/
void X86EMU_exec(void)
{
- u8 op1;
-
- M.x86.intr = 0;
- DB(x86emu_end_instr();
- )
-
- for (;;) {
- DB(if (CHECK_IP_FETCH())
- x86emu_check_ip_access();)
- /* If debugging, save the IP and CS values. */
- SAVE_IP_CS(M.x86.R_CS, M.x86.R_IP);
- INC_DECODED_INST_LEN(1);
- if (M.x86.intr) {
- if (M.x86.intr & INTR_HALTED) {
- DB(printk("halted\n"); X86EMU_trace_regs();
- )
- return;
- }
- if (((M.x86.intr & INTR_SYNCH)
- && (M.x86.intno == 0 || M.x86.intno == 2))
- || !ACCESS_FLAG(F_IF)) {
- x86emu_intr_handle();
- }
- }
- op1 = (*sys_rdb) (((u32) M.x86.R_CS << 4) + (M.x86.R_IP++));
- (*x86emu_optab[op1]) (op1);
- }
+ u8 op1;
+
+ M.x86.intr = 0;
+ DB(x86emu_end_instr();)
+
+ for (;;) {
+DB( if (CHECK_IP_FETCH())
+ x86emu_check_ip_access();)
+ /* If debugging, save the IP and CS values. */
+ SAVE_IP_CS(M.x86.R_CS, M.x86.R_IP);
+ INC_DECODED_INST_LEN(1);
+ if (M.x86.intr) {
+ if (M.x86.intr & INTR_HALTED) {
+DB( if (M.x86.R_SP != 0) {
+ printk("halted\n");
+ X86EMU_trace_regs();
+ }
+ else {
+ if (M.x86.debug)
+ printk("Service completed successfully\n");
+ })
+ return;
+ }
+ if (((M.x86.intr & INTR_SYNCH) && (M.x86.intno == 0 || M.x86.intno == 2)) ||
+ !ACCESS_FLAG(F_IF)) {
+ x86emu_intr_handle();
+ }
+ }
+ op1 = (*sys_rdb)(((u32)M.x86.R_CS << 4) + (M.x86.R_IP++));
+ (*x86emu_optab[op1])(op1);
+ if (M.x86.debug & DEBUG_EXIT) {
+ M.x86.debug &= ~DEBUG_EXIT;
+ return;
+ }
+ }
}
/****************************************************************************
@@ -125,14 +132,14 @@ Halts the system by setting the halted system flag.
****************************************************************************/
void X86EMU_halt_sys(void)
{
- M.x86.intr |= INTR_HALTED;
+ M.x86.intr |= INTR_HALTED;
}
/****************************************************************************
PARAMETERS:
-mod - Mod value from decoded byte
-regh - Reg h value from decoded byte
-regl - Reg l value from decoded byte
+mod - Mod value from decoded byte
+regh - Reg h value from decoded byte
+regl - Reg l value from decoded byte
REMARKS:
Raise the specified interrupt to be handled before the execution of the
@@ -140,17 +147,20 @@ next instruction.
NOTE: Do not inline this function, as (*sys_rdb) is already inline!
****************************************************************************/
-void fetch_decode_modrm(int *mod, int *regh, int *regl)
+void fetch_decode_modrm(
+ int *mod,
+ int *regh,
+ int *regl)
{
- int fetched;
-
- DB(if (CHECK_IP_FETCH())
- x86emu_check_ip_access();)
- fetched = (*sys_rdb) (((u32) M.x86.R_CS << 4) + (M.x86.R_IP++));
- INC_DECODED_INST_LEN(1);
- *mod = (fetched >> 6) & 0x03;
- *regh = (fetched >> 3) & 0x07;
- *regl = (fetched >> 0) & 0x07;
+ int fetched;
+
+DB( if (CHECK_IP_FETCH())
+ x86emu_check_ip_access();)
+ fetched = (*sys_rdb)(((u32)M.x86.R_CS << 4) + (M.x86.R_IP++));
+ INC_DECODED_INST_LEN(1);
+ *mod = (fetched >> 6) & 0x03;
+ *regh = (fetched >> 3) & 0x07;
+ *regl = (fetched >> 0) & 0x07;
}
/****************************************************************************
@@ -165,13 +175,13 @@ NOTE: Do not inline this function, as (*sys_rdb) is already inline!
****************************************************************************/
u8 fetch_byte_imm(void)
{
- u8 fetched;
+ u8 fetched;
- DB(if (CHECK_IP_FETCH())
- x86emu_check_ip_access();)
- fetched = (*sys_rdb) (((u32) M.x86.R_CS << 4) + (M.x86.R_IP++));
- INC_DECODED_INST_LEN(1);
- return fetched;
+DB( if (CHECK_IP_FETCH())
+ x86emu_check_ip_access();)
+ fetched = (*sys_rdb)(((u32)M.x86.R_CS << 4) + (M.x86.R_IP++));
+ INC_DECODED_INST_LEN(1);
+ return fetched;
}
/****************************************************************************
@@ -186,14 +196,14 @@ NOTE: Do not inline this function, as (*sys_rdw) is already inline!
****************************************************************************/
u16 fetch_word_imm(void)
{
- u16 fetched;
-
- DB(if (CHECK_IP_FETCH())
- x86emu_check_ip_access();)
- fetched = (*sys_rdw) (((u32) M.x86.R_CS << 4) + (M.x86.R_IP));
- M.x86.R_IP += 2;
- INC_DECODED_INST_LEN(2);
- return fetched;
+ u16 fetched;
+
+DB( if (CHECK_IP_FETCH())
+ x86emu_check_ip_access();)
+ fetched = (*sys_rdw)(((u32)M.x86.R_CS << 4) + (M.x86.R_IP));
+ M.x86.R_IP += 2;
+ INC_DECODED_INST_LEN(2);
+ return fetched;
}
/****************************************************************************
@@ -208,14 +218,14 @@ NOTE: Do not inline this function, as (*sys_rdw) is already inline!
****************************************************************************/
u32 fetch_long_imm(void)
{
- u32 fetched;
-
- DB(if (CHECK_IP_FETCH())
- x86emu_check_ip_access();)
- fetched = (*sys_rdl) (((u32) M.x86.R_CS << 4) + (M.x86.R_IP));
- M.x86.R_IP += 4;
- INC_DECODED_INST_LEN(4);
- return fetched;
+ u32 fetched;
+
+DB( if (CHECK_IP_FETCH())
+ x86emu_check_ip_access();)
+ fetched = (*sys_rdl)(((u32)M.x86.R_CS << 4) + (M.x86.R_IP));
+ M.x86.R_IP += 4;
+ INC_DECODED_INST_LEN(4);
+ return fetched;
}
/****************************************************************************
@@ -233,169 +243,178 @@ decodings of addressing modes would have to set/clear a bit describing
whether the access is relative to DS or SS. That is the function of the
cpu-state-varible M.x86.mode. There are several potential states:
- repe prefix seen (handled elsewhere)
- repne prefix seen (ditto)
+ repe prefix seen (handled elsewhere)
+ repne prefix seen (ditto)
- cs segment override
- ds segment override
- es segment override
- fs segment override
- gs segment override
- ss segment override
+ cs segment override
+ ds segment override
+ es segment override
+ fs segment override
+ gs segment override
+ ss segment override
- ds/ss select (in absense of override)
+ ds/ss select (in absense of override)
Each of the above 7 items are handled with a bit in the mode field.
****************************************************************************/
_INLINE u32 get_data_segment(void)
{
-#define GET_SEGMENT(segment)
- switch (M.x86.mode & SYSMODE_SEGMASK) {
- case 0: /* default case: use ds register */
- case SYSMODE_SEGOVR_DS:
- case SYSMODE_SEGOVR_DS | SYSMODE_SEG_DS_SS:
- return M.x86.R_DS;
- case SYSMODE_SEG_DS_SS: /* non-overridden, use ss register */
- return M.x86.R_SS;
- case SYSMODE_SEGOVR_CS:
- case SYSMODE_SEGOVR_CS | SYSMODE_SEG_DS_SS:
- return M.x86.R_CS;
- case SYSMODE_SEGOVR_ES:
- case SYSMODE_SEGOVR_ES | SYSMODE_SEG_DS_SS:
- return M.x86.R_ES;
- case SYSMODE_SEGOVR_FS:
- case SYSMODE_SEGOVR_FS | SYSMODE_SEG_DS_SS:
- return M.x86.R_FS;
- case SYSMODE_SEGOVR_GS:
- case SYSMODE_SEGOVR_GS | SYSMODE_SEG_DS_SS:
- return M.x86.R_GS;
- case SYSMODE_SEGOVR_SS:
- case SYSMODE_SEGOVR_SS | SYSMODE_SEG_DS_SS:
- return M.x86.R_SS;
- default:
-#ifdef DEBUG
- printk("error: should not happen: multiple overrides.\n");
+#define GET_SEGMENT(segment)
+ switch (M.x86.mode & SYSMODE_SEGMASK) {
+ case 0: /* default case: use ds register */
+ case SYSMODE_SEGOVR_DS:
+ case SYSMODE_SEGOVR_DS | SYSMODE_SEG_DS_SS:
+ return M.x86.R_DS;
+ case SYSMODE_SEG_DS_SS: /* non-overridden, use ss register */
+ return M.x86.R_SS;
+ case SYSMODE_SEGOVR_CS:
+ case SYSMODE_SEGOVR_CS | SYSMODE_SEG_DS_SS:
+ return M.x86.R_CS;
+ case SYSMODE_SEGOVR_ES:
+ case SYSMODE_SEGOVR_ES | SYSMODE_SEG_DS_SS:
+ return M.x86.R_ES;
+ case SYSMODE_SEGOVR_FS:
+ case SYSMODE_SEGOVR_FS | SYSMODE_SEG_DS_SS:
+ return M.x86.R_FS;
+ case SYSMODE_SEGOVR_GS:
+ case SYSMODE_SEGOVR_GS | SYSMODE_SEG_DS_SS:
+ return M.x86.R_GS;
+ case SYSMODE_SEGOVR_SS:
+ case SYSMODE_SEGOVR_SS | SYSMODE_SEG_DS_SS:
+ return M.x86.R_SS;
+ default:
+#ifdef DEBUG
+ printk("error: should not happen: multiple overrides.\n");
#endif
- HALT_SYS();
- return 0;
- }
+ HALT_SYS();
+ return 0;
+ }
}
/****************************************************************************
PARAMETERS:
-offset - Offset to load data from
+offset - Offset to load data from
RETURNS:
Byte value read from the absolute memory location.
NOTE: Do not inline this function as (*sys_rdX) is already inline!
****************************************************************************/
-u8 fetch_data_byte(uint offset)
+u8 fetch_data_byte(
+ uint offset)
{
#ifdef DEBUG
- if (CHECK_DATA_ACCESS())
- x86emu_check_data_access((u16) get_data_segment(), offset);
+ if (CHECK_DATA_ACCESS())
+ x86emu_check_data_access((u16)get_data_segment(), offset);
#endif
- return (*sys_rdb) ((get_data_segment() << 4) + offset);
+ return (*sys_rdb)((get_data_segment() << 4) + offset);
}
/****************************************************************************
PARAMETERS:
-offset - Offset to load data from
+offset - Offset to load data from
RETURNS:
Word value read from the absolute memory location.
NOTE: Do not inline this function as (*sys_rdX) is already inline!
****************************************************************************/
-u16 fetch_data_word(uint offset)
+u16 fetch_data_word(
+ uint offset)
{
#ifdef DEBUG
- if (CHECK_DATA_ACCESS())
- x86emu_check_data_access((u16) get_data_segment(), offset);
+ if (CHECK_DATA_ACCESS())
+ x86emu_check_data_access((u16)get_data_segment(), offset);
#endif
- return (*sys_rdw) ((get_data_segment() << 4) + offset);
+ return (*sys_rdw)((get_data_segment() << 4) + offset);
}
/****************************************************************************
PARAMETERS:
-offset - Offset to load data from
+offset - Offset to load data from
RETURNS:
Long value read from the absolute memory location.
NOTE: Do not inline this function as (*sys_rdX) is already inline!
****************************************************************************/
-u32 fetch_data_long(uint offset)
+u32 fetch_data_long(
+ uint offset)
{
#ifdef DEBUG
- if (CHECK_DATA_ACCESS())
- x86emu_check_data_access((u16) get_data_segment(), offset);
+ if (CHECK_DATA_ACCESS())
+ x86emu_check_data_access((u16)get_data_segment(), offset);
#endif
- return (*sys_rdl) ((get_data_segment() << 4) + offset);
+ return (*sys_rdl)((get_data_segment() << 4) + offset);
}
/****************************************************************************
PARAMETERS:
-segment - Segment to load data from
-offset - Offset to load data from
+segment - Segment to load data from
+offset - Offset to load data from
RETURNS:
Byte value read from the absolute memory location.
NOTE: Do not inline this function as (*sys_rdX) is already inline!
****************************************************************************/
-u8 fetch_data_byte_abs(uint segment, uint offset)
+u8 fetch_data_byte_abs(
+ uint segment,
+ uint offset)
{
#ifdef DEBUG
- if (CHECK_DATA_ACCESS())
- x86emu_check_data_access(segment, offset);
+ if (CHECK_DATA_ACCESS())
+ x86emu_check_data_access(segment, offset);
#endif
- return (*sys_rdb) (((u32) segment << 4) + offset);
+ return (*sys_rdb)(((u32)segment << 4) + offset);
}
/****************************************************************************
PARAMETERS:
-segment - Segment to load data from
-offset - Offset to load data from
+segment - Segment to load data from
+offset - Offset to load data from
RETURNS:
Word value read from the absolute memory location.
NOTE: Do not inline this function as (*sys_rdX) is already inline!
****************************************************************************/
-u16 fetch_data_word_abs(uint segment, uint offset)
+u16 fetch_data_word_abs(
+ uint segment,
+ uint offset)
{
#ifdef DEBUG
- if (CHECK_DATA_ACCESS())
- x86emu_check_data_access(segment, offset);
+ if (CHECK_DATA_ACCESS())
+ x86emu_check_data_access(segment, offset);
#endif
- return (*sys_rdw) (((u32) segment << 4) + offset);
+ return (*sys_rdw)(((u32)segment << 4) + offset);
}
/****************************************************************************
PARAMETERS:
-segment - Segment to load data from
-offset - Offset to load data from
+segment - Segment to load data from
+offset - Offset to load data from
RETURNS:
Long value read from the absolute memory location.
NOTE: Do not inline this function as (*sys_rdX) is already inline!
****************************************************************************/
-u32 fetch_data_long_abs(uint segment, uint offset)
+u32 fetch_data_long_abs(
+ uint segment,
+ uint offset)
{
#ifdef DEBUG
- if (CHECK_DATA_ACCESS())
- x86emu_check_data_access(segment, offset);
+ if (CHECK_DATA_ACCESS())
+ x86emu_check_data_access(segment, offset);
#endif
- return (*sys_rdl) (((u32) segment << 4) + offset);
+ return (*sys_rdl)(((u32)segment << 4) + offset);
}
/****************************************************************************
PARAMETERS:
-offset - Offset to store data at
-val - Value to store
+offset - Offset to store data at
+val - Value to store
REMARKS:
Writes a word value to an segmented memory location. The segment used is
@@ -403,19 +422,21 @@ the current 'default' segment, which may have been overridden.
NOTE: Do not inline this function as (*sys_wrX) is already inline!
****************************************************************************/
-void store_data_byte(uint offset, u8 val)
+void store_data_byte(
+ uint offset,
+ u8 val)
{
#ifdef DEBUG
- if (CHECK_DATA_ACCESS())
- x86emu_check_data_access((u16) get_data_segment(), offset);
+ if (CHECK_DATA_ACCESS())
+ x86emu_check_data_access((u16)get_data_segment(), offset);
#endif
- (*sys_wrb) ((get_data_segment() << 4) + offset, val);
+ (*sys_wrb)((get_data_segment() << 4) + offset, val);
}
/****************************************************************************
PARAMETERS:
-offset - Offset to store data at
-val - Value to store
+offset - Offset to store data at
+val - Value to store
REMARKS:
Writes a word value to an segmented memory location. The segment used is
@@ -423,19 +444,21 @@ the current 'default' segment, which may have been overridden.
NOTE: Do not inline this function as (*sys_wrX) is already inline!
****************************************************************************/
-void store_data_word(uint offset, u16 val)
+void store_data_word(
+ uint offset,
+ u16 val)
{
#ifdef DEBUG
- if (CHECK_DATA_ACCESS())
- x86emu_check_data_access((u16) get_data_segment(), offset);
+ if (CHECK_DATA_ACCESS())
+ x86emu_check_data_access((u16)get_data_segment(), offset);
#endif
- (*sys_wrw) ((get_data_segment() << 4) + offset, val);
+ (*sys_wrw)((get_data_segment() << 4) + offset, val);
}
/****************************************************************************
PARAMETERS:
-offset - Offset to store data at
-val - Value to store
+offset - Offset to store data at
+val - Value to store
REMARKS:
Writes a long value to an segmented memory location. The segment used is
@@ -443,78 +466,89 @@ the current 'default' segment, which may have been overridden.
NOTE: Do not inline this function as (*sys_wrX) is already inline!
****************************************************************************/
-void store_data_long(uint offset, u32 val)
+void store_data_long(
+ uint offset,
+ u32 val)
{
#ifdef DEBUG
- if (CHECK_DATA_ACCESS())
- x86emu_check_data_access((u16) get_data_segment(), offset);
+ if (CHECK_DATA_ACCESS())
+ x86emu_check_data_access((u16)get_data_segment(), offset);
#endif
- (*sys_wrl) ((get_data_segment() << 4) + offset, val);
+ (*sys_wrl)((get_data_segment() << 4) + offset, val);
}
/****************************************************************************
PARAMETERS:
-segment - Segment to store data at
-offset - Offset to store data at
-val - Value to store
+segment - Segment to store data at
+offset - Offset to store data at
+val - Value to store
REMARKS:
Writes a byte value to an absolute memory location.
NOTE: Do not inline this function as (*sys_wrX) is already inline!
****************************************************************************/
-void store_data_byte_abs(uint segment, uint offset, u8 val)
+void store_data_byte_abs(
+ uint segment,
+ uint offset,
+ u8 val)
{
#ifdef DEBUG
- if (CHECK_DATA_ACCESS())
- x86emu_check_data_access(segment, offset);
+ if (CHECK_DATA_ACCESS())
+ x86emu_check_data_access(segment, offset);
#endif
- (*sys_wrb) (((u32) segment << 4) + offset, val);
+ (*sys_wrb)(((u32)segment << 4) + offset, val);
}
/****************************************************************************
PARAMETERS:
-segment - Segment to store data at
-offset - Offset to store data at
-val - Value to store
+segment - Segment to store data at
+offset - Offset to store data at
+val - Value to store
REMARKS:
Writes a word value to an absolute memory location.
NOTE: Do not inline this function as (*sys_wrX) is already inline!
****************************************************************************/
-void store_data_word_abs(uint segment, uint offset, u16 val)
+void store_data_word_abs(
+ uint segment,
+ uint offset,
+ u16 val)
{
#ifdef DEBUG
- if (CHECK_DATA_ACCESS())
- x86emu_check_data_access(segment, offset);
+ if (CHECK_DATA_ACCESS())
+ x86emu_check_data_access(segment, offset);
#endif
- (*sys_wrw) (((u32) segment << 4) + offset, val);
+ (*sys_wrw)(((u32)segment << 4) + offset, val);
}
/****************************************************************************
PARAMETERS:
-segment - Segment to store data at
-offset - Offset to store data at
-val - Value to store
+segment - Segment to store data at
+offset - Offset to store data at
+val - Value to store
REMARKS:
Writes a long value to an absolute memory location.
NOTE: Do not inline this function as (*sys_wrX) is already inline!
****************************************************************************/
-void store_data_long_abs(uint segment, uint offset, u32 val)
+void store_data_long_abs(
+ uint segment,
+ uint offset,
+ u32 val)
{
#ifdef DEBUG
- if (CHECK_DATA_ACCESS())
- x86emu_check_data_access(segment, offset);
+ if (CHECK_DATA_ACCESS())
+ x86emu_check_data_access(segment, offset);
#endif
- (*sys_wrl) (((u32) segment << 4) + offset, val);
+ (*sys_wrl)(((u32)segment << 4) + offset, val);
}
/****************************************************************************
PARAMETERS:
-reg - Register to decode
+reg - Register to decode
RETURNS:
Pointer to the appropriate register
@@ -523,41 +557,42 @@ REMARKS:
Return a pointer to the register given by the R/RM field of the
modrm byte, for byte operands. Also enables the decoding of instructions.
****************************************************************************/
-u8 *decode_rm_byte_register(int reg)
+u8* decode_rm_byte_register(
+ int reg)
{
- switch (reg) {
- case 0:
- DECODE_PRINTF("AL");
- return &M.x86.R_AL;
- case 1:
- DECODE_PRINTF("CL");
- return &M.x86.R_CL;
- case 2:
- DECODE_PRINTF("DL");
- return &M.x86.R_DL;
- case 3:
- DECODE_PRINTF("BL");
- return &M.x86.R_BL;
- case 4:
- DECODE_PRINTF("AH");
- return &M.x86.R_AH;
- case 5:
- DECODE_PRINTF("CH");
- return &M.x86.R_CH;
- case 6:
- DECODE_PRINTF("DH");
- return &M.x86.R_DH;
- case 7:
- DECODE_PRINTF("BH");
- return &M.x86.R_BH;
- }
- HALT_SYS();
- return NULL; /* NOT REACHED OR REACHED ON ERROR */
+ switch (reg) {
+ case 0:
+ DECODE_PRINTF("AL");
+ return &M.x86.R_AL;
+ case 1:
+ DECODE_PRINTF("CL");
+ return &M.x86.R_CL;
+ case 2:
+ DECODE_PRINTF("DL");
+ return &M.x86.R_DL;
+ case 3:
+ DECODE_PRINTF("BL");
+ return &M.x86.R_BL;
+ case 4:
+ DECODE_PRINTF("AH");
+ return &M.x86.R_AH;
+ case 5:
+ DECODE_PRINTF("CH");
+ return &M.x86.R_CH;
+ case 6:
+ DECODE_PRINTF("DH");
+ return &M.x86.R_DH;
+ case 7:
+ DECODE_PRINTF("BH");
+ return &M.x86.R_BH;
+ }
+ HALT_SYS();
+ return NULL; /* NOT REACHED OR REACHED ON ERROR */
}
/****************************************************************************
PARAMETERS:
-reg - Register to decode
+reg - Register to decode
RETURNS:
Pointer to the appropriate register
@@ -566,41 +601,42 @@ REMARKS:
Return a pointer to the register given by the R/RM field of the
modrm byte, for word operands. Also enables the decoding of instructions.
****************************************************************************/
-u16 *decode_rm_word_register(int reg)
+u16* decode_rm_word_register(
+ int reg)
{
- switch (reg) {
- case 0:
- DECODE_PRINTF("AX");
- return &M.x86.R_AX;
- case 1:
- DECODE_PRINTF("CX");
- return &M.x86.R_CX;
- case 2:
- DECODE_PRINTF("DX");
- return &M.x86.R_DX;
- case 3:
- DECODE_PRINTF("BX");
- return &M.x86.R_BX;
- case 4:
- DECODE_PRINTF("SP");
- return &M.x86.R_SP;
- case 5:
- DECODE_PRINTF("BP");
- return &M.x86.R_BP;
- case 6:
- DECODE_PRINTF("SI");
- return &M.x86.R_SI;
- case 7:
- DECODE_PRINTF("DI");
- return &M.x86.R_DI;
- }
- HALT_SYS();
- return NULL; /* NOTREACHED OR REACHED ON ERROR */
+ switch (reg) {
+ case 0:
+ DECODE_PRINTF("AX");
+ return &M.x86.R_AX;
+ case 1:
+ DECODE_PRINTF("CX");
+ return &M.x86.R_CX;
+ case 2:
+ DECODE_PRINTF("DX");
+ return &M.x86.R_DX;
+ case 3:
+ DECODE_PRINTF("BX");
+ return &M.x86.R_BX;
+ case 4:
+ DECODE_PRINTF("SP");
+ return &M.x86.R_SP;
+ case 5:
+ DECODE_PRINTF("BP");
+ return &M.x86.R_BP;
+ case 6:
+ DECODE_PRINTF("SI");
+ return &M.x86.R_SI;
+ case 7:
+ DECODE_PRINTF("DI");
+ return &M.x86.R_DI;
+ }
+ HALT_SYS();
+ return NULL; /* NOTREACHED OR REACHED ON ERROR */
}
/****************************************************************************
PARAMETERS:
-reg - Register to decode
+reg - Register to decode
RETURNS:
Pointer to the appropriate register
@@ -609,41 +645,42 @@ REMARKS:
Return a pointer to the register given by the R/RM field of the
modrm byte, for dword operands. Also enables the decoding of instructions.
****************************************************************************/
-u32 *decode_rm_long_register(int reg)
+u32* decode_rm_long_register(
+ int reg)
{
- switch (reg) {
- case 0:
- DECODE_PRINTF("EAX");
- return &M.x86.R_EAX;
- case 1:
- DECODE_PRINTF("ECX");
- return &M.x86.R_ECX;
- case 2:
- DECODE_PRINTF("EDX");
- return &M.x86.R_EDX;
- case 3:
- DECODE_PRINTF("EBX");
- return &M.x86.R_EBX;
- case 4:
- DECODE_PRINTF("ESP");
- return &M.x86.R_ESP;
- case 5:
- DECODE_PRINTF("EBP");
- return &M.x86.R_EBP;
- case 6:
- DECODE_PRINTF("ESI");
- return &M.x86.R_ESI;
- case 7:
- DECODE_PRINTF("EDI");
- return &M.x86.R_EDI;
- }
- HALT_SYS();
- return NULL; /* NOTREACHED OR REACHED ON ERROR */
+ switch (reg) {
+ case 0:
+ DECODE_PRINTF("EAX");
+ return &M.x86.R_EAX;
+ case 1:
+ DECODE_PRINTF("ECX");
+ return &M.x86.R_ECX;
+ case 2:
+ DECODE_PRINTF("EDX");
+ return &M.x86.R_EDX;
+ case 3:
+ DECODE_PRINTF("EBX");
+ return &M.x86.R_EBX;
+ case 4:
+ DECODE_PRINTF("ESP");
+ return &M.x86.R_ESP;
+ case 5:
+ DECODE_PRINTF("EBP");
+ return &M.x86.R_EBP;
+ case 6:
+ DECODE_PRINTF("ESI");
+ return &M.x86.R_ESI;
+ case 7:
+ DECODE_PRINTF("EDI");
+ return &M.x86.R_EDI;
+ }
+ HALT_SYS();
+ return NULL; /* NOTREACHED OR REACHED ON ERROR */
}
/****************************************************************************
PARAMETERS:
-reg - Register to decode
+reg - Register to decode
RETURNS:
Pointer to the appropriate register
@@ -653,40 +690,172 @@ Return a pointer to the register given by the R/RM field of the
modrm byte, for word operands, modified from above for the weirdo
special case of segreg operands. Also enables the decoding of instructions.
****************************************************************************/
-u16 *decode_rm_seg_register(int reg)
+u16* decode_rm_seg_register(
+ int reg)
+{
+ switch (reg) {
+ case 0:
+ DECODE_PRINTF("ES");
+ return &M.x86.R_ES;
+ case 1:
+ DECODE_PRINTF("CS");
+ return &M.x86.R_CS;
+ case 2:
+ DECODE_PRINTF("SS");
+ return &M.x86.R_SS;
+ case 3:
+ DECODE_PRINTF("DS");
+ return &M.x86.R_DS;
+ case 4:
+ DECODE_PRINTF("FS");
+ return &M.x86.R_FS;
+ case 5:
+ DECODE_PRINTF("GS");
+ return &M.x86.R_GS;
+ case 6:
+ case 7:
+ DECODE_PRINTF("ILLEGAL SEGREG");
+ break;
+ }
+ HALT_SYS();
+ return NULL; /* NOT REACHED OR REACHED ON ERROR */
+}
+
+/****************************************************************************
+PARAMETERS:
+scale - scale value of SIB byte
+index - index value of SIB byte
+
+RETURNS:
+Value of scale * index
+
+REMARKS:
+Decodes scale/index of SIB byte and returns relevant offset part of
+effective address.
+****************************************************************************/
+unsigned decode_sib_si(
+ int scale,
+ int index)
+{
+ scale = 1 << scale;
+ if (scale > 1) {
+ DECODE_PRINTF2("[%d*", scale);
+ } else {
+ DECODE_PRINTF("[");
+ }
+ switch (index) {
+ case 0:
+ DECODE_PRINTF("EAX]");
+ return M.x86.R_EAX * index;
+ case 1:
+ DECODE_PRINTF("ECX]");
+ return M.x86.R_ECX * index;
+ case 2:
+ DECODE_PRINTF("EDX]");
+ return M.x86.R_EDX * index;
+ case 3:
+ DECODE_PRINTF("EBX]");
+ return M.x86.R_EBX * index;
+ case 4:
+ DECODE_PRINTF("0]");
+ return 0;
+ case 5:
+ DECODE_PRINTF("EBP]");
+ return M.x86.R_EBP * index;
+ case 6:
+ DECODE_PRINTF("ESI]");
+ return M.x86.R_ESI * index;
+ case 7:
+ DECODE_PRINTF("EDI]");
+ return M.x86.R_EDI * index;
+ }
+ HALT_SYS();
+ return 0; /* NOT REACHED OR REACHED ON ERROR */
+}
+
+/****************************************************************************
+PARAMETERS:
+mod - MOD value of preceding ModR/M byte
+
+RETURNS:
+Offset in memory for the address decoding
+
+REMARKS:
+Decodes SIB addressing byte and returns calculated effective address.
+****************************************************************************/
+unsigned decode_sib_address(
+ int mod)
{
- switch (reg) {
- case 0:
- DECODE_PRINTF("ES");
- return &M.x86.R_ES;
- case 1:
- DECODE_PRINTF("CS");
- return &M.x86.R_CS;
- case 2:
- DECODE_PRINTF("SS");
- return &M.x86.R_SS;
- case 3:
- DECODE_PRINTF("DS");
- return &M.x86.R_DS;
- case 4:
- DECODE_PRINTF("FS");
- return &M.x86.R_FS;
- case 5:
- DECODE_PRINTF("GS");
- return &M.x86.R_GS;
-
- case 6:
- case 7:
- DECODE_PRINTF("ILLEGAL SEGREG");
- break;
- }
- HALT_SYS();
- return NULL; /* NOT REACHED OR REACHED ON ERROR */
+ int sib = fetch_byte_imm();
+ int ss = (sib >> 6) & 0x03;
+ int index = (sib >> 3) & 0x07;
+ int base = sib & 0x07;
+ int offset = 0;
+ int displacement;
+
+ switch (base) {
+ case 0:
+ DECODE_PRINTF("[EAX]");
+ offset = M.x86.R_EAX;
+ break;
+ case 1:
+ DECODE_PRINTF("[ECX]");
+ offset = M.x86.R_ECX;
+ break;
+ case 2:
+ DECODE_PRINTF("[EDX]");
+ offset = M.x86.R_EDX;
+ break;
+ case 3:
+ DECODE_PRINTF("[EBX]");
+ offset = M.x86.R_EBX;
+ break;
+ case 4:
+ DECODE_PRINTF("[ESP]");
+ offset = M.x86.R_ESP;
+ break;
+ case 5:
+ switch (mod) {
+ case 0:
+ displacement = (s32)fetch_long_imm();
+ DECODE_PRINTF2("[%d]", displacement);
+ offset = displacement;
+ break;
+ case 1:
+ displacement = (s8)fetch_byte_imm();
+ DECODE_PRINTF2("[%d][EBP]", displacement);
+ offset = M.x86.R_EBP + displacement;
+ break;
+ case 2:
+ displacement = (s32)fetch_long_imm();
+ DECODE_PRINTF2("[%d][EBP]", displacement);
+ offset = M.x86.R_EBP + displacement;
+ break;
+ default:
+ HALT_SYS();
+ }
+ DECODE_PRINTF("[EAX]");
+ offset = M.x86.R_EAX;
+ break;
+ case 6:
+ DECODE_PRINTF("[ESI]");
+ offset = M.x86.R_ESI;
+ break;
+ case 7:
+ DECODE_PRINTF("[EDI]");
+ offset = M.x86.R_EDI;
+ break;
+ default:
+ HALT_SYS();
+ }
+ offset += decode_sib_si(ss, index);
+ return offset;
+
}
/****************************************************************************
PARAMETERS:
-rm - RM value to decode
+rm - RM value to decode
RETURNS:
Offset in memory for the address decoding
@@ -695,55 +864,87 @@ REMARKS:
Return the offset given by mod=00 addressing. Also enables the
decoding of instructions.
-NOTE: The code which specifies the corresponding segment (ds vs ss)
- below in the case of [BP+..]. The assumption here is that at the
- point that this subroutine is called, the bit corresponding to
- SYSMODE_SEG_DS_SS will be zero. After every instruction
- except the segment override instructions, this bit (as well
- as any bits indicating segment overrides) will be clear. So
- if a SS access is needed, set this bit. Otherwise, DS access
- occurs (unless any of the segment override bits are set).
+NOTE: The code which specifies the corresponding segment (ds vs ss)
+ below in the case of [BP+..]. The assumption here is that at the
+ point that this subroutine is called, the bit corresponding to
+ SYSMODE_SEG_DS_SS will be zero. After every instruction
+ except the segment override instructions, this bit (as well
+ as any bits indicating segment overrides) will be clear. So
+ if a SS access is needed, set this bit. Otherwise, DS access
+ occurs (unless any of the segment override bits are set).
****************************************************************************/
-unsigned decode_rm00_address(int rm)
+unsigned decode_rm00_address(
+ int rm)
{
- unsigned offset;
-
- switch (rm) {
- case 0:
- DECODE_PRINTF("[BX+SI]");
- return M.x86.R_BX + M.x86.R_SI;
- case 1:
- DECODE_PRINTF("[BX+DI]");
- return M.x86.R_BX + M.x86.R_DI;
- case 2:
- DECODE_PRINTF("[BP+SI]");
- M.x86.mode |= SYSMODE_SEG_DS_SS;
- return M.x86.R_BP + M.x86.R_SI;
- case 3:
- DECODE_PRINTF("[BP+DI]");
- M.x86.mode |= SYSMODE_SEG_DS_SS;
- return M.x86.R_BP + M.x86.R_DI;
- case 4:
- DECODE_PRINTF("[SI]");
- return M.x86.R_SI;
- case 5:
- DECODE_PRINTF("[DI]");
- return M.x86.R_DI;
- case 6:
- offset = fetch_word_imm();
- DECODE_PRINTF2("[%04x]", offset);
- return offset;
- case 7:
- DECODE_PRINTF("[BX]");
- return M.x86.R_BX;
- }
- HALT_SYS();
- return 0;
+ unsigned offset;
+
+ if (M.x86.mode & SYSMODE_PREFIX_ADDR) {
+ /* 32-bit addressing */
+ switch (rm) {
+ case 0:
+ DECODE_PRINTF("[EAX]");
+ return M.x86.R_EAX;
+ case 1:
+ DECODE_PRINTF("[ECX]");
+ return M.x86.R_ECX;
+ case 2:
+ DECODE_PRINTF("[EDX]");
+ return M.x86.R_EDX;
+ case 3:
+ DECODE_PRINTF("[EBX]");
+ return M.x86.R_EBX;
+ case 4:
+ return decode_sib_address(0);
+ case 5:
+ offset = fetch_long_imm();
+ DECODE_PRINTF2("[%08x]", offset);
+ return offset;
+ case 6:
+ DECODE_PRINTF("[ESI]");
+ return M.x86.R_ESI;
+ case 7:
+ DECODE_PRINTF("[EDI]");
+ return M.x86.R_EDI;
+ }
+ } else {
+ /* 16-bit addressing */
+ switch (rm) {
+ case 0:
+ DECODE_PRINTF("[BX+SI]");
+ return (M.x86.R_BX + M.x86.R_SI) & 0xffff;
+ case 1:
+ DECODE_PRINTF("[BX+DI]");
+ return (M.x86.R_BX + M.x86.R_DI) & 0xffff;
+ case 2:
+ DECODE_PRINTF("[BP+SI]");
+ M.x86.mode |= SYSMODE_SEG_DS_SS;
+ return (M.x86.R_BP + M.x86.R_SI) & 0xffff;
+ case 3:
+ DECODE_PRINTF("[BP+DI]");
+ M.x86.mode |= SYSMODE_SEG_DS_SS;
+ return (M.x86.R_BP + M.x86.R_DI) & 0xffff;
+ case 4:
+ DECODE_PRINTF("[SI]");
+ return M.x86.R_SI;
+ case 5:
+ DECODE_PRINTF("[DI]");
+ return M.x86.R_DI;
+ case 6:
+ offset = fetch_word_imm();
+ DECODE_PRINTF2("[%04x]", offset);
+ return offset;
+ case 7:
+ DECODE_PRINTF("[BX]");
+ return M.x86.R_BX;
+ }
+ }
+ HALT_SYS();
+ return 0;
}
/****************************************************************************
PARAMETERS:
-rm - RM value to decode
+rm - RM value to decode
RETURNS:
Offset in memory for the address decoding
@@ -752,45 +953,87 @@ REMARKS:
Return the offset given by mod=01 addressing. Also enables the
decoding of instructions.
****************************************************************************/
-unsigned decode_rm01_address(int rm)
+unsigned decode_rm01_address(
+ int rm)
{
- int displacement = (s8) fetch_byte_imm();
- switch (rm) {
- case 0:
- DECODE_PRINTF2("%d[BX+SI]", displacement);
- return M.x86.R_BX + M.x86.R_SI + displacement;
- case 1:
- DECODE_PRINTF2("%d[BX+DI]", displacement);
- return M.x86.R_BX + M.x86.R_DI + displacement;
- case 2:
- DECODE_PRINTF2("%d[BP+SI]", displacement);
- M.x86.mode |= SYSMODE_SEG_DS_SS;
- return M.x86.R_BP + M.x86.R_SI + displacement;
- case 3:
- DECODE_PRINTF2("%d[BP+DI]", displacement);
- M.x86.mode |= SYSMODE_SEG_DS_SS;
- return M.x86.R_BP + M.x86.R_DI + displacement;
- case 4:
- DECODE_PRINTF2("%d[SI]", displacement);
- return M.x86.R_SI + displacement;
- case 5:
- DECODE_PRINTF2("%d[DI]", displacement);
- return M.x86.R_DI + displacement;
- case 6:
- DECODE_PRINTF2("%d[BP]", displacement);
- M.x86.mode |= SYSMODE_SEG_DS_SS;
- return M.x86.R_BP + displacement;
- case 7:
- DECODE_PRINTF2("%d[BX]", displacement);
- return M.x86.R_BX + displacement;
- }
- HALT_SYS();
- return 0; /* SHOULD NOT HAPPEN */
+ int displacement;
+
+ if (M.x86.mode & SYSMODE_PREFIX_ADDR) {
+ /* 32-bit addressing */
+ if (rm != 4)
+ displacement = (s8)fetch_byte_imm();
+ else
+ displacement = 0;
+
+ switch (rm) {
+ case 0:
+ DECODE_PRINTF2("%d[EAX]", displacement);
+ return M.x86.R_EAX + displacement;
+ case 1:
+ DECODE_PRINTF2("%d[ECX]", displacement);
+ return M.x86.R_ECX + displacement;
+ case 2:
+ DECODE_PRINTF2("%d[EDX]", displacement);
+ return M.x86.R_EDX + displacement;
+ case 3:
+ DECODE_PRINTF2("%d[EBX]", displacement);
+ return M.x86.R_EBX + displacement;
+ case 4: {
+ int offset = decode_sib_address(1);
+ displacement = (s8)fetch_byte_imm();
+ DECODE_PRINTF2("[%d]", displacement);
+ return offset + displacement;
+ }
+ case 5:
+ DECODE_PRINTF2("%d[EBP]", displacement);
+ return M.x86.R_EBP + displacement;
+ case 6:
+ DECODE_PRINTF2("%d[ESI]", displacement);
+ return M.x86.R_ESI + displacement;
+ case 7:
+ DECODE_PRINTF2("%d[EDI]", displacement);
+ return M.x86.R_EDI + displacement;
+ }
+ } else {
+ /* 16-bit addressing */
+ displacement = (s8)fetch_byte_imm();
+ switch (rm) {
+ case 0:
+ DECODE_PRINTF2("%d[BX+SI]", displacement);
+ return (M.x86.R_BX + M.x86.R_SI + displacement) & 0xffff;
+ case 1:
+ DECODE_PRINTF2("%d[BX+DI]", displacement);
+ return (M.x86.R_BX + M.x86.R_DI + displacement) & 0xffff;
+ case 2:
+ DECODE_PRINTF2("%d[BP+SI]", displacement);
+ M.x86.mode |= SYSMODE_SEG_DS_SS;
+ return (M.x86.R_BP + M.x86.R_SI + displacement) & 0xffff;
+ case 3:
+ DECODE_PRINTF2("%d[BP+DI]", displacement);
+ M.x86.mode |= SYSMODE_SEG_DS_SS;
+ return (M.x86.R_BP + M.x86.R_DI + displacement) & 0xffff;
+ case 4:
+ DECODE_PRINTF2("%d[SI]", displacement);
+ return (M.x86.R_SI + displacement) & 0xffff;
+ case 5:
+ DECODE_PRINTF2("%d[DI]", displacement);
+ return (M.x86.R_DI + displacement) & 0xffff;
+ case 6:
+ DECODE_PRINTF2("%d[BP]", displacement);
+ M.x86.mode |= SYSMODE_SEG_DS_SS;
+ return (M.x86.R_BP + displacement) & 0xffff;
+ case 7:
+ DECODE_PRINTF2("%d[BX]", displacement);
+ return (M.x86.R_BX + displacement) & 0xffff;
+ }
+ }
+ HALT_SYS();
+ return 0; /* SHOULD NOT HAPPEN */
}
/****************************************************************************
PARAMETERS:
-rm - RM value to decode
+rm - RM value to decode
RETURNS:
Offset in memory for the address decoding
@@ -799,39 +1042,107 @@ REMARKS:
Return the offset given by mod=10 addressing. Also enables the
decoding of instructions.
****************************************************************************/
-unsigned decode_rm10_address(int rm)
+unsigned decode_rm10_address(
+ int rm)
{
- unsigned displacement = (u16) fetch_word_imm();
- switch (rm) {
- case 0:
- DECODE_PRINTF2("%04x[BX+SI]", displacement);
- return M.x86.R_BX + M.x86.R_SI + displacement;
- case 1:
- DECODE_PRINTF2("%04x[BX+DI]", displacement);
- return M.x86.R_BX + M.x86.R_DI + displacement;
- case 2:
- DECODE_PRINTF2("%04x[BP+SI]", displacement);
- M.x86.mode |= SYSMODE_SEG_DS_SS;
- return M.x86.R_BP + M.x86.R_SI + displacement;
- case 3:
- DECODE_PRINTF2("%04x[BP+DI]", displacement);
- M.x86.mode |= SYSMODE_SEG_DS_SS;
- return M.x86.R_BP + M.x86.R_DI + displacement;
- case 4:
- DECODE_PRINTF2("%04x[SI]", displacement);
- return M.x86.R_SI + displacement;
- case 5:
- DECODE_PRINTF2("%04x[DI]", displacement);
- return M.x86.R_DI + displacement;
- case 6:
- DECODE_PRINTF2("%04x[BP]", displacement);
- M.x86.mode |= SYSMODE_SEG_DS_SS;
- return M.x86.R_BP + displacement;
- case 7:
- DECODE_PRINTF2("%04x[BX]", displacement);
- return M.x86.R_BX + displacement;
- }
- HALT_SYS();
- return 0;
- /*NOTREACHED */
+ if (M.x86.mode & SYSMODE_PREFIX_ADDR) {
+ int displacement;
+
+ /* 32-bit addressing */
+ if (rm != 4)
+ displacement = (s32)fetch_long_imm();
+ else
+ displacement = 0;
+
+ switch (rm) {
+ case 0:
+ DECODE_PRINTF2("%d[EAX]", displacement);
+ return M.x86.R_EAX + displacement;
+ case 1:
+ DECODE_PRINTF2("%d[ECX]", displacement);
+ return M.x86.R_ECX + displacement;
+ case 2:
+ DECODE_PRINTF2("%d[EDX]", displacement);
+ return M.x86.R_EDX + displacement;
+ case 3:
+ DECODE_PRINTF2("%d[EBX]", displacement);
+ return M.x86.R_EBX + displacement;
+ case 4: {
+ int offset = decode_sib_address(2);
+ displacement = (s32)fetch_long_imm();
+ DECODE_PRINTF2("[%d]", displacement);
+ return offset + displacement;
+ }
+ case 5:
+ DECODE_PRINTF2("%d[EBP]", displacement);
+ return M.x86.R_EBP + displacement;
+ case 6:
+ DECODE_PRINTF2("%d[ESI]", displacement);
+ return M.x86.R_ESI + displacement;
+ case 7:
+ DECODE_PRINTF2("%d[EDI]", displacement);
+ return M.x86.R_EDI + displacement;
+ }
+ } else {
+ int displacement = (s16)fetch_word_imm();
+
+ /* 16-bit addressing */
+ switch (rm) {
+ case 0:
+ DECODE_PRINTF2("%d[BX+SI]", displacement);
+ return (M.x86.R_BX + M.x86.R_SI + displacement) & 0xffff;
+ case 1:
+ DECODE_PRINTF2("%d[BX+DI]", displacement);
+ return (M.x86.R_BX + M.x86.R_DI + displacement) & 0xffff;
+ case 2:
+ DECODE_PRINTF2("%d[BP+SI]", displacement);
+ M.x86.mode |= SYSMODE_SEG_DS_SS;
+ return (M.x86.R_BP + M.x86.R_SI + displacement) & 0xffff;
+ case 3:
+ DECODE_PRINTF2("%d[BP+DI]", displacement);
+ M.x86.mode |= SYSMODE_SEG_DS_SS;
+ return (M.x86.R_BP + M.x86.R_DI + displacement) & 0xffff;
+ case 4:
+ DECODE_PRINTF2("%d[SI]", displacement);
+ return (M.x86.R_SI + displacement) & 0xffff;
+ case 5:
+ DECODE_PRINTF2("%d[DI]", displacement);
+ return (M.x86.R_DI + displacement) & 0xffff;
+ case 6:
+ DECODE_PRINTF2("%d[BP]", displacement);
+ M.x86.mode |= SYSMODE_SEG_DS_SS;
+ return (M.x86.R_BP + displacement) & 0xffff;
+ case 7:
+ DECODE_PRINTF2("%d[BX]", displacement);
+ return (M.x86.R_BX + displacement) & 0xffff;
+ }
+ }
+ HALT_SYS();
+ return 0; /* SHOULD NOT HAPPEN */
}
+
+
+/****************************************************************************
+PARAMETERS:
+mod - modifier
+rm - RM value to decode
+
+RETURNS:
+Offset in memory for the address decoding, multiplexing calls to
+the decode_rmXX_address functions
+
+REMARKS:
+Return the offset given by "mod" addressing.
+****************************************************************************/
+
+unsigned decode_rmXX_address(int mod, int rm)
+{
+ if(mod == 0)
+ return decode_rm00_address(rm);
+ if(mod == 1)
+ return decode_rm01_address(rm);
+ return decode_rm10_address(rm);
+}
+
+
+
diff --git a/util/vgabios/x86emu/src/x86emu/fpu.c b/util/vgabios/x86emu/src/x86emu/fpu.c
index 40e47aaed..5da363d6d 100644
--- a/util/vgabios/x86emu/src/x86emu/fpu.c
+++ b/util/vgabios/x86emu/src/x86emu/fpu.c
@@ -1,10 +1,10 @@
/****************************************************************************
*
-* Realmode X86 Emulator Library
+* Realmode X86 Emulator Library
*
-* Copyright (C) 1996-1999 SciTech Software, Inc.
-* Copyright (C) David Mosberger-Tang
-* Copyright (C) 1999 Egbert Eich
+* Copyright (C) 1991-2004 SciTech Software, Inc.
+* Copyright (C) David Mosberger-Tang
+* Copyright (C) 1999 Egbert Eich
*
* ========================================================================
*
@@ -28,8 +28,8 @@
*
* ========================================================================
*
-* Language: ANSI C
-* Environment: Any
+* Language: ANSI C
+* Environment: Any
* Developer: Kendall Bennett
*
* Description: This file contains the code to implement the decoding and
@@ -44,901 +44,902 @@
/* opcode=0xd8 */
void x86emuOp_esc_coprocess_d8(u8 X86EMU_UNUSED(op1))
{
- START_OF_INSTR();
- DECODE_PRINTF("ESC D8\n");
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR_NO_TRACE();
+ START_OF_INSTR();
+ DECODE_PRINTF("ESC D8\n");
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR_NO_TRACE();
}
#ifdef DEBUG
static char *x86emu_fpu_op_d9_tab[] = {
- "FLD\tDWORD PTR ", "ESC_D9\t", "FST\tDWORD PTR ", "FSTP\tDWORD PTR ",
- "FLDENV\t", "FLDCW\t", "FSTENV\t", "FSTCW\t",
+ "FLD\tDWORD PTR ", "ESC_D9\t", "FST\tDWORD PTR ", "FSTP\tDWORD PTR ",
+ "FLDENV\t", "FLDCW\t", "FSTENV\t", "FSTCW\t",
- "FLD\tDWORD PTR ", "ESC_D9\t", "FST\tDWORD PTR ", "FSTP\tDWORD PTR ",
- "FLDENV\t", "FLDCW\t", "FSTENV\t", "FSTCW\t",
+ "FLD\tDWORD PTR ", "ESC_D9\t", "FST\tDWORD PTR ", "FSTP\tDWORD PTR ",
+ "FLDENV\t", "FLDCW\t", "FSTENV\t", "FSTCW\t",
- "FLD\tDWORD PTR ", "ESC_D9\t", "FST\tDWORD PTR ", "FSTP\tDWORD PTR ",
- "FLDENV\t", "FLDCW\t", "FSTENV\t", "FSTCW\t",
+ "FLD\tDWORD PTR ", "ESC_D9\t", "FST\tDWORD PTR ", "FSTP\tDWORD PTR ",
+ "FLDENV\t", "FLDCW\t", "FSTENV\t", "FSTCW\t",
};
static char *x86emu_fpu_op_d9_tab1[] = {
- "FLD\t", "FLD\t", "FLD\t", "FLD\t",
- "FLD\t", "FLD\t", "FLD\t", "FLD\t",
+ "FLD\t", "FLD\t", "FLD\t", "FLD\t",
+ "FLD\t", "FLD\t", "FLD\t", "FLD\t",
- "FXCH\t", "FXCH\t", "FXCH\t", "FXCH\t",
- "FXCH\t", "FXCH\t", "FXCH\t", "FXCH\t",
+ "FXCH\t", "FXCH\t", "FXCH\t", "FXCH\t",
+ "FXCH\t", "FXCH\t", "FXCH\t", "FXCH\t",
- "FNOP", "ESC_D9", "ESC_D9", "ESC_D9",
- "ESC_D9", "ESC_D9", "ESC_D9", "ESC_D9",
+ "FNOP", "ESC_D9", "ESC_D9", "ESC_D9",
+ "ESC_D9", "ESC_D9", "ESC_D9", "ESC_D9",
- "FSTP\t", "FSTP\t", "FSTP\t", "FSTP\t",
- "FSTP\t", "FSTP\t", "FSTP\t", "FSTP\t",
+ "FSTP\t", "FSTP\t", "FSTP\t", "FSTP\t",
+ "FSTP\t", "FSTP\t", "FSTP\t", "FSTP\t",
- "FCHS", "FABS", "ESC_D9", "ESC_D9",
- "FTST", "FXAM", "ESC_D9", "ESC_D9",
+ "FCHS", "FABS", "ESC_D9", "ESC_D9",
+ "FTST", "FXAM", "ESC_D9", "ESC_D9",
- "FLD1", "FLDL2T", "FLDL2E", "FLDPI",
- "FLDLG2", "FLDLN2", "FLDZ", "ESC_D9",
+ "FLD1", "FLDL2T", "FLDL2E", "FLDPI",
+ "FLDLG2", "FLDLN2", "FLDZ", "ESC_D9",
- "F2XM1", "FYL2X", "FPTAN", "FPATAN",
- "FXTRACT", "ESC_D9", "FDECSTP", "FINCSTP",
+ "F2XM1", "FYL2X", "FPTAN", "FPATAN",
+ "FXTRACT", "ESC_D9", "FDECSTP", "FINCSTP",
- "FPREM", "FYL2XP1", "FSQRT", "ESC_D9",
- "FRNDINT", "FSCALE", "ESC_D9", "ESC_D9",
+ "FPREM", "FYL2XP1", "FSQRT", "ESC_D9",
+ "FRNDINT", "FSCALE", "ESC_D9", "ESC_D9",
};
-#endif /* DEBUG */
+#endif /* DEBUG */
/* opcode=0xd9 */
void x86emuOp_esc_coprocess_d9(u8 X86EMU_UNUSED(op1))
{
- int mod, rl, rh;
- uint destoffset;
- u8 stkelem;
+ int mod, rl, rh;
+ uint destoffset;
+ u8 stkelem;
- START_OF_INSTR();
- FETCH_DECODE_MODRM(mod, rh, rl);
+ START_OF_INSTR();
+ FETCH_DECODE_MODRM(mod, rh, rl);
#ifdef DEBUG
- if (mod != 3) {
- DECODE_PRINTINSTR32(x86emu_fpu_op_d9_tab, mod, rh, rl);
- } else {
- DECODE_PRINTF(x86emu_fpu_op_d9_tab1[(rh << 3) + rl]);
- }
+ if (mod != 3) {
+ DECODE_PRINTINSTR32(x86emu_fpu_op_d9_tab, mod, rh, rl);
+ } else {
+ DECODE_PRINTF(x86emu_fpu_op_d9_tab1[(rh << 3) + rl]);
+ }
#endif
- switch (mod) {
- case 0:
- destoffset = decode_rm00_address(rl);
- DECODE_PRINTF("\n");
- break;
- case 1:
- destoffset = decode_rm01_address(rl);
- DECODE_PRINTF("\n");
- break;
- case 2:
- destoffset = decode_rm10_address(rl);
- DECODE_PRINTF("\n");
- break;
- case 3: /* register to register */
- stkelem = (u8) rl;
- if (rh < 4) {
- DECODE_PRINTF2("ST(%d)\n", stkelem);
- } else {
- DECODE_PRINTF("\n");
- }
- break;
- }
+ switch (mod) {
+ case 0:
+ destoffset = decode_rm00_address(rl);
+ DECODE_PRINTF("\n");
+ break;
+ case 1:
+ destoffset = decode_rm01_address(rl);
+ DECODE_PRINTF("\n");
+ break;
+ case 2:
+ destoffset = decode_rm10_address(rl);
+ DECODE_PRINTF("\n");
+ break;
+ case 3: /* register to register */
+ stkelem = (u8)rl;
+ if (rh < 4) {
+ DECODE_PRINTF2("ST(%d)\n", stkelem);
+ } else {
+ DECODE_PRINTF("\n");
+ }
+ break;
+ }
#ifdef X86EMU_FPU_PRESENT
- /* execute */
- switch (mod) {
- case 3:
- switch (rh) {
- case 0:
- x86emu_fpu_R_fld(X86EMU_FPU_STKTOP, stkelem);
- break;
- case 1:
- x86emu_fpu_R_fxch(X86EMU_FPU_STKTOP, stkelem);
- break;
- case 2:
- switch (rl) {
- case 0:
- x86emu_fpu_R_nop();
- break;
- default:
- x86emu_fpu_illegal();
- break;
- }
- case 3:
- x86emu_fpu_R_fstp(X86EMU_FPU_STKTOP, stkelem);
- break;
- case 4:
- switch (rl) {
- case 0:
- x86emu_fpu_R_fchs(X86EMU_FPU_STKTOP);
- break;
- case 1:
- x86emu_fpu_R_fabs(X86EMU_FPU_STKTOP);
- break;
- case 4:
- x86emu_fpu_R_ftst(X86EMU_FPU_STKTOP);
- break;
- case 5:
- x86emu_fpu_R_fxam(X86EMU_FPU_STKTOP);
- break;
- default:
- /* 2,3,6,7 */
- x86emu_fpu_illegal();
- break;
- }
- break;
-
- case 5:
- switch (rl) {
- case 0:
- x86emu_fpu_R_fld1(X86EMU_FPU_STKTOP);
- break;
- case 1:
- x86emu_fpu_R_fldl2t(X86EMU_FPU_STKTOP);
- break;
- case 2:
- x86emu_fpu_R_fldl2e(X86EMU_FPU_STKTOP);
- break;
- case 3:
- x86emu_fpu_R_fldpi(X86EMU_FPU_STKTOP);
- break;
- case 4:
- x86emu_fpu_R_fldlg2(X86EMU_FPU_STKTOP);
- break;
- case 5:
- x86emu_fpu_R_fldln2(X86EMU_FPU_STKTOP);
- break;
- case 6:
- x86emu_fpu_R_fldz(X86EMU_FPU_STKTOP);
- break;
- default:
- /* 7 */
- x86emu_fpu_illegal();
- break;
- }
- break;
-
- case 6:
- switch (rl) {
- case 0:
- x86emu_fpu_R_f2xm1(X86EMU_FPU_STKTOP);
- break;
- case 1:
- x86emu_fpu_R_fyl2x(X86EMU_FPU_STKTOP);
- break;
- case 2:
- x86emu_fpu_R_fptan(X86EMU_FPU_STKTOP);
- break;
- case 3:
- x86emu_fpu_R_fpatan(X86EMU_FPU_STKTOP);
- break;
- case 4:
- x86emu_fpu_R_fxtract(X86EMU_FPU_STKTOP);
- break;
- case 5:
- x86emu_fpu_illegal();
- break;
- case 6:
- x86emu_fpu_R_decstp();
- break;
- case 7:
- x86emu_fpu_R_incstp();
- break;
- }
- break;
-
- case 7:
- switch (rl) {
- case 0:
- x86emu_fpu_R_fprem(X86EMU_FPU_STKTOP);
- break;
- case 1:
- x86emu_fpu_R_fyl2xp1(X86EMU_FPU_STKTOP);
- break;
- case 2:
- x86emu_fpu_R_fsqrt(X86EMU_FPU_STKTOP);
- break;
- case 3:
- x86emu_fpu_illegal();
- break;
- case 4:
- x86emu_fpu_R_frndint(X86EMU_FPU_STKTOP);
- break;
- case 5:
- x86emu_fpu_R_fscale(X86EMU_FPU_STKTOP);
- break;
- case 6:
- case 7:
- default:
- x86emu_fpu_illegal();
- break;
- }
- break;
-
- default:
- switch (rh) {
- case 0:
- x86emu_fpu_M_fld(X86EMU_FPU_FLOAT, destoffset);
- break;
- case 1:
- x86emu_fpu_illegal();
- break;
- case 2:
- x86emu_fpu_M_fst(X86EMU_FPU_FLOAT, destoffset);
- break;
- case 3:
- x86emu_fpu_M_fstp(X86EMU_FPU_FLOAT, destoffset);
- break;
- case 4:
- x86emu_fpu_M_fldenv(X86EMU_FPU_WORD, destoffset);
- break;
- case 5:
- x86emu_fpu_M_fldcw(X86EMU_FPU_WORD, destoffset);
- break;
- case 6:
- x86emu_fpu_M_fstenv(X86EMU_FPU_WORD, destoffset);
- break;
- case 7:
- x86emu_fpu_M_fstcw(X86EMU_FPU_WORD, destoffset);
- break;
- }
- }
- }
-#endif /* X86EMU_FPU_PRESENT */
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR_NO_TRACE();
+ /* execute */
+ switch (mod) {
+ case 3:
+ switch (rh) {
+ case 0:
+ x86emu_fpu_R_fld(X86EMU_FPU_STKTOP, stkelem);
+ break;
+ case 1:
+ x86emu_fpu_R_fxch(X86EMU_FPU_STKTOP, stkelem);
+ break;
+ case 2:
+ switch (rl) {
+ case 0:
+ x86emu_fpu_R_nop();
+ break;
+ default:
+ x86emu_fpu_illegal();
+ break;
+ }
+ case 3:
+ x86emu_fpu_R_fstp(X86EMU_FPU_STKTOP, stkelem);
+ break;
+ case 4:
+ switch (rl) {
+ case 0:
+ x86emu_fpu_R_fchs(X86EMU_FPU_STKTOP);
+ break;
+ case 1:
+ x86emu_fpu_R_fabs(X86EMU_FPU_STKTOP);
+ break;
+ case 4:
+ x86emu_fpu_R_ftst(X86EMU_FPU_STKTOP);
+ break;
+ case 5:
+ x86emu_fpu_R_fxam(X86EMU_FPU_STKTOP);
+ break;
+ default:
+ /* 2,3,6,7 */
+ x86emu_fpu_illegal();
+ break;
+ }
+ break;
+
+ case 5:
+ switch (rl) {
+ case 0:
+ x86emu_fpu_R_fld1(X86EMU_FPU_STKTOP);
+ break;
+ case 1:
+ x86emu_fpu_R_fldl2t(X86EMU_FPU_STKTOP);
+ break;
+ case 2:
+ x86emu_fpu_R_fldl2e(X86EMU_FPU_STKTOP);
+ break;
+ case 3:
+ x86emu_fpu_R_fldpi(X86EMU_FPU_STKTOP);
+ break;
+ case 4:
+ x86emu_fpu_R_fldlg2(X86EMU_FPU_STKTOP);
+ break;
+ case 5:
+ x86emu_fpu_R_fldln2(X86EMU_FPU_STKTOP);
+ break;
+ case 6:
+ x86emu_fpu_R_fldz(X86EMU_FPU_STKTOP);
+ break;
+ default:
+ /* 7 */
+ x86emu_fpu_illegal();
+ break;
+ }
+ break;
+
+ case 6:
+ switch (rl) {
+ case 0:
+ x86emu_fpu_R_f2xm1(X86EMU_FPU_STKTOP);
+ break;
+ case 1:
+ x86emu_fpu_R_fyl2x(X86EMU_FPU_STKTOP);
+ break;
+ case 2:
+ x86emu_fpu_R_fptan(X86EMU_FPU_STKTOP);
+ break;
+ case 3:
+ x86emu_fpu_R_fpatan(X86EMU_FPU_STKTOP);
+ break;
+ case 4:
+ x86emu_fpu_R_fxtract(X86EMU_FPU_STKTOP);
+ break;
+ case 5:
+ x86emu_fpu_illegal();
+ break;
+ case 6:
+ x86emu_fpu_R_decstp();
+ break;
+ case 7:
+ x86emu_fpu_R_incstp();
+ break;
+ }
+ break;
+
+ case 7:
+ switch (rl) {
+ case 0:
+ x86emu_fpu_R_fprem(X86EMU_FPU_STKTOP);
+ break;
+ case 1:
+ x86emu_fpu_R_fyl2xp1(X86EMU_FPU_STKTOP);
+ break;
+ case 2:
+ x86emu_fpu_R_fsqrt(X86EMU_FPU_STKTOP);
+ break;
+ case 3:
+ x86emu_fpu_illegal();
+ break;
+ case 4:
+ x86emu_fpu_R_frndint(X86EMU_FPU_STKTOP);
+ break;
+ case 5:
+ x86emu_fpu_R_fscale(X86EMU_FPU_STKTOP);
+ break;
+ case 6:
+ case 7:
+ default:
+ x86emu_fpu_illegal();
+ break;
+ }
+ break;
+
+ default:
+ switch (rh) {
+ case 0:
+ x86emu_fpu_M_fld(X86EMU_FPU_FLOAT, destoffset);
+ break;
+ case 1:
+ x86emu_fpu_illegal();
+ break;
+ case 2:
+ x86emu_fpu_M_fst(X86EMU_FPU_FLOAT, destoffset);
+ break;
+ case 3:
+ x86emu_fpu_M_fstp(X86EMU_FPU_FLOAT, destoffset);
+ break;
+ case 4:
+ x86emu_fpu_M_fldenv(X86EMU_FPU_WORD, destoffset);
+ break;
+ case 5:
+ x86emu_fpu_M_fldcw(X86EMU_FPU_WORD, destoffset);
+ break;
+ case 6:
+ x86emu_fpu_M_fstenv(X86EMU_FPU_WORD, destoffset);
+ break;
+ case 7:
+ x86emu_fpu_M_fstcw(X86EMU_FPU_WORD, destoffset);
+ break;
+ }
+ }
+ }
+#endif /* X86EMU_FPU_PRESENT */
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR_NO_TRACE();
}
#ifdef DEBUG
char *x86emu_fpu_op_da_tab[] = {
- "FIADD\tDWORD PTR ", "FIMUL\tDWORD PTR ", "FICOM\tDWORD PTR ",
- "FICOMP\tDWORD PTR ",
- "FISUB\tDWORD PTR ", "FISUBR\tDWORD PTR ", "FIDIV\tDWORD PTR ",
- "FIDIVR\tDWORD PTR ",
-
- "FIADD\tDWORD PTR ", "FIMUL\tDWORD PTR ", "FICOM\tDWORD PTR ",
- "FICOMP\tDWORD PTR ",
- "FISUB\tDWORD PTR ", "FISUBR\tDWORD PTR ", "FIDIV\tDWORD PTR ",
- "FIDIVR\tDWORD PTR ",
-
- "FIADD\tDWORD PTR ", "FIMUL\tDWORD PTR ", "FICOM\tDWORD PTR ",
- "FICOMP\tDWORD PTR ",
- "FISUB\tDWORD PTR ", "FISUBR\tDWORD PTR ", "FIDIV\tDWORD PTR ",
- "FIDIVR\tDWORD PTR ",
-
- "ESC_DA ", "ESC_DA ", "ESC_DA ", "ESC_DA ",
- "ESC_DA ", "ESC_DA ", "ESC_DA ", "ESC_DA ",
+ "FIADD\tDWORD PTR ", "FIMUL\tDWORD PTR ", "FICOM\tDWORD PTR ",
+ "FICOMP\tDWORD PTR ",
+ "FISUB\tDWORD PTR ", "FISUBR\tDWORD PTR ", "FIDIV\tDWORD PTR ",
+ "FIDIVR\tDWORD PTR ",
+
+ "FIADD\tDWORD PTR ", "FIMUL\tDWORD PTR ", "FICOM\tDWORD PTR ",
+ "FICOMP\tDWORD PTR ",
+ "FISUB\tDWORD PTR ", "FISUBR\tDWORD PTR ", "FIDIV\tDWORD PTR ",
+ "FIDIVR\tDWORD PTR ",
+
+ "FIADD\tDWORD PTR ", "FIMUL\tDWORD PTR ", "FICOM\tDWORD PTR ",
+ "FICOMP\tDWORD PTR ",
+ "FISUB\tDWORD PTR ", "FISUBR\tDWORD PTR ", "FIDIV\tDWORD PTR ",
+ "FIDIVR\tDWORD PTR ",
+
+ "ESC_DA ", "ESC_DA ", "ESC_DA ", "ESC_DA ",
+ "ESC_DA ", "ESC_DA ", "ESC_DA ", "ESC_DA ",
};
-#endif /* DEBUG */
+#endif /* DEBUG */
/* opcode=0xda */
void x86emuOp_esc_coprocess_da(u8 X86EMU_UNUSED(op1))
{
- int mod, rl, rh;
- uint destoffset;
- u8 stkelem;
-
- START_OF_INSTR();
- FETCH_DECODE_MODRM(mod, rh, rl);
- DECODE_PRINTINSTR32(x86emu_fpu_op_da_tab, mod, rh, rl);
- switch (mod) {
- case 0:
- destoffset = decode_rm00_address(rl);
- DECODE_PRINTF("\n");
- break;
- case 1:
- destoffset = decode_rm01_address(rl);
- DECODE_PRINTF("\n");
- break;
- case 2:
- destoffset = decode_rm10_address(rl);
- DECODE_PRINTF("\n");
- break;
- case 3: /* register to register */
- stkelem = (u8) rl;
- DECODE_PRINTF2("\tST(%d),ST\n", stkelem);
- break;
- }
+ int mod, rl, rh;
+ uint destoffset;
+ u8 stkelem;
+
+ START_OF_INSTR();
+ FETCH_DECODE_MODRM(mod, rh, rl);
+ DECODE_PRINTINSTR32(x86emu_fpu_op_da_tab, mod, rh, rl);
+ switch (mod) {
+ case 0:
+ destoffset = decode_rm00_address(rl);
+ DECODE_PRINTF("\n");
+ break;
+ case 1:
+ destoffset = decode_rm01_address(rl);
+ DECODE_PRINTF("\n");
+ break;
+ case 2:
+ destoffset = decode_rm10_address(rl);
+ DECODE_PRINTF("\n");
+ break;
+ case 3: /* register to register */
+ stkelem = (u8)rl;
+ DECODE_PRINTF2("\tST(%d),ST\n", stkelem);
+ break;
+ }
#ifdef X86EMU_FPU_PRESENT
- switch (mod) {
- case 3:
- x86emu_fpu_illegal();
- break;
- default:
- switch (rh) {
- case 0:
- x86emu_fpu_M_iadd(X86EMU_FPU_SHORT, destoffset);
- break;
- case 1:
- x86emu_fpu_M_imul(X86EMU_FPU_SHORT, destoffset);
- break;
- case 2:
- x86emu_fpu_M_icom(X86EMU_FPU_SHORT, destoffset);
- break;
- case 3:
- x86emu_fpu_M_icomp(X86EMU_FPU_SHORT, destoffset);
- break;
- case 4:
- x86emu_fpu_M_isub(X86EMU_FPU_SHORT, destoffset);
- break;
- case 5:
- x86emu_fpu_M_isubr(X86EMU_FPU_SHORT, destoffset);
- break;
- case 6:
- x86emu_fpu_M_idiv(X86EMU_FPU_SHORT, destoffset);
- break;
- case 7:
- x86emu_fpu_M_idivr(X86EMU_FPU_SHORT, destoffset);
- break;
- }
- }
+ switch (mod) {
+ case 3:
+ x86emu_fpu_illegal();
+ break;
+ default:
+ switch (rh) {
+ case 0:
+ x86emu_fpu_M_iadd(X86EMU_FPU_SHORT, destoffset);
+ break;
+ case 1:
+ x86emu_fpu_M_imul(X86EMU_FPU_SHORT, destoffset);
+ break;
+ case 2:
+ x86emu_fpu_M_icom(X86EMU_FPU_SHORT, destoffset);
+ break;
+ case 3:
+ x86emu_fpu_M_icomp(X86EMU_FPU_SHORT, destoffset);
+ break;
+ case 4:
+ x86emu_fpu_M_isub(X86EMU_FPU_SHORT, destoffset);
+ break;
+ case 5:
+ x86emu_fpu_M_isubr(X86EMU_FPU_SHORT, destoffset);
+ break;
+ case 6:
+ x86emu_fpu_M_idiv(X86EMU_FPU_SHORT, destoffset);
+ break;
+ case 7:
+ x86emu_fpu_M_idivr(X86EMU_FPU_SHORT, destoffset);
+ break;
+ }
+ }
#endif
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR_NO_TRACE();
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR_NO_TRACE();
}
#ifdef DEBUG
char *x86emu_fpu_op_db_tab[] = {
- "FILD\tDWORD PTR ", "ESC_DB\t19", "FIST\tDWORD PTR ", "FISTP\tDWORD PTR ",
- "ESC_DB\t1C", "FLD\tTBYTE PTR ", "ESC_DB\t1E", "FSTP\tTBYTE PTR ",
+ "FILD\tDWORD PTR ", "ESC_DB\t19", "FIST\tDWORD PTR ", "FISTP\tDWORD PTR ",
+ "ESC_DB\t1C", "FLD\tTBYTE PTR ", "ESC_DB\t1E", "FSTP\tTBYTE PTR ",
- "FILD\tDWORD PTR ", "ESC_DB\t19", "FIST\tDWORD PTR ", "FISTP\tDWORD PTR ",
- "ESC_DB\t1C", "FLD\tTBYTE PTR ", "ESC_DB\t1E", "FSTP\tTBYTE PTR ",
+ "FILD\tDWORD PTR ", "ESC_DB\t19", "FIST\tDWORD PTR ", "FISTP\tDWORD PTR ",
+ "ESC_DB\t1C", "FLD\tTBYTE PTR ", "ESC_DB\t1E", "FSTP\tTBYTE PTR ",
- "FILD\tDWORD PTR ", "ESC_DB\t19", "FIST\tDWORD PTR ", "FISTP\tDWORD PTR ",
- "ESC_DB\t1C", "FLD\tTBYTE PTR ", "ESC_DB\t1E", "FSTP\tTBYTE PTR ",
+ "FILD\tDWORD PTR ", "ESC_DB\t19", "FIST\tDWORD PTR ", "FISTP\tDWORD PTR ",
+ "ESC_DB\t1C", "FLD\tTBYTE PTR ", "ESC_DB\t1E", "FSTP\tTBYTE PTR ",
};
-#endif /* DEBUG */
+#endif /* DEBUG */
/* opcode=0xdb */
void x86emuOp_esc_coprocess_db(u8 X86EMU_UNUSED(op1))
{
- int mod, rl, rh;
- uint destoffset;
+ int mod, rl, rh;
+ uint destoffset;
- START_OF_INSTR();
- FETCH_DECODE_MODRM(mod, rh, rl);
+ START_OF_INSTR();
+ FETCH_DECODE_MODRM(mod, rh, rl);
#ifdef DEBUG
- if (mod != 3) {
- DECODE_PRINTINSTR32(x86emu_fpu_op_db_tab, mod, rh, rl);
- } else if (rh == 4) { /* === 11 10 0 nnn */
- switch (rl) {
- case 0:
- DECODE_PRINTF("FENI\n");
- break;
- case 1:
- DECODE_PRINTF("FDISI\n");
- break;
- case 2:
- DECODE_PRINTF("FCLEX\n");
- break;
- case 3:
- DECODE_PRINTF("FINIT\n");
- break;
- }
- } else {
- DECODE_PRINTF2("ESC_DB %0x\n", (mod << 6) + (rh << 3) + (rl));
- }
-#endif /* DEBUG */
- switch (mod) {
- case 0:
- destoffset = decode_rm00_address(rl);
- break;
- case 1:
- destoffset = decode_rm01_address(rl);
- break;
- case 2:
- destoffset = decode_rm10_address(rl);
- break;
- case 3: /* register to register */
- break;
- }
+ if (mod != 3) {
+ DECODE_PRINTINSTR32(x86emu_fpu_op_db_tab, mod, rh, rl);
+ } else if (rh == 4) { /* === 11 10 0 nnn */
+ switch (rl) {
+ case 0:
+ DECODE_PRINTF("FENI\n");
+ break;
+ case 1:
+ DECODE_PRINTF("FDISI\n");
+ break;
+ case 2:
+ DECODE_PRINTF("FCLEX\n");
+ break;
+ case 3:
+ DECODE_PRINTF("FINIT\n");
+ break;
+ }
+ } else {
+ DECODE_PRINTF2("ESC_DB %0x\n", (mod << 6) + (rh << 3) + (rl));
+ }
+#endif /* DEBUG */
+ switch (mod) {
+ case 0:
+ destoffset = decode_rm00_address(rl);
+ break;
+ case 1:
+ destoffset = decode_rm01_address(rl);
+ break;
+ case 2:
+ destoffset = decode_rm10_address(rl);
+ break;
+ case 3: /* register to register */
+ break;
+ }
#ifdef X86EMU_FPU_PRESENT
- /* execute */
- switch (mod) {
- case 3:
- switch (rh) {
- case 4:
- switch (rl) {
- case 0:
- x86emu_fpu_R_feni();
- break;
- case 1:
- x86emu_fpu_R_fdisi();
- break;
- case 2:
- x86emu_fpu_R_fclex();
- break;
- case 3:
- x86emu_fpu_R_finit();
- break;
- default:
- x86emu_fpu_illegal();
- break;
- }
- break;
- default:
- x86emu_fpu_illegal();
- break;
- }
- break;
- default:
- switch (rh) {
- case 0:
- x86emu_fpu_M_fild(X86EMU_FPU_SHORT, destoffset);
- break;
- case 1:
- x86emu_fpu_illegal();
- break;
- case 2:
- x86emu_fpu_M_fist(X86EMU_FPU_SHORT, destoffset);
- break;
- case 3:
- x86emu_fpu_M_fistp(X86EMU_FPU_SHORT, destoffset);
- break;
- case 4:
- x86emu_fpu_illegal();
- break;
- case 5:
- x86emu_fpu_M_fld(X86EMU_FPU_LDBL, destoffset);
- break;
- case 6:
- x86emu_fpu_illegal();
- break;
- case 7:
- x86emu_fpu_M_fstp(X86EMU_FPU_LDBL, destoffset);
- break;
- }
- }
+ /* execute */
+ switch (mod) {
+ case 3:
+ switch (rh) {
+ case 4:
+ switch (rl) {
+ case 0:
+ x86emu_fpu_R_feni();
+ break;
+ case 1:
+ x86emu_fpu_R_fdisi();
+ break;
+ case 2:
+ x86emu_fpu_R_fclex();
+ break;
+ case 3:
+ x86emu_fpu_R_finit();
+ break;
+ default:
+ x86emu_fpu_illegal();
+ break;
+ }
+ break;
+ default:
+ x86emu_fpu_illegal();
+ break;
+ }
+ break;
+ default:
+ switch (rh) {
+ case 0:
+ x86emu_fpu_M_fild(X86EMU_FPU_SHORT, destoffset);
+ break;
+ case 1:
+ x86emu_fpu_illegal();
+ break;
+ case 2:
+ x86emu_fpu_M_fist(X86EMU_FPU_SHORT, destoffset);
+ break;
+ case 3:
+ x86emu_fpu_M_fistp(X86EMU_FPU_SHORT, destoffset);
+ break;
+ case 4:
+ x86emu_fpu_illegal();
+ break;
+ case 5:
+ x86emu_fpu_M_fld(X86EMU_FPU_LDBL, destoffset);
+ break;
+ case 6:
+ x86emu_fpu_illegal();
+ break;
+ case 7:
+ x86emu_fpu_M_fstp(X86EMU_FPU_LDBL, destoffset);
+ break;
+ }
+ }
#endif
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR_NO_TRACE();
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR_NO_TRACE();
}
#ifdef DEBUG
char *x86emu_fpu_op_dc_tab[] = {
- "FADD\tQWORD PTR ", "FMUL\tQWORD PTR ", "FCOM\tQWORD PTR ",
- "FCOMP\tQWORD PTR ",
- "FSUB\tQWORD PTR ", "FSUBR\tQWORD PTR ", "FDIV\tQWORD PTR ",
- "FDIVR\tQWORD PTR ",
-
- "FADD\tQWORD PTR ", "FMUL\tQWORD PTR ", "FCOM\tQWORD PTR ",
- "FCOMP\tQWORD PTR ",
- "FSUB\tQWORD PTR ", "FSUBR\tQWORD PTR ", "FDIV\tQWORD PTR ",
- "FDIVR\tQWORD PTR ",
-
- "FADD\tQWORD PTR ", "FMUL\tQWORD PTR ", "FCOM\tQWORD PTR ",
- "FCOMP\tQWORD PTR ",
- "FSUB\tQWORD PTR ", "FSUBR\tQWORD PTR ", "FDIV\tQWORD PTR ",
- "FDIVR\tQWORD PTR ",
-
- "FADD\t", "FMUL\t", "FCOM\t", "FCOMP\t",
- "FSUBR\t", "FSUB\t", "FDIVR\t", "FDIV\t",
+ "FADD\tQWORD PTR ", "FMUL\tQWORD PTR ", "FCOM\tQWORD PTR ",
+ "FCOMP\tQWORD PTR ",
+ "FSUB\tQWORD PTR ", "FSUBR\tQWORD PTR ", "FDIV\tQWORD PTR ",
+ "FDIVR\tQWORD PTR ",
+
+ "FADD\tQWORD PTR ", "FMUL\tQWORD PTR ", "FCOM\tQWORD PTR ",
+ "FCOMP\tQWORD PTR ",
+ "FSUB\tQWORD PTR ", "FSUBR\tQWORD PTR ", "FDIV\tQWORD PTR ",
+ "FDIVR\tQWORD PTR ",
+
+ "FADD\tQWORD PTR ", "FMUL\tQWORD PTR ", "FCOM\tQWORD PTR ",
+ "FCOMP\tQWORD PTR ",
+ "FSUB\tQWORD PTR ", "FSUBR\tQWORD PTR ", "FDIV\tQWORD PTR ",
+ "FDIVR\tQWORD PTR ",
+
+ "FADD\t", "FMUL\t", "FCOM\t", "FCOMP\t",
+ "FSUBR\t", "FSUB\t", "FDIVR\t", "FDIV\t",
};
-#endif /* DEBUG */
+#endif /* DEBUG */
/* opcode=0xdc */
void x86emuOp_esc_coprocess_dc(u8 X86EMU_UNUSED(op1))
{
- int mod, rl, rh;
- uint destoffset;
- u8 stkelem;
-
- START_OF_INSTR();
- FETCH_DECODE_MODRM(mod, rh, rl);
- DECODE_PRINTINSTR32(x86emu_fpu_op_dc_tab, mod, rh, rl);
- switch (mod) {
- case 0:
- destoffset = decode_rm00_address(rl);
- DECODE_PRINTF("\n");
- break;
- case 1:
- destoffset = decode_rm01_address(rl);
- DECODE_PRINTF("\n");
- break;
- case 2:
- destoffset = decode_rm10_address(rl);
- DECODE_PRINTF("\n");
- break;
- case 3: /* register to register */
- stkelem = (u8) rl;
- DECODE_PRINTF2("\tST(%d),ST\n", stkelem);
- break;
- }
+ int mod, rl, rh;
+ uint destoffset;
+ u8 stkelem;
+
+ START_OF_INSTR();
+ FETCH_DECODE_MODRM(mod, rh, rl);
+ DECODE_PRINTINSTR32(x86emu_fpu_op_dc_tab, mod, rh, rl);
+ switch (mod) {
+ case 0:
+ destoffset = decode_rm00_address(rl);
+ DECODE_PRINTF("\n");
+ break;
+ case 1:
+ destoffset = decode_rm01_address(rl);
+ DECODE_PRINTF("\n");
+ break;
+ case 2:
+ destoffset = decode_rm10_address(rl);
+ DECODE_PRINTF("\n");
+ break;
+ case 3: /* register to register */
+ stkelem = (u8)rl;
+ DECODE_PRINTF2("\tST(%d),ST\n", stkelem);
+ break;
+ }
#ifdef X86EMU_FPU_PRESENT
- /* execute */
- switch (mod) {
- case 3:
- switch (rh) {
- case 0:
- x86emu_fpu_R_fadd(stkelem, X86EMU_FPU_STKTOP);
- break;
- case 1:
- x86emu_fpu_R_fmul(stkelem, X86EMU_FPU_STKTOP);
- break;
- case 2:
- x86emu_fpu_R_fcom(stkelem, X86EMU_FPU_STKTOP);
- break;
- case 3:
- x86emu_fpu_R_fcomp(stkelem, X86EMU_FPU_STKTOP);
- break;
- case 4:
- x86emu_fpu_R_fsubr(stkelem, X86EMU_FPU_STKTOP);
- break;
- case 5:
- x86emu_fpu_R_fsub(stkelem, X86EMU_FPU_STKTOP);
- break;
- case 6:
- x86emu_fpu_R_fdivr(stkelem, X86EMU_FPU_STKTOP);
- break;
- case 7:
- x86emu_fpu_R_fdiv(stkelem, X86EMU_FPU_STKTOP);
- break;
- }
- break;
- default:
- switch (rh) {
- case 0:
- x86emu_fpu_M_fadd(X86EMU_FPU_DOUBLE, destoffset);
- break;
- case 1:
- x86emu_fpu_M_fmul(X86EMU_FPU_DOUBLE, destoffset);
- break;
- case 2:
- x86emu_fpu_M_fcom(X86EMU_FPU_DOUBLE, destoffset);
- break;
- case 3:
- x86emu_fpu_M_fcomp(X86EMU_FPU_DOUBLE, destoffset);
- break;
- case 4:
- x86emu_fpu_M_fsub(X86EMU_FPU_DOUBLE, destoffset);
- break;
- case 5:
- x86emu_fpu_M_fsubr(X86EMU_FPU_DOUBLE, destoffset);
- break;
- case 6:
- x86emu_fpu_M_fdiv(X86EMU_FPU_DOUBLE, destoffset);
- break;
- case 7:
- x86emu_fpu_M_fdivr(X86EMU_FPU_DOUBLE, destoffset);
- break;
- }
- }
+ /* execute */
+ switch (mod) {
+ case 3:
+ switch (rh) {
+ case 0:
+ x86emu_fpu_R_fadd(stkelem, X86EMU_FPU_STKTOP);
+ break;
+ case 1:
+ x86emu_fpu_R_fmul(stkelem, X86EMU_FPU_STKTOP);
+ break;
+ case 2:
+ x86emu_fpu_R_fcom(stkelem, X86EMU_FPU_STKTOP);
+ break;
+ case 3:
+ x86emu_fpu_R_fcomp(stkelem, X86EMU_FPU_STKTOP);
+ break;
+ case 4:
+ x86emu_fpu_R_fsubr(stkelem, X86EMU_FPU_STKTOP);
+ break;
+ case 5:
+ x86emu_fpu_R_fsub(stkelem, X86EMU_FPU_STKTOP);
+ break;
+ case 6:
+ x86emu_fpu_R_fdivr(stkelem, X86EMU_FPU_STKTOP);
+ break;
+ case 7:
+ x86emu_fpu_R_fdiv(stkelem, X86EMU_FPU_STKTOP);
+ break;
+ }
+ break;
+ default:
+ switch (rh) {
+ case 0:
+ x86emu_fpu_M_fadd(X86EMU_FPU_DOUBLE, destoffset);
+ break;
+ case 1:
+ x86emu_fpu_M_fmul(X86EMU_FPU_DOUBLE, destoffset);
+ break;
+ case 2:
+ x86emu_fpu_M_fcom(X86EMU_FPU_DOUBLE, destoffset);
+ break;
+ case 3:
+ x86emu_fpu_M_fcomp(X86EMU_FPU_DOUBLE, destoffset);
+ break;
+ case 4:
+ x86emu_fpu_M_fsub(X86EMU_FPU_DOUBLE, destoffset);
+ break;
+ case 5:
+ x86emu_fpu_M_fsubr(X86EMU_FPU_DOUBLE, destoffset);
+ break;
+ case 6:
+ x86emu_fpu_M_fdiv(X86EMU_FPU_DOUBLE, destoffset);
+ break;
+ case 7:
+ x86emu_fpu_M_fdivr(X86EMU_FPU_DOUBLE, destoffset);
+ break;
+ }
+ }
#endif
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR_NO_TRACE();
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR_NO_TRACE();
}
#ifdef DEBUG
static char *x86emu_fpu_op_dd_tab[] = {
- "FLD\tQWORD PTR ", "ESC_DD\t29,", "FST\tQWORD PTR ", "FSTP\tQWORD PTR ",
- "FRSTOR\t", "ESC_DD\t2D,", "FSAVE\t", "FSTSW\t",
+ "FLD\tQWORD PTR ", "ESC_DD\t29,", "FST\tQWORD PTR ", "FSTP\tQWORD PTR ",
+ "FRSTOR\t", "ESC_DD\t2D,", "FSAVE\t", "FSTSW\t",
- "FLD\tQWORD PTR ", "ESC_DD\t29,", "FST\tQWORD PTR ", "FSTP\tQWORD PTR ",
- "FRSTOR\t", "ESC_DD\t2D,", "FSAVE\t", "FSTSW\t",
+ "FLD\tQWORD PTR ", "ESC_DD\t29,", "FST\tQWORD PTR ", "FSTP\tQWORD PTR ",
+ "FRSTOR\t", "ESC_DD\t2D,", "FSAVE\t", "FSTSW\t",
- "FLD\tQWORD PTR ", "ESC_DD\t29,", "FST\tQWORD PTR ", "FSTP\tQWORD PTR ",
- "FRSTOR\t", "ESC_DD\t2D,", "FSAVE\t", "FSTSW\t",
+ "FLD\tQWORD PTR ", "ESC_DD\t29,", "FST\tQWORD PTR ", "FSTP\tQWORD PTR ",
+ "FRSTOR\t", "ESC_DD\t2D,", "FSAVE\t", "FSTSW\t",
- "FFREE\t", "FXCH\t", "FST\t", "FSTP\t",
- "ESC_DD\t2C,", "ESC_DD\t2D,", "ESC_DD\t2E,", "ESC_DD\t2F,",
+ "FFREE\t", "FXCH\t", "FST\t", "FSTP\t",
+ "ESC_DD\t2C,", "ESC_DD\t2D,", "ESC_DD\t2E,", "ESC_DD\t2F,",
};
-#endif /* DEBUG */
+#endif /* DEBUG */
/* opcode=0xdd */
void x86emuOp_esc_coprocess_dd(u8 X86EMU_UNUSED(op1))
{
- int mod, rl, rh;
- uint destoffset;
- u8 stkelem;
-
- START_OF_INSTR();
- FETCH_DECODE_MODRM(mod, rh, rl);
- DECODE_PRINTINSTR32(x86emu_fpu_op_dd_tab, mod, rh, rl);
- switch (mod) {
- case 0:
- destoffset = decode_rm00_address(rl);
- DECODE_PRINTF("\n");
- break;
- case 1:
- destoffset = decode_rm01_address(rl);
- DECODE_PRINTF("\n");
- break;
- case 2:
- destoffset = decode_rm10_address(rl);
- DECODE_PRINTF("\n");
- break;
- case 3: /* register to register */
- stkelem = (u8) rl;
- DECODE_PRINTF2("\tST(%d),ST\n", stkelem);
- break;
- }
+ int mod, rl, rh;
+ uint destoffset;
+ u8 stkelem;
+
+ START_OF_INSTR();
+ FETCH_DECODE_MODRM(mod, rh, rl);
+ DECODE_PRINTINSTR32(x86emu_fpu_op_dd_tab, mod, rh, rl);
+ switch (mod) {
+ case 0:
+ destoffset = decode_rm00_address(rl);
+ DECODE_PRINTF("\n");
+ break;
+ case 1:
+ destoffset = decode_rm01_address(rl);
+ DECODE_PRINTF("\n");
+ break;
+ case 2:
+ destoffset = decode_rm10_address(rl);
+ DECODE_PRINTF("\n");
+ break;
+ case 3: /* register to register */
+ stkelem = (u8)rl;
+ DECODE_PRINTF2("\tST(%d),ST\n", stkelem);
+ break;
+ }
#ifdef X86EMU_FPU_PRESENT
- switch (mod) {
- case 3:
- switch (rh) {
- case 0:
- x86emu_fpu_R_ffree(stkelem);
- break;
- case 1:
- x86emu_fpu_R_fxch(stkelem);
- break;
- case 2:
- x86emu_fpu_R_fst(stkelem); /* register version */
- break;
- case 3:
- x86emu_fpu_R_fstp(stkelem); /* register version */
- break;
- default:
- x86emu_fpu_illegal();
- break;
- }
- break;
- default:
- switch (rh) {
- case 0:
- x86emu_fpu_M_fld(X86EMU_FPU_DOUBLE, destoffset);
- break;
- case 1:
- x86emu_fpu_illegal();
- break;
- case 2:
- x86emu_fpu_M_fst(X86EMU_FPU_DOUBLE, destoffset);
- break;
- case 3:
- x86emu_fpu_M_fstp(X86EMU_FPU_DOUBLE, destoffset);
- break;
- case 4:
- x86emu_fpu_M_frstor(X86EMU_FPU_WORD, destoffset);
- break;
- case 5:
- x86emu_fpu_illegal();
- break;
- case 6:
- x86emu_fpu_M_fsave(X86EMU_FPU_WORD, destoffset);
- break;
- case 7:
- x86emu_fpu_M_fstsw(X86EMU_FPU_WORD, destoffset);
- break;
- }
- }
+ switch (mod) {
+ case 3:
+ switch (rh) {
+ case 0:
+ x86emu_fpu_R_ffree(stkelem);
+ break;
+ case 1:
+ x86emu_fpu_R_fxch(stkelem);
+ break;
+ case 2:
+ x86emu_fpu_R_fst(stkelem); /* register version */
+ break;
+ case 3:
+ x86emu_fpu_R_fstp(stkelem); /* register version */
+ break;
+ default:
+ x86emu_fpu_illegal();
+ break;
+ }
+ break;
+ default:
+ switch (rh) {
+ case 0:
+ x86emu_fpu_M_fld(X86EMU_FPU_DOUBLE, destoffset);
+ break;
+ case 1:
+ x86emu_fpu_illegal();
+ break;
+ case 2:
+ x86emu_fpu_M_fst(X86EMU_FPU_DOUBLE, destoffset);
+ break;
+ case 3:
+ x86emu_fpu_M_fstp(X86EMU_FPU_DOUBLE, destoffset);
+ break;
+ case 4:
+ x86emu_fpu_M_frstor(X86EMU_FPU_WORD, destoffset);
+ break;
+ case 5:
+ x86emu_fpu_illegal();
+ break;
+ case 6:
+ x86emu_fpu_M_fsave(X86EMU_FPU_WORD, destoffset);
+ break;
+ case 7:
+ x86emu_fpu_M_fstsw(X86EMU_FPU_WORD, destoffset);
+ break;
+ }
+ }
#endif
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR_NO_TRACE();
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR_NO_TRACE();
}
#ifdef DEBUG
-static char *x86emu_fpu_op_de_tab[] = {
- "FIADD\tWORD PTR ", "FIMUL\tWORD PTR ", "FICOM\tWORD PTR ",
- "FICOMP\tWORD PTR ",
- "FISUB\tWORD PTR ", "FISUBR\tWORD PTR ", "FIDIV\tWORD PTR ",
- "FIDIVR\tWORD PTR ",
-
- "FIADD\tWORD PTR ", "FIMUL\tWORD PTR ", "FICOM\tWORD PTR ",
- "FICOMP\tWORD PTR ",
- "FISUB\tWORD PTR ", "FISUBR\tWORD PTR ", "FIDIV\tWORD PTR ",
- "FIDIVR\tWORD PTR ",
-
- "FIADD\tWORD PTR ", "FIMUL\tWORD PTR ", "FICOM\tWORD PTR ",
- "FICOMP\tWORD PTR ",
- "FISUB\tWORD PTR ", "FISUBR\tWORD PTR ", "FIDIV\tWORD PTR ",
- "FIDIVR\tWORD PTR ",
-
- "FADDP\t", "FMULP\t", "FCOMP\t", "FCOMPP\t",
- "FSUBRP\t", "FSUBP\t", "FDIVRP\t", "FDIVP\t",
+static char *x86emu_fpu_op_de_tab[] =
+{
+ "FIADD\tWORD PTR ", "FIMUL\tWORD PTR ", "FICOM\tWORD PTR ",
+ "FICOMP\tWORD PTR ",
+ "FISUB\tWORD PTR ", "FISUBR\tWORD PTR ", "FIDIV\tWORD PTR ",
+ "FIDIVR\tWORD PTR ",
+
+ "FIADD\tWORD PTR ", "FIMUL\tWORD PTR ", "FICOM\tWORD PTR ",
+ "FICOMP\tWORD PTR ",
+ "FISUB\tWORD PTR ", "FISUBR\tWORD PTR ", "FIDIV\tWORD PTR ",
+ "FIDIVR\tWORD PTR ",
+
+ "FIADD\tWORD PTR ", "FIMUL\tWORD PTR ", "FICOM\tWORD PTR ",
+ "FICOMP\tWORD PTR ",
+ "FISUB\tWORD PTR ", "FISUBR\tWORD PTR ", "FIDIV\tWORD PTR ",
+ "FIDIVR\tWORD PTR ",
+
+ "FADDP\t", "FMULP\t", "FCOMP\t", "FCOMPP\t",
+ "FSUBRP\t", "FSUBP\t", "FDIVRP\t", "FDIVP\t",
};
-#endif /* DEBUG */
+#endif /* DEBUG */
/* opcode=0xde */
void x86emuOp_esc_coprocess_de(u8 X86EMU_UNUSED(op1))
{
- int mod, rl, rh;
- uint destoffset;
- u8 stkelem;
-
- START_OF_INSTR();
- FETCH_DECODE_MODRM(mod, rh, rl);
- DECODE_PRINTINSTR32(x86emu_fpu_op_de_tab, mod, rh, rl);
- switch (mod) {
- case 0:
- destoffset = decode_rm00_address(rl);
- DECODE_PRINTF("\n");
- break;
- case 1:
- destoffset = decode_rm01_address(rl);
- DECODE_PRINTF("\n");
- break;
- case 2:
- destoffset = decode_rm10_address(rl);
- DECODE_PRINTF("\n");
- break;
- case 3: /* register to register */
- stkelem = (u8) rl;
- DECODE_PRINTF2("\tST(%d),ST\n", stkelem);
- break;
- }
+ int mod, rl, rh;
+ uint destoffset;
+ u8 stkelem;
+
+ START_OF_INSTR();
+ FETCH_DECODE_MODRM(mod, rh, rl);
+ DECODE_PRINTINSTR32(x86emu_fpu_op_de_tab, mod, rh, rl);
+ switch (mod) {
+ case 0:
+ destoffset = decode_rm00_address(rl);
+ DECODE_PRINTF("\n");
+ break;
+ case 1:
+ destoffset = decode_rm01_address(rl);
+ DECODE_PRINTF("\n");
+ break;
+ case 2:
+ destoffset = decode_rm10_address(rl);
+ DECODE_PRINTF("\n");
+ break;
+ case 3: /* register to register */
+ stkelem = (u8)rl;
+ DECODE_PRINTF2("\tST(%d),ST\n", stkelem);
+ break;
+ }
#ifdef X86EMU_FPU_PRESENT
- switch (mod) {
- case 3:
- switch (rh) {
- case 0:
- x86emu_fpu_R_faddp(stkelem, X86EMU_FPU_STKTOP);
- break;
- case 1:
- x86emu_fpu_R_fmulp(stkelem, X86EMU_FPU_STKTOP);
- break;
- case 2:
- x86emu_fpu_R_fcomp(stkelem, X86EMU_FPU_STKTOP);
- break;
- case 3:
- if (stkelem == 1)
- x86emu_fpu_R_fcompp(stkelem, X86EMU_FPU_STKTOP);
- else
- x86emu_fpu_illegal();
- break;
- case 4:
- x86emu_fpu_R_fsubrp(stkelem, X86EMU_FPU_STKTOP);
- break;
- case 5:
- x86emu_fpu_R_fsubp(stkelem, X86EMU_FPU_STKTOP);
- break;
- case 6:
- x86emu_fpu_R_fdivrp(stkelem, X86EMU_FPU_STKTOP);
- break;
- case 7:
- x86emu_fpu_R_fdivp(stkelem, X86EMU_FPU_STKTOP);
- break;
- }
- break;
- default:
- switch (rh) {
- case 0:
- x86emu_fpu_M_fiadd(X86EMU_FPU_WORD, destoffset);
- break;
- case 1:
- x86emu_fpu_M_fimul(X86EMU_FPU_WORD, destoffset);
- break;
- case 2:
- x86emu_fpu_M_ficom(X86EMU_FPU_WORD, destoffset);
- break;
- case 3:
- x86emu_fpu_M_ficomp(X86EMU_FPU_WORD, destoffset);
- break;
- case 4:
- x86emu_fpu_M_fisub(X86EMU_FPU_WORD, destoffset);
- break;
- case 5:
- x86emu_fpu_M_fisubr(X86EMU_FPU_WORD, destoffset);
- break;
- case 6:
- x86emu_fpu_M_fidiv(X86EMU_FPU_WORD, destoffset);
- break;
- case 7:
- x86emu_fpu_M_fidivr(X86EMU_FPU_WORD, destoffset);
- break;
- }
- }
+ switch (mod) {
+ case 3:
+ switch (rh) {
+ case 0:
+ x86emu_fpu_R_faddp(stkelem, X86EMU_FPU_STKTOP);
+ break;
+ case 1:
+ x86emu_fpu_R_fmulp(stkelem, X86EMU_FPU_STKTOP);
+ break;
+ case 2:
+ x86emu_fpu_R_fcomp(stkelem, X86EMU_FPU_STKTOP);
+ break;
+ case 3:
+ if (stkelem == 1)
+ x86emu_fpu_R_fcompp(stkelem, X86EMU_FPU_STKTOP);
+ else
+ x86emu_fpu_illegal();
+ break;
+ case 4:
+ x86emu_fpu_R_fsubrp(stkelem, X86EMU_FPU_STKTOP);
+ break;
+ case 5:
+ x86emu_fpu_R_fsubp(stkelem, X86EMU_FPU_STKTOP);
+ break;
+ case 6:
+ x86emu_fpu_R_fdivrp(stkelem, X86EMU_FPU_STKTOP);
+ break;
+ case 7:
+ x86emu_fpu_R_fdivp(stkelem, X86EMU_FPU_STKTOP);
+ break;
+ }
+ break;
+ default:
+ switch (rh) {
+ case 0:
+ x86emu_fpu_M_fiadd(X86EMU_FPU_WORD, destoffset);
+ break;
+ case 1:
+ x86emu_fpu_M_fimul(X86EMU_FPU_WORD, destoffset);
+ break;
+ case 2:
+ x86emu_fpu_M_ficom(X86EMU_FPU_WORD, destoffset);
+ break;
+ case 3:
+ x86emu_fpu_M_ficomp(X86EMU_FPU_WORD, destoffset);
+ break;
+ case 4:
+ x86emu_fpu_M_fisub(X86EMU_FPU_WORD, destoffset);
+ break;
+ case 5:
+ x86emu_fpu_M_fisubr(X86EMU_FPU_WORD, destoffset);
+ break;
+ case 6:
+ x86emu_fpu_M_fidiv(X86EMU_FPU_WORD, destoffset);
+ break;
+ case 7:
+ x86emu_fpu_M_fidivr(X86EMU_FPU_WORD, destoffset);
+ break;
+ }
+ }
#endif
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR_NO_TRACE();
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR_NO_TRACE();
}
#ifdef DEBUG
static char *x86emu_fpu_op_df_tab[] = {
- /* mod == 00 */
- "FILD\tWORD PTR ", "ESC_DF\t39\n", "FIST\tWORD PTR ", "FISTP\tWORD PTR ",
- "FBLD\tTBYTE PTR ", "FILD\tQWORD PTR ", "FBSTP\tTBYTE PTR ",
- "FISTP\tQWORD PTR ",
-
- /* mod == 01 */
- "FILD\tWORD PTR ", "ESC_DF\t39 ", "FIST\tWORD PTR ", "FISTP\tWORD PTR ",
- "FBLD\tTBYTE PTR ", "FILD\tQWORD PTR ", "FBSTP\tTBYTE PTR ",
- "FISTP\tQWORD PTR ",
-
- /* mod == 10 */
- "FILD\tWORD PTR ", "ESC_DF\t39 ", "FIST\tWORD PTR ", "FISTP\tWORD PTR ",
- "FBLD\tTBYTE PTR ", "FILD\tQWORD PTR ", "FBSTP\tTBYTE PTR ",
- "FISTP\tQWORD PTR ",
-
- /* mod == 11 */
- "FFREE\t", "FXCH\t", "FST\t", "FSTP\t",
- "ESC_DF\t3C,", "ESC_DF\t3D,", "ESC_DF\t3E,", "ESC_DF\t3F,"
+ /* mod == 00 */
+ "FILD\tWORD PTR ", "ESC_DF\t39\n", "FIST\tWORD PTR ", "FISTP\tWORD PTR ",
+ "FBLD\tTBYTE PTR ", "FILD\tQWORD PTR ", "FBSTP\tTBYTE PTR ",
+ "FISTP\tQWORD PTR ",
+
+ /* mod == 01 */
+ "FILD\tWORD PTR ", "ESC_DF\t39 ", "FIST\tWORD PTR ", "FISTP\tWORD PTR ",
+ "FBLD\tTBYTE PTR ", "FILD\tQWORD PTR ", "FBSTP\tTBYTE PTR ",
+ "FISTP\tQWORD PTR ",
+
+ /* mod == 10 */
+ "FILD\tWORD PTR ", "ESC_DF\t39 ", "FIST\tWORD PTR ", "FISTP\tWORD PTR ",
+ "FBLD\tTBYTE PTR ", "FILD\tQWORD PTR ", "FBSTP\tTBYTE PTR ",
+ "FISTP\tQWORD PTR ",
+
+ /* mod == 11 */
+ "FFREE\t", "FXCH\t", "FST\t", "FSTP\t",
+ "ESC_DF\t3C,", "ESC_DF\t3D,", "ESC_DF\t3E,", "ESC_DF\t3F,"
};
-#endif /* DEBUG */
+#endif /* DEBUG */
/* opcode=0xdf */
void x86emuOp_esc_coprocess_df(u8 X86EMU_UNUSED(op1))
{
- int mod, rl, rh;
- uint destoffset;
- u8 stkelem;
-
- START_OF_INSTR();
- FETCH_DECODE_MODRM(mod, rh, rl);
- DECODE_PRINTINSTR32(x86emu_fpu_op_df_tab, mod, rh, rl);
- switch (mod) {
- case 0:
- destoffset = decode_rm00_address(rl);
- DECODE_PRINTF("\n");
- break;
- case 1:
- destoffset = decode_rm01_address(rl);
- DECODE_PRINTF("\n");
- break;
- case 2:
- destoffset = decode_rm10_address(rl);
- DECODE_PRINTF("\n");
- break;
- case 3: /* register to register */
- stkelem = (u8) rl;
- DECODE_PRINTF2("\tST(%d)\n", stkelem);
- break;
- }
+ int mod, rl, rh;
+ uint destoffset;
+ u8 stkelem;
+
+ START_OF_INSTR();
+ FETCH_DECODE_MODRM(mod, rh, rl);
+ DECODE_PRINTINSTR32(x86emu_fpu_op_df_tab, mod, rh, rl);
+ switch (mod) {
+ case 0:
+ destoffset = decode_rm00_address(rl);
+ DECODE_PRINTF("\n");
+ break;
+ case 1:
+ destoffset = decode_rm01_address(rl);
+ DECODE_PRINTF("\n");
+ break;
+ case 2:
+ destoffset = decode_rm10_address(rl);
+ DECODE_PRINTF("\n");
+ break;
+ case 3: /* register to register */
+ stkelem = (u8)rl;
+ DECODE_PRINTF2("\tST(%d)\n", stkelem);
+ break;
+ }
#ifdef X86EMU_FPU_PRESENT
- switch (mod) {
- case 3:
- switch (rh) {
- case 0:
- x86emu_fpu_R_ffree(stkelem);
- break;
- case 1:
- x86emu_fpu_R_fxch(stkelem);
- break;
- case 2:
- x86emu_fpu_R_fst(stkelem); /* register version */
- break;
- case 3:
- x86emu_fpu_R_fstp(stkelem); /* register version */
- break;
- default:
- x86emu_fpu_illegal();
- break;
- }
- break;
- default:
- switch (rh) {
- case 0:
- x86emu_fpu_M_fild(X86EMU_FPU_WORD, destoffset);
- break;
- case 1:
- x86emu_fpu_illegal();
- break;
- case 2:
- x86emu_fpu_M_fist(X86EMU_FPU_WORD, destoffset);
- break;
- case 3:
- x86emu_fpu_M_fistp(X86EMU_FPU_WORD, destoffset);
- break;
- case 4:
- x86emu_fpu_M_fbld(X86EMU_FPU_BSD, destoffset);
- break;
- case 5:
- x86emu_fpu_M_fild(X86EMU_FPU_LONG, destoffset);
- break;
- case 6:
- x86emu_fpu_M_fbstp(X86EMU_FPU_BSD, destoffset);
- break;
- case 7:
- x86emu_fpu_M_fistp(X86EMU_FPU_LONG, destoffset);
- break;
- }
- }
+ switch (mod) {
+ case 3:
+ switch (rh) {
+ case 0:
+ x86emu_fpu_R_ffree(stkelem);
+ break;
+ case 1:
+ x86emu_fpu_R_fxch(stkelem);
+ break;
+ case 2:
+ x86emu_fpu_R_fst(stkelem); /* register version */
+ break;
+ case 3:
+ x86emu_fpu_R_fstp(stkelem); /* register version */
+ break;
+ default:
+ x86emu_fpu_illegal();
+ break;
+ }
+ break;
+ default:
+ switch (rh) {
+ case 0:
+ x86emu_fpu_M_fild(X86EMU_FPU_WORD, destoffset);
+ break;
+ case 1:
+ x86emu_fpu_illegal();
+ break;
+ case 2:
+ x86emu_fpu_M_fist(X86EMU_FPU_WORD, destoffset);
+ break;
+ case 3:
+ x86emu_fpu_M_fistp(X86EMU_FPU_WORD, destoffset);
+ break;
+ case 4:
+ x86emu_fpu_M_fbld(X86EMU_FPU_BSD, destoffset);
+ break;
+ case 5:
+ x86emu_fpu_M_fild(X86EMU_FPU_LONG, destoffset);
+ break;
+ case 6:
+ x86emu_fpu_M_fbstp(X86EMU_FPU_BSD, destoffset);
+ break;
+ case 7:
+ x86emu_fpu_M_fistp(X86EMU_FPU_LONG, destoffset);
+ break;
+ }
+ }
#endif
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR_NO_TRACE();
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR_NO_TRACE();
}
diff --git a/util/vgabios/x86emu/src/x86emu/makefile b/util/vgabios/x86emu/src/x86emu/makefile
index 8ce2e9e84..3fbc363b3 100644
--- a/util/vgabios/x86emu/src/x86emu/makefile
+++ b/util/vgabios/x86emu/src/x86emu/makefile
@@ -2,7 +2,7 @@
#
# Realmode X86 Emulator Library
#
-# Copyright (C) 1996-1999 SciTech Software, Inc.
+# Copyright (C) 1991-2004 SciTech Software, Inc.
#
# ========================================================================
#
diff --git a/util/vgabios/x86emu/src/x86emu/makefile.linux b/util/vgabios/x86emu/src/x86emu/makefile.linux
index 313526a5d..39d6b5031 100644
--- a/util/vgabios/x86emu/src/x86emu/makefile.linux
+++ b/util/vgabios/x86emu/src/x86emu/makefile.linux
@@ -31,9 +31,9 @@
#############################################################################
TARGETLIB = libx86emu.a
+TARGETDEBUGLIB =libx86emud.a
OBJS=\
-debug.o \
decode.o \
fpu.o \
ops.o \
@@ -41,20 +41,40 @@ ops2.o \
prim_ops.o \
sys.o
+DEBUGOBJS=debug.d \
+ decode.d \
+ fpu.d \
+ ops.d \
+ ops2.d \
+ prim_ops.d \
+ sys.d
+
+.SUFFIXES: .d
+
+all: $(TARGETLIB) $(TARGETDEBUGLIB)
+
$(TARGETLIB): $(OBJS)
ar rv $(TARGETLIB) $(OBJS)
-INCS = -I. -Ix86emu -I../../include
-CFLAGS = -D__DRIVER__ -DFORCE_POST -D_CEXPORT= -DNO_LONG_LONG -DDEBUG
+$(TARGETDEBUGLIB): $(DEBUGOBJS)
+ ar rv $(TARGETDEBUGLIB) $(DEBUGOBJS)
+
+INCS = -I. -I../../include -I../../include/x86emu
+#CFLAGS = -D__DRIVER__ -DFORCE_POST -D_CEXPORT= -DNO_LONG_LONG
+CFLAGS = -D__DRIVER__ -DFORCE_POST
+CDEBUGFLAGS = -DDEBUG
.c.o:
- gcc -g -O -Wall -c $(CFLAGS) $(INCS) $*.c
+ gcc -g -Os -Wall -c $(CFLAGS) $(INCS) $*.c
+
+.c.d:
+ gcc -g -O -Wall -c -o$*.d $(CFLAGS) $(CDEBUGFLAGS) $(INCS) $*.c
.cpp.o:
gcc -c $(CFLAGS) $(INCS) $*.cpp
clean:
- rm -f *.a *.o
+ rm -f *.a *.o *.d
-validate: validate.o libx86emu.a
- gcc -o validate validate.o -lx86emu -L.
+validate: validate.c libx86emu.a x86emu/prim_asm.h
+ gcc $(CFLAGS) $(INCS) -Wall -O2 -o validate validate.c -lx86emu -L.
diff --git a/util/vgabios/x86emu/src/x86emu/ops.c b/util/vgabios/x86emu/src/x86emu/ops.c
index 92dbd6683..1b702500a 100644
--- a/util/vgabios/x86emu/src/x86emu/ops.c
+++ b/util/vgabios/x86emu/src/x86emu/ops.c
@@ -2,7 +2,7 @@
*
* Realmode X86 Emulator Library
*
-* Copyright (C) 1996-1999 SciTech Software, Inc.
+* Copyright (C) 1991-2004 SciTech Software, Inc.
* Copyright (C) David Mosberger-Tang
* Copyright (C) 1999 Egbert Eich
*
@@ -70,12 +70,100 @@
*
****************************************************************************/
-/* $XFree86: xc/extras/x86emu/src/x86emu/ops.c,v 1.6 2001/01/06 20:19:03 tsi Exp $ */
-
#include "x86emu/x86emui.h"
/*----------------------------- Implementation ----------------------------*/
+/* constant arrays to do several instructions in just one function */
+
+#ifdef DEBUG
+static char *x86emu_GenOpName[8] = {
+ "ADD", "OR", "ADC", "SBB", "AND", "SUB", "XOR", "CMP"};
+#endif
+
+/* used by several opcodes */
+static u8 (*genop_byte_operation[])(u8 d, u8 s) =
+{
+ add_byte, /* 00 */
+ or_byte, /* 01 */
+ adc_byte, /* 02 */
+ sbb_byte, /* 03 */
+ and_byte, /* 04 */
+ sub_byte, /* 05 */
+ xor_byte, /* 06 */
+ cmp_byte, /* 07 */
+};
+
+static u16 (*genop_word_operation[])(u16 d, u16 s) =
+{
+ add_word, /*00 */
+ or_word, /*01 */
+ adc_word, /*02 */
+ sbb_word, /*03 */
+ and_word, /*04 */
+ sub_word, /*05 */
+ xor_word, /*06 */
+ cmp_word, /*07 */
+};
+
+static u32 (*genop_long_operation[])(u32 d, u32 s) =
+{
+ add_long, /*00 */
+ or_long, /*01 */
+ adc_long, /*02 */
+ sbb_long, /*03 */
+ and_long, /*04 */
+ sub_long, /*05 */
+ xor_long, /*06 */
+ cmp_long, /*07 */
+};
+
+/* used by opcodes 80, c0, d0, and d2. */
+static u8(*opcD0_byte_operation[])(u8 d, u8 s) =
+{
+ rol_byte,
+ ror_byte,
+ rcl_byte,
+ rcr_byte,
+ shl_byte,
+ shr_byte,
+ shl_byte, /* sal_byte === shl_byte by definition */
+ sar_byte,
+};
+
+/* used by opcodes c1, d1, and d3. */
+static u16(*opcD1_word_operation[])(u16 s, u8 d) =
+{
+ rol_word,
+ ror_word,
+ rcl_word,
+ rcr_word,
+ shl_word,
+ shr_word,
+ shl_word, /* sal_byte === shl_byte by definition */
+ sar_word,
+};
+
+/* used by opcodes c1, d1, and d3. */
+static u32 (*opcD1_long_operation[])(u32 s, u8 d) =
+{
+ rol_long,
+ ror_long,
+ rcl_long,
+ rcr_long,
+ shl_long,
+ shr_long,
+ shl_long, /* sal_byte === shl_byte by definition */
+ sar_long,
+};
+
+#ifdef DEBUG
+
+static char *opF6_names[8] =
+ { "TEST\t", "", "NOT\t", "NEG\t", "MUL\t", "IMUL\t", "DIV\t", "IDIV\t" };
+
+#endif
+
/****************************************************************************
PARAMETERS:
op1 - Instruction op code
@@ -83,406 +171,278 @@ op1 - Instruction op code
REMARKS:
Handles illegal opcodes.
****************************************************************************/
-void x86emuOp_illegal_op(u8 op1)
-{
- START_OF_INSTR();
- DECODE_PRINTF("ILLEGAL X86 OPCODE\n");
- TRACE_REGS();
- printk("%04x:%04x: %02X ILLEGAL X86 OPCODE!\n", M.x86.R_CS, M.x86.R_IP - 1, op1);
- HALT_SYS();
- END_OF_INSTR();
-}
-
-/****************************************************************************
-REMARKS:
-Handles opcode 0x00
-****************************************************************************/
-void x86emuOp_add_byte_RM_R(u8 X86EMU_UNUSED(op1))
-{
- int mod, rl, rh;
- uint destoffset;
- u8 *destreg, *srcreg;
- u8 destval;
-
- START_OF_INSTR();
- DECODE_PRINTF("ADD\t");
- FETCH_DECODE_MODRM(mod, rh, rl);
- switch (mod) {
- case 0:
- destoffset = decode_rm00_address(rl);
- DECODE_PRINTF(",");
- destval = fetch_data_byte(destoffset);
- srcreg = DECODE_RM_BYTE_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- destval = add_byte(destval, *srcreg);
- store_data_byte(destoffset, destval);
- break;
- case 1:
- destoffset = decode_rm01_address(rl);
- DECODE_PRINTF(",");
- destval = fetch_data_byte(destoffset);
- srcreg = DECODE_RM_BYTE_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- destval = add_byte(destval, *srcreg);
- store_data_byte(destoffset, destval);
- break;
- case 2:
- destoffset = decode_rm10_address(rl);
- DECODE_PRINTF(",");
- destval = fetch_data_byte(destoffset);
- srcreg = DECODE_RM_BYTE_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- destval = add_byte(destval, *srcreg);
- store_data_byte(destoffset, destval);
- break;
- case 3: /* register to register */
- destreg = DECODE_RM_BYTE_REGISTER(rl);
- DECODE_PRINTF(",");
- srcreg = DECODE_RM_BYTE_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = add_byte(*destreg, *srcreg);
- break;
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
-}
-
-/****************************************************************************
-REMARKS:
-Handles opcode 0x01
-****************************************************************************/
-void x86emuOp_add_word_RM_R(u8 X86EMU_UNUSED(op1))
-{
- int mod, rl, rh;
- uint destoffset;
-
- START_OF_INSTR();
- DECODE_PRINTF("ADD\t");
- FETCH_DECODE_MODRM(mod, rh, rl);
- switch (mod) {
- case 0:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 destval;
- u32 *srcreg;
-
- destoffset = decode_rm00_address(rl);
- DECODE_PRINTF(",");
- destval = fetch_data_long(destoffset);
- srcreg = DECODE_RM_LONG_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- destval = add_long(destval, *srcreg);
- store_data_long(destoffset, destval);
- } else {
- u16 destval;
- u16 *srcreg;
-
- destoffset = decode_rm00_address(rl);
- DECODE_PRINTF(",");
- destval = fetch_data_word(destoffset);
- srcreg = DECODE_RM_WORD_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- destval = add_word(destval, *srcreg);
- store_data_word(destoffset, destval);
- }
- break;
- case 1:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 destval;
- u32 *srcreg;
-
- destoffset = decode_rm01_address(rl);
- DECODE_PRINTF(",");
- destval = fetch_data_long(destoffset);
- srcreg = DECODE_RM_LONG_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- destval = add_long(destval, *srcreg);
- store_data_long(destoffset, destval);
- } else {
- u16 destval;
- u16 *srcreg;
-
- destoffset = decode_rm01_address(rl);
- DECODE_PRINTF(",");
- destval = fetch_data_word(destoffset);
- srcreg = DECODE_RM_WORD_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- destval = add_word(destval, *srcreg);
- store_data_word(destoffset, destval);
- }
- break;
- case 2:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 destval;
- u32 *srcreg;
-
- destoffset = decode_rm10_address(rl);
- DECODE_PRINTF(",");
- destval = fetch_data_long(destoffset);
- srcreg = DECODE_RM_LONG_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- destval = add_long(destval, *srcreg);
- store_data_long(destoffset, destval);
- } else {
- u16 destval;
- u16 *srcreg;
-
- destoffset = decode_rm10_address(rl);
- DECODE_PRINTF(",");
- destval = fetch_data_word(destoffset);
- srcreg = DECODE_RM_WORD_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- destval = add_word(destval, *srcreg);
- store_data_word(destoffset, destval);
- }
- break;
- case 3: /* register to register */
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 *destreg, *srcreg;
-
- destreg = DECODE_RM_LONG_REGISTER(rl);
- DECODE_PRINTF(",");
- srcreg = DECODE_RM_LONG_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = add_long(*destreg, *srcreg);
- } else {
- u16 *destreg, *srcreg;
-
- destreg = DECODE_RM_WORD_REGISTER(rl);
- DECODE_PRINTF(",");
- srcreg = DECODE_RM_WORD_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = add_word(*destreg, *srcreg);
- }
- break;
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
-}
-
-/****************************************************************************
-REMARKS:
-Handles opcode 0x02
-****************************************************************************/
-void x86emuOp_add_byte_R_RM(u8 X86EMU_UNUSED(op1))
-{
- int mod, rl, rh;
- u8 *destreg, *srcreg;
- uint srcoffset;
- u8 srcval;
-
- START_OF_INSTR();
- DECODE_PRINTF("ADD\t");
- FETCH_DECODE_MODRM(mod, rh, rl);
- switch (mod) {
- case 0:
- destreg = DECODE_RM_BYTE_REGISTER(rh);
- DECODE_PRINTF(",");
- srcoffset = decode_rm00_address(rl);
- srcval = fetch_data_byte(srcoffset);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = add_byte(*destreg, srcval);
- break;
- case 1:
- destreg = DECODE_RM_BYTE_REGISTER(rh);
- DECODE_PRINTF(",");
- srcoffset = decode_rm01_address(rl);
- srcval = fetch_data_byte(srcoffset);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = add_byte(*destreg, srcval);
- break;
- case 2:
- destreg = DECODE_RM_BYTE_REGISTER(rh);
- DECODE_PRINTF(",");
- srcoffset = decode_rm10_address(rl);
- srcval = fetch_data_byte(srcoffset);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = add_byte(*destreg, srcval);
- break;
- case 3: /* register to register */
- destreg = DECODE_RM_BYTE_REGISTER(rh);
- DECODE_PRINTF(",");
- srcreg = DECODE_RM_BYTE_REGISTER(rl);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = add_byte(*destreg, *srcreg);
- break;
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
-}
-
-/****************************************************************************
-REMARKS:
-Handles opcode 0x03
-****************************************************************************/
-void x86emuOp_add_word_R_RM(u8 X86EMU_UNUSED(op1))
-{
- int mod, rl, rh;
- uint srcoffset;
-
- START_OF_INSTR();
- DECODE_PRINTF("ADD\t");
- FETCH_DECODE_MODRM(mod, rh, rl);
- switch (mod) {
- case 0:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 *destreg;
- u32 srcval;
-
- destreg = DECODE_RM_LONG_REGISTER(rh);
- DECODE_PRINTF(",");
- srcoffset = decode_rm00_address(rl);
- srcval = fetch_data_long(srcoffset);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = add_long(*destreg, srcval);
- } else {
- u16 *destreg;
- u16 srcval;
-
- destreg = DECODE_RM_WORD_REGISTER(rh);
- DECODE_PRINTF(",");
- srcoffset = decode_rm00_address(rl);
- srcval = fetch_data_word(srcoffset);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = add_word(*destreg, srcval);
- }
- break;
- case 1:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 *destreg;
- u32 srcval;
-
- destreg = DECODE_RM_LONG_REGISTER(rh);
- DECODE_PRINTF(",");
- srcoffset = decode_rm01_address(rl);
- srcval = fetch_data_long(srcoffset);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = add_long(*destreg, srcval);
- } else {
- u16 *destreg;
- u16 srcval;
-
- destreg = DECODE_RM_WORD_REGISTER(rh);
- DECODE_PRINTF(",");
- srcoffset = decode_rm01_address(rl);
- srcval = fetch_data_word(srcoffset);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = add_word(*destreg, srcval);
- }
- break;
- case 2:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 *destreg;
- u32 srcval;
-
- destreg = DECODE_RM_LONG_REGISTER(rh);
- DECODE_PRINTF(",");
- srcoffset = decode_rm10_address(rl);
- srcval = fetch_data_long(srcoffset);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = add_long(*destreg, srcval);
- } else {
- u16 *destreg;
- u16 srcval;
-
- destreg = DECODE_RM_WORD_REGISTER(rh);
- DECODE_PRINTF(",");
- srcoffset = decode_rm10_address(rl);
- srcval = fetch_data_word(srcoffset);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = add_word(*destreg, srcval);
- }
- break;
- case 3: /* register to register */
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 *destreg, *srcreg;
-
- destreg = DECODE_RM_LONG_REGISTER(rh);
- DECODE_PRINTF(",");
- srcreg = DECODE_RM_LONG_REGISTER(rl);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = add_long(*destreg, *srcreg);
- } else {
- u16 *destreg, *srcreg;
-
- destreg = DECODE_RM_WORD_REGISTER(rh);
- DECODE_PRINTF(",");
- srcreg = DECODE_RM_WORD_REGISTER(rl);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = add_word(*destreg, *srcreg);
- }
- break;
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
-}
-
-/****************************************************************************
-REMARKS:
-Handles opcode 0x04
-****************************************************************************/
-void x86emuOp_add_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
-{
- u8 srcval;
-
- START_OF_INSTR();
- DECODE_PRINTF("ADD\tAL,");
- srcval = fetch_byte_imm();
- DECODE_PRINTF2("%x\n", srcval);
- TRACE_AND_STEP();
- M.x86.R_AL = add_byte(M.x86.R_AL, srcval);
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
-}
-
-/****************************************************************************
-REMARKS:
-Handles opcode 0x05
+void x86emuOp_illegal_op(
+ u8 op1)
+{
+ START_OF_INSTR();
+ if (M.x86.R_SP != 0) {
+ DECODE_PRINTF("ILLEGAL X86 OPCODE\n");
+ TRACE_REGS();
+ DB( printk("%04x:%04x: %02X ILLEGAL X86 OPCODE!\n",
+ M.x86.R_CS, M.x86.R_IP-1,op1));
+ HALT_SYS();
+ }
+ else {
+ /* If we get here, it means the stack pointer is back to zero
+ * so we are just returning from an emulator service call
+ * so therte is no need to display an error message. We trap
+ * the emulator with an 0xF1 opcode to finish the service
+ * call.
+ */
+ X86EMU_halt_sys();
+ }
+ END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcodes 0x00, 0x08, 0x10, 0x18, 0x20, 0x28, 0x30, 0x38
+****************************************************************************/
+void x86emuOp_genop_byte_RM_R(u8 op1)
+{
+ int mod, rl, rh;
+ uint destoffset;
+ u8 *destreg, *srcreg;
+ u8 destval;
+
+ op1 = (op1 >> 3) & 0x7;
+
+ START_OF_INSTR();
+ DECODE_PRINTF(x86emu_GenOpName[op1]);
+ DECODE_PRINTF("\t");
+ FETCH_DECODE_MODRM(mod, rh, rl);
+ if(mod<3)
+ { destoffset = decode_rmXX_address(mod,rl);
+ DECODE_PRINTF(",");
+ destval = fetch_data_byte(destoffset);
+ srcreg = DECODE_RM_BYTE_REGISTER(rh);
+ DECODE_PRINTF("\n");
+ TRACE_AND_STEP();
+ destval = genop_byte_operation[op1](destval, *srcreg);
+ store_data_byte(destoffset, destval);
+ }
+ else
+ { /* register to register */
+ destreg = DECODE_RM_BYTE_REGISTER(rl);
+ DECODE_PRINTF(",");
+ srcreg = DECODE_RM_BYTE_REGISTER(rh);
+ DECODE_PRINTF("\n");
+ TRACE_AND_STEP();
+ *destreg = genop_byte_operation[op1](*destreg, *srcreg);
+ }
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcodes 0x01, 0x09, 0x11, 0x19, 0x21, 0x29, 0x31, 0x39
+****************************************************************************/
+void x86emuOp_genop_word_RM_R(u8 op1)
+{
+ int mod, rl, rh;
+ uint destoffset;
+
+ op1 = (op1 >> 3) & 0x7;
+
+ START_OF_INSTR();
+ DECODE_PRINTF(x86emu_GenOpName[op1]);
+ DECODE_PRINTF("\t");
+ FETCH_DECODE_MODRM(mod, rh, rl);
+
+ if(mod<3) {
+ destoffset = decode_rmXX_address(mod,rl);
+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+ u32 destval;
+ u32 *srcreg;
+
+ DECODE_PRINTF(",");
+ destval = fetch_data_long(destoffset);
+ srcreg = DECODE_RM_LONG_REGISTER(rh);
+ DECODE_PRINTF("\n");
+ TRACE_AND_STEP();
+ destval = genop_long_operation[op1](destval, *srcreg);
+ store_data_long(destoffset, destval);
+ } else {
+ u16 destval;
+ u16 *srcreg;
+
+ DECODE_PRINTF(",");
+ destval = fetch_data_word(destoffset);
+ srcreg = DECODE_RM_WORD_REGISTER(rh);
+ DECODE_PRINTF("\n");
+ TRACE_AND_STEP();
+ destval = genop_word_operation[op1](destval, *srcreg);
+ store_data_word(destoffset, destval);
+ }
+ } else { /* register to register */
+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+ u32 *destreg,*srcreg;
+
+ destreg = DECODE_RM_LONG_REGISTER(rl);
+ DECODE_PRINTF(",");
+ srcreg = DECODE_RM_LONG_REGISTER(rh);
+ DECODE_PRINTF("\n");
+ TRACE_AND_STEP();
+ *destreg = genop_long_operation[op1](*destreg, *srcreg);
+ } else {
+ u16 *destreg,*srcreg;
+
+ destreg = DECODE_RM_WORD_REGISTER(rl);
+ DECODE_PRINTF(",");
+ srcreg = DECODE_RM_WORD_REGISTER(rh);
+ DECODE_PRINTF("\n");
+ TRACE_AND_STEP();
+ *destreg = genop_word_operation[op1](*destreg, *srcreg);
+ }
+ }
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcodes 0x02, 0x0a, 0x12, 0x1a, 0x22, 0x2a, 0x32, 0x3a
+****************************************************************************/
+void x86emuOp_genop_byte_R_RM(u8 op1)
+{
+ int mod, rl, rh;
+ u8 *destreg, *srcreg;
+ uint srcoffset;
+ u8 srcval;
+
+ op1 = (op1 >> 3) & 0x7;
+
+ START_OF_INSTR();
+ DECODE_PRINTF(x86emu_GenOpName[op1]);
+ DECODE_PRINTF("\t");
+ FETCH_DECODE_MODRM(mod, rh, rl);
+ if (mod < 3) {
+ destreg = DECODE_RM_BYTE_REGISTER(rh);
+ DECODE_PRINTF(",");
+ srcoffset = decode_rmXX_address(mod,rl);
+ srcval = fetch_data_byte(srcoffset);
+ } else { /* register to register */
+ destreg = DECODE_RM_BYTE_REGISTER(rh);
+ DECODE_PRINTF(",");
+ srcreg = DECODE_RM_BYTE_REGISTER(rl);
+ srcval = *srcreg;
+ }
+ DECODE_PRINTF("\n");
+ TRACE_AND_STEP();
+ *destreg = genop_byte_operation[op1](*destreg, srcval);
+
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcodes 0x03, 0x0b, 0x13, 0x1b, 0x23, 0x2b, 0x33, 0x3b
+****************************************************************************/
+void x86emuOp_genop_word_R_RM(u8 op1)
+{
+ int mod, rl, rh;
+ uint srcoffset;
+ u32 *destreg32, srcval;
+ u16 *destreg;
+
+ op1 = (op1 >> 3) & 0x7;
+
+ START_OF_INSTR();
+ DECODE_PRINTF(x86emu_GenOpName[op1]);
+ DECODE_PRINTF("\t");
+ FETCH_DECODE_MODRM(mod, rh, rl);
+ if (mod < 3) {
+ srcoffset = decode_rmXX_address(mod,rl);
+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+ destreg32 = DECODE_RM_LONG_REGISTER(rh);
+ DECODE_PRINTF(",");
+ srcval = fetch_data_long(srcoffset);
+ DECODE_PRINTF("\n");
+ TRACE_AND_STEP();
+ *destreg32 = genop_long_operation[op1](*destreg32, srcval);
+ } else {
+ destreg = DECODE_RM_WORD_REGISTER(rh);
+ DECODE_PRINTF(",");
+ srcval = fetch_data_word(srcoffset);
+ DECODE_PRINTF("\n");
+ TRACE_AND_STEP();
+ *destreg = genop_word_operation[op1](*destreg, srcval);
+ }
+ } else { /* register to register */
+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+ u32 *srcreg;
+ destreg32 = DECODE_RM_LONG_REGISTER(rh);
+ DECODE_PRINTF(",");
+ srcreg = DECODE_RM_LONG_REGISTER(rl);
+ DECODE_PRINTF("\n");
+ TRACE_AND_STEP();
+ *destreg32 = genop_long_operation[op1](*destreg32, *srcreg);
+ } else {
+ u16 *srcreg;
+ destreg = DECODE_RM_WORD_REGISTER(rh);
+ DECODE_PRINTF(",");
+ srcreg = DECODE_RM_WORD_REGISTER(rl);
+ DECODE_PRINTF("\n");
+ TRACE_AND_STEP();
+ *destreg = genop_word_operation[op1](*destreg, *srcreg);
+ }
+ }
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcodes 0x04, 0x0c, 0x14, 0x1c, 0x24, 0x2c, 0x34, 0x3c
****************************************************************************/
-void x86emuOp_add_word_AX_IMM(u8 X86EMU_UNUSED(op1))
+void x86emuOp_genop_byte_AL_IMM(u8 op1)
{
- u32 srcval;
-
- START_OF_INSTR();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- DECODE_PRINTF("ADD\tEAX,");
- srcval = fetch_long_imm();
- } else {
- DECODE_PRINTF("ADD\tAX,");
- srcval = fetch_word_imm();
- }
- DECODE_PRINTF2("%x\n", srcval);
- TRACE_AND_STEP();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- M.x86.R_EAX = add_long(M.x86.R_EAX, srcval);
- } else {
- M.x86.R_AX = add_word(M.x86.R_AX, (u16) srcval);
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ u8 srcval;
+
+ op1 = (op1 >> 3) & 0x7;
+
+ START_OF_INSTR();
+ DECODE_PRINTF(x86emu_GenOpName[op1]);
+ DECODE_PRINTF("\tAL,");
+ srcval = fetch_byte_imm();
+ DECODE_PRINTF2("%x\n", srcval);
+ TRACE_AND_STEP();
+ M.x86.R_AL = genop_byte_operation[op1](M.x86.R_AL, srcval);
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcodes 0x05, 0x0d, 0x15, 0x1d, 0x25, 0x2d, 0x35, 0x3d
+****************************************************************************/
+void x86emuOp_genop_word_AX_IMM(u8 op1)
+{
+ u32 srcval;
+
+ op1 = (op1 >> 3) & 0x7;
+
+ START_OF_INSTR();
+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+ DECODE_PRINTF(x86emu_GenOpName[op1]);
+ DECODE_PRINTF("\tEAX,");
+ srcval = fetch_long_imm();
+ } else {
+ DECODE_PRINTF(x86emu_GenOpName[op1]);
+ DECODE_PRINTF("\tAX,");
+ srcval = fetch_word_imm();
+ }
+ DECODE_PRINTF2("%x\n", srcval);
+ TRACE_AND_STEP();
+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+ M.x86.R_EAX = genop_long_operation[op1](M.x86.R_EAX, srcval);
+ } else {
+ M.x86.R_AX = genop_word_operation[op1](M.x86.R_AX, (u16)srcval);
+ }
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/****************************************************************************
@@ -491,12 +451,12 @@ Handles opcode 0x06
****************************************************************************/
void x86emuOp_push_ES(u8 X86EMU_UNUSED(op1))
{
- START_OF_INSTR();
- DECODE_PRINTF("PUSH\tES\n");
- TRACE_AND_STEP();
- push_word(M.x86.R_ES);
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ START_OF_INSTR();
+ DECODE_PRINTF("PUSH\tES\n");
+ TRACE_AND_STEP();
+ push_word(M.x86.R_ES);
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/****************************************************************************
@@ -505,404 +465,12 @@ Handles opcode 0x07
****************************************************************************/
void x86emuOp_pop_ES(u8 X86EMU_UNUSED(op1))
{
- START_OF_INSTR();
- DECODE_PRINTF("POP\tES\n");
- TRACE_AND_STEP();
- M.x86.R_ES = pop_word();
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
-}
-
-/****************************************************************************
-REMARKS:
-Handles opcode 0x08
-****************************************************************************/
-void x86emuOp_or_byte_RM_R(u8 X86EMU_UNUSED(op1))
-{
- int mod, rl, rh;
- u8 *destreg, *srcreg;
- uint destoffset;
- u8 destval;
-
- START_OF_INSTR();
- DECODE_PRINTF("OR\t");
- FETCH_DECODE_MODRM(mod, rh, rl);
- switch (mod) {
- case 0:
- destoffset = decode_rm00_address(rl);
- DECODE_PRINTF(",");
- destval = fetch_data_byte(destoffset);
- srcreg = DECODE_RM_BYTE_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- destval = or_byte(destval, *srcreg);
- store_data_byte(destoffset, destval);
- break;
- case 1:
- destoffset = decode_rm01_address(rl);
- DECODE_PRINTF(",");
- destval = fetch_data_byte(destoffset);
- srcreg = DECODE_RM_BYTE_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- destval = or_byte(destval, *srcreg);
- store_data_byte(destoffset, destval);
- break;
- case 2:
- destoffset = decode_rm10_address(rl);
- DECODE_PRINTF(",");
- destval = fetch_data_byte(destoffset);
- srcreg = DECODE_RM_BYTE_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- destval = or_byte(destval, *srcreg);
- store_data_byte(destoffset, destval);
- break;
- case 3: /* register to register */
- destreg = DECODE_RM_BYTE_REGISTER(rl);
- DECODE_PRINTF(",");
- srcreg = DECODE_RM_BYTE_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = or_byte(*destreg, *srcreg);
- break;
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
-}
-
-/****************************************************************************
-REMARKS:
-Handles opcode 0x09
-****************************************************************************/
-void x86emuOp_or_word_RM_R(u8 X86EMU_UNUSED(op1))
-{
- int mod, rl, rh;
- uint destoffset;
-
- START_OF_INSTR();
- DECODE_PRINTF("OR\t");
- FETCH_DECODE_MODRM(mod, rh, rl);
- switch (mod) {
- case 0:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 destval;
- u32 *srcreg;
-
- destoffset = decode_rm00_address(rl);
- DECODE_PRINTF(",");
- destval = fetch_data_long(destoffset);
- srcreg = DECODE_RM_LONG_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- destval = or_long(destval, *srcreg);
- store_data_long(destoffset, destval);
- } else {
- u16 destval;
- u16 *srcreg;
-
- destoffset = decode_rm00_address(rl);
- DECODE_PRINTF(",");
- destval = fetch_data_word(destoffset);
- srcreg = DECODE_RM_WORD_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- destval = or_word(destval, *srcreg);
- store_data_word(destoffset, destval);
- }
- break;
- case 1:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 destval;
- u32 *srcreg;
-
- destoffset = decode_rm01_address(rl);
- DECODE_PRINTF(",");
- destval = fetch_data_long(destoffset);
- srcreg = DECODE_RM_LONG_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- destval = or_long(destval, *srcreg);
- store_data_long(destoffset, destval);
- } else {
- u16 destval;
- u16 *srcreg;
-
- destoffset = decode_rm01_address(rl);
- DECODE_PRINTF(",");
- destval = fetch_data_word(destoffset);
- srcreg = DECODE_RM_WORD_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- destval = or_word(destval, *srcreg);
- store_data_word(destoffset, destval);
- }
- break;
- case 2:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 destval;
- u32 *srcreg;
-
- destoffset = decode_rm10_address(rl);
- DECODE_PRINTF(",");
- destval = fetch_data_long(destoffset);
- srcreg = DECODE_RM_LONG_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- destval = or_long(destval, *srcreg);
- store_data_long(destoffset, destval);
- } else {
- u16 destval;
- u16 *srcreg;
-
- destoffset = decode_rm10_address(rl);
- DECODE_PRINTF(",");
- destval = fetch_data_word(destoffset);
- srcreg = DECODE_RM_WORD_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- destval = or_word(destval, *srcreg);
- store_data_word(destoffset, destval);
- }
- break;
- case 3: /* register to register */
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 *destreg, *srcreg;
-
- destreg = DECODE_RM_LONG_REGISTER(rl);
- DECODE_PRINTF(",");
- srcreg = DECODE_RM_LONG_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = or_long(*destreg, *srcreg);
- } else {
- u16 *destreg, *srcreg;
-
- destreg = DECODE_RM_WORD_REGISTER(rl);
- DECODE_PRINTF(",");
- srcreg = DECODE_RM_WORD_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = or_word(*destreg, *srcreg);
- }
- break;
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
-}
-
-/****************************************************************************
-REMARKS:
-Handles opcode 0x0a
-****************************************************************************/
-void x86emuOp_or_byte_R_RM(u8 X86EMU_UNUSED(op1))
-{
- int mod, rl, rh;
- u8 *destreg, *srcreg;
- uint srcoffset;
- u8 srcval;
-
- START_OF_INSTR();
- DECODE_PRINTF("OR\t");
- FETCH_DECODE_MODRM(mod, rh, rl);
- switch (mod) {
- case 0:
- destreg = DECODE_RM_BYTE_REGISTER(rh);
- DECODE_PRINTF(",");
- srcoffset = decode_rm00_address(rl);
- srcval = fetch_data_byte(srcoffset);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = or_byte(*destreg, srcval);
- break;
- case 1:
- destreg = DECODE_RM_BYTE_REGISTER(rh);
- DECODE_PRINTF(",");
- srcoffset = decode_rm01_address(rl);
- srcval = fetch_data_byte(srcoffset);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = or_byte(*destreg, srcval);
- break;
- case 2:
- destreg = DECODE_RM_BYTE_REGISTER(rh);
- DECODE_PRINTF(",");
- srcoffset = decode_rm10_address(rl);
- srcval = fetch_data_byte(srcoffset);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = or_byte(*destreg, srcval);
- break;
- case 3: /* register to register */
- destreg = DECODE_RM_BYTE_REGISTER(rh);
- DECODE_PRINTF(",");
- srcreg = DECODE_RM_BYTE_REGISTER(rl);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = or_byte(*destreg, *srcreg);
- break;
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
-}
-
-/****************************************************************************
-REMARKS:
-Handles opcode 0x0b
-****************************************************************************/
-void x86emuOp_or_word_R_RM(u8 X86EMU_UNUSED(op1))
-{
- int mod, rl, rh;
- uint srcoffset;
-
- START_OF_INSTR();
- DECODE_PRINTF("OR\t");
- FETCH_DECODE_MODRM(mod, rh, rl);
- switch (mod) {
- case 0:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 *destreg;
- u32 srcval;
-
- destreg = DECODE_RM_LONG_REGISTER(rh);
- DECODE_PRINTF(",");
- srcoffset = decode_rm00_address(rl);
- srcval = fetch_data_long(srcoffset);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = or_long(*destreg, srcval);
- } else {
- u16 *destreg;
- u16 srcval;
-
- destreg = DECODE_RM_WORD_REGISTER(rh);
- DECODE_PRINTF(",");
- srcoffset = decode_rm00_address(rl);
- srcval = fetch_data_word(srcoffset);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = or_word(*destreg, srcval);
- }
- break;
- case 1:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 *destreg;
- u32 srcval;
-
- destreg = DECODE_RM_LONG_REGISTER(rh);
- DECODE_PRINTF(",");
- srcoffset = decode_rm01_address(rl);
- srcval = fetch_data_long(srcoffset);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = or_long(*destreg, srcval);
- } else {
- u16 *destreg;
- u16 srcval;
-
- destreg = DECODE_RM_WORD_REGISTER(rh);
- DECODE_PRINTF(",");
- srcoffset = decode_rm01_address(rl);
- srcval = fetch_data_word(srcoffset);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = or_word(*destreg, srcval);
- }
- break;
- case 2:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 *destreg;
- u32 srcval;
-
- destreg = DECODE_RM_LONG_REGISTER(rh);
- DECODE_PRINTF(",");
- srcoffset = decode_rm10_address(rl);
- srcval = fetch_data_long(srcoffset);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = or_long(*destreg, srcval);
- } else {
- u16 *destreg;
- u16 srcval;
-
- destreg = DECODE_RM_WORD_REGISTER(rh);
- DECODE_PRINTF(",");
- srcoffset = decode_rm10_address(rl);
- srcval = fetch_data_word(srcoffset);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = or_word(*destreg, srcval);
- }
- break;
- case 3: /* register to register */
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 *destreg, *srcreg;
-
- destreg = DECODE_RM_LONG_REGISTER(rh);
- DECODE_PRINTF(",");
- srcreg = DECODE_RM_LONG_REGISTER(rl);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = or_long(*destreg, *srcreg);
- } else {
- u16 *destreg, *srcreg;
-
- destreg = DECODE_RM_WORD_REGISTER(rh);
- DECODE_PRINTF(",");
- srcreg = DECODE_RM_WORD_REGISTER(rl);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = or_word(*destreg, *srcreg);
- }
- break;
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
-}
-
-/****************************************************************************
-REMARKS:
-Handles opcode 0x0c
-****************************************************************************/
-void x86emuOp_or_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
-{
- u8 srcval;
-
- START_OF_INSTR();
- DECODE_PRINTF("OR\tAL,");
- srcval = fetch_byte_imm();
- DECODE_PRINTF2("%x\n", srcval);
- TRACE_AND_STEP();
- M.x86.R_AL = or_byte(M.x86.R_AL, srcval);
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
-}
-
-/****************************************************************************
-REMARKS:
-Handles opcode 0x0d
-****************************************************************************/
-void x86emuOp_or_word_AX_IMM(u8 X86EMU_UNUSED(op1))
-{
- u32 srcval;
-
- START_OF_INSTR();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- DECODE_PRINTF("OR\tEAX,");
- srcval = fetch_long_imm();
- } else {
- DECODE_PRINTF("OR\tAX,");
- srcval = fetch_word_imm();
- }
- DECODE_PRINTF2("%x\n", srcval);
- TRACE_AND_STEP();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- M.x86.R_EAX = or_long(M.x86.R_EAX, srcval);
- } else {
- M.x86.R_AX = or_word(M.x86.R_AX, (u16) srcval);
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ START_OF_INSTR();
+ DECODE_PRINTF("POP\tES\n");
+ TRACE_AND_STEP();
+ M.x86.R_ES = pop_word();
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/****************************************************************************
@@ -911,12 +479,12 @@ Handles opcode 0x0e
****************************************************************************/
void x86emuOp_push_CS(u8 X86EMU_UNUSED(op1))
{
- START_OF_INSTR();
- DECODE_PRINTF("PUSH\tCS\n");
- TRACE_AND_STEP();
- push_word(M.x86.R_CS);
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ START_OF_INSTR();
+ DECODE_PRINTF("PUSH\tCS\n");
+ TRACE_AND_STEP();
+ push_word(M.x86.R_CS);
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/****************************************************************************
@@ -925,401 +493,9 @@ Handles opcode 0x0f. Escape for two-byte opcode (286 or better)
****************************************************************************/
void x86emuOp_two_byte(u8 X86EMU_UNUSED(op1))
{
- u8 op2 = (*sys_rdb) (((u32) M.x86.R_CS << 4) + (M.x86.R_IP++));
- INC_DECODED_INST_LEN(1);
- (*x86emu_optab2[op2]) (op2);
-}
-
-/****************************************************************************
-REMARKS:
-Handles opcode 0x10
-****************************************************************************/
-void x86emuOp_adc_byte_RM_R(u8 X86EMU_UNUSED(op1))
-{
- int mod, rl, rh;
- u8 *destreg, *srcreg;
- uint destoffset;
- u8 destval;
-
- START_OF_INSTR();
- DECODE_PRINTF("ADC\t");
- FETCH_DECODE_MODRM(mod, rh, rl);
- switch (mod) {
- case 0:
- destoffset = decode_rm00_address(rl);
- DECODE_PRINTF(",");
- destval = fetch_data_byte(destoffset);
- srcreg = DECODE_RM_BYTE_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- destval = adc_byte(destval, *srcreg);
- store_data_byte(destoffset, destval);
- break;
- case 1:
- destoffset = decode_rm01_address(rl);
- DECODE_PRINTF(",");
- destval = fetch_data_byte(destoffset);
- srcreg = DECODE_RM_BYTE_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- destval = adc_byte(destval, *srcreg);
- store_data_byte(destoffset, destval);
- break;
- case 2:
- destoffset = decode_rm10_address(rl);
- DECODE_PRINTF(",");
- destval = fetch_data_byte(destoffset);
- srcreg = DECODE_RM_BYTE_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- destval = adc_byte(destval, *srcreg);
- store_data_byte(destoffset, destval);
- break;
- case 3: /* register to register */
- destreg = DECODE_RM_BYTE_REGISTER(rl);
- DECODE_PRINTF(",");
- srcreg = DECODE_RM_BYTE_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = adc_byte(*destreg, *srcreg);
- break;
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
-}
-
-/****************************************************************************
-REMARKS:
-Handles opcode 0x11
-****************************************************************************/
-void x86emuOp_adc_word_RM_R(u8 X86EMU_UNUSED(op1))
-{
- int mod, rl, rh;
- uint destoffset;
-
- START_OF_INSTR();
- DECODE_PRINTF("ADC\t");
- FETCH_DECODE_MODRM(mod, rh, rl);
- switch (mod) {
- case 0:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 destval;
- u32 *srcreg;
-
- destoffset = decode_rm00_address(rl);
- DECODE_PRINTF(",");
- destval = fetch_data_long(destoffset);
- srcreg = DECODE_RM_LONG_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- destval = adc_long(destval, *srcreg);
- store_data_long(destoffset, destval);
- } else {
- u16 destval;
- u16 *srcreg;
-
- destoffset = decode_rm00_address(rl);
- DECODE_PRINTF(",");
- destval = fetch_data_word(destoffset);
- srcreg = DECODE_RM_WORD_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- destval = adc_word(destval, *srcreg);
- store_data_word(destoffset, destval);
- }
- break;
- case 1:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 destval;
- u32 *srcreg;
-
- destoffset = decode_rm01_address(rl);
- DECODE_PRINTF(",");
- destval = fetch_data_long(destoffset);
- srcreg = DECODE_RM_LONG_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- destval = adc_long(destval, *srcreg);
- store_data_long(destoffset, destval);
- } else {
- u16 destval;
- u16 *srcreg;
-
- destoffset = decode_rm01_address(rl);
- DECODE_PRINTF(",");
- destval = fetch_data_word(destoffset);
- srcreg = DECODE_RM_WORD_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- destval = adc_word(destval, *srcreg);
- store_data_word(destoffset, destval);
- }
- break;
- case 2:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 destval;
- u32 *srcreg;
-
- destoffset = decode_rm10_address(rl);
- DECODE_PRINTF(",");
- destval = fetch_data_long(destoffset);
- srcreg = DECODE_RM_LONG_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- destval = adc_long(destval, *srcreg);
- store_data_long(destoffset, destval);
- } else {
- u16 destval;
- u16 *srcreg;
-
- destoffset = decode_rm10_address(rl);
- DECODE_PRINTF(",");
- destval = fetch_data_word(destoffset);
- srcreg = DECODE_RM_WORD_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- destval = adc_word(destval, *srcreg);
- store_data_word(destoffset, destval);
- }
- break;
- case 3: /* register to register */
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 *destreg, *srcreg;
-
- destreg = DECODE_RM_LONG_REGISTER(rl);
- DECODE_PRINTF(",");
- srcreg = DECODE_RM_LONG_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = adc_long(*destreg, *srcreg);
- } else {
- u16 *destreg, *srcreg;
-
- destreg = DECODE_RM_WORD_REGISTER(rl);
- DECODE_PRINTF(",");
- srcreg = DECODE_RM_WORD_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = adc_word(*destreg, *srcreg);
- }
- break;
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
-}
-
-/****************************************************************************
-REMARKS:
-Handles opcode 0x12
-****************************************************************************/
-void x86emuOp_adc_byte_R_RM(u8 X86EMU_UNUSED(op1))
-{
- int mod, rl, rh;
- u8 *destreg, *srcreg;
- uint srcoffset;
- u8 srcval;
-
- START_OF_INSTR();
- DECODE_PRINTF("ADC\t");
- FETCH_DECODE_MODRM(mod, rh, rl);
- switch (mod) {
- case 0:
- destreg = DECODE_RM_BYTE_REGISTER(rh);
- DECODE_PRINTF(",");
- srcoffset = decode_rm00_address(rl);
- srcval = fetch_data_byte(srcoffset);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = adc_byte(*destreg, srcval);
- break;
- case 1:
- destreg = DECODE_RM_BYTE_REGISTER(rh);
- DECODE_PRINTF(",");
- srcoffset = decode_rm01_address(rl);
- srcval = fetch_data_byte(srcoffset);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = adc_byte(*destreg, srcval);
- break;
- case 2:
- destreg = DECODE_RM_BYTE_REGISTER(rh);
- DECODE_PRINTF(",");
- srcoffset = decode_rm10_address(rl);
- srcval = fetch_data_byte(srcoffset);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = adc_byte(*destreg, srcval);
- break;
- case 3: /* register to register */
- destreg = DECODE_RM_BYTE_REGISTER(rh);
- DECODE_PRINTF(",");
- srcreg = DECODE_RM_BYTE_REGISTER(rl);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = adc_byte(*destreg, *srcreg);
- break;
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
-}
-
-/****************************************************************************
-REMARKS:
-Handles opcode 0x13
-****************************************************************************/
-void x86emuOp_adc_word_R_RM(u8 X86EMU_UNUSED(op1))
-{
- int mod, rl, rh;
- uint srcoffset;
-
- START_OF_INSTR();
- DECODE_PRINTF("ADC\t");
- FETCH_DECODE_MODRM(mod, rh, rl);
- switch (mod) {
- case 0:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 *destreg;
- u32 srcval;
-
- destreg = DECODE_RM_LONG_REGISTER(rh);
- DECODE_PRINTF(",");
- srcoffset = decode_rm00_address(rl);
- srcval = fetch_data_long(srcoffset);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = adc_long(*destreg, srcval);
- } else {
- u16 *destreg;
- u16 srcval;
-
- destreg = DECODE_RM_WORD_REGISTER(rh);
- DECODE_PRINTF(",");
- srcoffset = decode_rm00_address(rl);
- srcval = fetch_data_word(srcoffset);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = adc_word(*destreg, srcval);
- }
- break;
- case 1:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 *destreg;
- u32 srcval;
-
- destreg = DECODE_RM_LONG_REGISTER(rh);
- DECODE_PRINTF(",");
- srcoffset = decode_rm01_address(rl);
- srcval = fetch_data_long(srcoffset);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = adc_long(*destreg, srcval);
- } else {
- u16 *destreg;
- u16 srcval;
-
- destreg = DECODE_RM_WORD_REGISTER(rh);
- DECODE_PRINTF(",");
- srcoffset = decode_rm01_address(rl);
- srcval = fetch_data_word(srcoffset);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = adc_word(*destreg, srcval);
- }
- break;
- case 2:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 *destreg;
- u32 srcval;
-
- destreg = DECODE_RM_LONG_REGISTER(rh);
- DECODE_PRINTF(",");
- srcoffset = decode_rm10_address(rl);
- srcval = fetch_data_long(srcoffset);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = adc_long(*destreg, srcval);
- } else {
- u16 *destreg;
- u16 srcval;
-
- destreg = DECODE_RM_WORD_REGISTER(rh);
- DECODE_PRINTF(",");
- srcoffset = decode_rm10_address(rl);
- srcval = fetch_data_word(srcoffset);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = adc_word(*destreg, srcval);
- }
- break;
- case 3: /* register to register */
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 *destreg, *srcreg;
-
- destreg = DECODE_RM_LONG_REGISTER(rh);
- DECODE_PRINTF(",");
- srcreg = DECODE_RM_LONG_REGISTER(rl);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = adc_long(*destreg, *srcreg);
- } else {
- u16 *destreg, *srcreg;
-
- destreg = DECODE_RM_WORD_REGISTER(rh);
- DECODE_PRINTF(",");
- srcreg = DECODE_RM_WORD_REGISTER(rl);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = adc_word(*destreg, *srcreg);
- }
- break;
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
-}
-
-/****************************************************************************
-REMARKS:
-Handles opcode 0x14
-****************************************************************************/
-void x86emuOp_adc_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
-{
- u8 srcval;
-
- START_OF_INSTR();
- DECODE_PRINTF("ADC\tAL,");
- srcval = fetch_byte_imm();
- DECODE_PRINTF2("%x\n", srcval);
- TRACE_AND_STEP();
- M.x86.R_AL = adc_byte(M.x86.R_AL, srcval);
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
-}
-
-/****************************************************************************
-REMARKS:
-Handles opcode 0x15
-****************************************************************************/
-void x86emuOp_adc_word_AX_IMM(u8 X86EMU_UNUSED(op1))
-{
- u32 srcval;
-
- START_OF_INSTR();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- DECODE_PRINTF("ADC\tEAX,");
- srcval = fetch_long_imm();
- } else {
- DECODE_PRINTF("ADC\tAX,");
- srcval = fetch_word_imm();
- }
- DECODE_PRINTF2("%x\n", srcval);
- TRACE_AND_STEP();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- M.x86.R_EAX = adc_long(M.x86.R_EAX, srcval);
- } else {
- M.x86.R_AX = adc_word(M.x86.R_AX, (u16) srcval);
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ u8 op2 = (*sys_rdb)(((u32)M.x86.R_CS << 4) + (M.x86.R_IP++));
+ INC_DECODED_INST_LEN(1);
+ (*x86emu_optab2[op2])(op2);
}
/****************************************************************************
@@ -1328,12 +504,12 @@ Handles opcode 0x16
****************************************************************************/
void x86emuOp_push_SS(u8 X86EMU_UNUSED(op1))
{
- START_OF_INSTR();
- DECODE_PRINTF("PUSH\tSS\n");
- TRACE_AND_STEP();
- push_word(M.x86.R_SS);
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ START_OF_INSTR();
+ DECODE_PRINTF("PUSH\tSS\n");
+ TRACE_AND_STEP();
+ push_word(M.x86.R_SS);
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/****************************************************************************
@@ -1342,404 +518,12 @@ Handles opcode 0x17
****************************************************************************/
void x86emuOp_pop_SS(u8 X86EMU_UNUSED(op1))
{
- START_OF_INSTR();
- DECODE_PRINTF("POP\tSS\n");
- TRACE_AND_STEP();
- M.x86.R_SS = pop_word();
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
-}
-
-/****************************************************************************
-REMARKS:
-Handles opcode 0x18
-****************************************************************************/
-void x86emuOp_sbb_byte_RM_R(u8 X86EMU_UNUSED(op1))
-{
- int mod, rl, rh;
- u8 *destreg, *srcreg;
- uint destoffset;
- u8 destval;
-
- START_OF_INSTR();
- DECODE_PRINTF("SBB\t");
- FETCH_DECODE_MODRM(mod, rh, rl);
- switch (mod) {
- case 0:
- destoffset = decode_rm00_address(rl);
- DECODE_PRINTF(",");
- destval = fetch_data_byte(destoffset);
- srcreg = DECODE_RM_BYTE_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- destval = sbb_byte(destval, *srcreg);
- store_data_byte(destoffset, destval);
- break;
- case 1:
- destoffset = decode_rm01_address(rl);
- DECODE_PRINTF(",");
- destval = fetch_data_byte(destoffset);
- srcreg = DECODE_RM_BYTE_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- destval = sbb_byte(destval, *srcreg);
- store_data_byte(destoffset, destval);
- break;
- case 2:
- destoffset = decode_rm10_address(rl);
- DECODE_PRINTF(",");
- destval = fetch_data_byte(destoffset);
- srcreg = DECODE_RM_BYTE_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- destval = sbb_byte(destval, *srcreg);
- store_data_byte(destoffset, destval);
- break;
- case 3: /* register to register */
- destreg = DECODE_RM_BYTE_REGISTER(rl);
- DECODE_PRINTF(",");
- srcreg = DECODE_RM_BYTE_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = sbb_byte(*destreg, *srcreg);
- break;
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
-}
-
-/****************************************************************************
-REMARKS:
-Handles opcode 0x19
-****************************************************************************/
-void x86emuOp_sbb_word_RM_R(u8 X86EMU_UNUSED(op1))
-{
- int mod, rl, rh;
- uint destoffset;
-
- START_OF_INSTR();
- DECODE_PRINTF("SBB\t");
- FETCH_DECODE_MODRM(mod, rh, rl);
- switch (mod) {
- case 0:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 destval;
- u32 *srcreg;
-
- destoffset = decode_rm00_address(rl);
- DECODE_PRINTF(",");
- destval = fetch_data_long(destoffset);
- srcreg = DECODE_RM_LONG_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- destval = sbb_long(destval, *srcreg);
- store_data_long(destoffset, destval);
- } else {
- u16 destval;
- u16 *srcreg;
-
- destoffset = decode_rm00_address(rl);
- DECODE_PRINTF(",");
- destval = fetch_data_word(destoffset);
- srcreg = DECODE_RM_WORD_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- destval = sbb_word(destval, *srcreg);
- store_data_word(destoffset, destval);
- }
- break;
- case 1:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 destval;
- u32 *srcreg;
-
- destoffset = decode_rm01_address(rl);
- DECODE_PRINTF(",");
- destval = fetch_data_long(destoffset);
- srcreg = DECODE_RM_LONG_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- destval = sbb_long(destval, *srcreg);
- store_data_long(destoffset, destval);
- } else {
- u16 destval;
- u16 *srcreg;
-
- destoffset = decode_rm01_address(rl);
- DECODE_PRINTF(",");
- destval = fetch_data_word(destoffset);
- srcreg = DECODE_RM_WORD_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- destval = sbb_word(destval, *srcreg);
- store_data_word(destoffset, destval);
- }
- break;
- case 2:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 destval;
- u32 *srcreg;
-
- destoffset = decode_rm10_address(rl);
- DECODE_PRINTF(",");
- destval = fetch_data_long(destoffset);
- srcreg = DECODE_RM_LONG_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- destval = sbb_long(destval, *srcreg);
- store_data_long(destoffset, destval);
- } else {
- u16 destval;
- u16 *srcreg;
-
- destoffset = decode_rm10_address(rl);
- DECODE_PRINTF(",");
- destval = fetch_data_word(destoffset);
- srcreg = DECODE_RM_WORD_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- destval = sbb_word(destval, *srcreg);
- store_data_word(destoffset, destval);
- }
- break;
- case 3: /* register to register */
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 *destreg, *srcreg;
-
- destreg = DECODE_RM_LONG_REGISTER(rl);
- DECODE_PRINTF(",");
- srcreg = DECODE_RM_LONG_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = sbb_long(*destreg, *srcreg);
- } else {
- u16 *destreg, *srcreg;
-
- destreg = DECODE_RM_WORD_REGISTER(rl);
- DECODE_PRINTF(",");
- srcreg = DECODE_RM_WORD_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = sbb_word(*destreg, *srcreg);
- }
- break;
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
-}
-
-/****************************************************************************
-REMARKS:
-Handles opcode 0x1a
-****************************************************************************/
-void x86emuOp_sbb_byte_R_RM(u8 X86EMU_UNUSED(op1))
-{
- int mod, rl, rh;
- u8 *destreg, *srcreg;
- uint srcoffset;
- u8 srcval;
-
- START_OF_INSTR();
- DECODE_PRINTF("SBB\t");
- FETCH_DECODE_MODRM(mod, rh, rl);
- switch (mod) {
- case 0:
- destreg = DECODE_RM_BYTE_REGISTER(rh);
- DECODE_PRINTF(",");
- srcoffset = decode_rm00_address(rl);
- srcval = fetch_data_byte(srcoffset);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = sbb_byte(*destreg, srcval);
- break;
- case 1:
- destreg = DECODE_RM_BYTE_REGISTER(rh);
- DECODE_PRINTF(",");
- srcoffset = decode_rm01_address(rl);
- srcval = fetch_data_byte(srcoffset);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = sbb_byte(*destreg, srcval);
- break;
- case 2:
- destreg = DECODE_RM_BYTE_REGISTER(rh);
- DECODE_PRINTF(",");
- srcoffset = decode_rm10_address(rl);
- srcval = fetch_data_byte(srcoffset);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = sbb_byte(*destreg, srcval);
- break;
- case 3: /* register to register */
- destreg = DECODE_RM_BYTE_REGISTER(rh);
- DECODE_PRINTF(",");
- srcreg = DECODE_RM_BYTE_REGISTER(rl);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = sbb_byte(*destreg, *srcreg);
- break;
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
-}
-
-/****************************************************************************
-REMARKS:
-Handles opcode 0x1b
-****************************************************************************/
-void x86emuOp_sbb_word_R_RM(u8 X86EMU_UNUSED(op1))
-{
- int mod, rl, rh;
- uint srcoffset;
-
- START_OF_INSTR();
- DECODE_PRINTF("SBB\t");
- FETCH_DECODE_MODRM(mod, rh, rl);
- switch (mod) {
- case 0:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 *destreg;
- u32 srcval;
-
- destreg = DECODE_RM_LONG_REGISTER(rh);
- DECODE_PRINTF(",");
- srcoffset = decode_rm00_address(rl);
- srcval = fetch_data_long(srcoffset);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = sbb_long(*destreg, srcval);
- } else {
- u16 *destreg;
- u16 srcval;
-
- destreg = DECODE_RM_WORD_REGISTER(rh);
- DECODE_PRINTF(",");
- srcoffset = decode_rm00_address(rl);
- srcval = fetch_data_word(srcoffset);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = sbb_word(*destreg, srcval);
- }
- break;
- case 1:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 *destreg;
- u32 srcval;
-
- destreg = DECODE_RM_LONG_REGISTER(rh);
- DECODE_PRINTF(",");
- srcoffset = decode_rm01_address(rl);
- srcval = fetch_data_long(srcoffset);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = sbb_long(*destreg, srcval);
- } else {
- u16 *destreg;
- u16 srcval;
-
- destreg = DECODE_RM_WORD_REGISTER(rh);
- DECODE_PRINTF(",");
- srcoffset = decode_rm01_address(rl);
- srcval = fetch_data_word(srcoffset);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = sbb_word(*destreg, srcval);
- }
- break;
- case 2:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 *destreg;
- u32 srcval;
-
- destreg = DECODE_RM_LONG_REGISTER(rh);
- DECODE_PRINTF(",");
- srcoffset = decode_rm10_address(rl);
- srcval = fetch_data_long(srcoffset);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = sbb_long(*destreg, srcval);
- } else {
- u16 *destreg;
- u16 srcval;
-
- destreg = DECODE_RM_WORD_REGISTER(rh);
- DECODE_PRINTF(",");
- srcoffset = decode_rm10_address(rl);
- srcval = fetch_data_word(srcoffset);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = sbb_word(*destreg, srcval);
- }
- break;
- case 3: /* register to register */
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 *destreg, *srcreg;
-
- destreg = DECODE_RM_LONG_REGISTER(rh);
- DECODE_PRINTF(",");
- srcreg = DECODE_RM_LONG_REGISTER(rl);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = sbb_long(*destreg, *srcreg);
- } else {
- u16 *destreg, *srcreg;
-
- destreg = DECODE_RM_WORD_REGISTER(rh);
- DECODE_PRINTF(",");
- srcreg = DECODE_RM_WORD_REGISTER(rl);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = sbb_word(*destreg, *srcreg);
- }
- break;
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
-}
-
-/****************************************************************************
-REMARKS:
-Handles opcode 0x1c
-****************************************************************************/
-void x86emuOp_sbb_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
-{
- u8 srcval;
-
- START_OF_INSTR();
- DECODE_PRINTF("SBB\tAL,");
- srcval = fetch_byte_imm();
- DECODE_PRINTF2("%x\n", srcval);
- TRACE_AND_STEP();
- M.x86.R_AL = sbb_byte(M.x86.R_AL, srcval);
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
-}
-
-/****************************************************************************
-REMARKS:
-Handles opcode 0x1d
-****************************************************************************/
-void x86emuOp_sbb_word_AX_IMM(u8 X86EMU_UNUSED(op1))
-{
- u32 srcval;
-
- START_OF_INSTR();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- DECODE_PRINTF("SBB\tEAX,");
- srcval = fetch_long_imm();
- } else {
- DECODE_PRINTF("SBB\tAX,");
- srcval = fetch_word_imm();
- }
- DECODE_PRINTF2("%x\n", srcval);
- TRACE_AND_STEP();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- M.x86.R_EAX = sbb_long(M.x86.R_EAX, srcval);
- } else {
- M.x86.R_AX = sbb_word(M.x86.R_AX, (u16) srcval);
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ START_OF_INSTR();
+ DECODE_PRINTF("POP\tSS\n");
+ TRACE_AND_STEP();
+ M.x86.R_SS = pop_word();
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/****************************************************************************
@@ -1748,12 +532,12 @@ Handles opcode 0x1e
****************************************************************************/
void x86emuOp_push_DS(u8 X86EMU_UNUSED(op1))
{
- START_OF_INSTR();
- DECODE_PRINTF("PUSH\tDS\n");
- TRACE_AND_STEP();
- push_word(M.x86.R_DS);
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ START_OF_INSTR();
+ DECODE_PRINTF("PUSH\tDS\n");
+ TRACE_AND_STEP();
+ push_word(M.x86.R_DS);
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/****************************************************************************
@@ -1762,409 +546,12 @@ Handles opcode 0x1f
****************************************************************************/
void x86emuOp_pop_DS(u8 X86EMU_UNUSED(op1))
{
- START_OF_INSTR();
- DECODE_PRINTF("POP\tDS\n");
- TRACE_AND_STEP();
- M.x86.R_DS = pop_word();
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
-}
-
-/****************************************************************************
-REMARKS:
-Handles opcode 0x20
-****************************************************************************/
-void x86emuOp_and_byte_RM_R(u8 X86EMU_UNUSED(op1))
-{
- int mod, rl, rh;
- u8 *destreg, *srcreg;
- uint destoffset;
- u8 destval;
-
- START_OF_INSTR();
- DECODE_PRINTF("AND\t");
- FETCH_DECODE_MODRM(mod, rh, rl);
-
- switch (mod) {
- case 0:
- destoffset = decode_rm00_address(rl);
- DECODE_PRINTF(",");
- destval = fetch_data_byte(destoffset);
- srcreg = DECODE_RM_BYTE_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- destval = and_byte(destval, *srcreg);
- store_data_byte(destoffset, destval);
- break;
-
- case 1:
- destoffset = decode_rm01_address(rl);
- DECODE_PRINTF(",");
- destval = fetch_data_byte(destoffset);
- srcreg = DECODE_RM_BYTE_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- destval = and_byte(destval, *srcreg);
- store_data_byte(destoffset, destval);
- break;
-
- case 2:
- destoffset = decode_rm10_address(rl);
- DECODE_PRINTF(",");
- destval = fetch_data_byte(destoffset);
- srcreg = DECODE_RM_BYTE_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- destval = and_byte(destval, *srcreg);
- store_data_byte(destoffset, destval);
- break;
-
- case 3: /* register to register */
- destreg = DECODE_RM_BYTE_REGISTER(rl);
- DECODE_PRINTF(",");
- srcreg = DECODE_RM_BYTE_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = and_byte(*destreg, *srcreg);
- break;
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
-}
-
-/****************************************************************************
-REMARKS:
-Handles opcode 0x21
-****************************************************************************/
-void x86emuOp_and_word_RM_R(u8 X86EMU_UNUSED(op1))
-{
- int mod, rl, rh;
- uint destoffset;
-
- START_OF_INSTR();
- DECODE_PRINTF("AND\t");
- FETCH_DECODE_MODRM(mod, rh, rl);
- switch (mod) {
- case 0:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 destval;
- u32 *srcreg;
-
- destoffset = decode_rm00_address(rl);
- DECODE_PRINTF(",");
- destval = fetch_data_long(destoffset);
- srcreg = DECODE_RM_LONG_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- destval = and_long(destval, *srcreg);
- store_data_long(destoffset, destval);
- } else {
- u16 destval;
- u16 *srcreg;
-
- destoffset = decode_rm00_address(rl);
- DECODE_PRINTF(",");
- destval = fetch_data_word(destoffset);
- srcreg = DECODE_RM_WORD_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- destval = and_word(destval, *srcreg);
- store_data_word(destoffset, destval);
- }
- break;
- case 1:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 destval;
- u32 *srcreg;
-
- destoffset = decode_rm01_address(rl);
- DECODE_PRINTF(",");
- destval = fetch_data_long(destoffset);
- srcreg = DECODE_RM_LONG_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- destval = and_long(destval, *srcreg);
- store_data_long(destoffset, destval);
- } else {
- u16 destval;
- u16 *srcreg;
-
- destoffset = decode_rm01_address(rl);
- DECODE_PRINTF(",");
- destval = fetch_data_word(destoffset);
- srcreg = DECODE_RM_WORD_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- destval = and_word(destval, *srcreg);
- store_data_word(destoffset, destval);
- }
- break;
- case 2:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 destval;
- u32 *srcreg;
-
- destoffset = decode_rm10_address(rl);
- DECODE_PRINTF(",");
- destval = fetch_data_long(destoffset);
- srcreg = DECODE_RM_LONG_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- destval = and_long(destval, *srcreg);
- store_data_long(destoffset, destval);
- } else {
- u16 destval;
- u16 *srcreg;
-
- destoffset = decode_rm10_address(rl);
- DECODE_PRINTF(",");
- destval = fetch_data_word(destoffset);
- srcreg = DECODE_RM_WORD_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- destval = and_word(destval, *srcreg);
- store_data_word(destoffset, destval);
- }
- break;
- case 3: /* register to register */
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 *destreg, *srcreg;
-
- destreg = DECODE_RM_LONG_REGISTER(rl);
- DECODE_PRINTF(",");
- srcreg = DECODE_RM_LONG_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = and_long(*destreg, *srcreg);
- } else {
- u16 *destreg, *srcreg;
-
- destreg = DECODE_RM_WORD_REGISTER(rl);
- DECODE_PRINTF(",");
- srcreg = DECODE_RM_WORD_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = and_word(*destreg, *srcreg);
- }
- break;
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
-}
-
-/****************************************************************************
-REMARKS:
-Handles opcode 0x22
-****************************************************************************/
-void x86emuOp_and_byte_R_RM(u8 X86EMU_UNUSED(op1))
-{
- int mod, rl, rh;
- u8 *destreg, *srcreg;
- uint srcoffset;
- u8 srcval;
-
- START_OF_INSTR();
- DECODE_PRINTF("AND\t");
- FETCH_DECODE_MODRM(mod, rh, rl);
- switch (mod) {
- case 0:
- destreg = DECODE_RM_BYTE_REGISTER(rh);
- DECODE_PRINTF(",");
- srcoffset = decode_rm00_address(rl);
- srcval = fetch_data_byte(srcoffset);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = and_byte(*destreg, srcval);
- break;
- case 1:
- destreg = DECODE_RM_BYTE_REGISTER(rh);
- DECODE_PRINTF(",");
- srcoffset = decode_rm01_address(rl);
- srcval = fetch_data_byte(srcoffset);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = and_byte(*destreg, srcval);
- break;
- case 2:
- destreg = DECODE_RM_BYTE_REGISTER(rh);
- DECODE_PRINTF(",");
- srcoffset = decode_rm10_address(rl);
- srcval = fetch_data_byte(srcoffset);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = and_byte(*destreg, srcval);
- break;
- case 3: /* register to register */
- destreg = DECODE_RM_BYTE_REGISTER(rh);
- DECODE_PRINTF(",");
- srcreg = DECODE_RM_BYTE_REGISTER(rl);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = and_byte(*destreg, *srcreg);
- break;
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
-}
-
-/****************************************************************************
-REMARKS:
-Handles opcode 0x23
-****************************************************************************/
-void x86emuOp_and_word_R_RM(u8 X86EMU_UNUSED(op1))
-{
- int mod, rl, rh;
- uint srcoffset;
-
- START_OF_INSTR();
- DECODE_PRINTF("AND\t");
- FETCH_DECODE_MODRM(mod, rh, rl);
- switch (mod) {
- case 0:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 *destreg;
- u32 srcval;
-
- destreg = DECODE_RM_LONG_REGISTER(rh);
- DECODE_PRINTF(",");
- srcoffset = decode_rm00_address(rl);
- srcval = fetch_data_long(srcoffset);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = and_long(*destreg, srcval);
- } else {
- u16 *destreg;
- u16 srcval;
-
- destreg = DECODE_RM_WORD_REGISTER(rh);
- DECODE_PRINTF(",");
- srcoffset = decode_rm00_address(rl);
- srcval = fetch_data_word(srcoffset);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = and_word(*destreg, srcval);
- }
- break;
- case 1:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 *destreg;
- u32 srcval;
-
- destreg = DECODE_RM_LONG_REGISTER(rh);
- DECODE_PRINTF(",");
- srcoffset = decode_rm01_address(rl);
- srcval = fetch_data_long(srcoffset);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = and_long(*destreg, srcval);
- break;
- } else {
- u16 *destreg;
- u16 srcval;
-
- destreg = DECODE_RM_WORD_REGISTER(rh);
- DECODE_PRINTF(",");
- srcoffset = decode_rm01_address(rl);
- srcval = fetch_data_word(srcoffset);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = and_word(*destreg, srcval);
- break;
- }
- case 2:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 *destreg;
- u32 srcval;
-
- destreg = DECODE_RM_LONG_REGISTER(rh);
- DECODE_PRINTF(",");
- srcoffset = decode_rm10_address(rl);
- srcval = fetch_data_long(srcoffset);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = and_long(*destreg, srcval);
- } else {
- u16 *destreg;
- u16 srcval;
-
- destreg = DECODE_RM_WORD_REGISTER(rh);
- DECODE_PRINTF(",");
- srcoffset = decode_rm10_address(rl);
- srcval = fetch_data_word(srcoffset);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = and_word(*destreg, srcval);
- }
- break;
- case 3: /* register to register */
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 *destreg, *srcreg;
-
- destreg = DECODE_RM_LONG_REGISTER(rh);
- DECODE_PRINTF(",");
- srcreg = DECODE_RM_LONG_REGISTER(rl);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = and_long(*destreg, *srcreg);
- } else {
- u16 *destreg, *srcreg;
-
- destreg = DECODE_RM_WORD_REGISTER(rh);
- DECODE_PRINTF(",");
- srcreg = DECODE_RM_WORD_REGISTER(rl);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = and_word(*destreg, *srcreg);
- }
- break;
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
-}
-
-/****************************************************************************
-REMARKS:
-Handles opcode 0x24
-****************************************************************************/
-void x86emuOp_and_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
-{
- u8 srcval;
-
- START_OF_INSTR();
- DECODE_PRINTF("AND\tAL,");
- srcval = fetch_byte_imm();
- DECODE_PRINTF2("%x\n", srcval);
- TRACE_AND_STEP();
- M.x86.R_AL = and_byte(M.x86.R_AL, srcval);
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
-}
-
-/****************************************************************************
-REMARKS:
-Handles opcode 0x25
-****************************************************************************/
-void x86emuOp_and_word_AX_IMM(u8 X86EMU_UNUSED(op1))
-{
- u32 srcval;
-
- START_OF_INSTR();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- DECODE_PRINTF("AND\tEAX,");
- srcval = fetch_long_imm();
- } else {
- DECODE_PRINTF("AND\tAX,");
- srcval = fetch_word_imm();
- }
- DECODE_PRINTF2("%x\n", srcval);
- TRACE_AND_STEP();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- M.x86.R_EAX = and_long(M.x86.R_EAX, srcval);
- } else {
- M.x86.R_AX = and_word(M.x86.R_AX, (u16) srcval);
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ START_OF_INSTR();
+ DECODE_PRINTF("POP\tDS\n");
+ TRACE_AND_STEP();
+ M.x86.R_DS = pop_word();
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/****************************************************************************
@@ -2173,15 +560,15 @@ Handles opcode 0x26
****************************************************************************/
void x86emuOp_segovr_ES(u8 X86EMU_UNUSED(op1))
{
- START_OF_INSTR();
- DECODE_PRINTF("ES:\n");
- TRACE_AND_STEP();
- M.x86.mode |= SYSMODE_SEGOVR_ES;
- /*
- * note the lack of DECODE_CLEAR_SEGOVR(r) since, here is one of 4
- * opcode subroutines we do not want to do this.
- */
- END_OF_INSTR();
+ START_OF_INSTR();
+ DECODE_PRINTF("ES:\n");
+ TRACE_AND_STEP();
+ M.x86.mode |= SYSMODE_SEGOVR_ES;
+ /*
+ * note the lack of DECODE_CLEAR_SEGOVR(r) since, here is one of 4
+ * opcode subroutines we do not want to do this.
+ */
+ END_OF_INSTR();
}
/****************************************************************************
@@ -2190,404 +577,12 @@ Handles opcode 0x27
****************************************************************************/
void x86emuOp_daa(u8 X86EMU_UNUSED(op1))
{
- START_OF_INSTR();
- DECODE_PRINTF("DAA\n");
- TRACE_AND_STEP();
- M.x86.R_AL = daa_byte(M.x86.R_AL);
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
-}
-
-/****************************************************************************
-REMARKS:
-Handles opcode 0x28
-****************************************************************************/
-void x86emuOp_sub_byte_RM_R(u8 X86EMU_UNUSED(op1))
-{
- int mod, rl, rh;
- u8 *destreg, *srcreg;
- uint destoffset;
- u8 destval;
-
- START_OF_INSTR();
- DECODE_PRINTF("SUB\t");
- FETCH_DECODE_MODRM(mod, rh, rl);
- switch (mod) {
- case 0:
- destoffset = decode_rm00_address(rl);
- DECODE_PRINTF(",");
- destval = fetch_data_byte(destoffset);
- srcreg = DECODE_RM_BYTE_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- destval = sub_byte(destval, *srcreg);
- store_data_byte(destoffset, destval);
- break;
- case 1:
- destoffset = decode_rm01_address(rl);
- DECODE_PRINTF(",");
- destval = fetch_data_byte(destoffset);
- srcreg = DECODE_RM_BYTE_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- destval = sub_byte(destval, *srcreg);
- store_data_byte(destoffset, destval);
- break;
- case 2:
- destoffset = decode_rm10_address(rl);
- DECODE_PRINTF(",");
- destval = fetch_data_byte(destoffset);
- srcreg = DECODE_RM_BYTE_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- destval = sub_byte(destval, *srcreg);
- store_data_byte(destoffset, destval);
- break;
- case 3: /* register to register */
- destreg = DECODE_RM_BYTE_REGISTER(rl);
- DECODE_PRINTF(",");
- srcreg = DECODE_RM_BYTE_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = sub_byte(*destreg, *srcreg);
- break;
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
-}
-
-/****************************************************************************
-REMARKS:
-Handles opcode 0x29
-****************************************************************************/
-void x86emuOp_sub_word_RM_R(u8 X86EMU_UNUSED(op1))
-{
- int mod, rl, rh;
- uint destoffset;
-
- START_OF_INSTR();
- DECODE_PRINTF("SUB\t");
- FETCH_DECODE_MODRM(mod, rh, rl);
- switch (mod) {
- case 0:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 destval;
- u32 *srcreg;
-
- destoffset = decode_rm00_address(rl);
- DECODE_PRINTF(",");
- destval = fetch_data_long(destoffset);
- srcreg = DECODE_RM_LONG_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- destval = sub_long(destval, *srcreg);
- store_data_long(destoffset, destval);
- } else {
- u16 destval;
- u16 *srcreg;
-
- destoffset = decode_rm00_address(rl);
- DECODE_PRINTF(",");
- destval = fetch_data_word(destoffset);
- srcreg = DECODE_RM_WORD_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- destval = sub_word(destval, *srcreg);
- store_data_word(destoffset, destval);
- }
- break;
- case 1:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 destval;
- u32 *srcreg;
-
- destoffset = decode_rm01_address(rl);
- DECODE_PRINTF(",");
- destval = fetch_data_long(destoffset);
- srcreg = DECODE_RM_LONG_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- destval = sub_long(destval, *srcreg);
- store_data_long(destoffset, destval);
- } else {
- u16 destval;
- u16 *srcreg;
-
- destoffset = decode_rm01_address(rl);
- DECODE_PRINTF(",");
- destval = fetch_data_word(destoffset);
- srcreg = DECODE_RM_WORD_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- destval = sub_word(destval, *srcreg);
- store_data_word(destoffset, destval);
- }
- break;
- case 2:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 destval;
- u32 *srcreg;
-
- destoffset = decode_rm10_address(rl);
- DECODE_PRINTF(",");
- destval = fetch_data_long(destoffset);
- srcreg = DECODE_RM_LONG_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- destval = sub_long(destval, *srcreg);
- store_data_long(destoffset, destval);
- } else {
- u16 destval;
- u16 *srcreg;
-
- destoffset = decode_rm10_address(rl);
- DECODE_PRINTF(",");
- destval = fetch_data_word(destoffset);
- srcreg = DECODE_RM_WORD_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- destval = sub_word(destval, *srcreg);
- store_data_word(destoffset, destval);
- }
- break;
- case 3: /* register to register */
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 *destreg, *srcreg;
-
- destreg = DECODE_RM_LONG_REGISTER(rl);
- DECODE_PRINTF(",");
- srcreg = DECODE_RM_LONG_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = sub_long(*destreg, *srcreg);
- } else {
- u16 *destreg, *srcreg;
-
- destreg = DECODE_RM_WORD_REGISTER(rl);
- DECODE_PRINTF(",");
- srcreg = DECODE_RM_WORD_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = sub_word(*destreg, *srcreg);
- }
- break;
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
-}
-
-/****************************************************************************
-REMARKS:
-Handles opcode 0x2a
-****************************************************************************/
-void x86emuOp_sub_byte_R_RM(u8 X86EMU_UNUSED(op1))
-{
- int mod, rl, rh;
- u8 *destreg, *srcreg;
- uint srcoffset;
- u8 srcval;
-
- START_OF_INSTR();
- DECODE_PRINTF("SUB\t");
- FETCH_DECODE_MODRM(mod, rh, rl);
- switch (mod) {
- case 0:
- destreg = DECODE_RM_BYTE_REGISTER(rh);
- DECODE_PRINTF(",");
- srcoffset = decode_rm00_address(rl);
- srcval = fetch_data_byte(srcoffset);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = sub_byte(*destreg, srcval);
- break;
- case 1:
- destreg = DECODE_RM_BYTE_REGISTER(rh);
- DECODE_PRINTF(",");
- srcoffset = decode_rm01_address(rl);
- srcval = fetch_data_byte(srcoffset);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = sub_byte(*destreg, srcval);
- break;
- case 2:
- destreg = DECODE_RM_BYTE_REGISTER(rh);
- DECODE_PRINTF(",");
- srcoffset = decode_rm10_address(rl);
- srcval = fetch_data_byte(srcoffset);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = sub_byte(*destreg, srcval);
- break;
- case 3: /* register to register */
- destreg = DECODE_RM_BYTE_REGISTER(rh);
- DECODE_PRINTF(",");
- srcreg = DECODE_RM_BYTE_REGISTER(rl);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = sub_byte(*destreg, *srcreg);
- break;
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
-}
-
-/****************************************************************************
-REMARKS:
-Handles opcode 0x2b
-****************************************************************************/
-void x86emuOp_sub_word_R_RM(u8 X86EMU_UNUSED(op1))
-{
- int mod, rl, rh;
- uint srcoffset;
-
- START_OF_INSTR();
- DECODE_PRINTF("SUB\t");
- FETCH_DECODE_MODRM(mod, rh, rl);
- switch (mod) {
- case 0:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 *destreg;
- u32 srcval;
-
- destreg = DECODE_RM_LONG_REGISTER(rh);
- DECODE_PRINTF(",");
- srcoffset = decode_rm00_address(rl);
- srcval = fetch_data_long(srcoffset);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = sub_long(*destreg, srcval);
- } else {
- u16 *destreg;
- u16 srcval;
-
- destreg = DECODE_RM_WORD_REGISTER(rh);
- DECODE_PRINTF(",");
- srcoffset = decode_rm00_address(rl);
- srcval = fetch_data_word(srcoffset);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = sub_word(*destreg, srcval);
- }
- break;
- case 1:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 *destreg;
- u32 srcval;
-
- destreg = DECODE_RM_LONG_REGISTER(rh);
- DECODE_PRINTF(",");
- srcoffset = decode_rm01_address(rl);
- srcval = fetch_data_long(srcoffset);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = sub_long(*destreg, srcval);
- } else {
- u16 *destreg;
- u16 srcval;
-
- destreg = DECODE_RM_WORD_REGISTER(rh);
- DECODE_PRINTF(",");
- srcoffset = decode_rm01_address(rl);
- srcval = fetch_data_word(srcoffset);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = sub_word(*destreg, srcval);
- }
- break;
- case 2:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 *destreg;
- u32 srcval;
-
- destreg = DECODE_RM_LONG_REGISTER(rh);
- DECODE_PRINTF(",");
- srcoffset = decode_rm10_address(rl);
- srcval = fetch_data_long(srcoffset);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = sub_long(*destreg, srcval);
- } else {
- u16 *destreg;
- u16 srcval;
-
- destreg = DECODE_RM_WORD_REGISTER(rh);
- DECODE_PRINTF(",");
- srcoffset = decode_rm10_address(rl);
- srcval = fetch_data_word(srcoffset);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = sub_word(*destreg, srcval);
- }
- break;
- case 3: /* register to register */
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 *destreg, *srcreg;
-
- destreg = DECODE_RM_LONG_REGISTER(rh);
- DECODE_PRINTF(",");
- srcreg = DECODE_RM_LONG_REGISTER(rl);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = sub_long(*destreg, *srcreg);
- } else {
- u16 *destreg, *srcreg;
-
- destreg = DECODE_RM_WORD_REGISTER(rh);
- DECODE_PRINTF(",");
- srcreg = DECODE_RM_WORD_REGISTER(rl);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = sub_word(*destreg, *srcreg);
- }
- break;
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
-}
-
-/****************************************************************************
-REMARKS:
-Handles opcode 0x2c
-****************************************************************************/
-void x86emuOp_sub_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
-{
- u8 srcval;
-
- START_OF_INSTR();
- DECODE_PRINTF("SUB\tAL,");
- srcval = fetch_byte_imm();
- DECODE_PRINTF2("%x\n", srcval);
- TRACE_AND_STEP();
- M.x86.R_AL = sub_byte(M.x86.R_AL, srcval);
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
-}
-
-/****************************************************************************
-REMARKS:
-Handles opcode 0x2d
-****************************************************************************/
-void x86emuOp_sub_word_AX_IMM(u8 X86EMU_UNUSED(op1))
-{
- u32 srcval;
-
- START_OF_INSTR();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- DECODE_PRINTF("SUB\tEAX,");
- srcval = fetch_long_imm();
- } else {
- DECODE_PRINTF("SUB\tAX,");
- srcval = fetch_word_imm();
- }
- DECODE_PRINTF2("%x\n", srcval);
- TRACE_AND_STEP();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- M.x86.R_EAX = sub_long(M.x86.R_EAX, srcval);
- } else {
- M.x86.R_AX = sub_word(M.x86.R_AX, (u16) srcval);
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ START_OF_INSTR();
+ DECODE_PRINTF("DAA\n");
+ TRACE_AND_STEP();
+ M.x86.R_AL = daa_byte(M.x86.R_AL);
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/****************************************************************************
@@ -2596,12 +591,12 @@ Handles opcode 0x2e
****************************************************************************/
void x86emuOp_segovr_CS(u8 X86EMU_UNUSED(op1))
{
- START_OF_INSTR();
- DECODE_PRINTF("CS:\n");
- TRACE_AND_STEP();
- M.x86.mode |= SYSMODE_SEGOVR_CS;
- /* note no DECODE_CLEAR_SEGOVR here. */
- END_OF_INSTR();
+ START_OF_INSTR();
+ DECODE_PRINTF("CS:\n");
+ TRACE_AND_STEP();
+ M.x86.mode |= SYSMODE_SEGOVR_CS;
+ /* note no DECODE_CLEAR_SEGOVR here. */
+ END_OF_INSTR();
}
/****************************************************************************
@@ -2610,404 +605,12 @@ Handles opcode 0x2f
****************************************************************************/
void x86emuOp_das(u8 X86EMU_UNUSED(op1))
{
- START_OF_INSTR();
- DECODE_PRINTF("DAS\n");
- TRACE_AND_STEP();
- M.x86.R_AL = das_byte(M.x86.R_AL);
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
-}
-
-/****************************************************************************
-REMARKS:
-Handles opcode 0x30
-****************************************************************************/
-void x86emuOp_xor_byte_RM_R(u8 X86EMU_UNUSED(op1))
-{
- int mod, rl, rh;
- u8 *destreg, *srcreg;
- uint destoffset;
- u8 destval;
-
- START_OF_INSTR();
- DECODE_PRINTF("XOR\t");
- FETCH_DECODE_MODRM(mod, rh, rl);
- switch (mod) {
- case 0:
- destoffset = decode_rm00_address(rl);
- DECODE_PRINTF(",");
- destval = fetch_data_byte(destoffset);
- srcreg = DECODE_RM_BYTE_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- destval = xor_byte(destval, *srcreg);
- store_data_byte(destoffset, destval);
- break;
- case 1:
- destoffset = decode_rm01_address(rl);
- DECODE_PRINTF(",");
- destval = fetch_data_byte(destoffset);
- srcreg = DECODE_RM_BYTE_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- destval = xor_byte(destval, *srcreg);
- store_data_byte(destoffset, destval);
- break;
- case 2:
- destoffset = decode_rm10_address(rl);
- DECODE_PRINTF(",");
- destval = fetch_data_byte(destoffset);
- srcreg = DECODE_RM_BYTE_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- destval = xor_byte(destval, *srcreg);
- store_data_byte(destoffset, destval);
- break;
- case 3: /* register to register */
- destreg = DECODE_RM_BYTE_REGISTER(rl);
- DECODE_PRINTF(",");
- srcreg = DECODE_RM_BYTE_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = xor_byte(*destreg, *srcreg);
- break;
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
-}
-
-/****************************************************************************
-REMARKS:
-Handles opcode 0x31
-****************************************************************************/
-void x86emuOp_xor_word_RM_R(u8 X86EMU_UNUSED(op1))
-{
- int mod, rl, rh;
- uint destoffset;
-
- START_OF_INSTR();
- DECODE_PRINTF("XOR\t");
- FETCH_DECODE_MODRM(mod, rh, rl);
- switch (mod) {
- case 0:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 destval;
- u32 *srcreg;
-
- destoffset = decode_rm00_address(rl);
- DECODE_PRINTF(",");
- destval = fetch_data_long(destoffset);
- srcreg = DECODE_RM_LONG_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- destval = xor_long(destval, *srcreg);
- store_data_long(destoffset, destval);
- } else {
- u16 destval;
- u16 *srcreg;
-
- destoffset = decode_rm00_address(rl);
- DECODE_PRINTF(",");
- destval = fetch_data_word(destoffset);
- srcreg = DECODE_RM_WORD_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- destval = xor_word(destval, *srcreg);
- store_data_word(destoffset, destval);
- }
- break;
- case 1:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 destval;
- u32 *srcreg;
-
- destoffset = decode_rm01_address(rl);
- DECODE_PRINTF(",");
- destval = fetch_data_long(destoffset);
- srcreg = DECODE_RM_LONG_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- destval = xor_long(destval, *srcreg);
- store_data_long(destoffset, destval);
- } else {
- u16 destval;
- u16 *srcreg;
-
- destoffset = decode_rm01_address(rl);
- DECODE_PRINTF(",");
- destval = fetch_data_word(destoffset);
- srcreg = DECODE_RM_WORD_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- destval = xor_word(destval, *srcreg);
- store_data_word(destoffset, destval);
- }
- break;
- case 2:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 destval;
- u32 *srcreg;
-
- destoffset = decode_rm10_address(rl);
- DECODE_PRINTF(",");
- destval = fetch_data_long(destoffset);
- srcreg = DECODE_RM_LONG_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- destval = xor_long(destval, *srcreg);
- store_data_long(destoffset, destval);
- } else {
- u16 destval;
- u16 *srcreg;
-
- destoffset = decode_rm10_address(rl);
- DECODE_PRINTF(",");
- destval = fetch_data_word(destoffset);
- srcreg = DECODE_RM_WORD_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- destval = xor_word(destval, *srcreg);
- store_data_word(destoffset, destval);
- }
- break;
- case 3: /* register to register */
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 *destreg, *srcreg;
-
- destreg = DECODE_RM_LONG_REGISTER(rl);
- DECODE_PRINTF(",");
- srcreg = DECODE_RM_LONG_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = xor_long(*destreg, *srcreg);
- } else {
- u16 *destreg, *srcreg;
-
- destreg = DECODE_RM_WORD_REGISTER(rl);
- DECODE_PRINTF(",");
- srcreg = DECODE_RM_WORD_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = xor_word(*destreg, *srcreg);
- }
- break;
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
-}
-
-/****************************************************************************
-REMARKS:
-Handles opcode 0x32
-****************************************************************************/
-void x86emuOp_xor_byte_R_RM(u8 X86EMU_UNUSED(op1))
-{
- int mod, rl, rh;
- u8 *destreg, *srcreg;
- uint srcoffset;
- u8 srcval;
-
- START_OF_INSTR();
- DECODE_PRINTF("XOR\t");
- FETCH_DECODE_MODRM(mod, rh, rl);
- switch (mod) {
- case 0:
- destreg = DECODE_RM_BYTE_REGISTER(rh);
- DECODE_PRINTF(",");
- srcoffset = decode_rm00_address(rl);
- srcval = fetch_data_byte(srcoffset);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = xor_byte(*destreg, srcval);
- break;
- case 1:
- destreg = DECODE_RM_BYTE_REGISTER(rh);
- DECODE_PRINTF(",");
- srcoffset = decode_rm01_address(rl);
- srcval = fetch_data_byte(srcoffset);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = xor_byte(*destreg, srcval);
- break;
- case 2:
- destreg = DECODE_RM_BYTE_REGISTER(rh);
- DECODE_PRINTF(",");
- srcoffset = decode_rm10_address(rl);
- srcval = fetch_data_byte(srcoffset);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = xor_byte(*destreg, srcval);
- break;
- case 3: /* register to register */
- destreg = DECODE_RM_BYTE_REGISTER(rh);
- DECODE_PRINTF(",");
- srcreg = DECODE_RM_BYTE_REGISTER(rl);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = xor_byte(*destreg, *srcreg);
- break;
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
-}
-
-/****************************************************************************
-REMARKS:
-Handles opcode 0x33
-****************************************************************************/
-void x86emuOp_xor_word_R_RM(u8 X86EMU_UNUSED(op1))
-{
- int mod, rl, rh;
- uint srcoffset;
-
- START_OF_INSTR();
- DECODE_PRINTF("XOR\t");
- FETCH_DECODE_MODRM(mod, rh, rl);
- switch (mod) {
- case 0:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 *destreg;
- u32 srcval;
-
- destreg = DECODE_RM_LONG_REGISTER(rh);
- DECODE_PRINTF(",");
- srcoffset = decode_rm00_address(rl);
- srcval = fetch_data_long(srcoffset);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = xor_long(*destreg, srcval);
- } else {
- u16 *destreg;
- u16 srcval;
-
- destreg = DECODE_RM_WORD_REGISTER(rh);
- DECODE_PRINTF(",");
- srcoffset = decode_rm00_address(rl);
- srcval = fetch_data_word(srcoffset);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = xor_word(*destreg, srcval);
- }
- break;
- case 1:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 *destreg;
- u32 srcval;
-
- destreg = DECODE_RM_LONG_REGISTER(rh);
- DECODE_PRINTF(",");
- srcoffset = decode_rm01_address(rl);
- srcval = fetch_data_long(srcoffset);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = xor_long(*destreg, srcval);
- } else {
- u16 *destreg;
- u16 srcval;
-
- destreg = DECODE_RM_WORD_REGISTER(rh);
- DECODE_PRINTF(",");
- srcoffset = decode_rm01_address(rl);
- srcval = fetch_data_word(srcoffset);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = xor_word(*destreg, srcval);
- }
- break;
- case 2:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 *destreg;
- u32 srcval;
-
- destreg = DECODE_RM_LONG_REGISTER(rh);
- DECODE_PRINTF(",");
- srcoffset = decode_rm10_address(rl);
- srcval = fetch_data_long(srcoffset);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = xor_long(*destreg, srcval);
- } else {
- u16 *destreg;
- u16 srcval;
-
- destreg = DECODE_RM_WORD_REGISTER(rh);
- DECODE_PRINTF(",");
- srcoffset = decode_rm10_address(rl);
- srcval = fetch_data_word(srcoffset);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = xor_word(*destreg, srcval);
- }
- break;
- case 3: /* register to register */
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 *destreg, *srcreg;
-
- destreg = DECODE_RM_LONG_REGISTER(rh);
- DECODE_PRINTF(",");
- srcreg = DECODE_RM_LONG_REGISTER(rl);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = xor_long(*destreg, *srcreg);
- } else {
- u16 *destreg, *srcreg;
-
- destreg = DECODE_RM_WORD_REGISTER(rh);
- DECODE_PRINTF(",");
- srcreg = DECODE_RM_WORD_REGISTER(rl);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = xor_word(*destreg, *srcreg);
- }
- break;
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
-}
-
-/****************************************************************************
-REMARKS:
-Handles opcode 0x34
-****************************************************************************/
-void x86emuOp_xor_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
-{
- u8 srcval;
-
- START_OF_INSTR();
- DECODE_PRINTF("XOR\tAL,");
- srcval = fetch_byte_imm();
- DECODE_PRINTF2("%x\n", srcval);
- TRACE_AND_STEP();
- M.x86.R_AL = xor_byte(M.x86.R_AL, srcval);
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
-}
-
-/****************************************************************************
-REMARKS:
-Handles opcode 0x35
-****************************************************************************/
-void x86emuOp_xor_word_AX_IMM(u8 X86EMU_UNUSED(op1))
-{
- u32 srcval;
-
- START_OF_INSTR();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- DECODE_PRINTF("XOR\tEAX,");
- srcval = fetch_long_imm();
- } else {
- DECODE_PRINTF("XOR\tAX,");
- srcval = fetch_word_imm();
- }
- DECODE_PRINTF2("%x\n", srcval);
- TRACE_AND_STEP();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- M.x86.R_EAX = xor_long(M.x86.R_EAX, srcval);
- } else {
- M.x86.R_AX = xor_word(M.x86.R_AX, (u16) srcval);
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ START_OF_INSTR();
+ DECODE_PRINTF("DAS\n");
+ TRACE_AND_STEP();
+ M.x86.R_AL = das_byte(M.x86.R_AL);
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/****************************************************************************
@@ -3016,12 +619,12 @@ Handles opcode 0x36
****************************************************************************/
void x86emuOp_segovr_SS(u8 X86EMU_UNUSED(op1))
{
- START_OF_INSTR();
- DECODE_PRINTF("SS:\n");
- TRACE_AND_STEP();
- M.x86.mode |= SYSMODE_SEGOVR_SS;
- /* no DECODE_CLEAR_SEGOVR ! */
- END_OF_INSTR();
+ START_OF_INSTR();
+ DECODE_PRINTF("SS:\n");
+ TRACE_AND_STEP();
+ M.x86.mode |= SYSMODE_SEGOVR_SS;
+ /* no DECODE_CLEAR_SEGOVR ! */
+ END_OF_INSTR();
}
/****************************************************************************
@@ -3030,395 +633,12 @@ Handles opcode 0x37
****************************************************************************/
void x86emuOp_aaa(u8 X86EMU_UNUSED(op1))
{
- START_OF_INSTR();
- DECODE_PRINTF("AAA\n");
- TRACE_AND_STEP();
- M.x86.R_AX = aaa_word(M.x86.R_AX);
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
-}
-
-/****************************************************************************
-REMARKS:
-Handles opcode 0x38
-****************************************************************************/
-void x86emuOp_cmp_byte_RM_R(u8 X86EMU_UNUSED(op1))
-{
- int mod, rl, rh;
- uint destoffset;
- u8 *destreg, *srcreg;
- u8 destval;
-
- START_OF_INSTR();
- DECODE_PRINTF("CMP\t");
- FETCH_DECODE_MODRM(mod, rh, rl);
- switch (mod) {
- case 0:
- destoffset = decode_rm00_address(rl);
- DECODE_PRINTF(",");
- destval = fetch_data_byte(destoffset);
- srcreg = DECODE_RM_BYTE_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- cmp_byte(destval, *srcreg);
- break;
- case 1:
- destoffset = decode_rm01_address(rl);
- DECODE_PRINTF(",");
- destval = fetch_data_byte(destoffset);
- srcreg = DECODE_RM_BYTE_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- cmp_byte(destval, *srcreg);
- break;
- case 2:
- destoffset = decode_rm10_address(rl);
- DECODE_PRINTF(",");
- destval = fetch_data_byte(destoffset);
- srcreg = DECODE_RM_BYTE_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- cmp_byte(destval, *srcreg);
- break;
- case 3: /* register to register */
- destreg = DECODE_RM_BYTE_REGISTER(rl);
- DECODE_PRINTF(",");
- srcreg = DECODE_RM_BYTE_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- cmp_byte(*destreg, *srcreg);
- break;
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
-}
-
-/****************************************************************************
-REMARKS:
-Handles opcode 0x39
-****************************************************************************/
-void x86emuOp_cmp_word_RM_R(u8 X86EMU_UNUSED(op1))
-{
- int mod, rl, rh;
- uint destoffset;
-
- START_OF_INSTR();
- DECODE_PRINTF("CMP\t");
- FETCH_DECODE_MODRM(mod, rh, rl);
- switch (mod) {
- case 0:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 destval;
- u32 *srcreg;
-
- destoffset = decode_rm00_address(rl);
- DECODE_PRINTF(",");
- destval = fetch_data_long(destoffset);
- srcreg = DECODE_RM_LONG_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- cmp_long(destval, *srcreg);
- } else {
- u16 destval;
- u16 *srcreg;
-
- destoffset = decode_rm00_address(rl);
- DECODE_PRINTF(",");
- destval = fetch_data_word(destoffset);
- srcreg = DECODE_RM_WORD_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- cmp_word(destval, *srcreg);
- }
- break;
- case 1:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 destval;
- u32 *srcreg;
-
- destoffset = decode_rm01_address(rl);
- DECODE_PRINTF(",");
- destval = fetch_data_long(destoffset);
- srcreg = DECODE_RM_LONG_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- cmp_long(destval, *srcreg);
- } else {
- u16 destval;
- u16 *srcreg;
-
- destoffset = decode_rm01_address(rl);
- DECODE_PRINTF(",");
- destval = fetch_data_word(destoffset);
- srcreg = DECODE_RM_WORD_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- cmp_word(destval, *srcreg);
- }
- break;
- case 2:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 destval;
- u32 *srcreg;
-
- destoffset = decode_rm10_address(rl);
- DECODE_PRINTF(",");
- destval = fetch_data_long(destoffset);
- srcreg = DECODE_RM_LONG_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- cmp_long(destval, *srcreg);
- } else {
- u16 destval;
- u16 *srcreg;
-
- destoffset = decode_rm10_address(rl);
- DECODE_PRINTF(",");
- destval = fetch_data_word(destoffset);
- srcreg = DECODE_RM_WORD_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- cmp_word(destval, *srcreg);
- }
- break;
- case 3: /* register to register */
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 *destreg, *srcreg;
-
- destreg = DECODE_RM_LONG_REGISTER(rl);
- DECODE_PRINTF(",");
- srcreg = DECODE_RM_LONG_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- cmp_long(*destreg, *srcreg);
- } else {
- u16 *destreg, *srcreg;
-
- destreg = DECODE_RM_WORD_REGISTER(rl);
- DECODE_PRINTF(",");
- srcreg = DECODE_RM_WORD_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- cmp_word(*destreg, *srcreg);
- }
- break;
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
-}
-
-/****************************************************************************
-REMARKS:
-Handles opcode 0x3a
-****************************************************************************/
-void x86emuOp_cmp_byte_R_RM(u8 X86EMU_UNUSED(op1))
-{
- int mod, rl, rh;
- u8 *destreg, *srcreg;
- uint srcoffset;
- u8 srcval;
-
- START_OF_INSTR();
- DECODE_PRINTF("CMP\t");
- FETCH_DECODE_MODRM(mod, rh, rl);
- switch (mod) {
- case 0:
- destreg = DECODE_RM_BYTE_REGISTER(rh);
- DECODE_PRINTF(",");
- srcoffset = decode_rm00_address(rl);
- srcval = fetch_data_byte(srcoffset);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- cmp_byte(*destreg, srcval);
- break;
- case 1:
- destreg = DECODE_RM_BYTE_REGISTER(rh);
- DECODE_PRINTF(",");
- srcoffset = decode_rm01_address(rl);
- srcval = fetch_data_byte(srcoffset);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- cmp_byte(*destreg, srcval);
- break;
- case 2:
- destreg = DECODE_RM_BYTE_REGISTER(rh);
- DECODE_PRINTF(",");
- srcoffset = decode_rm10_address(rl);
- srcval = fetch_data_byte(srcoffset);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- cmp_byte(*destreg, srcval);
- break;
- case 3: /* register to register */
- destreg = DECODE_RM_BYTE_REGISTER(rh);
- DECODE_PRINTF(",");
- srcreg = DECODE_RM_BYTE_REGISTER(rl);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- cmp_byte(*destreg, *srcreg);
- break;
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
-}
-
-/****************************************************************************
-REMARKS:
-Handles opcode 0x3b
-****************************************************************************/
-void x86emuOp_cmp_word_R_RM(u8 X86EMU_UNUSED(op1))
-{
- int mod, rl, rh;
- uint srcoffset;
-
- START_OF_INSTR();
- DECODE_PRINTF("CMP\t");
- FETCH_DECODE_MODRM(mod, rh, rl);
- switch (mod) {
- case 0:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 *destreg;
- u32 srcval;
-
- destreg = DECODE_RM_LONG_REGISTER(rh);
- DECODE_PRINTF(",");
- srcoffset = decode_rm00_address(rl);
- srcval = fetch_data_long(srcoffset);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- cmp_long(*destreg, srcval);
- } else {
- u16 *destreg;
- u16 srcval;
-
- destreg = DECODE_RM_WORD_REGISTER(rh);
- DECODE_PRINTF(",");
- srcoffset = decode_rm00_address(rl);
- srcval = fetch_data_word(srcoffset);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- cmp_word(*destreg, srcval);
- }
- break;
- case 1:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 *destreg;
- u32 srcval;
-
- destreg = DECODE_RM_LONG_REGISTER(rh);
- DECODE_PRINTF(",");
- srcoffset = decode_rm01_address(rl);
- srcval = fetch_data_long(srcoffset);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- cmp_long(*destreg, srcval);
- } else {
- u16 *destreg;
- u16 srcval;
-
- destreg = DECODE_RM_WORD_REGISTER(rh);
- DECODE_PRINTF(",");
- srcoffset = decode_rm01_address(rl);
- srcval = fetch_data_word(srcoffset);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- cmp_word(*destreg, srcval);
- }
- break;
- case 2:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 *destreg;
- u32 srcval;
-
- destreg = DECODE_RM_LONG_REGISTER(rh);
- DECODE_PRINTF(",");
- srcoffset = decode_rm10_address(rl);
- srcval = fetch_data_long(srcoffset);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- cmp_long(*destreg, srcval);
- } else {
- u16 *destreg;
- u16 srcval;
-
- destreg = DECODE_RM_WORD_REGISTER(rh);
- DECODE_PRINTF(",");
- srcoffset = decode_rm10_address(rl);
- srcval = fetch_data_word(srcoffset);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- cmp_word(*destreg, srcval);
- }
- break;
- case 3: /* register to register */
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 *destreg, *srcreg;
-
- destreg = DECODE_RM_LONG_REGISTER(rh);
- DECODE_PRINTF(",");
- srcreg = DECODE_RM_LONG_REGISTER(rl);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- cmp_long(*destreg, *srcreg);
- } else {
- u16 *destreg, *srcreg;
-
- destreg = DECODE_RM_WORD_REGISTER(rh);
- DECODE_PRINTF(",");
- srcreg = DECODE_RM_WORD_REGISTER(rl);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- cmp_word(*destreg, *srcreg);
- }
- break;
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
-}
-
-/****************************************************************************
-REMARKS:
-Handles opcode 0x3c
-****************************************************************************/
-void x86emuOp_cmp_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
-{
- u8 srcval;
-
- START_OF_INSTR();
- DECODE_PRINTF("CMP\tAL,");
- srcval = fetch_byte_imm();
- DECODE_PRINTF2("%x\n", srcval);
- TRACE_AND_STEP();
- cmp_byte(M.x86.R_AL, srcval);
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
-}
-
-/****************************************************************************
-REMARKS:
-Handles opcode 0x3d
-****************************************************************************/
-void x86emuOp_cmp_word_AX_IMM(u8 X86EMU_UNUSED(op1))
-{
- u32 srcval;
-
- START_OF_INSTR();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- DECODE_PRINTF("CMP\tEAX,");
- srcval = fetch_long_imm();
- } else {
- DECODE_PRINTF("CMP\tAX,");
- srcval = fetch_word_imm();
- }
- DECODE_PRINTF2("%x\n", srcval);
- TRACE_AND_STEP();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- cmp_long(M.x86.R_EAX, srcval);
- } else {
- cmp_word(M.x86.R_AX, (u16) srcval);
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ START_OF_INSTR();
+ DECODE_PRINTF("AAA\n");
+ TRACE_AND_STEP();
+ M.x86.R_AX = aaa_word(M.x86.R_AX);
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/****************************************************************************
@@ -3427,12 +647,12 @@ Handles opcode 0x3e
****************************************************************************/
void x86emuOp_segovr_DS(u8 X86EMU_UNUSED(op1))
{
- START_OF_INSTR();
- DECODE_PRINTF("DS:\n");
- TRACE_AND_STEP();
- M.x86.mode |= SYSMODE_SEGOVR_DS;
- /* NO DECODE_CLEAR_SEGOVR! */
- END_OF_INSTR();
+ START_OF_INSTR();
+ DECODE_PRINTF("DS:\n");
+ TRACE_AND_STEP();
+ M.x86.mode |= SYSMODE_SEGOVR_DS;
+ /* NO DECODE_CLEAR_SEGOVR! */
+ END_OF_INSTR();
}
/****************************************************************************
@@ -3441,720 +661,116 @@ Handles opcode 0x3f
****************************************************************************/
void x86emuOp_aas(u8 X86EMU_UNUSED(op1))
{
- START_OF_INSTR();
- DECODE_PRINTF("AAS\n");
- TRACE_AND_STEP();
- M.x86.R_AX = aas_word(M.x86.R_AX);
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
-}
-
-/****************************************************************************
-REMARKS:
-Handles opcode 0x40
-****************************************************************************/
-void x86emuOp_inc_AX(u8 X86EMU_UNUSED(op1))
+ START_OF_INSTR();
+ DECODE_PRINTF("AAS\n");
+ TRACE_AND_STEP();
+ M.x86.R_AX = aas_word(M.x86.R_AX);
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0x40 - 0x47
+****************************************************************************/
+void x86emuOp_inc_register(u8 op1)
{
- START_OF_INSTR();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- DECODE_PRINTF("INC\tEAX\n");
- } else {
- DECODE_PRINTF("INC\tAX\n");
- }
- TRACE_AND_STEP();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- M.x86.R_EAX = inc_long(M.x86.R_EAX);
- } else {
- M.x86.R_AX = inc_word(M.x86.R_AX);
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ START_OF_INSTR();
+ op1 &= 0x7;
+ DECODE_PRINTF("INC\t");
+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+ u32 *reg;
+ reg = DECODE_RM_LONG_REGISTER(op1);
+ DECODE_PRINTF("\n");
+ TRACE_AND_STEP();
+ *reg = inc_long(*reg);
+ } else {
+ u16 *reg;
+ reg = DECODE_RM_WORD_REGISTER(op1);
+ DECODE_PRINTF("\n");
+ TRACE_AND_STEP();
+ *reg = inc_word(*reg);
+ }
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/****************************************************************************
REMARKS:
-Handles opcode 0x41
+Handles opcode 0x48 - 0x4F
****************************************************************************/
-void x86emuOp_inc_CX(u8 X86EMU_UNUSED(op1))
+void x86emuOp_dec_register(u8 op1)
{
- START_OF_INSTR();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- DECODE_PRINTF("INC\tECX\n");
- } else {
- DECODE_PRINTF("INC\tCX\n");
- }
- TRACE_AND_STEP();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- M.x86.R_ECX = inc_long(M.x86.R_ECX);
- } else {
- M.x86.R_CX = inc_word(M.x86.R_CX);
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ START_OF_INSTR();
+ op1 &= 0x7;
+ DECODE_PRINTF("DEC\t");
+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+ u32 *reg;
+ reg = DECODE_RM_LONG_REGISTER(op1);
+ DECODE_PRINTF("\n");
+ TRACE_AND_STEP();
+ *reg = dec_long(*reg);
+ } else {
+ u16 *reg;
+ reg = DECODE_RM_WORD_REGISTER(op1);
+ DECODE_PRINTF("\n");
+ TRACE_AND_STEP();
+ *reg = dec_word(*reg);
+ }
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/****************************************************************************
REMARKS:
-Handles opcode 0x42
+Handles opcode 0x50 - 0x57
****************************************************************************/
-void x86emuOp_inc_DX(u8 X86EMU_UNUSED(op1))
+void x86emuOp_push_register(u8 op1)
{
- START_OF_INSTR();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- DECODE_PRINTF("INC\tEDX\n");
- } else {
- DECODE_PRINTF("INC\tDX\n");
- }
- TRACE_AND_STEP();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- M.x86.R_EDX = inc_long(M.x86.R_EDX);
- } else {
- M.x86.R_DX = inc_word(M.x86.R_DX);
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ START_OF_INSTR();
+ op1 &= 0x7;
+ DECODE_PRINTF("PUSH\t");
+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+ u32 *reg;
+ reg = DECODE_RM_LONG_REGISTER(op1);
+ DECODE_PRINTF("\n");
+ TRACE_AND_STEP();
+ push_long(*reg);
+ } else {
+ u16 *reg;
+ reg = DECODE_RM_WORD_REGISTER(op1);
+ DECODE_PRINTF("\n");
+ TRACE_AND_STEP();
+ push_word(*reg);
+ }
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/****************************************************************************
REMARKS:
-Handles opcode 0x43
+Handles opcode 0x58 - 0x5F
****************************************************************************/
-void x86emuOp_inc_BX(u8 X86EMU_UNUSED(op1))
+void x86emuOp_pop_register(u8 op1)
{
- START_OF_INSTR();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- DECODE_PRINTF("INC\tEBX\n");
- } else {
- DECODE_PRINTF("INC\tBX\n");
- }
- TRACE_AND_STEP();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- M.x86.R_EBX = inc_long(M.x86.R_EBX);
- } else {
- M.x86.R_BX = inc_word(M.x86.R_BX);
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
-}
-
-/****************************************************************************
-REMARKS:
-Handles opcode 0x44
-****************************************************************************/
-void x86emuOp_inc_SP(u8 X86EMU_UNUSED(op1))
-{
- START_OF_INSTR();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- DECODE_PRINTF("INC\tESP\n");
- } else {
- DECODE_PRINTF("INC\tSP\n");
- }
- TRACE_AND_STEP();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- M.x86.R_ESP = inc_long(M.x86.R_ESP);
- } else {
- M.x86.R_SP = inc_word(M.x86.R_SP);
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
-}
-
-/****************************************************************************
-REMARKS:
-Handles opcode 0x45
-****************************************************************************/
-void x86emuOp_inc_BP(u8 X86EMU_UNUSED(op1))
-{
- START_OF_INSTR();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- DECODE_PRINTF("INC\tEBP\n");
- } else {
- DECODE_PRINTF("INC\tBP\n");
- }
- TRACE_AND_STEP();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- M.x86.R_EBP = inc_long(M.x86.R_EBP);
- } else {
- M.x86.R_BP = inc_word(M.x86.R_BP);
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
-}
-
-/****************************************************************************
-REMARKS:
-Handles opcode 0x46
-****************************************************************************/
-void x86emuOp_inc_SI(u8 X86EMU_UNUSED(op1))
-{
- START_OF_INSTR();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- DECODE_PRINTF("INC\tESI\n");
- } else {
- DECODE_PRINTF("INC\tSI\n");
- }
- TRACE_AND_STEP();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- M.x86.R_ESI = inc_long(M.x86.R_ESI);
- } else {
- M.x86.R_SI = inc_word(M.x86.R_SI);
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
-}
-
-/****************************************************************************
-REMARKS:
-Handles opcode 0x47
-****************************************************************************/
-void x86emuOp_inc_DI(u8 X86EMU_UNUSED(op1))
-{
- START_OF_INSTR();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- DECODE_PRINTF("INC\tEDI\n");
- } else {
- DECODE_PRINTF("INC\tDI\n");
- }
- TRACE_AND_STEP();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- M.x86.R_EDI = inc_long(M.x86.R_EDI);
- } else {
- M.x86.R_DI = inc_word(M.x86.R_DI);
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
-}
-
-/****************************************************************************
-REMARKS:
-Handles opcode 0x48
-****************************************************************************/
-void x86emuOp_dec_AX(u8 X86EMU_UNUSED(op1))
-{
- START_OF_INSTR();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- DECODE_PRINTF("DEC\tEAX\n");
- } else {
- DECODE_PRINTF("DEC\tAX\n");
- }
- TRACE_AND_STEP();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- M.x86.R_EAX = dec_long(M.x86.R_EAX);
- } else {
- M.x86.R_AX = dec_word(M.x86.R_AX);
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
-}
-
-/****************************************************************************
-REMARKS:
-Handles opcode 0x49
-****************************************************************************/
-void x86emuOp_dec_CX(u8 X86EMU_UNUSED(op1))
-{
- START_OF_INSTR();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- DECODE_PRINTF("DEC\tECX\n");
- } else {
- DECODE_PRINTF("DEC\tCX\n");
- }
- TRACE_AND_STEP();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- M.x86.R_ECX = dec_long(M.x86.R_ECX);
- } else {
- M.x86.R_CX = dec_word(M.x86.R_CX);
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
-}
-
-/****************************************************************************
-REMARKS:
-Handles opcode 0x4a
-****************************************************************************/
-void x86emuOp_dec_DX(u8 X86EMU_UNUSED(op1))
-{
- START_OF_INSTR();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- DECODE_PRINTF("DEC\tEDX\n");
- } else {
- DECODE_PRINTF("DEC\tDX\n");
- }
- TRACE_AND_STEP();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- M.x86.R_EDX = dec_long(M.x86.R_EDX);
- } else {
- M.x86.R_DX = dec_word(M.x86.R_DX);
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
-}
-
-/****************************************************************************
-REMARKS:
-Handles opcode 0x4b
-****************************************************************************/
-void x86emuOp_dec_BX(u8 X86EMU_UNUSED(op1))
-{
- START_OF_INSTR();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- DECODE_PRINTF("DEC\tEBX\n");
- } else {
- DECODE_PRINTF("DEC\tBX\n");
- }
- TRACE_AND_STEP();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- M.x86.R_EBX = dec_long(M.x86.R_EBX);
- } else {
- M.x86.R_BX = dec_word(M.x86.R_BX);
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
-}
-
-/****************************************************************************
-REMARKS:
-Handles opcode 0x4c
-****************************************************************************/
-void x86emuOp_dec_SP(u8 X86EMU_UNUSED(op1))
-{
- START_OF_INSTR();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- DECODE_PRINTF("DEC\tESP\n");
- } else {
- DECODE_PRINTF("DEC\tSP\n");
- }
- TRACE_AND_STEP();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- M.x86.R_ESP = dec_long(M.x86.R_ESP);
- } else {
- M.x86.R_SP = dec_word(M.x86.R_SP);
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
-}
-
-/****************************************************************************
-REMARKS:
-Handles opcode 0x4d
-****************************************************************************/
-void x86emuOp_dec_BP(u8 X86EMU_UNUSED(op1))
-{
- START_OF_INSTR();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- DECODE_PRINTF("DEC\tEBP\n");
- } else {
- DECODE_PRINTF("DEC\tBP\n");
- }
- TRACE_AND_STEP();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- M.x86.R_EBP = dec_long(M.x86.R_EBP);
- } else {
- M.x86.R_BP = dec_word(M.x86.R_BP);
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
-}
-
-/****************************************************************************
-REMARKS:
-Handles opcode 0x4e
-****************************************************************************/
-void x86emuOp_dec_SI(u8 X86EMU_UNUSED(op1))
-{
- START_OF_INSTR();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- DECODE_PRINTF("DEC\tESI\n");
- } else {
- DECODE_PRINTF("DEC\tSI\n");
- }
- TRACE_AND_STEP();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- M.x86.R_ESI = dec_long(M.x86.R_ESI);
- } else {
- M.x86.R_SI = dec_word(M.x86.R_SI);
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
-}
-
-/****************************************************************************
-REMARKS:
-Handles opcode 0x4f
-****************************************************************************/
-void x86emuOp_dec_DI(u8 X86EMU_UNUSED(op1))
-{
- START_OF_INSTR();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- DECODE_PRINTF("DEC\tEDI\n");
- } else {
- DECODE_PRINTF("DEC\tDI\n");
- }
- TRACE_AND_STEP();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- M.x86.R_EDI = dec_long(M.x86.R_EDI);
- } else {
- M.x86.R_DI = dec_word(M.x86.R_DI);
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
-}
-
-/****************************************************************************
-REMARKS:
-Handles opcode 0x50
-****************************************************************************/
-void x86emuOp_push_AX(u8 X86EMU_UNUSED(op1))
-{
- START_OF_INSTR();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- DECODE_PRINTF("PUSH\tEAX\n");
- } else {
- DECODE_PRINTF("PUSH\tAX\n");
- }
- TRACE_AND_STEP();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- push_long(M.x86.R_EAX);
- } else {
- push_word(M.x86.R_AX);
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
-}
-
-/****************************************************************************
-REMARKS:
-Handles opcode 0x51
-****************************************************************************/
-void x86emuOp_push_CX(u8 X86EMU_UNUSED(op1))
-{
- START_OF_INSTR();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- DECODE_PRINTF("PUSH\tECX\n");
- } else {
- DECODE_PRINTF("PUSH\tCX\n");
- }
- TRACE_AND_STEP();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- push_long(M.x86.R_ECX);
- } else {
- push_word(M.x86.R_CX);
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
-}
-
-/****************************************************************************
-REMARKS:
-Handles opcode 0x52
-****************************************************************************/
-void x86emuOp_push_DX(u8 X86EMU_UNUSED(op1))
-{
- START_OF_INSTR();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- DECODE_PRINTF("PUSH\tEDX\n");
- } else {
- DECODE_PRINTF("PUSH\tDX\n");
- }
- TRACE_AND_STEP();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- push_long(M.x86.R_EDX);
- } else {
- push_word(M.x86.R_DX);
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
-}
-
-/****************************************************************************
-REMARKS:
-Handles opcode 0x53
-****************************************************************************/
-void x86emuOp_push_BX(u8 X86EMU_UNUSED(op1))
-{
- START_OF_INSTR();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- DECODE_PRINTF("PUSH\tEBX\n");
- } else {
- DECODE_PRINTF("PUSH\tBX\n");
- }
- TRACE_AND_STEP();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- push_long(M.x86.R_EBX);
- } else {
- push_word(M.x86.R_BX);
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
-}
-
-/****************************************************************************
-REMARKS:
-Handles opcode 0x54
-****************************************************************************/
-void x86emuOp_push_SP(u8 X86EMU_UNUSED(op1))
-{
- START_OF_INSTR();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- DECODE_PRINTF("PUSH\tESP\n");
- } else {
- DECODE_PRINTF("PUSH\tSP\n");
- }
- TRACE_AND_STEP();
- /* Always push (E)SP, since we are emulating an i386 and above
- * processor. This is necessary as some BIOS'es use this to check
- * what type of processor is in the system.
- */
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- push_long(M.x86.R_ESP);
- } else {
- push_word((u16) (M.x86.R_SP));
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
-}
-
-/****************************************************************************
-REMARKS:
-Handles opcode 0x55
-****************************************************************************/
-void x86emuOp_push_BP(u8 X86EMU_UNUSED(op1))
-{
- START_OF_INSTR();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- DECODE_PRINTF("PUSH\tEBP\n");
- } else {
- DECODE_PRINTF("PUSH\tBP\n");
- }
- TRACE_AND_STEP();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- push_long(M.x86.R_EBP);
- } else {
- push_word(M.x86.R_BP);
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
-}
-
-/****************************************************************************
-REMARKS:
-Handles opcode 0x56
-****************************************************************************/
-void x86emuOp_push_SI(u8 X86EMU_UNUSED(op1))
-{
- START_OF_INSTR();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- DECODE_PRINTF("PUSH\tESI\n");
- } else {
- DECODE_PRINTF("PUSH\tSI\n");
- }
- TRACE_AND_STEP();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- push_long(M.x86.R_ESI);
- } else {
- push_word(M.x86.R_SI);
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
-}
-
-/****************************************************************************
-REMARKS:
-Handles opcode 0x57
-****************************************************************************/
-void x86emuOp_push_DI(u8 X86EMU_UNUSED(op1))
-{
- START_OF_INSTR();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- DECODE_PRINTF("PUSH\tEDI\n");
- } else {
- DECODE_PRINTF("PUSH\tDI\n");
- }
- TRACE_AND_STEP();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- push_long(M.x86.R_EDI);
- } else {
- push_word(M.x86.R_DI);
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
-}
-
-/****************************************************************************
-REMARKS:
-Handles opcode 0x58
-****************************************************************************/
-void x86emuOp_pop_AX(u8 X86EMU_UNUSED(op1))
-{
- START_OF_INSTR();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- DECODE_PRINTF("POP\tEAX\n");
- } else {
- DECODE_PRINTF("POP\tAX\n");
- }
- TRACE_AND_STEP();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- M.x86.R_EAX = pop_long();
- } else {
- M.x86.R_AX = pop_word();
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
-}
-
-/****************************************************************************
-REMARKS:
-Handles opcode 0x59
-****************************************************************************/
-void x86emuOp_pop_CX(u8 X86EMU_UNUSED(op1))
-{
- START_OF_INSTR();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- DECODE_PRINTF("POP\tECX\n");
- } else {
- DECODE_PRINTF("POP\tCX\n");
- }
- TRACE_AND_STEP();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- M.x86.R_ECX = pop_long();
- } else {
- M.x86.R_CX = pop_word();
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
-}
-
-/****************************************************************************
-REMARKS:
-Handles opcode 0x5a
-****************************************************************************/
-void x86emuOp_pop_DX(u8 X86EMU_UNUSED(op1))
-{
- START_OF_INSTR();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- DECODE_PRINTF("POP\tEDX\n");
- } else {
- DECODE_PRINTF("POP\tDX\n");
- }
- TRACE_AND_STEP();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- M.x86.R_EDX = pop_long();
- } else {
- M.x86.R_DX = pop_word();
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
-}
-
-/****************************************************************************
-REMARKS:
-Handles opcode 0x5b
-****************************************************************************/
-void x86emuOp_pop_BX(u8 X86EMU_UNUSED(op1))
-{
- START_OF_INSTR();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- DECODE_PRINTF("POP\tEBX\n");
- } else {
- DECODE_PRINTF("POP\tBX\n");
- }
- TRACE_AND_STEP();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- M.x86.R_EBX = pop_long();
- } else {
- M.x86.R_BX = pop_word();
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
-}
-
-/****************************************************************************
-REMARKS:
-Handles opcode 0x5c
-****************************************************************************/
-void x86emuOp_pop_SP(u8 X86EMU_UNUSED(op1))
-{
- START_OF_INSTR();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- DECODE_PRINTF("POP\tESP\n");
- } else {
- DECODE_PRINTF("POP\tSP\n");
- }
- TRACE_AND_STEP();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- M.x86.R_ESP = pop_long();
- } else {
- M.x86.R_SP = pop_word();
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
-}
-
-/****************************************************************************
-REMARKS:
-Handles opcode 0x5d
-****************************************************************************/
-void x86emuOp_pop_BP(u8 X86EMU_UNUSED(op1))
-{
- START_OF_INSTR();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- DECODE_PRINTF("POP\tEBP\n");
- } else {
- DECODE_PRINTF("POP\tBP\n");
- }
- TRACE_AND_STEP();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- M.x86.R_EBP = pop_long();
- } else {
- M.x86.R_BP = pop_word();
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
-}
-
-/****************************************************************************
-REMARKS:
-Handles opcode 0x5e
-****************************************************************************/
-void x86emuOp_pop_SI(u8 X86EMU_UNUSED(op1))
-{
- START_OF_INSTR();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- DECODE_PRINTF("POP\tESI\n");
- } else {
- DECODE_PRINTF("POP\tSI\n");
- }
- TRACE_AND_STEP();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- M.x86.R_ESI = pop_long();
- } else {
- M.x86.R_SI = pop_word();
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
-}
-
-/****************************************************************************
-REMARKS:
-Handles opcode 0x5f
-****************************************************************************/
-void x86emuOp_pop_DI(u8 X86EMU_UNUSED(op1))
-{
- START_OF_INSTR();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- DECODE_PRINTF("POP\tEDI\n");
- } else {
- DECODE_PRINTF("POP\tDI\n");
- }
- TRACE_AND_STEP();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- M.x86.R_EDI = pop_long();
- } else {
- M.x86.R_DI = pop_word();
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ START_OF_INSTR();
+ op1 &= 0x7;
+ DECODE_PRINTF("POP\t");
+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+ u32 *reg;
+ reg = DECODE_RM_LONG_REGISTER(op1);
+ DECODE_PRINTF("\n");
+ TRACE_AND_STEP();
+ *reg = pop_long();
+ } else {
+ u16 *reg;
+ reg = DECODE_RM_WORD_REGISTER(op1);
+ DECODE_PRINTF("\n");
+ TRACE_AND_STEP();
+ *reg = pop_word();
+ }
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/****************************************************************************
@@ -4163,38 +779,38 @@ Handles opcode 0x60
****************************************************************************/
void x86emuOp_push_all(u8 X86EMU_UNUSED(op1))
{
- START_OF_INSTR();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- DECODE_PRINTF("PUSHAD\n");
- } else {
- DECODE_PRINTF("PUSHA\n");
- }
- TRACE_AND_STEP();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 old_sp = M.x86.R_ESP;
-
- push_long(M.x86.R_EAX);
- push_long(M.x86.R_ECX);
- push_long(M.x86.R_EDX);
- push_long(M.x86.R_EBX);
- push_long(old_sp);
- push_long(M.x86.R_EBP);
- push_long(M.x86.R_ESI);
- push_long(M.x86.R_EDI);
- } else {
- u16 old_sp = M.x86.R_SP;
-
- push_word(M.x86.R_AX);
- push_word(M.x86.R_CX);
- push_word(M.x86.R_DX);
- push_word(M.x86.R_BX);
- push_word(old_sp);
- push_word(M.x86.R_BP);
- push_word(M.x86.R_SI);
- push_word(M.x86.R_DI);
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ START_OF_INSTR();
+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+ DECODE_PRINTF("PUSHAD\n");
+ } else {
+ DECODE_PRINTF("PUSHA\n");
+ }
+ TRACE_AND_STEP();
+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+ u32 old_sp = M.x86.R_ESP;
+
+ push_long(M.x86.R_EAX);
+ push_long(M.x86.R_ECX);
+ push_long(M.x86.R_EDX);
+ push_long(M.x86.R_EBX);
+ push_long(old_sp);
+ push_long(M.x86.R_EBP);
+ push_long(M.x86.R_ESI);
+ push_long(M.x86.R_EDI);
+ } else {
+ u16 old_sp = M.x86.R_SP;
+
+ push_word(M.x86.R_AX);
+ push_word(M.x86.R_CX);
+ push_word(M.x86.R_DX);
+ push_word(M.x86.R_BX);
+ push_word(old_sp);
+ push_word(M.x86.R_BP);
+ push_word(M.x86.R_SI);
+ push_word(M.x86.R_DI);
+ }
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/****************************************************************************
@@ -4203,34 +819,34 @@ Handles opcode 0x61
****************************************************************************/
void x86emuOp_pop_all(u8 X86EMU_UNUSED(op1))
{
- START_OF_INSTR();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- DECODE_PRINTF("POPAD\n");
- } else {
- DECODE_PRINTF("POPA\n");
- }
- TRACE_AND_STEP();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- M.x86.R_EDI = pop_long();
- M.x86.R_ESI = pop_long();
- M.x86.R_EBP = pop_long();
- M.x86.R_ESP += 4; /* skip ESP */
- M.x86.R_EBX = pop_long();
- M.x86.R_EDX = pop_long();
- M.x86.R_ECX = pop_long();
- M.x86.R_EAX = pop_long();
- } else {
- M.x86.R_DI = pop_word();
- M.x86.R_SI = pop_word();
- M.x86.R_BP = pop_word();
- M.x86.R_SP += 2; /* skip SP */
- M.x86.R_BX = pop_word();
- M.x86.R_DX = pop_word();
- M.x86.R_CX = pop_word();
- M.x86.R_AX = pop_word();
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ START_OF_INSTR();
+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+ DECODE_PRINTF("POPAD\n");
+ } else {
+ DECODE_PRINTF("POPA\n");
+ }
+ TRACE_AND_STEP();
+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+ M.x86.R_EDI = pop_long();
+ M.x86.R_ESI = pop_long();
+ M.x86.R_EBP = pop_long();
+ M.x86.R_ESP += 4; /* skip ESP */
+ M.x86.R_EBX = pop_long();
+ M.x86.R_EDX = pop_long();
+ M.x86.R_ECX = pop_long();
+ M.x86.R_EAX = pop_long();
+ } else {
+ M.x86.R_DI = pop_word();
+ M.x86.R_SI = pop_word();
+ M.x86.R_BP = pop_word();
+ M.x86.R_SP += 2; /* skip SP */
+ M.x86.R_BX = pop_word();
+ M.x86.R_DX = pop_word();
+ M.x86.R_CX = pop_word();
+ M.x86.R_AX = pop_word();
+ }
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/*opcode 0x62 ILLEGAL OP, calls x86emuOp_illegal_op() */
@@ -4242,15 +858,15 @@ Handles opcode 0x64
****************************************************************************/
void x86emuOp_segovr_FS(u8 X86EMU_UNUSED(op1))
{
- START_OF_INSTR();
- DECODE_PRINTF("FS:\n");
- TRACE_AND_STEP();
- M.x86.mode |= SYSMODE_SEGOVR_FS;
- /*
- * note the lack of DECODE_CLEAR_SEGOVR(r) since, here is one of 4
- * opcode subroutines we do not want to do this.
- */
- END_OF_INSTR();
+ START_OF_INSTR();
+ DECODE_PRINTF("FS:\n");
+ TRACE_AND_STEP();
+ M.x86.mode |= SYSMODE_SEGOVR_FS;
+ /*
+ * note the lack of DECODE_CLEAR_SEGOVR(r) since, here is one of 4
+ * opcode subroutines we do not want to do this.
+ */
+ END_OF_INSTR();
}
/****************************************************************************
@@ -4259,15 +875,15 @@ Handles opcode 0x65
****************************************************************************/
void x86emuOp_segovr_GS(u8 X86EMU_UNUSED(op1))
{
- START_OF_INSTR();
- DECODE_PRINTF("GS:\n");
- TRACE_AND_STEP();
- M.x86.mode |= SYSMODE_SEGOVR_GS;
- /*
- * note the lack of DECODE_CLEAR_SEGOVR(r) since, here is one of 4
- * opcode subroutines we do not want to do this.
- */
- END_OF_INSTR();
+ START_OF_INSTR();
+ DECODE_PRINTF("GS:\n");
+ TRACE_AND_STEP();
+ M.x86.mode |= SYSMODE_SEGOVR_GS;
+ /*
+ * note the lack of DECODE_CLEAR_SEGOVR(r) since, here is one of 4
+ * opcode subroutines we do not want to do this.
+ */
+ END_OF_INSTR();
}
/****************************************************************************
@@ -4276,12 +892,12 @@ Handles opcode 0x66 - prefix for 32-bit register
****************************************************************************/
void x86emuOp_prefix_data(u8 X86EMU_UNUSED(op1))
{
- START_OF_INSTR();
- DECODE_PRINTF("DATA:\n");
- TRACE_AND_STEP();
- M.x86.mode |= SYSMODE_PREFIX_DATA;
- /* note no DECODE_CLEAR_SEGOVR here. */
- END_OF_INSTR();
+ START_OF_INSTR();
+ DECODE_PRINTF("DATA:\n");
+ TRACE_AND_STEP();
+ M.x86.mode |= SYSMODE_PREFIX_DATA;
+ /* note no DECODE_CLEAR_SEGOVR here. */
+ END_OF_INSTR();
}
/****************************************************************************
@@ -4290,12 +906,12 @@ Handles opcode 0x67 - prefix for 32-bit address
****************************************************************************/
void x86emuOp_prefix_addr(u8 X86EMU_UNUSED(op1))
{
- START_OF_INSTR();
- DECODE_PRINTF("ADDR:\n");
- TRACE_AND_STEP();
- M.x86.mode |= SYSMODE_PREFIX_ADDR;
- /* note no DECODE_CLEAR_SEGOVR here. */
- END_OF_INSTR();
+ START_OF_INSTR();
+ DECODE_PRINTF("ADDR:\n");
+ TRACE_AND_STEP();
+ M.x86.mode |= SYSMODE_PREFIX_ADDR;
+ /* note no DECODE_CLEAR_SEGOVR here. */
+ END_OF_INSTR();
}
/****************************************************************************
@@ -4304,23 +920,23 @@ Handles opcode 0x68
****************************************************************************/
void x86emuOp_push_word_IMM(u8 X86EMU_UNUSED(op1))
{
- u32 imm;
+ u32 imm;
- START_OF_INSTR();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- imm = fetch_long_imm();
- } else {
- imm = fetch_word_imm();
- }
- DECODE_PRINTF2("PUSH\t%x\n", imm);
- TRACE_AND_STEP();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- push_long(imm);
- } else {
- push_word((u16) imm);
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ START_OF_INSTR();
+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+ imm = fetch_long_imm();
+ } else {
+ imm = fetch_word_imm();
+ }
+ DECODE_PRINTF2("PUSH\t%x\n", imm);
+ TRACE_AND_STEP();
+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+ push_long(imm);
+ } else {
+ push_word((u16)imm);
+ }
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/****************************************************************************
@@ -4329,199 +945,105 @@ Handles opcode 0x69
****************************************************************************/
void x86emuOp_imul_word_IMM(u8 X86EMU_UNUSED(op1))
{
- int mod, rl, rh;
- uint srcoffset;
-
- START_OF_INSTR();
- DECODE_PRINTF("IMUL\t");
- FETCH_DECODE_MODRM(mod, rh, rl);
- switch (mod) {
- case 0:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 *destreg;
- u32 srcval;
- u32 res_lo, res_hi;
- s32 imm;
-
- destreg = DECODE_RM_LONG_REGISTER(rh);
- DECODE_PRINTF(",");
- srcoffset = decode_rm00_address(rl);
- srcval = fetch_data_long(srcoffset);
- imm = fetch_long_imm();
- DECODE_PRINTF2(",%d\n", (s32) imm);
- TRACE_AND_STEP();
- imul_long_direct(&res_lo, &res_hi, (s32) srcval, (s32) imm);
- if (res_hi != 0) {
- SET_FLAG(F_CF);
- SET_FLAG(F_OF);
- } else {
- CLEAR_FLAG(F_CF);
- CLEAR_FLAG(F_OF);
- }
- *destreg = (u32) res_lo;
- } else {
- u16 *destreg;
- u16 srcval;
- u32 res;
- s16 imm;
-
- destreg = DECODE_RM_WORD_REGISTER(rh);
- DECODE_PRINTF(",");
- srcoffset = decode_rm00_address(rl);
- srcval = fetch_data_word(srcoffset);
- imm = fetch_word_imm();
- DECODE_PRINTF2(",%d\n", (s32) imm);
- TRACE_AND_STEP();
- res = (s16) srcval *(s16) imm;
- if (res > 0xFFFF) {
- SET_FLAG(F_CF);
- SET_FLAG(F_OF);
- } else {
- CLEAR_FLAG(F_CF);
- CLEAR_FLAG(F_OF);
- }
- *destreg = (u16) res;
- }
- break;
- case 1:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 *destreg;
- u32 srcval;
- u32 res_lo, res_hi;
- s32 imm;
-
- destreg = DECODE_RM_LONG_REGISTER(rh);
- DECODE_PRINTF(",");
- srcoffset = decode_rm01_address(rl);
- srcval = fetch_data_long(srcoffset);
- imm = fetch_long_imm();
- DECODE_PRINTF2(",%d\n", (s32) imm);
- TRACE_AND_STEP();
- imul_long_direct(&res_lo, &res_hi, (s32) srcval, (s32) imm);
- if (res_hi != 0) {
- SET_FLAG(F_CF);
- SET_FLAG(F_OF);
- } else {
- CLEAR_FLAG(F_CF);
- CLEAR_FLAG(F_OF);
- }
- *destreg = (u32) res_lo;
- } else {
- u16 *destreg;
- u16 srcval;
- u32 res;
- s16 imm;
-
- destreg = DECODE_RM_WORD_REGISTER(rh);
- DECODE_PRINTF(",");
- srcoffset = decode_rm01_address(rl);
- srcval = fetch_data_word(srcoffset);
- imm = fetch_word_imm();
- DECODE_PRINTF2(",%d\n", (s32) imm);
- TRACE_AND_STEP();
- res = (s16) srcval *(s16) imm;
- if (res > 0xFFFF) {
- SET_FLAG(F_CF);
- SET_FLAG(F_OF);
- } else {
- CLEAR_FLAG(F_CF);
- CLEAR_FLAG(F_OF);
- }
- *destreg = (u16) res;
- }
- break;
- case 2:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 *destreg;
- u32 srcval;
- u32 res_lo, res_hi;
- s32 imm;
-
- destreg = DECODE_RM_LONG_REGISTER(rh);
- DECODE_PRINTF(",");
- srcoffset = decode_rm10_address(rl);
- srcval = fetch_data_long(srcoffset);
- imm = fetch_long_imm();
- DECODE_PRINTF2(",%d\n", (s32) imm);
- TRACE_AND_STEP();
- imul_long_direct(&res_lo, &res_hi, (s32) srcval, (s32) imm);
- if (res_hi != 0) {
- SET_FLAG(F_CF);
- SET_FLAG(F_OF);
- } else {
- CLEAR_FLAG(F_CF);
- CLEAR_FLAG(F_OF);
- }
- *destreg = (u32) res_lo;
- } else {
- u16 *destreg;
- u16 srcval;
- u32 res;
- s16 imm;
-
- destreg = DECODE_RM_WORD_REGISTER(rh);
- DECODE_PRINTF(",");
- srcoffset = decode_rm10_address(rl);
- srcval = fetch_data_word(srcoffset);
- imm = fetch_word_imm();
- DECODE_PRINTF2(",%d\n", (s32) imm);
- TRACE_AND_STEP();
- res = (s16) srcval *(s16) imm;
- if (res > 0xFFFF) {
- SET_FLAG(F_CF);
- SET_FLAG(F_OF);
- } else {
- CLEAR_FLAG(F_CF);
- CLEAR_FLAG(F_OF);
- }
- *destreg = (u16) res;
- }
- break;
- case 3: /* register to register */
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 *destreg, *srcreg;
- u32 res_lo, res_hi;
- s32 imm;
-
- destreg = DECODE_RM_LONG_REGISTER(rh);
- DECODE_PRINTF(",");
- srcreg = DECODE_RM_LONG_REGISTER(rl);
- imm = fetch_long_imm();
- DECODE_PRINTF2(",%d\n", (s32) imm);
- TRACE_AND_STEP();
- imul_long_direct(&res_lo, &res_hi, (s32) * srcreg, (s32) imm);
- if (res_hi != 0) {
- SET_FLAG(F_CF);
- SET_FLAG(F_OF);
- } else {
- CLEAR_FLAG(F_CF);
- CLEAR_FLAG(F_OF);
- }
- *destreg = (u32) res_lo;
- } else {
- u16 *destreg, *srcreg;
- u32 res;
- s16 imm;
-
- destreg = DECODE_RM_WORD_REGISTER(rh);
- DECODE_PRINTF(",");
- srcreg = DECODE_RM_WORD_REGISTER(rl);
- imm = fetch_word_imm();
- DECODE_PRINTF2(",%d\n", (s32) imm);
- res = (s16) * srcreg * (s16) imm;
- if (res > 0xFFFF) {
- SET_FLAG(F_CF);
- SET_FLAG(F_OF);
- } else {
- CLEAR_FLAG(F_CF);
- CLEAR_FLAG(F_OF);
- }
- *destreg = (u16) res;
- }
- break;
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ int mod, rl, rh;
+ uint srcoffset;
+
+ START_OF_INSTR();
+ DECODE_PRINTF("IMUL\t");
+ FETCH_DECODE_MODRM(mod, rh, rl);
+ if (mod < 3) {
+ srcoffset = decode_rmXX_address(mod, rl);
+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+ u32 *destreg;
+ u32 srcval;
+ u32 res_lo,res_hi;
+ s32 imm;
+
+ destreg = DECODE_RM_LONG_REGISTER(rh);
+ DECODE_PRINTF(",");
+ srcval = fetch_data_long(srcoffset);
+ imm = fetch_long_imm();
+ DECODE_PRINTF2(",%d\n", (s32)imm);
+ TRACE_AND_STEP();
+ imul_long_direct(&res_lo,&res_hi,(s32)srcval,(s32)imm);
+ if ((((res_lo & 0x80000000) == 0) && (res_hi == 0x00000000)) ||
+ (((res_lo & 0x80000000) != 0) && (res_hi == 0xFFFFFFFF))) {
+ CLEAR_FLAG(F_CF);
+ CLEAR_FLAG(F_OF);
+ } else {
+ SET_FLAG(F_CF);
+ SET_FLAG(F_OF);
+ }
+ *destreg = (u32)res_lo;
+ } else {
+ u16 *destreg;
+ u16 srcval;
+ u32 res;
+ s16 imm;
+
+ destreg = DECODE_RM_WORD_REGISTER(rh);
+ DECODE_PRINTF(",");
+ srcval = fetch_data_word(srcoffset);
+ imm = fetch_word_imm();
+ DECODE_PRINTF2(",%d\n", (s32)imm);
+ TRACE_AND_STEP();
+ res = (s16)srcval * (s16)imm;
+ if ((((res & 0x8000) == 0) && ((res >> 16) == 0x0000)) ||
+ (((res & 0x8000) != 0) && ((res >> 16) == 0xFFFF))) {
+ CLEAR_FLAG(F_CF);
+ CLEAR_FLAG(F_OF);
+ } else {
+ SET_FLAG(F_CF);
+ SET_FLAG(F_OF);
+ }
+ *destreg = (u16)res;
+ }
+ } else { /* register to register */
+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+ u32 *destreg,*srcreg;
+ u32 res_lo,res_hi;
+ s32 imm;
+
+ destreg = DECODE_RM_LONG_REGISTER(rh);
+ DECODE_PRINTF(",");
+ srcreg = DECODE_RM_LONG_REGISTER(rl);
+ imm = fetch_long_imm();
+ DECODE_PRINTF2(",%d\n", (s32)imm);
+ TRACE_AND_STEP();
+ imul_long_direct(&res_lo,&res_hi,(s32)*srcreg,(s32)imm);
+ if ((((res_lo & 0x80000000) == 0) && (res_hi == 0x00000000)) ||
+ (((res_lo & 0x80000000) != 0) && (res_hi == 0xFFFFFFFF))) {
+ CLEAR_FLAG(F_CF);
+ CLEAR_FLAG(F_OF);
+ } else {
+ SET_FLAG(F_CF);
+ SET_FLAG(F_OF);
+ }
+ *destreg = (u32)res_lo;
+ } else {
+ u16 *destreg,*srcreg;
+ u32 res;
+ s16 imm;
+
+ destreg = DECODE_RM_WORD_REGISTER(rh);
+ DECODE_PRINTF(",");
+ srcreg = DECODE_RM_WORD_REGISTER(rl);
+ imm = fetch_word_imm();
+ DECODE_PRINTF2(",%d\n", (s32)imm);
+ res = (s16)*srcreg * (s16)imm;
+ if ((((res & 0x8000) == 0) && ((res >> 16) == 0x0000)) ||
+ (((res & 0x8000) != 0) && ((res >> 16) == 0xFFFF))) {
+ CLEAR_FLAG(F_CF);
+ CLEAR_FLAG(F_OF);
+ } else {
+ SET_FLAG(F_CF);
+ SET_FLAG(F_OF);
+ }
+ *destreg = (u16)res;
+ }
+ }
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/****************************************************************************
@@ -4530,15 +1052,15 @@ Handles opcode 0x6a
****************************************************************************/
void x86emuOp_push_byte_IMM(u8 X86EMU_UNUSED(op1))
{
- s16 imm;
+ s16 imm;
- START_OF_INSTR();
- imm = (s8) fetch_byte_imm();
- DECODE_PRINTF2("PUSH\t%d\n", imm);
- TRACE_AND_STEP();
- push_word(imm);
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ START_OF_INSTR();
+ imm = (s8)fetch_byte_imm();
+ DECODE_PRINTF2("PUSH\t%d\n", imm);
+ TRACE_AND_STEP();
+ push_word(imm);
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/****************************************************************************
@@ -4547,192 +1069,103 @@ Handles opcode 0x6b
****************************************************************************/
void x86emuOp_imul_byte_IMM(u8 X86EMU_UNUSED(op1))
{
- int mod, rl, rh;
- uint srcoffset;
- s8 imm;
-
- START_OF_INSTR();
- DECODE_PRINTF("IMUL\t");
- FETCH_DECODE_MODRM(mod, rh, rl);
- switch (mod) {
- case 0:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 *destreg;
- u32 srcval;
- u32 res_lo, res_hi;
-
- destreg = DECODE_RM_LONG_REGISTER(rh);
- DECODE_PRINTF(",");
- srcoffset = decode_rm00_address(rl);
- srcval = fetch_data_long(srcoffset);
- imm = fetch_byte_imm();
- DECODE_PRINTF2(",%d\n", (s32) imm);
- TRACE_AND_STEP();
- imul_long_direct(&res_lo, &res_hi, (s32) srcval, (s32) imm);
- if (res_hi != 0) {
- SET_FLAG(F_CF);
- SET_FLAG(F_OF);
- } else {
- CLEAR_FLAG(F_CF);
- CLEAR_FLAG(F_OF);
- }
- *destreg = (u32) res_lo;
- } else {
- u16 *destreg;
- u16 srcval;
- u32 res;
-
- destreg = DECODE_RM_WORD_REGISTER(rh);
- DECODE_PRINTF(",");
- srcoffset = decode_rm00_address(rl);
- srcval = fetch_data_word(srcoffset);
- imm = fetch_byte_imm();
- DECODE_PRINTF2(",%d\n", (s32) imm);
- TRACE_AND_STEP();
- res = (s16) srcval *(s16) imm;
- if (res > 0xFFFF) {
- SET_FLAG(F_CF);
- SET_FLAG(F_OF);
- } else {
- CLEAR_FLAG(F_CF);
- CLEAR_FLAG(F_OF);
- }
- *destreg = (u16) res;
- }
- break;
- case 1:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 *destreg;
- u32 srcval;
- u32 res_lo, res_hi;
-
- destreg = DECODE_RM_LONG_REGISTER(rh);
- DECODE_PRINTF(",");
- srcoffset = decode_rm01_address(rl);
- srcval = fetch_data_long(srcoffset);
- imm = fetch_byte_imm();
- DECODE_PRINTF2(",%d\n", (s32) imm);
- TRACE_AND_STEP();
- imul_long_direct(&res_lo, &res_hi, (s32) srcval, (s32) imm);
- if (res_hi != 0) {
- SET_FLAG(F_CF);
- SET_FLAG(F_OF);
- } else {
- CLEAR_FLAG(F_CF);
- CLEAR_FLAG(F_OF);
- }
- *destreg = (u32) res_lo;
- } else {
- u16 *destreg;
- u16 srcval;
- u32 res;
-
- destreg = DECODE_RM_WORD_REGISTER(rh);
- DECODE_PRINTF(",");
- srcoffset = decode_rm01_address(rl);
- srcval = fetch_data_word(srcoffset);
- imm = fetch_byte_imm();
- DECODE_PRINTF2(",%d\n", (s32) imm);
- TRACE_AND_STEP();
- res = (s16) srcval *(s16) imm;
- if (res > 0xFFFF) {
- SET_FLAG(F_CF);
- SET_FLAG(F_OF);
- } else {
- CLEAR_FLAG(F_CF);
- CLEAR_FLAG(F_OF);
- }
- *destreg = (u16) res;
- }
- break;
- case 2:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 *destreg;
- u32 srcval;
- u32 res_lo, res_hi;
-
- destreg = DECODE_RM_LONG_REGISTER(rh);
- DECODE_PRINTF(",");
- srcoffset = decode_rm10_address(rl);
- srcval = fetch_data_long(srcoffset);
- imm = fetch_byte_imm();
- DECODE_PRINTF2(",%d\n", (s32) imm);
- TRACE_AND_STEP();
- imul_long_direct(&res_lo, &res_hi, (s32) srcval, (s32) imm);
- if (res_hi != 0) {
- SET_FLAG(F_CF);
- SET_FLAG(F_OF);
- } else {
- CLEAR_FLAG(F_CF);
- CLEAR_FLAG(F_OF);
- }
- *destreg = (u32) res_lo;
- } else {
- u16 *destreg;
- u16 srcval;
- u32 res;
-
- destreg = DECODE_RM_WORD_REGISTER(rh);
- DECODE_PRINTF(",");
- srcoffset = decode_rm10_address(rl);
- srcval = fetch_data_word(srcoffset);
- imm = fetch_byte_imm();
- DECODE_PRINTF2(",%d\n", (s32) imm);
- TRACE_AND_STEP();
- res = (s16) srcval *(s16) imm;
- if (res > 0xFFFF) {
- SET_FLAG(F_CF);
- SET_FLAG(F_OF);
- } else {
- CLEAR_FLAG(F_CF);
- CLEAR_FLAG(F_OF);
- }
- *destreg = (u16) res;
- }
- break;
- case 3: /* register to register */
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 *destreg, *srcreg;
- u32 res_lo, res_hi;
-
- destreg = DECODE_RM_LONG_REGISTER(rh);
- DECODE_PRINTF(",");
- srcreg = DECODE_RM_LONG_REGISTER(rl);
- imm = fetch_byte_imm();
- DECODE_PRINTF2(",%d\n", (s32) imm);
- TRACE_AND_STEP();
- imul_long_direct(&res_lo, &res_hi, (s32) * srcreg, (s32) imm);
- if (res_hi != 0) {
- SET_FLAG(F_CF);
- SET_FLAG(F_OF);
- } else {
- CLEAR_FLAG(F_CF);
- CLEAR_FLAG(F_OF);
- }
- *destreg = (u32) res_lo;
- } else {
- u16 *destreg, *srcreg;
- u32 res;
-
- destreg = DECODE_RM_WORD_REGISTER(rh);
- DECODE_PRINTF(",");
- srcreg = DECODE_RM_WORD_REGISTER(rl);
- imm = fetch_byte_imm();
- DECODE_PRINTF2(",%d\n", (s32) imm);
- res = (s16) * srcreg * (s16) imm;
- if (res > 0xFFFF) {
- SET_FLAG(F_CF);
- SET_FLAG(F_OF);
- } else {
- CLEAR_FLAG(F_CF);
- CLEAR_FLAG(F_OF);
- }
- *destreg = (u16) res;
- }
- break;
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ int mod, rl, rh;
+ uint srcoffset;
+ s8 imm;
+
+ START_OF_INSTR();
+ DECODE_PRINTF("IMUL\t");
+ FETCH_DECODE_MODRM(mod, rh, rl);
+ if (mod < 3) {
+ srcoffset = decode_rmXX_address(mod, rl);
+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+ u32 *destreg;
+ u32 srcval;
+ u32 res_lo,res_hi;
+
+ destreg = DECODE_RM_LONG_REGISTER(rh);
+ DECODE_PRINTF(",");
+ srcval = fetch_data_long(srcoffset);
+ imm = fetch_byte_imm();
+ DECODE_PRINTF2(",%d\n", (s32)imm);
+ TRACE_AND_STEP();
+ imul_long_direct(&res_lo,&res_hi,(s32)srcval,(s32)imm);
+ if ((((res_lo & 0x80000000) == 0) && (res_hi == 0x00000000)) ||
+ (((res_lo & 0x80000000) != 0) && (res_hi == 0xFFFFFFFF))) {
+ CLEAR_FLAG(F_CF);
+ CLEAR_FLAG(F_OF);
+ } else {
+ SET_FLAG(F_CF);
+ SET_FLAG(F_OF);
+ }
+ *destreg = (u32)res_lo;
+ } else {
+ u16 *destreg;
+ u16 srcval;
+ u32 res;
+
+ destreg = DECODE_RM_WORD_REGISTER(rh);
+ DECODE_PRINTF(",");
+ srcval = fetch_data_word(srcoffset);
+ imm = fetch_byte_imm();
+ DECODE_PRINTF2(",%d\n", (s32)imm);
+ TRACE_AND_STEP();
+ res = (s16)srcval * (s16)imm;
+ if ((((res & 0x8000) == 0) && ((res >> 16) == 0x0000)) ||
+ (((res & 0x8000) != 0) && ((res >> 16) == 0xFFFF))) {
+ CLEAR_FLAG(F_CF);
+ CLEAR_FLAG(F_OF);
+ } else {
+ SET_FLAG(F_CF);
+ SET_FLAG(F_OF);
+ }
+ *destreg = (u16)res;
+ }
+ } else { /* register to register */
+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+ u32 *destreg,*srcreg;
+ u32 res_lo,res_hi;
+
+ destreg = DECODE_RM_LONG_REGISTER(rh);
+ DECODE_PRINTF(",");
+ srcreg = DECODE_RM_LONG_REGISTER(rl);
+ imm = fetch_byte_imm();
+ DECODE_PRINTF2(",%d\n", (s32)imm);
+ TRACE_AND_STEP();
+ imul_long_direct(&res_lo,&res_hi,(s32)*srcreg,(s32)imm);
+ if ((((res_lo & 0x80000000) == 0) && (res_hi == 0x00000000)) ||
+ (((res_lo & 0x80000000) != 0) && (res_hi == 0xFFFFFFFF))) {
+ CLEAR_FLAG(F_CF);
+ CLEAR_FLAG(F_OF);
+ } else {
+ SET_FLAG(F_CF);
+ SET_FLAG(F_OF);
+ }
+ *destreg = (u32)res_lo;
+ } else {
+ u16 *destreg,*srcreg;
+ u32 res;
+
+ destreg = DECODE_RM_WORD_REGISTER(rh);
+ DECODE_PRINTF(",");
+ srcreg = DECODE_RM_WORD_REGISTER(rl);
+ imm = fetch_byte_imm();
+ DECODE_PRINTF2(",%d\n", (s32)imm);
+ TRACE_AND_STEP();
+ res = (s16)*srcreg * (s16)imm;
+ if ((((res & 0x8000) == 0) && ((res >> 16) == 0x0000)) ||
+ (((res & 0x8000) != 0) && ((res >> 16) == 0xFFFF))) {
+ CLEAR_FLAG(F_CF);
+ CLEAR_FLAG(F_OF);
+ } else {
+ SET_FLAG(F_CF);
+ SET_FLAG(F_OF);
+ }
+ *destreg = (u16)res;
+ }
+ }
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/****************************************************************************
@@ -4741,12 +1174,12 @@ Handles opcode 0x6c
****************************************************************************/
void x86emuOp_ins_byte(u8 X86EMU_UNUSED(op1))
{
- START_OF_INSTR();
- DECODE_PRINTF("INSB\n");
- ins(1);
- TRACE_AND_STEP();
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ START_OF_INSTR();
+ DECODE_PRINTF("INSB\n");
+ ins(1);
+ TRACE_AND_STEP();
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/****************************************************************************
@@ -4755,17 +1188,17 @@ Handles opcode 0x6d
****************************************************************************/
void x86emuOp_ins_word(u8 X86EMU_UNUSED(op1))
{
- START_OF_INSTR();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- DECODE_PRINTF("INSD\n");
- ins(4);
- } else {
- DECODE_PRINTF("INSW\n");
- ins(2);
- }
- TRACE_AND_STEP();
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ START_OF_INSTR();
+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+ DECODE_PRINTF("INSD\n");
+ ins(4);
+ } else {
+ DECODE_PRINTF("INSW\n");
+ ins(2);
+ }
+ TRACE_AND_STEP();
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/****************************************************************************
@@ -4774,12 +1207,12 @@ Handles opcode 0x6e
****************************************************************************/
void x86emuOp_outs_byte(u8 X86EMU_UNUSED(op1))
{
- START_OF_INSTR();
- DECODE_PRINTF("OUTSB\n");
- outs(1);
- TRACE_AND_STEP();
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ START_OF_INSTR();
+ DECODE_PRINTF("OUTSB\n");
+ outs(1);
+ TRACE_AND_STEP();
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/****************************************************************************
@@ -4788,528 +1221,124 @@ Handles opcode 0x6f
****************************************************************************/
void x86emuOp_outs_word(u8 X86EMU_UNUSED(op1))
{
- START_OF_INSTR();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- DECODE_PRINTF("OUTSD\n");
- outs(4);
- } else {
- DECODE_PRINTF("OUTSW\n");
- outs(2);
- }
- TRACE_AND_STEP();
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
-}
-
-/****************************************************************************
-REMARKS:
-Handles opcode 0x70
-****************************************************************************/
-void x86emuOp_jump_near_O(u8 X86EMU_UNUSED(op1))
-{
- s8 offset;
- u16 target;
-
- /* jump to byte offset if overflow flag is set */
- START_OF_INSTR();
- DECODE_PRINTF("JO\t");
- offset = (s8) fetch_byte_imm();
- target = (u16) (M.x86.R_IP + (s16) offset);
- DECODE_PRINTF2("%x\n", target);
- TRACE_AND_STEP();
- if (ACCESS_FLAG(F_OF))
- M.x86.R_IP = target;
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
-}
-
-/****************************************************************************
-REMARKS:
-Handles opcode 0x71
-****************************************************************************/
-void x86emuOp_jump_near_NO(u8 X86EMU_UNUSED(op1))
-{
- s8 offset;
- u16 target;
-
- /* jump to byte offset if overflow is not set */
- START_OF_INSTR();
- DECODE_PRINTF("JNO\t");
- offset = (s8) fetch_byte_imm();
- target = (u16) (M.x86.R_IP + (s16) offset);
- DECODE_PRINTF2("%x\n", target);
- TRACE_AND_STEP();
- if (!ACCESS_FLAG(F_OF))
- M.x86.R_IP = target;
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
-}
-
-/****************************************************************************
-REMARKS:
-Handles opcode 0x72
-****************************************************************************/
-void x86emuOp_jump_near_B(u8 X86EMU_UNUSED(op1))
-{
- s8 offset;
- u16 target;
-
- /* jump to byte offset if carry flag is set. */
- START_OF_INSTR();
- DECODE_PRINTF("JB\t");
- offset = (s8) fetch_byte_imm();
- target = (u16) (M.x86.R_IP + (s16) offset);
- DECODE_PRINTF2("%x\n", target);
- TRACE_AND_STEP();
- if (ACCESS_FLAG(F_CF))
- M.x86.R_IP = target;
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
-}
-
-/****************************************************************************
-REMARKS:
-Handles opcode 0x73
-****************************************************************************/
-void x86emuOp_jump_near_NB(u8 X86EMU_UNUSED(op1))
-{
- s8 offset;
- u16 target;
-
- /* jump to byte offset if carry flag is clear. */
- START_OF_INSTR();
- DECODE_PRINTF("JNB\t");
- offset = (s8) fetch_byte_imm();
- target = (u16) (M.x86.R_IP + (s16) offset);
- DECODE_PRINTF2("%x\n", target);
- TRACE_AND_STEP();
- if (!ACCESS_FLAG(F_CF))
- M.x86.R_IP = target;
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
-}
-
-/****************************************************************************
-REMARKS:
-Handles opcode 0x74
-****************************************************************************/
-void x86emuOp_jump_near_Z(u8 X86EMU_UNUSED(op1))
-{
- s8 offset;
- u16 target;
-
- /* jump to byte offset if zero flag is set. */
- START_OF_INSTR();
- DECODE_PRINTF("JZ\t");
- offset = (s8) fetch_byte_imm();
- target = (u16) (M.x86.R_IP + (s16) offset);
- DECODE_PRINTF2("%x\n", target);
- TRACE_AND_STEP();
- if (ACCESS_FLAG(F_ZF))
- M.x86.R_IP = target;
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
-}
-
-/****************************************************************************
-REMARKS:
-Handles opcode 0x75
-****************************************************************************/
-void x86emuOp_jump_near_NZ(u8 X86EMU_UNUSED(op1))
-{
- s8 offset;
- u16 target;
-
- /* jump to byte offset if zero flag is clear. */
- START_OF_INSTR();
- DECODE_PRINTF("JNZ\t");
- offset = (s8) fetch_byte_imm();
- target = (u16) (M.x86.R_IP + (s16) offset);
- DECODE_PRINTF2("%x\n", target);
- TRACE_AND_STEP();
- if (!ACCESS_FLAG(F_ZF))
- M.x86.R_IP = target;
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ START_OF_INSTR();
+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+ DECODE_PRINTF("OUTSD\n");
+ outs(4);
+ } else {
+ DECODE_PRINTF("OUTSW\n");
+ outs(2);
+ }
+ TRACE_AND_STEP();
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/****************************************************************************
REMARKS:
-Handles opcode 0x76
+Handles opcode 0x70 - 0x7F
****************************************************************************/
-void x86emuOp_jump_near_BE(u8 X86EMU_UNUSED(op1))
-{
- s8 offset;
- u16 target;
-
- /* jump to byte offset if carry flag is set or if the zero
- flag is set. */
- START_OF_INSTR();
- DECODE_PRINTF("JBE\t");
- offset = (s8) fetch_byte_imm();
- target = (u16) (M.x86.R_IP + (s16) offset);
- DECODE_PRINTF2("%x\n", target);
- TRACE_AND_STEP();
- if (ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF))
- M.x86.R_IP = target;
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
-}
+int x86emu_check_jump_condition(u8 op);
-/****************************************************************************
-REMARKS:
-Handles opcode 0x77
-****************************************************************************/
-void x86emuOp_jump_near_NBE(u8 X86EMU_UNUSED(op1))
+void x86emuOp_jump_near_cond(u8 op1)
{
- s8 offset;
- u16 target;
+ s8 offset;
+ u16 target;
+ int cond;
- /* jump to byte offset if carry flag is clear and if the zero
- flag is clear */
- START_OF_INSTR();
- DECODE_PRINTF("JNBE\t");
- offset = (s8) fetch_byte_imm();
- target = (u16) (M.x86.R_IP + (s16) offset);
- DECODE_PRINTF2("%x\n", target);
- TRACE_AND_STEP();
- if (!(ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF)))
- M.x86.R_IP = target;
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
-}
-
-/****************************************************************************
-REMARKS:
-Handles opcode 0x78
-****************************************************************************/
-void x86emuOp_jump_near_S(u8 X86EMU_UNUSED(op1))
-{
- s8 offset;
- u16 target;
-
- /* jump to byte offset if sign flag is set */
- START_OF_INSTR();
- DECODE_PRINTF("JS\t");
- offset = (s8) fetch_byte_imm();
- target = (u16) (M.x86.R_IP + (s16) offset);
- DECODE_PRINTF2("%x\n", target);
- TRACE_AND_STEP();
- if (ACCESS_FLAG(F_SF))
- M.x86.R_IP = target;
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
-}
-
-/****************************************************************************
-REMARKS:
-Handles opcode 0x79
-****************************************************************************/
-void x86emuOp_jump_near_NS(u8 X86EMU_UNUSED(op1))
-{
- s8 offset;
- u16 target;
-
- /* jump to byte offset if sign flag is clear */
- START_OF_INSTR();
- DECODE_PRINTF("JNS\t");
- offset = (s8) fetch_byte_imm();
- target = (u16) (M.x86.R_IP + (s16) offset);
- DECODE_PRINTF2("%x\n", target);
- TRACE_AND_STEP();
- if (!ACCESS_FLAG(F_SF))
- M.x86.R_IP = target;
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
-}
-
-/****************************************************************************
-REMARKS:
-Handles opcode 0x7a
-****************************************************************************/
-void x86emuOp_jump_near_P(u8 X86EMU_UNUSED(op1))
-{
- s8 offset;
- u16 target;
-
- /* jump to byte offset if parity flag is set (even parity) */
- START_OF_INSTR();
- DECODE_PRINTF("JP\t");
- offset = (s8) fetch_byte_imm();
- target = (u16) (M.x86.R_IP + (s16) offset);
- DECODE_PRINTF2("%x\n", target);
- TRACE_AND_STEP();
- if (ACCESS_FLAG(F_PF))
- M.x86.R_IP = target;
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
-}
-
-/****************************************************************************
-REMARKS:
-Handles opcode 0x7b
-****************************************************************************/
-void x86emuOp_jump_near_NP(u8 X86EMU_UNUSED(op1))
-{
- s8 offset;
- u16 target;
-
- /* jump to byte offset if parity flag is clear (odd parity) */
- START_OF_INSTR();
- DECODE_PRINTF("JNP\t");
- offset = (s8) fetch_byte_imm();
- target = (u16) (M.x86.R_IP + (s16) offset);
- DECODE_PRINTF2("%x\n", target);
- TRACE_AND_STEP();
- if (!ACCESS_FLAG(F_PF))
- M.x86.R_IP = target;
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ /* jump to byte offset if overflow flag is set */
+ START_OF_INSTR();
+ cond = x86emu_check_jump_condition(op1 & 0xF);
+ offset = (s8)fetch_byte_imm();
+ target = (u16)(M.x86.R_IP + (s16)offset);
+ DECODE_PRINTF2("%x\n", target);
+ TRACE_AND_STEP();
+ if (cond)
+ M.x86.R_IP = target;
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/****************************************************************************
REMARKS:
-Handles opcode 0x7c
-****************************************************************************/
-void x86emuOp_jump_near_L(u8 X86EMU_UNUSED(op1))
-{
- s8 offset;
- u16 target;
- int sf, of;
-
- /* jump to byte offset if sign flag not equal to overflow flag. */
- START_OF_INSTR();
- DECODE_PRINTF("JL\t");
- offset = (s8) fetch_byte_imm();
- target = (u16) (M.x86.R_IP + (s16) offset);
- DECODE_PRINTF2("%x\n", target);
- TRACE_AND_STEP();
- sf = ACCESS_FLAG(F_SF) != 0;
- of = ACCESS_FLAG(F_OF) != 0;
- if (sf ^ of)
- M.x86.R_IP = target;
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
-}
-
-/****************************************************************************
-REMARKS:
-Handles opcode 0x7d
-****************************************************************************/
-void x86emuOp_jump_near_NL(u8 X86EMU_UNUSED(op1))
-{
- s8 offset;
- u16 target;
- int sf, of;
-
- /* jump to byte offset if sign flag not equal to overflow flag. */
- START_OF_INSTR();
- DECODE_PRINTF("JNL\t");
- offset = (s8) fetch_byte_imm();
- target = (u16) (M.x86.R_IP + (s16) offset);
- DECODE_PRINTF2("%x\n", target);
- TRACE_AND_STEP();
- sf = ACCESS_FLAG(F_SF) != 0;
- of = ACCESS_FLAG(F_OF) != 0;
- /* note: inverse of above, but using == instead of xor. */
- if (sf == of)
- M.x86.R_IP = target;
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
-}
-
-/****************************************************************************
-REMARKS:
-Handles opcode 0x7e
-****************************************************************************/
-void x86emuOp_jump_near_LE(u8 X86EMU_UNUSED(op1))
-{
- s8 offset;
- u16 target;
- int sf, of;
-
- /* jump to byte offset if sign flag not equal to overflow flag
- or the zero flag is set */
- START_OF_INSTR();
- DECODE_PRINTF("JLE\t");
- offset = (s8) fetch_byte_imm();
- target = (u16) (M.x86.R_IP + (s16) offset);
- DECODE_PRINTF2("%x\n", target);
- TRACE_AND_STEP();
- sf = ACCESS_FLAG(F_SF) != 0;
- of = ACCESS_FLAG(F_OF) != 0;
- if ((sf ^ of) || ACCESS_FLAG(F_ZF))
- M.x86.R_IP = target;
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
-}
-
-/****************************************************************************
-REMARKS:
-Handles opcode 0x7f
-****************************************************************************/
-void x86emuOp_jump_near_NLE(u8 X86EMU_UNUSED(op1))
-{
- s8 offset;
- u16 target;
- int sf, of;
-
- /* jump to byte offset if sign flag equal to overflow flag.
- and the zero flag is clear */
- START_OF_INSTR();
- DECODE_PRINTF("JNLE\t");
- offset = (s8) fetch_byte_imm();
- target = (u16) (M.x86.R_IP + (s16) offset);
- DECODE_PRINTF2("%x\n", target);
- TRACE_AND_STEP();
- sf = ACCESS_FLAG(F_SF) != 0;
- of = ACCESS_FLAG(F_OF) != 0;
- if ((sf == of) && !ACCESS_FLAG(F_ZF))
- M.x86.R_IP = target;
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
-}
-
-static u8(*opc80_byte_operation[]) (u8 d, u8 s) = {
- add_byte, /* 00 */
- or_byte, /* 01 */
- adc_byte, /* 02 */
- sbb_byte, /* 03 */
- and_byte, /* 04 */
- sub_byte, /* 05 */
- xor_byte, /* 06 */
- cmp_byte, /* 07 */
-};
-
-/****************************************************************************
-REMARKS:
Handles opcode 0x80
****************************************************************************/
void x86emuOp_opc80_byte_RM_IMM(u8 X86EMU_UNUSED(op1))
{
- int mod, rl, rh;
- u8 *destreg;
- uint destoffset;
- u8 imm;
- u8 destval;
-
- /*
- * Weirdo special case instruction format. Part of the opcode
- * held below in "RH". Doubly nested case would result, except
- * that the decoded instruction
- */
- START_OF_INSTR();
- FETCH_DECODE_MODRM(mod, rh, rl);
+ int mod, rl, rh;
+ u8 *destreg;
+ uint destoffset;
+ u8 imm;
+ u8 destval;
+
+ /*
+ * Weirdo special case instruction format. Part of the opcode
+ * held below in "RH". Doubly nested case would result, except
+ * that the decoded instruction
+ */
+ START_OF_INSTR();
+ FETCH_DECODE_MODRM(mod, rh, rl);
#ifdef DEBUG
- if (DEBUG_DECODE()) {
- /* XXX DECODE_PRINTF may be changed to something more
- general, so that it is important to leave the strings
- in the same format, even though the result is that the
- above test is done twice. */
-
- switch (rh) {
- case 0:
- DECODE_PRINTF("ADD\t");
- break;
- case 1:
- DECODE_PRINTF("OR\t");
- break;
- case 2:
- DECODE_PRINTF("ADC\t");
- break;
- case 3:
- DECODE_PRINTF("SBB\t");
- break;
- case 4:
- DECODE_PRINTF("AND\t");
- break;
- case 5:
- DECODE_PRINTF("SUB\t");
- break;
- case 6:
- DECODE_PRINTF("XOR\t");
- break;
- case 7:
- DECODE_PRINTF("CMP\t");
- break;
- }
- }
+ if (DEBUG_DECODE()) {
+ /* XXX DECODE_PRINTF may be changed to something more
+ general, so that it is important to leave the strings
+ in the same format, even though the result is that the
+ above test is done twice. */
+
+ switch (rh) {
+ case 0:
+ DECODE_PRINTF("ADD\t");
+ break;
+ case 1:
+ DECODE_PRINTF("OR\t");
+ break;
+ case 2:
+ DECODE_PRINTF("ADC\t");
+ break;
+ case 3:
+ DECODE_PRINTF("SBB\t");
+ break;
+ case 4:
+ DECODE_PRINTF("AND\t");
+ break;
+ case 5:
+ DECODE_PRINTF("SUB\t");
+ break;
+ case 6:
+ DECODE_PRINTF("XOR\t");
+ break;
+ case 7:
+ DECODE_PRINTF("CMP\t");
+ break;
+ }
+ }
#endif
- /* know operation, decode the mod byte to find the addressing
- mode. */
- switch (mod) {
- case 0:
- DECODE_PRINTF("BYTE PTR ");
- destoffset = decode_rm00_address(rl);
- DECODE_PRINTF(",");
- destval = fetch_data_byte(destoffset);
- imm = fetch_byte_imm();
- DECODE_PRINTF2("%x\n", imm);
- TRACE_AND_STEP();
- destval = (*opc80_byte_operation[rh]) (destval, imm);
- if (rh != 7)
- store_data_byte(destoffset, destval);
- break;
- case 1:
- DECODE_PRINTF("BYTE PTR ");
- destoffset = decode_rm01_address(rl);
- DECODE_PRINTF(",");
- destval = fetch_data_byte(destoffset);
- imm = fetch_byte_imm();
- DECODE_PRINTF2("%x\n", imm);
- TRACE_AND_STEP();
- destval = (*opc80_byte_operation[rh]) (destval, imm);
- if (rh != 7)
- store_data_byte(destoffset, destval);
- break;
- case 2:
- DECODE_PRINTF("BYTE PTR ");
- destoffset = decode_rm10_address(rl);
- DECODE_PRINTF(",");
- destval = fetch_data_byte(destoffset);
- imm = fetch_byte_imm();
- DECODE_PRINTF2("%x\n", imm);
- TRACE_AND_STEP();
- destval = (*opc80_byte_operation[rh]) (destval, imm);
- if (rh != 7)
- store_data_byte(destoffset, destval);
- break;
- case 3: /* register to register */
- destreg = DECODE_RM_BYTE_REGISTER(rl);
- DECODE_PRINTF(",");
- imm = fetch_byte_imm();
- DECODE_PRINTF2("%x\n", imm);
- TRACE_AND_STEP();
- destval = (*opc80_byte_operation[rh]) (*destreg, imm);
- if (rh != 7)
- *destreg = destval;
- break;
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
-}
-
-static u16(*opc81_word_operation[]) (u16 d, u16 s) = {
- add_word, /*00 */
- or_word, /*01 */
- adc_word, /*02 */
- sbb_word, /*03 */
- and_word, /*04 */
- sub_word, /*05 */
- xor_word, /*06 */
- cmp_word, /*07 */
-};
-
-static u32(*opc81_long_operation[]) (u32 d, u32 s) = {
- add_long, /*00 */
- or_long, /*01 */
- adc_long, /*02 */
- sbb_long, /*03 */
- and_long, /*04 */
- sub_long, /*05 */
- xor_long, /*06 */
- cmp_long, /*07 */
-};
+ /* know operation, decode the mod byte to find the addressing
+ mode. */
+ if (mod < 3) {
+ DECODE_PRINTF("BYTE PTR ");
+ destoffset = decode_rmXX_address(mod, rl);
+ DECODE_PRINTF(",");
+ destval = fetch_data_byte(destoffset);
+ imm = fetch_byte_imm();
+ DECODE_PRINTF2("%x\n", imm);
+ TRACE_AND_STEP();
+ destval = (*genop_byte_operation[rh]) (destval, imm);
+ if (rh != 7)
+ store_data_byte(destoffset, destval);
+ } else { /* register to register */
+ destreg = DECODE_RM_BYTE_REGISTER(rl);
+ DECODE_PRINTF(",");
+ imm = fetch_byte_imm();
+ DECODE_PRINTF2("%x\n", imm);
+ TRACE_AND_STEP();
+ destval = (*genop_byte_operation[rh]) (*destreg, imm);
+ if (rh != 7)
+ *destreg = destval;
+ }
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
+}
/****************************************************************************
REMARKS:
@@ -5317,185 +1346,111 @@ Handles opcode 0x81
****************************************************************************/
void x86emuOp_opc81_word_RM_IMM(u8 X86EMU_UNUSED(op1))
{
- int mod, rl, rh;
- uint destoffset;
+ int mod, rl, rh;
+ uint destoffset;
- /*
- * Weirdo special case instruction format. Part of the opcode
- * held below in "RH". Doubly nested case would result, except
- * that the decoded instruction
- */
- START_OF_INSTR();
- FETCH_DECODE_MODRM(mod, rh, rl);
+ /*
+ * Weirdo special case instruction format. Part of the opcode
+ * held below in "RH". Doubly nested case would result, except
+ * that the decoded instruction
+ */
+ START_OF_INSTR();
+ FETCH_DECODE_MODRM(mod, rh, rl);
#ifdef DEBUG
- if (DEBUG_DECODE()) {
- /* XXX DECODE_PRINTF may be changed to something more
- general, so that it is important to leave the strings
- in the same format, even though the result is that the
- above test is done twice. */
-
- switch (rh) {
- case 0:
- DECODE_PRINTF("ADD\t");
- break;
- case 1:
- DECODE_PRINTF("OR\t");
- break;
- case 2:
- DECODE_PRINTF("ADC\t");
- break;
- case 3:
- DECODE_PRINTF("SBB\t");
- break;
- case 4:
- DECODE_PRINTF("AND\t");
- break;
- case 5:
- DECODE_PRINTF("SUB\t");
- break;
- case 6:
- DECODE_PRINTF("XOR\t");
- break;
- case 7:
- DECODE_PRINTF("CMP\t");
- break;
- }
- }
+ if (DEBUG_DECODE()) {
+ /* XXX DECODE_PRINTF may be changed to something more
+ general, so that it is important to leave the strings
+ in the same format, even though the result is that the
+ above test is done twice. */
+
+ switch (rh) {
+ case 0:
+ DECODE_PRINTF("ADD\t");
+ break;
+ case 1:
+ DECODE_PRINTF("OR\t");
+ break;
+ case 2:
+ DECODE_PRINTF("ADC\t");
+ break;
+ case 3:
+ DECODE_PRINTF("SBB\t");
+ break;
+ case 4:
+ DECODE_PRINTF("AND\t");
+ break;
+ case 5:
+ DECODE_PRINTF("SUB\t");
+ break;
+ case 6:
+ DECODE_PRINTF("XOR\t");
+ break;
+ case 7:
+ DECODE_PRINTF("CMP\t");
+ break;
+ }
+ }
#endif
- /*
- * Know operation, decode the mod byte to find the addressing
- * mode.
- */
- switch (mod) {
- case 0:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 destval, imm;
-
- DECODE_PRINTF("DWORD PTR ");
- destoffset = decode_rm00_address(rl);
- DECODE_PRINTF(",");
- destval = fetch_data_long(destoffset);
- imm = fetch_long_imm();
- DECODE_PRINTF2("%x\n", imm);
- TRACE_AND_STEP();
- destval = (*opc81_long_operation[rh]) (destval, imm);
- if (rh != 7)
- store_data_long(destoffset, destval);
- } else {
- u16 destval, imm;
-
- DECODE_PRINTF("WORD PTR ");
- destoffset = decode_rm00_address(rl);
- DECODE_PRINTF(",");
- destval = fetch_data_word(destoffset);
- imm = fetch_word_imm();
- DECODE_PRINTF2("%x\n", imm);
- TRACE_AND_STEP();
- destval = (*opc81_word_operation[rh]) (destval, imm);
- if (rh != 7)
- store_data_word(destoffset, destval);
- }
- break;
- case 1:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 destval, imm;
-
- DECODE_PRINTF("DWORD PTR ");
- destoffset = decode_rm01_address(rl);
- DECODE_PRINTF(",");
- destval = fetch_data_long(destoffset);
- imm = fetch_long_imm();
- DECODE_PRINTF2("%x\n", imm);
- TRACE_AND_STEP();
- destval = (*opc81_long_operation[rh]) (destval, imm);
- if (rh != 7)
- store_data_long(destoffset, destval);
- } else {
- u16 destval, imm;
-
- DECODE_PRINTF("WORD PTR ");
- destoffset = decode_rm01_address(rl);
- DECODE_PRINTF(",");
- destval = fetch_data_word(destoffset);
- imm = fetch_word_imm();
- DECODE_PRINTF2("%x\n", imm);
- TRACE_AND_STEP();
- destval = (*opc81_word_operation[rh]) (destval, imm);
- if (rh != 7)
- store_data_word(destoffset, destval);
- }
- break;
- case 2:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 destval, imm;
-
- DECODE_PRINTF("DWORD PTR ");
- destoffset = decode_rm10_address(rl);
- DECODE_PRINTF(",");
- destval = fetch_data_long(destoffset);
- imm = fetch_long_imm();
- DECODE_PRINTF2("%x\n", imm);
- TRACE_AND_STEP();
- destval = (*opc81_long_operation[rh]) (destval, imm);
- if (rh != 7)
- store_data_long(destoffset, destval);
- } else {
- u16 destval, imm;
-
- DECODE_PRINTF("WORD PTR ");
- destoffset = decode_rm10_address(rl);
- DECODE_PRINTF(",");
- destval = fetch_data_word(destoffset);
- imm = fetch_word_imm();
- DECODE_PRINTF2("%x\n", imm);
- TRACE_AND_STEP();
- destval = (*opc81_word_operation[rh]) (destval, imm);
- if (rh != 7)
- store_data_word(destoffset, destval);
- }
- break;
- case 3: /* register to register */
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 *destreg;
- u32 destval, imm;
-
- destreg = DECODE_RM_LONG_REGISTER(rl);
- DECODE_PRINTF(",");
- imm = fetch_long_imm();
- DECODE_PRINTF2("%x\n", imm);
- TRACE_AND_STEP();
- destval = (*opc81_long_operation[rh]) (*destreg, imm);
- if (rh != 7)
- *destreg = destval;
- } else {
- u16 *destreg;
- u16 destval, imm;
-
- destreg = DECODE_RM_WORD_REGISTER(rl);
- DECODE_PRINTF(",");
- imm = fetch_word_imm();
- DECODE_PRINTF2("%x\n", imm);
- TRACE_AND_STEP();
- destval = (*opc81_word_operation[rh]) (*destreg, imm);
- if (rh != 7)
- *destreg = destval;
- }
- break;
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
-}
-
-static u8(*opc82_byte_operation[]) (u8 s, u8 d) = {
- add_byte, /*00 */
- or_byte, /*01 *//*YYY UNUSED ???? */
- adc_byte, /*02 */
- sbb_byte, /*03 */
- and_byte, /*04 *//*YYY UNUSED ???? */
- sub_byte, /*05 */
- xor_byte, /*06 *//*YYY UNUSED ???? */
- cmp_byte, /*07 */
-};
+ /*
+ * Know operation, decode the mod byte to find the addressing
+ * mode.
+ */
+ if (mod < 3) {
+ DECODE_PRINTF("DWORD PTR ");
+ destoffset = decode_rmXX_address(mod, rl);
+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+ u32 destval,imm;
+
+ DECODE_PRINTF(",");
+ destval = fetch_data_long(destoffset);
+ imm = fetch_long_imm();
+ DECODE_PRINTF2("%x\n", imm);
+ TRACE_AND_STEP();
+ destval = (*genop_long_operation[rh]) (destval, imm);
+ if (rh != 7)
+ store_data_long(destoffset, destval);
+ } else {
+ u16 destval,imm;
+
+ DECODE_PRINTF(",");
+ destval = fetch_data_word(destoffset);
+ imm = fetch_word_imm();
+ DECODE_PRINTF2("%x\n", imm);
+ TRACE_AND_STEP();
+ destval = (*genop_word_operation[rh]) (destval, imm);
+ if (rh != 7)
+ store_data_word(destoffset, destval);
+ }
+ } else { /* register to register */
+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+ u32 *destreg;
+ u32 destval,imm;
+
+ destreg = DECODE_RM_LONG_REGISTER(rl);
+ DECODE_PRINTF(",");
+ imm = fetch_long_imm();
+ DECODE_PRINTF2("%x\n", imm);
+ TRACE_AND_STEP();
+ destval = (*genop_long_operation[rh]) (*destreg, imm);
+ if (rh != 7)
+ *destreg = destval;
+ } else {
+ u16 *destreg;
+ u16 destval,imm;
+
+ destreg = DECODE_RM_WORD_REGISTER(rl);
+ DECODE_PRINTF(",");
+ imm = fetch_word_imm();
+ DECODE_PRINTF2("%x\n", imm);
+ TRACE_AND_STEP();
+ destval = (*genop_word_operation[rh]) (*destreg, imm);
+ if (rh != 7)
+ *destreg = destval;
+ }
+ }
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
+}
/****************************************************************************
REMARKS:
@@ -5503,125 +1458,78 @@ Handles opcode 0x82
****************************************************************************/
void x86emuOp_opc82_byte_RM_IMM(u8 X86EMU_UNUSED(op1))
{
- int mod, rl, rh;
- u8 *destreg;
- uint destoffset;
- u8 imm;
- u8 destval;
-
- /*
- * Weirdo special case instruction format. Part of the opcode
- * held below in "RH". Doubly nested case would result, except
- * that the decoded instruction Similar to opcode 81, except that
- * the immediate byte is sign extended to a word length.
- */
- START_OF_INSTR();
- FETCH_DECODE_MODRM(mod, rh, rl);
+ int mod, rl, rh;
+ u8 *destreg;
+ uint destoffset;
+ u8 imm;
+ u8 destval;
+
+ /*
+ * Weirdo special case instruction format. Part of the opcode
+ * held below in "RH". Doubly nested case would result, except
+ * that the decoded instruction Similar to opcode 81, except that
+ * the immediate byte is sign extended to a word length.
+ */
+ START_OF_INSTR();
+ FETCH_DECODE_MODRM(mod, rh, rl);
#ifdef DEBUG
- if (DEBUG_DECODE()) {
- /* XXX DECODE_PRINTF may be changed to something more
- general, so that it is important to leave the strings
- in the same format, even though the result is that the
- above test is done twice. */
- switch (rh) {
- case 0:
- DECODE_PRINTF("ADD\t");
- break;
- case 1:
- DECODE_PRINTF("OR\t");
- break;
- case 2:
- DECODE_PRINTF("ADC\t");
- break;
- case 3:
- DECODE_PRINTF("SBB\t");
- break;
- case 4:
- DECODE_PRINTF("AND\t");
- break;
- case 5:
- DECODE_PRINTF("SUB\t");
- break;
- case 6:
- DECODE_PRINTF("XOR\t");
- break;
- case 7:
- DECODE_PRINTF("CMP\t");
- break;
- }
- }
+ if (DEBUG_DECODE()) {
+ /* XXX DECODE_PRINTF may be changed to something more
+ general, so that it is important to leave the strings
+ in the same format, even though the result is that the
+ above test is done twice. */
+ switch (rh) {
+ case 0:
+ DECODE_PRINTF("ADD\t");
+ break;
+ case 1:
+ DECODE_PRINTF("OR\t");
+ break;
+ case 2:
+ DECODE_PRINTF("ADC\t");
+ break;
+ case 3:
+ DECODE_PRINTF("SBB\t");
+ break;
+ case 4:
+ DECODE_PRINTF("AND\t");
+ break;
+ case 5:
+ DECODE_PRINTF("SUB\t");
+ break;
+ case 6:
+ DECODE_PRINTF("XOR\t");
+ break;
+ case 7:
+ DECODE_PRINTF("CMP\t");
+ break;
+ }
+ }
#endif
- /* know operation, decode the mod byte to find the addressing
- mode. */
- switch (mod) {
- case 0:
- DECODE_PRINTF("BYTE PTR ");
- destoffset = decode_rm00_address(rl);
- destval = fetch_data_byte(destoffset);
- imm = fetch_byte_imm();
- DECODE_PRINTF2(",%x\n", imm);
- TRACE_AND_STEP();
- destval = (*opc82_byte_operation[rh]) (destval, imm);
- if (rh != 7)
- store_data_byte(destoffset, destval);
- break;
- case 1:
- DECODE_PRINTF("BYTE PTR ");
- destoffset = decode_rm01_address(rl);
- destval = fetch_data_byte(destoffset);
- imm = fetch_byte_imm();
- DECODE_PRINTF2(",%x\n", imm);
- TRACE_AND_STEP();
- destval = (*opc82_byte_operation[rh]) (destval, imm);
- if (rh != 7)
- store_data_byte(destoffset, destval);
- break;
- case 2:
- DECODE_PRINTF("BYTE PTR ");
- destoffset = decode_rm10_address(rl);
- destval = fetch_data_byte(destoffset);
- imm = fetch_byte_imm();
- DECODE_PRINTF2(",%x\n", imm);
- TRACE_AND_STEP();
- destval = (*opc82_byte_operation[rh]) (destval, imm);
- if (rh != 7)
- store_data_byte(destoffset, destval);
- break;
- case 3: /* register to register */
- destreg = DECODE_RM_BYTE_REGISTER(rl);
- imm = fetch_byte_imm();
- DECODE_PRINTF2(",%x\n", imm);
- TRACE_AND_STEP();
- destval = (*opc82_byte_operation[rh]) (*destreg, imm);
- if (rh != 7)
- *destreg = destval;
- break;
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
-}
-
-static u16(*opc83_word_operation[]) (u16 s, u16 d) = {
- add_word, /*00 */
- or_word, /*01 *//*YYY UNUSED ???? */
- adc_word, /*02 */
- sbb_word, /*03 */
- and_word, /*04 *//*YYY UNUSED ???? */
- sub_word, /*05 */
- xor_word, /*06 *//*YYY UNUSED ???? */
- cmp_word, /*07 */
-};
-
-static u32(*opc83_long_operation[]) (u32 s, u32 d) = {
- add_long, /*00 */
- or_long, /*01 *//*YYY UNUSED ???? */
- adc_long, /*02 */
- sbb_long, /*03 */
- and_long, /*04 *//*YYY UNUSED ???? */
- sub_long, /*05 */
- xor_long, /*06 *//*YYY UNUSED ???? */
- cmp_long, /*07 */
-};
+ /* know operation, decode the mod byte to find the addressing
+ mode. */
+ if (mod < 3) {
+ DECODE_PRINTF("BYTE PTR ");
+ destoffset = decode_rmXX_address(mod, rl);
+ destval = fetch_data_byte(destoffset);
+ imm = fetch_byte_imm();
+ DECODE_PRINTF2(",%x\n", imm);
+ TRACE_AND_STEP();
+ destval = (*genop_byte_operation[rh]) (destval, imm);
+ if (rh != 7)
+ store_data_byte(destoffset, destval);
+ } else { /* register to register */
+ destreg = DECODE_RM_BYTE_REGISTER(rl);
+ imm = fetch_byte_imm();
+ DECODE_PRINTF2(",%x\n", imm);
+ TRACE_AND_STEP();
+ destval = (*genop_byte_operation[rh]) (*destreg, imm);
+ if (rh != 7)
+ *destreg = destval;
+ }
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
+}
/****************************************************************************
REMARKS:
@@ -5629,163 +1537,105 @@ Handles opcode 0x83
****************************************************************************/
void x86emuOp_opc83_word_RM_IMM(u8 X86EMU_UNUSED(op1))
{
- int mod, rl, rh;
- uint destoffset;
-
- /*
- * Weirdo special case instruction format. Part of the opcode
- * held below in "RH". Doubly nested case would result, except
- * that the decoded instruction Similar to opcode 81, except that
- * the immediate byte is sign extended to a word length.
- */
- START_OF_INSTR();
- FETCH_DECODE_MODRM(mod, rh, rl);
+ int mod, rl, rh;
+ uint destoffset;
+
+ /*
+ * Weirdo special case instruction format. Part of the opcode
+ * held below in "RH". Doubly nested case would result, except
+ * that the decoded instruction Similar to opcode 81, except that
+ * the immediate byte is sign extended to a word length.
+ */
+ START_OF_INSTR();
+ FETCH_DECODE_MODRM(mod, rh, rl);
#ifdef DEBUG
- if (DEBUG_DECODE()) {
- /* XXX DECODE_PRINTF may be changed to something more
- general, so that it is important to leave the strings
- in the same format, even though the result is that the
- above test is done twice. */
- switch (rh) {
- case 0:
- DECODE_PRINTF("ADD\t");
- break;
- case 1:
- DECODE_PRINTF("OR\t");
- break;
- case 2:
- DECODE_PRINTF("ADC\t");
- break;
- case 3:
- DECODE_PRINTF("SBB\t");
- break;
- case 4:
- DECODE_PRINTF("AND\t");
- break;
- case 5:
- DECODE_PRINTF("SUB\t");
- break;
- case 6:
- DECODE_PRINTF("XOR\t");
- break;
- case 7:
- DECODE_PRINTF("CMP\t");
- break;
- }
- }
+ if (DEBUG_DECODE()) {
+ /* XXX DECODE_PRINTF may be changed to something more
+ general, so that it is important to leave the strings
+ in the same format, even though the result is that the
+ above test is done twice. */
+ switch (rh) {
+ case 0:
+ DECODE_PRINTF("ADD\t");
+ break;
+ case 1:
+ DECODE_PRINTF("OR\t");
+ break;
+ case 2:
+ DECODE_PRINTF("ADC\t");
+ break;
+ case 3:
+ DECODE_PRINTF("SBB\t");
+ break;
+ case 4:
+ DECODE_PRINTF("AND\t");
+ break;
+ case 5:
+ DECODE_PRINTF("SUB\t");
+ break;
+ case 6:
+ DECODE_PRINTF("XOR\t");
+ break;
+ case 7:
+ DECODE_PRINTF("CMP\t");
+ break;
+ }
+ }
#endif
- /* know operation, decode the mod byte to find the addressing
- mode. */
- switch (mod) {
- case 0:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 destval, imm;
-
- DECODE_PRINTF("DWORD PTR ");
- destoffset = decode_rm00_address(rl);
- destval = fetch_data_long(destoffset);
- imm = (s8) fetch_byte_imm();
- DECODE_PRINTF2(",%x\n", imm);
- TRACE_AND_STEP();
- destval = (*opc83_long_operation[rh]) (destval, imm);
- if (rh != 7)
- store_data_long(destoffset, destval);
- } else {
- u16 destval, imm;
-
- DECODE_PRINTF("WORD PTR ");
- destoffset = decode_rm00_address(rl);
- destval = fetch_data_word(destoffset);
- imm = (s8) fetch_byte_imm();
- DECODE_PRINTF2(",%x\n", imm);
- TRACE_AND_STEP();
- destval = (*opc83_word_operation[rh]) (destval, imm);
- if (rh != 7)
- store_data_word(destoffset, destval);
- }
- break;
- case 1:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 destval, imm;
-
- DECODE_PRINTF("DWORD PTR ");
- destoffset = decode_rm01_address(rl);
- destval = fetch_data_long(destoffset);
- imm = (s8) fetch_byte_imm();
- DECODE_PRINTF2(",%x\n", imm);
- TRACE_AND_STEP();
- destval = (*opc83_long_operation[rh]) (destval, imm);
- if (rh != 7)
- store_data_long(destoffset, destval);
- } else {
- u16 destval, imm;
-
- DECODE_PRINTF("WORD PTR ");
- destoffset = decode_rm01_address(rl);
- destval = fetch_data_word(destoffset);
- imm = (s8) fetch_byte_imm();
- DECODE_PRINTF2(",%x\n", imm);
- TRACE_AND_STEP();
- destval = (*opc83_word_operation[rh]) (destval, imm);
- if (rh != 7)
- store_data_word(destoffset, destval);
- }
- break;
- case 2:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 destval, imm;
-
- DECODE_PRINTF("DWORD PTR ");
- destoffset = decode_rm10_address(rl);
- destval = fetch_data_long(destoffset);
- imm = (s8) fetch_byte_imm();
- DECODE_PRINTF2(",%x\n", imm);
- TRACE_AND_STEP();
- destval = (*opc83_long_operation[rh]) (destval, imm);
- if (rh != 7)
- store_data_long(destoffset, destval);
- } else {
- u16 destval, imm;
-
- DECODE_PRINTF("WORD PTR ");
- destoffset = decode_rm10_address(rl);
- destval = fetch_data_word(destoffset);
- imm = (s8) fetch_byte_imm();
- DECODE_PRINTF2(",%x\n", imm);
- TRACE_AND_STEP();
- destval = (*opc83_word_operation[rh]) (destval, imm);
- if (rh != 7)
- store_data_word(destoffset, destval);
- }
- break;
- case 3: /* register to register */
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 *destreg;
- u32 destval, imm;
-
- destreg = DECODE_RM_LONG_REGISTER(rl);
- imm = (s8) fetch_byte_imm();
- DECODE_PRINTF2(",%x\n", imm);
- TRACE_AND_STEP();
- destval = (*opc83_long_operation[rh]) (*destreg, imm);
- if (rh != 7)
- *destreg = destval;
- } else {
- u16 *destreg;
- u16 destval, imm;
-
- destreg = DECODE_RM_WORD_REGISTER(rl);
- imm = (s8) fetch_byte_imm();
- DECODE_PRINTF2(",%x\n", imm);
- TRACE_AND_STEP();
- destval = (*opc83_word_operation[rh]) (*destreg, imm);
- if (rh != 7)
- *destreg = destval;
- }
- break;
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ /* know operation, decode the mod byte to find the addressing
+ mode. */
+ if (mod < 3) {
+ DECODE_PRINTF("DWORD PTR ");
+ destoffset = decode_rmXX_address(mod,rl);
+
+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+ u32 destval,imm;
+
+ destval = fetch_data_long(destoffset);
+ imm = (s8) fetch_byte_imm();
+ DECODE_PRINTF2(",%x\n", imm);
+ TRACE_AND_STEP();
+ destval = (*genop_long_operation[rh]) (destval, imm);
+ if (rh != 7)
+ store_data_long(destoffset, destval);
+ } else {
+ u16 destval,imm;
+
+ destval = fetch_data_word(destoffset);
+ imm = (s8) fetch_byte_imm();
+ DECODE_PRINTF2(",%x\n", imm);
+ TRACE_AND_STEP();
+ destval = (*genop_word_operation[rh]) (destval, imm);
+ if (rh != 7)
+ store_data_word(destoffset, destval);
+ }
+ } else { /* register to register */
+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+ u32 *destreg;
+ u32 destval,imm;
+
+ destreg = DECODE_RM_LONG_REGISTER(rl);
+ imm = (s8) fetch_byte_imm();
+ DECODE_PRINTF2(",%x\n", imm);
+ TRACE_AND_STEP();
+ destval = (*genop_long_operation[rh]) (*destreg, imm);
+ if (rh != 7)
+ *destreg = destval;
+ } else {
+ u16 *destreg;
+ u16 destval,imm;
+
+ destreg = DECODE_RM_WORD_REGISTER(rl);
+ imm = (s8) fetch_byte_imm();
+ DECODE_PRINTF2(",%x\n", imm);
+ TRACE_AND_STEP();
+ destval = (*genop_word_operation[rh]) (*destreg, imm);
+ if (rh != 7)
+ *destreg = destval;
+ }
+ }
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/****************************************************************************
@@ -5794,53 +1644,32 @@ Handles opcode 0x84
****************************************************************************/
void x86emuOp_test_byte_RM_R(u8 X86EMU_UNUSED(op1))
{
- int mod, rl, rh;
- u8 *destreg, *srcreg;
- uint destoffset;
- u8 destval;
-
- START_OF_INSTR();
- DECODE_PRINTF("TEST\t");
- FETCH_DECODE_MODRM(mod, rh, rl);
- switch (mod) {
- case 0:
- destoffset = decode_rm00_address(rl);
- DECODE_PRINTF(",");
- destval = fetch_data_byte(destoffset);
- srcreg = DECODE_RM_BYTE_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- test_byte(destval, *srcreg);
- break;
- case 1:
- destoffset = decode_rm01_address(rl);
- DECODE_PRINTF(",");
- destval = fetch_data_byte(destoffset);
- srcreg = DECODE_RM_BYTE_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- test_byte(destval, *srcreg);
- break;
- case 2:
- destoffset = decode_rm10_address(rl);
- DECODE_PRINTF(",");
- destval = fetch_data_byte(destoffset);
- srcreg = DECODE_RM_BYTE_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- test_byte(destval, *srcreg);
- break;
- case 3: /* register to register */
- destreg = DECODE_RM_BYTE_REGISTER(rl);
- DECODE_PRINTF(",");
- srcreg = DECODE_RM_BYTE_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- test_byte(*destreg, *srcreg);
- break;
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ int mod, rl, rh;
+ u8 *destreg, *srcreg;
+ uint destoffset;
+ u8 destval;
+
+ START_OF_INSTR();
+ DECODE_PRINTF("TEST\t");
+ FETCH_DECODE_MODRM(mod, rh, rl);
+ if (mod < 3) {
+ destoffset = decode_rmXX_address(mod, rl);
+ DECODE_PRINTF(",");
+ destval = fetch_data_byte(destoffset);
+ srcreg = DECODE_RM_BYTE_REGISTER(rh);
+ DECODE_PRINTF("\n");
+ TRACE_AND_STEP();
+ test_byte(destval, *srcreg);
+ } else { /* register to register */
+ destreg = DECODE_RM_BYTE_REGISTER(rl);
+ DECODE_PRINTF(",");
+ srcreg = DECODE_RM_BYTE_REGISTER(rh);
+ DECODE_PRINTF("\n");
+ TRACE_AND_STEP();
+ test_byte(*destreg, *srcreg);
+ }
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/****************************************************************************
@@ -5849,112 +1678,58 @@ Handles opcode 0x85
****************************************************************************/
void x86emuOp_test_word_RM_R(u8 X86EMU_UNUSED(op1))
{
- int mod, rl, rh;
- uint destoffset;
-
- START_OF_INSTR();
- DECODE_PRINTF("TEST\t");
- FETCH_DECODE_MODRM(mod, rh, rl);
- switch (mod) {
- case 0:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 destval;
- u32 *srcreg;
-
- destoffset = decode_rm00_address(rl);
- DECODE_PRINTF(",");
- destval = fetch_data_long(destoffset);
- srcreg = DECODE_RM_LONG_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- test_long(destval, *srcreg);
- } else {
- u16 destval;
- u16 *srcreg;
-
- destoffset = decode_rm00_address(rl);
- DECODE_PRINTF(",");
- destval = fetch_data_word(destoffset);
- srcreg = DECODE_RM_WORD_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- test_word(destval, *srcreg);
- }
- break;
- case 1:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 destval;
- u32 *srcreg;
-
- destoffset = decode_rm01_address(rl);
- DECODE_PRINTF(",");
- destval = fetch_data_long(destoffset);
- srcreg = DECODE_RM_LONG_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- test_long(destval, *srcreg);
- } else {
- u16 destval;
- u16 *srcreg;
-
- destoffset = decode_rm01_address(rl);
- DECODE_PRINTF(",");
- destval = fetch_data_word(destoffset);
- srcreg = DECODE_RM_WORD_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- test_word(destval, *srcreg);
- }
- break;
- case 2:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 destval;
- u32 *srcreg;
-
- destoffset = decode_rm10_address(rl);
- DECODE_PRINTF(",");
- destval = fetch_data_long(destoffset);
- srcreg = DECODE_RM_LONG_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- test_long(destval, *srcreg);
- } else {
- u16 destval;
- u16 *srcreg;
-
- destoffset = decode_rm10_address(rl);
- DECODE_PRINTF(",");
- destval = fetch_data_word(destoffset);
- srcreg = DECODE_RM_WORD_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- test_word(destval, *srcreg);
- }
- break;
- case 3: /* register to register */
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 *destreg, *srcreg;
-
- destreg = DECODE_RM_LONG_REGISTER(rl);
- DECODE_PRINTF(",");
- srcreg = DECODE_RM_LONG_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- test_long(*destreg, *srcreg);
- } else {
- u16 *destreg, *srcreg;
-
- destreg = DECODE_RM_WORD_REGISTER(rl);
- DECODE_PRINTF(",");
- srcreg = DECODE_RM_WORD_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- test_word(*destreg, *srcreg);
- }
- break;
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ int mod, rl, rh;
+ uint destoffset;
+
+ START_OF_INSTR();
+ DECODE_PRINTF("TEST\t");
+ FETCH_DECODE_MODRM(mod, rh, rl);
+ if (mod < 3) {
+ destoffset = decode_rmXX_address(mod, rl);
+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+ u32 destval;
+ u32 *srcreg;
+
+ DECODE_PRINTF(",");
+ destval = fetch_data_long(destoffset);
+ srcreg = DECODE_RM_LONG_REGISTER(rh);
+ DECODE_PRINTF("\n");
+ TRACE_AND_STEP();
+ test_long(destval, *srcreg);
+ } else {
+ u16 destval;
+ u16 *srcreg;
+
+ DECODE_PRINTF(",");
+ destval = fetch_data_word(destoffset);
+ srcreg = DECODE_RM_WORD_REGISTER(rh);
+ DECODE_PRINTF("\n");
+ TRACE_AND_STEP();
+ test_word(destval, *srcreg);
+ }
+ } else { /* register to register */
+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+ u32 *destreg,*srcreg;
+
+ destreg = DECODE_RM_LONG_REGISTER(rl);
+ DECODE_PRINTF(",");
+ srcreg = DECODE_RM_LONG_REGISTER(rh);
+ DECODE_PRINTF("\n");
+ TRACE_AND_STEP();
+ test_long(*destreg, *srcreg);
+ } else {
+ u16 *destreg,*srcreg;
+
+ destreg = DECODE_RM_WORD_REGISTER(rl);
+ DECODE_PRINTF(",");
+ srcreg = DECODE_RM_WORD_REGISTER(rh);
+ DECODE_PRINTF("\n");
+ TRACE_AND_STEP();
+ test_word(*destreg, *srcreg);
+ }
+ }
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/****************************************************************************
@@ -5963,65 +1738,38 @@ Handles opcode 0x86
****************************************************************************/
void x86emuOp_xchg_byte_RM_R(u8 X86EMU_UNUSED(op1))
{
- int mod, rl, rh;
- u8 *destreg, *srcreg;
- uint destoffset;
- u8 destval;
- u8 tmp;
-
- START_OF_INSTR();
- DECODE_PRINTF("XCHG\t");
- FETCH_DECODE_MODRM(mod, rh, rl);
- switch (mod) {
- case 0:
- destoffset = decode_rm00_address(rl);
- DECODE_PRINTF(",");
- destval = fetch_data_byte(destoffset);
- srcreg = DECODE_RM_BYTE_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- tmp = *srcreg;
- *srcreg = destval;
- destval = tmp;
- store_data_byte(destoffset, destval);
- break;
- case 1:
- destoffset = decode_rm01_address(rl);
- DECODE_PRINTF(",");
- destval = fetch_data_byte(destoffset);
- srcreg = DECODE_RM_BYTE_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- tmp = *srcreg;
- *srcreg = destval;
- destval = tmp;
- store_data_byte(destoffset, destval);
- break;
- case 2:
- destoffset = decode_rm10_address(rl);
- DECODE_PRINTF(",");
- destval = fetch_data_byte(destoffset);
- srcreg = DECODE_RM_BYTE_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- tmp = *srcreg;
- *srcreg = destval;
- destval = tmp;
- store_data_byte(destoffset, destval);
- break;
- case 3: /* register to register */
- destreg = DECODE_RM_BYTE_REGISTER(rl);
- DECODE_PRINTF(",");
- srcreg = DECODE_RM_BYTE_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- tmp = *srcreg;
- *srcreg = *destreg;
- *destreg = tmp;
- break;
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ int mod, rl, rh;
+ u8 *destreg, *srcreg;
+ uint destoffset;
+ u8 destval;
+ u8 tmp;
+
+ START_OF_INSTR();
+ DECODE_PRINTF("XCHG\t");
+ FETCH_DECODE_MODRM(mod, rh, rl);
+ if (mod < 3) {
+ destoffset = decode_rmXX_address(mod, rl);
+ DECODE_PRINTF(",");
+ destval = fetch_data_byte(destoffset);
+ srcreg = DECODE_RM_BYTE_REGISTER(rh);
+ DECODE_PRINTF("\n");
+ TRACE_AND_STEP();
+ tmp = *srcreg;
+ *srcreg = destval;
+ destval = tmp;
+ store_data_byte(destoffset, destval);
+ } else { /* register to register */
+ destreg = DECODE_RM_BYTE_REGISTER(rl);
+ DECODE_PRINTF(",");
+ srcreg = DECODE_RM_BYTE_REGISTER(rh);
+ DECODE_PRINTF("\n");
+ TRACE_AND_STEP();
+ tmp = *srcreg;
+ *srcreg = *destreg;
+ *destreg = tmp;
+ }
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/****************************************************************************
@@ -6030,136 +1778,69 @@ Handles opcode 0x87
****************************************************************************/
void x86emuOp_xchg_word_RM_R(u8 X86EMU_UNUSED(op1))
{
- int mod, rl, rh;
- uint destoffset;
-
- START_OF_INSTR();
- DECODE_PRINTF("XCHG\t");
- FETCH_DECODE_MODRM(mod, rh, rl);
- switch (mod) {
- case 0:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 *srcreg;
- u32 destval, tmp;
-
- destoffset = decode_rm00_address(rl);
- DECODE_PRINTF(",");
- destval = fetch_data_long(destoffset);
- srcreg = DECODE_RM_LONG_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- tmp = *srcreg;
- *srcreg = destval;
- destval = tmp;
- store_data_long(destoffset, destval);
- } else {
- u16 *srcreg;
- u16 destval, tmp;
-
- destoffset = decode_rm00_address(rl);
- DECODE_PRINTF(",");
- destval = fetch_data_word(destoffset);
- srcreg = DECODE_RM_WORD_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- tmp = *srcreg;
- *srcreg = destval;
- destval = tmp;
- store_data_word(destoffset, destval);
- }
- break;
- case 1:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 *srcreg;
- u32 destval, tmp;
-
- destoffset = decode_rm01_address(rl);
- DECODE_PRINTF(",");
- destval = fetch_data_long(destoffset);
- srcreg = DECODE_RM_LONG_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- tmp = *srcreg;
- *srcreg = destval;
- destval = tmp;
- store_data_long(destoffset, destval);
- } else {
- u16 *srcreg;
- u16 destval, tmp;
-
- destoffset = decode_rm01_address(rl);
- DECODE_PRINTF(",");
- destval = fetch_data_word(destoffset);
- srcreg = DECODE_RM_WORD_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- tmp = *srcreg;
- *srcreg = destval;
- destval = tmp;
- store_data_word(destoffset, destval);
- }
- break;
- case 2:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 *srcreg;
- u32 destval, tmp;
-
- destoffset = decode_rm10_address(rl);
- DECODE_PRINTF(",");
- destval = fetch_data_long(destoffset);
- srcreg = DECODE_RM_LONG_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- tmp = *srcreg;
- *srcreg = destval;
- destval = tmp;
- store_data_long(destoffset, destval);
- } else {
- u16 *srcreg;
- u16 destval, tmp;
-
- destoffset = decode_rm10_address(rl);
- DECODE_PRINTF(",");
- destval = fetch_data_word(destoffset);
- srcreg = DECODE_RM_WORD_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- tmp = *srcreg;
- *srcreg = destval;
- destval = tmp;
- store_data_word(destoffset, destval);
- }
- break;
- case 3: /* register to register */
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 *destreg, *srcreg;
- u32 tmp;
-
- destreg = DECODE_RM_LONG_REGISTER(rl);
- DECODE_PRINTF(",");
- srcreg = DECODE_RM_LONG_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- tmp = *srcreg;
- *srcreg = *destreg;
- *destreg = tmp;
- } else {
- u16 *destreg, *srcreg;
- u16 tmp;
-
- destreg = DECODE_RM_WORD_REGISTER(rl);
- DECODE_PRINTF(",");
- srcreg = DECODE_RM_WORD_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- tmp = *srcreg;
- *srcreg = *destreg;
- *destreg = tmp;
- }
- break;
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ int mod, rl, rh;
+ uint destoffset;
+
+ START_OF_INSTR();
+ DECODE_PRINTF("XCHG\t");
+ FETCH_DECODE_MODRM(mod, rh, rl);
+ if (mod < 3) {
+ destoffset = decode_rmXX_address(mod, rl);
+ DECODE_PRINTF(",");
+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+ u32 *srcreg;
+ u32 destval,tmp;
+
+ destval = fetch_data_long(destoffset);
+ srcreg = DECODE_RM_LONG_REGISTER(rh);
+ DECODE_PRINTF("\n");
+ TRACE_AND_STEP();
+ tmp = *srcreg;
+ *srcreg = destval;
+ destval = tmp;
+ store_data_long(destoffset, destval);
+ } else {
+ u16 *srcreg;
+ u16 destval,tmp;
+
+ destval = fetch_data_word(destoffset);
+ srcreg = DECODE_RM_WORD_REGISTER(rh);
+ DECODE_PRINTF("\n");
+ TRACE_AND_STEP();
+ tmp = *srcreg;
+ *srcreg = destval;
+ destval = tmp;
+ store_data_word(destoffset, destval);
+ }
+ } else { /* register to register */
+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+ u32 *destreg,*srcreg;
+ u32 tmp;
+
+ destreg = DECODE_RM_LONG_REGISTER(rl);
+ DECODE_PRINTF(",");
+ srcreg = DECODE_RM_LONG_REGISTER(rh);
+ DECODE_PRINTF("\n");
+ TRACE_AND_STEP();
+ tmp = *srcreg;
+ *srcreg = *destreg;
+ *destreg = tmp;
+ } else {
+ u16 *destreg,*srcreg;
+ u16 tmp;
+
+ destreg = DECODE_RM_WORD_REGISTER(rl);
+ DECODE_PRINTF(",");
+ srcreg = DECODE_RM_WORD_REGISTER(rh);
+ DECODE_PRINTF("\n");
+ TRACE_AND_STEP();
+ tmp = *srcreg;
+ *srcreg = *destreg;
+ *destreg = tmp;
+ }
+ }
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/****************************************************************************
@@ -6168,49 +1849,30 @@ Handles opcode 0x88
****************************************************************************/
void x86emuOp_mov_byte_RM_R(u8 X86EMU_UNUSED(op1))
{
- int mod, rl, rh;
- u8 *destreg, *srcreg;
- uint destoffset;
-
- START_OF_INSTR();
- DECODE_PRINTF("MOV\t");
- FETCH_DECODE_MODRM(mod, rh, rl);
- switch (mod) {
- case 0:
- destoffset = decode_rm00_address(rl);
- DECODE_PRINTF(",");
- srcreg = DECODE_RM_BYTE_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- store_data_byte(destoffset, *srcreg);
- break;
- case 1:
- destoffset = decode_rm01_address(rl);
- DECODE_PRINTF(",");
- srcreg = DECODE_RM_BYTE_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- store_data_byte(destoffset, *srcreg);
- break;
- case 2:
- destoffset = decode_rm10_address(rl);
- DECODE_PRINTF(",");
- srcreg = DECODE_RM_BYTE_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- store_data_byte(destoffset, *srcreg);
- break;
- case 3: /* register to register */
- destreg = DECODE_RM_BYTE_REGISTER(rl);
- DECODE_PRINTF(",");
- srcreg = DECODE_RM_BYTE_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = *srcreg;
- break;
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ int mod, rl, rh;
+ u8 *destreg, *srcreg;
+ uint destoffset;
+
+ START_OF_INSTR();
+ DECODE_PRINTF("MOV\t");
+ FETCH_DECODE_MODRM(mod, rh, rl);
+ if (mod < 3) {
+ destoffset = decode_rmXX_address(mod, rl);
+ DECODE_PRINTF(",");
+ srcreg = DECODE_RM_BYTE_REGISTER(rh);
+ DECODE_PRINTF("\n");
+ TRACE_AND_STEP();
+ store_data_byte(destoffset, *srcreg);
+ } else { /* register to register */
+ destreg = DECODE_RM_BYTE_REGISTER(rl);
+ DECODE_PRINTF(",");
+ srcreg = DECODE_RM_BYTE_REGISTER(rh);
+ DECODE_PRINTF("\n");
+ TRACE_AND_STEP();
+ *destreg = *srcreg;
+ }
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/****************************************************************************
@@ -6219,100 +1881,54 @@ Handles opcode 0x89
****************************************************************************/
void x86emuOp_mov_word_RM_R(u8 X86EMU_UNUSED(op1))
{
- int mod, rl, rh;
- uint destoffset;
-
- START_OF_INSTR();
- DECODE_PRINTF("MOV\t");
- FETCH_DECODE_MODRM(mod, rh, rl);
- switch (mod) {
- case 0:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 *srcreg;
-
- destoffset = decode_rm00_address(rl);
- DECODE_PRINTF(",");
- srcreg = DECODE_RM_LONG_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- store_data_long(destoffset, *srcreg);
- } else {
- u16 *srcreg;
-
- destoffset = decode_rm00_address(rl);
- DECODE_PRINTF(",");
- srcreg = DECODE_RM_WORD_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- store_data_word(destoffset, *srcreg);
- }
- break;
- case 1:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 *srcreg;
-
- destoffset = decode_rm01_address(rl);
- DECODE_PRINTF(",");
- srcreg = DECODE_RM_LONG_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- store_data_long(destoffset, *srcreg);
- } else {
- u16 *srcreg;
-
- destoffset = decode_rm01_address(rl);
- DECODE_PRINTF(",");
- srcreg = DECODE_RM_WORD_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- store_data_word(destoffset, *srcreg);
- }
- break;
- case 2:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 *srcreg;
-
- destoffset = decode_rm10_address(rl);
- DECODE_PRINTF(",");
- srcreg = DECODE_RM_LONG_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- store_data_long(destoffset, *srcreg);
- } else {
- u16 *srcreg;
-
- destoffset = decode_rm10_address(rl);
- DECODE_PRINTF(",");
- srcreg = DECODE_RM_WORD_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- store_data_word(destoffset, *srcreg);
- }
- break;
- case 3: /* register to register */
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 *destreg, *srcreg;
-
- destreg = DECODE_RM_LONG_REGISTER(rl);
- DECODE_PRINTF(",");
- srcreg = DECODE_RM_LONG_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = *srcreg;
- } else {
- u16 *destreg, *srcreg;
-
- destreg = DECODE_RM_WORD_REGISTER(rl);
- DECODE_PRINTF(",");
- srcreg = DECODE_RM_WORD_REGISTER(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = *srcreg;
- }
- break;
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ int mod, rl, rh;
+ uint destoffset;
+
+ START_OF_INSTR();
+ DECODE_PRINTF("MOV\t");
+ FETCH_DECODE_MODRM(mod, rh, rl);
+ if (mod < 3) {
+ destoffset = decode_rmXX_address(mod, rl);
+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+ u32 *srcreg;
+
+ DECODE_PRINTF(",");
+ srcreg = DECODE_RM_LONG_REGISTER(rh);
+ DECODE_PRINTF("\n");
+ TRACE_AND_STEP();
+ store_data_long(destoffset, *srcreg);
+ } else {
+ u16 *srcreg;
+
+ DECODE_PRINTF(",");
+ srcreg = DECODE_RM_WORD_REGISTER(rh);
+ DECODE_PRINTF("\n");
+ TRACE_AND_STEP();
+ store_data_word(destoffset, *srcreg);
+ }
+ } else { /* register to register */
+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+ u32 *destreg,*srcreg;
+
+ destreg = DECODE_RM_LONG_REGISTER(rl);
+ DECODE_PRINTF(",");
+ srcreg = DECODE_RM_LONG_REGISTER(rh);
+ DECODE_PRINTF("\n");
+ TRACE_AND_STEP();
+ *destreg = *srcreg;
+ } else {
+ u16 *destreg,*srcreg;
+
+ destreg = DECODE_RM_WORD_REGISTER(rl);
+ DECODE_PRINTF(",");
+ srcreg = DECODE_RM_WORD_REGISTER(rh);
+ DECODE_PRINTF("\n");
+ TRACE_AND_STEP();
+ *destreg = *srcreg;
+ }
+ }
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/****************************************************************************
@@ -6321,53 +1937,32 @@ Handles opcode 0x8a
****************************************************************************/
void x86emuOp_mov_byte_R_RM(u8 X86EMU_UNUSED(op1))
{
- int mod, rl, rh;
- u8 *destreg, *srcreg;
- uint srcoffset;
- u8 srcval;
-
- START_OF_INSTR();
- DECODE_PRINTF("MOV\t");
- FETCH_DECODE_MODRM(mod, rh, rl);
- switch (mod) {
- case 0:
- destreg = DECODE_RM_BYTE_REGISTER(rh);
- DECODE_PRINTF(",");
- srcoffset = decode_rm00_address(rl);
- srcval = fetch_data_byte(srcoffset);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = srcval;
- break;
- case 1:
- destreg = DECODE_RM_BYTE_REGISTER(rh);
- DECODE_PRINTF(",");
- srcoffset = decode_rm01_address(rl);
- srcval = fetch_data_byte(srcoffset);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = srcval;
- break;
- case 2:
- destreg = DECODE_RM_BYTE_REGISTER(rh);
- DECODE_PRINTF(",");
- srcoffset = decode_rm10_address(rl);
- srcval = fetch_data_byte(srcoffset);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = srcval;
- break;
- case 3: /* register to register */
- destreg = DECODE_RM_BYTE_REGISTER(rh);
- DECODE_PRINTF(",");
- srcreg = DECODE_RM_BYTE_REGISTER(rl);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = *srcreg;
- break;
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ int mod, rl, rh;
+ u8 *destreg, *srcreg;
+ uint srcoffset;
+ u8 srcval;
+
+ START_OF_INSTR();
+ DECODE_PRINTF("MOV\t");
+ FETCH_DECODE_MODRM(mod, rh, rl);
+ if (mod < 3) {
+ destreg = DECODE_RM_BYTE_REGISTER(rh);
+ DECODE_PRINTF(",");
+ srcoffset = decode_rmXX_address(mod, rl);
+ srcval = fetch_data_byte(srcoffset);
+ DECODE_PRINTF("\n");
+ TRACE_AND_STEP();
+ *destreg = srcval;
+ } else { /* register to register */
+ destreg = DECODE_RM_BYTE_REGISTER(rh);
+ DECODE_PRINTF(",");
+ srcreg = DECODE_RM_BYTE_REGISTER(rl);
+ DECODE_PRINTF("\n");
+ TRACE_AND_STEP();
+ *destreg = *srcreg;
+ }
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/****************************************************************************
@@ -6376,112 +1971,59 @@ Handles opcode 0x8b
****************************************************************************/
void x86emuOp_mov_word_R_RM(u8 X86EMU_UNUSED(op1))
{
- int mod, rl, rh;
- uint srcoffset;
-
- START_OF_INSTR();
- DECODE_PRINTF("MOV\t");
- FETCH_DECODE_MODRM(mod, rh, rl);
- switch (mod) {
- case 0:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 *destreg;
- u32 srcval;
-
- destreg = DECODE_RM_LONG_REGISTER(rh);
- DECODE_PRINTF(",");
- srcoffset = decode_rm00_address(rl);
- srcval = fetch_data_long(srcoffset);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = srcval;
- } else {
- u16 *destreg;
- u16 srcval;
-
- destreg = DECODE_RM_WORD_REGISTER(rh);
- DECODE_PRINTF(",");
- srcoffset = decode_rm00_address(rl);
- srcval = fetch_data_word(srcoffset);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = srcval;
- }
- break;
- case 1:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 *destreg;
- u32 srcval;
-
- destreg = DECODE_RM_LONG_REGISTER(rh);
- DECODE_PRINTF(",");
- srcoffset = decode_rm01_address(rl);
- srcval = fetch_data_long(srcoffset);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = srcval;
- } else {
- u16 *destreg;
- u16 srcval;
-
- destreg = DECODE_RM_WORD_REGISTER(rh);
- DECODE_PRINTF(",");
- srcoffset = decode_rm01_address(rl);
- srcval = fetch_data_word(srcoffset);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = srcval;
- }
- break;
- case 2:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 *destreg;
- u32 srcval;
-
- destreg = DECODE_RM_LONG_REGISTER(rh);
- DECODE_PRINTF(",");
- srcoffset = decode_rm10_address(rl);
- srcval = fetch_data_long(srcoffset);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = srcval;
- } else {
- u16 *destreg;
- u16 srcval;
-
- destreg = DECODE_RM_WORD_REGISTER(rh);
- DECODE_PRINTF(",");
- srcoffset = decode_rm10_address(rl);
- srcval = fetch_data_word(srcoffset);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = srcval;
- }
- break;
- case 3: /* register to register */
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 *destreg, *srcreg;
-
- destreg = DECODE_RM_LONG_REGISTER(rh);
- DECODE_PRINTF(",");
- srcreg = DECODE_RM_LONG_REGISTER(rl);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = *srcreg;
- } else {
- u16 *destreg, *srcreg;
-
- destreg = DECODE_RM_WORD_REGISTER(rh);
- DECODE_PRINTF(",");
- srcreg = DECODE_RM_WORD_REGISTER(rl);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = *srcreg;
- }
- break;
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ int mod, rl, rh;
+ uint srcoffset;
+
+ START_OF_INSTR();
+ DECODE_PRINTF("MOV\t");
+ FETCH_DECODE_MODRM(mod, rh, rl);
+ if (mod < 3) {
+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+ u32 *destreg;
+ u32 srcval;
+
+ destreg = DECODE_RM_LONG_REGISTER(rh);
+ DECODE_PRINTF(",");
+ srcoffset = decode_rmXX_address(mod, rl);
+ srcval = fetch_data_long(srcoffset);
+ DECODE_PRINTF("\n");
+ TRACE_AND_STEP();
+ *destreg = srcval;
+ } else {
+ u16 *destreg;
+ u16 srcval;
+
+ destreg = DECODE_RM_WORD_REGISTER(rh);
+ DECODE_PRINTF(",");
+ srcoffset = decode_rmXX_address(mod, rl);
+ srcval = fetch_data_word(srcoffset);
+ DECODE_PRINTF("\n");
+ TRACE_AND_STEP();
+ *destreg = srcval;
+ }
+ } else { /* register to register */
+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+ u32 *destreg, *srcreg;
+
+ destreg = DECODE_RM_LONG_REGISTER(rh);
+ DECODE_PRINTF(",");
+ srcreg = DECODE_RM_LONG_REGISTER(rl);
+ DECODE_PRINTF("\n");
+ TRACE_AND_STEP();
+ *destreg = *srcreg;
+ } else {
+ u16 *destreg, *srcreg;
+
+ destreg = DECODE_RM_WORD_REGISTER(rh);
+ DECODE_PRINTF(",");
+ srcreg = DECODE_RM_WORD_REGISTER(rl);
+ DECODE_PRINTF("\n");
+ TRACE_AND_STEP();
+ *destreg = *srcreg;
+ }
+ }
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/****************************************************************************
@@ -6490,53 +2032,32 @@ Handles opcode 0x8c
****************************************************************************/
void x86emuOp_mov_word_RM_SR(u8 X86EMU_UNUSED(op1))
{
- int mod, rl, rh;
- u16 *destreg, *srcreg;
- uint destoffset;
- u16 destval;
-
- START_OF_INSTR();
- DECODE_PRINTF("MOV\t");
- FETCH_DECODE_MODRM(mod, rh, rl);
- switch (mod) {
- case 0:
- destoffset = decode_rm00_address(rl);
- DECODE_PRINTF(",");
- srcreg = decode_rm_seg_register(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- destval = *srcreg;
- store_data_word(destoffset, destval);
- break;
- case 1:
- destoffset = decode_rm01_address(rl);
- DECODE_PRINTF(",");
- srcreg = decode_rm_seg_register(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- destval = *srcreg;
- store_data_word(destoffset, destval);
- break;
- case 2:
- destoffset = decode_rm10_address(rl);
- DECODE_PRINTF(",");
- srcreg = decode_rm_seg_register(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- destval = *srcreg;
- store_data_word(destoffset, destval);
- break;
- case 3: /* register to register */
- destreg = DECODE_RM_WORD_REGISTER(rl);
- DECODE_PRINTF(",");
- srcreg = decode_rm_seg_register(rh);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = *srcreg;
- break;
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ int mod, rl, rh;
+ u16 *destreg, *srcreg;
+ uint destoffset;
+ u16 destval;
+
+ START_OF_INSTR();
+ DECODE_PRINTF("MOV\t");
+ FETCH_DECODE_MODRM(mod, rh, rl);
+ if (mod < 3) {
+ destoffset = decode_rmXX_address(mod, rl);
+ DECODE_PRINTF(",");
+ srcreg = decode_rm_seg_register(rh);
+ DECODE_PRINTF("\n");
+ TRACE_AND_STEP();
+ destval = *srcreg;
+ store_data_word(destoffset, destval);
+ } else { /* register to register */
+ destreg = DECODE_RM_WORD_REGISTER(rl);
+ DECODE_PRINTF(",");
+ srcreg = decode_rm_seg_register(rh);
+ DECODE_PRINTF("\n");
+ TRACE_AND_STEP();
+ *destreg = *srcreg;
+ }
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/****************************************************************************
@@ -6545,9 +2066,9 @@ Handles opcode 0x8d
****************************************************************************/
void x86emuOp_lea_word_R_M(u8 X86EMU_UNUSED(op1))
{
- int mod, rl, rh;
- u16 *srcreg;
- uint destoffset;
+ int mod, rl, rh;
+ u16 *srcreg;
+ uint destoffset;
/*
* TODO: Need to handle address size prefix!
@@ -6555,40 +2076,20 @@ void x86emuOp_lea_word_R_M(u8 X86EMU_UNUSED(op1))
* 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;
- 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;
- 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;
- break;
- case 3: /* register to register */
- /* undefined. Do nothing. */
- break;
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ START_OF_INSTR();
+ DECODE_PRINTF("LEA\t");
+ FETCH_DECODE_MODRM(mod, rh, rl);
+ if (mod < 3) {
+ srcreg = DECODE_RM_WORD_REGISTER(rh);
+ DECODE_PRINTF(",");
+ destoffset = decode_rmXX_address(mod, rl);
+ DECODE_PRINTF("\n");
+ TRACE_AND_STEP();
+ *srcreg = (u16)destoffset;
+ }
+ /* } else { undefined. Do nothing. } */
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/****************************************************************************
@@ -6597,59 +2098,38 @@ Handles opcode 0x8e
****************************************************************************/
void x86emuOp_mov_word_SR_RM(u8 X86EMU_UNUSED(op1))
{
- int mod, rl, rh;
- u16 *destreg, *srcreg;
- uint srcoffset;
- u16 srcval;
-
- START_OF_INSTR();
- DECODE_PRINTF("MOV\t");
- FETCH_DECODE_MODRM(mod, rh, rl);
- switch (mod) {
- case 0:
- destreg = decode_rm_seg_register(rh);
- DECODE_PRINTF(",");
- srcoffset = decode_rm00_address(rl);
- srcval = fetch_data_word(srcoffset);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = srcval;
- break;
- case 1:
- destreg = decode_rm_seg_register(rh);
- DECODE_PRINTF(",");
- srcoffset = decode_rm01_address(rl);
- srcval = fetch_data_word(srcoffset);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = srcval;
- break;
- case 2:
- destreg = decode_rm_seg_register(rh);
- DECODE_PRINTF(",");
- srcoffset = decode_rm10_address(rl);
- srcval = fetch_data_word(srcoffset);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = srcval;
- break;
- case 3: /* register to register */
- destreg = decode_rm_seg_register(rh);
- DECODE_PRINTF(",");
- srcreg = DECODE_RM_WORD_REGISTER(rl);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = *srcreg;
- break;
- }
- /*
- * Clean up, and reset all the R_xSP pointers to the correct
- * locations. This is about 3x too much overhead (doing all the
- * segreg ptrs when only one is needed, but this instruction
- * *cannot* be that common, and this isn't too much work anyway.
- */
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ int mod, rl, rh;
+ u16 *destreg, *srcreg;
+ uint srcoffset;
+ u16 srcval;
+
+ START_OF_INSTR();
+ DECODE_PRINTF("MOV\t");
+ FETCH_DECODE_MODRM(mod, rh, rl);
+ if (mod < 3) {
+ destreg = decode_rm_seg_register(rh);
+ DECODE_PRINTF(",");
+ srcoffset = decode_rmXX_address(mod, rl);
+ srcval = fetch_data_word(srcoffset);
+ DECODE_PRINTF("\n");
+ TRACE_AND_STEP();
+ *destreg = srcval;
+ } else { /* register to register */
+ destreg = decode_rm_seg_register(rh);
+ DECODE_PRINTF(",");
+ srcreg = DECODE_RM_WORD_REGISTER(rl);
+ DECODE_PRINTF("\n");
+ TRACE_AND_STEP();
+ *destreg = *srcreg;
+ }
+ /*
+ * Clean up, and reset all the R_xSP pointers to the correct
+ * locations. This is about 3x too much overhead (doing all the
+ * segreg ptrs when only one is needed, but this instruction
+ * *cannot* be that common, and this isn't too much work anyway.
+ */
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/****************************************************************************
@@ -6658,94 +2138,52 @@ Handles opcode 0x8f
****************************************************************************/
void x86emuOp_pop_RM(u8 X86EMU_UNUSED(op1))
{
- int mod, rl, rh;
- uint destoffset;
-
- START_OF_INSTR();
- DECODE_PRINTF("POP\t");
- FETCH_DECODE_MODRM(mod, rh, rl);
- if (rh != 0) {
- DECODE_PRINTF("ILLEGAL DECODE OF OPCODE 8F\n");
- HALT_SYS();
- }
- switch (mod) {
- case 0:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 destval;
-
- destoffset = decode_rm00_address(rl);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- destval = pop_long();
- store_data_long(destoffset, destval);
- } else {
- u16 destval;
-
- destoffset = decode_rm00_address(rl);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- destval = pop_word();
- store_data_word(destoffset, destval);
- }
- break;
- case 1:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 destval;
-
- destoffset = decode_rm01_address(rl);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- destval = pop_long();
- store_data_long(destoffset, destval);
- } else {
- u16 destval;
-
- destoffset = decode_rm01_address(rl);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- destval = pop_word();
- store_data_word(destoffset, destval);
- }
- break;
- case 2:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 destval;
-
- destoffset = decode_rm10_address(rl);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- destval = pop_long();
- store_data_long(destoffset, destval);
- } else {
- u16 destval;
-
- destoffset = decode_rm10_address(rl);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- destval = pop_word();
- store_data_word(destoffset, destval);
- }
- break;
- case 3: /* register to register */
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 *destreg;
-
- destreg = DECODE_RM_LONG_REGISTER(rl);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = pop_long();
- } else {
- u16 *destreg;
-
- destreg = DECODE_RM_WORD_REGISTER(rl);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = pop_word();
- }
- break;
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ int mod, rl, rh;
+ uint destoffset;
+
+ START_OF_INSTR();
+ DECODE_PRINTF("POP\t");
+ FETCH_DECODE_MODRM(mod, rh, rl);
+ if (rh != 0) {
+ DECODE_PRINTF("ILLEGAL DECODE OF OPCODE 8F\n");
+ HALT_SYS();
+ }
+ if (mod < 3) {
+ destoffset = decode_rmXX_address(mod, rl);
+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+ u32 destval;
+
+ DECODE_PRINTF("\n");
+ TRACE_AND_STEP();
+ destval = pop_long();
+ store_data_long(destoffset, destval);
+ } else {
+ u16 destval;
+
+ DECODE_PRINTF("\n");
+ TRACE_AND_STEP();
+ destval = pop_word();
+ store_data_word(destoffset, destval);
+ }
+ } else { /* register to register */
+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+ u32 *destreg;
+
+ destreg = DECODE_RM_LONG_REGISTER(rl);
+ DECODE_PRINTF("\n");
+ TRACE_AND_STEP();
+ *destreg = pop_long();
+ } else {
+ u16 *destreg;
+
+ destreg = DECODE_RM_WORD_REGISTER(rl);
+ DECODE_PRINTF("\n");
+ TRACE_AND_STEP();
+ *destreg = pop_word();
+ }
+ }
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/****************************************************************************
@@ -6754,207 +2192,46 @@ Handles opcode 0x90
****************************************************************************/
void x86emuOp_nop(u8 X86EMU_UNUSED(op1))
{
- START_OF_INSTR();
- DECODE_PRINTF("NOP\n");
- TRACE_AND_STEP();
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ START_OF_INSTR();
+ DECODE_PRINTF("NOP\n");
+ TRACE_AND_STEP();
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/****************************************************************************
REMARKS:
-Handles opcode 0x91
+Handles opcode 0x91-0x97
****************************************************************************/
-void x86emuOp_xchg_word_AX_CX(u8 X86EMU_UNUSED(op1))
+void x86emuOp_xchg_word_AX_register(u8 X86EMU_UNUSED(op1))
{
- u32 tmp;
+ u32 tmp;
- START_OF_INSTR();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- DECODE_PRINTF("XCHG\tEAX,ECX\n");
- } else {
- DECODE_PRINTF("XCHG\tAX,CX\n");
- }
- TRACE_AND_STEP();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- tmp = M.x86.R_EAX;
- M.x86.R_EAX = M.x86.R_ECX;
- M.x86.R_ECX = tmp;
- } else {
- tmp = M.x86.R_AX;
- M.x86.R_AX = M.x86.R_CX;
- M.x86.R_CX = (u16) tmp;
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
-}
+ op1 &= 0x7;
-/****************************************************************************
-REMARKS:
-Handles opcode 0x92
-****************************************************************************/
-void x86emuOp_xchg_word_AX_DX(u8 X86EMU_UNUSED(op1))
-{
- u32 tmp;
+ START_OF_INSTR();
- START_OF_INSTR();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- DECODE_PRINTF("XCHG\tEAX,EDX\n");
- } else {
- DECODE_PRINTF("XCHG\tAX,DX\n");
- }
- TRACE_AND_STEP();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- tmp = M.x86.R_EAX;
- M.x86.R_EAX = M.x86.R_EDX;
- M.x86.R_EDX = tmp;
- } else {
- tmp = M.x86.R_AX;
- M.x86.R_AX = M.x86.R_DX;
- M.x86.R_DX = (u16) tmp;
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
-}
-
-/****************************************************************************
-REMARKS:
-Handles opcode 0x93
-****************************************************************************/
-void x86emuOp_xchg_word_AX_BX(u8 X86EMU_UNUSED(op1))
-{
- u32 tmp;
-
- START_OF_INSTR();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- DECODE_PRINTF("XCHG\tEAX,EBX\n");
- } else {
- DECODE_PRINTF("XCHG\tAX,BX\n");
- }
- TRACE_AND_STEP();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- tmp = M.x86.R_EAX;
- M.x86.R_EAX = M.x86.R_EBX;
- M.x86.R_EBX = tmp;
- } else {
- tmp = M.x86.R_AX;
- M.x86.R_AX = M.x86.R_BX;
- M.x86.R_BX = (u16) tmp;
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
-}
-
-/****************************************************************************
-REMARKS:
-Handles opcode 0x94
-****************************************************************************/
-void x86emuOp_xchg_word_AX_SP(u8 X86EMU_UNUSED(op1))
-{
- u32 tmp;
-
- START_OF_INSTR();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- DECODE_PRINTF("XCHG\tEAX,ESP\n");
- } else {
- DECODE_PRINTF("XCHG\tAX,SP\n");
- }
- TRACE_AND_STEP();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- tmp = M.x86.R_EAX;
- M.x86.R_EAX = M.x86.R_ESP;
- M.x86.R_ESP = tmp;
- } else {
- tmp = M.x86.R_AX;
- M.x86.R_AX = M.x86.R_SP;
- M.x86.R_SP = (u16) tmp;
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
-}
-
-/****************************************************************************
-REMARKS:
-Handles opcode 0x95
-****************************************************************************/
-void x86emuOp_xchg_word_AX_BP(u8 X86EMU_UNUSED(op1))
-{
- u32 tmp;
-
- START_OF_INSTR();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- DECODE_PRINTF("XCHG\tEAX,EBP\n");
- } else {
- DECODE_PRINTF("XCHG\tAX,BP\n");
- }
- TRACE_AND_STEP();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- tmp = M.x86.R_EAX;
- M.x86.R_EAX = M.x86.R_EBP;
- M.x86.R_EBP = tmp;
- } else {
- tmp = M.x86.R_AX;
- M.x86.R_AX = M.x86.R_BP;
- M.x86.R_BP = (u16) tmp;
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
-}
-
-/****************************************************************************
-REMARKS:
-Handles opcode 0x96
-****************************************************************************/
-void x86emuOp_xchg_word_AX_SI(u8 X86EMU_UNUSED(op1))
-{
- u32 tmp;
-
- START_OF_INSTR();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- DECODE_PRINTF("XCHG\tEAX,ESI\n");
- } else {
- DECODE_PRINTF("XCHG\tAX,SI\n");
- }
- TRACE_AND_STEP();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- tmp = M.x86.R_EAX;
- M.x86.R_EAX = M.x86.R_ESI;
- M.x86.R_ESI = tmp;
- } else {
- tmp = M.x86.R_AX;
- M.x86.R_AX = M.x86.R_SI;
- M.x86.R_SI = (u16) tmp;
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
-}
-
-/****************************************************************************
-REMARKS:
-Handles opcode 0x97
-****************************************************************************/
-void x86emuOp_xchg_word_AX_DI(u8 X86EMU_UNUSED(op1))
-{
- u32 tmp;
-
- START_OF_INSTR();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- DECODE_PRINTF("XCHG\tEAX,EDI\n");
- } else {
- DECODE_PRINTF("XCHG\tAX,DI\n");
- }
- TRACE_AND_STEP();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- tmp = M.x86.R_EAX;
- M.x86.R_EAX = M.x86.R_EDI;
- M.x86.R_EDI = tmp;
- } else {
- tmp = M.x86.R_AX;
- M.x86.R_AX = M.x86.R_DI;
- M.x86.R_DI = (u16) tmp;
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+ u32 *reg32;
+ DECODE_PRINTF("XCHG\tEAX,");
+ reg32 = DECODE_RM_LONG_REGISTER(op1);
+ DECODE_PRINTF("\n");
+ TRACE_AND_STEP();
+ tmp = M.x86.R_EAX;
+ M.x86.R_EAX = *reg32;
+ *reg32 = tmp;
+ } else {
+ u16 *reg16;
+ DECODE_PRINTF("XCHG\tAX,");
+ reg16 = DECODE_RM_WORD_REGISTER(op1);
+ DECODE_PRINTF("\n");
+ TRACE_AND_STEP();
+ tmp = M.x86.R_AX;
+ M.x86.R_EAX = *reg16;
+ *reg16 = (u16)tmp;
+ }
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/****************************************************************************
@@ -6963,28 +2240,28 @@ Handles opcode 0x98
****************************************************************************/
void x86emuOp_cbw(u8 X86EMU_UNUSED(op1))
{
- START_OF_INSTR();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- DECODE_PRINTF("CWDE\n");
- } else {
- DECODE_PRINTF("CBW\n");
- }
- TRACE_AND_STEP();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- if (M.x86.R_AX & 0x8000) {
- M.x86.R_EAX |= 0xffff0000;
- } else {
- M.x86.R_EAX &= 0x0000ffff;
- }
- } else {
- if (M.x86.R_AL & 0x80) {
- M.x86.R_AH = 0xff;
- } else {
- M.x86.R_AH = 0x0;
- }
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ START_OF_INSTR();
+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+ DECODE_PRINTF("CWDE\n");
+ } else {
+ DECODE_PRINTF("CBW\n");
+ }
+ TRACE_AND_STEP();
+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+ if (M.x86.R_AX & 0x8000) {
+ M.x86.R_EAX |= 0xffff0000;
+ } else {
+ M.x86.R_EAX &= 0x0000ffff;
+ }
+ } else {
+ if (M.x86.R_AL & 0x80) {
+ M.x86.R_AH = 0xff;
+ } else {
+ M.x86.R_AH = 0x0;
+ }
+ }
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/****************************************************************************
@@ -6993,29 +2270,29 @@ Handles opcode 0x99
****************************************************************************/
void x86emuOp_cwd(u8 X86EMU_UNUSED(op1))
{
- START_OF_INSTR();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- DECODE_PRINTF("CDQ\n");
- } else {
- DECODE_PRINTF("CWD\n");
- }
- DECODE_PRINTF("CWD\n");
- TRACE_AND_STEP();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- if (M.x86.R_EAX & 0x80000000) {
- M.x86.R_EDX = 0xffffffff;
- } else {
- M.x86.R_EDX = 0x0;
- }
- } else {
- if (M.x86.R_AX & 0x8000) {
- M.x86.R_DX = 0xffff;
- } else {
- M.x86.R_DX = 0x0;
- }
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ START_OF_INSTR();
+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+ DECODE_PRINTF("CDQ\n");
+ } else {
+ DECODE_PRINTF("CWD\n");
+ }
+ DECODE_PRINTF("CWD\n");
+ TRACE_AND_STEP();
+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+ if (M.x86.R_EAX & 0x80000000) {
+ M.x86.R_EDX = 0xffffffff;
+ } else {
+ M.x86.R_EDX = 0x0;
+ }
+ } else {
+ if (M.x86.R_AX & 0x8000) {
+ M.x86.R_DX = 0xffff;
+ } else {
+ M.x86.R_DX = 0x0;
+ }
+ }
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/****************************************************************************
@@ -7024,9 +2301,9 @@ Handles opcode 0x9a
****************************************************************************/
void x86emuOp_call_far_IMM(u8 X86EMU_UNUSED(op1))
{
- u16 farseg, faroff;
+ u16 farseg, faroff;
- START_OF_INSTR();
+ START_OF_INSTR();
DECODE_PRINTF("CALL\t");
faroff = fetch_word_imm();
farseg = fetch_word_imm();
@@ -7034,19 +2311,19 @@ void x86emuOp_call_far_IMM(u8 X86EMU_UNUSED(op1))
DECODE_PRINTF2("%04x\n", faroff);
CALL_TRACE(M.x86.saved_cs, M.x86.saved_ip, farseg, faroff, "FAR ");
- /* XXX
- *
- * Hooked interrupt vectors calling into our "BIOS" will cause
- * problems unless all intersegment stuff is checked for BIOS
- * access. Check needed here. For moment, let it alone.
- */
- 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;
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ /* XXX
+ *
+ * Hooked interrupt vectors calling into our "BIOS" will cause
+ * problems unless all intersegment stuff is checked for BIOS
+ * access. Check needed here. For moment, let it alone.
+ */
+ 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;
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/****************************************************************************
@@ -7055,12 +2332,12 @@ Handles opcode 0x9b
****************************************************************************/
void x86emuOp_wait(u8 X86EMU_UNUSED(op1))
{
- START_OF_INSTR();
- DECODE_PRINTF("WAIT");
- TRACE_AND_STEP();
- /* NADA. */
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ START_OF_INSTR();
+ DECODE_PRINTF("WAIT");
+ TRACE_AND_STEP();
+ /* NADA. */
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/****************************************************************************
@@ -7069,25 +2346,25 @@ Handles opcode 0x9c
****************************************************************************/
void x86emuOp_pushf_word(u8 X86EMU_UNUSED(op1))
{
- u32 flags;
+ u32 flags;
- START_OF_INSTR();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- DECODE_PRINTF("PUSHFD\n");
- } else {
- DECODE_PRINTF("PUSHF\n");
- }
- TRACE_AND_STEP();
+ START_OF_INSTR();
+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+ DECODE_PRINTF("PUSHFD\n");
+ } else {
+ DECODE_PRINTF("PUSHF\n");
+ }
+ TRACE_AND_STEP();
- /* clear out *all* bits not representing flags, and turn on real bits */
- flags = (M.x86.R_EFLG & F_MSK) | F_ALWAYS_ON;
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- push_long(flags);
- } else {
- push_word((u16) flags);
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ /* clear out *all* bits not representing flags, and turn on real bits */
+ flags = (M.x86.R_EFLG & F_MSK) | F_ALWAYS_ON;
+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+ push_long(flags);
+ } else {
+ push_word((u16)flags);
+ }
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/****************************************************************************
@@ -7096,20 +2373,20 @@ Handles opcode 0x9d
****************************************************************************/
void x86emuOp_popf_word(u8 X86EMU_UNUSED(op1))
{
- START_OF_INSTR();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- DECODE_PRINTF("POPFD\n");
- } else {
- DECODE_PRINTF("POPF\n");
- }
- TRACE_AND_STEP();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- M.x86.R_EFLG = pop_long();
- } else {
- M.x86.R_FLG = pop_word();
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ START_OF_INSTR();
+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+ DECODE_PRINTF("POPFD\n");
+ } else {
+ DECODE_PRINTF("POPF\n");
+ }
+ TRACE_AND_STEP();
+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+ M.x86.R_EFLG = pop_long();
+ } else {
+ M.x86.R_FLG = pop_word();
+ }
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/****************************************************************************
@@ -7118,15 +2395,15 @@ Handles opcode 0x9e
****************************************************************************/
void x86emuOp_sahf(u8 X86EMU_UNUSED(op1))
{
- START_OF_INSTR();
- DECODE_PRINTF("SAHF\n");
- TRACE_AND_STEP();
- /* clear the lower bits of the flag register */
- M.x86.R_FLG &= 0xffffff00;
- /* or in the AH register into the flags register */
- M.x86.R_FLG |= M.x86.R_AH;
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ START_OF_INSTR();
+ DECODE_PRINTF("SAHF\n");
+ TRACE_AND_STEP();
+ /* clear the lower bits of the flag register */
+ M.x86.R_FLG &= 0xffffff00;
+ /* or in the AH register into the flags register */
+ M.x86.R_FLG |= M.x86.R_AH;
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/****************************************************************************
@@ -7135,15 +2412,15 @@ Handles opcode 0x9f
****************************************************************************/
void x86emuOp_lahf(u8 X86EMU_UNUSED(op1))
{
- START_OF_INSTR();
- DECODE_PRINTF("LAHF\n");
- TRACE_AND_STEP();
- M.x86.R_AH = (u8) (M.x86.R_FLG & 0xff);
- /*undocumented TC++ behavior??? Nope. It's documented, but
- you have too look real hard to notice it. */
- M.x86.R_AH |= 0x2;
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ START_OF_INSTR();
+ DECODE_PRINTF("LAHF\n");
+ TRACE_AND_STEP();
+ M.x86.R_AH = (u8)(M.x86.R_FLG & 0xff);
+ /*undocumented TC++ behavior??? Nope. It's documented, but
+ you have too look real hard to notice it. */
+ M.x86.R_AH |= 0x2;
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/****************************************************************************
@@ -7152,16 +2429,16 @@ Handles opcode 0xa0
****************************************************************************/
void x86emuOp_mov_AL_M_IMM(u8 X86EMU_UNUSED(op1))
{
- u16 offset;
+ u16 offset;
- START_OF_INSTR();
- DECODE_PRINTF("MOV\tAL,");
- offset = fetch_word_imm();
- DECODE_PRINTF2("[%04x]\n", offset);
- TRACE_AND_STEP();
- M.x86.R_AL = fetch_data_byte(offset);
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ START_OF_INSTR();
+ DECODE_PRINTF("MOV\tAL,");
+ offset = fetch_word_imm();
+ DECODE_PRINTF2("[%04x]\n", offset);
+ TRACE_AND_STEP();
+ M.x86.R_AL = fetch_data_byte(offset);
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/****************************************************************************
@@ -7170,23 +2447,23 @@ Handles opcode 0xa1
****************************************************************************/
void x86emuOp_mov_AX_M_IMM(u8 X86EMU_UNUSED(op1))
{
- u16 offset;
+ u16 offset;
- START_OF_INSTR();
- offset = fetch_word_imm();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- DECODE_PRINTF2("MOV\tEAX,[%04x]\n", offset);
- } else {
- DECODE_PRINTF2("MOV\tAX,[%04x]\n", offset);
- }
- TRACE_AND_STEP();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- M.x86.R_EAX = fetch_data_long(offset);
- } else {
- M.x86.R_AX = fetch_data_word(offset);
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ START_OF_INSTR();
+ offset = fetch_word_imm();
+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+ DECODE_PRINTF2("MOV\tEAX,[%04x]\n", offset);
+ } else {
+ DECODE_PRINTF2("MOV\tAX,[%04x]\n", offset);
+ }
+ TRACE_AND_STEP();
+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+ M.x86.R_EAX = fetch_data_long(offset);
+ } else {
+ M.x86.R_AX = fetch_data_word(offset);
+ }
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/****************************************************************************
@@ -7195,16 +2472,16 @@ Handles opcode 0xa2
****************************************************************************/
void x86emuOp_mov_M_AL_IMM(u8 X86EMU_UNUSED(op1))
{
- u16 offset;
+ u16 offset;
- START_OF_INSTR();
- DECODE_PRINTF("MOV\t");
- offset = fetch_word_imm();
- DECODE_PRINTF2("[%04x],AL\n", offset);
- TRACE_AND_STEP();
- store_data_byte(offset, M.x86.R_AL);
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ START_OF_INSTR();
+ DECODE_PRINTF("MOV\t");
+ offset = fetch_word_imm();
+ DECODE_PRINTF2("[%04x],AL\n", offset);
+ TRACE_AND_STEP();
+ store_data_byte(offset, M.x86.R_AL);
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/****************************************************************************
@@ -7213,23 +2490,23 @@ Handles opcode 0xa3
****************************************************************************/
void x86emuOp_mov_M_AX_IMM(u8 X86EMU_UNUSED(op1))
{
- u16 offset;
+ u16 offset;
- START_OF_INSTR();
- offset = fetch_word_imm();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- DECODE_PRINTF2("MOV\t[%04x],EAX\n", offset);
- } else {
- DECODE_PRINTF2("MOV\t[%04x],AX\n", offset);
- }
- TRACE_AND_STEP();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- store_data_long(offset, M.x86.R_EAX);
- } else {
- store_data_word(offset, M.x86.R_AX);
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ START_OF_INSTR();
+ offset = fetch_word_imm();
+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+ DECODE_PRINTF2("MOV\t[%04x],EAX\n", offset);
+ } else {
+ DECODE_PRINTF2("MOV\t[%04x],AX\n", offset);
+ }
+ TRACE_AND_STEP();
+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+ store_data_long(offset, M.x86.R_EAX);
+ } else {
+ store_data_word(offset, M.x86.R_AX);
+ }
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/****************************************************************************
@@ -7238,33 +2515,33 @@ Handles opcode 0xa4
****************************************************************************/
void x86emuOp_movs_byte(u8 X86EMU_UNUSED(op1))
{
- u8 val;
- u32 count;
- int inc;
-
- START_OF_INSTR();
- DECODE_PRINTF("MOVS\tBYTE\n");
- if (ACCESS_FLAG(F_DF)) /* down */
- inc = -1;
- else
- inc = 1;
- TRACE_AND_STEP();
- count = 1;
- if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
- /* dont care whether REPE or REPNE */
- /* move them until CX is ZERO. */
- count = M.x86.R_CX;
- M.x86.R_CX = 0;
- M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
- }
- while (count--) {
- val = fetch_data_byte(M.x86.R_SI);
- store_data_byte_abs(M.x86.R_ES, M.x86.R_DI, val);
- M.x86.R_SI += inc;
- M.x86.R_DI += inc;
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ u8 val;
+ u32 count;
+ int inc;
+
+ START_OF_INSTR();
+ DECODE_PRINTF("MOVS\tBYTE\n");
+ if (ACCESS_FLAG(F_DF)) /* down */
+ inc = -1;
+ else
+ inc = 1;
+ TRACE_AND_STEP();
+ count = 1;
+ if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
+ /* dont care whether REPE or REPNE */
+ /* move them until CX is ZERO. */
+ count = M.x86.R_CX;
+ M.x86.R_CX = 0;
+ M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
+ }
+ while (count--) {
+ val = fetch_data_byte(M.x86.R_SI);
+ store_data_byte_abs(M.x86.R_ES, M.x86.R_DI, val);
+ M.x86.R_SI += inc;
+ M.x86.R_DI += inc;
+ }
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/****************************************************************************
@@ -7273,46 +2550,46 @@ Handles opcode 0xa5
****************************************************************************/
void x86emuOp_movs_word(u8 X86EMU_UNUSED(op1))
{
- u32 val;
- int inc;
- u32 count;
-
- START_OF_INSTR();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- DECODE_PRINTF("MOVS\tDWORD\n");
- if (ACCESS_FLAG(F_DF)) /* down */
- inc = -4;
- else
- inc = 4;
- } else {
- DECODE_PRINTF("MOVS\tWORD\n");
- if (ACCESS_FLAG(F_DF)) /* down */
- inc = -2;
- else
- inc = 2;
- }
- TRACE_AND_STEP();
- count = 1;
- if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
- /* dont care whether REPE or REPNE */
- /* move them until CX is ZERO. */
- count = M.x86.R_CX;
- M.x86.R_CX = 0;
- M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
- }
- while (count--) {
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- val = fetch_data_long(M.x86.R_SI);
- store_data_long_abs(M.x86.R_ES, M.x86.R_DI, val);
- } else {
- val = fetch_data_word(M.x86.R_SI);
- store_data_word_abs(M.x86.R_ES, M.x86.R_DI, (u16) val);
- }
- M.x86.R_SI += inc;
- M.x86.R_DI += inc;
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ u32 val;
+ int inc;
+ u32 count;
+
+ START_OF_INSTR();
+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+ DECODE_PRINTF("MOVS\tDWORD\n");
+ if (ACCESS_FLAG(F_DF)) /* down */
+ inc = -4;
+ else
+ inc = 4;
+ } else {
+ DECODE_PRINTF("MOVS\tWORD\n");
+ if (ACCESS_FLAG(F_DF)) /* down */
+ inc = -2;
+ else
+ inc = 2;
+ }
+ TRACE_AND_STEP();
+ count = 1;
+ if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
+ /* dont care whether REPE or REPNE */
+ /* move them until CX is ZERO. */
+ count = M.x86.R_CX;
+ M.x86.R_CX = 0;
+ M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
+ }
+ while (count--) {
+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+ val = fetch_data_long(M.x86.R_SI);
+ store_data_long_abs(M.x86.R_ES, M.x86.R_DI, val);
+ } else {
+ val = fetch_data_word(M.x86.R_SI);
+ store_data_word_abs(M.x86.R_ES, M.x86.R_DI, (u16)val);
+ }
+ M.x86.R_SI += inc;
+ M.x86.R_DI += inc;
+ }
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/****************************************************************************
@@ -7321,54 +2598,40 @@ Handles opcode 0xa6
****************************************************************************/
void x86emuOp_cmps_byte(u8 X86EMU_UNUSED(op1))
{
- s8 val1, val2;
- int inc;
-
- START_OF_INSTR();
- DECODE_PRINTF("CMPS\tBYTE\n");
- TRACE_AND_STEP();
- if (ACCESS_FLAG(F_DF)) /* down */
- inc = -1;
- else
- inc = 1;
-
- if (M.x86.mode & SYSMODE_PREFIX_REPE) {
- /* REPE */
- /* move them until CX is ZERO. */
- while (M.x86.R_CX != 0) {
- val1 = fetch_data_byte(M.x86.R_SI);
- val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
- cmp_byte(val1, val2);
- M.x86.R_CX -= 1;
- M.x86.R_SI += inc;
- M.x86.R_DI += inc;
- if (ACCESS_FLAG(F_ZF) == 0)
- break;
- }
- M.x86.mode &= ~SYSMODE_PREFIX_REPE;
- } else if (M.x86.mode & SYSMODE_PREFIX_REPNE) {
- /* REPNE */
- /* move them until CX is ZERO. */
- while (M.x86.R_CX != 0) {
- val1 = fetch_data_byte(M.x86.R_SI);
- val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
- cmp_byte(val1, val2);
- M.x86.R_CX -= 1;
- M.x86.R_SI += inc;
- M.x86.R_DI += inc;
- if (ACCESS_FLAG(F_ZF))
- break; /* zero flag set means equal */
- }
- M.x86.mode &= ~SYSMODE_PREFIX_REPNE;
- } else {
- val1 = fetch_data_byte(M.x86.R_SI);
- val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
- cmp_byte(val1, val2);
- M.x86.R_SI += inc;
- M.x86.R_DI += inc;
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ s8 val1, val2;
+ int inc;
+
+ START_OF_INSTR();
+ DECODE_PRINTF("CMPS\tBYTE\n");
+ TRACE_AND_STEP();
+ if (ACCESS_FLAG(F_DF)) /* down */
+ inc = -1;
+ else
+ inc = 1;
+
+ if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
+ /* REPE */
+ /* move them until CX is ZERO. */
+ while (M.x86.R_CX != 0) {
+ val1 = fetch_data_byte(M.x86.R_SI);
+ val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
+ cmp_byte(val1, val2);
+ M.x86.R_CX -= 1;
+ M.x86.R_SI += inc;
+ M.x86.R_DI += inc;
+ if ( (M.x86.mode & SYSMODE_PREFIX_REPE) && (ACCESS_FLAG(F_ZF) == 0) ) break;
+ if ( (M.x86.mode & SYSMODE_PREFIX_REPNE) && ACCESS_FLAG(F_ZF) ) break;
+ }
+ M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
+ } else {
+ val1 = fetch_data_byte(M.x86.R_SI);
+ val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
+ cmp_byte(val1, val2);
+ M.x86.R_SI += inc;
+ M.x86.R_DI += inc;
+ }
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/****************************************************************************
@@ -7377,79 +2640,56 @@ Handles opcode 0xa7
****************************************************************************/
void x86emuOp_cmps_word(u8 X86EMU_UNUSED(op1))
{
- u32 val1, val2;
- int inc;
-
- START_OF_INSTR();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- DECODE_PRINTF("CMPS\tDWORD\n");
- if (ACCESS_FLAG(F_DF)) /* down */
- inc = -4;
- else
- inc = 4;
- } else {
- DECODE_PRINTF("CMPS\tWORD\n");
- if (ACCESS_FLAG(F_DF)) /* down */
- inc = -2;
- else
- inc = 2;
- }
- TRACE_AND_STEP();
- if (M.x86.mode & SYSMODE_PREFIX_REPE) {
- /* REPE */
- /* move them until CX is ZERO. */
- while (M.x86.R_CX != 0) {
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- val1 = fetch_data_long(M.x86.R_SI);
- val2 = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
- cmp_long(val1, val2);
- } else {
- val1 = fetch_data_word(M.x86.R_SI);
- val2 = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
- cmp_word((u16) val1, (u16) val2);
- }
- M.x86.R_CX -= 1;
- M.x86.R_SI += inc;
- M.x86.R_DI += inc;
- if (ACCESS_FLAG(F_ZF) == 0)
- break;
- }
- M.x86.mode &= ~SYSMODE_PREFIX_REPE;
- } else if (M.x86.mode & SYSMODE_PREFIX_REPNE) {
- /* REPNE */
- /* move them until CX is ZERO. */
- while (M.x86.R_CX != 0) {
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- val1 = fetch_data_long(M.x86.R_SI);
- val2 = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
- cmp_long(val1, val2);
- } else {
- val1 = fetch_data_word(M.x86.R_SI);
- val2 = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
- cmp_word((u16) val1, (u16) val2);
- }
- M.x86.R_CX -= 1;
- M.x86.R_SI += inc;
- M.x86.R_DI += inc;
- if (ACCESS_FLAG(F_ZF))
- break; /* zero flag set means equal */
- }
- M.x86.mode &= ~SYSMODE_PREFIX_REPNE;
- } else {
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- val1 = fetch_data_long(M.x86.R_SI);
- val2 = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
- cmp_long(val1, val2);
- } else {
- val1 = fetch_data_word(M.x86.R_SI);
- val2 = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
- cmp_word((u16) val1, (u16) val2);
- }
- M.x86.R_SI += inc;
- M.x86.R_DI += inc;
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ u32 val1,val2;
+ int inc;
+
+ START_OF_INSTR();
+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+ DECODE_PRINTF("CMPS\tDWORD\n");
+ inc = 4;
+ } else {
+ DECODE_PRINTF("CMPS\tWORD\n");
+ inc = 2;
+ }
+ if (ACCESS_FLAG(F_DF)) /* down */
+ inc = -inc;
+
+ TRACE_AND_STEP();
+ if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
+ /* REPE */
+ /* move them until CX is ZERO. */
+ while (M.x86.R_CX != 0) {
+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+ val1 = fetch_data_long(M.x86.R_SI);
+ val2 = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
+ cmp_long(val1, val2);
+ } else {
+ val1 = fetch_data_word(M.x86.R_SI);
+ val2 = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
+ cmp_word((u16)val1, (u16)val2);
+ }
+ M.x86.R_CX -= 1;
+ M.x86.R_SI += inc;
+ M.x86.R_DI += inc;
+ if ( (M.x86.mode & SYSMODE_PREFIX_REPE) && ACCESS_FLAG(F_ZF) == 0 ) break;
+ if ( (M.x86.mode & SYSMODE_PREFIX_REPNE) && ACCESS_FLAG(F_ZF) ) break;
+ }
+ M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
+ } else {
+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+ val1 = fetch_data_long(M.x86.R_SI);
+ val2 = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
+ cmp_long(val1, val2);
+ } else {
+ val1 = fetch_data_word(M.x86.R_SI);
+ val2 = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
+ cmp_word((u16)val1, (u16)val2);
+ }
+ M.x86.R_SI += inc;
+ M.x86.R_DI += inc;
+ }
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/****************************************************************************
@@ -7458,16 +2698,16 @@ Handles opcode 0xa8
****************************************************************************/
void x86emuOp_test_AL_IMM(u8 X86EMU_UNUSED(op1))
{
- int imm;
+ int imm;
- START_OF_INSTR();
- DECODE_PRINTF("TEST\tAL,");
- imm = fetch_byte_imm();
- DECODE_PRINTF2("%04x\n", imm);
- TRACE_AND_STEP();
- test_byte(M.x86.R_AL, (u8) imm);
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ START_OF_INSTR();
+ DECODE_PRINTF("TEST\tAL,");
+ imm = fetch_byte_imm();
+ DECODE_PRINTF2("%04x\n", imm);
+ TRACE_AND_STEP();
+ test_byte(M.x86.R_AL, (u8)imm);
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/****************************************************************************
@@ -7476,25 +2716,25 @@ Handles opcode 0xa9
****************************************************************************/
void x86emuOp_test_AX_IMM(u8 X86EMU_UNUSED(op1))
{
- u32 srcval;
-
- START_OF_INSTR();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- DECODE_PRINTF("TEST\tEAX,");
- srcval = fetch_long_imm();
- } else {
- DECODE_PRINTF("TEST\tAX,");
- srcval = fetch_word_imm();
- }
- DECODE_PRINTF2("%x\n", srcval);
- TRACE_AND_STEP();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- test_long(M.x86.R_EAX, srcval);
- } else {
- test_word(M.x86.R_AX, (u16) srcval);
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ u32 srcval;
+
+ START_OF_INSTR();
+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+ DECODE_PRINTF("TEST\tEAX,");
+ srcval = fetch_long_imm();
+ } else {
+ DECODE_PRINTF("TEST\tAX,");
+ srcval = fetch_word_imm();
+ }
+ DECODE_PRINTF2("%x\n", srcval);
+ TRACE_AND_STEP();
+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+ test_long(M.x86.R_EAX, srcval);
+ } else {
+ test_word(M.x86.R_AX, (u16)srcval);
+ }
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/****************************************************************************
@@ -7503,30 +2743,30 @@ Handles opcode 0xaa
****************************************************************************/
void x86emuOp_stos_byte(u8 X86EMU_UNUSED(op1))
{
- int inc;
-
- START_OF_INSTR();
- DECODE_PRINTF("STOS\tBYTE\n");
- if (ACCESS_FLAG(F_DF)) /* down */
- inc = -1;
- else
- inc = 1;
- TRACE_AND_STEP();
- if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
- /* dont care whether REPE or REPNE */
- /* move them until CX is ZERO. */
- while (M.x86.R_CX != 0) {
- store_data_byte_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_AL);
- M.x86.R_CX -= 1;
- M.x86.R_DI += inc;
- }
- M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
- } else {
- store_data_byte_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_AL);
- M.x86.R_DI += inc;
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ int inc;
+
+ START_OF_INSTR();
+ DECODE_PRINTF("STOS\tBYTE\n");
+ if (ACCESS_FLAG(F_DF)) /* down */
+ inc = -1;
+ else
+ inc = 1;
+ TRACE_AND_STEP();
+ if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
+ /* dont care whether REPE or REPNE */
+ /* move them until CX is ZERO. */
+ while (M.x86.R_CX != 0) {
+ store_data_byte_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_AL);
+ M.x86.R_CX -= 1;
+ M.x86.R_DI += inc;
+ }
+ M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
+ } else {
+ store_data_byte_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_AL);
+ M.x86.R_DI += inc;
+ }
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/****************************************************************************
@@ -7535,42 +2775,42 @@ Handles opcode 0xab
****************************************************************************/
void x86emuOp_stos_word(u8 X86EMU_UNUSED(op1))
{
- int inc;
- u32 count;
-
- START_OF_INSTR();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- DECODE_PRINTF("STOS\tDWORD\n");
- if (ACCESS_FLAG(F_DF)) /* down */
- inc = -4;
- else
- inc = 4;
- } else {
- DECODE_PRINTF("STOS\tWORD\n");
- if (ACCESS_FLAG(F_DF)) /* down */
- inc = -2;
- else
- inc = 2;
- }
- TRACE_AND_STEP();
- count = 1;
- if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
- /* dont care whether REPE or REPNE */
- /* move them until CX is ZERO. */
- count = M.x86.R_CX;
- M.x86.R_CX = 0;
- M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
- }
- while (count--) {
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- store_data_long_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_EAX);
- } else {
- store_data_word_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_AX);
- }
- M.x86.R_DI += inc;
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ int inc;
+ u32 count;
+
+ START_OF_INSTR();
+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+ DECODE_PRINTF("STOS\tDWORD\n");
+ if (ACCESS_FLAG(F_DF)) /* down */
+ inc = -4;
+ else
+ inc = 4;
+ } else {
+ DECODE_PRINTF("STOS\tWORD\n");
+ if (ACCESS_FLAG(F_DF)) /* down */
+ inc = -2;
+ else
+ inc = 2;
+ }
+ TRACE_AND_STEP();
+ count = 1;
+ if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
+ /* dont care whether REPE or REPNE */
+ /* move them until CX is ZERO. */
+ count = M.x86.R_CX;
+ M.x86.R_CX = 0;
+ M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
+ }
+ while (count--) {
+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+ store_data_long_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_EAX);
+ } else {
+ store_data_word_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_AX);
+ }
+ M.x86.R_DI += inc;
+ }
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/****************************************************************************
@@ -7579,30 +2819,30 @@ Handles opcode 0xac
****************************************************************************/
void x86emuOp_lods_byte(u8 X86EMU_UNUSED(op1))
{
- int inc;
-
- START_OF_INSTR();
- DECODE_PRINTF("LODS\tBYTE\n");
- TRACE_AND_STEP();
- if (ACCESS_FLAG(F_DF)) /* down */
- inc = -1;
- else
- inc = 1;
- if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
- /* dont care whether REPE or REPNE */
- /* move them until CX is ZERO. */
- while (M.x86.R_CX != 0) {
- M.x86.R_AL = fetch_data_byte(M.x86.R_SI);
- M.x86.R_CX -= 1;
- M.x86.R_SI += inc;
- }
- M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
- } else {
- M.x86.R_AL = fetch_data_byte(M.x86.R_SI);
- M.x86.R_SI += inc;
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ int inc;
+
+ START_OF_INSTR();
+ DECODE_PRINTF("LODS\tBYTE\n");
+ TRACE_AND_STEP();
+ if (ACCESS_FLAG(F_DF)) /* down */
+ inc = -1;
+ else
+ inc = 1;
+ if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
+ /* dont care whether REPE or REPNE */
+ /* move them until CX is ZERO. */
+ while (M.x86.R_CX != 0) {
+ M.x86.R_AL = fetch_data_byte(M.x86.R_SI);
+ M.x86.R_CX -= 1;
+ M.x86.R_SI += inc;
+ }
+ M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
+ } else {
+ M.x86.R_AL = fetch_data_byte(M.x86.R_SI);
+ M.x86.R_SI += inc;
+ }
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/****************************************************************************
@@ -7611,42 +2851,42 @@ Handles opcode 0xad
****************************************************************************/
void x86emuOp_lods_word(u8 X86EMU_UNUSED(op1))
{
- int inc;
- u32 count;
-
- START_OF_INSTR();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- DECODE_PRINTF("LODS\tDWORD\n");
- if (ACCESS_FLAG(F_DF)) /* down */
- inc = -4;
- else
- inc = 4;
- } else {
- DECODE_PRINTF("LODS\tWORD\n");
- if (ACCESS_FLAG(F_DF)) /* down */
- inc = -2;
- else
- inc = 2;
- }
- TRACE_AND_STEP();
- count = 1;
- if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
- /* dont care whether REPE or REPNE */
- /* move them until CX is ZERO. */
- count = M.x86.R_CX;
- M.x86.R_CX = 0;
- M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
- }
- while (count--) {
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- M.x86.R_EAX = fetch_data_long(M.x86.R_SI);
- } else {
- M.x86.R_AX = fetch_data_word(M.x86.R_SI);
- }
- M.x86.R_SI += inc;
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ int inc;
+ u32 count;
+
+ START_OF_INSTR();
+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+ DECODE_PRINTF("LODS\tDWORD\n");
+ if (ACCESS_FLAG(F_DF)) /* down */
+ inc = -4;
+ else
+ inc = 4;
+ } else {
+ DECODE_PRINTF("LODS\tWORD\n");
+ if (ACCESS_FLAG(F_DF)) /* down */
+ inc = -2;
+ else
+ inc = 2;
+ }
+ TRACE_AND_STEP();
+ count = 1;
+ if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
+ /* dont care whether REPE or REPNE */
+ /* move them until CX is ZERO. */
+ count = M.x86.R_CX;
+ M.x86.R_CX = 0;
+ M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
+ }
+ while (count--) {
+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+ M.x86.R_EAX = fetch_data_long(M.x86.R_SI);
+ } else {
+ M.x86.R_AX = fetch_data_word(M.x86.R_SI);
+ }
+ M.x86.R_SI += inc;
+ }
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/****************************************************************************
@@ -7655,47 +2895,47 @@ Handles opcode 0xae
****************************************************************************/
void x86emuOp_scas_byte(u8 X86EMU_UNUSED(op1))
{
- s8 val2;
- int inc;
-
- START_OF_INSTR();
- DECODE_PRINTF("SCAS\tBYTE\n");
- TRACE_AND_STEP();
- if (ACCESS_FLAG(F_DF)) /* down */
- inc = -1;
- else
- inc = 1;
- if (M.x86.mode & SYSMODE_PREFIX_REPE) {
- /* REPE */
- /* move them until CX is ZERO. */
- while (M.x86.R_CX != 0) {
- val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
- cmp_byte(M.x86.R_AL, val2);
- M.x86.R_CX -= 1;
- M.x86.R_DI += inc;
- if (ACCESS_FLAG(F_ZF) == 0)
- break;
- }
- M.x86.mode &= ~SYSMODE_PREFIX_REPE;
- } else if (M.x86.mode & SYSMODE_PREFIX_REPNE) {
- /* REPNE */
- /* move them until CX is ZERO. */
- while (M.x86.R_CX != 0) {
- val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
- cmp_byte(M.x86.R_AL, val2);
- M.x86.R_CX -= 1;
- M.x86.R_DI += inc;
- if (ACCESS_FLAG(F_ZF))
- break; /* zero flag set means equal */
- }
- M.x86.mode &= ~SYSMODE_PREFIX_REPNE;
- } else {
- val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
- cmp_byte(M.x86.R_AL, val2);
- M.x86.R_DI += inc;
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ s8 val2;
+ int inc;
+
+ START_OF_INSTR();
+ DECODE_PRINTF("SCAS\tBYTE\n");
+ TRACE_AND_STEP();
+ if (ACCESS_FLAG(F_DF)) /* down */
+ inc = -1;
+ else
+ inc = 1;
+ if (M.x86.mode & SYSMODE_PREFIX_REPE) {
+ /* REPE */
+ /* move them until CX is ZERO. */
+ while (M.x86.R_CX != 0) {
+ val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
+ cmp_byte(M.x86.R_AL, val2);
+ M.x86.R_CX -= 1;
+ M.x86.R_DI += inc;
+ if (ACCESS_FLAG(F_ZF) == 0)
+ break;
+ }
+ M.x86.mode &= ~SYSMODE_PREFIX_REPE;
+ } else if (M.x86.mode & SYSMODE_PREFIX_REPNE) {
+ /* REPNE */
+ /* move them until CX is ZERO. */
+ while (M.x86.R_CX != 0) {
+ val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
+ cmp_byte(M.x86.R_AL, val2);
+ M.x86.R_CX -= 1;
+ M.x86.R_DI += inc;
+ if (ACCESS_FLAG(F_ZF))
+ break; /* zero flag set means equal */
+ }
+ M.x86.mode &= ~SYSMODE_PREFIX_REPNE;
+ } else {
+ val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
+ cmp_byte(M.x86.R_AL, val2);
+ M.x86.R_DI += inc;
+ }
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/****************************************************************************
@@ -7704,699 +2944,299 @@ Handles opcode 0xaf
****************************************************************************/
void x86emuOp_scas_word(u8 X86EMU_UNUSED(op1))
{
- int inc;
- u32 val;
-
- START_OF_INSTR();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- DECODE_PRINTF("SCAS\tDWORD\n");
- if (ACCESS_FLAG(F_DF)) /* down */
- inc = -4;
- else
- inc = 4;
- } else {
- DECODE_PRINTF("SCAS\tWORD\n");
- if (ACCESS_FLAG(F_DF)) /* down */
- inc = -2;
- else
- inc = 2;
- }
- TRACE_AND_STEP();
- if (M.x86.mode & SYSMODE_PREFIX_REPE) {
- /* REPE */
- /* move them until CX is ZERO. */
- while (M.x86.R_CX != 0) {
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- val = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
- cmp_long(M.x86.R_EAX, val);
- } else {
- val = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
- cmp_word(M.x86.R_AX, (u16) val);
- }
- M.x86.R_CX -= 1;
- M.x86.R_DI += inc;
- if (ACCESS_FLAG(F_ZF) == 0)
- break;
- }
- M.x86.mode &= ~SYSMODE_PREFIX_REPE;
- } else if (M.x86.mode & SYSMODE_PREFIX_REPNE) {
- /* REPNE */
- /* move them until CX is ZERO. */
- while (M.x86.R_CX != 0) {
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- val = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
- cmp_long(M.x86.R_EAX, val);
- } else {
- val = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
- cmp_word(M.x86.R_AX, (u16) val);
- }
- M.x86.R_CX -= 1;
- M.x86.R_DI += inc;
- if (ACCESS_FLAG(F_ZF))
- break; /* zero flag set means equal */
- }
- M.x86.mode &= ~SYSMODE_PREFIX_REPNE;
- } else {
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- val = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
- cmp_long(M.x86.R_EAX, val);
- } else {
- val = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
- cmp_word(M.x86.R_AX, (u16) val);
- }
- M.x86.R_DI += inc;
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
-}
-
-/****************************************************************************
-REMARKS:
-Handles opcode 0xb0
-****************************************************************************/
-void x86emuOp_mov_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
-{
- u8 imm;
-
- START_OF_INSTR();
- DECODE_PRINTF("MOV\tAL,");
- imm = fetch_byte_imm();
- DECODE_PRINTF2("%x\n", imm);
- TRACE_AND_STEP();
- M.x86.R_AL = imm;
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ int inc;
+ u32 val;
+
+ START_OF_INSTR();
+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+ DECODE_PRINTF("SCAS\tDWORD\n");
+ if (ACCESS_FLAG(F_DF)) /* down */
+ inc = -4;
+ else
+ inc = 4;
+ } else {
+ DECODE_PRINTF("SCAS\tWORD\n");
+ if (ACCESS_FLAG(F_DF)) /* down */
+ inc = -2;
+ else
+ inc = 2;
+ }
+ TRACE_AND_STEP();
+ if (M.x86.mode & SYSMODE_PREFIX_REPE) {
+ /* REPE */
+ /* move them until CX is ZERO. */
+ while (M.x86.R_CX != 0) {
+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+ val = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
+ cmp_long(M.x86.R_EAX, val);
+ } else {
+ val = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
+ cmp_word(M.x86.R_AX, (u16)val);
+ }
+ M.x86.R_CX -= 1;
+ M.x86.R_DI += inc;
+ if (ACCESS_FLAG(F_ZF) == 0)
+ break;
+ }
+ M.x86.mode &= ~SYSMODE_PREFIX_REPE;
+ } else if (M.x86.mode & SYSMODE_PREFIX_REPNE) {
+ /* REPNE */
+ /* move them until CX is ZERO. */
+ while (M.x86.R_CX != 0) {
+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+ val = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
+ cmp_long(M.x86.R_EAX, val);
+ } else {
+ val = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
+ cmp_word(M.x86.R_AX, (u16)val);
+ }
+ M.x86.R_CX -= 1;
+ M.x86.R_DI += inc;
+ if (ACCESS_FLAG(F_ZF))
+ break; /* zero flag set means equal */
+ }
+ M.x86.mode &= ~SYSMODE_PREFIX_REPNE;
+ } else {
+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+ val = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
+ cmp_long(M.x86.R_EAX, val);
+ } else {
+ val = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
+ cmp_word(M.x86.R_AX, (u16)val);
+ }
+ M.x86.R_DI += inc;
+ }
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0xb0 - 0xb7
+****************************************************************************/
+void x86emuOp_mov_byte_register_IMM(u8 op1)
+{
+ u8 imm, *ptr;
+
+ START_OF_INSTR();
+ DECODE_PRINTF("MOV\t");
+ ptr = DECODE_RM_BYTE_REGISTER(op1 & 0x7);
+ DECODE_PRINTF(",");
+ imm = fetch_byte_imm();
+ DECODE_PRINTF2("%x\n", imm);
+ TRACE_AND_STEP();
+ *ptr = imm;
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
+}
+
+/****************************************************************************
+REMARKS:
+Handles opcode 0xb8 - 0xbf
+****************************************************************************/
+void x86emuOp_mov_word_register_IMM(u8 X86EMU_UNUSED(op1))
+{
+ u32 srcval;
+
+ op1 &= 0x7;
+
+ START_OF_INSTR();
+ DECODE_PRINTF("MOV\t");
+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+ u32 *reg32;
+ reg32 = DECODE_RM_LONG_REGISTER(op1);
+ srcval = fetch_long_imm();
+ DECODE_PRINTF2(",%x\n", srcval);
+ TRACE_AND_STEP();
+ *reg32 = srcval;
+ } else {
+ u16 *reg16;
+ reg16 = DECODE_RM_WORD_REGISTER(op1);
+ srcval = fetch_word_imm();
+ DECODE_PRINTF2(",%x\n", srcval);
+ TRACE_AND_STEP();
+ *reg16 = (u16)srcval;
+ }
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/****************************************************************************
REMARKS:
-Handles opcode 0xb1
-****************************************************************************/
-void x86emuOp_mov_byte_CL_IMM(u8 X86EMU_UNUSED(op1))
-{
- u8 imm;
-
- START_OF_INSTR();
- DECODE_PRINTF("MOV\tCL,");
- imm = fetch_byte_imm();
- DECODE_PRINTF2("%x\n", imm);
- TRACE_AND_STEP();
- M.x86.R_CL = imm;
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
-}
-
-/****************************************************************************
-REMARKS:
-Handles opcode 0xb2
-****************************************************************************/
-void x86emuOp_mov_byte_DL_IMM(u8 X86EMU_UNUSED(op1))
-{
- u8 imm;
-
- START_OF_INSTR();
- DECODE_PRINTF("MOV\tDL,");
- imm = fetch_byte_imm();
- DECODE_PRINTF2("%x\n", imm);
- TRACE_AND_STEP();
- M.x86.R_DL = imm;
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
-}
-
-/****************************************************************************
-REMARKS:
-Handles opcode 0xb3
-****************************************************************************/
-void x86emuOp_mov_byte_BL_IMM(u8 X86EMU_UNUSED(op1))
-{
- u8 imm;
-
- START_OF_INSTR();
- DECODE_PRINTF("MOV\tBL,");
- imm = fetch_byte_imm();
- DECODE_PRINTF2("%x\n", imm);
- TRACE_AND_STEP();
- M.x86.R_BL = imm;
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
-}
-
-/****************************************************************************
-REMARKS:
-Handles opcode 0xb4
-****************************************************************************/
-void x86emuOp_mov_byte_AH_IMM(u8 X86EMU_UNUSED(op1))
-{
- u8 imm;
-
- START_OF_INSTR();
- DECODE_PRINTF("MOV\tAH,");
- imm = fetch_byte_imm();
- DECODE_PRINTF2("%x\n", imm);
- TRACE_AND_STEP();
- M.x86.R_AH = imm;
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
-}
-
-/****************************************************************************
-REMARKS:
-Handles opcode 0xb5
-****************************************************************************/
-void x86emuOp_mov_byte_CH_IMM(u8 X86EMU_UNUSED(op1))
-{
- u8 imm;
-
- START_OF_INSTR();
- DECODE_PRINTF("MOV\tCH,");
- imm = fetch_byte_imm();
- DECODE_PRINTF2("%x\n", imm);
- TRACE_AND_STEP();
- M.x86.R_CH = imm;
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
-}
-
-/****************************************************************************
-REMARKS:
-Handles opcode 0xb6
-****************************************************************************/
-void x86emuOp_mov_byte_DH_IMM(u8 X86EMU_UNUSED(op1))
-{
- u8 imm;
-
- START_OF_INSTR();
- DECODE_PRINTF("MOV\tDH,");
- imm = fetch_byte_imm();
- DECODE_PRINTF2("%x\n", imm);
- TRACE_AND_STEP();
- M.x86.R_DH = imm;
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
-}
-
-/****************************************************************************
-REMARKS:
-Handles opcode 0xb7
-****************************************************************************/
-void x86emuOp_mov_byte_BH_IMM(u8 X86EMU_UNUSED(op1))
-{
- u8 imm;
-
- START_OF_INSTR();
- DECODE_PRINTF("MOV\tBH,");
- imm = fetch_byte_imm();
- DECODE_PRINTF2("%x\n", imm);
- TRACE_AND_STEP();
- M.x86.R_BH = imm;
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
-}
-
-/****************************************************************************
-REMARKS:
-Handles opcode 0xb8
-****************************************************************************/
-void x86emuOp_mov_word_AX_IMM(u8 X86EMU_UNUSED(op1))
-{
- u32 srcval;
-
- START_OF_INSTR();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- DECODE_PRINTF("MOV\tEAX,");
- srcval = fetch_long_imm();
- } else {
- DECODE_PRINTF("MOV\tAX,");
- srcval = fetch_word_imm();
- }
- DECODE_PRINTF2("%x\n", srcval);
- TRACE_AND_STEP();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- M.x86.R_EAX = srcval;
- } else {
- M.x86.R_AX = (u16) srcval;
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
-}
-
-/****************************************************************************
-REMARKS:
-Handles opcode 0xb9
-****************************************************************************/
-void x86emuOp_mov_word_CX_IMM(u8 X86EMU_UNUSED(op1))
-{
- u32 srcval;
-
- START_OF_INSTR();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- DECODE_PRINTF("MOV\tECX,");
- srcval = fetch_long_imm();
- } else {
- DECODE_PRINTF("MOV\tCX,");
- srcval = fetch_word_imm();
- }
- DECODE_PRINTF2("%x\n", srcval);
- TRACE_AND_STEP();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- M.x86.R_ECX = srcval;
- } else {
- M.x86.R_CX = (u16) srcval;
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
-}
-
-/****************************************************************************
-REMARKS:
-Handles opcode 0xba
-****************************************************************************/
-void x86emuOp_mov_word_DX_IMM(u8 X86EMU_UNUSED(op1))
-{
- u32 srcval;
-
- START_OF_INSTR();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- DECODE_PRINTF("MOV\tEDX,");
- srcval = fetch_long_imm();
- } else {
- DECODE_PRINTF("MOV\tDX,");
- srcval = fetch_word_imm();
- }
- DECODE_PRINTF2("%x\n", srcval);
- TRACE_AND_STEP();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- M.x86.R_EDX = srcval;
- } else {
- M.x86.R_DX = (u16) srcval;
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
-}
-
-/****************************************************************************
-REMARKS:
-Handles opcode 0xbb
-****************************************************************************/
-void x86emuOp_mov_word_BX_IMM(u8 X86EMU_UNUSED(op1))
-{
- u32 srcval;
-
- START_OF_INSTR();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- DECODE_PRINTF("MOV\tEBX,");
- srcval = fetch_long_imm();
- } else {
- DECODE_PRINTF("MOV\tBX,");
- srcval = fetch_word_imm();
- }
- DECODE_PRINTF2("%x\n", srcval);
- TRACE_AND_STEP();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- M.x86.R_EBX = srcval;
- } else {
- M.x86.R_BX = (u16) srcval;
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
-}
-
-/****************************************************************************
-REMARKS:
-Handles opcode 0xbc
-****************************************************************************/
-void x86emuOp_mov_word_SP_IMM(u8 X86EMU_UNUSED(op1))
-{
- u32 srcval;
-
- START_OF_INSTR();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- DECODE_PRINTF("MOV\tESP,");
- srcval = fetch_long_imm();
- } else {
- DECODE_PRINTF("MOV\tSP,");
- srcval = fetch_word_imm();
- }
- DECODE_PRINTF2("%x\n", srcval);
- TRACE_AND_STEP();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- M.x86.R_ESP = srcval;
- } else {
- M.x86.R_SP = (u16) srcval;
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
-}
-
-/****************************************************************************
-REMARKS:
-Handles opcode 0xbd
-****************************************************************************/
-void x86emuOp_mov_word_BP_IMM(u8 X86EMU_UNUSED(op1))
-{
- u32 srcval;
-
- START_OF_INSTR();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- DECODE_PRINTF("MOV\tEBP,");
- srcval = fetch_long_imm();
- } else {
- DECODE_PRINTF("MOV\tBP,");
- srcval = fetch_word_imm();
- }
- DECODE_PRINTF2("%x\n", srcval);
- TRACE_AND_STEP();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- M.x86.R_EBP = srcval;
- } else {
- M.x86.R_BP = (u16) srcval;
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
-}
-
-/****************************************************************************
-REMARKS:
-Handles opcode 0xbe
-****************************************************************************/
-void x86emuOp_mov_word_SI_IMM(u8 X86EMU_UNUSED(op1))
-{
- u32 srcval;
-
- START_OF_INSTR();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- DECODE_PRINTF("MOV\tESI,");
- srcval = fetch_long_imm();
- } else {
- DECODE_PRINTF("MOV\tSI,");
- srcval = fetch_word_imm();
- }
- DECODE_PRINTF2("%x\n", srcval);
- TRACE_AND_STEP();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- M.x86.R_ESI = srcval;
- } else {
- M.x86.R_SI = (u16) srcval;
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
-}
-
-/****************************************************************************
-REMARKS:
-Handles opcode 0xbf
-****************************************************************************/
-void x86emuOp_mov_word_DI_IMM(u8 X86EMU_UNUSED(op1))
-{
- u32 srcval;
-
- START_OF_INSTR();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- DECODE_PRINTF("MOV\tEDI,");
- srcval = fetch_long_imm();
- } else {
- DECODE_PRINTF("MOV\tDI,");
- srcval = fetch_word_imm();
- }
- DECODE_PRINTF2("%x\n", srcval);
- TRACE_AND_STEP();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- M.x86.R_EDI = srcval;
- } else {
- M.x86.R_DI = (u16) srcval;
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
-}
-
-/* used by opcodes c0, d0, and d2. */
-static u8(*opcD0_byte_operation[]) (u8 d, u8 s) = {
- rol_byte, ror_byte, rcl_byte, rcr_byte, shl_byte, shr_byte, shl_byte, /* sal_byte === shl_byte by definition */
-sar_byte,};
-
-/****************************************************************************
-REMARKS:
Handles opcode 0xc0
****************************************************************************/
void x86emuOp_opcC0_byte_RM_MEM(u8 X86EMU_UNUSED(op1))
{
- int mod, rl, rh;
- u8 *destreg;
- uint destoffset;
- u8 destval;
- u8 amt;
-
- /*
- * Yet another weirdo special case instruction format. Part of
- * the opcode held below in "RH". Doubly nested case would
- * result, except that the decoded instruction
- */
- START_OF_INSTR();
- FETCH_DECODE_MODRM(mod, rh, rl);
+ int mod, rl, rh;
+ u8 *destreg;
+ uint destoffset;
+ u8 destval;
+ u8 amt;
+
+ /*
+ * Yet another weirdo special case instruction format. Part of
+ * the opcode held below in "RH". Doubly nested case would
+ * result, except that the decoded instruction
+ */
+ START_OF_INSTR();
+ FETCH_DECODE_MODRM(mod, rh, rl);
#ifdef DEBUG
- if (DEBUG_DECODE()) {
- /* XXX DECODE_PRINTF may be changed to something more
- general, so that it is important to leave the strings
- in the same format, even though the result is that the
- above test is done twice. */
-
- switch (rh) {
- case 0:
- DECODE_PRINTF("ROL\t");
- break;
- case 1:
- DECODE_PRINTF("ROR\t");
- break;
- case 2:
- DECODE_PRINTF("RCL\t");
- break;
- case 3:
- DECODE_PRINTF("RCR\t");
- break;
- case 4:
- DECODE_PRINTF("SHL\t");
- break;
- case 5:
- DECODE_PRINTF("SHR\t");
- break;
- case 6:
- DECODE_PRINTF("SAL\t");
- break;
- case 7:
- DECODE_PRINTF("SAR\t");
- break;
- }
- }
+ if (DEBUG_DECODE()) {
+ /* XXX DECODE_PRINTF may be changed to something more
+ general, so that it is important to leave the strings
+ in the same format, even though the result is that the
+ above test is done twice. */
+
+ switch (rh) {
+ case 0:
+ DECODE_PRINTF("ROL\t");
+ break;
+ case 1:
+ DECODE_PRINTF("ROR\t");
+ break;
+ case 2:
+ DECODE_PRINTF("RCL\t");
+ break;
+ case 3:
+ DECODE_PRINTF("RCR\t");
+ break;
+ case 4:
+ DECODE_PRINTF("SHL\t");
+ break;
+ case 5:
+ DECODE_PRINTF("SHR\t");
+ break;
+ case 6:
+ DECODE_PRINTF("SAL\t");
+ break;
+ case 7:
+ DECODE_PRINTF("SAR\t");
+ break;
+ }
+ }
#endif
- /* know operation, decode the mod byte to find the addressing
- mode. */
- switch (mod) {
- case 0:
- DECODE_PRINTF("BYTE PTR ");
- destoffset = decode_rm00_address(rl);
- amt = fetch_byte_imm();
- DECODE_PRINTF2(",%x\n", amt);
- destval = fetch_data_byte(destoffset);
- TRACE_AND_STEP();
- destval = (*opcD0_byte_operation[rh]) (destval, amt);
- store_data_byte(destoffset, destval);
- break;
- case 1:
- DECODE_PRINTF("BYTE PTR ");
- destoffset = decode_rm01_address(rl);
- amt = fetch_byte_imm();
- DECODE_PRINTF2(",%x\n", amt);
- destval = fetch_data_byte(destoffset);
- TRACE_AND_STEP();
- destval = (*opcD0_byte_operation[rh]) (destval, amt);
- store_data_byte(destoffset, destval);
- break;
- case 2:
- DECODE_PRINTF("BYTE PTR ");
- destoffset = decode_rm10_address(rl);
- amt = fetch_byte_imm();
- DECODE_PRINTF2(",%x\n", amt);
- destval = fetch_data_byte(destoffset);
- TRACE_AND_STEP();
- destval = (*opcD0_byte_operation[rh]) (destval, amt);
- store_data_byte(destoffset, destval);
- break;
- case 3: /* register to register */
- destreg = DECODE_RM_BYTE_REGISTER(rl);
- amt = fetch_byte_imm();
- DECODE_PRINTF2(",%x\n", amt);
- TRACE_AND_STEP();
- destval = (*opcD0_byte_operation[rh]) (*destreg, amt);
- *destreg = destval;
- break;
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ /* know operation, decode the mod byte to find the addressing
+ mode. */
+ if (mod < 3) {
+ DECODE_PRINTF("BYTE PTR ");
+ destoffset = decode_rmXX_address(mod, rl);
+ amt = fetch_byte_imm();
+ DECODE_PRINTF2(",%x\n", amt);
+ destval = fetch_data_byte(destoffset);
+ TRACE_AND_STEP();
+ destval = (*opcD0_byte_operation[rh]) (destval, amt);
+ store_data_byte(destoffset, destval);
+ } else { /* register to register */
+ destreg = DECODE_RM_BYTE_REGISTER(rl);
+ amt = fetch_byte_imm();
+ DECODE_PRINTF2(",%x\n", amt);
+ TRACE_AND_STEP();
+ destval = (*opcD0_byte_operation[rh]) (*destreg, amt);
+ *destreg = destval;
+ }
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
-/* used by opcodes c1, d1, and d3. */
-static u16(*opcD1_word_operation[]) (u16 s, u8 d) = {
- rol_word, ror_word, rcl_word, rcr_word, shl_word, shr_word, shl_word, /* sal_byte === shl_byte by definition */
-sar_word,};
-
-/* used by opcodes c1, d1, and d3. */
-static u32(*opcD1_long_operation[]) (u32 s, u8 d) = {
- rol_long, ror_long, rcl_long, rcr_long, shl_long, shr_long, shl_long, /* sal_byte === shl_byte by definition */
-sar_long,};
-
/****************************************************************************
REMARKS:
Handles opcode 0xc1
****************************************************************************/
void x86emuOp_opcC1_word_RM_MEM(u8 X86EMU_UNUSED(op1))
{
- int mod, rl, rh;
- uint destoffset;
- u8 amt;
-
- /*
- * Yet another weirdo special case instruction format. Part of
- * the opcode held below in "RH". Doubly nested case would
- * result, except that the decoded instruction
- */
- START_OF_INSTR();
- FETCH_DECODE_MODRM(mod, rh, rl);
+ int mod, rl, rh;
+ uint destoffset;
+ u8 amt;
+
+ /*
+ * Yet another weirdo special case instruction format. Part of
+ * the opcode held below in "RH". Doubly nested case would
+ * result, except that the decoded instruction
+ */
+ START_OF_INSTR();
+ FETCH_DECODE_MODRM(mod, rh, rl);
#ifdef DEBUG
- if (DEBUG_DECODE()) {
- /* XXX DECODE_PRINTF may be changed to something more
- general, so that it is important to leave the strings
- in the same format, even though the result is that the
- above test is done twice. */
-
- switch (rh) {
- case 0:
- DECODE_PRINTF("ROL\t");
- break;
- case 1:
- DECODE_PRINTF("ROR\t");
- break;
- case 2:
- DECODE_PRINTF("RCL\t");
- break;
- case 3:
- DECODE_PRINTF("RCR\t");
- break;
- case 4:
- DECODE_PRINTF("SHL\t");
- break;
- case 5:
- DECODE_PRINTF("SHR\t");
- break;
- case 6:
- DECODE_PRINTF("SAL\t");
- break;
- case 7:
- DECODE_PRINTF("SAR\t");
- break;
- }
- }
+ if (DEBUG_DECODE()) {
+ /* XXX DECODE_PRINTF may be changed to something more
+ general, so that it is important to leave the strings
+ in the same format, even though the result is that the
+ above test is done twice. */
+
+ switch (rh) {
+ case 0:
+ DECODE_PRINTF("ROL\t");
+ break;
+ case 1:
+ DECODE_PRINTF("ROR\t");
+ break;
+ case 2:
+ DECODE_PRINTF("RCL\t");
+ break;
+ case 3:
+ DECODE_PRINTF("RCR\t");
+ break;
+ case 4:
+ DECODE_PRINTF("SHL\t");
+ break;
+ case 5:
+ DECODE_PRINTF("SHR\t");
+ break;
+ case 6:
+ DECODE_PRINTF("SAL\t");
+ break;
+ case 7:
+ DECODE_PRINTF("SAR\t");
+ break;
+ }
+ }
#endif
- /* know operation, decode the mod byte to find the addressing
- mode. */
- switch (mod) {
- case 0:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 destval;
-
- DECODE_PRINTF("DWORD PTR ");
- destoffset = decode_rm00_address(rl);
- amt = fetch_byte_imm();
- DECODE_PRINTF2(",%x\n", amt);
- destval = fetch_data_long(destoffset);
- TRACE_AND_STEP();
- destval = (*opcD1_long_operation[rh]) (destval, amt);
- store_data_long(destoffset, destval);
- } else {
- u16 destval;
-
- DECODE_PRINTF("WORD PTR ");
- destoffset = decode_rm00_address(rl);
- amt = fetch_byte_imm();
- DECODE_PRINTF2(",%x\n", amt);
- destval = fetch_data_word(destoffset);
- TRACE_AND_STEP();
- destval = (*opcD1_word_operation[rh]) (destval, amt);
- store_data_word(destoffset, destval);
- }
- break;
- case 1:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 destval;
-
- DECODE_PRINTF("DWORD PTR ");
- destoffset = decode_rm01_address(rl);
- amt = fetch_byte_imm();
- DECODE_PRINTF2(",%x\n", amt);
- destval = fetch_data_long(destoffset);
- TRACE_AND_STEP();
- destval = (*opcD1_long_operation[rh]) (destval, amt);
- store_data_long(destoffset, destval);
- } else {
- u16 destval;
-
- DECODE_PRINTF("WORD PTR ");
- destoffset = decode_rm01_address(rl);
- amt = fetch_byte_imm();
- DECODE_PRINTF2(",%x\n", amt);
- destval = fetch_data_word(destoffset);
- TRACE_AND_STEP();
- destval = (*opcD1_word_operation[rh]) (destval, amt);
- store_data_word(destoffset, destval);
- }
- break;
- case 2:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 destval;
-
- DECODE_PRINTF("DWORD PTR ");
- destoffset = decode_rm10_address(rl);
- amt = fetch_byte_imm();
- DECODE_PRINTF2(",%x\n", amt);
- destval = fetch_data_long(destoffset);
- TRACE_AND_STEP();
- destval = (*opcD1_long_operation[rh]) (destval, amt);
- store_data_long(destoffset, destval);
- } else {
- u16 destval;
-
- DECODE_PRINTF("WORD PTR ");
- destoffset = decode_rm10_address(rl);
- amt = fetch_byte_imm();
- DECODE_PRINTF2(",%x\n", amt);
- destval = fetch_data_word(destoffset);
- TRACE_AND_STEP();
- destval = (*opcD1_word_operation[rh]) (destval, amt);
- store_data_word(destoffset, destval);
- }
- break;
- case 3: /* register to register */
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 *destreg;
-
- destreg = DECODE_RM_LONG_REGISTER(rl);
- amt = fetch_byte_imm();
- DECODE_PRINTF2(",%x\n", amt);
- TRACE_AND_STEP();
- *destreg = (*opcD1_long_operation[rh]) (*destreg, amt);
- } else {
- u16 *destreg;
-
- destreg = DECODE_RM_WORD_REGISTER(rl);
- amt = fetch_byte_imm();
- DECODE_PRINTF2(",%x\n", amt);
- TRACE_AND_STEP();
- *destreg = (*opcD1_word_operation[rh]) (*destreg, amt);
- }
- break;
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ /* know operation, decode the mod byte to find the addressing
+ mode. */
+ if (mod < 3) {
+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+ u32 destval;
+
+ DECODE_PRINTF("DWORD PTR ");
+ destoffset = decode_rmXX_address(mod, rl);
+ amt = fetch_byte_imm();
+ DECODE_PRINTF2(",%x\n", amt);
+ destval = fetch_data_long(destoffset);
+ TRACE_AND_STEP();
+ destval = (*opcD1_long_operation[rh]) (destval, amt);
+ store_data_long(destoffset, destval);
+ } else {
+ u16 destval;
+
+ DECODE_PRINTF("WORD PTR ");
+ destoffset = decode_rmXX_address(mod, rl);
+ amt = fetch_byte_imm();
+ DECODE_PRINTF2(",%x\n", amt);
+ destval = fetch_data_word(destoffset);
+ TRACE_AND_STEP();
+ destval = (*opcD1_word_operation[rh]) (destval, amt);
+ store_data_word(destoffset, destval);
+ }
+ } else { /* register to register */
+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+ u32 *destreg;
+
+ destreg = DECODE_RM_LONG_REGISTER(rl);
+ amt = fetch_byte_imm();
+ DECODE_PRINTF2(",%x\n", amt);
+ TRACE_AND_STEP();
+ *destreg = (*opcD1_long_operation[rh]) (*destreg, amt);
+ } else {
+ u16 *destreg;
+
+ destreg = DECODE_RM_WORD_REGISTER(rl);
+ amt = fetch_byte_imm();
+ DECODE_PRINTF2(",%x\n", amt);
+ TRACE_AND_STEP();
+ *destreg = (*opcD1_word_operation[rh]) (*destreg, amt);
+ }
+ }
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/****************************************************************************
@@ -8405,18 +3245,18 @@ Handles opcode 0xc2
****************************************************************************/
void x86emuOp_ret_near_IMM(u8 X86EMU_UNUSED(op1))
{
- u16 imm;
+ u16 imm;
- START_OF_INSTR();
- DECODE_PRINTF("RET\t");
- imm = fetch_word_imm();
- DECODE_PRINTF2("%x\n", imm);
- RETURN_TRACE("RET", M.x86.saved_cs, M.x86.saved_ip);
+ START_OF_INSTR();
+ DECODE_PRINTF("RET\t");
+ imm = fetch_word_imm();
+ DECODE_PRINTF2("%x\n", imm);
+ RETURN_TRACE("RET",M.x86.saved_cs,M.x86.saved_ip);
TRACE_AND_STEP();
- M.x86.R_IP = pop_word();
- M.x86.R_SP += imm;
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ M.x86.R_IP = pop_word();
+ M.x86.R_SP += imm;
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/****************************************************************************
@@ -8425,13 +3265,13 @@ Handles opcode 0xc3
****************************************************************************/
void x86emuOp_ret_near(u8 X86EMU_UNUSED(op1))
{
- START_OF_INSTR();
- DECODE_PRINTF("RET\n");
- RETURN_TRACE("RET", M.x86.saved_cs, M.x86.saved_ip);
+ START_OF_INSTR();
+ DECODE_PRINTF("RET\n");
+ RETURN_TRACE("RET",M.x86.saved_cs,M.x86.saved_ip);
TRACE_AND_STEP();
- M.x86.R_IP = pop_word();
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ M.x86.R_IP = pop_word();
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/****************************************************************************
@@ -8440,47 +3280,26 @@ Handles opcode 0xc4
****************************************************************************/
void x86emuOp_les_R_IMM(u8 X86EMU_UNUSED(op1))
{
- int mod, rh, rl;
- u16 *dstreg;
- uint srcoffset;
-
- START_OF_INSTR();
- DECODE_PRINTF("LES\t");
- FETCH_DECODE_MODRM(mod, rh, rl);
- switch (mod) {
- case 0:
- dstreg = DECODE_RM_WORD_REGISTER(rh);
- DECODE_PRINTF(",");
- srcoffset = decode_rm00_address(rl);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *dstreg = fetch_data_word(srcoffset);
- M.x86.R_ES = fetch_data_word(srcoffset + 2);
- break;
- case 1:
- dstreg = DECODE_RM_WORD_REGISTER(rh);
- DECODE_PRINTF(",");
- srcoffset = decode_rm01_address(rl);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *dstreg = fetch_data_word(srcoffset);
- M.x86.R_ES = fetch_data_word(srcoffset + 2);
- break;
- case 2:
- dstreg = DECODE_RM_WORD_REGISTER(rh);
- DECODE_PRINTF(",");
- srcoffset = decode_rm10_address(rl);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *dstreg = fetch_data_word(srcoffset);
- M.x86.R_ES = fetch_data_word(srcoffset + 2);
- break;
- case 3: /* register to register */
- /* UNDEFINED! */
- TRACE_AND_STEP();
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ int mod, rh, rl;
+ u16 *dstreg;
+ uint srcoffset;
+
+ START_OF_INSTR();
+ DECODE_PRINTF("LES\t");
+ FETCH_DECODE_MODRM(mod, rh, rl);
+ if (mod < 3) {
+ dstreg = DECODE_RM_WORD_REGISTER(rh);
+ DECODE_PRINTF(",");
+ srcoffset = decode_rmXX_address(mod, rl);
+ DECODE_PRINTF("\n");
+ TRACE_AND_STEP();
+ *dstreg = fetch_data_word(srcoffset);
+ M.x86.R_ES = fetch_data_word(srcoffset + 2);
+ }
+ /* else UNDEFINED! register to register */
+
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/****************************************************************************
@@ -8489,47 +3308,25 @@ Handles opcode 0xc5
****************************************************************************/
void x86emuOp_lds_R_IMM(u8 X86EMU_UNUSED(op1))
{
- int mod, rh, rl;
- u16 *dstreg;
- uint srcoffset;
-
- START_OF_INSTR();
- DECODE_PRINTF("LDS\t");
- FETCH_DECODE_MODRM(mod, rh, rl);
- switch (mod) {
- case 0:
- dstreg = DECODE_RM_WORD_REGISTER(rh);
- DECODE_PRINTF(",");
- srcoffset = decode_rm00_address(rl);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *dstreg = fetch_data_word(srcoffset);
- M.x86.R_DS = fetch_data_word(srcoffset + 2);
- break;
- case 1:
- dstreg = DECODE_RM_WORD_REGISTER(rh);
- DECODE_PRINTF(",");
- srcoffset = decode_rm01_address(rl);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *dstreg = fetch_data_word(srcoffset);
- M.x86.R_DS = fetch_data_word(srcoffset + 2);
- break;
- case 2:
- dstreg = DECODE_RM_WORD_REGISTER(rh);
- DECODE_PRINTF(",");
- srcoffset = decode_rm10_address(rl);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *dstreg = fetch_data_word(srcoffset);
- M.x86.R_DS = fetch_data_word(srcoffset + 2);
- break;
- case 3: /* register to register */
- /* UNDEFINED! */
- TRACE_AND_STEP();
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ int mod, rh, rl;
+ u16 *dstreg;
+ uint srcoffset;
+
+ START_OF_INSTR();
+ DECODE_PRINTF("LDS\t");
+ FETCH_DECODE_MODRM(mod, rh, rl);
+ if (mod < 3) {
+ dstreg = DECODE_RM_WORD_REGISTER(rh);
+ DECODE_PRINTF(",");
+ srcoffset = decode_rmXX_address(mod, rl);
+ DECODE_PRINTF("\n");
+ TRACE_AND_STEP();
+ *dstreg = fetch_data_word(srcoffset);
+ M.x86.R_DS = fetch_data_word(srcoffset + 2);
+ }
+ /* else UNDEFINED! */
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/****************************************************************************
@@ -8538,53 +3335,34 @@ Handles opcode 0xc6
****************************************************************************/
void x86emuOp_mov_byte_RM_IMM(u8 X86EMU_UNUSED(op1))
{
- int mod, rl, rh;
- u8 *destreg;
- uint destoffset;
- u8 imm;
-
- START_OF_INSTR();
- DECODE_PRINTF("MOV\t");
- FETCH_DECODE_MODRM(mod, rh, rl);
- if (rh != 0) {
- DECODE_PRINTF("ILLEGAL DECODE OF OPCODE c6\n");
- HALT_SYS();
- }
- switch (mod) {
- case 0:
- DECODE_PRINTF("BYTE PTR ");
- destoffset = decode_rm00_address(rl);
- imm = fetch_byte_imm();
- DECODE_PRINTF2(",%2x\n", imm);
- TRACE_AND_STEP();
- store_data_byte(destoffset, imm);
- break;
- case 1:
- DECODE_PRINTF("BYTE PTR ");
- destoffset = decode_rm01_address(rl);
- imm = fetch_byte_imm();
- DECODE_PRINTF2(",%2x\n", imm);
- TRACE_AND_STEP();
- store_data_byte(destoffset, imm);
- break;
- case 2:
- DECODE_PRINTF("BYTE PTR ");
- destoffset = decode_rm10_address(rl);
- imm = fetch_byte_imm();
- DECODE_PRINTF2(",%2x\n", imm);
- TRACE_AND_STEP();
- store_data_byte(destoffset, imm);
- break;
- case 3: /* register to register */
- destreg = DECODE_RM_BYTE_REGISTER(rl);
- imm = fetch_byte_imm();
- DECODE_PRINTF2(",%2x\n", imm);
- TRACE_AND_STEP();
- *destreg = imm;
- break;
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ int mod, rl, rh;
+ u8 *destreg;
+ uint destoffset;
+ u8 imm;
+
+ START_OF_INSTR();
+ DECODE_PRINTF("MOV\t");
+ FETCH_DECODE_MODRM(mod, rh, rl);
+ if (rh != 0) {
+ DECODE_PRINTF("ILLEGAL DECODE OF OPCODE c6\n");
+ HALT_SYS();
+ }
+ if (mod < 3) {
+ DECODE_PRINTF("BYTE PTR ");
+ destoffset = decode_rmXX_address(mod, rl);
+ imm = fetch_byte_imm();
+ DECODE_PRINTF2(",%2x\n", imm);
+ TRACE_AND_STEP();
+ store_data_byte(destoffset, imm);
+ } else { /* register to register */
+ destreg = DECODE_RM_BYTE_REGISTER(rl);
+ imm = fetch_byte_imm();
+ DECODE_PRINTF2(",%2x\n", imm);
+ TRACE_AND_STEP();
+ *destreg = imm;
+ }
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/****************************************************************************
@@ -8593,104 +3371,59 @@ Handles opcode 0xc7
****************************************************************************/
void x86emuOp_mov_word_RM_IMM(u8 X86EMU_UNUSED(op1))
{
- int mod, rl, rh;
- uint destoffset;
-
- START_OF_INSTR();
- DECODE_PRINTF("MOV\t");
- FETCH_DECODE_MODRM(mod, rh, rl);
- if (rh != 0) {
- DECODE_PRINTF("ILLEGAL DECODE OF OPCODE 8F\n");
- HALT_SYS();
- }
- switch (mod) {
- case 0:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 imm;
-
- DECODE_PRINTF("DWORD PTR ");
- destoffset = decode_rm00_address(rl);
- imm = fetch_long_imm();
- DECODE_PRINTF2(",%x\n", imm);
- TRACE_AND_STEP();
- store_data_long(destoffset, imm);
- } else {
- u16 imm;
-
- DECODE_PRINTF("WORD PTR ");
- destoffset = decode_rm00_address(rl);
- imm = fetch_word_imm();
- DECODE_PRINTF2(",%x\n", imm);
- TRACE_AND_STEP();
- store_data_word(destoffset, imm);
- }
- break;
- case 1:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 imm;
-
- DECODE_PRINTF("DWORD PTR ");
- destoffset = decode_rm01_address(rl);
- imm = fetch_long_imm();
- DECODE_PRINTF2(",%x\n", imm);
- TRACE_AND_STEP();
- store_data_long(destoffset, imm);
- } else {
- u16 imm;
-
- DECODE_PRINTF("WORD PTR ");
- destoffset = decode_rm01_address(rl);
- imm = fetch_word_imm();
- DECODE_PRINTF2(",%x\n", imm);
- TRACE_AND_STEP();
- store_data_word(destoffset, imm);
- }
- break;
- case 2:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 imm;
-
- DECODE_PRINTF("DWORD PTR ");
- destoffset = decode_rm10_address(rl);
- imm = fetch_long_imm();
- DECODE_PRINTF2(",%x\n", imm);
- TRACE_AND_STEP();
- store_data_long(destoffset, imm);
- } else {
- u16 imm;
-
- DECODE_PRINTF("WORD PTR ");
- destoffset = decode_rm10_address(rl);
- imm = fetch_word_imm();
- DECODE_PRINTF2(",%x\n", imm);
- TRACE_AND_STEP();
- store_data_word(destoffset, imm);
- }
- break;
- case 3: /* register to register */
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+ int mod, rl, rh;
+ uint destoffset;
+
+ START_OF_INSTR();
+ DECODE_PRINTF("MOV\t");
+ FETCH_DECODE_MODRM(mod, rh, rl);
+ if (rh != 0) {
+ DECODE_PRINTF("ILLEGAL DECODE OF OPCODE 8F\n");
+ HALT_SYS();
+ }
+ if (mod < 3) {
+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+ u32 imm;
+
+ DECODE_PRINTF("DWORD PTR ");
+ destoffset = decode_rmXX_address(mod, rl);
+ imm = fetch_long_imm();
+ DECODE_PRINTF2(",%x\n", imm);
+ TRACE_AND_STEP();
+ store_data_long(destoffset, imm);
+ } else {
+ u16 imm;
+
+ DECODE_PRINTF("WORD PTR ");
+ destoffset = decode_rmXX_address(mod, rl);
+ imm = fetch_word_imm();
+ DECODE_PRINTF2(",%x\n", imm);
+ TRACE_AND_STEP();
+ store_data_word(destoffset, imm);
+ }
+ } else { /* register to register */
+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
u32 *destreg;
u32 imm;
- destreg = DECODE_RM_LONG_REGISTER(rl);
- imm = fetch_long_imm();
- DECODE_PRINTF2(",%x\n", imm);
- TRACE_AND_STEP();
- *destreg = imm;
- } else {
+ destreg = DECODE_RM_LONG_REGISTER(rl);
+ imm = fetch_long_imm();
+ DECODE_PRINTF2(",%x\n", imm);
+ TRACE_AND_STEP();
+ *destreg = imm;
+ } else {
u16 *destreg;
u16 imm;
- destreg = DECODE_RM_WORD_REGISTER(rl);
- imm = fetch_word_imm();
- DECODE_PRINTF2(",%x\n", imm);
- TRACE_AND_STEP();
- *destreg = imm;
- }
- break;
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ destreg = DECODE_RM_WORD_REGISTER(rl);
+ imm = fetch_word_imm();
+ DECODE_PRINTF2(",%x\n", imm);
+ TRACE_AND_STEP();
+ *destreg = imm;
+ }
+ }
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/****************************************************************************
@@ -8699,29 +3432,29 @@ Handles opcode 0xc8
****************************************************************************/
void x86emuOp_enter(u8 X86EMU_UNUSED(op1))
{
- u16 local, frame_pointer;
- u8 nesting;
- int i;
-
- START_OF_INSTR();
- local = fetch_word_imm();
- nesting = fetch_byte_imm();
- DECODE_PRINTF2("ENTER %x\n", local);
- DECODE_PRINTF2(",%x\n", nesting);
- TRACE_AND_STEP();
- push_word(M.x86.R_BP);
- 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));
- }
- push_word(frame_pointer);
- }
- M.x86.R_BP = frame_pointer;
- M.x86.R_SP = (u16) (M.x86.R_SP - local);
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ u16 local,frame_pointer;
+ u8 nesting;
+ int i;
+
+ START_OF_INSTR();
+ local = fetch_word_imm();
+ nesting = fetch_byte_imm();
+ DECODE_PRINTF2("ENTER %x\n", local);
+ DECODE_PRINTF2(",%x\n", nesting);
+ TRACE_AND_STEP();
+ push_word(M.x86.R_BP);
+ 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));
+ }
+ push_word(frame_pointer);
+ }
+ M.x86.R_BP = frame_pointer;
+ M.x86.R_SP = (u16)(M.x86.R_SP - local);
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/****************************************************************************
@@ -8730,13 +3463,13 @@ Handles opcode 0xc9
****************************************************************************/
void x86emuOp_leave(u8 X86EMU_UNUSED(op1))
{
- START_OF_INSTR();
- DECODE_PRINTF("LEAVE\n");
- TRACE_AND_STEP();
- M.x86.R_SP = M.x86.R_BP;
- M.x86.R_BP = pop_word();
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ START_OF_INSTR();
+ DECODE_PRINTF("LEAVE\n");
+ TRACE_AND_STEP();
+ M.x86.R_SP = M.x86.R_BP;
+ M.x86.R_BP = pop_word();
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/****************************************************************************
@@ -8745,19 +3478,19 @@ Handles opcode 0xca
****************************************************************************/
void x86emuOp_ret_far_IMM(u8 X86EMU_UNUSED(op1))
{
- u16 imm;
+ u16 imm;
- START_OF_INSTR();
- DECODE_PRINTF("RETF\t");
- imm = fetch_word_imm();
- DECODE_PRINTF2("%x\n", imm);
- RETURN_TRACE("RETF", M.x86.saved_cs, M.x86.saved_ip);
+ START_OF_INSTR();
+ DECODE_PRINTF("RETF\t");
+ imm = fetch_word_imm();
+ 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();
- M.x86.R_SP += imm;
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ M.x86.R_IP = pop_word();
+ M.x86.R_CS = pop_word();
+ M.x86.R_SP += imm;
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/****************************************************************************
@@ -8766,14 +3499,14 @@ Handles opcode 0xcb
****************************************************************************/
void x86emuOp_ret_far(u8 X86EMU_UNUSED(op1))
{
- START_OF_INSTR();
- DECODE_PRINTF("RETF\n");
- RETURN_TRACE("RETF", M.x86.saved_cs, M.x86.saved_ip);
+ START_OF_INSTR();
+ 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();
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ M.x86.R_IP = pop_word();
+ M.x86.R_CS = pop_word();
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/****************************************************************************
@@ -8782,22 +3515,26 @@ Handles opcode 0xcc
****************************************************************************/
void x86emuOp_int3(u8 X86EMU_UNUSED(op1))
{
- START_OF_INSTR();
- DECODE_PRINTF("INT 3\n");
- TRACE_AND_STEP();
+ u16 tmp;
+
+ START_OF_INSTR();
+ DECODE_PRINTF("INT 3\n");
+ tmp = (u16) mem_access_word(3 * 4 + 2);
+ /* access the segment register */
+ TRACE_AND_STEP();
if (_X86EMU_intrTab[3]) {
- (*_X86EMU_intrTab[3]) (3);
- } else {
- push_word((u16) M.x86.R_FLG);
- CLEAR_FLAG(F_IF);
- CLEAR_FLAG(F_TF);
- push_word(M.x86.R_CS);
- M.x86.R_CS = mem_access_word(3 * 4 + 2);
- push_word(M.x86.R_IP);
- M.x86.R_IP = mem_access_word(3 * 4);
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ (*_X86EMU_intrTab[3])(3);
+ } else {
+ push_word((u16)M.x86.R_FLG);
+ CLEAR_FLAG(F_IF);
+ CLEAR_FLAG(F_TF);
+ push_word(M.x86.R_CS);
+ M.x86.R_CS = mem_access_word(3 * 4 + 2);
+ push_word(M.x86.R_IP);
+ M.x86.R_IP = mem_access_word(3 * 4);
+ }
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/****************************************************************************
@@ -8806,26 +3543,28 @@ Handles opcode 0xcd
****************************************************************************/
void x86emuOp_int_IMM(u8 X86EMU_UNUSED(op1))
{
- u8 intnum;
+ u16 tmp;
+ u8 intnum;
- START_OF_INSTR();
- DECODE_PRINTF("INT\t");
- intnum = fetch_byte_imm();
- DECODE_PRINTF2("%x\n", intnum);
- TRACE_AND_STEP();
+ START_OF_INSTR();
+ DECODE_PRINTF("INT\t");
+ intnum = fetch_byte_imm();
+ DECODE_PRINTF2("%x\n", intnum);
+ tmp = mem_access_word(intnum * 4 + 2);
+ TRACE_AND_STEP();
if (_X86EMU_intrTab[intnum]) {
- (*_X86EMU_intrTab[intnum]) (intnum);
- } else {
- push_word((u16) M.x86.R_FLG);
- CLEAR_FLAG(F_IF);
- CLEAR_FLAG(F_TF);
- push_word(M.x86.R_CS);
- M.x86.R_CS = mem_access_word(intnum * 4 + 2);
- push_word(M.x86.R_IP);
- M.x86.R_IP = mem_access_word(intnum * 4);
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ (*_X86EMU_intrTab[intnum])(intnum);
+ } else {
+ push_word((u16)M.x86.R_FLG);
+ CLEAR_FLAG(F_IF);
+ CLEAR_FLAG(F_TF);
+ push_word(M.x86.R_CS);
+ M.x86.R_CS = mem_access_word(intnum * 4 + 2);
+ push_word(M.x86.R_IP);
+ M.x86.R_IP = mem_access_word(intnum * 4);
+ }
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/****************************************************************************
@@ -8834,24 +3573,27 @@ Handles opcode 0xce
****************************************************************************/
void x86emuOp_into(u8 X86EMU_UNUSED(op1))
{
- START_OF_INSTR();
- DECODE_PRINTF("INTO\n");
- TRACE_AND_STEP();
- if (ACCESS_FLAG(F_OF)) {
+ u16 tmp;
+
+ START_OF_INSTR();
+ DECODE_PRINTF("INTO\n");
+ TRACE_AND_STEP();
+ if (ACCESS_FLAG(F_OF)) {
+ tmp = mem_access_word(4 * 4 + 2);
if (_X86EMU_intrTab[4]) {
- (*_X86EMU_intrTab[4]) (4);
- } else {
- push_word((u16) M.x86.R_FLG);
- CLEAR_FLAG(F_IF);
- CLEAR_FLAG(F_TF);
- push_word(M.x86.R_CS);
- M.x86.R_CS = mem_access_word(4 * 4 + 2);
- push_word(M.x86.R_IP);
- M.x86.R_IP = mem_access_word(4 * 4);
- }
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ (*_X86EMU_intrTab[4])(4);
+ } else {
+ push_word((u16)M.x86.R_FLG);
+ CLEAR_FLAG(F_IF);
+ CLEAR_FLAG(F_TF);
+ push_word(M.x86.R_CS);
+ M.x86.R_CS = mem_access_word(4 * 4 + 2);
+ push_word(M.x86.R_IP);
+ M.x86.R_IP = mem_access_word(4 * 4);
+ }
+ }
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/****************************************************************************
@@ -8860,16 +3602,16 @@ Handles opcode 0xcf
****************************************************************************/
void x86emuOp_iret(u8 X86EMU_UNUSED(op1))
{
- START_OF_INSTR();
- DECODE_PRINTF("IRET\n");
+ START_OF_INSTR();
+ DECODE_PRINTF("IRET\n");
- TRACE_AND_STEP();
+ TRACE_AND_STEP();
- M.x86.R_IP = pop_word();
- M.x86.R_CS = pop_word();
- M.x86.R_FLG = pop_word();
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ M.x86.R_IP = pop_word();
+ M.x86.R_CS = pop_word();
+ M.x86.R_FLG = pop_word();
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/****************************************************************************
@@ -8878,92 +3620,71 @@ Handles opcode 0xd0
****************************************************************************/
void x86emuOp_opcD0_byte_RM_1(u8 X86EMU_UNUSED(op1))
{
- int mod, rl, rh;
- u8 *destreg;
- uint destoffset;
- u8 destval;
-
- /*
- * Yet another weirdo special case instruction format. Part of
- * the opcode held below in "RH". Doubly nested case would
- * result, except that the decoded instruction
- */
- START_OF_INSTR();
- FETCH_DECODE_MODRM(mod, rh, rl);
+ int mod, rl, rh;
+ u8 *destreg;
+ uint destoffset;
+ u8 destval;
+
+ /*
+ * Yet another weirdo special case instruction format. Part of
+ * the opcode held below in "RH". Doubly nested case would
+ * result, except that the decoded instruction
+ */
+ START_OF_INSTR();
+ FETCH_DECODE_MODRM(mod, rh, rl);
#ifdef DEBUG
- if (DEBUG_DECODE()) {
- /* XXX DECODE_PRINTF may be changed to something more
- general, so that it is important to leave the strings
- in the same format, even though the result is that the
- above test is done twice. */
- switch (rh) {
- case 0:
- DECODE_PRINTF("ROL\t");
- break;
- case 1:
- DECODE_PRINTF("ROR\t");
- break;
- case 2:
- DECODE_PRINTF("RCL\t");
- break;
- case 3:
- DECODE_PRINTF("RCR\t");
- break;
- case 4:
- DECODE_PRINTF("SHL\t");
- break;
- case 5:
- DECODE_PRINTF("SHR\t");
- break;
- case 6:
- DECODE_PRINTF("SAL\t");
- break;
- case 7:
- DECODE_PRINTF("SAR\t");
- break;
- }
- }
+ if (DEBUG_DECODE()) {
+ /* XXX DECODE_PRINTF may be changed to something more
+ general, so that it is important to leave the strings
+ in the same format, even though the result is that the
+ above test is done twice. */
+ switch (rh) {
+ case 0:
+ DECODE_PRINTF("ROL\t");
+ break;
+ case 1:
+ DECODE_PRINTF("ROR\t");
+ break;
+ case 2:
+ DECODE_PRINTF("RCL\t");
+ break;
+ case 3:
+ DECODE_PRINTF("RCR\t");
+ break;
+ case 4:
+ DECODE_PRINTF("SHL\t");
+ break;
+ case 5:
+ DECODE_PRINTF("SHR\t");
+ break;
+ case 6:
+ DECODE_PRINTF("SAL\t");
+ break;
+ case 7:
+ DECODE_PRINTF("SAR\t");
+ break;
+ }
+ }
#endif
- /* know operation, decode the mod byte to find the addressing
- mode. */
- switch (mod) {
- case 0:
- DECODE_PRINTF("BYTE PTR ");
- destoffset = decode_rm00_address(rl);
- DECODE_PRINTF(",1\n");
- destval = fetch_data_byte(destoffset);
- TRACE_AND_STEP();
- destval = (*opcD0_byte_operation[rh]) (destval, 1);
- store_data_byte(destoffset, destval);
- break;
- case 1:
- DECODE_PRINTF("BYTE PTR ");
- destoffset = decode_rm01_address(rl);
- DECODE_PRINTF(",1\n");
- destval = fetch_data_byte(destoffset);
- TRACE_AND_STEP();
- destval = (*opcD0_byte_operation[rh]) (destval, 1);
- store_data_byte(destoffset, destval);
- break;
- case 2:
- DECODE_PRINTF("BYTE PTR ");
- destoffset = decode_rm10_address(rl);
- DECODE_PRINTF(",1\n");
- destval = fetch_data_byte(destoffset);
- TRACE_AND_STEP();
- destval = (*opcD0_byte_operation[rh]) (destval, 1);
- store_data_byte(destoffset, destval);
- break;
- case 3: /* register to register */
- destreg = DECODE_RM_BYTE_REGISTER(rl);
- DECODE_PRINTF(",1\n");
- TRACE_AND_STEP();
- destval = (*opcD0_byte_operation[rh]) (*destreg, 1);
- *destreg = destval;
- break;
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ /* know operation, decode the mod byte to find the addressing
+ mode. */
+ if (mod < 3) {
+ DECODE_PRINTF("BYTE PTR ");
+ destoffset = decode_rmXX_address(mod, rl);
+ DECODE_PRINTF(",1\n");
+ destval = fetch_data_byte(destoffset);
+ TRACE_AND_STEP();
+ destval = (*opcD0_byte_operation[rh]) (destval, 1);
+ store_data_byte(destoffset, destval);
+ } else { /* register to register */
+ destreg = DECODE_RM_BYTE_REGISTER(rl);
+ DECODE_PRINTF(",1\n");
+ TRACE_AND_STEP();
+ destval = (*opcD0_byte_operation[rh]) (*destreg, 1);
+ *destreg = destval;
+ }
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/****************************************************************************
@@ -8972,146 +3693,97 @@ Handles opcode 0xd1
****************************************************************************/
void x86emuOp_opcD1_word_RM_1(u8 X86EMU_UNUSED(op1))
{
- int mod, rl, rh;
- uint destoffset;
+ int mod, rl, rh;
+ uint destoffset;
- /*
- * Yet another weirdo special case instruction format. Part of
- * the opcode held below in "RH". Doubly nested case would
- * result, except that the decoded instruction
- */
- START_OF_INSTR();
- FETCH_DECODE_MODRM(mod, rh, rl);
+ /*
+ * Yet another weirdo special case instruction format. Part of
+ * the opcode held below in "RH". Doubly nested case would
+ * result, except that the decoded instruction
+ */
+ START_OF_INSTR();
+ FETCH_DECODE_MODRM(mod, rh, rl);
#ifdef DEBUG
- if (DEBUG_DECODE()) {
- /* XXX DECODE_PRINTF may be changed to something more
- general, so that it is important to leave the strings
- in the same format, even though the result is that the
- above test is done twice. */
- switch (rh) {
- case 0:
- DECODE_PRINTF("ROL\t");
- break;
- case 1:
- DECODE_PRINTF("ROR\t");
- break;
- case 2:
- DECODE_PRINTF("RCL\t");
- break;
- case 3:
- DECODE_PRINTF("RCR\t");
- break;
- case 4:
- DECODE_PRINTF("SHL\t");
- break;
- case 5:
- DECODE_PRINTF("SHR\t");
- break;
- case 6:
- DECODE_PRINTF("SAL\t");
- break;
- case 7:
- DECODE_PRINTF("SAR\t");
- break;
- }
- }
+ if (DEBUG_DECODE()) {
+ /* XXX DECODE_PRINTF may be changed to something more
+ general, so that it is important to leave the strings
+ in the same format, even though the result is that the
+ above test is done twice. */
+ switch (rh) {
+ case 0:
+ DECODE_PRINTF("ROL\t");
+ break;
+ case 1:
+ DECODE_PRINTF("ROR\t");
+ break;
+ case 2:
+ DECODE_PRINTF("RCL\t");
+ break;
+ case 3:
+ DECODE_PRINTF("RCR\t");
+ break;
+ case 4:
+ DECODE_PRINTF("SHL\t");
+ break;
+ case 5:
+ DECODE_PRINTF("SHR\t");
+ break;
+ case 6:
+ DECODE_PRINTF("SAL\t");
+ break;
+ case 7:
+ DECODE_PRINTF("SAR\t");
+ break;
+ }
+ }
#endif
- /* know operation, decode the mod byte to find the addressing
- mode. */
- switch (mod) {
- case 0:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 destval;
-
- DECODE_PRINTF("DWORD PTR ");
- destoffset = decode_rm00_address(rl);
- DECODE_PRINTF(",1\n");
- destval = fetch_data_long(destoffset);
- TRACE_AND_STEP();
- destval = (*opcD1_long_operation[rh]) (destval, 1);
- store_data_long(destoffset, destval);
- } else {
- u16 destval;
-
- DECODE_PRINTF("WORD PTR ");
- destoffset = decode_rm00_address(rl);
- DECODE_PRINTF(",1\n");
- destval = fetch_data_word(destoffset);
- TRACE_AND_STEP();
- destval = (*opcD1_word_operation[rh]) (destval, 1);
- store_data_word(destoffset, destval);
- }
- break;
- case 1:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 destval;
-
- DECODE_PRINTF("DWORD PTR ");
- destoffset = decode_rm01_address(rl);
- DECODE_PRINTF(",1\n");
- destval = fetch_data_long(destoffset);
- TRACE_AND_STEP();
- destval = (*opcD1_long_operation[rh]) (destval, 1);
- store_data_long(destoffset, destval);
- } else {
- u16 destval;
-
- DECODE_PRINTF("WORD PTR ");
- destoffset = decode_rm01_address(rl);
- DECODE_PRINTF(",1\n");
- destval = fetch_data_word(destoffset);
- TRACE_AND_STEP();
- destval = (*opcD1_word_operation[rh]) (destval, 1);
- store_data_word(destoffset, destval);
- }
- break;
- case 2:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 destval;
-
- DECODE_PRINTF("DWORD PTR ");
- destoffset = decode_rm10_address(rl);
- DECODE_PRINTF(",1\n");
- destval = fetch_data_long(destoffset);
- TRACE_AND_STEP();
- destval = (*opcD1_long_operation[rh]) (destval, 1);
- store_data_long(destoffset, destval);
- } else {
- u16 destval;
-
- DECODE_PRINTF("BYTE PTR ");
- destoffset = decode_rm10_address(rl);
- DECODE_PRINTF(",1\n");
- destval = fetch_data_word(destoffset);
- TRACE_AND_STEP();
- destval = (*opcD1_word_operation[rh]) (destval, 1);
- store_data_word(destoffset, destval);
- }
- break;
- case 3: /* register to register */
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+ /* know operation, decode the mod byte to find the addressing
+ mode. */
+ if (mod < 3) {
+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+ u32 destval;
+
+ DECODE_PRINTF("DWORD PTR ");
+ destoffset = decode_rmXX_address(mod, rl);
+ DECODE_PRINTF(",1\n");
+ destval = fetch_data_long(destoffset);
+ TRACE_AND_STEP();
+ destval = (*opcD1_long_operation[rh]) (destval, 1);
+ store_data_long(destoffset, destval);
+ } else {
+ u16 destval;
+
+ DECODE_PRINTF("WORD PTR ");
+ destoffset = decode_rmXX_address(mod, rl);
+ DECODE_PRINTF(",1\n");
+ destval = fetch_data_word(destoffset);
+ TRACE_AND_STEP();
+ destval = (*opcD1_word_operation[rh]) (destval, 1);
+ store_data_word(destoffset, destval);
+ }
+ } else { /* register to register */
+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
u32 destval;
u32 *destreg;
- destreg = DECODE_RM_LONG_REGISTER(rl);
- DECODE_PRINTF(",1\n");
- TRACE_AND_STEP();
- destval = (*opcD1_long_operation[rh]) (*destreg, 1);
- *destreg = destval;
- } else {
+ destreg = DECODE_RM_LONG_REGISTER(rl);
+ DECODE_PRINTF(",1\n");
+ TRACE_AND_STEP();
+ destval = (*opcD1_long_operation[rh]) (*destreg, 1);
+ *destreg = destval;
+ } else {
u16 destval;
u16 *destreg;
- destreg = DECODE_RM_WORD_REGISTER(rl);
- DECODE_PRINTF(",1\n");
- TRACE_AND_STEP();
- destval = (*opcD1_word_operation[rh]) (*destreg, 1);
- *destreg = destval;
- }
- break;
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ destreg = DECODE_RM_WORD_REGISTER(rl);
+ DECODE_PRINTF(",1\n");
+ TRACE_AND_STEP();
+ destval = (*opcD1_word_operation[rh]) (*destreg, 1);
+ *destreg = destval;
+ }
+ }
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/****************************************************************************
@@ -9120,94 +3792,73 @@ Handles opcode 0xd2
****************************************************************************/
void x86emuOp_opcD2_byte_RM_CL(u8 X86EMU_UNUSED(op1))
{
- int mod, rl, rh;
- u8 *destreg;
- uint destoffset;
- u8 destval;
- u8 amt;
-
- /*
- * Yet another weirdo special case instruction format. Part of
- * the opcode held below in "RH". Doubly nested case would
- * result, except that the decoded instruction
- */
- START_OF_INSTR();
- FETCH_DECODE_MODRM(mod, rh, rl);
+ int mod, rl, rh;
+ u8 *destreg;
+ uint destoffset;
+ u8 destval;
+ u8 amt;
+
+ /*
+ * Yet another weirdo special case instruction format. Part of
+ * the opcode held below in "RH". Doubly nested case would
+ * result, except that the decoded instruction
+ */
+ START_OF_INSTR();
+ FETCH_DECODE_MODRM(mod, rh, rl);
#ifdef DEBUG
- if (DEBUG_DECODE()) {
- /* XXX DECODE_PRINTF may be changed to something more
- general, so that it is important to leave the strings
- in the same format, even though the result is that the
- above test is done twice. */
- switch (rh) {
- case 0:
- DECODE_PRINTF("ROL\t");
- break;
- case 1:
- DECODE_PRINTF("ROR\t");
- break;
- case 2:
- DECODE_PRINTF("RCL\t");
- break;
- case 3:
- DECODE_PRINTF("RCR\t");
- break;
- case 4:
- DECODE_PRINTF("SHL\t");
- break;
- case 5:
- DECODE_PRINTF("SHR\t");
- break;
- case 6:
- DECODE_PRINTF("SAL\t");
- break;
- case 7:
- DECODE_PRINTF("SAR\t");
- break;
- }
- }
+ if (DEBUG_DECODE()) {
+ /* XXX DECODE_PRINTF may be changed to something more
+ general, so that it is important to leave the strings
+ in the same format, even though the result is that the
+ above test is done twice. */
+ switch (rh) {
+ case 0:
+ DECODE_PRINTF("ROL\t");
+ break;
+ case 1:
+ DECODE_PRINTF("ROR\t");
+ break;
+ case 2:
+ DECODE_PRINTF("RCL\t");
+ break;
+ case 3:
+ DECODE_PRINTF("RCR\t");
+ break;
+ case 4:
+ DECODE_PRINTF("SHL\t");
+ break;
+ case 5:
+ DECODE_PRINTF("SHR\t");
+ break;
+ case 6:
+ DECODE_PRINTF("SAL\t");
+ break;
+ case 7:
+ DECODE_PRINTF("SAR\t");
+ break;
+ }
+ }
#endif
- /* know operation, decode the mod byte to find the addressing
- mode. */
- amt = M.x86.R_CL;
- switch (mod) {
- case 0:
- DECODE_PRINTF("BYTE PTR ");
- destoffset = decode_rm00_address(rl);
- DECODE_PRINTF(",CL\n");
- destval = fetch_data_byte(destoffset);
- TRACE_AND_STEP();
- destval = (*opcD0_byte_operation[rh]) (destval, amt);
- store_data_byte(destoffset, destval);
- break;
- case 1:
- DECODE_PRINTF("BYTE PTR ");
- destoffset = decode_rm01_address(rl);
- DECODE_PRINTF(",CL\n");
- destval = fetch_data_byte(destoffset);
- TRACE_AND_STEP();
- destval = (*opcD0_byte_operation[rh]) (destval, amt);
- store_data_byte(destoffset, destval);
- break;
- case 2:
- DECODE_PRINTF("BYTE PTR ");
- destoffset = decode_rm10_address(rl);
- DECODE_PRINTF(",CL\n");
- destval = fetch_data_byte(destoffset);
- TRACE_AND_STEP();
- destval = (*opcD0_byte_operation[rh]) (destval, amt);
- store_data_byte(destoffset, destval);
- break;
- case 3: /* register to register */
- destreg = DECODE_RM_BYTE_REGISTER(rl);
- DECODE_PRINTF(",CL\n");
- TRACE_AND_STEP();
- destval = (*opcD0_byte_operation[rh]) (*destreg, amt);
- *destreg = destval;
- break;
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ /* know operation, decode the mod byte to find the addressing
+ mode. */
+ amt = M.x86.R_CL;
+ if (mod < 3) {
+ DECODE_PRINTF("BYTE PTR ");
+ destoffset = decode_rmXX_address(mod, rl);
+ DECODE_PRINTF(",CL\n");
+ destval = fetch_data_byte(destoffset);
+ TRACE_AND_STEP();
+ destval = (*opcD0_byte_operation[rh]) (destval, amt);
+ store_data_byte(destoffset, destval);
+ } else { /* register to register */
+ destreg = DECODE_RM_BYTE_REGISTER(rl);
+ DECODE_PRINTF(",CL\n");
+ TRACE_AND_STEP();
+ destval = (*opcD0_byte_operation[rh]) (*destreg, amt);
+ *destreg = destval;
+ }
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/****************************************************************************
@@ -9216,144 +3867,95 @@ Handles opcode 0xd3
****************************************************************************/
void x86emuOp_opcD3_word_RM_CL(u8 X86EMU_UNUSED(op1))
{
- int mod, rl, rh;
- uint destoffset;
- u8 amt;
-
- /*
- * Yet another weirdo special case instruction format. Part of
- * the opcode held below in "RH". Doubly nested case would
- * result, except that the decoded instruction
- */
- START_OF_INSTR();
- FETCH_DECODE_MODRM(mod, rh, rl);
+ int mod, rl, rh;
+ uint destoffset;
+ u8 amt;
+
+ /*
+ * Yet another weirdo special case instruction format. Part of
+ * the opcode held below in "RH". Doubly nested case would
+ * result, except that the decoded instruction
+ */
+ START_OF_INSTR();
+ FETCH_DECODE_MODRM(mod, rh, rl);
#ifdef DEBUG
- if (DEBUG_DECODE()) {
- /* XXX DECODE_PRINTF may be changed to something more
- general, so that it is important to leave the strings
- in the same format, even though the result is that the
- above test is done twice. */
- switch (rh) {
- case 0:
- DECODE_PRINTF("ROL\t");
- break;
- case 1:
- DECODE_PRINTF("ROR\t");
- break;
- case 2:
- DECODE_PRINTF("RCL\t");
- break;
- case 3:
- DECODE_PRINTF("RCR\t");
- break;
- case 4:
- DECODE_PRINTF("SHL\t");
- break;
- case 5:
- DECODE_PRINTF("SHR\t");
- break;
- case 6:
- DECODE_PRINTF("SAL\t");
- break;
- case 7:
- DECODE_PRINTF("SAR\t");
- break;
- }
- }
+ if (DEBUG_DECODE()) {
+ /* XXX DECODE_PRINTF may be changed to something more
+ general, so that it is important to leave the strings
+ in the same format, even though the result is that the
+ above test is done twice. */
+ switch (rh) {
+ case 0:
+ DECODE_PRINTF("ROL\t");
+ break;
+ case 1:
+ DECODE_PRINTF("ROR\t");
+ break;
+ case 2:
+ DECODE_PRINTF("RCL\t");
+ break;
+ case 3:
+ DECODE_PRINTF("RCR\t");
+ break;
+ case 4:
+ DECODE_PRINTF("SHL\t");
+ break;
+ case 5:
+ DECODE_PRINTF("SHR\t");
+ break;
+ case 6:
+ DECODE_PRINTF("SAL\t");
+ break;
+ case 7:
+ DECODE_PRINTF("SAR\t");
+ break;
+ }
+ }
#endif
- /* know operation, decode the mod byte to find the addressing
- mode. */
- amt = M.x86.R_CL;
- switch (mod) {
- case 0:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 destval;
-
- DECODE_PRINTF("DWORD PTR ");
- destoffset = decode_rm00_address(rl);
- DECODE_PRINTF(",CL\n");
- destval = fetch_data_long(destoffset);
- TRACE_AND_STEP();
- destval = (*opcD1_long_operation[rh]) (destval, amt);
- store_data_long(destoffset, destval);
- } else {
- u16 destval;
-
- DECODE_PRINTF("WORD PTR ");
- destoffset = decode_rm00_address(rl);
- DECODE_PRINTF(",CL\n");
- destval = fetch_data_word(destoffset);
- TRACE_AND_STEP();
- destval = (*opcD1_word_operation[rh]) (destval, amt);
- store_data_word(destoffset, destval);
- }
- break;
- case 1:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 destval;
-
- DECODE_PRINTF("DWORD PTR ");
- destoffset = decode_rm01_address(rl);
- DECODE_PRINTF(",CL\n");
- destval = fetch_data_long(destoffset);
- TRACE_AND_STEP();
- destval = (*opcD1_long_operation[rh]) (destval, amt);
- store_data_long(destoffset, destval);
- } else {
- u16 destval;
-
- DECODE_PRINTF("WORD PTR ");
- destoffset = decode_rm01_address(rl);
- DECODE_PRINTF(",CL\n");
- destval = fetch_data_word(destoffset);
- TRACE_AND_STEP();
- destval = (*opcD1_word_operation[rh]) (destval, amt);
- store_data_word(destoffset, destval);
- }
- break;
- case 2:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 destval;
-
- DECODE_PRINTF("DWORD PTR ");
- destoffset = decode_rm10_address(rl);
- DECODE_PRINTF(",CL\n");
- destval = fetch_data_long(destoffset);
- TRACE_AND_STEP();
- destval = (*opcD1_long_operation[rh]) (destval, amt);
- store_data_long(destoffset, destval);
- } else {
- u16 destval;
-
- DECODE_PRINTF("WORD PTR ");
- destoffset = decode_rm10_address(rl);
- DECODE_PRINTF(",CL\n");
- destval = fetch_data_word(destoffset);
- TRACE_AND_STEP();
- destval = (*opcD1_word_operation[rh]) (destval, amt);
- store_data_word(destoffset, destval);
- }
- break;
- case 3: /* register to register */
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 *destreg;
-
- destreg = DECODE_RM_LONG_REGISTER(rl);
- DECODE_PRINTF(",CL\n");
- TRACE_AND_STEP();
- *destreg = (*opcD1_long_operation[rh]) (*destreg, amt);
- } else {
- u16 *destreg;
-
- destreg = DECODE_RM_WORD_REGISTER(rl);
- DECODE_PRINTF(",CL\n");
- TRACE_AND_STEP();
- *destreg = (*opcD1_word_operation[rh]) (*destreg, amt);
- }
- break;
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ /* know operation, decode the mod byte to find the addressing
+ mode. */
+ amt = M.x86.R_CL;
+ if (mod < 3) {
+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+ u32 destval;
+
+ DECODE_PRINTF("DWORD PTR ");
+ destoffset = decode_rmXX_address(mod, rl);
+ DECODE_PRINTF(",CL\n");
+ destval = fetch_data_long(destoffset);
+ TRACE_AND_STEP();
+ destval = (*opcD1_long_operation[rh]) (destval, amt);
+ store_data_long(destoffset, destval);
+ } else {
+ u16 destval;
+
+ DECODE_PRINTF("WORD PTR ");
+ destoffset = decode_rmXX_address(mod, rl);
+ DECODE_PRINTF(",CL\n");
+ destval = fetch_data_word(destoffset);
+ TRACE_AND_STEP();
+ destval = (*opcD1_word_operation[rh]) (destval, amt);
+ store_data_word(destoffset, destval);
+ }
+ } else { /* register to register */
+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+ u32 *destreg;
+
+ destreg = DECODE_RM_LONG_REGISTER(rl);
+ DECODE_PRINTF(",CL\n");
+ TRACE_AND_STEP();
+ *destreg = (*opcD1_long_operation[rh]) (*destreg, amt);
+ } else {
+ u16 *destreg;
+
+ destreg = DECODE_RM_WORD_REGISTER(rl);
+ DECODE_PRINTF(",CL\n");
+ TRACE_AND_STEP();
+ *destreg = (*opcD1_word_operation[rh]) (*destreg, amt);
+ }
+ }
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/****************************************************************************
@@ -9362,21 +3964,21 @@ Handles opcode 0xd4
****************************************************************************/
void x86emuOp_aam(u8 X86EMU_UNUSED(op1))
{
- u8 a;
+ u8 a;
- START_OF_INSTR();
- DECODE_PRINTF("AAM\n");
- a = fetch_byte_imm(); /* this is a stupid encoding. */
- if (a != 10) {
- DECODE_PRINTF("ERROR DECODING AAM\n");
- TRACE_REGS();
- HALT_SYS();
- }
- TRACE_AND_STEP();
- /* note the type change here --- returning AL and AH in AX. */
- M.x86.R_AX = aam_word(M.x86.R_AL);
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ START_OF_INSTR();
+ DECODE_PRINTF("AAM\n");
+ a = fetch_byte_imm(); /* this is a stupid encoding. */
+ if (a != 10) {
+ DECODE_PRINTF("ERROR DECODING AAM\n");
+ TRACE_REGS();
+ HALT_SYS();
+ }
+ TRACE_AND_STEP();
+ /* note the type change here --- returning AL and AH in AX. */
+ M.x86.R_AX = aam_word(M.x86.R_AL);
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/****************************************************************************
@@ -9385,15 +3987,15 @@ Handles opcode 0xd5
****************************************************************************/
void x86emuOp_aad(u8 X86EMU_UNUSED(op1))
{
- u8 a;
+ u8 a;
- START_OF_INSTR();
- DECODE_PRINTF("AAD\n");
- a = fetch_byte_imm();
- TRACE_AND_STEP();
- M.x86.R_AX = aad_word(M.x86.R_AX);
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ START_OF_INSTR();
+ DECODE_PRINTF("AAD\n");
+ a = fetch_byte_imm();
+ TRACE_AND_STEP();
+ M.x86.R_AX = aad_word(M.x86.R_AX);
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/* opcode 0xd6 ILLEGAL OPCODE */
@@ -9404,15 +4006,15 @@ Handles opcode 0xd7
****************************************************************************/
void x86emuOp_xlat(u8 X86EMU_UNUSED(op1))
{
- u16 addr;
+ u16 addr;
- START_OF_INSTR();
- DECODE_PRINTF("XLAT\n");
- TRACE_AND_STEP();
- addr = (u16) (M.x86.R_BX + (u8) M.x86.R_AL);
- M.x86.R_AL = fetch_data_byte(addr);
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ START_OF_INSTR();
+ DECODE_PRINTF("XLAT\n");
+ TRACE_AND_STEP();
+ addr = (u16)(M.x86.R_BX + (u8)M.x86.R_AL);
+ M.x86.R_AL = fetch_data_byte(addr);
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/* instuctions D8 .. DF are in i87_ops.c */
@@ -9423,19 +4025,19 @@ Handles opcode 0xe0
****************************************************************************/
void x86emuOp_loopne(u8 X86EMU_UNUSED(op1))
{
- s16 ip;
+ s16 ip;
- START_OF_INSTR();
- DECODE_PRINTF("LOOPNE\t");
- ip = (s8) fetch_byte_imm();
- ip += (s16) M.x86.R_IP;
- DECODE_PRINTF2("%04x\n", ip);
- TRACE_AND_STEP();
- M.x86.R_CX -= 1;
- if (M.x86.R_CX != 0 && !ACCESS_FLAG(F_ZF)) /* CX != 0 and !ZF */
- M.x86.R_IP = ip;
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ START_OF_INSTR();
+ DECODE_PRINTF("LOOPNE\t");
+ ip = (s8) fetch_byte_imm();
+ ip += (s16) M.x86.R_IP;
+ DECODE_PRINTF2("%04x\n", ip);
+ TRACE_AND_STEP();
+ M.x86.R_CX -= 1;
+ if (M.x86.R_CX != 0 && !ACCESS_FLAG(F_ZF)) /* CX != 0 and !ZF */
+ M.x86.R_IP = ip;
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/****************************************************************************
@@ -9444,19 +4046,19 @@ Handles opcode 0xe1
****************************************************************************/
void x86emuOp_loope(u8 X86EMU_UNUSED(op1))
{
- s16 ip;
+ s16 ip;
- START_OF_INSTR();
- DECODE_PRINTF("LOOPE\t");
- ip = (s8) fetch_byte_imm();
- ip += (s16) M.x86.R_IP;
- DECODE_PRINTF2("%04x\n", ip);
- TRACE_AND_STEP();
- M.x86.R_CX -= 1;
- if (M.x86.R_CX != 0 && ACCESS_FLAG(F_ZF)) /* CX != 0 and ZF */
- M.x86.R_IP = ip;
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ START_OF_INSTR();
+ DECODE_PRINTF("LOOPE\t");
+ ip = (s8) fetch_byte_imm();
+ ip += (s16) M.x86.R_IP;
+ DECODE_PRINTF2("%04x\n", ip);
+ TRACE_AND_STEP();
+ M.x86.R_CX -= 1;
+ if (M.x86.R_CX != 0 && ACCESS_FLAG(F_ZF)) /* CX != 0 and ZF */
+ M.x86.R_IP = ip;
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/****************************************************************************
@@ -9465,19 +4067,19 @@ Handles opcode 0xe2
****************************************************************************/
void x86emuOp_loop(u8 X86EMU_UNUSED(op1))
{
- s16 ip;
+ s16 ip;
- START_OF_INSTR();
- DECODE_PRINTF("LOOP\t");
- ip = (s8) fetch_byte_imm();
- ip += (s16) M.x86.R_IP;
- DECODE_PRINTF2("%04x\n", ip);
- TRACE_AND_STEP();
- M.x86.R_CX -= 1;
- if (M.x86.R_CX != 0)
- M.x86.R_IP = ip;
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ START_OF_INSTR();
+ DECODE_PRINTF("LOOP\t");
+ ip = (s8) fetch_byte_imm();
+ ip += (s16) M.x86.R_IP;
+ DECODE_PRINTF2("%04x\n", ip);
+ TRACE_AND_STEP();
+ M.x86.R_CX -= 1;
+ if (M.x86.R_CX != 0)
+ M.x86.R_IP = ip;
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/****************************************************************************
@@ -9486,20 +4088,20 @@ Handles opcode 0xe3
****************************************************************************/
void x86emuOp_jcxz(u8 X86EMU_UNUSED(op1))
{
- u16 target;
- s8 offset;
+ u16 target;
+ s8 offset;
- /* jump to byte offset if overflow flag is set */
- START_OF_INSTR();
- DECODE_PRINTF("JCXZ\t");
- offset = (s8) fetch_byte_imm();
- target = (u16) (M.x86.R_IP + offset);
- DECODE_PRINTF2("%x\n", target);
- TRACE_AND_STEP();
- if (M.x86.R_CX == 0)
- M.x86.R_IP = target;
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ /* jump to byte offset if overflow flag is set */
+ START_OF_INSTR();
+ DECODE_PRINTF("JCXZ\t");
+ offset = (s8)fetch_byte_imm();
+ target = (u16)(M.x86.R_IP + offset);
+ DECODE_PRINTF2("%x\n", target);
+ TRACE_AND_STEP();
+ if (M.x86.R_CX == 0)
+ M.x86.R_IP = target;
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/****************************************************************************
@@ -9508,16 +4110,16 @@ Handles opcode 0xe4
****************************************************************************/
void x86emuOp_in_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
{
- u8 port;
+ u8 port;
- START_OF_INSTR();
- DECODE_PRINTF("IN\t");
+ START_OF_INSTR();
+ DECODE_PRINTF("IN\t");
port = (u8) fetch_byte_imm();
- DECODE_PRINTF2("%x,AL\n", port);
- TRACE_AND_STEP();
- M.x86.R_AL = (*sys_inb) (port);
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ DECODE_PRINTF2("%x,AL\n", port);
+ TRACE_AND_STEP();
+ M.x86.R_AL = (*sys_inb)(port);
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/****************************************************************************
@@ -9526,24 +4128,24 @@ Handles opcode 0xe5
****************************************************************************/
void x86emuOp_in_word_AX_IMM(u8 X86EMU_UNUSED(op1))
{
- u8 port;
+ u8 port;
- START_OF_INSTR();
- DECODE_PRINTF("IN\t");
+ START_OF_INSTR();
+ DECODE_PRINTF("IN\t");
port = (u8) fetch_byte_imm();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- DECODE_PRINTF2("EAX,%x\n", port);
- } else {
- DECODE_PRINTF2("AX,%x\n", port);
- }
- TRACE_AND_STEP();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- M.x86.R_EAX = (*sys_inl) (port);
- } else {
- M.x86.R_AX = (*sys_inw) (port);
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+ DECODE_PRINTF2("EAX,%x\n", port);
+ } else {
+ DECODE_PRINTF2("AX,%x\n", port);
+ }
+ TRACE_AND_STEP();
+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+ M.x86.R_EAX = (*sys_inl)(port);
+ } else {
+ M.x86.R_AX = (*sys_inw)(port);
+ }
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/****************************************************************************
@@ -9552,16 +4154,16 @@ Handles opcode 0xe6
****************************************************************************/
void x86emuOp_out_byte_IMM_AL(u8 X86EMU_UNUSED(op1))
{
- u8 port;
+ u8 port;
- START_OF_INSTR();
- DECODE_PRINTF("OUT\t");
+ START_OF_INSTR();
+ DECODE_PRINTF("OUT\t");
port = (u8) fetch_byte_imm();
- DECODE_PRINTF2("%x,AL\n", port);
- TRACE_AND_STEP();
- (*sys_outb) (port, M.x86.R_AL);
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ DECODE_PRINTF2("%x,AL\n", port);
+ TRACE_AND_STEP();
+ (*sys_outb)(port, M.x86.R_AL);
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/****************************************************************************
@@ -9570,24 +4172,24 @@ Handles opcode 0xe7
****************************************************************************/
void x86emuOp_out_word_IMM_AX(u8 X86EMU_UNUSED(op1))
{
- u8 port;
+ u8 port;
- START_OF_INSTR();
- DECODE_PRINTF("OUT\t");
+ START_OF_INSTR();
+ DECODE_PRINTF("OUT\t");
port = (u8) fetch_byte_imm();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- DECODE_PRINTF2("%x,EAX\n", port);
- } else {
- DECODE_PRINTF2("%x,AX\n", port);
- }
- TRACE_AND_STEP();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- (*sys_outl) (port, M.x86.R_EAX);
- } else {
- (*sys_outw) (port, M.x86.R_AX);
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+ DECODE_PRINTF2("%x,EAX\n", port);
+ } else {
+ DECODE_PRINTF2("%x,AX\n", port);
+ }
+ TRACE_AND_STEP();
+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+ (*sys_outl)(port, M.x86.R_EAX);
+ } else {
+ (*sys_outw)(port, M.x86.R_AX);
+ }
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/****************************************************************************
@@ -9596,19 +4198,19 @@ Handles opcode 0xe8
****************************************************************************/
void x86emuOp_call_near_IMM(u8 X86EMU_UNUSED(op1))
{
- s16 ip;
+ s16 ip;
- START_OF_INSTR();
+ 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);
+ ip += (s16) M.x86.R_IP; /* CHECK SIGN */
+ DECODE_PRINTF2("%04x\n", ip);
CALL_TRACE(M.x86.saved_cs, M.x86.saved_ip, M.x86.R_CS, ip, "");
- TRACE_AND_STEP();
- push_word(M.x86.R_IP);
- M.x86.R_IP = ip;
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ TRACE_AND_STEP();
+ push_word(M.x86.R_IP);
+ M.x86.R_IP = ip;
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/****************************************************************************
@@ -9617,23 +4219,17 @@ Handles opcode 0xe9
****************************************************************************/
void x86emuOp_jump_near_IMM(u8 X86EMU_UNUSED(op1))
{
- int ip;
-
- START_OF_INSTR();
- DECODE_PRINTF("JMP\t");
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- ip = (s32) fetch_long_imm();
- ip += (s16) M.x86.R_IP;
- DECODE_PRINTF2("%04x\n", (u16) ip);
- } else {
- ip = (s16) fetch_word_imm();
- ip += (s16) M.x86.R_IP;
- DECODE_PRINTF2("%04x\n", (u16) ip);
- }
- TRACE_AND_STEP();
- M.x86.R_IP = (u16) ip;
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ int ip;
+
+ START_OF_INSTR();
+ DECODE_PRINTF("JMP\t");
+ ip = (s16)fetch_word_imm();
+ ip += (s16)M.x86.R_IP;
+ DECODE_PRINTF2("%04x\n", ip);
+ TRACE_AND_STEP();
+ M.x86.R_IP = (u16)ip;
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/****************************************************************************
@@ -9642,19 +4238,19 @@ Handles opcode 0xea
****************************************************************************/
void x86emuOp_jump_far_IMM(u8 X86EMU_UNUSED(op1))
{
- u16 cs, ip;
+ u16 cs, ip;
- START_OF_INSTR();
- DECODE_PRINTF("JMP\tFAR ");
- 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_CS = cs;
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ START_OF_INSTR();
+ DECODE_PRINTF("JMP\tFAR ");
+ 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_CS = cs;
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/****************************************************************************
@@ -9663,18 +4259,18 @@ Handles opcode 0xeb
****************************************************************************/
void x86emuOp_jump_byte_IMM(u8 X86EMU_UNUSED(op1))
{
- u16 target;
- s8 offset;
+ u16 target;
+ s8 offset;
- START_OF_INSTR();
- DECODE_PRINTF("JMP\t");
- offset = (s8) fetch_byte_imm();
- target = (u16) (M.x86.R_IP + offset);
- DECODE_PRINTF2("%x\n", target);
- TRACE_AND_STEP();
- M.x86.R_IP = target;
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ START_OF_INSTR();
+ DECODE_PRINTF("JMP\t");
+ offset = (s8)fetch_byte_imm();
+ target = (u16)(M.x86.R_IP + offset);
+ DECODE_PRINTF2("%x\n", target);
+ TRACE_AND_STEP();
+ M.x86.R_IP = target;
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/****************************************************************************
@@ -9683,12 +4279,12 @@ Handles opcode 0xec
****************************************************************************/
void x86emuOp_in_byte_AL_DX(u8 X86EMU_UNUSED(op1))
{
- START_OF_INSTR();
- DECODE_PRINTF("IN\tAL,DX\n");
- TRACE_AND_STEP();
- M.x86.R_AL = (*sys_inb) (M.x86.R_DX);
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ START_OF_INSTR();
+ DECODE_PRINTF("IN\tAL,DX\n");
+ TRACE_AND_STEP();
+ M.x86.R_AL = (*sys_inb)(M.x86.R_DX);
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/****************************************************************************
@@ -9697,20 +4293,20 @@ Handles opcode 0xed
****************************************************************************/
void x86emuOp_in_word_AX_DX(u8 X86EMU_UNUSED(op1))
{
- START_OF_INSTR();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- DECODE_PRINTF("IN\tEAX,DX\n");
- } else {
- DECODE_PRINTF("IN\tAX,DX\n");
- }
- TRACE_AND_STEP();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- M.x86.R_EAX = (*sys_inl) (M.x86.R_DX);
- } else {
- M.x86.R_AX = (*sys_inw) (M.x86.R_DX);
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ START_OF_INSTR();
+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+ DECODE_PRINTF("IN\tEAX,DX\n");
+ } else {
+ DECODE_PRINTF("IN\tAX,DX\n");
+ }
+ TRACE_AND_STEP();
+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+ M.x86.R_EAX = (*sys_inl)(M.x86.R_DX);
+ } else {
+ M.x86.R_AX = (*sys_inw)(M.x86.R_DX);
+ }
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/****************************************************************************
@@ -9719,12 +4315,12 @@ Handles opcode 0xee
****************************************************************************/
void x86emuOp_out_byte_DX_AL(u8 X86EMU_UNUSED(op1))
{
- START_OF_INSTR();
- DECODE_PRINTF("OUT\tDX,AL\n");
- TRACE_AND_STEP();
- (*sys_outb) (M.x86.R_DX, M.x86.R_AL);
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ START_OF_INSTR();
+ DECODE_PRINTF("OUT\tDX,AL\n");
+ TRACE_AND_STEP();
+ (*sys_outb)(M.x86.R_DX, M.x86.R_AL);
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/****************************************************************************
@@ -9733,20 +4329,20 @@ Handles opcode 0xef
****************************************************************************/
void x86emuOp_out_word_DX_AX(u8 X86EMU_UNUSED(op1))
{
- START_OF_INSTR();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- DECODE_PRINTF("OUT\tDX,EAX\n");
- } else {
- DECODE_PRINTF("OUT\tDX,AX\n");
- }
- TRACE_AND_STEP();
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- (*sys_outl) (M.x86.R_DX, M.x86.R_EAX);
- } else {
- (*sys_outw) (M.x86.R_DX, M.x86.R_AX);
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ START_OF_INSTR();
+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+ DECODE_PRINTF("OUT\tDX,EAX\n");
+ } else {
+ DECODE_PRINTF("OUT\tDX,AX\n");
+ }
+ TRACE_AND_STEP();
+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+ (*sys_outl)(M.x86.R_DX, M.x86.R_EAX);
+ } else {
+ (*sys_outw)(M.x86.R_DX, M.x86.R_AX);
+ }
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/****************************************************************************
@@ -9755,11 +4351,11 @@ Handles opcode 0xf0
****************************************************************************/
void x86emuOp_lock(u8 X86EMU_UNUSED(op1))
{
- START_OF_INSTR();
- DECODE_PRINTF("LOCK:\n");
- TRACE_AND_STEP();
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ START_OF_INSTR();
+ DECODE_PRINTF("LOCK:\n");
+ TRACE_AND_STEP();
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/*opcode 0xf1 ILLEGAL OPERATION */
@@ -9770,12 +4366,12 @@ Handles opcode 0xf2
****************************************************************************/
void x86emuOp_repne(u8 X86EMU_UNUSED(op1))
{
- START_OF_INSTR();
- DECODE_PRINTF("REPNE\n");
- TRACE_AND_STEP();
- M.x86.mode |= SYSMODE_PREFIX_REPNE;
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ START_OF_INSTR();
+ DECODE_PRINTF("REPNE\n");
+ TRACE_AND_STEP();
+ M.x86.mode |= SYSMODE_PREFIX_REPNE;
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/****************************************************************************
@@ -9784,12 +4380,12 @@ Handles opcode 0xf3
****************************************************************************/
void x86emuOp_repe(u8 X86EMU_UNUSED(op1))
{
- START_OF_INSTR();
- DECODE_PRINTF("REPE\n");
- TRACE_AND_STEP();
- M.x86.mode |= SYSMODE_PREFIX_REPE;
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ START_OF_INSTR();
+ DECODE_PRINTF("REPE\n");
+ TRACE_AND_STEP();
+ M.x86.mode |= SYSMODE_PREFIX_REPE;
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/****************************************************************************
@@ -9798,12 +4394,12 @@ Handles opcode 0xf4
****************************************************************************/
void x86emuOp_halt(u8 X86EMU_UNUSED(op1))
{
- START_OF_INSTR();
- DECODE_PRINTF("HALT\n");
- TRACE_AND_STEP();
- HALT_SYS();
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ START_OF_INSTR();
+ DECODE_PRINTF("HALT\n");
+ TRACE_AND_STEP();
+ HALT_SYS();
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/****************************************************************************
@@ -9812,13 +4408,13 @@ Handles opcode 0xf5
****************************************************************************/
void x86emuOp_cmc(u8 X86EMU_UNUSED(op1))
{
- /* complement the carry flag. */
- START_OF_INSTR();
- DECODE_PRINTF("CMC\n");
- TRACE_AND_STEP();
- TOGGLE_FLAG(F_CF);
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ /* complement the carry flag. */
+ START_OF_INSTR();
+ DECODE_PRINTF("CMC\n");
+ TRACE_AND_STEP();
+ TOGGLE_FLAG(F_CF);
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/****************************************************************************
@@ -9827,282 +4423,114 @@ Handles opcode 0xf6
****************************************************************************/
void x86emuOp_opcF6_byte_RM(u8 X86EMU_UNUSED(op1))
{
- int mod, rl, rh;
- u8 *destreg;
- uint destoffset;
- u8 destval, srcval;
-
- /* long, drawn out code follows. Double switch for a total
- of 32 cases. */
- START_OF_INSTR();
- FETCH_DECODE_MODRM(mod, rh, rl);
- switch (mod) {
- case 0: /* mod=00 */
- switch (rh) {
- case 0: /* test byte imm */
- DECODE_PRINTF("TEST\tBYTE PTR ");
- destoffset = decode_rm00_address(rl);
- DECODE_PRINTF(",");
- srcval = fetch_byte_imm();
- DECODE_PRINTF2("%02x\n", srcval);
- destval = fetch_data_byte(destoffset);
- TRACE_AND_STEP();
- test_byte(destval, srcval);
- break;
- case 1:
- DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n");
- HALT_SYS();
- break;
- case 2:
- DECODE_PRINTF("NOT\tBYTE PTR ");
- destoffset = decode_rm00_address(rl);
- DECODE_PRINTF("\n");
- destval = fetch_data_byte(destoffset);
- TRACE_AND_STEP();
- destval = not_byte(destval);
- store_data_byte(destoffset, destval);
- break;
- case 3:
- DECODE_PRINTF("NEG\tBYTE PTR ");
- destoffset = decode_rm00_address(rl);
- DECODE_PRINTF("\n");
- destval = fetch_data_byte(destoffset);
- TRACE_AND_STEP();
- destval = neg_byte(destval);
- store_data_byte(destoffset, destval);
- break;
- case 4:
- DECODE_PRINTF("MUL\tBYTE PTR ");
- destoffset = decode_rm00_address(rl);
- DECODE_PRINTF("\n");
- destval = fetch_data_byte(destoffset);
- TRACE_AND_STEP();
- mul_byte(destval);
- break;
- case 5:
- DECODE_PRINTF("IMUL\tBYTE PTR ");
- destoffset = decode_rm00_address(rl);
- DECODE_PRINTF("\n");
- destval = fetch_data_byte(destoffset);
- TRACE_AND_STEP();
- imul_byte(destval);
- break;
- case 6:
- DECODE_PRINTF("DIV\tBYTE PTR ");
- destoffset = decode_rm00_address(rl);
- DECODE_PRINTF("\n");
- destval = fetch_data_byte(destoffset);
- TRACE_AND_STEP();
- div_byte(destval);
- break;
- case 7:
- DECODE_PRINTF("IDIV\tBYTE PTR ");
- destoffset = decode_rm00_address(rl);
- DECODE_PRINTF("\n");
- destval = fetch_data_byte(destoffset);
- TRACE_AND_STEP();
- idiv_byte(destval);
- break;
- }
- break; /* end mod==00 */
- case 1: /* mod=01 */
- switch (rh) {
- case 0: /* test byte imm */
- DECODE_PRINTF("TEST\tBYTE PTR ");
- destoffset = decode_rm01_address(rl);
- DECODE_PRINTF(",");
- srcval = fetch_byte_imm();
- DECODE_PRINTF2("%02x\n", srcval);
- destval = fetch_data_byte(destoffset);
- TRACE_AND_STEP();
- test_byte(destval, srcval);
- break;
- case 1:
- DECODE_PRINTF("ILLEGAL OP MOD=01 RH=01 OP=F6\n");
- HALT_SYS();
- break;
- case 2:
- DECODE_PRINTF("NOT\tBYTE PTR ");
- destoffset = decode_rm01_address(rl);
- DECODE_PRINTF("\n");
- destval = fetch_data_byte(destoffset);
- TRACE_AND_STEP();
- destval = not_byte(destval);
- store_data_byte(destoffset, destval);
- break;
- case 3:
- DECODE_PRINTF("NEG\tBYTE PTR ");
- destoffset = decode_rm01_address(rl);
- DECODE_PRINTF("\n");
- destval = fetch_data_byte(destoffset);
- TRACE_AND_STEP();
- destval = neg_byte(destval);
- store_data_byte(destoffset, destval);
- break;
- case 4:
- DECODE_PRINTF("MUL\tBYTE PTR ");
- destoffset = decode_rm01_address(rl);
- DECODE_PRINTF("\n");
- destval = fetch_data_byte(destoffset);
- TRACE_AND_STEP();
- mul_byte(destval);
- break;
- case 5:
- DECODE_PRINTF("IMUL\tBYTE PTR ");
- destoffset = decode_rm01_address(rl);
- DECODE_PRINTF("\n");
- destval = fetch_data_byte(destoffset);
- TRACE_AND_STEP();
- imul_byte(destval);
- break;
- case 6:
- DECODE_PRINTF("DIV\tBYTE PTR ");
- destoffset = decode_rm01_address(rl);
- DECODE_PRINTF("\n");
- destval = fetch_data_byte(destoffset);
- TRACE_AND_STEP();
- div_byte(destval);
- break;
- case 7:
- DECODE_PRINTF("IDIV\tBYTE PTR ");
- destoffset = decode_rm01_address(rl);
- DECODE_PRINTF("\n");
- destval = fetch_data_byte(destoffset);
- TRACE_AND_STEP();
- idiv_byte(destval);
- break;
- }
- break; /* end mod==01 */
- case 2: /* mod=10 */
- switch (rh) {
- case 0: /* test byte imm */
- DECODE_PRINTF("TEST\tBYTE PTR ");
- destoffset = decode_rm10_address(rl);
- DECODE_PRINTF(",");
- srcval = fetch_byte_imm();
- DECODE_PRINTF2("%02x\n", srcval);
- destval = fetch_data_byte(destoffset);
- TRACE_AND_STEP();
- test_byte(destval, srcval);
- break;
- case 1:
- DECODE_PRINTF("ILLEGAL OP MOD=10 RH=01 OP=F6\n");
- HALT_SYS();
- break;
- case 2:
- DECODE_PRINTF("NOT\tBYTE PTR ");
- destoffset = decode_rm10_address(rl);
- DECODE_PRINTF("\n");
- destval = fetch_data_byte(destoffset);
- TRACE_AND_STEP();
- destval = not_byte(destval);
- store_data_byte(destoffset, destval);
- break;
- case 3:
- DECODE_PRINTF("NEG\tBYTE PTR ");
- destoffset = decode_rm10_address(rl);
- DECODE_PRINTF("\n");
- destval = fetch_data_byte(destoffset);
- TRACE_AND_STEP();
- destval = neg_byte(destval);
- store_data_byte(destoffset, destval);
- break;
- case 4:
- DECODE_PRINTF("MUL\tBYTE PTR ");
- destoffset = decode_rm10_address(rl);
- DECODE_PRINTF("\n");
- destval = fetch_data_byte(destoffset);
- TRACE_AND_STEP();
- mul_byte(destval);
- break;
- case 5:
- DECODE_PRINTF("IMUL\tBYTE PTR ");
- destoffset = decode_rm10_address(rl);
- DECODE_PRINTF("\n");
- destval = fetch_data_byte(destoffset);
- TRACE_AND_STEP();
- imul_byte(destval);
- break;
- case 6:
- DECODE_PRINTF("DIV\tBYTE PTR ");
- destoffset = decode_rm10_address(rl);
- DECODE_PRINTF("\n");
- destval = fetch_data_byte(destoffset);
- TRACE_AND_STEP();
- div_byte(destval);
- break;
- case 7:
- DECODE_PRINTF("IDIV\tBYTE PTR ");
- destoffset = decode_rm10_address(rl);
- DECODE_PRINTF("\n");
- destval = fetch_data_byte(destoffset);
- TRACE_AND_STEP();
- idiv_byte(destval);
- break;
- }
- break; /* end mod==10 */
- case 3: /* mod=11 */
- switch (rh) {
- case 0: /* test byte imm */
- DECODE_PRINTF("TEST\t");
- destreg = DECODE_RM_BYTE_REGISTER(rl);
- DECODE_PRINTF(",");
- srcval = fetch_byte_imm();
- DECODE_PRINTF2("%02x\n", srcval);
- TRACE_AND_STEP();
- test_byte(*destreg, srcval);
- break;
- case 1:
- DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n");
- HALT_SYS();
- break;
- case 2:
- DECODE_PRINTF("NOT\t");
- destreg = DECODE_RM_BYTE_REGISTER(rl);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = not_byte(*destreg);
- break;
- case 3:
- DECODE_PRINTF("NEG\t");
- destreg = DECODE_RM_BYTE_REGISTER(rl);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = neg_byte(*destreg);
- break;
- case 4:
- DECODE_PRINTF("MUL\t");
- destreg = DECODE_RM_BYTE_REGISTER(rl);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- mul_byte(*destreg); /*!!! */
- break;
- case 5:
- DECODE_PRINTF("IMUL\t");
- destreg = DECODE_RM_BYTE_REGISTER(rl);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- imul_byte(*destreg);
- break;
- case 6:
- DECODE_PRINTF("DIV\t");
- destreg = DECODE_RM_BYTE_REGISTER(rl);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- div_byte(*destreg);
- break;
- case 7:
- DECODE_PRINTF("IDIV\t");
- destreg = DECODE_RM_BYTE_REGISTER(rl);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- idiv_byte(*destreg);
- break;
- }
- break; /* end mod==11 */
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ int mod, rl, rh;
+ u8 *destreg;
+ uint destoffset;
+ u8 destval, srcval;
+
+ /* long, drawn out code follows. Double switch for a total
+ of 32 cases. */
+ START_OF_INSTR();
+ FETCH_DECODE_MODRM(mod, rh, rl);
+ DECODE_PRINTF(opF6_names[rh]);
+ if (mod < 3) {
+ DECODE_PRINTF("BYTE PTR ");
+ destoffset = decode_rmXX_address(mod, rl);
+ destval = fetch_data_byte(destoffset);
+
+ switch (rh) {
+ case 0: /* test byte imm */
+ DECODE_PRINTF(",");
+ srcval = fetch_byte_imm();
+ DECODE_PRINTF2("%02x\n", srcval);
+ TRACE_AND_STEP();
+ test_byte(destval, srcval);
+ break;
+ case 1:
+ DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n");
+ HALT_SYS();
+ break;
+ case 2:
+ DECODE_PRINTF("\n");
+ TRACE_AND_STEP();
+ destval = not_byte(destval);
+ store_data_byte(destoffset, destval);
+ break;
+ case 3:
+ DECODE_PRINTF("\n");
+ TRACE_AND_STEP();
+ destval = neg_byte(destval);
+ store_data_byte(destoffset, destval);
+ break;
+ case 4:
+ DECODE_PRINTF("\n");
+ TRACE_AND_STEP();
+ mul_byte(destval);
+ break;
+ case 5:
+ DECODE_PRINTF("\n");
+ TRACE_AND_STEP();
+ imul_byte(destval);
+ break;
+ case 6:
+ DECODE_PRINTF("\n");
+ TRACE_AND_STEP();
+ div_byte(destval);
+ break;
+ default:
+ DECODE_PRINTF("\n");
+ TRACE_AND_STEP();
+ idiv_byte(destval);
+ break;
+ }
+ } else { /* mod=11 */
+ destreg = DECODE_RM_BYTE_REGISTER(rl);
+ switch (rh) {
+ case 0: /* test byte imm */
+ DECODE_PRINTF(",");
+ srcval = fetch_byte_imm();
+ DECODE_PRINTF2("%02x\n", srcval);
+ TRACE_AND_STEP();
+ test_byte(*destreg, srcval);
+ break;
+ case 1:
+ DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n");
+ HALT_SYS();
+ break;
+ case 2:
+ DECODE_PRINTF("\n");
+ TRACE_AND_STEP();
+ *destreg = not_byte(*destreg);
+ break;
+ case 3:
+ DECODE_PRINTF("\n");
+ TRACE_AND_STEP();
+ *destreg = neg_byte(*destreg);
+ break;
+ case 4:
+ DECODE_PRINTF("\n");
+ TRACE_AND_STEP();
+ mul_byte(*destreg); /*!!! */
+ break;
+ case 5:
+ DECODE_PRINTF("\n");
+ TRACE_AND_STEP();
+ imul_byte(*destreg);
+ break;
+ case 6:
+ DECODE_PRINTF("\n");
+ TRACE_AND_STEP();
+ div_byte(*destreg);
+ break;
+ default:
+ DECODE_PRINTF("\n");
+ TRACE_AND_STEP();
+ idiv_byte(*destreg);
+ break;
+ }
+ }
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/****************************************************************************
@@ -10111,653 +4539,224 @@ Handles opcode 0xf7
****************************************************************************/
void x86emuOp_opcF7_word_RM(u8 X86EMU_UNUSED(op1))
{
- int mod, rl, rh;
- uint destoffset;
-
- /* long, drawn out code follows. Double switch for a total
- of 32 cases. */
- START_OF_INSTR();
- FETCH_DECODE_MODRM(mod, rh, rl);
- switch (mod) {
- case 0: /* mod=00 */
- switch (rh) {
- case 0: /* test word imm */
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 destval, srcval;
-
- DECODE_PRINTF("TEST\tDWORD PTR ");
- destoffset = decode_rm00_address(rl);
- DECODE_PRINTF(",");
- srcval = fetch_long_imm();
- DECODE_PRINTF2("%x\n", srcval);
- destval = fetch_data_long(destoffset);
- TRACE_AND_STEP();
- test_long(destval, srcval);
- } else {
- u16 destval, srcval;
-
- DECODE_PRINTF("TEST\tWORD PTR ");
- destoffset = decode_rm00_address(rl);
- DECODE_PRINTF(",");
- srcval = fetch_word_imm();
- DECODE_PRINTF2("%x\n", srcval);
- destval = fetch_data_word(destoffset);
- TRACE_AND_STEP();
- test_word(destval, srcval);
- }
- break;
- case 1:
- DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F7\n");
- HALT_SYS();
- break;
- case 2:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 destval;
-
- DECODE_PRINTF("NOT\tDWORD PTR ");
- destoffset = decode_rm00_address(rl);
- DECODE_PRINTF("\n");
- destval = fetch_data_long(destoffset);
- TRACE_AND_STEP();
- destval = not_long(destval);
- store_data_long(destoffset, destval);
- } else {
- u16 destval;
-
- DECODE_PRINTF("NOT\tWORD PTR ");
- destoffset = decode_rm00_address(rl);
- DECODE_PRINTF("\n");
- destval = fetch_data_word(destoffset);
- TRACE_AND_STEP();
- destval = not_word(destval);
- store_data_word(destoffset, destval);
- }
- break;
- case 3:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 destval;
-
- DECODE_PRINTF("NEG\tDWORD PTR ");
- destoffset = decode_rm00_address(rl);
- DECODE_PRINTF("\n");
- destval = fetch_data_long(destoffset);
- TRACE_AND_STEP();
- destval = neg_long(destval);
- store_data_long(destoffset, destval);
- } else {
- u16 destval;
-
- DECODE_PRINTF("NEG\tWORD PTR ");
- destoffset = decode_rm00_address(rl);
- DECODE_PRINTF("\n");
- destval = fetch_data_word(destoffset);
- TRACE_AND_STEP();
- destval = neg_word(destval);
- store_data_word(destoffset, destval);
- }
- break;
- case 4:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 destval;
-
- DECODE_PRINTF("MUL\tDWORD PTR ");
- destoffset = decode_rm00_address(rl);
- DECODE_PRINTF("\n");
- destval = fetch_data_long(destoffset);
- TRACE_AND_STEP();
- mul_long(destval);
- } else {
- u16 destval;
-
- DECODE_PRINTF("MUL\tWORD PTR ");
- destoffset = decode_rm00_address(rl);
- DECODE_PRINTF("\n");
- destval = fetch_data_word(destoffset);
- TRACE_AND_STEP();
- mul_word(destval);
- }
- break;
- case 5:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 destval;
-
- DECODE_PRINTF("IMUL\tDWORD PTR ");
- destoffset = decode_rm00_address(rl);
- DECODE_PRINTF("\n");
- destval = fetch_data_long(destoffset);
- TRACE_AND_STEP();
- imul_long(destval);
- } else {
- u16 destval;
-
- DECODE_PRINTF("IMUL\tWORD PTR ");
- destoffset = decode_rm00_address(rl);
- DECODE_PRINTF("\n");
- destval = fetch_data_word(destoffset);
- TRACE_AND_STEP();
- imul_word(destval);
- }
- break;
- case 6:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 destval;
-
- DECODE_PRINTF("DIV\tDWORD PTR ");
- destoffset = decode_rm00_address(rl);
- DECODE_PRINTF("\n");
- destval = fetch_data_long(destoffset);
- TRACE_AND_STEP();
- div_long(destval);
- } else {
- u16 destval;
-
- DECODE_PRINTF("DIV\tWORD PTR ");
- destoffset = decode_rm00_address(rl);
- DECODE_PRINTF("\n");
- destval = fetch_data_word(destoffset);
- TRACE_AND_STEP();
- div_word(destval);
- }
- break;
- case 7:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 destval;
-
- DECODE_PRINTF("IDIV\tDWORD PTR ");
- destoffset = decode_rm00_address(rl);
- DECODE_PRINTF("\n");
- destval = fetch_data_long(destoffset);
- TRACE_AND_STEP();
- idiv_long(destval);
- } else {
- u16 destval;
-
- DECODE_PRINTF("IDIV\tWORD PTR ");
- destoffset = decode_rm00_address(rl);
- DECODE_PRINTF("\n");
- destval = fetch_data_word(destoffset);
- TRACE_AND_STEP();
- idiv_word(destval);
- }
- break;
- }
- break; /* end mod==00 */
- case 1: /* mod=01 */
- switch (rh) {
- case 0: /* test word imm */
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 destval, srcval;
-
- DECODE_PRINTF("TEST\tDWORD PTR ");
- destoffset = decode_rm01_address(rl);
- DECODE_PRINTF(",");
- srcval = fetch_long_imm();
- DECODE_PRINTF2("%x\n", srcval);
- destval = fetch_data_long(destoffset);
- TRACE_AND_STEP();
- test_long(destval, srcval);
- } else {
- u16 destval, srcval;
-
- DECODE_PRINTF("TEST\tWORD PTR ");
- destoffset = decode_rm01_address(rl);
- DECODE_PRINTF(",");
- srcval = fetch_word_imm();
- DECODE_PRINTF2("%x\n", srcval);
- destval = fetch_data_word(destoffset);
- TRACE_AND_STEP();
- test_word(destval, srcval);
- }
- break;
- case 1:
- DECODE_PRINTF("ILLEGAL OP MOD=01 RH=01 OP=F6\n");
- HALT_SYS();
- break;
- case 2:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 destval;
-
- DECODE_PRINTF("NOT\tDWORD PTR ");
- destoffset = decode_rm01_address(rl);
- DECODE_PRINTF("\n");
- destval = fetch_data_long(destoffset);
- TRACE_AND_STEP();
- destval = not_long(destval);
- store_data_long(destoffset, destval);
- } else {
- u16 destval;
-
- DECODE_PRINTF("NOT\tWORD PTR ");
- destoffset = decode_rm01_address(rl);
- DECODE_PRINTF("\n");
- destval = fetch_data_word(destoffset);
- TRACE_AND_STEP();
- destval = not_word(destval);
- store_data_word(destoffset, destval);
- }
- break;
- case 3:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 destval;
-
- DECODE_PRINTF("NEG\tDWORD PTR ");
- destoffset = decode_rm01_address(rl);
- DECODE_PRINTF("\n");
- destval = fetch_data_long(destoffset);
- TRACE_AND_STEP();
- destval = neg_long(destval);
- store_data_long(destoffset, destval);
- } else {
- u16 destval;
-
- DECODE_PRINTF("NEG\tWORD PTR ");
- destoffset = decode_rm01_address(rl);
- DECODE_PRINTF("\n");
- destval = fetch_data_word(destoffset);
- TRACE_AND_STEP();
- destval = neg_word(destval);
- store_data_word(destoffset, destval);
- }
- break;
- case 4:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 destval;
-
- DECODE_PRINTF("MUL\tDWORD PTR ");
- destoffset = decode_rm01_address(rl);
- DECODE_PRINTF("\n");
- destval = fetch_data_long(destoffset);
- TRACE_AND_STEP();
- mul_long(destval);
- } else {
- u16 destval;
-
- DECODE_PRINTF("MUL\tWORD PTR ");
- destoffset = decode_rm01_address(rl);
- DECODE_PRINTF("\n");
- destval = fetch_data_word(destoffset);
- TRACE_AND_STEP();
- mul_word(destval);
- }
- break;
- case 5:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 destval;
-
- DECODE_PRINTF("IMUL\tDWORD PTR ");
- destoffset = decode_rm01_address(rl);
- DECODE_PRINTF("\n");
- destval = fetch_data_long(destoffset);
- TRACE_AND_STEP();
- imul_long(destval);
- } else {
- u16 destval;
-
- DECODE_PRINTF("IMUL\tWORD PTR ");
- destoffset = decode_rm01_address(rl);
- DECODE_PRINTF("\n");
- destval = fetch_data_word(destoffset);
- TRACE_AND_STEP();
- imul_word(destval);
- }
- break;
- case 6:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 destval;
-
- DECODE_PRINTF("DIV\tDWORD PTR ");
- destoffset = decode_rm01_address(rl);
- DECODE_PRINTF("\n");
- destval = fetch_data_long(destoffset);
- TRACE_AND_STEP();
- div_long(destval);
- } else {
- u16 destval;
-
- DECODE_PRINTF("DIV\tWORD PTR ");
- destoffset = decode_rm01_address(rl);
- DECODE_PRINTF("\n");
- destval = fetch_data_word(destoffset);
- TRACE_AND_STEP();
- div_word(destval);
- }
- break;
- case 7:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 destval;
-
- DECODE_PRINTF("IDIV\tDWORD PTR ");
- destoffset = decode_rm01_address(rl);
- DECODE_PRINTF("\n");
- destval = fetch_data_long(destoffset);
- TRACE_AND_STEP();
- idiv_long(destval);
- } else {
- u16 destval;
-
- DECODE_PRINTF("IDIV\tWORD PTR ");
- destoffset = decode_rm01_address(rl);
- DECODE_PRINTF("\n");
- destval = fetch_data_word(destoffset);
- TRACE_AND_STEP();
- idiv_word(destval);
- }
- break;
- }
- break; /* end mod==01 */
- case 2: /* mod=10 */
- switch (rh) {
- case 0: /* test word imm */
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 destval, srcval;
-
- DECODE_PRINTF("TEST\tDWORD PTR ");
- destoffset = decode_rm10_address(rl);
- DECODE_PRINTF(",");
- srcval = fetch_long_imm();
- DECODE_PRINTF2("%x\n", srcval);
- destval = fetch_data_long(destoffset);
- TRACE_AND_STEP();
- test_long(destval, srcval);
- } else {
- u16 destval, srcval;
-
- DECODE_PRINTF("TEST\tWORD PTR ");
- destoffset = decode_rm10_address(rl);
- DECODE_PRINTF(",");
- srcval = fetch_word_imm();
- DECODE_PRINTF2("%x\n", srcval);
- destval = fetch_data_word(destoffset);
- TRACE_AND_STEP();
- test_word(destval, srcval);
- }
- break;
- case 1:
- DECODE_PRINTF("ILLEGAL OP MOD=10 RH=01 OP=F6\n");
- HALT_SYS();
- break;
- case 2:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 destval;
-
- DECODE_PRINTF("NOT\tDWORD PTR ");
- destoffset = decode_rm10_address(rl);
- DECODE_PRINTF("\n");
- destval = fetch_data_long(destoffset);
- TRACE_AND_STEP();
- destval = not_long(destval);
- store_data_long(destoffset, destval);
- } else {
- u16 destval;
-
- DECODE_PRINTF("NOT\tWORD PTR ");
- destoffset = decode_rm10_address(rl);
- DECODE_PRINTF("\n");
- destval = fetch_data_word(destoffset);
- TRACE_AND_STEP();
- destval = not_word(destval);
- store_data_word(destoffset, destval);
- }
- break;
- case 3:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 destval;
-
- DECODE_PRINTF("NEG\tDWORD PTR ");
- destoffset = decode_rm10_address(rl);
- DECODE_PRINTF("\n");
- destval = fetch_data_long(destoffset);
- TRACE_AND_STEP();
- destval = neg_long(destval);
- store_data_long(destoffset, destval);
- } else {
- u16 destval;
-
- DECODE_PRINTF("NEG\tWORD PTR ");
- destoffset = decode_rm10_address(rl);
- DECODE_PRINTF("\n");
- destval = fetch_data_word(destoffset);
- TRACE_AND_STEP();
- destval = neg_word(destval);
- store_data_word(destoffset, destval);
- }
- break;
- case 4:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 destval;
-
- DECODE_PRINTF("MUL\tDWORD PTR ");
- destoffset = decode_rm10_address(rl);
- DECODE_PRINTF("\n");
- destval = fetch_data_long(destoffset);
- TRACE_AND_STEP();
- mul_long(destval);
- } else {
- u16 destval;
-
- DECODE_PRINTF("MUL\tWORD PTR ");
- destoffset = decode_rm10_address(rl);
- DECODE_PRINTF("\n");
- destval = fetch_data_word(destoffset);
- TRACE_AND_STEP();
- mul_word(destval);
- }
- break;
- case 5:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 destval;
-
- DECODE_PRINTF("IMUL\tDWORD PTR ");
- destoffset = decode_rm10_address(rl);
- DECODE_PRINTF("\n");
- destval = fetch_data_long(destoffset);
- TRACE_AND_STEP();
- imul_long(destval);
- } else {
- u16 destval;
-
- DECODE_PRINTF("IMUL\tWORD PTR ");
- destoffset = decode_rm10_address(rl);
- DECODE_PRINTF("\n");
- destval = fetch_data_word(destoffset);
- TRACE_AND_STEP();
- imul_word(destval);
- }
- break;
- case 6:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 destval;
-
- DECODE_PRINTF("DIV\tDWORD PTR ");
- destoffset = decode_rm10_address(rl);
- DECODE_PRINTF("\n");
- destval = fetch_data_long(destoffset);
- TRACE_AND_STEP();
- div_long(destval);
- } else {
- u16 destval;
-
- DECODE_PRINTF("DIV\tWORD PTR ");
- destoffset = decode_rm10_address(rl);
- DECODE_PRINTF("\n");
- destval = fetch_data_word(destoffset);
- TRACE_AND_STEP();
- div_word(destval);
- }
- break;
- case 7:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 destval;
-
- DECODE_PRINTF("IDIV\tDWORD PTR ");
- destoffset = decode_rm10_address(rl);
- DECODE_PRINTF("\n");
- destval = fetch_data_long(destoffset);
- TRACE_AND_STEP();
- idiv_long(destval);
- } else {
- u16 destval;
-
- DECODE_PRINTF("IDIV\tWORD PTR ");
- destoffset = decode_rm10_address(rl);
- DECODE_PRINTF("\n");
- destval = fetch_data_word(destoffset);
- TRACE_AND_STEP();
- idiv_word(destval);
- }
- break;
- }
- break; /* end mod==10 */
- case 3: /* mod=11 */
- switch (rh) {
- case 0: /* test word imm */
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 *destreg;
- u32 srcval;
-
- DECODE_PRINTF("TEST\t");
- destreg = DECODE_RM_LONG_REGISTER(rl);
- DECODE_PRINTF(",");
- srcval = fetch_long_imm();
- DECODE_PRINTF2("%x\n", srcval);
- TRACE_AND_STEP();
- test_long(*destreg, srcval);
- } else {
- u16 *destreg;
- u16 srcval;
-
- DECODE_PRINTF("TEST\t");
- destreg = DECODE_RM_WORD_REGISTER(rl);
- DECODE_PRINTF(",");
- srcval = fetch_word_imm();
- DECODE_PRINTF2("%x\n", srcval);
- TRACE_AND_STEP();
- test_word(*destreg, srcval);
- }
- break;
- case 1:
- DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n");
- HALT_SYS();
- break;
- case 2:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 *destreg;
-
- DECODE_PRINTF("NOT\t");
- destreg = DECODE_RM_LONG_REGISTER(rl);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = not_long(*destreg);
- } else {
- u16 *destreg;
-
- DECODE_PRINTF("NOT\t");
- destreg = DECODE_RM_WORD_REGISTER(rl);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = not_word(*destreg);
- }
- break;
- case 3:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 *destreg;
-
- DECODE_PRINTF("NEG\t");
- destreg = DECODE_RM_LONG_REGISTER(rl);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = neg_long(*destreg);
- } else {
- u16 *destreg;
-
- DECODE_PRINTF("NEG\t");
- destreg = DECODE_RM_WORD_REGISTER(rl);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = neg_word(*destreg);
- }
- break;
- case 4:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 *destreg;
-
- DECODE_PRINTF("MUL\t");
- destreg = DECODE_RM_LONG_REGISTER(rl);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- mul_long(*destreg); /*!!! */
- } else {
- u16 *destreg;
-
- DECODE_PRINTF("MUL\t");
- destreg = DECODE_RM_WORD_REGISTER(rl);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- mul_word(*destreg); /*!!! */
- }
- break;
- case 5:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 *destreg;
-
- DECODE_PRINTF("IMUL\t");
- destreg = DECODE_RM_LONG_REGISTER(rl);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- imul_long(*destreg);
- } else {
- u16 *destreg;
-
- DECODE_PRINTF("IMUL\t");
- destreg = DECODE_RM_WORD_REGISTER(rl);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- imul_word(*destreg);
- }
- break;
- case 6:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 *destreg;
-
- DECODE_PRINTF("DIV\t");
- destreg = DECODE_RM_LONG_REGISTER(rl);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- div_long(*destreg);
- } else {
- u16 *destreg;
-
- DECODE_PRINTF("DIV\t");
- destreg = DECODE_RM_WORD_REGISTER(rl);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- div_word(*destreg);
- }
- break;
- case 7:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 *destreg;
-
- DECODE_PRINTF("IDIV\t");
- destreg = DECODE_RM_LONG_REGISTER(rl);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- idiv_long(*destreg);
- } else {
- u16 *destreg;
-
- DECODE_PRINTF("IDIV\t");
- destreg = DECODE_RM_WORD_REGISTER(rl);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- idiv_word(*destreg);
- }
- break;
- }
- break; /* end mod==11 */
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ int mod, rl, rh;
+ uint destoffset;
+
+ START_OF_INSTR();
+ FETCH_DECODE_MODRM(mod, rh, rl);
+ DECODE_PRINTF(opF6_names[rh]);
+ if (mod < 3) {
+
+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+ u32 destval, srcval;
+
+ DECODE_PRINTF("DWORD PTR ");
+ destoffset = decode_rmXX_address(mod, rl);
+ destval = fetch_data_long(destoffset);
+
+ switch (rh) {
+ case 0:
+ DECODE_PRINTF(",");
+ srcval = fetch_long_imm();
+ DECODE_PRINTF2("%x\n", srcval);
+ TRACE_AND_STEP();
+ test_long(destval, srcval);
+ break;
+ case 1:
+ DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F7\n");
+ HALT_SYS();
+ break;
+ case 2:
+ DECODE_PRINTF("\n");
+ TRACE_AND_STEP();
+ destval = not_long(destval);
+ store_data_long(destoffset, destval);
+ break;
+ case 3:
+ DECODE_PRINTF("\n");
+ TRACE_AND_STEP();
+ destval = neg_long(destval);
+ store_data_long(destoffset, destval);
+ break;
+ case 4:
+ DECODE_PRINTF("\n");
+ TRACE_AND_STEP();
+ mul_long(destval);
+ break;
+ case 5:
+ DECODE_PRINTF("\n");
+ TRACE_AND_STEP();
+ imul_long(destval);
+ break;
+ case 6:
+ DECODE_PRINTF("\n");
+ TRACE_AND_STEP();
+ div_long(destval);
+ break;
+ case 7:
+ DECODE_PRINTF("\n");
+ TRACE_AND_STEP();
+ idiv_long(destval);
+ break;
+ }
+ } else {
+ u16 destval, srcval;
+
+ DECODE_PRINTF("WORD PTR ");
+ destoffset = decode_rmXX_address(mod, rl);
+ destval = fetch_data_word(destoffset);
+
+ switch (rh) {
+ case 0: /* test word imm */
+ DECODE_PRINTF(",");
+ srcval = fetch_word_imm();
+ DECODE_PRINTF2("%x\n", srcval);
+ TRACE_AND_STEP();
+ test_word(destval, srcval);
+ break;
+ case 1:
+ DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F7\n");
+ HALT_SYS();
+ break;
+ case 2:
+ DECODE_PRINTF("\n");
+ TRACE_AND_STEP();
+ destval = not_word(destval);
+ store_data_word(destoffset, destval);
+ break;
+ case 3:
+ DECODE_PRINTF("\n");
+ TRACE_AND_STEP();
+ destval = neg_word(destval);
+ store_data_word(destoffset, destval);
+ break;
+ case 4:
+ DECODE_PRINTF("\n");
+ TRACE_AND_STEP();
+ mul_word(destval);
+ break;
+ case 5:
+ DECODE_PRINTF("\n");
+ TRACE_AND_STEP();
+ imul_word(destval);
+ break;
+ case 6:
+ DECODE_PRINTF("\n");
+ TRACE_AND_STEP();
+ div_word(destval);
+ break;
+ case 7:
+ DECODE_PRINTF("\n");
+ TRACE_AND_STEP();
+ idiv_word(destval);
+ break;
+ }
+ }
+
+ } else { /* mod=11 */
+
+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+ u32 *destreg;
+ u32 srcval;
+
+ destreg = DECODE_RM_LONG_REGISTER(rl);
+
+ switch (rh) {
+ case 0: /* test word imm */
+ DECODE_PRINTF(",");
+ srcval = fetch_long_imm();
+ DECODE_PRINTF2("%x\n", srcval);
+ TRACE_AND_STEP();
+ test_long(*destreg, srcval);
+ break;
+ case 1:
+ DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n");
+ HALT_SYS();
+ break;
+ case 2:
+ DECODE_PRINTF("\n");
+ TRACE_AND_STEP();
+ *destreg = not_long(*destreg);
+ break;
+ case 3:
+ DECODE_PRINTF("\n");
+ TRACE_AND_STEP();
+ *destreg = neg_long(*destreg);
+ break;
+ case 4:
+ DECODE_PRINTF("\n");
+ TRACE_AND_STEP();
+ mul_long(*destreg); /*!!! */
+ break;
+ case 5:
+ DECODE_PRINTF("\n");
+ TRACE_AND_STEP();
+ imul_long(*destreg);
+ break;
+ case 6:
+ DECODE_PRINTF("\n");
+ TRACE_AND_STEP();
+ div_long(*destreg);
+ break;
+ case 7:
+ DECODE_PRINTF("\n");
+ TRACE_AND_STEP();
+ idiv_long(*destreg);
+ break;
+ }
+ } else {
+ u16 *destreg;
+ u16 srcval;
+
+ destreg = DECODE_RM_WORD_REGISTER(rl);
+
+ switch (rh) {
+ case 0: /* test word imm */
+ DECODE_PRINTF(",");
+ srcval = fetch_word_imm();
+ DECODE_PRINTF2("%x\n", srcval);
+ TRACE_AND_STEP();
+ test_word(*destreg, srcval);
+ break;
+ case 1:
+ DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n");
+ HALT_SYS();
+ break;
+ case 2:
+ DECODE_PRINTF("\n");
+ TRACE_AND_STEP();
+ *destreg = not_word(*destreg);
+ break;
+ case 3:
+ DECODE_PRINTF("\n");
+ TRACE_AND_STEP();
+ *destreg = neg_word(*destreg);
+ break;
+ case 4:
+ DECODE_PRINTF("\n");
+ TRACE_AND_STEP();
+ mul_word(*destreg); /*!!! */
+ break;
+ case 5:
+ DECODE_PRINTF("\n");
+ TRACE_AND_STEP();
+ imul_word(*destreg);
+ break;
+ case 6:
+ DECODE_PRINTF("\n");
+ TRACE_AND_STEP();
+ div_word(*destreg);
+ break;
+ case 7:
+ DECODE_PRINTF("\n");
+ TRACE_AND_STEP();
+ idiv_word(*destreg);
+ break;
+ }
+ }
+ }
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/****************************************************************************
@@ -10766,13 +4765,13 @@ Handles opcode 0xf8
****************************************************************************/
void x86emuOp_clc(u8 X86EMU_UNUSED(op1))
{
- /* clear the carry flag. */
- START_OF_INSTR();
- DECODE_PRINTF("CLC\n");
- TRACE_AND_STEP();
- CLEAR_FLAG(F_CF);
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ /* clear the carry flag. */
+ START_OF_INSTR();
+ DECODE_PRINTF("CLC\n");
+ TRACE_AND_STEP();
+ CLEAR_FLAG(F_CF);
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/****************************************************************************
@@ -10781,13 +4780,13 @@ Handles opcode 0xf9
****************************************************************************/
void x86emuOp_stc(u8 X86EMU_UNUSED(op1))
{
- /* set the carry flag. */
- START_OF_INSTR();
- DECODE_PRINTF("STC\n");
- TRACE_AND_STEP();
- SET_FLAG(F_CF);
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ /* set the carry flag. */
+ START_OF_INSTR();
+ DECODE_PRINTF("STC\n");
+ TRACE_AND_STEP();
+ SET_FLAG(F_CF);
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/****************************************************************************
@@ -10796,13 +4795,13 @@ Handles opcode 0xfa
****************************************************************************/
void x86emuOp_cli(u8 X86EMU_UNUSED(op1))
{
- /* clear interrupts. */
- START_OF_INSTR();
- DECODE_PRINTF("CLI\n");
- TRACE_AND_STEP();
- CLEAR_FLAG(F_IF);
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ /* clear interrupts. */
+ START_OF_INSTR();
+ DECODE_PRINTF("CLI\n");
+ TRACE_AND_STEP();
+ CLEAR_FLAG(F_IF);
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/****************************************************************************
@@ -10811,13 +4810,13 @@ Handles opcode 0xfb
****************************************************************************/
void x86emuOp_sti(u8 X86EMU_UNUSED(op1))
{
- /* enable interrupts. */
- START_OF_INSTR();
- DECODE_PRINTF("STI\n");
- TRACE_AND_STEP();
- SET_FLAG(F_IF);
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ /* enable interrupts. */
+ START_OF_INSTR();
+ DECODE_PRINTF("STI\n");
+ TRACE_AND_STEP();
+ SET_FLAG(F_IF);
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/****************************************************************************
@@ -10826,13 +4825,13 @@ Handles opcode 0xfc
****************************************************************************/
void x86emuOp_cld(u8 X86EMU_UNUSED(op1))
{
- /* clear interrupts. */
- START_OF_INSTR();
- DECODE_PRINTF("CLD\n");
- TRACE_AND_STEP();
- CLEAR_FLAG(F_DF);
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ /* clear interrupts. */
+ START_OF_INSTR();
+ DECODE_PRINTF("CLD\n");
+ TRACE_AND_STEP();
+ CLEAR_FLAG(F_DF);
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/****************************************************************************
@@ -10841,13 +4840,13 @@ Handles opcode 0xfd
****************************************************************************/
void x86emuOp_std(u8 X86EMU_UNUSED(op1))
{
- /* clear interrupts. */
- START_OF_INSTR();
- DECODE_PRINTF("STD\n");
- TRACE_AND_STEP();
- SET_FLAG(F_DF);
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ /* clear interrupts. */
+ START_OF_INSTR();
+ DECODE_PRINTF("STD\n");
+ TRACE_AND_STEP();
+ SET_FLAG(F_DF);
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/****************************************************************************
@@ -10856,115 +4855,62 @@ Handles opcode 0xfe
****************************************************************************/
void x86emuOp_opcFE_byte_RM(u8 X86EMU_UNUSED(op1))
{
- int mod, rh, rl;
- u8 destval;
- uint destoffset;
- u8 *destreg;
+ int mod, rh, rl;
+ u8 destval;
+ uint destoffset;
+ u8 *destreg;
- /* Yet another special case instruction. */
- START_OF_INSTR();
- FETCH_DECODE_MODRM(mod, rh, rl);
+ /* Yet another special case instruction. */
+ START_OF_INSTR();
+ FETCH_DECODE_MODRM(mod, rh, rl);
#ifdef DEBUG
- if (DEBUG_DECODE()) {
- /* XXX DECODE_PRINTF may be changed to something more
- general, so that it is important to leave the strings
- in the same format, even though the result is that the
- above test is done twice. */
-
- switch (rh) {
- case 0:
- DECODE_PRINTF("INC\t");
- break;
- case 1:
- DECODE_PRINTF("DEC\t");
- break;
- case 2:
- case 3:
- case 4:
- case 5:
- case 6:
- case 7:
- DECODE_PRINTF2("ILLEGAL OP MAJOR OP 0xFE MINOR OP %x \n", mod);
- HALT_SYS();
- break;
- }
- }
+ if (DEBUG_DECODE()) {
+ /* XXX DECODE_PRINTF may be changed to something more
+ general, so that it is important to leave the strings
+ in the same format, even though the result is that the
+ above test is done twice. */
+
+ switch (rh) {
+ case 0:
+ DECODE_PRINTF("INC\t");
+ break;
+ case 1:
+ DECODE_PRINTF("DEC\t");
+ break;
+ case 2:
+ case 3:
+ case 4:
+ case 5:
+ case 6:
+ case 7:
+ DECODE_PRINTF2("ILLEGAL OP MAJOR OP 0xFE MINOR OP %x \n", mod);
+ HALT_SYS();
+ break;
+ }
+ }
#endif
- switch (mod) {
- case 0:
- DECODE_PRINTF("BYTE PTR ");
- destoffset = decode_rm00_address(rl);
- DECODE_PRINTF("\n");
- switch (rh) {
- case 0: /* inc word ptr ... */
- destval = fetch_data_byte(destoffset);
- TRACE_AND_STEP();
- destval = inc_byte(destval);
- store_data_byte(destoffset, destval);
- break;
- case 1: /* dec word ptr ... */
- destval = fetch_data_byte(destoffset);
- TRACE_AND_STEP();
- destval = dec_byte(destval);
- store_data_byte(destoffset, destval);
- break;
- }
- break;
- case 1:
- DECODE_PRINTF("BYTE PTR ");
- destoffset = decode_rm01_address(rl);
- DECODE_PRINTF("\n");
- switch (rh) {
- case 0:
- destval = fetch_data_byte(destoffset);
- TRACE_AND_STEP();
- destval = inc_byte(destval);
- store_data_byte(destoffset, destval);
- break;
- case 1:
- destval = fetch_data_byte(destoffset);
- TRACE_AND_STEP();
- destval = dec_byte(destval);
- store_data_byte(destoffset, destval);
- break;
- }
- break;
- case 2:
- DECODE_PRINTF("BYTE PTR ");
- destoffset = decode_rm10_address(rl);
- DECODE_PRINTF("\n");
- switch (rh) {
- case 0:
- destval = fetch_data_byte(destoffset);
- TRACE_AND_STEP();
- destval = inc_byte(destval);
- store_data_byte(destoffset, destval);
- break;
- case 1:
- destval = fetch_data_byte(destoffset);
- TRACE_AND_STEP();
- destval = dec_byte(destval);
- store_data_byte(destoffset, destval);
- break;
- }
- break;
- case 3:
- destreg = DECODE_RM_BYTE_REGISTER(rl);
- DECODE_PRINTF("\n");
- switch (rh) {
- case 0:
- TRACE_AND_STEP();
- *destreg = inc_byte(*destreg);
- break;
- case 1:
- TRACE_AND_STEP();
- *destreg = dec_byte(*destreg);
- break;
- }
- break;
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ if (mod < 3) {
+ DECODE_PRINTF("BYTE PTR ");
+ destoffset = decode_rmXX_address(mod, rl);
+ DECODE_PRINTF("\n");
+ destval = fetch_data_byte(destoffset);
+ TRACE_AND_STEP();
+ if (rh == 0)
+ destval = inc_byte(destval);
+ else
+ destval = dec_byte(destval);
+ store_data_byte(destoffset, destval);
+ } else {
+ destreg = DECODE_RM_BYTE_REGISTER(rl);
+ DECODE_PRINTF("\n");
+ TRACE_AND_STEP();
+ if (rh == 0)
+ *destreg = inc_byte(*destreg);
+ else
+ *destreg = dec_byte(*destreg);
+ }
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/****************************************************************************
@@ -10973,499 +4919,344 @@ Handles opcode 0xff
****************************************************************************/
void x86emuOp_opcFF_word_RM(u8 X86EMU_UNUSED(op1))
{
- int mod, rh, rl;
- uint destoffset = 0;
+ int mod, rh, rl;
+ uint destoffset = 0;
u16 *destreg;
- u16 destval, destval2;
+ u16 destval,destval2;
- /* Yet another special case instruction. */
- START_OF_INSTR();
- FETCH_DECODE_MODRM(mod, rh, rl);
+ /* Yet another special case instruction. */
+ START_OF_INSTR();
+ FETCH_DECODE_MODRM(mod, rh, rl);
#ifdef DEBUG
- if (DEBUG_DECODE()) {
- /* XXX DECODE_PRINTF may be changed to something more
- general, so that it is important to leave the strings
- in the same format, even though the result is that the
- above test is done twice. */
-
- switch (rh) {
- case 0:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- DECODE_PRINTF("INC\tDWORD PTR ");
- } else {
- DECODE_PRINTF("INC\tWORD PTR ");
- }
- break;
- case 1:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- DECODE_PRINTF("DEC\tDWORD PTR ");
- } else {
- DECODE_PRINTF("DEC\tWORD PTR ");
- }
- break;
- case 2:
- DECODE_PRINTF("CALL\t");
- break;
- case 3:
- DECODE_PRINTF("CALL\tFAR ");
- break;
- case 4:
- DECODE_PRINTF("JMP\t");
- break;
- case 5:
- DECODE_PRINTF("JMP\tFAR ");
- break;
- case 6:
- DECODE_PRINTF("PUSH\t");
- break;
- case 7:
- DECODE_PRINTF("ILLEGAL DECODING OF OPCODE FF\t");
- HALT_SYS();
- break;
- }
- }
+ if (DEBUG_DECODE()) {
+ /* XXX DECODE_PRINTF may be changed to something more
+ general, so that it is important to leave the strings
+ in the same format, even though the result is that the
+ above test is done twice. */
+
+ switch (rh) {
+ case 0:
+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+ DECODE_PRINTF("INC\tDWORD PTR ");
+ } else {
+ DECODE_PRINTF("INC\tWORD PTR ");
+ }
+ break;
+ case 1:
+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+ DECODE_PRINTF("DEC\tDWORD PTR ");
+ } else {
+ DECODE_PRINTF("DEC\tWORD PTR ");
+ }
+ break;
+ case 2:
+ DECODE_PRINTF("CALL\t ");
+ break;
+ case 3:
+ DECODE_PRINTF("CALL\tFAR ");
+ break;
+ case 4:
+ DECODE_PRINTF("JMP\t");
+ break;
+ case 5:
+ DECODE_PRINTF("JMP\tFAR ");
+ break;
+ case 6:
+ DECODE_PRINTF("PUSH\t");
+ break;
+ case 7:
+ DECODE_PRINTF("ILLEGAL DECODING OF OPCODE FF\t");
+ HALT_SYS();
+ break;
+ }
+ }
#endif
- switch (mod) {
- case 0:
- destoffset = decode_rm00_address(rl);
- DECODE_PRINTF("\n");
- switch (rh) {
- case 0: /* inc word ptr ... */
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 destval;
-
- destval = fetch_data_long(destoffset);
- TRACE_AND_STEP();
- destval = inc_long(destval);
- store_data_long(destoffset, destval);
- } else {
- u16 destval;
-
- destval = fetch_data_word(destoffset);
- TRACE_AND_STEP();
- destval = inc_word(destval);
- store_data_word(destoffset, destval);
- }
- break;
- case 1: /* dec word ptr ... */
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 destval;
-
- destval = fetch_data_long(destoffset);
- TRACE_AND_STEP();
- destval = dec_long(destval);
- store_data_long(destoffset, destval);
- } else {
- u16 destval;
-
- destval = fetch_data_word(destoffset);
- TRACE_AND_STEP();
- destval = dec_word(destval);
- store_data_word(destoffset, destval);
- }
- break;
- case 2: /* call word ptr ... */
- destval = fetch_data_word(destoffset);
- TRACE_AND_STEP();
- push_word(M.x86.R_IP);
- M.x86.R_IP = destval;
- break;
- case 3: /* call far ptr ... */
- destval = fetch_data_word(destoffset);
- destval2 = fetch_data_word(destoffset + 2);
- TRACE_AND_STEP();
- push_word(M.x86.R_CS);
- M.x86.R_CS = destval2;
- push_word(M.x86.R_IP);
- M.x86.R_IP = destval;
- break;
- case 4: /* jmp word ptr ... */
- destval = fetch_data_word(destoffset);
- TRACE_AND_STEP();
- M.x86.R_IP = destval;
- break;
- case 5: /* jmp far ptr ... */
- destval = fetch_data_word(destoffset);
- destval2 = fetch_data_word(destoffset + 2);
- TRACE_AND_STEP();
- M.x86.R_IP = destval;
- M.x86.R_CS = destval2;
- break;
- case 6: /* push word ptr ... */
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 destval;
-
- destval = fetch_data_long(destoffset);
- TRACE_AND_STEP();
- push_long(destval);
- } else {
- u16 destval;
-
- destval = fetch_data_word(destoffset);
- TRACE_AND_STEP();
- push_word(destval);
- }
- break;
- }
- break;
- case 1:
- destoffset = decode_rm01_address(rl);
- DECODE_PRINTF("\n");
- switch (rh) {
- case 0:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 destval;
-
- destval = fetch_data_long(destoffset);
- TRACE_AND_STEP();
- destval = inc_long(destval);
- store_data_long(destoffset, destval);
- } else {
- u16 destval;
-
- destval = fetch_data_word(destoffset);
- TRACE_AND_STEP();
- destval = inc_word(destval);
- store_data_word(destoffset, destval);
- }
- break;
- case 1:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 destval;
-
- destval = fetch_data_long(destoffset);
- TRACE_AND_STEP();
- destval = dec_long(destval);
- store_data_long(destoffset, destval);
- } else {
- u16 destval;
-
- destval = fetch_data_word(destoffset);
- TRACE_AND_STEP();
- destval = dec_word(destval);
- store_data_word(destoffset, destval);
- }
- break;
- case 2: /* call word ptr ... */
- destval = fetch_data_word(destoffset);
- TRACE_AND_STEP();
- push_word(M.x86.R_IP);
- M.x86.R_IP = destval;
- break;
- case 3: /* call far ptr ... */
- destval = fetch_data_word(destoffset);
- destval2 = fetch_data_word(destoffset + 2);
- TRACE_AND_STEP();
- push_word(M.x86.R_CS);
- M.x86.R_CS = destval2;
- push_word(M.x86.R_IP);
- M.x86.R_IP = destval;
- break;
- case 4: /* jmp word ptr ... */
- destval = fetch_data_word(destoffset);
- TRACE_AND_STEP();
- M.x86.R_IP = destval;
- break;
- case 5: /* jmp far ptr ... */
- destval = fetch_data_word(destoffset);
- destval2 = fetch_data_word(destoffset + 2);
- TRACE_AND_STEP();
- M.x86.R_IP = destval;
- M.x86.R_CS = destval2;
- break;
- case 6: /* push word ptr ... */
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 destval;
-
- destval = fetch_data_long(destoffset);
- TRACE_AND_STEP();
- push_long(destval);
- } else {
- u16 destval;
-
- destval = fetch_data_word(destoffset);
- TRACE_AND_STEP();
- push_word(destval);
- }
- break;
- }
- break;
- case 2:
- destoffset = decode_rm10_address(rl);
- DECODE_PRINTF("\n");
- switch (rh) {
- case 0:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 destval;
-
- destval = fetch_data_long(destoffset);
- TRACE_AND_STEP();
- destval = inc_long(destval);
- store_data_long(destoffset, destval);
- } else {
- u16 destval;
-
- destval = fetch_data_word(destoffset);
- TRACE_AND_STEP();
- destval = inc_word(destval);
- store_data_word(destoffset, destval);
- }
- break;
- case 1:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 destval;
-
- destval = fetch_data_long(destoffset);
- TRACE_AND_STEP();
- destval = dec_long(destval);
- store_data_long(destoffset, destval);
- } else {
- u16 destval;
-
- destval = fetch_data_word(destoffset);
- TRACE_AND_STEP();
- destval = dec_word(destval);
- store_data_word(destoffset, destval);
- }
- break;
- case 2: /* call word ptr ... */
- destval = fetch_data_word(destoffset);
- TRACE_AND_STEP();
- push_word(M.x86.R_IP);
- M.x86.R_IP = destval;
- break;
- case 3: /* call far ptr ... */
- destval = fetch_data_word(destoffset);
- destval2 = fetch_data_word(destoffset + 2);
- TRACE_AND_STEP();
- push_word(M.x86.R_CS);
- M.x86.R_CS = destval2;
- push_word(M.x86.R_IP);
- M.x86.R_IP = destval;
- break;
- case 4: /* jmp word ptr ... */
- destval = fetch_data_word(destoffset);
- TRACE_AND_STEP();
- M.x86.R_IP = destval;
- break;
- case 5: /* jmp far ptr ... */
- destval = fetch_data_word(destoffset);
- destval2 = fetch_data_word(destoffset + 2);
- TRACE_AND_STEP();
- M.x86.R_IP = destval;
- M.x86.R_CS = destval2;
- break;
- case 6: /* push word ptr ... */
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 destval;
-
- destval = fetch_data_long(destoffset);
- TRACE_AND_STEP();
- push_long(destval);
- } else {
- u16 destval;
-
- destval = fetch_data_word(destoffset);
- TRACE_AND_STEP();
- push_word(destval);
- }
- break;
- }
- break;
- case 3:
- switch (rh) {
- case 0:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 *destreg;
-
- destreg = DECODE_RM_LONG_REGISTER(rl);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = inc_long(*destreg);
- } else {
- u16 *destreg;
-
- destreg = DECODE_RM_WORD_REGISTER(rl);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = inc_word(*destreg);
- }
- break;
- case 1:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 *destreg;
-
- destreg = DECODE_RM_LONG_REGISTER(rl);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = dec_long(*destreg);
- } else {
- u16 *destreg;
-
- destreg = DECODE_RM_WORD_REGISTER(rl);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- *destreg = dec_word(*destreg);
- }
- break;
- case 2: /* call word ptr ... */
- destreg = DECODE_RM_WORD_REGISTER(rl);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- push_word(M.x86.R_IP);
- M.x86.R_IP = *destreg;
- break;
- case 3: /* jmp far ptr ... */
- DECODE_PRINTF("OPERATION UNDEFINED 0XFF \n");
- TRACE_AND_STEP();
- HALT_SYS();
- break;
-
- case 4: /* jmp ... */
- destreg = DECODE_RM_WORD_REGISTER(rl);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- M.x86.R_IP = (u16) (*destreg);
- break;
- case 5: /* jmp far ptr ... */
- DECODE_PRINTF("OPERATION UNDEFINED 0XFF \n");
- TRACE_AND_STEP();
- HALT_SYS();
- break;
- case 6:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 *destreg;
-
- destreg = DECODE_RM_LONG_REGISTER(rl);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- push_long(*destreg);
- } else {
- u16 *destreg;
-
- destreg = DECODE_RM_WORD_REGISTER(rl);
- DECODE_PRINTF("\n");
- TRACE_AND_STEP();
- push_word(*destreg);
- }
- break;
- }
- break;
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ if (mod < 3) {
+ destoffset = decode_rmXX_address(mod, rl);
+ DECODE_PRINTF("\n");
+ switch (rh) {
+ case 0: /* inc word ptr ... */
+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+ u32 destval;
+
+ destval = fetch_data_long(destoffset);
+ TRACE_AND_STEP();
+ destval = inc_long(destval);
+ store_data_long(destoffset, destval);
+ } else {
+ u16 destval;
+
+ destval = fetch_data_word(destoffset);
+ TRACE_AND_STEP();
+ destval = inc_word(destval);
+ store_data_word(destoffset, destval);
+ }
+ break;
+ case 1: /* dec word ptr ... */
+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+ u32 destval;
+
+ destval = fetch_data_long(destoffset);
+ TRACE_AND_STEP();
+ destval = dec_long(destval);
+ store_data_long(destoffset, destval);
+ } else {
+ u16 destval;
+
+ destval = fetch_data_word(destoffset);
+ TRACE_AND_STEP();
+ destval = dec_word(destval);
+ store_data_word(destoffset, destval);
+ }
+ break;
+ case 2: /* call word ptr ... */
+ destval = fetch_data_word(destoffset);
+ TRACE_AND_STEP();
+ push_word(M.x86.R_IP);
+ M.x86.R_IP = destval;
+ break;
+ case 3: /* call far ptr ... */
+ destval = fetch_data_word(destoffset);
+ destval2 = fetch_data_word(destoffset + 2);
+ TRACE_AND_STEP();
+ push_word(M.x86.R_CS);
+ M.x86.R_CS = destval2;
+ push_word(M.x86.R_IP);
+ M.x86.R_IP = destval;
+ break;
+ case 4: /* jmp word ptr ... */
+ destval = fetch_data_word(destoffset);
+ TRACE_AND_STEP();
+ M.x86.R_IP = destval;
+ break;
+ case 5: /* jmp far ptr ... */
+ destval = fetch_data_word(destoffset);
+ destval2 = fetch_data_word(destoffset + 2);
+ TRACE_AND_STEP();
+ M.x86.R_IP = destval;
+ M.x86.R_CS = destval2;
+ break;
+ case 6: /* push word ptr ... */
+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+ u32 destval;
+
+ destval = fetch_data_long(destoffset);
+ TRACE_AND_STEP();
+ push_long(destval);
+ } else {
+ u16 destval;
+
+ destval = fetch_data_word(destoffset);
+ TRACE_AND_STEP();
+ push_word(destval);
+ }
+ break;
+ }
+ } else {
+ switch (rh) {
+ case 0:
+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+ u32 *destreg;
+
+ destreg = DECODE_RM_LONG_REGISTER(rl);
+ DECODE_PRINTF("\n");
+ TRACE_AND_STEP();
+ *destreg = inc_long(*destreg);
+ } else {
+ u16 *destreg;
+
+ destreg = DECODE_RM_WORD_REGISTER(rl);
+ DECODE_PRINTF("\n");
+ TRACE_AND_STEP();
+ *destreg = inc_word(*destreg);
+ }
+ break;
+ case 1:
+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+ u32 *destreg;
+
+ destreg = DECODE_RM_LONG_REGISTER(rl);
+ DECODE_PRINTF("\n");
+ TRACE_AND_STEP();
+ *destreg = dec_long(*destreg);
+ } else {
+ u16 *destreg;
+
+ destreg = DECODE_RM_WORD_REGISTER(rl);
+ DECODE_PRINTF("\n");
+ TRACE_AND_STEP();
+ *destreg = dec_word(*destreg);
+ }
+ break;
+ case 2: /* call word ptr ... */
+ destreg = DECODE_RM_WORD_REGISTER(rl);
+ DECODE_PRINTF("\n");
+ TRACE_AND_STEP();
+ push_word(M.x86.R_IP);
+ M.x86.R_IP = *destreg;
+ break;
+ case 3: /* jmp far ptr ... */
+ DECODE_PRINTF("OPERATION UNDEFINED 0XFF \n");
+ TRACE_AND_STEP();
+ HALT_SYS();
+ break;
+
+ case 4: /* jmp ... */
+ destreg = DECODE_RM_WORD_REGISTER(rl);
+ DECODE_PRINTF("\n");
+ TRACE_AND_STEP();
+ M.x86.R_IP = (u16) (*destreg);
+ break;
+ case 5: /* jmp far ptr ... */
+ DECODE_PRINTF("OPERATION UNDEFINED 0XFF \n");
+ TRACE_AND_STEP();
+ HALT_SYS();
+ break;
+ case 6:
+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+ u32 *destreg;
+
+ destreg = DECODE_RM_LONG_REGISTER(rl);
+ DECODE_PRINTF("\n");
+ TRACE_AND_STEP();
+ push_long(*destreg);
+ } else {
+ u16 *destreg;
+
+ destreg = DECODE_RM_WORD_REGISTER(rl);
+ DECODE_PRINTF("\n");
+ TRACE_AND_STEP();
+ push_word(*destreg);
+ }
+ break;
+ }
+ }
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/***************************************************************************
* Single byte operation code table:
**************************************************************************/
-void (*x86emu_optab[256]) (u8) = {
-/* 0x00 */ x86emuOp_add_byte_RM_R,
-/* 0x01 */ x86emuOp_add_word_RM_R,
-/* 0x02 */ x86emuOp_add_byte_R_RM,
-/* 0x03 */ x86emuOp_add_word_R_RM,
-/* 0x04 */ x86emuOp_add_byte_AL_IMM,
-/* 0x05 */ x86emuOp_add_word_AX_IMM,
+void (*x86emu_optab[256])(u8) =
+{
+/* 0x00 */ x86emuOp_genop_byte_RM_R,
+/* 0x01 */ x86emuOp_genop_word_RM_R,
+/* 0x02 */ x86emuOp_genop_byte_R_RM,
+/* 0x03 */ x86emuOp_genop_word_R_RM,
+/* 0x04 */ x86emuOp_genop_byte_AL_IMM,
+/* 0x05 */ x86emuOp_genop_word_AX_IMM,
/* 0x06 */ x86emuOp_push_ES,
/* 0x07 */ x86emuOp_pop_ES,
-/* 0x08 */ x86emuOp_or_byte_RM_R,
-/* 0x09 */ x86emuOp_or_word_RM_R,
-/* 0x0a */ x86emuOp_or_byte_R_RM,
-/* 0x0b */ x86emuOp_or_word_R_RM,
-/* 0x0c */ x86emuOp_or_byte_AL_IMM,
-/* 0x0d */ x86emuOp_or_word_AX_IMM,
+
+/* 0x08 */ x86emuOp_genop_byte_RM_R,
+/* 0x09 */ x86emuOp_genop_word_RM_R,
+/* 0x0a */ x86emuOp_genop_byte_R_RM,
+/* 0x0b */ x86emuOp_genop_word_R_RM,
+/* 0x0c */ x86emuOp_genop_byte_AL_IMM,
+/* 0x0d */ x86emuOp_genop_word_AX_IMM,
/* 0x0e */ x86emuOp_push_CS,
/* 0x0f */ x86emuOp_two_byte,
-/* 0x10 */ x86emuOp_adc_byte_RM_R,
-/* 0x11 */ x86emuOp_adc_word_RM_R,
-/* 0x12 */ x86emuOp_adc_byte_R_RM,
-/* 0x13 */ x86emuOp_adc_word_R_RM,
-/* 0x14 */ x86emuOp_adc_byte_AL_IMM,
-/* 0x15 */ x86emuOp_adc_word_AX_IMM,
+
+/* 0x10 */ x86emuOp_genop_byte_RM_R,
+/* 0x11 */ x86emuOp_genop_word_RM_R,
+/* 0x12 */ x86emuOp_genop_byte_R_RM,
+/* 0x13 */ x86emuOp_genop_word_R_RM,
+/* 0x14 */ x86emuOp_genop_byte_AL_IMM,
+/* 0x15 */ x86emuOp_genop_word_AX_IMM,
/* 0x16 */ x86emuOp_push_SS,
/* 0x17 */ x86emuOp_pop_SS,
-/* 0x18 */ x86emuOp_sbb_byte_RM_R,
-/* 0x19 */ x86emuOp_sbb_word_RM_R,
-/* 0x1a */ x86emuOp_sbb_byte_R_RM,
-/* 0x1b */ x86emuOp_sbb_word_R_RM,
-/* 0x1c */ x86emuOp_sbb_byte_AL_IMM,
-/* 0x1d */ x86emuOp_sbb_word_AX_IMM,
+
+/* 0x18 */ x86emuOp_genop_byte_RM_R,
+/* 0x19 */ x86emuOp_genop_word_RM_R,
+/* 0x1a */ x86emuOp_genop_byte_R_RM,
+/* 0x1b */ x86emuOp_genop_word_R_RM,
+/* 0x1c */ x86emuOp_genop_byte_AL_IMM,
+/* 0x1d */ x86emuOp_genop_word_AX_IMM,
/* 0x1e */ x86emuOp_push_DS,
/* 0x1f */ x86emuOp_pop_DS,
-/* 0x20 */ x86emuOp_and_byte_RM_R,
-/* 0x21 */ x86emuOp_and_word_RM_R,
-/* 0x22 */ x86emuOp_and_byte_R_RM,
-/* 0x23 */ x86emuOp_and_word_R_RM,
-/* 0x24 */ x86emuOp_and_byte_AL_IMM,
-/* 0x25 */ x86emuOp_and_word_AX_IMM,
+
+/* 0x20 */ x86emuOp_genop_byte_RM_R,
+/* 0x21 */ x86emuOp_genop_word_RM_R,
+/* 0x22 */ x86emuOp_genop_byte_R_RM,
+/* 0x23 */ x86emuOp_genop_word_R_RM,
+/* 0x24 */ x86emuOp_genop_byte_AL_IMM,
+/* 0x25 */ x86emuOp_genop_word_AX_IMM,
/* 0x26 */ x86emuOp_segovr_ES,
/* 0x27 */ x86emuOp_daa,
-/* 0x28 */ x86emuOp_sub_byte_RM_R,
-/* 0x29 */ x86emuOp_sub_word_RM_R,
-/* 0x2a */ x86emuOp_sub_byte_R_RM,
-/* 0x2b */ x86emuOp_sub_word_R_RM,
-/* 0x2c */ x86emuOp_sub_byte_AL_IMM,
-/* 0x2d */ x86emuOp_sub_word_AX_IMM,
+
+/* 0x28 */ x86emuOp_genop_byte_RM_R,
+/* 0x29 */ x86emuOp_genop_word_RM_R,
+/* 0x2a */ x86emuOp_genop_byte_R_RM,
+/* 0x2b */ x86emuOp_genop_word_R_RM,
+/* 0x2c */ x86emuOp_genop_byte_AL_IMM,
+/* 0x2d */ x86emuOp_genop_word_AX_IMM,
/* 0x2e */ x86emuOp_segovr_CS,
/* 0x2f */ x86emuOp_das,
-/* 0x30 */ x86emuOp_xor_byte_RM_R,
-/* 0x31 */ x86emuOp_xor_word_RM_R,
-/* 0x32 */ x86emuOp_xor_byte_R_RM,
-/* 0x33 */ x86emuOp_xor_word_R_RM,
-/* 0x34 */ x86emuOp_xor_byte_AL_IMM,
-/* 0x35 */ x86emuOp_xor_word_AX_IMM,
+
+/* 0x30 */ x86emuOp_genop_byte_RM_R,
+/* 0x31 */ x86emuOp_genop_word_RM_R,
+/* 0x32 */ x86emuOp_genop_byte_R_RM,
+/* 0x33 */ x86emuOp_genop_word_R_RM,
+/* 0x34 */ x86emuOp_genop_byte_AL_IMM,
+/* 0x35 */ x86emuOp_genop_word_AX_IMM,
/* 0x36 */ x86emuOp_segovr_SS,
/* 0x37 */ x86emuOp_aaa,
-/* 0x38 */ x86emuOp_cmp_byte_RM_R,
-/* 0x39 */ x86emuOp_cmp_word_RM_R,
-/* 0x3a */ x86emuOp_cmp_byte_R_RM,
-/* 0x3b */ x86emuOp_cmp_word_R_RM,
-/* 0x3c */ x86emuOp_cmp_byte_AL_IMM,
-/* 0x3d */ x86emuOp_cmp_word_AX_IMM,
+
+/* 0x38 */ x86emuOp_genop_byte_RM_R,
+/* 0x39 */ x86emuOp_genop_word_RM_R,
+/* 0x3a */ x86emuOp_genop_byte_R_RM,
+/* 0x3b */ x86emuOp_genop_word_R_RM,
+/* 0x3c */ x86emuOp_genop_byte_AL_IMM,
+/* 0x3d */ x86emuOp_genop_word_AX_IMM,
/* 0x3e */ x86emuOp_segovr_DS,
/* 0x3f */ x86emuOp_aas,
-/* 0x40 */ x86emuOp_inc_AX,
-/* 0x41 */ x86emuOp_inc_CX,
-/* 0x42 */ x86emuOp_inc_DX,
-/* 0x43 */ x86emuOp_inc_BX,
-/* 0x44 */ x86emuOp_inc_SP,
-/* 0x45 */ x86emuOp_inc_BP,
-/* 0x46 */ x86emuOp_inc_SI,
-/* 0x47 */ x86emuOp_inc_DI,
-/* 0x48 */ x86emuOp_dec_AX,
-/* 0x49 */ x86emuOp_dec_CX,
-/* 0x4a */ x86emuOp_dec_DX,
-/* 0x4b */ x86emuOp_dec_BX,
-/* 0x4c */ x86emuOp_dec_SP,
-/* 0x4d */ x86emuOp_dec_BP,
-/* 0x4e */ x86emuOp_dec_SI,
-/* 0x4f */ x86emuOp_dec_DI,
-/* 0x50 */ x86emuOp_push_AX,
-/* 0x51 */ x86emuOp_push_CX,
-/* 0x52 */ x86emuOp_push_DX,
-/* 0x53 */ x86emuOp_push_BX,
-/* 0x54 */ x86emuOp_push_SP,
-/* 0x55 */ x86emuOp_push_BP,
-/* 0x56 */ x86emuOp_push_SI,
-/* 0x57 */ x86emuOp_push_DI,
-/* 0x58 */ x86emuOp_pop_AX,
-/* 0x59 */ x86emuOp_pop_CX,
-/* 0x5a */ x86emuOp_pop_DX,
-/* 0x5b */ x86emuOp_pop_BX,
-/* 0x5c */ x86emuOp_pop_SP,
-/* 0x5d */ x86emuOp_pop_BP,
-/* 0x5e */ x86emuOp_pop_SI,
-/* 0x5f */ x86emuOp_pop_DI,
+
+/* 0x40 */ x86emuOp_inc_register,
+/* 0x41 */ x86emuOp_inc_register,
+/* 0x42 */ x86emuOp_inc_register,
+/* 0x43 */ x86emuOp_inc_register,
+/* 0x44 */ x86emuOp_inc_register,
+/* 0x45 */ x86emuOp_inc_register,
+/* 0x46 */ x86emuOp_inc_register,
+/* 0x47 */ x86emuOp_inc_register,
+
+/* 0x48 */ x86emuOp_dec_register,
+/* 0x49 */ x86emuOp_dec_register,
+/* 0x4a */ x86emuOp_dec_register,
+/* 0x4b */ x86emuOp_dec_register,
+/* 0x4c */ x86emuOp_dec_register,
+/* 0x4d */ x86emuOp_dec_register,
+/* 0x4e */ x86emuOp_dec_register,
+/* 0x4f */ x86emuOp_dec_register,
+
+/* 0x50 */ x86emuOp_push_register,
+/* 0x51 */ x86emuOp_push_register,
+/* 0x52 */ x86emuOp_push_register,
+/* 0x53 */ x86emuOp_push_register,
+/* 0x54 */ x86emuOp_push_register,
+/* 0x55 */ x86emuOp_push_register,
+/* 0x56 */ x86emuOp_push_register,
+/* 0x57 */ x86emuOp_push_register,
+
+/* 0x58 */ x86emuOp_pop_register,
+/* 0x59 */ x86emuOp_pop_register,
+/* 0x5a */ x86emuOp_pop_register,
+/* 0x5b */ x86emuOp_pop_register,
+/* 0x5c */ x86emuOp_pop_register,
+/* 0x5d */ x86emuOp_pop_register,
+/* 0x5e */ x86emuOp_pop_register,
+/* 0x5f */ x86emuOp_pop_register,
+
/* 0x60 */ x86emuOp_push_all,
/* 0x61 */ x86emuOp_pop_all,
- /* 0x62 */ x86emuOp_illegal_op,
- /* bound */
- /* 0x63 */ x86emuOp_illegal_op,
- /* arpl */
+/* 0x62 */ x86emuOp_illegal_op, /* bound */
+/* 0x63 */ x86emuOp_illegal_op, /* arpl */
/* 0x64 */ x86emuOp_segovr_FS,
/* 0x65 */ x86emuOp_segovr_GS,
/* 0x66 */ x86emuOp_prefix_data,
/* 0x67 */ x86emuOp_prefix_addr,
+
/* 0x68 */ x86emuOp_push_word_IMM,
/* 0x69 */ x86emuOp_imul_word_IMM,
/* 0x6a */ x86emuOp_push_byte_IMM,
@@ -11474,22 +5265,25 @@ void (*x86emu_optab[256]) (u8) = {
/* 0x6d */ x86emuOp_ins_word,
/* 0x6e */ x86emuOp_outs_byte,
/* 0x6f */ x86emuOp_outs_word,
-/* 0x70 */ x86emuOp_jump_near_O,
-/* 0x71 */ x86emuOp_jump_near_NO,
-/* 0x72 */ x86emuOp_jump_near_B,
-/* 0x73 */ x86emuOp_jump_near_NB,
-/* 0x74 */ x86emuOp_jump_near_Z,
-/* 0x75 */ x86emuOp_jump_near_NZ,
-/* 0x76 */ x86emuOp_jump_near_BE,
-/* 0x77 */ x86emuOp_jump_near_NBE,
-/* 0x78 */ x86emuOp_jump_near_S,
-/* 0x79 */ x86emuOp_jump_near_NS,
-/* 0x7a */ x86emuOp_jump_near_P,
-/* 0x7b */ x86emuOp_jump_near_NP,
-/* 0x7c */ x86emuOp_jump_near_L,
-/* 0x7d */ x86emuOp_jump_near_NL,
-/* 0x7e */ x86emuOp_jump_near_LE,
-/* 0x7f */ x86emuOp_jump_near_NLE,
+
+/* 0x70 */ x86emuOp_jump_near_cond,
+/* 0x71 */ x86emuOp_jump_near_cond,
+/* 0x72 */ x86emuOp_jump_near_cond,
+/* 0x73 */ x86emuOp_jump_near_cond,
+/* 0x74 */ x86emuOp_jump_near_cond,
+/* 0x75 */ x86emuOp_jump_near_cond,
+/* 0x76 */ x86emuOp_jump_near_cond,
+/* 0x77 */ x86emuOp_jump_near_cond,
+
+/* 0x78 */ x86emuOp_jump_near_cond,
+/* 0x79 */ x86emuOp_jump_near_cond,
+/* 0x7a */ x86emuOp_jump_near_cond,
+/* 0x7b */ x86emuOp_jump_near_cond,
+/* 0x7c */ x86emuOp_jump_near_cond,
+/* 0x7d */ x86emuOp_jump_near_cond,
+/* 0x7e */ x86emuOp_jump_near_cond,
+/* 0x7f */ x86emuOp_jump_near_cond,
+
/* 0x80 */ x86emuOp_opc80_byte_RM_IMM,
/* 0x81 */ x86emuOp_opc81_word_RM_IMM,
/* 0x82 */ x86emuOp_opc82_byte_RM_IMM,
@@ -11498,6 +5292,7 @@ void (*x86emu_optab[256]) (u8) = {
/* 0x85 */ x86emuOp_test_word_RM_R,
/* 0x86 */ x86emuOp_xchg_byte_RM_R,
/* 0x87 */ x86emuOp_xchg_word_RM_R,
+
/* 0x88 */ x86emuOp_mov_byte_RM_R,
/* 0x89 */ x86emuOp_mov_word_RM_R,
/* 0x8a */ x86emuOp_mov_byte_R_RM,
@@ -11506,14 +5301,16 @@ void (*x86emu_optab[256]) (u8) = {
/* 0x8d */ x86emuOp_lea_word_R_M,
/* 0x8e */ x86emuOp_mov_word_SR_RM,
/* 0x8f */ x86emuOp_pop_RM,
+
/* 0x90 */ x86emuOp_nop,
-/* 0x91 */ x86emuOp_xchg_word_AX_CX,
-/* 0x92 */ x86emuOp_xchg_word_AX_DX,
-/* 0x93 */ x86emuOp_xchg_word_AX_BX,
-/* 0x94 */ x86emuOp_xchg_word_AX_SP,
-/* 0x95 */ x86emuOp_xchg_word_AX_BP,
-/* 0x96 */ x86emuOp_xchg_word_AX_SI,
-/* 0x97 */ x86emuOp_xchg_word_AX_DI,
+/* 0x91 */ x86emuOp_xchg_word_AX_register,
+/* 0x92 */ x86emuOp_xchg_word_AX_register,
+/* 0x93 */ x86emuOp_xchg_word_AX_register,
+/* 0x94 */ x86emuOp_xchg_word_AX_register,
+/* 0x95 */ x86emuOp_xchg_word_AX_register,
+/* 0x96 */ x86emuOp_xchg_word_AX_register,
+/* 0x97 */ x86emuOp_xchg_word_AX_register,
+
/* 0x98 */ x86emuOp_cbw,
/* 0x99 */ x86emuOp_cwd,
/* 0x9a */ x86emuOp_call_far_IMM,
@@ -11522,6 +5319,7 @@ void (*x86emu_optab[256]) (u8) = {
/* 0x9d */ x86emuOp_popf_word,
/* 0x9e */ x86emuOp_sahf,
/* 0x9f */ x86emuOp_lahf,
+
/* 0xa0 */ x86emuOp_mov_AL_M_IMM,
/* 0xa1 */ x86emuOp_mov_AX_M_IMM,
/* 0xa2 */ x86emuOp_mov_M_AL_IMM,
@@ -11538,22 +5336,25 @@ void (*x86emu_optab[256]) (u8) = {
/* 0xad */ x86emuOp_lods_word,
/* 0xac */ x86emuOp_scas_byte,
/* 0xad */ x86emuOp_scas_word,
-/* 0xb0 */ x86emuOp_mov_byte_AL_IMM,
-/* 0xb1 */ x86emuOp_mov_byte_CL_IMM,
-/* 0xb2 */ x86emuOp_mov_byte_DL_IMM,
-/* 0xb3 */ x86emuOp_mov_byte_BL_IMM,
-/* 0xb4 */ x86emuOp_mov_byte_AH_IMM,
-/* 0xb5 */ x86emuOp_mov_byte_CH_IMM,
-/* 0xb6 */ x86emuOp_mov_byte_DH_IMM,
-/* 0xb7 */ x86emuOp_mov_byte_BH_IMM,
-/* 0xb8 */ x86emuOp_mov_word_AX_IMM,
-/* 0xb9 */ x86emuOp_mov_word_CX_IMM,
-/* 0xba */ x86emuOp_mov_word_DX_IMM,
-/* 0xbb */ x86emuOp_mov_word_BX_IMM,
-/* 0xbc */ x86emuOp_mov_word_SP_IMM,
-/* 0xbd */ x86emuOp_mov_word_BP_IMM,
-/* 0xbe */ x86emuOp_mov_word_SI_IMM,
-/* 0xbf */ x86emuOp_mov_word_DI_IMM,
+
+/* 0xb0 */ x86emuOp_mov_byte_register_IMM,
+/* 0xb1 */ x86emuOp_mov_byte_register_IMM,
+/* 0xb2 */ x86emuOp_mov_byte_register_IMM,
+/* 0xb3 */ x86emuOp_mov_byte_register_IMM,
+/* 0xb4 */ x86emuOp_mov_byte_register_IMM,
+/* 0xb5 */ x86emuOp_mov_byte_register_IMM,
+/* 0xb6 */ x86emuOp_mov_byte_register_IMM,
+/* 0xb7 */ x86emuOp_mov_byte_register_IMM,
+
+/* 0xb8 */ x86emuOp_mov_word_register_IMM,
+/* 0xb9 */ x86emuOp_mov_word_register_IMM,
+/* 0xba */ x86emuOp_mov_word_register_IMM,
+/* 0xbb */ x86emuOp_mov_word_register_IMM,
+/* 0xbc */ x86emuOp_mov_word_register_IMM,
+/* 0xbd */ x86emuOp_mov_word_register_IMM,
+/* 0xbe */ x86emuOp_mov_word_register_IMM,
+/* 0xbf */ x86emuOp_mov_word_register_IMM,
+
/* 0xc0 */ x86emuOp_opcC0_byte_RM_MEM,
/* 0xc1 */ x86emuOp_opcC1_word_RM_MEM,
/* 0xc2 */ x86emuOp_ret_near_IMM,
@@ -11570,14 +5371,14 @@ void (*x86emu_optab[256]) (u8) = {
/* 0xcd */ x86emuOp_int_IMM,
/* 0xce */ x86emuOp_into,
/* 0xcf */ x86emuOp_iret,
+
/* 0xd0 */ x86emuOp_opcD0_byte_RM_1,
/* 0xd1 */ x86emuOp_opcD1_word_RM_1,
/* 0xd2 */ x86emuOp_opcD2_byte_RM_CL,
/* 0xd3 */ x86emuOp_opcD3_word_RM_CL,
/* 0xd4 */ x86emuOp_aam,
/* 0xd5 */ x86emuOp_aad,
- /* 0xd6 */ x86emuOp_illegal_op,
- /* Undocumented SETALC instruction */
+/* 0xd6 */ x86emuOp_illegal_op, /* Undocumented SETALC instruction */
/* 0xd7 */ x86emuOp_xlat,
/* 0xd8 */ x86emuOp_esc_coprocess_d8,
/* 0xd9 */ x86emuOp_esc_coprocess_d9,
@@ -11587,6 +5388,7 @@ void (*x86emu_optab[256]) (u8) = {
/* 0xdd */ x86emuOp_esc_coprocess_dd,
/* 0xde */ x86emuOp_esc_coprocess_de,
/* 0xdf */ x86emuOp_esc_coprocess_df,
+
/* 0xe0 */ x86emuOp_loopne,
/* 0xe1 */ x86emuOp_loope,
/* 0xe2 */ x86emuOp_loop,
@@ -11595,6 +5397,7 @@ void (*x86emu_optab[256]) (u8) = {
/* 0xe5 */ x86emuOp_in_word_AX_IMM,
/* 0xe6 */ x86emuOp_out_byte_IMM_AL,
/* 0xe7 */ x86emuOp_out_word_IMM_AX,
+
/* 0xe8 */ x86emuOp_call_near_IMM,
/* 0xe9 */ x86emuOp_jump_near_IMM,
/* 0xea */ x86emuOp_jump_far_IMM,
@@ -11603,6 +5406,7 @@ void (*x86emu_optab[256]) (u8) = {
/* 0xed */ x86emuOp_in_word_AX_DX,
/* 0xee */ x86emuOp_out_byte_DX_AL,
/* 0xef */ x86emuOp_out_word_DX_AX,
+
/* 0xf0 */ x86emuOp_lock,
/* 0xf1 */ x86emuOp_illegal_op,
/* 0xf2 */ x86emuOp_repne,
@@ -11611,6 +5415,7 @@ void (*x86emu_optab[256]) (u8) = {
/* 0xf5 */ x86emuOp_cmc,
/* 0xf6 */ x86emuOp_opcF6_byte_RM,
/* 0xf7 */ x86emuOp_opcF7_word_RM,
+
/* 0xf8 */ x86emuOp_clc,
/* 0xf9 */ x86emuOp_stc,
/* 0xfa */ x86emuOp_cli,
diff --git a/util/vgabios/x86emu/src/x86emu/ops2.c b/util/vgabios/x86emu/src/x86emu/ops2.c
index da3df4fbb..e312a03fe 100644
--- a/util/vgabios/x86emu/src/x86emu/ops2.c
+++ b/util/vgabios/x86emu/src/x86emu/ops2.c
@@ -1,10 +1,10 @@
/****************************************************************************
*
-* Realmode X86 Emulator Library
+* Realmode X86 Emulator Library
*
-* Copyright (C) 1996-1999 SciTech Software, Inc.
-* Copyright (C) David Mosberger-Tang
-* Copyright (C) 1999 Egbert Eich
+* Copyright (C) 1991-2004 SciTech Software, Inc.
+* Copyright (C) David Mosberger-Tang
+* Copyright (C) 1999 Egbert Eich
*
* ========================================================================
*
@@ -28,8 +28,8 @@
*
* ========================================================================
*
-* Language: ANSI C
-* Environment: Any
+* Language: ANSI C
+* Environment: Any
* Developer: Kendall Bennett
*
* Description: This file includes subroutines to implement the decoding
@@ -37,10 +37,8 @@
* instructions.
*
****************************************************************************/
-/* $XFree86: xc/extras/x86emu/src/x86emu/ops2.c,v 1.4 2000/11/16 19:44:50 eich Exp $ */
#include "x86emu/x86emui.h"
-//#include </root/freebios/util/vgabios/x86emu/include/msr.h>
/*----------------------------- Implementation ----------------------------*/
@@ -51,50 +49,16 @@ op1 - Instruction op code
REMARKS:
Handles illegal opcodes.
****************************************************************************/
-void x86emuOp2_illegal_op(u8 op2)
+void x86emuOp2_illegal_op(
+ u8 op2)
{
- START_OF_INSTR();
- DECODE_PRINTF("ILLEGAL EXTENDED X86 OPCODE\n");
- TRACE_REGS();
- printk("%04x:%04x: %02X ILLEGAL EXTENDED X86 OPCODE!\n",
- M.x86.R_CS, M.x86.R_IP - 2, op2);
- HALT_SYS();
- END_OF_INSTR();
-}
-
-/****************************************************************************
-REMARKS:
-Handles opcode 0x0f,0x31
-****************************************************************************/
-void x86emuOp2_rdtsc(u8 op2)
-{
- static unsigned long eax = 0, edx = 0;
- char *name = 0;
-
- /* rdtsc */
- START_OF_INSTR();
- switch (op2) {
- case 0x31:
- name = "RDTSC\t";
- //rdtsc(eax, edx);
- eax++;
- if (eax == 0)
- edx++;
- M.x86.R_EAX = eax;
- M.x86.R_EDX = edx;
- break;
- default:
- DECODE_PRINTF("ILLEGAL EXTENDED X86 OPCODE(0f)\n");
- TRACE_REGS();
- printk("%04x:%04x: %02X ILLEGAL EXTENDED X86 OPCODE!\n",
- M.x86.R_CS, M.x86.R_IP - 2, op2);
- HALT_SYS();
- break;
- }
- DECODE_PRINTF(name);
- TRACE_AND_STEP();
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ START_OF_INSTR();
+ DECODE_PRINTF("ILLEGAL EXTENDED X86 OPCODE\n");
+ TRACE_REGS();
+ printk("%04x:%04x: %02X ILLEGAL EXTENDED X86 OPCODE!\n",
+ M.x86.R_CS, M.x86.R_IP-2,op2);
+ HALT_SYS();
+ END_OF_INSTR();
}
#define xorl(a,b) ((a) && !(b)) || (!(a) && (b))
@@ -103,89 +67,92 @@ void x86emuOp2_rdtsc(u8 op2)
REMARKS:
Handles opcode 0x0f,0x80-0x8F
****************************************************************************/
+int x86emu_check_jump_condition(u8 op)
+{
+ switch (op) {
+ case 0x0:
+ DECODE_PRINTF("JO\t");
+ return ACCESS_FLAG(F_OF);
+ case 0x1:
+ DECODE_PRINTF("JNO\t");
+ return !ACCESS_FLAG(F_OF);
+ break;
+ case 0x2:
+ DECODE_PRINTF("JB\t");
+ return ACCESS_FLAG(F_CF);
+ break;
+ case 0x3:
+ DECODE_PRINTF("JNB\t");
+ return !ACCESS_FLAG(F_CF);
+ break;
+ case 0x4:
+ DECODE_PRINTF("JZ\t");
+ return ACCESS_FLAG(F_ZF);
+ break;
+ case 0x5:
+ DECODE_PRINTF("JNZ\t");
+ return !ACCESS_FLAG(F_ZF);
+ break;
+ case 0x6:
+ DECODE_PRINTF("JBE\t");
+ return ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF);
+ break;
+ case 0x7:
+ DECODE_PRINTF("JNBE\t");
+ return !(ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF));
+ break;
+ case 0x8:
+ DECODE_PRINTF("JS\t");
+ return ACCESS_FLAG(F_SF);
+ break;
+ case 0x9:
+ DECODE_PRINTF("JNS\t");
+ return !ACCESS_FLAG(F_SF);
+ break;
+ case 0xa:
+ DECODE_PRINTF("JP\t");
+ return ACCESS_FLAG(F_PF);
+ break;
+ case 0xb:
+ DECODE_PRINTF("JNP\t");
+ return !ACCESS_FLAG(F_PF);
+ break;
+ case 0xc:
+ DECODE_PRINTF("JL\t");
+ return xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF));
+ break;
+ case 0xd:
+ DECODE_PRINTF("JNL\t");
+ return !xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF));
+ break;
+ case 0xe:
+ DECODE_PRINTF("JLE\t");
+ return (xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) ||
+ ACCESS_FLAG(F_ZF));
+ break;
+ default:
+ DECODE_PRINTF("JNLE\t");
+ return !(xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) ||
+ ACCESS_FLAG(F_ZF));
+ }
+}
+
void x86emuOp2_long_jump(u8 op2)
{
- s32 target;
- char *name = 0;
- int cond = 0;
-
- /* conditional jump to word offset. */
- START_OF_INSTR();
- switch (op2) {
- case 0x80:
- name = "JO\t";
- cond = ACCESS_FLAG(F_OF);
- break;
- case 0x81:
- name = "JNO\t";
- cond = !ACCESS_FLAG(F_OF);
- break;
- case 0x82:
- name = "JB\t";
- cond = ACCESS_FLAG(F_CF);
- break;
- case 0x83:
- name = "JNB\t";
- cond = !ACCESS_FLAG(F_CF);
- break;
- case 0x84:
- name = "JZ\t";
- cond = ACCESS_FLAG(F_ZF);
- break;
- case 0x85:
- name = "JNZ\t";
- cond = !ACCESS_FLAG(F_ZF);
- break;
- case 0x86:
- name = "JBE\t";
- cond = ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF);
- break;
- case 0x87:
- name = "JNBE\t";
- cond = !(ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF));
- break;
- case 0x88:
- name = "JS\t";
- cond = ACCESS_FLAG(F_SF);
- break;
- case 0x89:
- name = "JNS\t";
- cond = !ACCESS_FLAG(F_SF);
- break;
- case 0x8a:
- name = "JP\t";
- cond = ACCESS_FLAG(F_PF);
- break;
- case 0x8b:
- name = "JNP\t";
- cond = !ACCESS_FLAG(F_PF);
- break;
- case 0x8c:
- name = "JL\t";
- cond = xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF));
- break;
- case 0x8d:
- name = "JNL\t";
- cond = xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF));
- break;
- case 0x8e:
- name = "JLE\t";
- cond = (xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) || ACCESS_FLAG(F_ZF));
- break;
- case 0x8f:
- name = "JNLE\t";
- cond = !(xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) || ACCESS_FLAG(F_ZF));
- break;
- }
- DECODE_PRINTF(name);
- target = (s16) fetch_word_imm();
- target += (s16) M.x86.R_IP;
- DECODE_PRINTF2("%04x\n", target);
- TRACE_AND_STEP();
- if (cond)
- M.x86.R_IP = (u16) target;
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ s32 target;
+ int cond;
+
+ /* conditional jump to word offset. */
+ START_OF_INSTR();
+ cond = x86emu_check_jump_condition(op2 & 0xF);
+ target = (s16) fetch_word_imm();
+ target += (s16) M.x86.R_IP;
+ DECODE_PRINTF2("%04x\n", target);
+ TRACE_AND_STEP();
+ if (cond)
+ M.x86.R_IP = (u16)target;
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/****************************************************************************
@@ -194,105 +161,94 @@ Handles opcode 0x0f,0x90-0x9F
****************************************************************************/
void x86emuOp2_set_byte(u8 op2)
{
- int mod, rl, rh;
- uint destoffset;
- u8 *destreg;
- char *name = 0;
- int cond = 0;
-
- START_OF_INSTR();
- switch (op2) {
- case 0x90:
- name = "SETO\t";
- cond = ACCESS_FLAG(F_OF);
- break;
- case 0x91:
- name = "SETNO\t";
- cond = !ACCESS_FLAG(F_OF);
- break;
- case 0x92:
- name = "SETB\t";
- cond = ACCESS_FLAG(F_CF);
- break;
- case 0x93:
- name = "SETNB\t";
- cond = !ACCESS_FLAG(F_CF);
- break;
- case 0x94:
- name = "SETZ\t";
- cond = ACCESS_FLAG(F_ZF);
- break;
- case 0x95:
- name = "SETNZ\t";
- cond = !ACCESS_FLAG(F_ZF);
- break;
- case 0x96:
- name = "SETBE\t";
- cond = ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF);
- break;
- case 0x97:
- name = "SETNBE\t";
- cond = !(ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF));
- break;
- case 0x98:
- name = "SETS\t";
- cond = ACCESS_FLAG(F_SF);
- break;
- case 0x99:
- name = "SETNS\t";
- cond = !ACCESS_FLAG(F_SF);
- break;
- case 0x9a:
- name = "SETP\t";
- cond = ACCESS_FLAG(F_PF);
- break;
- case 0x9b:
- name = "SETNP\t";
- cond = !ACCESS_FLAG(F_PF);
- break;
- case 0x9c:
- name = "SETL\t";
- cond = xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF));
- break;
- case 0x9d:
- name = "SETNL\t";
- cond = xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF));
- break;
- case 0x9e:
- name = "SETLE\t";
- cond = (xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) || ACCESS_FLAG(F_ZF));
- break;
- case 0x9f:
- name = "SETNLE\t";
- cond = !(xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) || ACCESS_FLAG(F_ZF));
- break;
- }
- DECODE_PRINTF(name);
- FETCH_DECODE_MODRM(mod, rh, rl);
- switch (mod) {
- case 0:
- destoffset = decode_rm00_address(rl);
- TRACE_AND_STEP();
- store_data_byte(destoffset, cond ? 0x01 : 0x00);
- break;
- case 1:
- destoffset = decode_rm01_address(rl);
- TRACE_AND_STEP();
- store_data_byte(destoffset, cond ? 0x01 : 0x00);
- break;
- case 2:
- destoffset = decode_rm10_address(rl);
- TRACE_AND_STEP();
- store_data_byte(destoffset, cond ? 0x01 : 0x00);
- break;
- case 3: /* register to register */
- destreg = DECODE_RM_BYTE_REGISTER(rl);
- TRACE_AND_STEP();
- *destreg = cond ? 0x01 : 0x00;
- break;
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ int mod, rl, rh;
+ uint destoffset;
+ u8 *destreg;
+ char *name = 0;
+ int cond = 0;
+
+ START_OF_INSTR();
+ switch (op2) {
+ case 0x90:
+ name = "SETO\t";
+ cond = ACCESS_FLAG(F_OF);
+ break;
+ case 0x91:
+ name = "SETNO\t";
+ cond = !ACCESS_FLAG(F_OF);
+ break;
+ case 0x92:
+ name = "SETB\t";
+ cond = ACCESS_FLAG(F_CF);
+ break;
+ case 0x93:
+ name = "SETNB\t";
+ cond = !ACCESS_FLAG(F_CF);
+ break;
+ case 0x94:
+ name = "SETZ\t";
+ cond = ACCESS_FLAG(F_ZF);
+ break;
+ case 0x95:
+ name = "SETNZ\t";
+ cond = !ACCESS_FLAG(F_ZF);
+ break;
+ case 0x96:
+ name = "SETBE\t";
+ cond = ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF);
+ break;
+ case 0x97:
+ name = "SETNBE\t";
+ cond = !(ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF));
+ break;
+ case 0x98:
+ name = "SETS\t";
+ cond = ACCESS_FLAG(F_SF);
+ break;
+ case 0x99:
+ name = "SETNS\t";
+ cond = !ACCESS_FLAG(F_SF);
+ break;
+ case 0x9a:
+ name = "SETP\t";
+ cond = ACCESS_FLAG(F_PF);
+ break;
+ case 0x9b:
+ name = "SETNP\t";
+ cond = !ACCESS_FLAG(F_PF);
+ break;
+ case 0x9c:
+ name = "SETL\t";
+ cond = xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF));
+ break;
+ case 0x9d:
+ name = "SETNL\t";
+ cond = !xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF));
+ break;
+ case 0x9e:
+ name = "SETLE\t";
+ cond = (xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) ||
+ ACCESS_FLAG(F_ZF));
+ break;
+ case 0x9f:
+ name = "SETNLE\t";
+ cond = !(xorl(ACCESS_FLAG(F_SF), ACCESS_FLAG(F_OF)) ||
+ ACCESS_FLAG(F_ZF));
+ break;
+ }
+ DECODE_PRINTF(name);
+ FETCH_DECODE_MODRM(mod, rh, rl);
+ if (mod < 3) {
+ destoffset = decode_rmXX_address(mod, rl);
+ TRACE_AND_STEP();
+ store_data_byte(destoffset, cond ? 0x01 : 0x00);
+ } else { /* register to register */
+ destreg = DECODE_RM_BYTE_REGISTER(rl);
+ TRACE_AND_STEP();
+ *destreg = cond ? 0x01 : 0x00;
+ }
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/****************************************************************************
@@ -301,12 +257,12 @@ Handles opcode 0x0f,0xa0
****************************************************************************/
void x86emuOp2_push_FS(u8 X86EMU_UNUSED(op2))
{
- START_OF_INSTR();
- DECODE_PRINTF("PUSH\tFS\n");
- TRACE_AND_STEP();
- push_word(M.x86.R_FS);
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ START_OF_INSTR();
+ DECODE_PRINTF("PUSH\tFS\n");
+ TRACE_AND_STEP();
+ push_word(M.x86.R_FS);
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/****************************************************************************
@@ -315,12 +271,12 @@ Handles opcode 0x0f,0xa1
****************************************************************************/
void x86emuOp2_pop_FS(u8 X86EMU_UNUSED(op2))
{
- START_OF_INSTR();
- DECODE_PRINTF("POP\tFS\n");
- TRACE_AND_STEP();
- M.x86.R_FS = pop_word();
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ START_OF_INSTR();
+ DECODE_PRINTF("POP\tFS\n");
+ TRACE_AND_STEP();
+ M.x86.R_FS = pop_word();
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/****************************************************************************
@@ -329,119 +285,61 @@ Handles opcode 0x0f,0xa3
****************************************************************************/
void x86emuOp2_bt_R(u8 X86EMU_UNUSED(op2))
{
- int mod, rl, rh;
- uint srcoffset;
- int bit, disp;
-
- START_OF_INSTR();
- DECODE_PRINTF("BT\t");
- FETCH_DECODE_MODRM(mod, rh, rl);
- switch (mod) {
- case 0:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 srcval;
- u32 *shiftreg;
-
- srcoffset = decode_rm00_address(rl);
- DECODE_PRINTF(",");
- shiftreg = DECODE_RM_LONG_REGISTER(rh);
- TRACE_AND_STEP();
- bit = *shiftreg & 0x1F;
- disp = (s16) * shiftreg >> 5;
- srcval = fetch_data_long(srcoffset + disp);
- CONDITIONAL_SET_FLAG(srcval & (0x1 << bit), F_CF);
- } else {
- u16 srcval;
- u16 *shiftreg;
-
- srcoffset = decode_rm00_address(rl);
- DECODE_PRINTF(",");
- shiftreg = DECODE_RM_WORD_REGISTER(rh);
- TRACE_AND_STEP();
- bit = *shiftreg & 0xF;
- disp = (s16) * shiftreg >> 4;
- srcval = fetch_data_word(srcoffset + disp);
- CONDITIONAL_SET_FLAG(srcval & (0x1 << bit), F_CF);
- }
- break;
- case 1:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 srcval;
- u32 *shiftreg;
-
- srcoffset = decode_rm01_address(rl);
- DECODE_PRINTF(",");
- shiftreg = DECODE_RM_LONG_REGISTER(rh);
- TRACE_AND_STEP();
- bit = *shiftreg & 0x1F;
- disp = (s16) * shiftreg >> 5;
- srcval = fetch_data_long(srcoffset + disp);
- CONDITIONAL_SET_FLAG(srcval & (0x1 << bit), F_CF);
- } else {
- u16 srcval;
- u16 *shiftreg;
-
- srcoffset = decode_rm01_address(rl);
- DECODE_PRINTF(",");
- shiftreg = DECODE_RM_WORD_REGISTER(rh);
- TRACE_AND_STEP();
- bit = *shiftreg & 0xF;
- disp = (s16) * shiftreg >> 4;
- srcval = fetch_data_word(srcoffset + disp);
- CONDITIONAL_SET_FLAG(srcval & (0x1 << bit), F_CF);
- }
- break;
- case 2:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 srcval;
- u32 *shiftreg;
-
- srcoffset = decode_rm10_address(rl);
- DECODE_PRINTF(",");
- shiftreg = DECODE_RM_LONG_REGISTER(rh);
- TRACE_AND_STEP();
- bit = *shiftreg & 0x1F;
- disp = (s16) * shiftreg >> 5;
- srcval = fetch_data_long(srcoffset + disp);
- CONDITIONAL_SET_FLAG(srcval & (0x1 << bit), F_CF);
- } else {
- u16 srcval;
- u16 *shiftreg;
-
- srcoffset = decode_rm10_address(rl);
- DECODE_PRINTF(",");
- shiftreg = DECODE_RM_WORD_REGISTER(rh);
- TRACE_AND_STEP();
- bit = *shiftreg & 0xF;
- disp = (s16) * shiftreg >> 4;
- srcval = fetch_data_word(srcoffset + disp);
- CONDITIONAL_SET_FLAG(srcval & (0x1 << bit), F_CF);
- }
- break;
- case 3: /* register to register */
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 *srcreg, *shiftreg;
-
- srcreg = DECODE_RM_LONG_REGISTER(rl);
- DECODE_PRINTF(",");
- shiftreg = DECODE_RM_LONG_REGISTER(rh);
- TRACE_AND_STEP();
- bit = *shiftreg & 0x1F;
- CONDITIONAL_SET_FLAG(*srcreg & (0x1 << bit), F_CF);
- } else {
- u16 *srcreg, *shiftreg;
-
- srcreg = DECODE_RM_WORD_REGISTER(rl);
- DECODE_PRINTF(",");
- shiftreg = DECODE_RM_WORD_REGISTER(rh);
- TRACE_AND_STEP();
- bit = *shiftreg & 0xF;
- CONDITIONAL_SET_FLAG(*srcreg & (0x1 << bit), F_CF);
- }
- break;
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();
+ int mod, rl, rh;
+ uint srcoffset;
+ int bit,disp;
+
+ START_OF_INSTR();
+ DECODE_PRINTF("BT\t");
+ FETCH_DECODE_MODRM(mod, rh, rl);
+ if (mod < 3) {
+ srcoffset = decode_rmXX_address(mod, rl);
+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+ u32 srcval;
+ u32 *shiftreg;
+
+ DECODE_PRINTF(",");
+ shiftreg = DECODE_RM_LONG_REGISTER(rh);
+ TRACE_AND_STEP();
+ bit = *shiftreg & 0x1F;
+ disp = (s16)*shiftreg >> 5;
+ srcval = fetch_data_long(srcoffset+disp);
+ CONDITIONAL_SET_FLAG(srcval & (0x1 << bit),F_CF);
+ } else {
+ u16 srcval;
+ u16 *shiftreg;
+
+ DECODE_PRINTF(",");
+ shiftreg = DECODE_RM_WORD_REGISTER(rh);
+ TRACE_AND_STEP();
+ bit = *shiftreg & 0xF;
+ disp = (s16)*shiftreg >> 4;
+ srcval = fetch_data_word(srcoffset+disp);
+ CONDITIONAL_SET_FLAG(srcval & (0x1 << bit),F_CF);
+ }
+ } else { /* register to register */
+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
+ u32 *srcreg,*shiftreg;
+
+ srcreg = DECODE_RM_LONG_REGISTER(rl);
+ DECODE_PRINTF(",");
+ shiftreg = DECODE_RM_LONG_REGISTER(rh);
+ TRACE_AND_STEP();
+ bit = *shiftreg & 0x1F;
+ CONDITIONAL_SET_FLAG(*srcreg & (0x1 << bit),F_CF);
+ } else {
+ u16 *srcreg,*shiftreg;
+
+ srcreg = DECODE_RM_WORD_REGISTER(rl);
+ DECODE_PRINTF(",");
+ shiftreg = DECODE_RM_WORD_REGISTER(rh);
+ TRACE_AND_STEP();
+ bit = *shiftreg & 0xF;
+ CONDITIONAL_SET_FLAG(*srcreg & (0x1 << bit),F_CF);
+ }
+ }
+ DECODE_CLEAR_SEGOVR();
+ END_OF_INSTR();
}
/****************************************************************************
@@ -450,135 +348,69 @@ Handles opcode 0x0f,0xa4
****************************************************************************/
void x86emuOp2_shld_IMM(u8 X86EMU_UNUSED(op2))
{
- int mod, rl, rh;
- uint destoffset;
- u8 shift;
-
- START_OF_INSTR();
- DECODE_PRINTF("SHLD\t");
- FETCH_DECODE_MODRM(mod, rh, rl);
- switch (mod) {
- case 0:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 destval;
- u32 *shiftreg;
-
- destoffset = decode_rm00_address(rl);
- DECODE_PRINTF(",");
- shiftreg = DECODE_RM_LONG_REGISTER(rh);
- DECODE_PRINTF(",");
- shift = fetch_byte_imm();
- DECODE_PRINTF2("%d\n", shift);
- TRACE_AND_STEP();
- destval = fetch_data_long(destoffset);
- destval = shld_long(destval, *shiftreg, shift);
- store_data_long(destoffset, destval);
- } else {
- u16 destval;
- u16 *shiftreg;
-
- destoffset = decode_rm00_address(rl);
- DECODE_PRINTF(",");
- shiftreg = DECODE_RM_WORD_REGISTER(rh);
- DECODE_PRINTF(",");
- shift = fetch_byte_imm();
- DECODE_PRINTF2("%d\n", shift);
- TRACE_AND_STEP();
- destval = fetch_data_word(destoffset);
- destval = shld_word(destval, *shiftreg, shift);
- store_data_word(destoffset, destval);
- }
- break;
- case 1:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 destval;
- u32 *shiftreg;
-
- destoffset = decode_rm01_address(rl);
- DECODE_PRINTF(",");
- shiftreg = DECODE_RM_LONG_REGISTER(rh);
- DECODE_PRINTF(",");
- shift = fetch_byte_imm();
- DECODE_PRINTF2("%d\n", shift);
- TRACE_AND_STEP();
- destval = fetch_data_long(destoffset);
- destval = shld_long(destval, *shiftreg, shift);
- store_data_long(destoffset, destval);
- } else {
- u16 destval;
- u16 *shiftreg;
-
- destoffset = decode_rm01_address(rl);
- DECODE_PRINTF(",");
- shiftreg = DECODE_RM_WORD_REGISTER(rh);
- DECODE_PRINTF(",");
- shift = fetch_byte_imm();
- DECODE_PRINTF2("%d\n", shift);
- TRACE_AND_STEP();
- destval = fetch_data_word(destoffset);
- destval = shld_word(destval, *shiftreg, shift);
- store_data_word(destoffset, destval);
- }
- break;
- case 2:
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 destval;
- u32 *shiftreg;
-
- destoffset = decode_rm10_address(rl);
- DECODE_PRINTF(",");
- shiftreg = DECODE_RM_LONG_REGISTER(rh);
- DECODE_PRINTF(",");
- shift = fetch_byte_imm();
- DECODE_PRINTF2("%d\n", shift);
- TRACE_AND_STEP();
- destval = fetch_data_long(destoffset);
- destval = shld_long(destval, *shiftreg, shift);
- store_data_long(destoffset, destval);
- } else {
- u16 destval;
- u16 *shiftreg;
-
- destoffset = decode_rm10_address(rl);
- DECODE_PRINTF(",");
- shiftreg = DECODE_RM_WORD_REGISTER(rh);
- DECODE_PRINTF(",");
- shift = fetch_byte_imm();
- DECODE_PRINTF2("%d\n", shift);
- TRACE_AND_STEP();
- destval = fetch_data_word(destoffset);
- destval = shld_word(destval, *shiftreg, shift);
- store_data_word(destoffset, destval);
- }
- break;
- case 3: /* register to register */
- if (M.x86.mode & SYSMODE_PREFIX_DATA) {
- u32 *destreg, *shiftreg;
-
- destreg = DECODE_RM_LONG_REGISTER(rl);
- DECODE_PRINTF(",");
- shiftreg = DECODE_RM_LONG_REGISTER(rh);
- DECODE_PRINTF(",");
- shift = fetch_byte_imm();
- DECODE_PRINTF2("%d\n", shift);
- TRACE_AND_STEP();
- *destreg = shld_long(*destreg, *shiftreg, shift);
- } else {
- u16 *destreg, *shiftreg;
-
- destreg = DECODE_RM_WORD_REGISTER(rl);
- DECODE_PRINTF(",");
- shiftreg = DECODE_RM_WORD_REGISTER(rh);
- DECODE_PRINTF(",");
- shift = fetch_byte_imm();
- DECODE_PRINTF2("%d\n", shift);
- TRACE_AND_STEP();
- *destreg = shld_word(*destreg, *shiftreg, shift);
- }
- break;
- }
- DECODE_CLEAR_SEGOVR();
- END_OF_INSTR();