Android-x86
Fork
Donation

  • R/O
  • HTTP
  • SSH
  • HTTPS

external-v86d: Commit

external/v86d


Commit MetaInfo

Revisionf61fb756c45cc813876ac26cfa19dd883301a27e (tree)
Time2015-10-20 18:02:56
AuthorPaulo Sergio Travaglia <pstglia@gmai...>
CommiterChih-Wei Huang

Log Message

Add x86emu for 64-bit support

The x86emu is required for other architectures and x86_64.

Change Summary

Incremental Difference

--- a/Android.mk
+++ b/Android.mk
@@ -18,14 +18,27 @@ LOCAL_CFLAGS += \
1818 -include $(call use_uapi,video/uvesafb.h) \
1919 -include $(call use_uapi,linux/connector.h)
2020
21-LOCAL_SRC_FILES := \
22- v86.c \
23- v86_lrmi.c \
24- v86_common.c \
25- lrmi/lrmi.c \
21+LOCAL_SRC_FILES := \
22+ v86.c \
23+ v86_common.c
24+
25+LOCAL_SRC_FILES_x86 := \
26+ v86_lrmi.c \
27+ lrmi/lrmi.c \
2628 lrmi/x86-common.c
2729
28-LOCAL_C_INCLUDES += $(LOCAL_PATH)/lrmi
30+LOCAL_SRC_FILES_x86_64 := \
31+ v86_mem.c \
32+ v86_x86emu.c \
33+ x86emu/decode.c \
34+ x86emu/fpu.c \
35+ x86emu/ops.c \
36+ x86emu/ops2.c \
37+ x86emu/prim_ops.c \
38+ x86emu/sys.c
39+
40+LOCAL_C_INCLUDES_x86 := $(LOCAL_PATH)/lrmi
41+LOCAL_C_INCLUDES_x86_64 := $(LOCAL_PATH)/x86emu
2942
3043 LOCAL_MODULE := v86d
3144 LOCAL_MODULE_TAGS := optional
--- /dev/null
+++ b/v86_mem.c
@@ -0,0 +1,341 @@
1+#include <errno.h>
2+#include <fcntl.h>
3+#include <string.h>
4+#include <sys/mman.h>
5+#include <unistd.h>
6+#include "v86.h"
7+
8+#define REAL_MEM_BLOCKS 0x100
9+
10+u8 *mem_low; /* 0x000000 - 0x001000 */
11+u8 *mem_real; /* 0x010000 - 0x09ffff */
12+u8 *mem_vbios; /* 0x0c0000 - 0x0cxxxx */
13+u8 *mem_sbios; /* 0x0f0000 - 0x0fffff */
14+u8 *mem_vram; /* 0x0a0000 - 0xbfffff */
15+u8 *mem_ebda; /* usually: 0x9fc00 - 0x9ffff */
16+
17+static u32 ebda_start;
18+static u32 ebda_size;
19+static u32 ebda_diff;
20+static u32 vbios_size;
21+
22+struct mem_block {
23+ unsigned int size : 20;
24+ unsigned int free : 1;
25+};
26+
27+static struct {
28+ int ready;
29+ int count;
30+ struct mem_block blocks[REAL_MEM_BLOCKS];
31+} mem_info = { 0 };
32+
33+void *vptr(u32 addr) {
34+
35+ /* Order the if's in the expected probability of access to the
36+ * given region of memory. */
37+ if (addr >= REAL_MEM_BASE && addr < REAL_MEM_BASE + REAL_MEM_SIZE)
38+ return (mem_real + addr - REAL_MEM_BASE);
39+ else if (addr >= VBIOS_BASE && addr < VBIOS_BASE + vbios_size)
40+ return (mem_vbios + addr - VBIOS_BASE);
41+ else if (addr >= SBIOS_BASE && addr < SBIOS_BASE + SBIOS_SIZE)
42+ return (mem_sbios + addr - SBIOS_BASE);
43+ else if (addr >= VRAM_BASE && addr < VRAM_BASE + VRAM_SIZE)
44+ return (mem_vram + addr - VRAM_BASE);
45+ else if (addr < IVTBDA_SIZE)
46+ return (mem_low + addr);
47+ else if (mem_ebda && addr >= ebda_start && addr < ebda_start + ebda_size)
48+ return (mem_ebda + addr - ebda_start + ebda_diff);
49+ else {
50+ ulog(LOG_WARNING, "Trying to access an unsupported memory region at %x", addr);
51+ return NULL;
52+ }
53+}
54+
55+/* We don't care about memory accesses at boundaries of different memory
56+ * regions, since our v86 memory is non contiguous anyway. */
57+u8 v_rdb(u32 addr) {
58+ return *(u8*) vptr(addr);
59+}
60+
61+u16 v_rdw(u32 addr) {
62+ return *(u16*) vptr(addr);
63+}
64+
65+u32 v_rdl(u32 addr) {
66+ return *(u32*) vptr(addr);
67+}
68+
69+void v_wrb(u32 addr, u8 val) {
70+ u8 *t = vptr(addr);
71+ *t = val;
72+}
73+
74+void v_wrw(u32 addr, u16 val) {
75+ u16 *t = vptr(addr);
76+ *t = val;
77+}
78+
79+void v_wrl(u32 addr, u32 val) {
80+ u32 *t = vptr(addr);
81+ *t = val;
82+}
83+
84+static void *map_file(void *start, size_t length, int prot, int flags, char *name, long offset)
85+{
86+ void *m;
87+ int fd;
88+
89+ fd = open(name, (flags & MAP_SHARED) ? O_RDWR : O_RDONLY);
90+
91+ if (fd == -1) {
92+ ulog(LOG_ERR, "Open '%s' failed with: %s\n", name, strerror(errno));
93+ return NULL;
94+ }
95+
96+ m = mmap(start, length, prot, flags, fd, offset);
97+
98+ if (m == (void *)-1) {
99+ ulog(LOG_ERR, "mmap '%s' failed with: %s\n", name, strerror(errno));
100+ close(fd);
101+ return NULL;
102+ }
103+
104+ close(fd);
105+ return m;
106+}
107+
108+static int real_mem_init(void)
109+{
110+ if (mem_info.ready)
111+ return 0;
112+
113+ mem_real = map_file(NULL, REAL_MEM_SIZE, PROT_READ | PROT_WRITE,
114+ MAP_PRIVATE, "/dev/zero", 0);
115+ if (!mem_real)
116+ return 1;
117+
118+ mem_info.ready = 1;
119+ mem_info.count = 1;
120+ mem_info.blocks[0].size = REAL_MEM_SIZE;
121+ mem_info.blocks[0].free = 1;
122+
123+ return 0;
124+}
125+
126+static void real_mem_deinit(void)
127+{
128+ if (mem_info.ready) {
129+ munmap(mem_real, REAL_MEM_SIZE);
130+ mem_info.ready = 0;
131+ }
132+}
133+
134+static void insert_block(int i)
135+{
136+ memmove(mem_info.blocks + i + 1, mem_info.blocks + i,
137+ (mem_info.count - i) * sizeof(struct mem_block));
138+ mem_info.count++;
139+}
140+
141+static void delete_block(int i)
142+{
143+ mem_info.count--;
144+ memmove(mem_info.blocks + i, mem_info.blocks + i + 1,
145+ (mem_info.count - i) * sizeof(struct mem_block));
146+}
147+
148+u32 v86_mem_alloc(int size)
149+{
150+ int i;
151+ u32 r = REAL_MEM_BASE;
152+
153+ if (!mem_info.ready)
154+ return 0;
155+
156+ if (mem_info.count == REAL_MEM_BLOCKS)
157+ return 0;
158+
159+ size = (size + 15) & ~15;
160+
161+ for (i = 0; i < mem_info.count; i++) {
162+ if (mem_info.blocks[i].free && size < mem_info.blocks[i].size) {
163+ insert_block(i);
164+
165+ mem_info.blocks[i].size = size;
166+ mem_info.blocks[i].free = 0;
167+ mem_info.blocks[i + 1].size -= size;
168+
169+ return r;
170+ }
171+
172+ r += mem_info.blocks[i].size;
173+ }
174+
175+ return 0;
176+}
177+
178+void v86_mem_free(u32 m)
179+{
180+ int i;
181+ u32 r = REAL_MEM_BASE;
182+
183+ if (!mem_info.ready)
184+ return;
185+
186+ i = 0;
187+ while (m != r) {
188+ r += mem_info.blocks[i].size;
189+ i++;
190+ if (i == mem_info.count)
191+ return;
192+ }
193+
194+ mem_info.blocks[i].free = 1;
195+
196+ if (i + 1 < mem_info.count && mem_info.blocks[i + 1].free) {
197+ mem_info.blocks[i].size += mem_info.blocks[i + 1].size;
198+ delete_block(i + 1);
199+ }
200+
201+ if (i - 1 >= 0 && mem_info.blocks[i - 1].free) {
202+ mem_info.blocks[i - 1].size += mem_info.blocks[i].size;
203+ delete_block(i);
204+ }
205+}
206+
207+static int get_bytes_from_phys(u32 addr, int num_bytes, void *dest)
208+{
209+ u8 *mem_tmp;
210+ int size = num_bytes;
211+ u32 diff = 0;
212+ u32 t;
213+
214+ t = addr & -getpagesize();
215+ if (t) {
216+ diff = addr - t;
217+ addr = t;
218+ size += diff;
219+ }
220+
221+ mem_tmp = map_file(NULL, size, PROT_READ | PROT_WRITE,
222+ MAP_SHARED, "/dev/mem", addr);
223+ if (!mem_tmp)
224+ return -1;
225+
226+ memcpy(dest, mem_tmp + diff, num_bytes);
227+ munmap(mem_tmp, size);
228+ return 0;
229+}
230+
231+int v86_mem_init(void)
232+{
233+ u8 tmp[4];
234+
235+ if (real_mem_init())
236+ return 1;
237+
238+ /*
239+ * We have to map the IVTBDA as shared. Without it, setting video
240+ * modes will not work correctly on some cards (e.g. nVidia GeForce
241+ * 8600M, PCI ID 10de:0425).
242+ */
243+ mem_low = map_file(NULL, IVTBDA_SIZE, PROT_READ | PROT_WRITE,
244+ MAP_SHARED, "/dev/mem", IVTBDA_BASE);
245+ if (!mem_low) {
246+ real_mem_deinit();
247+ return 1;
248+ }
249+
250+ /* Try to find the start of the EBDA */
251+ ebda_start = (*(u16*)(mem_low + 0x40e)) << 4;
252+ if (!ebda_start || ebda_start > EBDA_BASE)
253+ ebda_start = EBDA_BASE;
254+
255+ if (get_bytes_from_phys(ebda_start, 1, tmp)) {
256+ ulog(LOG_WARNING, "Failed to read EBDA size from %x. Ignoring EBDA.", ebda_start);
257+ } else {
258+ /* The first byte in the EBDA is its size in kB */
259+ ebda_size = ((u32) tmp[0]) << 10;
260+ if (ebda_start + ebda_size > VRAM_BASE) {
261+ ulog(LOG_WARNING, "EBDA too big (%x), truncating.", ebda_size);
262+ ebda_size = VRAM_BASE - ebda_start;
263+ }
264+
265+ /* Map the EBDA */
266+ ulog(LOG_DEBUG, "EBDA at %5x-%5x\n", ebda_start, ebda_start + ebda_size - 1);
267+ u32 t = ebda_start & -getpagesize();
268+
269+ if (t) {
270+ ebda_diff = ebda_start - t;
271+ }
272+
273+ mem_ebda = map_file(NULL, ebda_size + ebda_diff, PROT_READ | PROT_WRITE, MAP_SHARED, "/dev/mem", ebda_start - ebda_diff);
274+ if (!mem_ebda) {
275+ ulog(LOG_WARNING, "Failed to mmap EBDA. Proceeding without it.");
276+ }
277+ }
278+
279+ /* Map the Video RAM */
280+ mem_vram = map_file(NULL, VRAM_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, "/dev/mem", VRAM_BASE);
281+ if (!mem_vram) {
282+ ulog(LOG_ERR, "Failed to mmap the Video RAM.");
283+ v86_mem_cleanup();
284+ return 1;
285+ }
286+
287+ /* Map the Video BIOS */
288+ get_bytes_from_phys(VBIOS_BASE, 4, tmp);
289+ if (tmp[0] != 0x55 || tmp[1] != 0xAA) {
290+ ulog(LOG_ERR, "Video BIOS not found at %x.", VBIOS_BASE);
291+ v86_mem_cleanup();
292+ return 1;
293+ }
294+ vbios_size = tmp[2] * 0x200;
295+ ulog(LOG_DEBUG, "VBIOS at %5x-%5x\n", VBIOS_BASE, VBIOS_BASE + vbios_size - 1);
296+
297+ /*
298+ * The Video BIOS and the System BIOS have to be mapped with PROT_WRITE.
299+ * There is at least one case where mapping them without this flag causes
300+ * a segfault during the emulation: https://bugs.gentoo.org/show_bug.cgi?id=245254
301+ */
302+ mem_vbios = map_file(NULL, vbios_size, PROT_READ | PROT_WRITE,
303+ MAP_SHARED, "/dev/mem", VBIOS_BASE);
304+
305+ if (!mem_vbios) {
306+ ulog(LOG_ERR, "Failed to mmap the Video BIOS.");
307+ v86_mem_cleanup();
308+ return 1;
309+ }
310+
311+ /* Map the system BIOS */
312+ mem_sbios = map_file(NULL, SBIOS_SIZE, PROT_READ | PROT_WRITE,
313+ MAP_SHARED, "/dev/mem", SBIOS_BASE);
314+ if (!mem_sbios) {
315+ ulog(LOG_ERR, "Failed to mmap the System BIOS as %5x.", SBIOS_BASE);
316+ v86_mem_cleanup();
317+ return 1;
318+ }
319+
320+ return 0;
321+}
322+
323+void v86_mem_cleanup(void)
324+{
325+ if (mem_low)
326+ munmap(mem_low, IVTBDA_SIZE);
327+
328+ if (mem_ebda)
329+ munmap(mem_ebda, ebda_size + ebda_diff);
330+
331+ if (mem_vram)
332+ munmap(mem_vram, VRAM_SIZE);
333+
334+ if (mem_vbios)
335+ munmap(mem_vbios, vbios_size);
336+
337+ if (mem_sbios)
338+ munmap(mem_sbios, SBIOS_SIZE);
339+
340+ real_mem_deinit();
341+}
--- /dev/null
+++ b/v86_x86emu.c
@@ -0,0 +1,192 @@
1+#include <stdarg.h>
2+#include <string.h>
3+#include <x86emu.h>
4+#include "v86.h"
5+#include "v86_x86emu.h"
6+
7+u32 stack;
8+u32 halt;
9+
10+__BUILDIO(b,b,u8);
11+__BUILDIO(w,w,u16);
12+__BUILDIO(l,,u32);
13+
14+void printk(const char *fmt, ...)
15+{
16+ va_list argptr;
17+ va_start(argptr, fmt);
18+ vsyslog(LOG_INFO, fmt, argptr);
19+ va_end(argptr);
20+}
21+
22+void pushw(u16 val)
23+{
24+ X86_ESP -= 2;
25+ v_wrw(((u32) X86_SS << 4) + X86_SP, val);
26+}
27+
28+static void x86emu_do_int(int num)
29+{
30+ u32 eflags;
31+
32+ eflags = X86_EFLAGS;
33+
34+ /* Return address and flags */
35+ pushw(eflags);
36+ pushw(X86_CS);
37+ pushw(X86_IP);
38+
39+ X86_EFLAGS = X86_EFLAGS & ~(X86_VIF_MASK | X86_TF_MASK);
40+ X86_CS = v_rdw((num << 2) + 2);
41+ X86_IP = v_rdw((num << 2));
42+}
43+
44+int v86_init()
45+{
46+ X86EMU_intrFuncs intFuncs[256];
47+ X86EMU_pioFuncs pioFuncs = {
48+ .inb = &x_inb,
49+ .inw = &x_inw,
50+ .inl = &x_inl,
51+ .outb = &x_outb,
52+ .outw = &x_outw,
53+ .outl = &x_outl,
54+ };
55+
56+ X86EMU_memFuncs memFuncs = {
57+ .rdb = &v_rdb,
58+ .rdw = &v_rdw,
59+ .rdl = &v_rdl,
60+ .wrb = &v_wrb,
61+ .wrw = &v_wrw,
62+ .wrl = &v_wrl,
63+ };
64+
65+ int i;
66+
67+ if (v86_mem_init()) {
68+ ulog(LOG_ERR, "v86 memory initialization failed.");
69+ return -1;
70+ }
71+
72+ stack = v86_mem_alloc(DEFAULT_STACK_SIZE);
73+ if (!stack) {
74+ ulog(LOG_ERR, "v86 memory allocation failed.");
75+ return -1;
76+ }
77+
78+ X86_SS = stack >> 4;
79+ X86_ESP = DEFAULT_STACK_SIZE;
80+
81+ halt = v86_mem_alloc(0x100);
82+ if (!halt) {
83+ ulog(LOG_ERR, "v86 memory alocation failed.");
84+ return -1;
85+ }
86+ v_wrb(halt, 0xF4);
87+
88+ X86EMU_setupPioFuncs(&pioFuncs);
89+ X86EMU_setupMemFuncs(&memFuncs);
90+
91+ /* Setup interrupt handlers */
92+ for (i = 0; i < 256; i++) {
93+ intFuncs[i] = x86emu_do_int;
94+ }
95+ X86EMU_setupIntrFuncs(intFuncs);
96+
97+ /* Set the default flags */
98+ X86_EFLAGS = X86_IF_MASK | X86_IOPL_MASK;
99+
100+ ioperm(0, 1024, 1);
101+ iopl(3);
102+
103+ return 0;
104+}
105+
106+void v86_cleanup()
107+{
108+ v86_mem_cleanup();
109+}
110+
111+void rconv_v86_to_x86emu(struct v86_regs *rs)
112+{
113+ X86_EAX = rs->eax;
114+ X86_EBX = rs->ebx;
115+ X86_ECX = rs->ecx;
116+ X86_EDX = rs->edx;
117+ X86_EDI = rs->edi;
118+ X86_ESI = rs->esi;
119+ X86_EBP = rs->ebp;
120+ X86_ESP = rs->esp;
121+ X86_EFLAGS = rs->eflags;
122+ X86_EIP = rs->eip;
123+ X86_CS = rs->cs;
124+ X86_DS = rs->ds;
125+ X86_ES = rs->es;
126+ X86_FS = rs->fs;
127+ X86_GS = rs->gs;
128+}
129+
130+void rconv_x86emu_to_v86(struct v86_regs *rd)
131+{
132+ rd->eax = X86_EAX;
133+ rd->ebx = X86_EBX;
134+ rd->ecx = X86_ECX;
135+ rd->edx = X86_EDX;
136+ rd->edi = X86_EDI;
137+ rd->esi = X86_ESI;
138+ rd->ebp = X86_EBP;
139+ rd->esp = X86_ESP;
140+ rd->eflags = X86_EFLAGS;
141+ rd->eip = X86_EIP;
142+ rd->cs = X86_CS;
143+ rd->ds = X86_DS;
144+ rd->es = X86_ES;
145+ rd->fs = X86_FS;
146+ rd->gs = X86_GS;
147+}
148+
149+/*
150+ * Perform a simulated interrupt call.
151+ */
152+int v86_int(int num, struct v86_regs *regs)
153+{
154+ rconv_v86_to_x86emu(regs);
155+
156+ X86_GS = 0;
157+ X86_FS = 0;
158+ X86_DS = 0x0040;
159+ X86_CS = v_rdw((num << 2) + 2);
160+ X86_EIP = v_rdw((num << 2));
161+ X86_SS = stack >> 4;
162+ X86_ESP = DEFAULT_STACK_SIZE;
163+ X86_EFLAGS = X86_IF_MASK | X86_IOPL_MASK;
164+
165+ pushw(X86_EFLAGS);
166+ pushw((halt >> 4));
167+ pushw(0x0);
168+
169+ X86EMU_exec();
170+
171+ rconv_x86emu_to_v86(regs);
172+ return 0;
173+}
174+
175+void v86_dump_regs()
176+{
177+ ulog(LOG_DEBUG,
178+ "EAX=0x%8.8lx, EBX=0x%8.8lx, ECX=0x%8.8lx, EDX=0x%8.8lx\n",
179+ (unsigned long)X86_EAX, (unsigned long)X86_EBX,
180+ (unsigned long)X86_ECX, (unsigned long)X86_EDX);
181+ ulog(LOG_DEBUG,
182+ "ESP=0x%8.8lx, EBP=0x%8.8lx, ESI=0x%8.8lx, EDI=0x%8.8lx\n",
183+ (unsigned long)X86_ESP, (unsigned long)X86_EBP,
184+ (unsigned long)X86_ESI, (unsigned long)X86_EDI);
185+ ulog(LOG_DEBUG,
186+ "CS=0x%4.4x, SS=0x%4.4x,"
187+ " DS=0x%4.4x, ES=0x%4.4x, FS=0x%4.4x, GS=0x%4.4x\n",
188+ X86_CS, X86_SS, X86_DS, X86_ES, X86_FS, X86_GS);
189+ ulog(LOG_DEBUG,
190+ "EIP=0x%8.8lx, EFLAGS=0x%8.8lx\n",
191+ (unsigned long)X86_EIP, (unsigned long)X86_EFLAGS);
192+}
--- /dev/null
+++ b/v86_x86emu.h
@@ -0,0 +1,69 @@
1+#ifndef __H_V86_X86EMU
2+#define __H_V86_X86EMU
3+
4+#define X86_EAX M.x86.R_EAX
5+#define X86_EBX M.x86.R_EBX
6+#define X86_ECX M.x86.R_ECX
7+#define X86_EDX M.x86.R_EDX
8+#define X86_ESI M.x86.R_ESI
9+#define X86_EDI M.x86.R_EDI
10+#define X86_EBP M.x86.R_EBP
11+#define X86_EIP M.x86.R_EIP
12+#define X86_ESP M.x86.R_ESP
13+#define X86_EFLAGS M.x86.R_EFLG
14+
15+#define X86_FLAGS M.x86.R_FLG
16+#define X86_AX M.x86.R_AX
17+#define X86_BX M.x86.R_BX
18+#define X86_CX M.x86.R_CX
19+#define X86_DX M.x86.R_DX
20+#define X86_SI M.x86.R_SI
21+#define X86_DI M.x86.R_DI
22+#define X86_BP M.x86.R_BP
23+#define X86_IP M.x86.R_IP
24+#define X86_SP M.x86.R_SP
25+#define X86_CS M.x86.R_CS
26+#define X86_DS M.x86.R_DS
27+#define X86_ES M.x86.R_ES
28+#define X86_SS M.x86.R_SS
29+#define X86_FS M.x86.R_FS
30+#define X86_GS M.x86.R_GS
31+
32+#define X86_AL M.x86.R_AL
33+#define X86_BL M.x86.R_BL
34+#define X86_CL M.x86.R_CL
35+#define X86_DL M.x86.R_DL
36+
37+#define X86_AH M.x86.R_AH
38+#define X86_BH M.x86.R_BH
39+#define X86_CH M.x86.R_CH
40+#define X86_DH M.x86.R_DH
41+
42+#define X86_TF_MASK 0x00000100
43+#define X86_IF_MASK 0x00000200
44+#define X86_IOPL_MASK 0x00003000
45+#define X86_NT_MASK 0x00004000
46+#define X86_VM_MASK 0x00020000
47+#define X86_AC_MASK 0x00040000
48+#define X86_VIF_MASK 0x00080000 /* virtual interrupt flag */
49+#define X86_VIP_MASK 0x00100000 /* virtual interrupt pending */
50+#define X86_ID_MASK 0x00200000
51+
52+#define DEFAULT_V86_FLAGS (X86_IF_MASK | X86_IOPL_MASK)
53+
54+#define __BUILDIO(bwl,bw,type) \
55+static void x_out ## bwl (u16 port, type value) { \
56+ /*printf("out" #bwl " %x, %x\n", port, value);*/ \
57+ __asm__ __volatile__("out" #bwl " %" #bw "0, %w1" \
58+ : : "a"(value), "Nd"(port)); \
59+} \
60+ \
61+static type x_in ## bwl (u16 port) { \
62+ type value; \
63+ __asm__ __volatile__("in" #bwl " %w1, %" #bw "0" \
64+ : "=a"(value) \
65+ : "Nd"(port)); \
66+ /*printf("in" #bwl " %x = %x\n", port, value);*/ \
67+ return value; \
68+}
69+#endif /* __H_V86_X86EMU */
--- /dev/null
+++ b/x86emu/decode.c
@@ -0,0 +1,1092 @@
1+/****************************************************************************
2+*
3+* Realmode X86 Emulator Library
4+*
5+* Copyright (C) 1996-1999 SciTech Software, Inc.
6+* Copyright (C) David Mosberger-Tang
7+* Copyright (C) 1999 Egbert Eich
8+*
9+* ========================================================================
10+*
11+* Permission to use, copy, modify, distribute, and sell this software and
12+* its documentation for any purpose is hereby granted without fee,
13+* provided that the above copyright notice appear in all copies and that
14+* both that copyright notice and this permission notice appear in
15+* supporting documentation, and that the name of the authors not be used
16+* in advertising or publicity pertaining to distribution of the software
17+* without specific, written prior permission. The authors makes no
18+* representations about the suitability of this software for any purpose.
19+* It is provided "as is" without express or implied warranty.
20+*
21+* THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
22+* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
23+* EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
24+* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
25+* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
26+* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
27+* PERFORMANCE OF THIS SOFTWARE.
28+*
29+* ========================================================================
30+*
31+* Language: ANSI C
32+* Environment: Any
33+* Developer: Kendall Bennett
34+*
35+* Description: This file includes subroutines which are related to
36+* instruction decoding and accessess of immediate data via IP. etc.
37+*
38+****************************************************************************/
39+
40+#include <stdlib.h>
41+#include "x86emu/x86emui.h"
42+
43+/*----------------------------- Implementation ----------------------------*/
44+
45+/****************************************************************************
46+REMARKS:
47+Handles any pending asychronous interrupts.
48+****************************************************************************/
49+static void
50+x86emu_intr_handle(void)
51+{
52+ u8 intno;
53+
54+ if (M.x86.intr & INTR_SYNCH) {
55+ intno = M.x86.intno;
56+ if (_X86EMU_intrTab[intno]) {
57+ (*_X86EMU_intrTab[intno]) (intno);
58+ }
59+ else {
60+ push_word((u16) M.x86.R_FLG);
61+ CLEAR_FLAG(F_IF);
62+ CLEAR_FLAG(F_TF);
63+ push_word(M.x86.R_CS);
64+ M.x86.R_CS = mem_access_word(intno * 4 + 2);
65+ push_word(M.x86.R_IP);
66+ M.x86.R_IP = mem_access_word(intno * 4);
67+ M.x86.intr = 0;
68+ }
69+ }
70+}
71+
72+/****************************************************************************
73+PARAMETERS:
74+intrnum - Interrupt number to raise
75+
76+REMARKS:
77+Raise the specified interrupt to be handled before the execution of the
78+next instruction.
79+****************************************************************************/
80+void
81+x86emu_intr_raise(u8 intrnum)
82+{
83+ M.x86.intno = intrnum;
84+ M.x86.intr |= INTR_SYNCH;
85+}
86+
87+/****************************************************************************
88+REMARKS:
89+Main execution loop for the emulator. We return from here when the system
90+halts, which is normally caused by a stack fault when we return from the
91+original real mode call.
92+****************************************************************************/
93+void
94+X86EMU_exec(void)
95+{
96+ u8 op1;
97+
98+ M.x86.intr = 0;
99+ DB(x86emu_end_instr();
100+ )
101+
102+ for (;;) {
103+ DB(if (CHECK_IP_FETCH())
104+ x86emu_check_ip_access();)
105+ /* If debugging, save the IP and CS values. */
106+ SAVE_IP_CS(M.x86.R_CS, M.x86.R_IP);
107+ INC_DECODED_INST_LEN(1);
108+ if (M.x86.intr) {
109+ if (M.x86.intr & INTR_HALTED) {
110+ DB(if (M.x86.R_SP != 0) {
111+ printk("halted\n"); X86EMU_trace_regs();}
112+ else {
113+ if (M.x86.debug)
114+ printk("Service completed successfully\n");}
115+ )
116+ return;
117+ }
118+ if (((M.x86.intr & INTR_SYNCH) &&
119+ (M.x86.intno == 0 || M.x86.intno == 2)) ||
120+ !ACCESS_FLAG(F_IF)) {
121+ x86emu_intr_handle();
122+ }
123+ }
124+ op1 = (*sys_rdb) (((u32) M.x86.R_CS << 4) + (M.x86.R_IP++));
125+ (*x86emu_optab[op1]) (op1);
126+ if (M.x86.debug & DEBUG_EXIT) {
127+ M.x86.debug &= ~DEBUG_EXIT;
128+ return;
129+ }
130+ }
131+}
132+
133+/****************************************************************************
134+REMARKS:
135+Halts the system by setting the halted system flag.
136+****************************************************************************/
137+void
138+X86EMU_halt_sys(void)
139+{
140+ M.x86.intr |= INTR_HALTED;
141+}
142+
143+/****************************************************************************
144+PARAMETERS:
145+mod - Mod value from decoded byte
146+regh - Reg h value from decoded byte
147+regl - Reg l value from decoded byte
148+
149+REMARKS:
150+Raise the specified interrupt to be handled before the execution of the
151+next instruction.
152+
153+NOTE: Do not inline this function, as (*sys_rdb) is already inline!
154+****************************************************************************/
155+void
156+fetch_decode_modrm(int *mod, int *regh, int *regl)
157+{
158+ int fetched;
159+
160+ DB(if (CHECK_IP_FETCH())
161+ x86emu_check_ip_access();)
162+ fetched = (*sys_rdb) (((u32) M.x86.R_CS << 4) + (M.x86.R_IP++));
163+ INC_DECODED_INST_LEN(1);
164+ *mod = (fetched >> 6) & 0x03;
165+ *regh = (fetched >> 3) & 0x07;
166+ *regl = (fetched >> 0) & 0x07;
167+}
168+
169+/****************************************************************************
170+RETURNS:
171+Immediate byte value read from instruction queue
172+
173+REMARKS:
174+This function returns the immediate byte from the instruction queue, and
175+moves the instruction pointer to the next value.
176+
177+NOTE: Do not inline this function, as (*sys_rdb) is already inline!
178+****************************************************************************/
179+u8
180+fetch_byte_imm(void)
181+{
182+ u8 fetched;
183+
184+ DB(if (CHECK_IP_FETCH())
185+ x86emu_check_ip_access();)
186+ fetched = (*sys_rdb) (((u32) M.x86.R_CS << 4) + (M.x86.R_IP++));
187+ INC_DECODED_INST_LEN(1);
188+ return fetched;
189+}
190+
191+/****************************************************************************
192+RETURNS:
193+Immediate word value read from instruction queue
194+
195+REMARKS:
196+This function returns the immediate byte from the instruction queue, and
197+moves the instruction pointer to the next value.
198+
199+NOTE: Do not inline this function, as (*sys_rdw) is already inline!
200+****************************************************************************/
201+u16
202+fetch_word_imm(void)
203+{
204+ u16 fetched;
205+
206+ DB(if (CHECK_IP_FETCH())
207+ x86emu_check_ip_access();)
208+ fetched = (*sys_rdw) (((u32) M.x86.R_CS << 4) + (M.x86.R_IP));
209+ M.x86.R_IP += 2;
210+ INC_DECODED_INST_LEN(2);
211+ return fetched;
212+}
213+
214+/****************************************************************************
215+RETURNS:
216+Immediate lone value read from instruction queue
217+
218+REMARKS:
219+This function returns the immediate byte from the instruction queue, and
220+moves the instruction pointer to the next value.
221+
222+NOTE: Do not inline this function, as (*sys_rdw) is already inline!
223+****************************************************************************/
224+u32
225+fetch_long_imm(void)
226+{
227+ u32 fetched;
228+
229+ DB(if (CHECK_IP_FETCH())
230+ x86emu_check_ip_access();)
231+ fetched = (*sys_rdl) (((u32) M.x86.R_CS << 4) + (M.x86.R_IP));
232+ M.x86.R_IP += 4;
233+ INC_DECODED_INST_LEN(4);
234+ return fetched;
235+}
236+
237+/****************************************************************************
238+RETURNS:
239+Value of the default data segment
240+
241+REMARKS:
242+Inline function that returns the default data segment for the current
243+instruction.
244+
245+On the x86 processor, the default segment is not always DS if there is
246+no segment override. Address modes such as -3[BP] or 10[BP+SI] all refer to
247+addresses relative to SS (ie: on the stack). So, at the minimum, all
248+decodings of addressing modes would have to set/clear a bit describing
249+whether the access is relative to DS or SS. That is the function of the
250+cpu-state-varible M.x86.mode. There are several potential states:
251+
252+ repe prefix seen (handled elsewhere)
253+ repne prefix seen (ditto)
254+
255+ cs segment override
256+ ds segment override
257+ es segment override
258+ fs segment override
259+ gs segment override
260+ ss segment override
261+
262+ ds/ss select (in absense of override)
263+
264+Each of the above 7 items are handled with a bit in the mode field.
265+****************************************************************************/
266+_INLINE u32
267+get_data_segment(void)
268+{
269+#define GET_SEGMENT(segment)
270+ switch (M.x86.mode & SYSMODE_SEGMASK) {
271+ case 0: /* default case: use ds register */
272+ case SYSMODE_SEGOVR_DS:
273+ case SYSMODE_SEGOVR_DS | SYSMODE_SEG_DS_SS:
274+ return M.x86.R_DS;
275+ case SYSMODE_SEG_DS_SS: /* non-overridden, use ss register */
276+ return M.x86.R_SS;
277+ case SYSMODE_SEGOVR_CS:
278+ case SYSMODE_SEGOVR_CS | SYSMODE_SEG_DS_SS:
279+ return M.x86.R_CS;
280+ case SYSMODE_SEGOVR_ES:
281+ case SYSMODE_SEGOVR_ES | SYSMODE_SEG_DS_SS:
282+ return M.x86.R_ES;
283+ case SYSMODE_SEGOVR_FS:
284+ case SYSMODE_SEGOVR_FS | SYSMODE_SEG_DS_SS:
285+ return M.x86.R_FS;
286+ case SYSMODE_SEGOVR_GS:
287+ case SYSMODE_SEGOVR_GS | SYSMODE_SEG_DS_SS:
288+ return M.x86.R_GS;
289+ case SYSMODE_SEGOVR_SS:
290+ case SYSMODE_SEGOVR_SS | SYSMODE_SEG_DS_SS:
291+ return M.x86.R_SS;
292+ default:
293+#ifdef DEBUG
294+ printk("error: should not happen: multiple overrides.\n");
295+#endif
296+ HALT_SYS();
297+ return 0;
298+ }
299+}
300+
301+/****************************************************************************
302+PARAMETERS:
303+offset - Offset to load data from
304+
305+RETURNS:
306+Byte value read from the absolute memory location.
307+
308+NOTE: Do not inline this function as (*sys_rdX) is already inline!
309+****************************************************************************/
310+u8
311+fetch_data_byte(uint offset)
312+{
313+#ifdef DEBUG
314+ if (CHECK_DATA_ACCESS())
315+ x86emu_check_data_access((u16) get_data_segment(), offset);
316+#endif
317+ return (*sys_rdb) ((get_data_segment() << 4) + offset);
318+}
319+
320+/****************************************************************************
321+PARAMETERS:
322+offset - Offset to load data from
323+
324+RETURNS:
325+Word value read from the absolute memory location.
326+
327+NOTE: Do not inline this function as (*sys_rdX) is already inline!
328+****************************************************************************/
329+u16
330+fetch_data_word(uint offset)
331+{
332+#ifdef DEBUG
333+ if (CHECK_DATA_ACCESS())
334+ x86emu_check_data_access((u16) get_data_segment(), offset);
335+#endif
336+ return (*sys_rdw) ((get_data_segment() << 4) + offset);
337+}
338+
339+/****************************************************************************
340+PARAMETERS:
341+offset - Offset to load data from
342+
343+RETURNS:
344+Long value read from the absolute memory location.
345+
346+NOTE: Do not inline this function as (*sys_rdX) is already inline!
347+****************************************************************************/
348+u32
349+fetch_data_long(uint offset)
350+{
351+#ifdef DEBUG
352+ if (CHECK_DATA_ACCESS())
353+ x86emu_check_data_access((u16) get_data_segment(), offset);
354+#endif
355+ return (*sys_rdl) ((get_data_segment() << 4) + offset);
356+}
357+
358+/****************************************************************************
359+PARAMETERS:
360+segment - Segment to load data from
361+offset - Offset to load data from
362+
363+RETURNS:
364+Byte value read from the absolute memory location.
365+
366+NOTE: Do not inline this function as (*sys_rdX) is already inline!
367+****************************************************************************/
368+u8
369+fetch_data_byte_abs(uint segment, uint offset)
370+{
371+#ifdef DEBUG
372+ if (CHECK_DATA_ACCESS())
373+ x86emu_check_data_access(segment, offset);
374+#endif
375+ return (*sys_rdb) (((u32) segment << 4) + offset);
376+}
377+
378+/****************************************************************************
379+PARAMETERS:
380+segment - Segment to load data from
381+offset - Offset to load data from
382+
383+RETURNS:
384+Word value read from the absolute memory location.
385+
386+NOTE: Do not inline this function as (*sys_rdX) is already inline!
387+****************************************************************************/
388+u16
389+fetch_data_word_abs(uint segment, uint offset)
390+{
391+#ifdef DEBUG
392+ if (CHECK_DATA_ACCESS())
393+ x86emu_check_data_access(segment, offset);
394+#endif
395+ return (*sys_rdw) (((u32) segment << 4) + offset);
396+}
397+
398+/****************************************************************************
399+PARAMETERS:
400+segment - Segment to load data from
401+offset - Offset to load data from
402+
403+RETURNS:
404+Long value read from the absolute memory location.
405+
406+NOTE: Do not inline this function as (*sys_rdX) is already inline!
407+****************************************************************************/
408+u32
409+fetch_data_long_abs(uint segment, uint offset)
410+{
411+#ifdef DEBUG
412+ if (CHECK_DATA_ACCESS())
413+ x86emu_check_data_access(segment, offset);
414+#endif
415+ return (*sys_rdl) (((u32) segment << 4) + offset);
416+}
417+
418+/****************************************************************************
419+PARAMETERS:
420+offset - Offset to store data at
421+val - Value to store
422+
423+REMARKS:
424+Writes a word value to an segmented memory location. The segment used is
425+the current 'default' segment, which may have been overridden.
426+
427+NOTE: Do not inline this function as (*sys_wrX) is already inline!
428+****************************************************************************/
429+void
430+store_data_byte(uint offset, u8 val)
431+{
432+#ifdef DEBUG
433+ if (CHECK_DATA_ACCESS())
434+ x86emu_check_data_access((u16) get_data_segment(), offset);
435+#endif
436+ (*sys_wrb) ((get_data_segment() << 4) + offset, val);
437+}
438+
439+/****************************************************************************
440+PARAMETERS:
441+offset - Offset to store data at
442+val - Value to store
443+
444+REMARKS:
445+Writes a word value to an segmented memory location. The segment used is
446+the current 'default' segment, which may have been overridden.
447+
448+NOTE: Do not inline this function as (*sys_wrX) is already inline!
449+****************************************************************************/
450+void
451+store_data_word(uint offset, u16 val)
452+{
453+#ifdef DEBUG
454+ if (CHECK_DATA_ACCESS())
455+ x86emu_check_data_access((u16) get_data_segment(), offset);
456+#endif
457+ (*sys_wrw) ((get_data_segment() << 4) + offset, val);
458+}
459+
460+/****************************************************************************
461+PARAMETERS:
462+offset - Offset to store data at
463+val - Value to store
464+
465+REMARKS:
466+Writes a long value to an segmented memory location. The segment used is
467+the current 'default' segment, which may have been overridden.
468+
469+NOTE: Do not inline this function as (*sys_wrX) is already inline!
470+****************************************************************************/
471+void
472+store_data_long(uint offset, u32 val)
473+{
474+#ifdef DEBUG
475+ if (CHECK_DATA_ACCESS())
476+ x86emu_check_data_access((u16) get_data_segment(), offset);
477+#endif
478+ (*sys_wrl) ((get_data_segment() << 4) + offset, val);
479+}
480+
481+/****************************************************************************
482+PARAMETERS:
483+segment - Segment to store data at
484+offset - Offset to store data at
485+val - Value to store
486+
487+REMARKS:
488+Writes a byte value to an absolute memory location.
489+
490+NOTE: Do not inline this function as (*sys_wrX) is already inline!
491+****************************************************************************/
492+void
493+store_data_byte_abs(uint segment, uint offset, u8 val)
494+{
495+#ifdef DEBUG
496+ if (CHECK_DATA_ACCESS())
497+ x86emu_check_data_access(segment, offset);
498+#endif
499+ (*sys_wrb) (((u32) segment << 4) + offset, val);
500+}
501+
502+/****************************************************************************
503+PARAMETERS:
504+segment - Segment to store data at
505+offset - Offset to store data at
506+val - Value to store
507+
508+REMARKS:
509+Writes a word value to an absolute memory location.
510+
511+NOTE: Do not inline this function as (*sys_wrX) is already inline!
512+****************************************************************************/
513+void
514+store_data_word_abs(uint segment, uint offset, u16 val)
515+{
516+#ifdef DEBUG
517+ if (CHECK_DATA_ACCESS())
518+ x86emu_check_data_access(segment, offset);
519+#endif
520+ (*sys_wrw) (((u32) segment << 4) + offset, val);
521+}
522+
523+/****************************************************************************
524+PARAMETERS:
525+segment - Segment to store data at
526+offset - Offset to store data at
527+val - Value to store
528+
529+REMARKS:
530+Writes a long value to an absolute memory location.
531+
532+NOTE: Do not inline this function as (*sys_wrX) is already inline!
533+****************************************************************************/
534+void
535+store_data_long_abs(uint segment, uint offset, u32 val)
536+{
537+#ifdef DEBUG
538+ if (CHECK_DATA_ACCESS())
539+ x86emu_check_data_access(segment, offset);
540+#endif
541+ (*sys_wrl) (((u32) segment << 4) + offset, val);
542+}
543+
544+/****************************************************************************
545+PARAMETERS:
546+reg - Register to decode
547+
548+RETURNS:
549+Pointer to the appropriate register
550+
551+REMARKS:
552+Return a pointer to the register given by the R/RM field of the
553+modrm byte, for byte operands. Also enables the decoding of instructions.
554+****************************************************************************/
555+u8 *
556+decode_rm_byte_register(int reg)
557+{
558+ switch (reg) {
559+ case 0:
560+ DECODE_PRINTF("AL");
561+ return &M.x86.R_AL;
562+ case 1:
563+ DECODE_PRINTF("CL");
564+ return &M.x86.R_CL;
565+ case 2:
566+ DECODE_PRINTF("DL");
567+ return &M.x86.R_DL;
568+ case 3:
569+ DECODE_PRINTF("BL");
570+ return &M.x86.R_BL;
571+ case 4:
572+ DECODE_PRINTF("AH");
573+ return &M.x86.R_AH;
574+ case 5:
575+ DECODE_PRINTF("CH");
576+ return &M.x86.R_CH;
577+ case 6:
578+ DECODE_PRINTF("DH");
579+ return &M.x86.R_DH;
580+ case 7:
581+ DECODE_PRINTF("BH");
582+ return &M.x86.R_BH;
583+ }
584+ HALT_SYS();
585+ return NULL; /* NOT REACHED OR REACHED ON ERROR */
586+}
587+
588+/****************************************************************************
589+PARAMETERS:
590+reg - Register to decode
591+
592+RETURNS:
593+Pointer to the appropriate register
594+
595+REMARKS:
596+Return a pointer to the register given by the R/RM field of the
597+modrm byte, for word operands. Also enables the decoding of instructions.
598+****************************************************************************/
599+u16 *
600+decode_rm_word_register(int reg)
601+{
602+ switch (reg) {
603+ case 0:
604+ DECODE_PRINTF("AX");
605+ return &M.x86.R_AX;
606+ case 1:
607+ DECODE_PRINTF("CX");
608+ return &M.x86.R_CX;
609+ case 2:
610+ DECODE_PRINTF("DX");
611+ return &M.x86.R_DX;
612+ case 3:
613+ DECODE_PRINTF("BX");
614+ return &M.x86.R_BX;
615+ case 4:
616+ DECODE_PRINTF("SP");
617+ return &M.x86.R_SP;
618+ case 5:
619+ DECODE_PRINTF("BP");
620+ return &M.x86.R_BP;
621+ case 6:
622+ DECODE_PRINTF("SI");
623+ return &M.x86.R_SI;
624+ case 7:
625+ DECODE_PRINTF("DI");
626+ return &M.x86.R_DI;
627+ }
628+ HALT_SYS();
629+ return NULL; /* NOTREACHED OR REACHED ON ERROR */
630+}
631+
632+/****************************************************************************
633+PARAMETERS:
634+reg - Register to decode
635+
636+RETURNS:
637+Pointer to the appropriate register
638+
639+REMARKS:
640+Return a pointer to the register given by the R/RM field of the
641+modrm byte, for dword operands. Also enables the decoding of instructions.
642+****************************************************************************/
643+u32 *
644+decode_rm_long_register(int reg)
645+{
646+ switch (reg) {
647+ case 0:
648+ DECODE_PRINTF("EAX");
649+ return &M.x86.R_EAX;
650+ case 1:
651+ DECODE_PRINTF("ECX");
652+ return &M.x86.R_ECX;
653+ case 2:
654+ DECODE_PRINTF("EDX");
655+ return &M.x86.R_EDX;
656+ case 3:
657+ DECODE_PRINTF("EBX");
658+ return &M.x86.R_EBX;
659+ case 4:
660+ DECODE_PRINTF("ESP");
661+ return &M.x86.R_ESP;
662+ case 5:
663+ DECODE_PRINTF("EBP");
664+ return &M.x86.R_EBP;
665+ case 6:
666+ DECODE_PRINTF("ESI");
667+ return &M.x86.R_ESI;
668+ case 7:
669+ DECODE_PRINTF("EDI");
670+ return &M.x86.R_EDI;
671+ }
672+ HALT_SYS();
673+ return NULL; /* NOTREACHED OR REACHED ON ERROR */
674+}
675+
676+/****************************************************************************
677+PARAMETERS:
678+reg - Register to decode
679+
680+RETURNS:
681+Pointer to the appropriate register
682+
683+REMARKS:
684+Return a pointer to the register given by the R/RM field of the
685+modrm byte, for word operands, modified from above for the weirdo
686+special case of segreg operands. Also enables the decoding of instructions.
687+****************************************************************************/
688+u16 *
689+decode_rm_seg_register(int reg)
690+{
691+ switch (reg) {
692+ case 0:
693+ DECODE_PRINTF("ES");
694+ return &M.x86.R_ES;
695+ case 1:
696+ DECODE_PRINTF("CS");
697+ return &M.x86.R_CS;
698+ case 2:
699+ DECODE_PRINTF("SS");
700+ return &M.x86.R_SS;
701+ case 3:
702+ DECODE_PRINTF("DS");
703+ return &M.x86.R_DS;
704+ case 4:
705+ DECODE_PRINTF("FS");
706+ return &M.x86.R_FS;
707+ case 5:
708+ DECODE_PRINTF("GS");
709+ return &M.x86.R_GS;
710+ case 6:
711+ case 7:
712+ DECODE_PRINTF("ILLEGAL SEGREG");
713+ break;
714+ }
715+ HALT_SYS();
716+ return NULL; /* NOT REACHED OR REACHED ON ERROR */
717+}
718+
719+/*
720+ *
721+ * return offset from the SIB Byte
722+ */
723+u32
724+decode_sib_address(int sib, int mod)
725+{
726+ u32 base = 0, i = 0, scale = 1;
727+
728+ switch (sib & 0x07) {
729+ case 0:
730+ DECODE_PRINTF("[EAX]");
731+ base = M.x86.R_EAX;
732+ break;
733+ case 1:
734+ DECODE_PRINTF("[ECX]");
735+ base = M.x86.R_ECX;
736+ break;
737+ case 2:
738+ DECODE_PRINTF("[EDX]");
739+ base = M.x86.R_EDX;
740+ break;
741+ case 3:
742+ DECODE_PRINTF("[EBX]");
743+ base = M.x86.R_EBX;
744+ break;
745+ case 4:
746+ DECODE_PRINTF("[ESP]");
747+ base = M.x86.R_ESP;
748+ M.x86.mode |= SYSMODE_SEG_DS_SS;
749+ break;
750+ case 5:
751+ if (mod == 0) {
752+ base = fetch_long_imm();
753+ DECODE_PRINTF2("%08x", base);
754+ }
755+ else {
756+ DECODE_PRINTF("[EBP]");
757+ base = M.x86.R_ESP;
758+ M.x86.mode |= SYSMODE_SEG_DS_SS;
759+ }
760+ break;
761+ case 6:
762+ DECODE_PRINTF("[ESI]");
763+ base = M.x86.R_ESI;
764+ break;
765+ case 7:
766+ DECODE_PRINTF("[EDI]");
767+ base = M.x86.R_EDI;
768+ break;
769+ }
770+ switch ((sib >> 3) & 0x07) {
771+ case 0:
772+ DECODE_PRINTF("[EAX");
773+ i = M.x86.R_EAX;
774+ break;
775+ case 1:
776+ DECODE_PRINTF("[ECX");
777+ i = M.x86.R_ECX;
778+ break;
779+ case 2:
780+ DECODE_PRINTF("[EDX");
781+ i = M.x86.R_EDX;
782+ break;
783+ case 3:
784+ DECODE_PRINTF("[EBX");
785+ i = M.x86.R_EBX;
786+ break;
787+ case 4:
788+ i = 0;
789+ break;
790+ case 5:
791+ DECODE_PRINTF("[EBP");
792+ i = M.x86.R_EBP;
793+ break;
794+ case 6:
795+ DECODE_PRINTF("[ESI");
796+ i = M.x86.R_ESI;
797+ break;
798+ case 7:
799+ DECODE_PRINTF("[EDI");
800+ i = M.x86.R_EDI;
801+ break;
802+ }
803+ scale = 1 << ((sib >> 6) & 0x03);
804+ if (((sib >> 3) & 0x07) != 4) {
805+ if (scale == 1) {
806+ DECODE_PRINTF("]");
807+ }
808+ else {
809+ DECODE_PRINTF2("*%d]", scale);
810+ }
811+ }
812+ return base + (i * scale);
813+}
814+
815+/****************************************************************************
816+PARAMETERS:
817+rm - RM value to decode
818+
819+RETURNS:
820+Offset in memory for the address decoding
821+
822+REMARKS:
823+Return the offset given by mod=00 addressing. Also enables the
824+decoding of instructions.
825+
826+NOTE: The code which specifies the corresponding segment (ds vs ss)
827+ below in the case of [BP+..]. The assumption here is that at the
828+ point that this subroutine is called, the bit corresponding to
829+ SYSMODE_SEG_DS_SS will be zero. After every instruction
830+ except the segment override instructions, this bit (as well
831+ as any bits indicating segment overrides) will be clear. So
832+ if a SS access is needed, set this bit. Otherwise, DS access
833+ occurs (unless any of the segment override bits are set).
834+****************************************************************************/
835+u32
836+decode_rm00_address(int rm)
837+{
838+ u32 offset;
839+ int sib;
840+
841+ if (M.x86.mode & SYSMODE_PREFIX_ADDR) {
842+ /* 32-bit addressing */
843+ switch (rm) {
844+ case 0:
845+ DECODE_PRINTF("[EAX]");
846+ return M.x86.R_EAX;
847+ case 1:
848+ DECODE_PRINTF("[ECX]");
849+ return M.x86.R_ECX;
850+ case 2:
851+ DECODE_PRINTF("[EDX]");
852+ return M.x86.R_EDX;
853+ case 3:
854+ DECODE_PRINTF("[EBX]");
855+ return M.x86.R_EBX;
856+ case 4:
857+ sib = fetch_byte_imm();
858+ return decode_sib_address(sib, 0);
859+ case 5:
860+ offset = fetch_long_imm();
861+ DECODE_PRINTF2("[%08x]", offset);
862+ return offset;
863+ case 6:
864+ DECODE_PRINTF("[ESI]");
865+ return M.x86.R_ESI;
866+ case 7:
867+ DECODE_PRINTF("[EDI]");
868+ return M.x86.R_EDI;
869+ }
870+ HALT_SYS();
871+ }
872+ else {
873+ /* 16-bit addressing */
874+ switch (rm) {
875+ case 0:
876+ DECODE_PRINTF("[BX+SI]");
877+ return (M.x86.R_BX + M.x86.R_SI) & 0xffff;
878+ case 1:
879+ DECODE_PRINTF("[BX+DI]");
880+ return (M.x86.R_BX + M.x86.R_DI) & 0xffff;
881+ case 2:
882+ DECODE_PRINTF("[BP+SI]");
883+ M.x86.mode |= SYSMODE_SEG_DS_SS;
884+ return (M.x86.R_BP + M.x86.R_SI) & 0xffff;
885+ case 3:
886+ DECODE_PRINTF("[BP+DI]");
887+ M.x86.mode |= SYSMODE_SEG_DS_SS;
888+ return (M.x86.R_BP + M.x86.R_DI) & 0xffff;
889+ case 4:
890+ DECODE_PRINTF("[SI]");
891+ return M.x86.R_SI;
892+ case 5:
893+ DECODE_PRINTF("[DI]");
894+ return M.x86.R_DI;
895+ case 6:
896+ offset = fetch_word_imm();
897+ DECODE_PRINTF2("[%04x]", offset);
898+ return offset;
899+ case 7:
900+ DECODE_PRINTF("[BX]");
901+ return M.x86.R_BX;
902+ }
903+ HALT_SYS();
904+ }
905+ return 0;
906+}
907+
908+/****************************************************************************
909+PARAMETERS:
910+rm - RM value to decode
911+
912+RETURNS:
913+Offset in memory for the address decoding
914+
915+REMARKS:
916+Return the offset given by mod=01 addressing. Also enables the
917+decoding of instructions.
918+****************************************************************************/
919+u32
920+decode_rm01_address(int rm)
921+{
922+ int displacement = 0;
923+ int sib;
924+
925+ /* Fetch disp8 if no SIB byte */
926+ if (!((M.x86.mode & SYSMODE_PREFIX_ADDR) && (rm == 4)))
927+ displacement = (s8) fetch_byte_imm();
928+
929+ if (M.x86.mode & SYSMODE_PREFIX_ADDR) {
930+ /* 32-bit addressing */
931+ switch (rm) {
932+ case 0:
933+ DECODE_PRINTF2("%d[EAX]", displacement);
934+ return M.x86.R_EAX + displacement;
935+ case 1:
936+ DECODE_PRINTF2("%d[ECX]", displacement);
937+ return M.x86.R_ECX + displacement;
938+ case 2:
939+ DECODE_PRINTF2("%d[EDX]", displacement);
940+ return M.x86.R_EDX + displacement;
941+ case 3:
942+ DECODE_PRINTF2("%d[EBX]", displacement);
943+ return M.x86.R_EBX + displacement;
944+ case 4:
945+ sib = fetch_byte_imm();
946+ displacement = (s8) fetch_byte_imm();
947+ DECODE_PRINTF2("%d", displacement);
948+ return decode_sib_address(sib, 1) + displacement;
949+ case 5:
950+ DECODE_PRINTF2("%d[EBP]", displacement);
951+ return M.x86.R_EBP + displacement;
952+ case 6:
953+ DECODE_PRINTF2("%d[ESI]", displacement);
954+ return M.x86.R_ESI + displacement;
955+ case 7:
956+ DECODE_PRINTF2("%d[EDI]", displacement);
957+ return M.x86.R_EDI + displacement;
958+ }
959+ HALT_SYS();
960+ }
961+ else {
962+ /* 16-bit addressing */
963+ switch (rm) {
964+ case 0:
965+ DECODE_PRINTF2("%d[BX+SI]", displacement);
966+ return (M.x86.R_BX + M.x86.R_SI + displacement) & 0xffff;
967+ case 1:
968+ DECODE_PRINTF2("%d[BX+DI]", displacement);
969+ return (M.x86.R_BX + M.x86.R_DI + displacement) & 0xffff;
970+ case 2:
971+ DECODE_PRINTF2("%d[BP+SI]", displacement);
972+ M.x86.mode |= SYSMODE_SEG_DS_SS;
973+ return (M.x86.R_BP + M.x86.R_SI + displacement) & 0xffff;
974+ case 3:
975+ DECODE_PRINTF2("%d[BP+DI]", displacement);
976+ M.x86.mode |= SYSMODE_SEG_DS_SS;
977+ return (M.x86.R_BP + M.x86.R_DI + displacement) & 0xffff;
978+ case 4:
979+ DECODE_PRINTF2("%d[SI]", displacement);
980+ return (M.x86.R_SI + displacement) & 0xffff;
981+ case 5:
982+ DECODE_PRINTF2("%d[DI]", displacement);
983+ return (M.x86.R_DI + displacement) & 0xffff;
984+ case 6:
985+ DECODE_PRINTF2("%d[BP]", displacement);
986+ M.x86.mode |= SYSMODE_SEG_DS_SS;
987+ return (M.x86.R_BP + displacement) & 0xffff;
988+ case 7:
989+ DECODE_PRINTF2("%d[BX]", displacement);
990+ return (M.x86.R_BX + displacement) & 0xffff;
991+ }
992+ HALT_SYS();
993+ }
994+ return 0; /* SHOULD NOT HAPPEN */
995+}
996+
997+/****************************************************************************
998+PARAMETERS:
999+rm - RM value to decode
1000+
1001+RETURNS:
1002+Offset in memory for the address decoding
1003+
1004+REMARKS:
1005+Return the offset given by mod=10 addressing. Also enables the
1006+decoding of instructions.
1007+****************************************************************************/
1008+u32
1009+decode_rm10_address(int rm)
1010+{
1011+ u32 displacement = 0;
1012+ int sib;
1013+
1014+ /* Fetch disp16 if 16-bit addr mode */
1015+ if (!(M.x86.mode & SYSMODE_PREFIX_ADDR))
1016+ displacement = (u16) fetch_word_imm();
1017+ else {
1018+ /* Fetch disp32 if no SIB byte */
1019+ if (rm != 4)
1020+ displacement = (u32) fetch_long_imm();
1021+ }
1022+
1023+ if (M.x86.mode & SYSMODE_PREFIX_ADDR) {
1024+ /* 32-bit addressing */
1025+ switch (rm) {
1026+ case 0:
1027+ DECODE_PRINTF2("%08x[EAX]", displacement);
1028+ return M.x86.R_EAX + displacement;
1029+ case 1:
1030+ DECODE_PRINTF2("%08x[ECX]", displacement);
1031+ return M.x86.R_ECX + displacement;
1032+ case 2:
1033+ DECODE_PRINTF2("%08x[EDX]", displacement);
1034+ M.x86.mode |= SYSMODE_SEG_DS_SS;
1035+ return M.x86.R_EDX + displacement;
1036+ case 3:
1037+ DECODE_PRINTF2("%08x[EBX]", displacement);
1038+ return M.x86.R_EBX + displacement;
1039+ case 4:
1040+ sib = fetch_byte_imm();
1041+ displacement = (u32) fetch_long_imm();
1042+ DECODE_PRINTF2("%08x", displacement);
1043+ return decode_sib_address(sib, 2) + displacement;
1044+ break;
1045+ case 5:
1046+ DECODE_PRINTF2("%08x[EBP]", displacement);
1047+ return M.x86.R_EBP + displacement;
1048+ case 6:
1049+ DECODE_PRINTF2("%08x[ESI]", displacement);
1050+ return M.x86.R_ESI + displacement;
1051+ case 7:
1052+ DECODE_PRINTF2("%08x[EDI]", displacement);
1053+ return M.x86.R_EDI + displacement;
1054+ }
1055+ HALT_SYS();
1056+ }
1057+ else {
1058+ /* 16-bit addressing */
1059+ switch (rm) {
1060+ case 0:
1061+ DECODE_PRINTF2("%04x[BX+SI]", displacement);
1062+ return (M.x86.R_BX + M.x86.R_SI + displacement) & 0xffff;
1063+ case 1:
1064+ DECODE_PRINTF2("%04x[BX+DI]", displacement);
1065+ return (M.x86.R_BX + M.x86.R_DI + displacement) & 0xffff;
1066+ case 2:
1067+ DECODE_PRINTF2("%04x[BP+SI]", displacement);
1068+ M.x86.mode |= SYSMODE_SEG_DS_SS;
1069+ return (M.x86.R_BP + M.x86.R_SI + displacement) & 0xffff;
1070+ case 3:
1071+ DECODE_PRINTF2("%04x[BP+DI]", displacement);
1072+ M.x86.mode |= SYSMODE_SEG_DS_SS;
1073+ return (M.x86.R_BP + M.x86.R_DI + displacement) & 0xffff;
1074+ case 4:
1075+ DECODE_PRINTF2("%04x[SI]", displacement);
1076+ return (M.x86.R_SI + displacement) & 0xffff;
1077+ case 5:
1078+ DECODE_PRINTF2("%04x[DI]", displacement);
1079+ return (M.x86.R_DI + displacement) & 0xffff;
1080+ case 6:
1081+ DECODE_PRINTF2("%04x[BP]", displacement);
1082+ M.x86.mode |= SYSMODE_SEG_DS_SS;
1083+ return (M.x86.R_BP + displacement) & 0xffff;
1084+ case 7:
1085+ DECODE_PRINTF2("%04x[BX]", displacement);
1086+ return (M.x86.R_BX + displacement) & 0xffff;
1087+ }
1088+ HALT_SYS();
1089+ }
1090+ return 0;
1091+ /*NOTREACHED */
1092+}
--- /dev/null
+++ b/x86emu/fpu.c
@@ -0,0 +1,976 @@
1+/****************************************************************************
2+*
3+* Realmode X86 Emulator Library
4+*
5+* Copyright (C) 1996-1999 SciTech Software, Inc.
6+* Copyright (C) David Mosberger-Tang
7+* Copyright (C) 1999 Egbert Eich
8+*
9+* ========================================================================
10+*
11+* Permission to use, copy, modify, distribute, and sell this software and
12+* its documentation for any purpose is hereby granted without fee,
13+* provided that the above copyright notice appear in all copies and that
14+* both that copyright notice and this permission notice appear in
15+* supporting documentation, and that the name of the authors not be used
16+* in advertising or publicity pertaining to distribution of the software
17+* without specific, written prior permission. The authors makes no
18+* representations about the suitability of this software for any purpose.
19+* It is provided "as is" without express or implied warranty.
20+*
21+* THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
22+* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
23+* EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
24+* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
25+* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
26+* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
27+* PERFORMANCE OF THIS SOFTWARE.
28+*
29+* ========================================================================
30+*
31+* Language: ANSI C
32+* Environment: Any
33+* Developer: Kendall Bennett
34+*
35+* Description: This file contains the code to implement the decoding and
36+* emulation of the FPU instructions.
37+*
38+****************************************************************************/
39+
40+#include "x86emu/x86emui.h"
41+
42+/*----------------------------- Implementation ----------------------------*/
43+
44+/* opcode=0xd8 */
45+void
46+x86emuOp_esc_coprocess_d8(u8 X86EMU_UNUSED(op1))
47+{
48+ START_OF_INSTR();
49+ DECODE_PRINTF("ESC D8\n");
50+ DECODE_CLEAR_SEGOVR();
51+ END_OF_INSTR_NO_TRACE();
52+}
53+
54+#ifdef DEBUG
55+
56+static const char *x86emu_fpu_op_d9_tab[] = {
57+ "FLD\tDWORD PTR ", "ESC_D9\t", "FST\tDWORD PTR ", "FSTP\tDWORD PTR ",
58+ "FLDENV\t", "FLDCW\t", "FSTENV\t", "FSTCW\t",
59+
60+ "FLD\tDWORD PTR ", "ESC_D9\t", "FST\tDWORD PTR ", "FSTP\tDWORD PTR ",
61+ "FLDENV\t", "FLDCW\t", "FSTENV\t", "FSTCW\t",
62+
63+ "FLD\tDWORD PTR ", "ESC_D9\t", "FST\tDWORD PTR ", "FSTP\tDWORD PTR ",
64+ "FLDENV\t", "FLDCW\t", "FSTENV\t", "FSTCW\t",
65+};
66+
67+static const char *x86emu_fpu_op_d9_tab1[] = {
68+ "FLD\t", "FLD\t", "FLD\t", "FLD\t",
69+ "FLD\t", "FLD\t", "FLD\t", "FLD\t",
70+
71+ "FXCH\t", "FXCH\t", "FXCH\t", "FXCH\t",
72+ "FXCH\t", "FXCH\t", "FXCH\t", "FXCH\t",
73+
74+ "FNOP", "ESC_D9", "ESC_D9", "ESC_D9",
75+ "ESC_D9", "ESC_D9", "ESC_D9", "ESC_D9",
76+
77+ "FSTP\t", "FSTP\t", "FSTP\t", "FSTP\t",
78+ "FSTP\t", "FSTP\t", "FSTP\t", "FSTP\t",
79+
80+ "FCHS", "FABS", "ESC_D9", "ESC_D9",
81+ "FTST", "FXAM", "ESC_D9", "ESC_D9",
82+
83+ "FLD1", "FLDL2T", "FLDL2E", "FLDPI",
84+ "FLDLG2", "FLDLN2", "FLDZ", "ESC_D9",
85+
86+ "F2XM1", "FYL2X", "FPTAN", "FPATAN",
87+ "FXTRACT", "ESC_D9", "FDECSTP", "FINCSTP",
88+
89+ "FPREM", "FYL2XP1", "FSQRT", "ESC_D9",
90+ "FRNDINT", "FSCALE", "ESC_D9", "ESC_D9",
91+};
92+
93+#endif /* DEBUG */
94+
95+/* opcode=0xd9 */
96+void
97+x86emuOp_esc_coprocess_d9(u8 X86EMU_UNUSED(op1))
98+{
99+ int mod, rl, rh;
100+ uint destoffset = 0;
101+ u8 stkelem = 0;
102+
103+ START_OF_INSTR();
104+ FETCH_DECODE_MODRM(mod, rh, rl);
105+#ifdef DEBUG
106+ if (mod != 3) {
107+ DECODE_PRINTINSTR32(x86emu_fpu_op_d9_tab, mod, rh, rl);
108+ }
109+ else {
110+ DECODE_PRINTF(x86emu_fpu_op_d9_tab1[(rh << 3) + rl]);
111+ }
112+#endif
113+ switch (mod) {
114+ case 0:
115+ destoffset = decode_rm00_address(rl);
116+ DECODE_PRINTF("\n");
117+ break;
118+ case 1:
119+ destoffset = decode_rm01_address(rl);
120+ DECODE_PRINTF("\n");
121+ break;
122+ case 2:
123+ destoffset = decode_rm10_address(rl);
124+ DECODE_PRINTF("\n");
125+ break;
126+ case 3: /* register to register */
127+ stkelem = (u8) rl;
128+ if (rh < 4) {
129+ DECODE_PRINTF2("ST(%d)\n", stkelem);
130+ }
131+ else {
132+ DECODE_PRINTF("\n");
133+ }
134+ break;
135+ }
136+#ifdef X86EMU_FPU_PRESENT
137+ /* execute */
138+ switch (mod) {
139+ case 3:
140+ switch (rh) {
141+ case 0:
142+ x86emu_fpu_R_fld(X86EMU_FPU_STKTOP, stkelem);
143+ break;
144+ case 1:
145+ x86emu_fpu_R_fxch(X86EMU_FPU_STKTOP, stkelem);
146+ break;
147+ case 2:
148+ switch (rl) {
149+ case 0:
150+ x86emu_fpu_R_nop();
151+ break;
152+ default:
153+ x86emu_fpu_illegal();
154+ break;
155+ }
156+ case 3:
157+ x86emu_fpu_R_fstp(X86EMU_FPU_STKTOP, stkelem);
158+ break;
159+ case 4:
160+ switch (rl) {
161+ case 0:
162+ x86emu_fpu_R_fchs(X86EMU_FPU_STKTOP);
163+ break;
164+ case 1:
165+ x86emu_fpu_R_fabs(X86EMU_FPU_STKTOP);
166+ break;
167+ case 4:
168+ x86emu_fpu_R_ftst(X86EMU_FPU_STKTOP);
169+ break;
170+ case 5:
171+ x86emu_fpu_R_fxam(X86EMU_FPU_STKTOP);
172+ break;
173+ default:
174+ /* 2,3,6,7 */
175+ x86emu_fpu_illegal();
176+ break;
177+ }
178+ break;
179+
180+ case 5:
181+ switch (rl) {
182+ case 0:
183+ x86emu_fpu_R_fld1(X86EMU_FPU_STKTOP);
184+ break;
185+ case 1:
186+ x86emu_fpu_R_fldl2t(X86EMU_FPU_STKTOP);
187+ break;
188+ case 2:
189+ x86emu_fpu_R_fldl2e(X86EMU_FPU_STKTOP);
190+ break;
191+ case 3:
192+ x86emu_fpu_R_fldpi(X86EMU_FPU_STKTOP);
193+ break;
194+ case 4:
195+ x86emu_fpu_R_fldlg2(X86EMU_FPU_STKTOP);
196+ break;
197+ case 5:
198+ x86emu_fpu_R_fldln2(X86EMU_FPU_STKTOP);
199+ break;
200+ case 6:
201+ x86emu_fpu_R_fldz(X86EMU_FPU_STKTOP);
202+ break;
203+ default:
204+ /* 7 */
205+ x86emu_fpu_illegal();
206+ break;
207+ }
208+ break;
209+
210+ case 6:
211+ switch (rl) {
212+ case 0:
213+ x86emu_fpu_R_f2xm1(X86EMU_FPU_STKTOP);
214+ break;
215+ case 1:
216+ x86emu_fpu_R_fyl2x(X86EMU_FPU_STKTOP);
217+ break;
218+ case 2:
219+ x86emu_fpu_R_fptan(X86EMU_FPU_STKTOP);
220+ break;
221+ case 3:
222+ x86emu_fpu_R_fpatan(X86EMU_FPU_STKTOP);
223+ break;
224+ case 4:
225+ x86emu_fpu_R_fxtract(X86EMU_FPU_STKTOP);
226+ break;
227+ case 5:
228+ x86emu_fpu_illegal();
229+ break;
230+ case 6:
231+ x86emu_fpu_R_decstp();
232+ break;
233+ case 7:
234+ x86emu_fpu_R_incstp();
235+ break;
236+ }
237+ break;
238+
239+ case 7:
240+ switch (rl) {
241+ case 0:
242+ x86emu_fpu_R_fprem(X86EMU_FPU_STKTOP);
243+ break;
244+ case 1:
245+ x86emu_fpu_R_fyl2xp1(X86EMU_FPU_STKTOP);
246+ break;
247+ case 2:
248+ x86emu_fpu_R_fsqrt(X86EMU_FPU_STKTOP);
249+ break;
250+ case 3:
251+ x86emu_fpu_illegal();
252+ break;
253+ case 4:
254+ x86emu_fpu_R_frndint(X86EMU_FPU_STKTOP);
255+ break;
256+ case 5:
257+ x86emu_fpu_R_fscale(X86EMU_FPU_STKTOP);
258+ break;
259+ case 6:
260+ case 7:
261+ default:
262+ x86emu_fpu_illegal();
263+ break;
264+ }
265+ break;
266+
267+ default:
268+ switch (rh) {
269+ case 0:
270+ x86emu_fpu_M_fld(X86EMU_FPU_FLOAT, destoffset);
271+ break;
272+ case 1:
273+ x86emu_fpu_illegal();
274+ break;
275+ case 2:
276+ x86emu_fpu_M_fst(X86EMU_FPU_FLOAT, destoffset);
277+ break;
278+ case 3:
279+ x86emu_fpu_M_fstp(X86EMU_FPU_FLOAT, destoffset);
280+ break;
281+ case 4:
282+ x86emu_fpu_M_fldenv(X86EMU_FPU_WORD, destoffset);
283+ break;
284+ case 5:
285+ x86emu_fpu_M_fldcw(X86EMU_FPU_WORD, destoffset);
286+ break;
287+ case 6:
288+ x86emu_fpu_M_fstenv(X86EMU_FPU_WORD, destoffset);
289+ break;
290+ case 7:
291+ x86emu_fpu_M_fstcw(X86EMU_FPU_WORD, destoffset);
292+ break;
293+ }
294+ }
295+ }
296+#else
297+ (void) destoffset;
298+ (void) stkelem;
299+#endif /* X86EMU_FPU_PRESENT */
300+ DECODE_CLEAR_SEGOVR();
301+ END_OF_INSTR_NO_TRACE();
302+}
303+
304+#ifdef DEBUG
305+
306+static const char *x86emu_fpu_op_da_tab[] = {
307+ "FIADD\tDWORD PTR ", "FIMUL\tDWORD PTR ", "FICOM\tDWORD PTR ",
308+ "FICOMP\tDWORD PTR ",
309+ "FISUB\tDWORD PTR ", "FISUBR\tDWORD PTR ", "FIDIV\tDWORD PTR ",
310+ "FIDIVR\tDWORD PTR ",
311+
312+ "FIADD\tDWORD PTR ", "FIMUL\tDWORD PTR ", "FICOM\tDWORD PTR ",
313+ "FICOMP\tDWORD PTR ",
314+ "FISUB\tDWORD PTR ", "FISUBR\tDWORD PTR ", "FIDIV\tDWORD PTR ",
315+ "FIDIVR\tDWORD PTR ",
316+
317+ "FIADD\tDWORD PTR ", "FIMUL\tDWORD PTR ", "FICOM\tDWORD PTR ",
318+ "FICOMP\tDWORD PTR ",
319+ "FISUB\tDWORD PTR ", "FISUBR\tDWORD PTR ", "FIDIV\tDWORD PTR ",
320+ "FIDIVR\tDWORD PTR ",
321+
322+ "ESC_DA ", "ESC_DA ", "ESC_DA ", "ESC_DA ",
323+ "ESC_DA ", "ESC_DA ", "ESC_DA ", "ESC_DA ",
324+};
325+
326+#endif /* DEBUG */
327+
328+/* opcode=0xda */
329+void
330+x86emuOp_esc_coprocess_da(u8 X86EMU_UNUSED(op1))
331+{
332+ int mod, rl, rh;
333+ uint destoffset = 0;
334+ u8 stkelem = 0;
335+
336+ START_OF_INSTR();
337+ FETCH_DECODE_MODRM(mod, rh, rl);
338+ DECODE_PRINTINSTR32(x86emu_fpu_op_da_tab, mod, rh, rl);
339+ switch (mod) {
340+ case 0:
341+ destoffset = decode_rm00_address(rl);
342+ DECODE_PRINTF("\n");
343+ break;
344+ case 1:
345+ destoffset = decode_rm01_address(rl);
346+ DECODE_PRINTF("\n");
347+ break;
348+ case 2:
349+ destoffset = decode_rm10_address(rl);
350+ DECODE_PRINTF("\n");
351+ break;
352+ case 3: /* register to register */
353+ stkelem = (u8) rl;
354+ DECODE_PRINTF2("\tST(%d),ST\n", stkelem);
355+ break;
356+ }
357+#ifdef X86EMU_FPU_PRESENT
358+ switch (mod) {
359+ case 3:
360+ x86emu_fpu_illegal();
361+ break;
362+ default:
363+ switch (rh) {
364+ case 0:
365+ x86emu_fpu_M_iadd(X86EMU_FPU_SHORT, destoffset);
366+ break;
367+ case 1:
368+ x86emu_fpu_M_imul(X86EMU_FPU_SHORT, destoffset);
369+ break;
370+ case 2:
371+ x86emu_fpu_M_icom(X86EMU_FPU_SHORT, destoffset);
372+ break;
373+ case 3:
374+ x86emu_fpu_M_icomp(X86EMU_FPU_SHORT, destoffset);
375+ break;
376+ case 4:
377+ x86emu_fpu_M_isub(X86EMU_FPU_SHORT, destoffset);
378+ break;
379+ case 5:
380+ x86emu_fpu_M_isubr(X86EMU_FPU_SHORT, destoffset);
381+ break;
382+ case 6:
383+ x86emu_fpu_M_idiv(X86EMU_FPU_SHORT, destoffset);
384+ break;
385+ case 7:
386+ x86emu_fpu_M_idivr(X86EMU_FPU_SHORT, destoffset);
387+ break;
388+ }
389+ }
390+#else
391+ (void) destoffset;
392+ (void) stkelem;
393+#endif
394+ DECODE_CLEAR_SEGOVR();
395+ END_OF_INSTR_NO_TRACE();
396+}
397+
398+#ifdef DEBUG
399+
400+static const char *x86emu_fpu_op_db_tab[] = {
401+ "FILD\tDWORD PTR ", "ESC_DB\t19", "FIST\tDWORD PTR ", "FISTP\tDWORD PTR ",
402+ "ESC_DB\t1C", "FLD\tTBYTE PTR ", "ESC_DB\t1E", "FSTP\tTBYTE PTR ",
403+
404+ "FILD\tDWORD PTR ", "ESC_DB\t19", "FIST\tDWORD PTR ", "FISTP\tDWORD PTR ",
405+ "ESC_DB\t1C", "FLD\tTBYTE PTR ", "ESC_DB\t1E", "FSTP\tTBYTE PTR ",
406+
407+ "FILD\tDWORD PTR ", "ESC_DB\t19", "FIST\tDWORD PTR ", "FISTP\tDWORD PTR ",
408+ "ESC_DB\t1C", "FLD\tTBYTE PTR ", "ESC_DB\t1E", "FSTP\tTBYTE PTR ",
409+};
410+
411+#endif /* DEBUG */
412+
413+/* opcode=0xdb */
414+void
415+x86emuOp_esc_coprocess_db(u8 X86EMU_UNUSED(op1))
416+{
417+ int mod, rl, rh;
418+ uint destoffset = 0;
419+
420+ START_OF_INSTR();
421+ FETCH_DECODE_MODRM(mod, rh, rl);
422+#ifdef DEBUG
423+ if (mod != 3) {
424+ DECODE_PRINTINSTR32(x86emu_fpu_op_db_tab, mod, rh, rl);
425+ }
426+ else if (rh == 4) { /* === 11 10 0 nnn */
427+ switch (rl) {
428+ case 0:
429+ DECODE_PRINTF("FENI\n");
430+ break;
431+ case 1:
432+ DECODE_PRINTF("FDISI\n");
433+ break;
434+ case 2:
435+ DECODE_PRINTF("FCLEX\n");
436+ break;
437+ case 3:
438+ DECODE_PRINTF("FINIT\n");
439+ break;
440+ }
441+ }
442+ else {
443+ DECODE_PRINTF2("ESC_DB %0x\n", (mod << 6) + (rh << 3) + (rl));
444+ }
445+#endif /* DEBUG */
446+ switch (mod) {
447+ case 0:
448+ destoffset = decode_rm00_address(rl);
449+ break;
450+ case 1:
451+ destoffset = decode_rm01_address(rl);
452+ break;
453+ case 2:
454+ destoffset = decode_rm10_address(rl);
455+ break;
456+ case 3: /* register to register */
457+ break;
458+ }
459+#ifdef X86EMU_FPU_PRESENT
460+ /* execute */
461+ switch (mod) {
462+ case 3:
463+ switch (rh) {
464+ case 4:
465+ switch (rl) {
466+ case 0:
467+ x86emu_fpu_R_feni();
468+ break;
469+ case 1:
470+ x86emu_fpu_R_fdisi();
471+ break;
472+ case 2:
473+ x86emu_fpu_R_fclex();
474+ break;
475+ case 3:
476+ x86emu_fpu_R_finit();
477+ break;
478+ default:
479+ x86emu_fpu_illegal();
480+ break;
481+ }
482+ break;
483+ default:
484+ x86emu_fpu_illegal();
485+ break;
486+ }
487+ break;
488+ default:
489+ switch (rh) {
490+ case 0:
491+ x86emu_fpu_M_fild(X86EMU_FPU_SHORT, destoffset);
492+ break;
493+ case 1:
494+ x86emu_fpu_illegal();
495+ break;
496+ case 2:
497+ x86emu_fpu_M_fist(X86EMU_FPU_SHORT, destoffset);
498+ break;
499+ case 3:
500+ x86emu_fpu_M_fistp(X86EMU_FPU_SHORT, destoffset);
501+ break;
502+ case 4:
503+ x86emu_fpu_illegal();
504+ break;
505+ case 5:
506+ x86emu_fpu_M_fld(X86EMU_FPU_LDBL, destoffset);
507+ break;
508+ case 6:
509+ x86emu_fpu_illegal();
510+ break;
511+ case 7:
512+ x86emu_fpu_M_fstp(X86EMU_FPU_LDBL, destoffset);
513+ break;
514+ }
515+ }
516+#else
517+ (void) destoffset;
518+#endif
519+ DECODE_CLEAR_SEGOVR();
520+ END_OF_INSTR_NO_TRACE();
521+}
522+
523+#ifdef DEBUG
524+static const char *x86emu_fpu_op_dc_tab[] = {
525+ "FADD\tQWORD PTR ", "FMUL\tQWORD PTR ", "FCOM\tQWORD PTR ",
526+ "FCOMP\tQWORD PTR ",
527+ "FSUB\tQWORD PTR ", "FSUBR\tQWORD PTR ", "FDIV\tQWORD PTR ",
528+ "FDIVR\tQWORD PTR ",
529+
530+ "FADD\tQWORD PTR ", "FMUL\tQWORD PTR ", "FCOM\tQWORD PTR ",
531+ "FCOMP\tQWORD PTR ",
532+ "FSUB\tQWORD PTR ", "FSUBR\tQWORD PTR ", "FDIV\tQWORD PTR ",
533+ "FDIVR\tQWORD PTR ",
534+
535+ "FADD\tQWORD PTR ", "FMUL\tQWORD PTR ", "FCOM\tQWORD PTR ",
536+ "FCOMP\tQWORD PTR ",
537+ "FSUB\tQWORD PTR ", "FSUBR\tQWORD PTR ", "FDIV\tQWORD PTR ",
538+ "FDIVR\tQWORD PTR ",
539+
540+ "FADD\t", "FMUL\t", "FCOM\t", "FCOMP\t",
541+ "FSUBR\t", "FSUB\t", "FDIVR\t", "FDIV\t",
542+};
543+#endif /* DEBUG */
544+
545+/* opcode=0xdc */
546+void
547+x86emuOp_esc_coprocess_dc(u8 X86EMU_UNUSED(op1))
548+{
549+ int mod, rl, rh;
550+ uint destoffset = 0;
551+ u8 stkelem = 0;
552+
553+ START_OF_INSTR();
554+ FETCH_DECODE_MODRM(mod, rh, rl);
555+ DECODE_PRINTINSTR32(x86emu_fpu_op_dc_tab, mod, rh, rl);
556+ switch (mod) {
557+ case 0:
558+ destoffset = decode_rm00_address(rl);
559+ DECODE_PRINTF("\n");
560+ break;
561+ case 1:
562+ destoffset = decode_rm01_address(rl);
563+ DECODE_PRINTF("\n");
564+ break;
565+ case 2:
566+ destoffset = decode_rm10_address(rl);
567+ DECODE_PRINTF("\n");
568+ break;
569+ case 3: /* register to register */
570+ stkelem = (u8) rl;
571+ DECODE_PRINTF2("\tST(%d),ST\n", stkelem);
572+ break;
573+ }
574+#ifdef X86EMU_FPU_PRESENT
575+ /* execute */
576+ switch (mod) {
577+ case 3:
578+ switch (rh) {
579+ case 0:
580+ x86emu_fpu_R_fadd(stkelem, X86EMU_FPU_STKTOP);
581+ break;
582+ case 1:
583+ x86emu_fpu_R_fmul(stkelem, X86EMU_FPU_STKTOP);
584+ break;
585+ case 2:
586+ x86emu_fpu_R_fcom(stkelem, X86EMU_FPU_STKTOP);
587+ break;
588+ case 3:
589+ x86emu_fpu_R_fcomp(stkelem, X86EMU_FPU_STKTOP);
590+ break;
591+ case 4:
592+ x86emu_fpu_R_fsubr(stkelem, X86EMU_FPU_STKTOP);
593+ break;
594+ case 5:
595+ x86emu_fpu_R_fsub(stkelem, X86EMU_FPU_STKTOP);
596+ break;
597+ case 6:
598+ x86emu_fpu_R_fdivr(stkelem, X86EMU_FPU_STKTOP);
599+ break;
600+ case 7:
601+ x86emu_fpu_R_fdiv(stkelem, X86EMU_FPU_STKTOP);
602+ break;
603+ }
604+ break;
605+ default:
606+ switch (rh) {
607+ case 0:
608+ x86emu_fpu_M_fadd(X86EMU_FPU_DOUBLE, destoffset);
609+ break;
610+ case 1:
611+ x86emu_fpu_M_fmul(X86EMU_FPU_DOUBLE, destoffset);
612+ break;
613+ case 2:
614+ x86emu_fpu_M_fcom(X86EMU_FPU_DOUBLE, destoffset);
615+ break;
616+ case 3:
617+ x86emu_fpu_M_fcomp(X86EMU_FPU_DOUBLE, destoffset);
618+ break;
619+ case 4:
620+ x86emu_fpu_M_fsub(X86EMU_FPU_DOUBLE, destoffset);
621+ break;
622+ case 5:
623+ x86emu_fpu_M_fsubr(X86EMU_FPU_DOUBLE, destoffset);
624+ break;
625+ case 6:
626+ x86emu_fpu_M_fdiv(X86EMU_FPU_DOUBLE, destoffset);
627+ break;
628+ case 7:
629+ x86emu_fpu_M_fdivr(X86EMU_FPU_DOUBLE, destoffset);
630+ break;
631+ }
632+ }
633+#else
634+ (void) destoffset;
635+ (void) stkelem;
636+#endif
637+ DECODE_CLEAR_SEGOVR();
638+ END_OF_INSTR_NO_TRACE();
639+}
640+
641+#ifdef DEBUG
642+
643+static const char *x86emu_fpu_op_dd_tab[] = {
644+ "FLD\tQWORD PTR ", "ESC_DD\t29,", "FST\tQWORD PTR ", "FSTP\tQWORD PTR ",
645+ "FRSTOR\t", "ESC_DD\t2D,", "FSAVE\t", "FSTSW\t",
646+
647+ "FLD\tQWORD PTR ", "ESC_DD\t29,", "FST\tQWORD PTR ", "FSTP\tQWORD PTR ",
648+ "FRSTOR\t", "ESC_DD\t2D,", "FSAVE\t", "FSTSW\t",
649+
650+ "FLD\tQWORD PTR ", "ESC_DD\t29,", "FST\tQWORD PTR ", "FSTP\tQWORD PTR ",
651+ "FRSTOR\t", "ESC_DD\t2D,", "FSAVE\t", "FSTSW\t",
652+
653+ "FFREE\t", "FXCH\t", "FST\t", "FSTP\t",
654+ "ESC_DD\t2C,", "ESC_DD\t2D,", "ESC_DD\t2E,", "ESC_DD\t2F,",
655+};
656+
657+#endif /* DEBUG */
658+
659+/* opcode=0xdd */
660+void
661+x86emuOp_esc_coprocess_dd(u8 X86EMU_UNUSED(op1))
662+{
663+ int mod, rl, rh;
664+ uint destoffset = 0;
665+ u8 stkelem = 0;
666+
667+ START_OF_INSTR();
668+ FETCH_DECODE_MODRM(mod, rh, rl);
669+ DECODE_PRINTINSTR32(x86emu_fpu_op_dd_tab, mod, rh, rl);
670+ switch (mod) {
671+ case 0:
672+ destoffset = decode_rm00_address(rl);
673+ DECODE_PRINTF("\n");
674+ break;
675+ case 1:
676+ destoffset = decode_rm01_address(rl);
677+ DECODE_PRINTF("\n");
678+ break;
679+ case 2:
680+ destoffset = decode_rm10_address(rl);
681+ DECODE_PRINTF("\n");
682+ break;
683+ case 3: /* register to register */
684+ stkelem = (u8) rl;
685+ DECODE_PRINTF2("\tST(%d),ST\n", stkelem);
686+ break;
687+ }
688+#ifdef X86EMU_FPU_PRESENT
689+ switch (mod) {
690+ case 3:
691+ switch (rh) {
692+ case 0:
693+ x86emu_fpu_R_ffree(stkelem);
694+ break;
695+ case 1:
696+ x86emu_fpu_R_fxch(stkelem);
697+ break;
698+ case 2:
699+ x86emu_fpu_R_fst(stkelem); /* register version */
700+ break;
701+ case 3:
702+ x86emu_fpu_R_fstp(stkelem); /* register version */
703+ break;
704+ default:
705+ x86emu_fpu_illegal();
706+ break;
707+ }
708+ break;
709+ default:
710+ switch (rh) {
711+ case 0:
712+ x86emu_fpu_M_fld(X86EMU_FPU_DOUBLE, destoffset);
713+ break;
714+ case 1:
715+ x86emu_fpu_illegal();
716+ break;
717+ case 2:
718+ x86emu_fpu_M_fst(X86EMU_FPU_DOUBLE, destoffset);
719+ break;
720+ case 3:
721+ x86emu_fpu_M_fstp(X86EMU_FPU_DOUBLE, destoffset);
722+ break;
723+ case 4:
724+ x86emu_fpu_M_frstor(X86EMU_FPU_WORD, destoffset);
725+ break;
726+ case 5:
727+ x86emu_fpu_illegal();
728+ break;
729+ case 6:
730+ x86emu_fpu_M_fsave(X86EMU_FPU_WORD, destoffset);
731+ break;
732+ case 7:
733+ x86emu_fpu_M_fstsw(X86EMU_FPU_WORD, destoffset);
734+ break;
735+ }
736+ }
737+#else
738+ (void) destoffset;
739+ (void) stkelem;
740+#endif
741+ DECODE_CLEAR_SEGOVR();
742+ END_OF_INSTR_NO_TRACE();
743+}
744+
745+#ifdef DEBUG
746+
747+static const char *x86emu_fpu_op_de_tab[] = {
748+ "FIADD\tWORD PTR ", "FIMUL\tWORD PTR ", "FICOM\tWORD PTR ",
749+ "FICOMP\tWORD PTR ",
750+ "FISUB\tWORD PTR ", "FISUBR\tWORD PTR ", "FIDIV\tWORD PTR ",
751+ "FIDIVR\tWORD PTR ",
752+
753+ "FIADD\tWORD PTR ", "FIMUL\tWORD PTR ", "FICOM\tWORD PTR ",
754+ "FICOMP\tWORD PTR ",
755+ "FISUB\tWORD PTR ", "FISUBR\tWORD PTR ", "FIDIV\tWORD PTR ",
756+ "FIDIVR\tWORD PTR ",
757+
758+ "FIADD\tWORD PTR ", "FIMUL\tWORD PTR ", "FICOM\tWORD PTR ",
759+ "FICOMP\tWORD PTR ",
760+ "FISUB\tWORD PTR ", "FISUBR\tWORD PTR ", "FIDIV\tWORD PTR ",
761+ "FIDIVR\tWORD PTR ",
762+
763+ "FADDP\t", "FMULP\t", "FCOMP\t", "FCOMPP\t",
764+ "FSUBRP\t", "FSUBP\t", "FDIVRP\t", "FDIVP\t",
765+};
766+
767+#endif /* DEBUG */
768+
769+/* opcode=0xde */
770+void
771+x86emuOp_esc_coprocess_de(u8 X86EMU_UNUSED(op1))
772+{
773+ int mod, rl, rh;
774+ uint destoffset = 0;
775+ u8 stkelem = 0;
776+
777+ START_OF_INSTR();
778+ FETCH_DECODE_MODRM(mod, rh, rl);
779+ DECODE_PRINTINSTR32(x86emu_fpu_op_de_tab, mod, rh, rl);
780+ switch (mod) {
781+ case 0:
782+ destoffset = decode_rm00_address(rl);
783+ DECODE_PRINTF("\n");
784+ break;
785+ case 1:
786+ destoffset = decode_rm01_address(rl);
787+ DECODE_PRINTF("\n");
788+ break;
789+ case 2:
790+ destoffset = decode_rm10_address(rl);
791+ DECODE_PRINTF("\n");
792+ break;
793+ case 3: /* register to register */
794+ stkelem = (u8) rl;
795+ DECODE_PRINTF2("\tST(%d),ST\n", stkelem);
796+ break;
797+ }
798+#ifdef X86EMU_FPU_PRESENT
799+ switch (mod) {
800+ case 3:
801+ switch (rh) {
802+ case 0:
803+ x86emu_fpu_R_faddp(stkelem, X86EMU_FPU_STKTOP);
804+ break;
805+ case 1:
806+ x86emu_fpu_R_fmulp(stkelem, X86EMU_FPU_STKTOP);
807+ break;
808+ case 2:
809+ x86emu_fpu_R_fcomp(stkelem, X86EMU_FPU_STKTOP);
810+ break;
811+ case 3:
812+ if (stkelem == 1)
813+ x86emu_fpu_R_fcompp(stkelem, X86EMU_FPU_STKTOP);
814+ else
815+ x86emu_fpu_illegal();
816+ break;
817+ case 4:
818+ x86emu_fpu_R_fsubrp(stkelem, X86EMU_FPU_STKTOP);
819+ break;
820+ case 5:
821+ x86emu_fpu_R_fsubp(stkelem, X86EMU_FPU_STKTOP);
822+ break;
823+ case 6:
824+ x86emu_fpu_R_fdivrp(stkelem, X86EMU_FPU_STKTOP);
825+ break;
826+ case 7:
827+ x86emu_fpu_R_fdivp(stkelem, X86EMU_FPU_STKTOP);
828+ break;
829+ }
830+ break;
831+ default:
832+ switch (rh) {
833+ case 0:
834+ x86emu_fpu_M_fiadd(X86EMU_FPU_WORD, destoffset);
835+ break;
836+ case 1:
837+ x86emu_fpu_M_fimul(X86EMU_FPU_WORD, destoffset);
838+ break;
839+ case 2:
840+ x86emu_fpu_M_ficom(X86EMU_FPU_WORD, destoffset);
841+ break;
842+ case 3:
843+ x86emu_fpu_M_ficomp(X86EMU_FPU_WORD, destoffset);
844+ break;
845+ case 4:
846+ x86emu_fpu_M_fisub(X86EMU_FPU_WORD, destoffset);
847+ break;
848+ case 5:
849+ x86emu_fpu_M_fisubr(X86EMU_FPU_WORD, destoffset);
850+ break;
851+ case 6:
852+ x86emu_fpu_M_fidiv(X86EMU_FPU_WORD, destoffset);
853+ break;
854+ case 7:
855+ x86emu_fpu_M_fidivr(X86EMU_FPU_WORD, destoffset);
856+ break;
857+ }
858+ }
859+#else
860+ (void) destoffset;
861+ (void) stkelem;
862+#endif
863+ DECODE_CLEAR_SEGOVR();
864+ END_OF_INSTR_NO_TRACE();
865+}
866+
867+#ifdef DEBUG
868+
869+static const char *x86emu_fpu_op_df_tab[] = {
870+ /* mod == 00 */
871+ "FILD\tWORD PTR ", "ESC_DF\t39\n", "FIST\tWORD PTR ", "FISTP\tWORD PTR ",
872+ "FBLD\tTBYTE PTR ", "FILD\tQWORD PTR ", "FBSTP\tTBYTE PTR ",
873+ "FISTP\tQWORD PTR ",
874+
875+ /* mod == 01 */
876+ "FILD\tWORD PTR ", "ESC_DF\t39 ", "FIST\tWORD PTR ", "FISTP\tWORD PTR ",
877+ "FBLD\tTBYTE PTR ", "FILD\tQWORD PTR ", "FBSTP\tTBYTE PTR ",
878+ "FISTP\tQWORD PTR ",
879+
880+ /* mod == 10 */
881+ "FILD\tWORD PTR ", "ESC_DF\t39 ", "FIST\tWORD PTR ", "FISTP\tWORD PTR ",
882+ "FBLD\tTBYTE PTR ", "FILD\tQWORD PTR ", "FBSTP\tTBYTE PTR ",
883+ "FISTP\tQWORD PTR ",
884+
885+ /* mod == 11 */
886+ "FFREE\t", "FXCH\t", "FST\t", "FSTP\t",
887+ "ESC_DF\t3C,", "ESC_DF\t3D,", "ESC_DF\t3E,", "ESC_DF\t3F,"
888+};
889+
890+#endif /* DEBUG */
891+
892+/* opcode=0xdf */
893+void
894+x86emuOp_esc_coprocess_df(u8 X86EMU_UNUSED(op1))
895+{
896+ int mod, rl, rh;
897+ uint destoffset = 0;
898+ u8 stkelem = 0;
899+
900+ START_OF_INSTR();
901+ FETCH_DECODE_MODRM(mod, rh, rl);
902+ DECODE_PRINTINSTR32(x86emu_fpu_op_df_tab, mod, rh, rl);
903+ switch (mod) {
904+ case 0:
905+ destoffset = decode_rm00_address(rl);
906+ DECODE_PRINTF("\n");
907+ break;
908+ case 1:
909+ destoffset = decode_rm01_address(rl);
910+ DECODE_PRINTF("\n");
911+ break;
912+ case 2:
913+ destoffset = decode_rm10_address(rl);
914+ DECODE_PRINTF("\n");
915+ break;
916+ case 3: /* register to register */
917+ stkelem = (u8) rl;
918+ DECODE_PRINTF2("\tST(%d)\n", stkelem);
919+ break;
920+ }
921+#ifdef X86EMU_FPU_PRESENT
922+ switch (mod) {
923+ case 3:
924+ switch (rh) {
925+ case 0:
926+ x86emu_fpu_R_ffree(stkelem);
927+ break;
928+ case 1:
929+ x86emu_fpu_R_fxch(stkelem);
930+ break;
931+ case 2:
932+ x86emu_fpu_R_fst(stkelem); /* register version */
933+ break;
934+ case 3:
935+ x86emu_fpu_R_fstp(stkelem); /* register version */
936+ break;
937+ default:
938+ x86emu_fpu_illegal();
939+ break;
940+ }
941+ break;
942+ default:
943+ switch (rh) {
944+ case 0:
945+ x86emu_fpu_M_fild(X86EMU_FPU_WORD, destoffset);
946+ break;
947+ case 1:
948+ x86emu_fpu_illegal();
949+ break;
950+ case 2:
951+ x86emu_fpu_M_fist(X86EMU_FPU_WORD, destoffset);
952+ break;
953+ case 3:
954+ x86emu_fpu_M_fistp(X86EMU_FPU_WORD, destoffset);
955+ break;
956+ case 4:
957+ x86emu_fpu_M_fbld(X86EMU_FPU_BSD, destoffset);
958+ break;
959+ case 5:
960+ x86emu_fpu_M_fild(X86EMU_FPU_LONG, destoffset);
961+ break;
962+ case 6:
963+ x86emu_fpu_M_fbstp(X86EMU_FPU_BSD, destoffset);
964+ break;
965+ case 7:
966+ x86emu_fpu_M_fistp(X86EMU_FPU_LONG, destoffset);
967+ break;
968+ }
969+ }
970+#else
971+ (void) destoffset;
972+ (void) stkelem;
973+#endif
974+ DECODE_CLEAR_SEGOVR();
975+ END_OF_INSTR_NO_TRACE();
976+}
--- /dev/null
+++ b/x86emu/ops.c
@@ -0,0 +1,12307 @@
1+/****************************************************************************
2+*
3+* Realmode X86 Emulator Library
4+*
5+* Copyright (C) 1996-1999 SciTech Software, Inc.
6+* Copyright (C) David Mosberger-Tang
7+* Copyright (C) 1999 Egbert Eich
8+*
9+* ========================================================================
10+*
11+* Permission to use, copy, modify, distribute, and sell this software and
12+* its documentation for any purpose is hereby granted without fee,
13+* provided that the above copyright notice appear in all copies and that
14+* both that copyright notice and this permission notice appear in
15+* supporting documentation, and that the name of the authors not be used
16+* in advertising or publicity pertaining to distribution of the software
17+* without specific, written prior permission. The authors makes no
18+* representations about the suitability of this software for any purpose.
19+* It is provided "as is" without express or implied warranty.
20+*
21+* THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
22+* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
23+* EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
24+* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
25+* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
26+* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
27+* PERFORMANCE OF THIS SOFTWARE.
28+*
29+* ========================================================================
30+*
31+* Language: ANSI C
32+* Environment: Any
33+* Developer: Kendall Bennett
34+*
35+* Description: This file includes subroutines to implement the decoding
36+* and emulation of all the x86 processor instructions.
37+*
38+* There are approximately 250 subroutines in here, which correspond
39+* to the 256 byte-"opcodes" found on the 8086. The table which
40+* dispatches this is found in the files optab.[ch].
41+*
42+* Each opcode proc has a comment preceeding it which gives it's table
43+* address. Several opcodes are missing (undefined) in the table.
44+*
45+* Each proc includes information for decoding (DECODE_PRINTF and
46+* DECODE_PRINTF2), debugging (TRACE_REGS, SINGLE_STEP), and misc
47+* functions (START_OF_INSTR, END_OF_INSTR).
48+*
49+* Many of the procedures are *VERY* similar in coding. This has
50+* allowed for a very large amount of code to be generated in a fairly
51+* short amount of time (i.e. cut, paste, and modify). The result is
52+* that much of the code below could have been folded into subroutines
53+* for a large reduction in size of this file. The downside would be
54+* that there would be a penalty in execution speed. The file could
55+* also have been *MUCH* larger by inlining certain functions which
56+* were called. This could have resulted even faster execution. The
57+* prime directive I used to decide whether to inline the code or to
58+* modularize it, was basically: 1) no unnecessary subroutine calls,
59+* 2) no routines more than about 200 lines in size, and 3) modularize
60+* any code that I might not get right the first time. The fetch_*
61+* subroutines fall into the latter category. The The decode_* fall
62+* into the second category. The coding of the "switch(mod){ .... }"
63+* in many of the subroutines below falls into the first category.
64+* Especially, the coding of {add,and,or,sub,...}_{byte,word}
65+* subroutines are an especially glaring case of the third guideline.
66+* Since so much of the code is cloned from other modules (compare
67+* opcode #00 to opcode #01), making the basic operations subroutine
68+* calls is especially important; otherwise mistakes in coding an
69+* "add" would represent a nightmare in maintenance.
70+*
71+****************************************************************************/
72+
73+#include "x86emu/x86emui.h"
74+
75+/*----------------------------- Implementation ----------------------------*/
76+
77+/****************************************************************************
78+PARAMETERS:
79+op1 - Instruction op code
80+
81+REMARKS:
82+Handles illegal opcodes.
83+****************************************************************************/
84+static void
85+x86emuOp_illegal_op(u8 op1)
86+{
87+ START_OF_INSTR();
88+ if (M.x86.R_SP != 0) {
89+ DECODE_PRINTF("ILLEGAL X86 OPCODE\n");
90+ TRACE_REGS();
91+ DB(printk("%04x:%04x: %02X ILLEGAL X86 OPCODE!\n",
92+ M.x86.R_CS, M.x86.R_IP - 1, op1));
93+ HALT_SYS();
94+ }
95+ else {
96+ /* If we get here, it means the stack pointer is back to zero
97+ * so we are just returning from an emulator service call
98+ * so therte is no need to display an error message. We trap
99+ * the emulator with an 0xF1 opcode to finish the service
100+ * call.
101+ */
102+ X86EMU_halt_sys();
103+ }
104+ END_OF_INSTR();
105+}
106+
107+/****************************************************************************
108+REMARKS:
109+Handles opcode 0x00
110+****************************************************************************/
111+static void
112+x86emuOp_add_byte_RM_R(u8 X86EMU_UNUSED(op1))
113+{
114+ int mod, rl, rh;
115+ uint destoffset;
116+ u8 *destreg, *srcreg;
117+ u8 destval;
118+
119+ START_OF_INSTR();
120+ DECODE_PRINTF("ADD\t");
121+ FETCH_DECODE_MODRM(mod, rh, rl);
122+ switch (mod) {
123+ case 0:
124+ destoffset = decode_rm00_address(rl);
125+ DECODE_PRINTF(",");
126+ destval = fetch_data_byte(destoffset);
127+ srcreg = DECODE_RM_BYTE_REGISTER(rh);
128+ DECODE_PRINTF("\n");
129+ TRACE_AND_STEP();
130+ destval = add_byte(destval, *srcreg);
131+ store_data_byte(destoffset, destval);
132+ break;
133+ case 1:
134+ destoffset = decode_rm01_address(rl);
135+ DECODE_PRINTF(",");
136+ destval = fetch_data_byte(destoffset);
137+ srcreg = DECODE_RM_BYTE_REGISTER(rh);
138+ DECODE_PRINTF("\n");
139+ TRACE_AND_STEP();
140+ destval = add_byte(destval, *srcreg);
141+ store_data_byte(destoffset, destval);
142+ break;
143+ case 2:
144+ destoffset = decode_rm10_address(rl);
145+ DECODE_PRINTF(",");
146+ destval = fetch_data_byte(destoffset);
147+ srcreg = DECODE_RM_BYTE_REGISTER(rh);
148+ DECODE_PRINTF("\n");
149+ TRACE_AND_STEP();
150+ destval = add_byte(destval, *srcreg);
151+ store_data_byte(destoffset, destval);
152+ break;
153+ case 3: /* register to register */
154+ destreg = DECODE_RM_BYTE_REGISTER(rl);
155+ DECODE_PRINTF(",");
156+ srcreg = DECODE_RM_BYTE_REGISTER(rh);
157+ DECODE_PRINTF("\n");
158+ TRACE_AND_STEP();
159+ *destreg = add_byte(*destreg, *srcreg);
160+ break;
161+ }
162+ DECODE_CLEAR_SEGOVR();
163+ END_OF_INSTR();
164+}
165+
166+/****************************************************************************
167+REMARKS:
168+Handles opcode 0x01
169+****************************************************************************/
170+static void
171+x86emuOp_add_word_RM_R(u8 X86EMU_UNUSED(op1))
172+{
173+ int mod, rl, rh;
174+ uint destoffset;
175+
176+ START_OF_INSTR();
177+ DECODE_PRINTF("ADD\t");
178+ FETCH_DECODE_MODRM(mod, rh, rl);
179+ switch (mod) {
180+ case 0:
181+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
182+ u32 destval;
183+ u32 *srcreg;
184+
185+ destoffset = decode_rm00_address(rl);
186+ DECODE_PRINTF(",");
187+ destval = fetch_data_long(destoffset);
188+ srcreg = DECODE_RM_LONG_REGISTER(rh);
189+ DECODE_PRINTF("\n");
190+ TRACE_AND_STEP();
191+ destval = add_long(destval, *srcreg);
192+ store_data_long(destoffset, destval);
193+ }
194+ else {
195+ u16 destval;
196+ u16 *srcreg;
197+
198+ destoffset = decode_rm00_address(rl);
199+ DECODE_PRINTF(",");
200+ destval = fetch_data_word(destoffset);
201+ srcreg = DECODE_RM_WORD_REGISTER(rh);
202+ DECODE_PRINTF("\n");
203+ TRACE_AND_STEP();
204+ destval = add_word(destval, *srcreg);
205+ store_data_word(destoffset, destval);
206+ }
207+ break;
208+ case 1:
209+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
210+ u32 destval;
211+ u32 *srcreg;
212+
213+ destoffset = decode_rm01_address(rl);
214+ DECODE_PRINTF(",");
215+ destval = fetch_data_long(destoffset);
216+ srcreg = DECODE_RM_LONG_REGISTER(rh);
217+ DECODE_PRINTF("\n");
218+ TRACE_AND_STEP();
219+ destval = add_long(destval, *srcreg);
220+ store_data_long(destoffset, destval);
221+ }
222+ else {
223+ u16 destval;
224+ u16 *srcreg;
225+
226+ destoffset = decode_rm01_address(rl);
227+ DECODE_PRINTF(",");
228+ destval = fetch_data_word(destoffset);
229+ srcreg = DECODE_RM_WORD_REGISTER(rh);
230+ DECODE_PRINTF("\n");
231+ TRACE_AND_STEP();
232+ destval = add_word(destval, *srcreg);
233+ store_data_word(destoffset, destval);
234+ }
235+ break;
236+ case 2:
237+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
238+ u32 destval;
239+ u32 *srcreg;
240+
241+ destoffset = decode_rm10_address(rl);
242+ DECODE_PRINTF(",");
243+ destval = fetch_data_long(destoffset);
244+ srcreg = DECODE_RM_LONG_REGISTER(rh);
245+ DECODE_PRINTF("\n");
246+ TRACE_AND_STEP();
247+ destval = add_long(destval, *srcreg);
248+ store_data_long(destoffset, destval);
249+ }
250+ else {
251+ u16 destval;
252+ u16 *srcreg;
253+
254+ destoffset = decode_rm10_address(rl);
255+ DECODE_PRINTF(",");
256+ destval = fetch_data_word(destoffset);
257+ srcreg = DECODE_RM_WORD_REGISTER(rh);
258+ DECODE_PRINTF("\n");
259+ TRACE_AND_STEP();
260+ destval = add_word(destval, *srcreg);
261+ store_data_word(destoffset, destval);
262+ }
263+ break;
264+ case 3: /* register to register */
265+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
266+ u32 *destreg, *srcreg;
267+
268+ destreg = DECODE_RM_LONG_REGISTER(rl);
269+ DECODE_PRINTF(",");
270+ srcreg = DECODE_RM_LONG_REGISTER(rh);
271+ DECODE_PRINTF("\n");
272+ TRACE_AND_STEP();
273+ *destreg = add_long(*destreg, *srcreg);
274+ }
275+ else {
276+ u16 *destreg, *srcreg;
277+
278+ destreg = DECODE_RM_WORD_REGISTER(rl);
279+ DECODE_PRINTF(",");
280+ srcreg = DECODE_RM_WORD_REGISTER(rh);
281+ DECODE_PRINTF("\n");
282+ TRACE_AND_STEP();
283+ *destreg = add_word(*destreg, *srcreg);
284+ }
285+ break;
286+ }
287+ DECODE_CLEAR_SEGOVR();
288+ END_OF_INSTR();
289+}
290+
291+/****************************************************************************
292+REMARKS:
293+Handles opcode 0x02
294+****************************************************************************/
295+static void
296+x86emuOp_add_byte_R_RM(u8 X86EMU_UNUSED(op1))
297+{
298+ int mod, rl, rh;
299+ u8 *destreg, *srcreg;
300+ uint srcoffset;
301+ u8 srcval;
302+
303+ START_OF_INSTR();
304+ DECODE_PRINTF("ADD\t");
305+ FETCH_DECODE_MODRM(mod, rh, rl);
306+ switch (mod) {
307+ case 0:
308+ destreg = DECODE_RM_BYTE_REGISTER(rh);
309+ DECODE_PRINTF(",");
310+ srcoffset = decode_rm00_address(rl);
311+ srcval = fetch_data_byte(srcoffset);
312+ DECODE_PRINTF("\n");
313+ TRACE_AND_STEP();
314+ *destreg = add_byte(*destreg, srcval);
315+ break;
316+ case 1:
317+ destreg = DECODE_RM_BYTE_REGISTER(rh);
318+ DECODE_PRINTF(",");
319+ srcoffset = decode_rm01_address(rl);
320+ srcval = fetch_data_byte(srcoffset);
321+ DECODE_PRINTF("\n");
322+ TRACE_AND_STEP();
323+ *destreg = add_byte(*destreg, srcval);
324+ break;
325+ case 2:
326+ destreg = DECODE_RM_BYTE_REGISTER(rh);
327+ DECODE_PRINTF(",");
328+ srcoffset = decode_rm10_address(rl);
329+ srcval = fetch_data_byte(srcoffset);
330+ DECODE_PRINTF("\n");
331+ TRACE_AND_STEP();
332+ *destreg = add_byte(*destreg, srcval);
333+ break;
334+ case 3: /* register to register */
335+ destreg = DECODE_RM_BYTE_REGISTER(rh);
336+ DECODE_PRINTF(",");
337+ srcreg = DECODE_RM_BYTE_REGISTER(rl);
338+ DECODE_PRINTF("\n");
339+ TRACE_AND_STEP();
340+ *destreg = add_byte(*destreg, *srcreg);
341+ break;
342+ }
343+ DECODE_CLEAR_SEGOVR();
344+ END_OF_INSTR();
345+}
346+
347+/****************************************************************************
348+REMARKS:
349+Handles opcode 0x03
350+****************************************************************************/
351+static void
352+x86emuOp_add_word_R_RM(u8 X86EMU_UNUSED(op1))
353+{
354+ int mod, rl, rh;
355+ uint srcoffset;
356+
357+ START_OF_INSTR();
358+ DECODE_PRINTF("ADD\t");
359+ FETCH_DECODE_MODRM(mod, rh, rl);
360+ switch (mod) {
361+ case 0:
362+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
363+ u32 *destreg;
364+ u32 srcval;
365+
366+ destreg = DECODE_RM_LONG_REGISTER(rh);
367+ DECODE_PRINTF(",");
368+ srcoffset = decode_rm00_address(rl);
369+ srcval = fetch_data_long(srcoffset);
370+ DECODE_PRINTF("\n");
371+ TRACE_AND_STEP();
372+ *destreg = add_long(*destreg, srcval);
373+ }
374+ else {
375+ u16 *destreg;
376+ u16 srcval;
377+
378+ destreg = DECODE_RM_WORD_REGISTER(rh);
379+ DECODE_PRINTF(",");
380+ srcoffset = decode_rm00_address(rl);
381+ srcval = fetch_data_word(srcoffset);
382+ DECODE_PRINTF("\n");
383+ TRACE_AND_STEP();
384+ *destreg = add_word(*destreg, srcval);
385+ }
386+ break;
387+ case 1:
388+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
389+ u32 *destreg;
390+ u32 srcval;
391+
392+ destreg = DECODE_RM_LONG_REGISTER(rh);
393+ DECODE_PRINTF(",");
394+ srcoffset = decode_rm01_address(rl);
395+ srcval = fetch_data_long(srcoffset);
396+ DECODE_PRINTF("\n");
397+ TRACE_AND_STEP();
398+ *destreg = add_long(*destreg, srcval);
399+ }
400+ else {
401+ u16 *destreg;
402+ u16 srcval;
403+
404+ destreg = DECODE_RM_WORD_REGISTER(rh);
405+ DECODE_PRINTF(",");
406+ srcoffset = decode_rm01_address(rl);
407+ srcval = fetch_data_word(srcoffset);
408+ DECODE_PRINTF("\n");
409+ TRACE_AND_STEP();
410+ *destreg = add_word(*destreg, srcval);
411+ }
412+ break;
413+ case 2:
414+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
415+ u32 *destreg;
416+ u32 srcval;
417+
418+ destreg = DECODE_RM_LONG_REGISTER(rh);
419+ DECODE_PRINTF(",");
420+ srcoffset = decode_rm10_address(rl);
421+ srcval = fetch_data_long(srcoffset);
422+ DECODE_PRINTF("\n");
423+ TRACE_AND_STEP();
424+ *destreg = add_long(*destreg, srcval);
425+ }
426+ else {
427+ u16 *destreg;
428+ u16 srcval;
429+
430+ destreg = DECODE_RM_WORD_REGISTER(rh);
431+ DECODE_PRINTF(",");
432+ srcoffset = decode_rm10_address(rl);
433+ srcval = fetch_data_word(srcoffset);
434+ DECODE_PRINTF("\n");
435+ TRACE_AND_STEP();
436+ *destreg = add_word(*destreg, srcval);
437+ }
438+ break;
439+ case 3: /* register to register */
440+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
441+ u32 *destreg, *srcreg;
442+
443+ destreg = DECODE_RM_LONG_REGISTER(rh);
444+ DECODE_PRINTF(",");
445+ srcreg = DECODE_RM_LONG_REGISTER(rl);
446+ DECODE_PRINTF("\n");
447+ TRACE_AND_STEP();
448+ *destreg = add_long(*destreg, *srcreg);
449+ }
450+ else {
451+ u16 *destreg, *srcreg;
452+
453+ destreg = DECODE_RM_WORD_REGISTER(rh);
454+ DECODE_PRINTF(",");
455+ srcreg = DECODE_RM_WORD_REGISTER(rl);
456+ DECODE_PRINTF("\n");
457+ TRACE_AND_STEP();
458+ *destreg = add_word(*destreg, *srcreg);
459+ }
460+ break;
461+ }
462+ DECODE_CLEAR_SEGOVR();
463+ END_OF_INSTR();
464+}
465+
466+/****************************************************************************
467+REMARKS:
468+Handles opcode 0x04
469+****************************************************************************/
470+static void
471+x86emuOp_add_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
472+{
473+ u8 srcval;
474+
475+ START_OF_INSTR();
476+ DECODE_PRINTF("ADD\tAL,");
477+ srcval = fetch_byte_imm();
478+ DECODE_PRINTF2("%x\n", srcval);
479+ TRACE_AND_STEP();
480+ M.x86.R_AL = add_byte(M.x86.R_AL, srcval);
481+ DECODE_CLEAR_SEGOVR();
482+ END_OF_INSTR();
483+}
484+
485+/****************************************************************************
486+REMARKS:
487+Handles opcode 0x05
488+****************************************************************************/
489+static void
490+x86emuOp_add_word_AX_IMM(u8 X86EMU_UNUSED(op1))
491+{
492+ u32 srcval;
493+
494+ START_OF_INSTR();
495+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
496+ DECODE_PRINTF("ADD\tEAX,");
497+ srcval = fetch_long_imm();
498+ }
499+ else {
500+ DECODE_PRINTF("ADD\tAX,");
501+ srcval = fetch_word_imm();
502+ }
503+ DECODE_PRINTF2("%x\n", srcval);
504+ TRACE_AND_STEP();
505+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
506+ M.x86.R_EAX = add_long(M.x86.R_EAX, srcval);
507+ }
508+ else {
509+ M.x86.R_AX = add_word(M.x86.R_AX, (u16) srcval);
510+ }
511+ DECODE_CLEAR_SEGOVR();
512+ END_OF_INSTR();
513+}
514+
515+/****************************************************************************
516+REMARKS:
517+Handles opcode 0x06
518+****************************************************************************/
519+static void
520+x86emuOp_push_ES(u8 X86EMU_UNUSED(op1))
521+{
522+ START_OF_INSTR();
523+ DECODE_PRINTF("PUSH\tES\n");
524+ TRACE_AND_STEP();
525+ push_word(M.x86.R_ES);
526+ DECODE_CLEAR_SEGOVR();
527+ END_OF_INSTR();
528+}
529+
530+/****************************************************************************
531+REMARKS:
532+Handles opcode 0x07
533+****************************************************************************/
534+static void
535+x86emuOp_pop_ES(u8 X86EMU_UNUSED(op1))
536+{
537+ START_OF_INSTR();
538+ DECODE_PRINTF("POP\tES\n");
539+ TRACE_AND_STEP();
540+ M.x86.R_ES = pop_word();
541+ DECODE_CLEAR_SEGOVR();
542+ END_OF_INSTR();
543+}
544+
545+/****************************************************************************
546+REMARKS:
547+Handles opcode 0x08
548+****************************************************************************/
549+static void
550+x86emuOp_or_byte_RM_R(u8 X86EMU_UNUSED(op1))
551+{
552+ int mod, rl, rh;
553+ u8 *destreg, *srcreg;
554+ uint destoffset;
555+ u8 destval;
556+
557+ START_OF_INSTR();
558+ DECODE_PRINTF("OR\t");
559+ FETCH_DECODE_MODRM(mod, rh, rl);
560+ switch (mod) {
561+ case 0:
562+ destoffset = decode_rm00_address(rl);
563+ DECODE_PRINTF(",");
564+ destval = fetch_data_byte(destoffset);
565+ srcreg = DECODE_RM_BYTE_REGISTER(rh);
566+ DECODE_PRINTF("\n");
567+ TRACE_AND_STEP();
568+ destval = or_byte(destval, *srcreg);
569+ store_data_byte(destoffset, destval);
570+ break;
571+ case 1:
572+ destoffset = decode_rm01_address(rl);
573+ DECODE_PRINTF(",");
574+ destval = fetch_data_byte(destoffset);
575+ srcreg = DECODE_RM_BYTE_REGISTER(rh);
576+ DECODE_PRINTF("\n");
577+ TRACE_AND_STEP();
578+ destval = or_byte(destval, *srcreg);
579+ store_data_byte(destoffset, destval);
580+ break;
581+ case 2:
582+ destoffset = decode_rm10_address(rl);
583+ DECODE_PRINTF(",");
584+ destval = fetch_data_byte(destoffset);
585+ srcreg = DECODE_RM_BYTE_REGISTER(rh);
586+ DECODE_PRINTF("\n");
587+ TRACE_AND_STEP();
588+ destval = or_byte(destval, *srcreg);
589+ store_data_byte(destoffset, destval);
590+ break;
591+ case 3: /* register to register */
592+ destreg = DECODE_RM_BYTE_REGISTER(rl);
593+ DECODE_PRINTF(",");
594+ srcreg = DECODE_RM_BYTE_REGISTER(rh);
595+ DECODE_PRINTF("\n");
596+ TRACE_AND_STEP();
597+ *destreg = or_byte(*destreg, *srcreg);
598+ break;
599+ }
600+ DECODE_CLEAR_SEGOVR();
601+ END_OF_INSTR();
602+}
603+
604+/****************************************************************************
605+REMARKS:
606+Handles opcode 0x09
607+****************************************************************************/
608+static void
609+x86emuOp_or_word_RM_R(u8 X86EMU_UNUSED(op1))
610+{
611+ int mod, rl, rh;
612+ uint destoffset;
613+
614+ START_OF_INSTR();
615+ DECODE_PRINTF("OR\t");
616+ FETCH_DECODE_MODRM(mod, rh, rl);
617+ switch (mod) {
618+ case 0:
619+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
620+ u32 destval;
621+ u32 *srcreg;
622+
623+ destoffset = decode_rm00_address(rl);
624+ DECODE_PRINTF(",");
625+ destval = fetch_data_long(destoffset);
626+ srcreg = DECODE_RM_LONG_REGISTER(rh);
627+ DECODE_PRINTF("\n");
628+ TRACE_AND_STEP();
629+ destval = or_long(destval, *srcreg);
630+ store_data_long(destoffset, destval);
631+ }
632+ else {
633+ u16 destval;
634+ u16 *srcreg;
635+
636+ destoffset = decode_rm00_address(rl);
637+ DECODE_PRINTF(",");
638+ destval = fetch_data_word(destoffset);
639+ srcreg = DECODE_RM_WORD_REGISTER(rh);
640+ DECODE_PRINTF("\n");
641+ TRACE_AND_STEP();
642+ destval = or_word(destval, *srcreg);
643+ store_data_word(destoffset, destval);
644+ }
645+ break;
646+ case 1:
647+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
648+ u32 destval;
649+ u32 *srcreg;
650+
651+ destoffset = decode_rm01_address(rl);
652+ DECODE_PRINTF(",");
653+ destval = fetch_data_long(destoffset);
654+ srcreg = DECODE_RM_LONG_REGISTER(rh);
655+ DECODE_PRINTF("\n");
656+ TRACE_AND_STEP();
657+ destval = or_long(destval, *srcreg);
658+ store_data_long(destoffset, destval);
659+ }
660+ else {
661+ u16 destval;
662+ u16 *srcreg;
663+
664+ destoffset = decode_rm01_address(rl);
665+ DECODE_PRINTF(",");
666+ destval = fetch_data_word(destoffset);
667+ srcreg = DECODE_RM_WORD_REGISTER(rh);
668+ DECODE_PRINTF("\n");
669+ TRACE_AND_STEP();
670+ destval = or_word(destval, *srcreg);
671+ store_data_word(destoffset, destval);
672+ }
673+ break;
674+ case 2:
675+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
676+ u32 destval;
677+ u32 *srcreg;
678+
679+ destoffset = decode_rm10_address(rl);
680+ DECODE_PRINTF(",");
681+ destval = fetch_data_long(destoffset);
682+ srcreg = DECODE_RM_LONG_REGISTER(rh);
683+ DECODE_PRINTF("\n");
684+ TRACE_AND_STEP();
685+ destval = or_long(destval, *srcreg);
686+ store_data_long(destoffset, destval);
687+ }
688+ else {
689+ u16 destval;
690+ u16 *srcreg;
691+
692+ destoffset = decode_rm10_address(rl);
693+ DECODE_PRINTF(",");
694+ destval = fetch_data_word(destoffset);
695+ srcreg = DECODE_RM_WORD_REGISTER(rh);
696+ DECODE_PRINTF("\n");
697+ TRACE_AND_STEP();
698+ destval = or_word(destval, *srcreg);
699+ store_data_word(destoffset, destval);
700+ }
701+ break;
702+ case 3: /* register to register */
703+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
704+ u32 *destreg, *srcreg;
705+
706+ destreg = DECODE_RM_LONG_REGISTER(rl);
707+ DECODE_PRINTF(",");
708+ srcreg = DECODE_RM_LONG_REGISTER(rh);
709+ DECODE_PRINTF("\n");
710+ TRACE_AND_STEP();
711+ *destreg = or_long(*destreg, *srcreg);
712+ }
713+ else {
714+ u16 *destreg, *srcreg;
715+
716+ destreg = DECODE_RM_WORD_REGISTER(rl);
717+ DECODE_PRINTF(",");
718+ srcreg = DECODE_RM_WORD_REGISTER(rh);
719+ DECODE_PRINTF("\n");
720+ TRACE_AND_STEP();
721+ *destreg = or_word(*destreg, *srcreg);
722+ }
723+ break;
724+ }
725+ DECODE_CLEAR_SEGOVR();
726+ END_OF_INSTR();
727+}
728+
729+/****************************************************************************
730+REMARKS:
731+Handles opcode 0x0a
732+****************************************************************************/
733+static void
734+x86emuOp_or_byte_R_RM(u8 X86EMU_UNUSED(op1))
735+{
736+ int mod, rl, rh;
737+ u8 *destreg, *srcreg;
738+ uint srcoffset;
739+ u8 srcval;
740+
741+ START_OF_INSTR();
742+ DECODE_PRINTF("OR\t");
743+ FETCH_DECODE_MODRM(mod, rh, rl);
744+ switch (mod) {
745+ case 0:
746+ destreg = DECODE_RM_BYTE_REGISTER(rh);
747+ DECODE_PRINTF(",");
748+ srcoffset = decode_rm00_address(rl);
749+ srcval = fetch_data_byte(srcoffset);
750+ DECODE_PRINTF("\n");
751+ TRACE_AND_STEP();
752+ *destreg = or_byte(*destreg, srcval);
753+ break;
754+ case 1:
755+ destreg = DECODE_RM_BYTE_REGISTER(rh);
756+ DECODE_PRINTF(",");
757+ srcoffset = decode_rm01_address(rl);
758+ srcval = fetch_data_byte(srcoffset);
759+ DECODE_PRINTF("\n");
760+ TRACE_AND_STEP();
761+ *destreg = or_byte(*destreg, srcval);
762+ break;
763+ case 2:
764+ destreg = DECODE_RM_BYTE_REGISTER(rh);
765+ DECODE_PRINTF(",");
766+ srcoffset = decode_rm10_address(rl);
767+ srcval = fetch_data_byte(srcoffset);
768+ DECODE_PRINTF("\n");
769+ TRACE_AND_STEP();
770+ *destreg = or_byte(*destreg, srcval);
771+ break;
772+ case 3: /* register to register */
773+ destreg = DECODE_RM_BYTE_REGISTER(rh);
774+ DECODE_PRINTF(",");
775+ srcreg = DECODE_RM_BYTE_REGISTER(rl);
776+ DECODE_PRINTF("\n");
777+ TRACE_AND_STEP();
778+ *destreg = or_byte(*destreg, *srcreg);
779+ break;
780+ }
781+ DECODE_CLEAR_SEGOVR();
782+ END_OF_INSTR();
783+}
784+
785+/****************************************************************************
786+REMARKS:
787+Handles opcode 0x0b
788+****************************************************************************/
789+static void
790+x86emuOp_or_word_R_RM(u8 X86EMU_UNUSED(op1))
791+{
792+ int mod, rl, rh;
793+ uint srcoffset;
794+
795+ START_OF_INSTR();
796+ DECODE_PRINTF("OR\t");
797+ FETCH_DECODE_MODRM(mod, rh, rl);
798+ switch (mod) {
799+ case 0:
800+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
801+ u32 *destreg;
802+ u32 srcval;
803+
804+ destreg = DECODE_RM_LONG_REGISTER(rh);
805+ DECODE_PRINTF(",");
806+ srcoffset = decode_rm00_address(rl);
807+ srcval = fetch_data_long(srcoffset);
808+ DECODE_PRINTF("\n");
809+ TRACE_AND_STEP();
810+ *destreg = or_long(*destreg, srcval);
811+ }
812+ else {
813+ u16 *destreg;
814+ u16 srcval;
815+
816+ destreg = DECODE_RM_WORD_REGISTER(rh);
817+ DECODE_PRINTF(",");
818+ srcoffset = decode_rm00_address(rl);
819+ srcval = fetch_data_word(srcoffset);
820+ DECODE_PRINTF("\n");
821+ TRACE_AND_STEP();
822+ *destreg = or_word(*destreg, srcval);
823+ }
824+ break;
825+ case 1:
826+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
827+ u32 *destreg;
828+ u32 srcval;
829+
830+ destreg = DECODE_RM_LONG_REGISTER(rh);
831+ DECODE_PRINTF(",");
832+ srcoffset = decode_rm01_address(rl);
833+ srcval = fetch_data_long(srcoffset);
834+ DECODE_PRINTF("\n");
835+ TRACE_AND_STEP();
836+ *destreg = or_long(*destreg, srcval);
837+ }
838+ else {
839+ u16 *destreg;
840+ u16 srcval;
841+
842+ destreg = DECODE_RM_WORD_REGISTER(rh);
843+ DECODE_PRINTF(",");
844+ srcoffset = decode_rm01_address(rl);
845+ srcval = fetch_data_word(srcoffset);
846+ DECODE_PRINTF("\n");
847+ TRACE_AND_STEP();
848+ *destreg = or_word(*destreg, srcval);
849+ }
850+ break;
851+ case 2:
852+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
853+ u32 *destreg;
854+ u32 srcval;
855+
856+ destreg = DECODE_RM_LONG_REGISTER(rh);
857+ DECODE_PRINTF(",");
858+ srcoffset = decode_rm10_address(rl);
859+ srcval = fetch_data_long(srcoffset);
860+ DECODE_PRINTF("\n");
861+ TRACE_AND_STEP();
862+ *destreg = or_long(*destreg, srcval);
863+ }
864+ else {
865+ u16 *destreg;
866+ u16 srcval;
867+
868+ destreg = DECODE_RM_WORD_REGISTER(rh);
869+ DECODE_PRINTF(",");
870+ srcoffset = decode_rm10_address(rl);
871+ srcval = fetch_data_word(srcoffset);
872+ DECODE_PRINTF("\n");
873+ TRACE_AND_STEP();
874+ *destreg = or_word(*destreg, srcval);
875+ }
876+ break;
877+ case 3: /* register to register */
878+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
879+ u32 *destreg, *srcreg;
880+
881+ destreg = DECODE_RM_LONG_REGISTER(rh);
882+ DECODE_PRINTF(",");
883+ srcreg = DECODE_RM_LONG_REGISTER(rl);
884+ DECODE_PRINTF("\n");
885+ TRACE_AND_STEP();
886+ *destreg = or_long(*destreg, *srcreg);
887+ }
888+ else {
889+ u16 *destreg, *srcreg;
890+
891+ destreg = DECODE_RM_WORD_REGISTER(rh);
892+ DECODE_PRINTF(",");
893+ srcreg = DECODE_RM_WORD_REGISTER(rl);
894+ DECODE_PRINTF("\n");
895+ TRACE_AND_STEP();
896+ *destreg = or_word(*destreg, *srcreg);
897+ }
898+ break;
899+ }
900+ DECODE_CLEAR_SEGOVR();
901+ END_OF_INSTR();
902+}
903+
904+/****************************************************************************
905+REMARKS:
906+Handles opcode 0x0c
907+****************************************************************************/
908+static void
909+x86emuOp_or_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
910+{
911+ u8 srcval;
912+
913+ START_OF_INSTR();
914+ DECODE_PRINTF("OR\tAL,");
915+ srcval = fetch_byte_imm();
916+ DECODE_PRINTF2("%x\n", srcval);
917+ TRACE_AND_STEP();
918+ M.x86.R_AL = or_byte(M.x86.R_AL, srcval);
919+ DECODE_CLEAR_SEGOVR();
920+ END_OF_INSTR();
921+}
922+
923+/****************************************************************************
924+REMARKS:
925+Handles opcode 0x0d
926+****************************************************************************/
927+static void
928+x86emuOp_or_word_AX_IMM(u8 X86EMU_UNUSED(op1))
929+{
930+ u32 srcval;
931+
932+ START_OF_INSTR();
933+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
934+ DECODE_PRINTF("OR\tEAX,");
935+ srcval = fetch_long_imm();
936+ }
937+ else {
938+ DECODE_PRINTF("OR\tAX,");
939+ srcval = fetch_word_imm();
940+ }
941+ DECODE_PRINTF2("%x\n", srcval);
942+ TRACE_AND_STEP();
943+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
944+ M.x86.R_EAX = or_long(M.x86.R_EAX, srcval);
945+ }
946+ else {
947+ M.x86.R_AX = or_word(M.x86.R_AX, (u16) srcval);
948+ }
949+ DECODE_CLEAR_SEGOVR();
950+ END_OF_INSTR();
951+}
952+
953+/****************************************************************************
954+REMARKS:
955+Handles opcode 0x0e
956+****************************************************************************/
957+static void
958+x86emuOp_push_CS(u8 X86EMU_UNUSED(op1))
959+{
960+ START_OF_INSTR();
961+ DECODE_PRINTF("PUSH\tCS\n");
962+ TRACE_AND_STEP();
963+ push_word(M.x86.R_CS);
964+ DECODE_CLEAR_SEGOVR();
965+ END_OF_INSTR();
966+}
967+
968+/****************************************************************************
969+REMARKS:
970+Handles opcode 0x0f. Escape for two-byte opcode (286 or better)
971+****************************************************************************/
972+static void
973+x86emuOp_two_byte(u8 X86EMU_UNUSED(op1))
974+{
975+ u8 op2 = (*sys_rdb) (((u32) M.x86.R_CS << 4) + (M.x86.R_IP++));
976+
977+ INC_DECODED_INST_LEN(1);
978+ (*x86emu_optab2[op2]) (op2);
979+}
980+
981+/****************************************************************************
982+REMARKS:
983+Handles opcode 0x10
984+****************************************************************************/
985+static void
986+x86emuOp_adc_byte_RM_R(u8 X86EMU_UNUSED(op1))
987+{
988+ int mod, rl, rh;
989+ u8 *destreg, *srcreg;
990+ uint destoffset;
991+ u8 destval;
992+
993+ START_OF_INSTR();
994+ DECODE_PRINTF("ADC\t");
995+ FETCH_DECODE_MODRM(mod, rh, rl);
996+ switch (mod) {
997+ case 0:
998+ destoffset = decode_rm00_address(rl);
999+ DECODE_PRINTF(",");
1000+ destval = fetch_data_byte(destoffset);
1001+ srcreg = DECODE_RM_BYTE_REGISTER(rh);
1002+ DECODE_PRINTF("\n");
1003+ TRACE_AND_STEP();
1004+ destval = adc_byte(destval, *srcreg);
1005+ store_data_byte(destoffset, destval);
1006+ break;
1007+ case 1:
1008+ destoffset = decode_rm01_address(rl);
1009+ DECODE_PRINTF(",");
1010+ destval = fetch_data_byte(destoffset);
1011+ srcreg = DECODE_RM_BYTE_REGISTER(rh);
1012+ DECODE_PRINTF("\n");
1013+ TRACE_AND_STEP();
1014+ destval = adc_byte(destval, *srcreg);
1015+ store_data_byte(destoffset, destval);
1016+ break;
1017+ case 2:
1018+ destoffset = decode_rm10_address(rl);
1019+ DECODE_PRINTF(",");
1020+ destval = fetch_data_byte(destoffset);
1021+ srcreg = DECODE_RM_BYTE_REGISTER(rh);
1022+ DECODE_PRINTF("\n");
1023+ TRACE_AND_STEP();
1024+ destval = adc_byte(destval, *srcreg);
1025+ store_data_byte(destoffset, destval);
1026+ break;
1027+ case 3: /* register to register */
1028+ destreg = DECODE_RM_BYTE_REGISTER(rl);
1029+ DECODE_PRINTF(",");
1030+ srcreg = DECODE_RM_BYTE_REGISTER(rh);
1031+ DECODE_PRINTF("\n");
1032+ TRACE_AND_STEP();
1033+ *destreg = adc_byte(*destreg, *srcreg);
1034+ break;
1035+ }
1036+ DECODE_CLEAR_SEGOVR();
1037+ END_OF_INSTR();
1038+}
1039+
1040+/****************************************************************************
1041+REMARKS:
1042+Handles opcode 0x11
1043+****************************************************************************/
1044+static void
1045+x86emuOp_adc_word_RM_R(u8 X86EMU_UNUSED(op1))
1046+{
1047+ int mod, rl, rh;
1048+ uint destoffset;
1049+
1050+ START_OF_INSTR();
1051+ DECODE_PRINTF("ADC\t");
1052+ FETCH_DECODE_MODRM(mod, rh, rl);
1053+ switch (mod) {
1054+ case 0:
1055+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1056+ u32 destval;
1057+ u32 *srcreg;
1058+
1059+ destoffset = decode_rm00_address(rl);
1060+ DECODE_PRINTF(",");
1061+ destval = fetch_data_long(destoffset);
1062+ srcreg = DECODE_RM_LONG_REGISTER(rh);
1063+ DECODE_PRINTF("\n");
1064+ TRACE_AND_STEP();
1065+ destval = adc_long(destval, *srcreg);
1066+ store_data_long(destoffset, destval);
1067+ }
1068+ else {
1069+ u16 destval;
1070+ u16 *srcreg;
1071+
1072+ destoffset = decode_rm00_address(rl);
1073+ DECODE_PRINTF(",");
1074+ destval = fetch_data_word(destoffset);
1075+ srcreg = DECODE_RM_WORD_REGISTER(rh);
1076+ DECODE_PRINTF("\n");
1077+ TRACE_AND_STEP();
1078+ destval = adc_word(destval, *srcreg);
1079+ store_data_word(destoffset, destval);
1080+ }
1081+ break;
1082+ case 1:
1083+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1084+ u32 destval;
1085+ u32 *srcreg;
1086+
1087+ destoffset = decode_rm01_address(rl);
1088+ DECODE_PRINTF(",");
1089+ destval = fetch_data_long(destoffset);
1090+ srcreg = DECODE_RM_LONG_REGISTER(rh);
1091+ DECODE_PRINTF("\n");
1092+ TRACE_AND_STEP();
1093+ destval = adc_long(destval, *srcreg);
1094+ store_data_long(destoffset, destval);
1095+ }
1096+ else {
1097+ u16 destval;
1098+ u16 *srcreg;
1099+
1100+ destoffset = decode_rm01_address(rl);
1101+ DECODE_PRINTF(",");
1102+ destval = fetch_data_word(destoffset);
1103+ srcreg = DECODE_RM_WORD_REGISTER(rh);
1104+ DECODE_PRINTF("\n");
1105+ TRACE_AND_STEP();
1106+ destval = adc_word(destval, *srcreg);
1107+ store_data_word(destoffset, destval);
1108+ }
1109+ break;
1110+ case 2:
1111+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1112+ u32 destval;
1113+ u32 *srcreg;
1114+
1115+ destoffset = decode_rm10_address(rl);
1116+ DECODE_PRINTF(",");
1117+ destval = fetch_data_long(destoffset);
1118+ srcreg = DECODE_RM_LONG_REGISTER(rh);
1119+ DECODE_PRINTF("\n");
1120+ TRACE_AND_STEP();
1121+ destval = adc_long(destval, *srcreg);
1122+ store_data_long(destoffset, destval);
1123+ }
1124+ else {
1125+ u16 destval;
1126+ u16 *srcreg;
1127+
1128+ destoffset = decode_rm10_address(rl);
1129+ DECODE_PRINTF(",");
1130+ destval = fetch_data_word(destoffset);
1131+ srcreg = DECODE_RM_WORD_REGISTER(rh);
1132+ DECODE_PRINTF("\n");
1133+ TRACE_AND_STEP();
1134+ destval = adc_word(destval, *srcreg);
1135+ store_data_word(destoffset, destval);
1136+ }
1137+ break;
1138+ case 3: /* register to register */
1139+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1140+ u32 *destreg, *srcreg;
1141+
1142+ destreg = DECODE_RM_LONG_REGISTER(rl);
1143+ DECODE_PRINTF(",");
1144+ srcreg = DECODE_RM_LONG_REGISTER(rh);
1145+ DECODE_PRINTF("\n");
1146+ TRACE_AND_STEP();
1147+ *destreg = adc_long(*destreg, *srcreg);
1148+ }
1149+ else {
1150+ u16 *destreg, *srcreg;
1151+
1152+ destreg = DECODE_RM_WORD_REGISTER(rl);
1153+ DECODE_PRINTF(",");
1154+ srcreg = DECODE_RM_WORD_REGISTER(rh);
1155+ DECODE_PRINTF("\n");
1156+ TRACE_AND_STEP();
1157+ *destreg = adc_word(*destreg, *srcreg);
1158+ }
1159+ break;
1160+ }
1161+ DECODE_CLEAR_SEGOVR();
1162+ END_OF_INSTR();
1163+}
1164+
1165+/****************************************************************************
1166+REMARKS:
1167+Handles opcode 0x12
1168+****************************************************************************/
1169+static void
1170+x86emuOp_adc_byte_R_RM(u8 X86EMU_UNUSED(op1))
1171+{
1172+ int mod, rl, rh;
1173+ u8 *destreg, *srcreg;
1174+ uint srcoffset;
1175+ u8 srcval;
1176+
1177+ START_OF_INSTR();
1178+ DECODE_PRINTF("ADC\t");
1179+ FETCH_DECODE_MODRM(mod, rh, rl);
1180+ switch (mod) {
1181+ case 0:
1182+ destreg = DECODE_RM_BYTE_REGISTER(rh);
1183+ DECODE_PRINTF(",");
1184+ srcoffset = decode_rm00_address(rl);
1185+ srcval = fetch_data_byte(srcoffset);
1186+ DECODE_PRINTF("\n");
1187+ TRACE_AND_STEP();
1188+ *destreg = adc_byte(*destreg, srcval);
1189+ break;
1190+ case 1:
1191+ destreg = DECODE_RM_BYTE_REGISTER(rh);
1192+ DECODE_PRINTF(",");
1193+ srcoffset = decode_rm01_address(rl);
1194+ srcval = fetch_data_byte(srcoffset);
1195+ DECODE_PRINTF("\n");
1196+ TRACE_AND_STEP();
1197+ *destreg = adc_byte(*destreg, srcval);
1198+ break;
1199+ case 2:
1200+ destreg = DECODE_RM_BYTE_REGISTER(rh);
1201+ DECODE_PRINTF(",");
1202+ srcoffset = decode_rm10_address(rl);
1203+ srcval = fetch_data_byte(srcoffset);
1204+ DECODE_PRINTF("\n");
1205+ TRACE_AND_STEP();
1206+ *destreg = adc_byte(*destreg, srcval);
1207+ break;
1208+ case 3: /* register to register */
1209+ destreg = DECODE_RM_BYTE_REGISTER(rh);
1210+ DECODE_PRINTF(",");
1211+ srcreg = DECODE_RM_BYTE_REGISTER(rl);
1212+ DECODE_PRINTF("\n");
1213+ TRACE_AND_STEP();
1214+ *destreg = adc_byte(*destreg, *srcreg);
1215+ break;
1216+ }
1217+ DECODE_CLEAR_SEGOVR();
1218+ END_OF_INSTR();
1219+}
1220+
1221+/****************************************************************************
1222+REMARKS:
1223+Handles opcode 0x13
1224+****************************************************************************/
1225+static void
1226+x86emuOp_adc_word_R_RM(u8 X86EMU_UNUSED(op1))
1227+{
1228+ int mod, rl, rh;
1229+ uint srcoffset;
1230+
1231+ START_OF_INSTR();
1232+ DECODE_PRINTF("ADC\t");
1233+ FETCH_DECODE_MODRM(mod, rh, rl);
1234+ switch (mod) {
1235+ case 0:
1236+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1237+ u32 *destreg;
1238+ u32 srcval;
1239+
1240+ destreg = DECODE_RM_LONG_REGISTER(rh);
1241+ DECODE_PRINTF(",");
1242+ srcoffset = decode_rm00_address(rl);
1243+ srcval = fetch_data_long(srcoffset);
1244+ DECODE_PRINTF("\n");
1245+ TRACE_AND_STEP();
1246+ *destreg = adc_long(*destreg, srcval);
1247+ }
1248+ else {
1249+ u16 *destreg;
1250+ u16 srcval;
1251+
1252+ destreg = DECODE_RM_WORD_REGISTER(rh);
1253+ DECODE_PRINTF(",");
1254+ srcoffset = decode_rm00_address(rl);
1255+ srcval = fetch_data_word(srcoffset);
1256+ DECODE_PRINTF("\n");
1257+ TRACE_AND_STEP();
1258+ *destreg = adc_word(*destreg, srcval);
1259+ }
1260+ break;
1261+ case 1:
1262+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1263+ u32 *destreg;
1264+ u32 srcval;
1265+
1266+ destreg = DECODE_RM_LONG_REGISTER(rh);
1267+ DECODE_PRINTF(",");
1268+ srcoffset = decode_rm01_address(rl);
1269+ srcval = fetch_data_long(srcoffset);
1270+ DECODE_PRINTF("\n");
1271+ TRACE_AND_STEP();
1272+ *destreg = adc_long(*destreg, srcval);
1273+ }
1274+ else {
1275+ u16 *destreg;
1276+ u16 srcval;
1277+
1278+ destreg = DECODE_RM_WORD_REGISTER(rh);
1279+ DECODE_PRINTF(",");
1280+ srcoffset = decode_rm01_address(rl);
1281+ srcval = fetch_data_word(srcoffset);
1282+ DECODE_PRINTF("\n");
1283+ TRACE_AND_STEP();
1284+ *destreg = adc_word(*destreg, srcval);
1285+ }
1286+ break;
1287+ case 2:
1288+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1289+ u32 *destreg;
1290+ u32 srcval;
1291+
1292+ destreg = DECODE_RM_LONG_REGISTER(rh);
1293+ DECODE_PRINTF(",");
1294+ srcoffset = decode_rm10_address(rl);
1295+ srcval = fetch_data_long(srcoffset);
1296+ DECODE_PRINTF("\n");
1297+ TRACE_AND_STEP();
1298+ *destreg = adc_long(*destreg, srcval);
1299+ }
1300+ else {
1301+ u16 *destreg;
1302+ u16 srcval;
1303+
1304+ destreg = DECODE_RM_WORD_REGISTER(rh);
1305+ DECODE_PRINTF(",");
1306+ srcoffset = decode_rm10_address(rl);
1307+ srcval = fetch_data_word(srcoffset);
1308+ DECODE_PRINTF("\n");
1309+ TRACE_AND_STEP();
1310+ *destreg = adc_word(*destreg, srcval);
1311+ }
1312+ break;
1313+ case 3: /* register to register */
1314+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1315+ u32 *destreg, *srcreg;
1316+
1317+ destreg = DECODE_RM_LONG_REGISTER(rh);
1318+ DECODE_PRINTF(",");
1319+ srcreg = DECODE_RM_LONG_REGISTER(rl);
1320+ DECODE_PRINTF("\n");
1321+ TRACE_AND_STEP();
1322+ *destreg = adc_long(*destreg, *srcreg);
1323+ }
1324+ else {
1325+ u16 *destreg, *srcreg;
1326+
1327+ destreg = DECODE_RM_WORD_REGISTER(rh);
1328+ DECODE_PRINTF(",");
1329+ srcreg = DECODE_RM_WORD_REGISTER(rl);
1330+ DECODE_PRINTF("\n");
1331+ TRACE_AND_STEP();
1332+ *destreg = adc_word(*destreg, *srcreg);
1333+ }
1334+ break;
1335+ }
1336+ DECODE_CLEAR_SEGOVR();
1337+ END_OF_INSTR();
1338+}
1339+
1340+/****************************************************************************
1341+REMARKS:
1342+Handles opcode 0x14
1343+****************************************************************************/
1344+static void
1345+x86emuOp_adc_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
1346+{
1347+ u8 srcval;
1348+
1349+ START_OF_INSTR();
1350+ DECODE_PRINTF("ADC\tAL,");
1351+ srcval = fetch_byte_imm();
1352+ DECODE_PRINTF2("%x\n", srcval);
1353+ TRACE_AND_STEP();
1354+ M.x86.R_AL = adc_byte(M.x86.R_AL, srcval);
1355+ DECODE_CLEAR_SEGOVR();
1356+ END_OF_INSTR();
1357+}
1358+
1359+/****************************************************************************
1360+REMARKS:
1361+Handles opcode 0x15
1362+****************************************************************************/
1363+static void
1364+x86emuOp_adc_word_AX_IMM(u8 X86EMU_UNUSED(op1))
1365+{
1366+ u32 srcval;
1367+
1368+ START_OF_INSTR();
1369+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1370+ DECODE_PRINTF("ADC\tEAX,");
1371+ srcval = fetch_long_imm();
1372+ }
1373+ else {
1374+ DECODE_PRINTF("ADC\tAX,");
1375+ srcval = fetch_word_imm();
1376+ }
1377+ DECODE_PRINTF2("%x\n", srcval);
1378+ TRACE_AND_STEP();
1379+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1380+ M.x86.R_EAX = adc_long(M.x86.R_EAX, srcval);
1381+ }
1382+ else {
1383+ M.x86.R_AX = adc_word(M.x86.R_AX, (u16) srcval);
1384+ }
1385+ DECODE_CLEAR_SEGOVR();
1386+ END_OF_INSTR();
1387+}
1388+
1389+/****************************************************************************
1390+REMARKS:
1391+Handles opcode 0x16
1392+****************************************************************************/
1393+static void
1394+x86emuOp_push_SS(u8 X86EMU_UNUSED(op1))
1395+{
1396+ START_OF_INSTR();
1397+ DECODE_PRINTF("PUSH\tSS\n");
1398+ TRACE_AND_STEP();
1399+ push_word(M.x86.R_SS);
1400+ DECODE_CLEAR_SEGOVR();
1401+ END_OF_INSTR();
1402+}
1403+
1404+/****************************************************************************
1405+REMARKS:
1406+Handles opcode 0x17
1407+****************************************************************************/
1408+static void
1409+x86emuOp_pop_SS(u8 X86EMU_UNUSED(op1))
1410+{
1411+ START_OF_INSTR();
1412+ DECODE_PRINTF("POP\tSS\n");
1413+ TRACE_AND_STEP();
1414+ M.x86.R_SS = pop_word();
1415+ DECODE_CLEAR_SEGOVR();
1416+ END_OF_INSTR();
1417+}
1418+
1419+/****************************************************************************
1420+REMARKS:
1421+Handles opcode 0x18
1422+****************************************************************************/
1423+static void
1424+x86emuOp_sbb_byte_RM_R(u8 X86EMU_UNUSED(op1))
1425+{
1426+ int mod, rl, rh;
1427+ u8 *destreg, *srcreg;
1428+ uint destoffset;
1429+ u8 destval;
1430+
1431+ START_OF_INSTR();
1432+ DECODE_PRINTF("SBB\t");
1433+ FETCH_DECODE_MODRM(mod, rh, rl);
1434+ switch (mod) {
1435+ case 0:
1436+ destoffset = decode_rm00_address(rl);
1437+ DECODE_PRINTF(",");
1438+ destval = fetch_data_byte(destoffset);
1439+ srcreg = DECODE_RM_BYTE_REGISTER(rh);
1440+ DECODE_PRINTF("\n");
1441+ TRACE_AND_STEP();
1442+ destval = sbb_byte(destval, *srcreg);
1443+ store_data_byte(destoffset, destval);
1444+ break;
1445+ case 1:
1446+ destoffset = decode_rm01_address(rl);
1447+ DECODE_PRINTF(",");
1448+ destval = fetch_data_byte(destoffset);
1449+ srcreg = DECODE_RM_BYTE_REGISTER(rh);
1450+ DECODE_PRINTF("\n");
1451+ TRACE_AND_STEP();
1452+ destval = sbb_byte(destval, *srcreg);
1453+ store_data_byte(destoffset, destval);
1454+ break;
1455+ case 2:
1456+ destoffset = decode_rm10_address(rl);
1457+ DECODE_PRINTF(",");
1458+ destval = fetch_data_byte(destoffset);
1459+ srcreg = DECODE_RM_BYTE_REGISTER(rh);
1460+ DECODE_PRINTF("\n");
1461+ TRACE_AND_STEP();
1462+ destval = sbb_byte(destval, *srcreg);
1463+ store_data_byte(destoffset, destval);
1464+ break;
1465+ case 3: /* register to register */
1466+ destreg = DECODE_RM_BYTE_REGISTER(rl);
1467+ DECODE_PRINTF(",");
1468+ srcreg = DECODE_RM_BYTE_REGISTER(rh);
1469+ DECODE_PRINTF("\n");
1470+ TRACE_AND_STEP();
1471+ *destreg = sbb_byte(*destreg, *srcreg);
1472+ break;
1473+ }
1474+ DECODE_CLEAR_SEGOVR();
1475+ END_OF_INSTR();
1476+}
1477+
1478+/****************************************************************************
1479+REMARKS:
1480+Handles opcode 0x19
1481+****************************************************************************/
1482+static void
1483+x86emuOp_sbb_word_RM_R(u8 X86EMU_UNUSED(op1))
1484+{
1485+ int mod, rl, rh;
1486+ uint destoffset;
1487+
1488+ START_OF_INSTR();
1489+ DECODE_PRINTF("SBB\t");
1490+ FETCH_DECODE_MODRM(mod, rh, rl);
1491+ switch (mod) {
1492+ case 0:
1493+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1494+ u32 destval;
1495+ u32 *srcreg;
1496+
1497+ destoffset = decode_rm00_address(rl);
1498+ DECODE_PRINTF(",");
1499+ destval = fetch_data_long(destoffset);
1500+ srcreg = DECODE_RM_LONG_REGISTER(rh);
1501+ DECODE_PRINTF("\n");
1502+ TRACE_AND_STEP();
1503+ destval = sbb_long(destval, *srcreg);
1504+ store_data_long(destoffset, destval);
1505+ }
1506+ else {
1507+ u16 destval;
1508+ u16 *srcreg;
1509+
1510+ destoffset = decode_rm00_address(rl);
1511+ DECODE_PRINTF(",");
1512+ destval = fetch_data_word(destoffset);
1513+ srcreg = DECODE_RM_WORD_REGISTER(rh);
1514+ DECODE_PRINTF("\n");
1515+ TRACE_AND_STEP();
1516+ destval = sbb_word(destval, *srcreg);
1517+ store_data_word(destoffset, destval);
1518+ }
1519+ break;
1520+ case 1:
1521+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1522+ u32 destval;
1523+ u32 *srcreg;
1524+
1525+ destoffset = decode_rm01_address(rl);
1526+ DECODE_PRINTF(",");
1527+ destval = fetch_data_long(destoffset);
1528+ srcreg = DECODE_RM_LONG_REGISTER(rh);
1529+ DECODE_PRINTF("\n");
1530+ TRACE_AND_STEP();
1531+ destval = sbb_long(destval, *srcreg);
1532+ store_data_long(destoffset, destval);
1533+ }
1534+ else {
1535+ u16 destval;
1536+ u16 *srcreg;
1537+
1538+ destoffset = decode_rm01_address(rl);
1539+ DECODE_PRINTF(",");
1540+ destval = fetch_data_word(destoffset);
1541+ srcreg = DECODE_RM_WORD_REGISTER(rh);
1542+ DECODE_PRINTF("\n");
1543+ TRACE_AND_STEP();
1544+ destval = sbb_word(destval, *srcreg);
1545+ store_data_word(destoffset, destval);
1546+ }
1547+ break;
1548+ case 2:
1549+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1550+ u32 destval;
1551+ u32 *srcreg;
1552+
1553+ destoffset = decode_rm10_address(rl);
1554+ DECODE_PRINTF(",");
1555+ destval = fetch_data_long(destoffset);
1556+ srcreg = DECODE_RM_LONG_REGISTER(rh);
1557+ DECODE_PRINTF("\n");
1558+ TRACE_AND_STEP();
1559+ destval = sbb_long(destval, *srcreg);
1560+ store_data_long(destoffset, destval);
1561+ }
1562+ else {
1563+ u16 destval;
1564+ u16 *srcreg;
1565+
1566+ destoffset = decode_rm10_address(rl);
1567+ DECODE_PRINTF(",");
1568+ destval = fetch_data_word(destoffset);
1569+ srcreg = DECODE_RM_WORD_REGISTER(rh);
1570+ DECODE_PRINTF("\n");
1571+ TRACE_AND_STEP();
1572+ destval = sbb_word(destval, *srcreg);
1573+ store_data_word(destoffset, destval);
1574+ }
1575+ break;
1576+ case 3: /* register to register */
1577+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1578+ u32 *destreg, *srcreg;
1579+
1580+ destreg = DECODE_RM_LONG_REGISTER(rl);
1581+ DECODE_PRINTF(",");
1582+ srcreg = DECODE_RM_LONG_REGISTER(rh);
1583+ DECODE_PRINTF("\n");
1584+ TRACE_AND_STEP();
1585+ *destreg = sbb_long(*destreg, *srcreg);
1586+ }
1587+ else {
1588+ u16 *destreg, *srcreg;
1589+
1590+ destreg = DECODE_RM_WORD_REGISTER(rl);
1591+ DECODE_PRINTF(",");
1592+ srcreg = DECODE_RM_WORD_REGISTER(rh);
1593+ DECODE_PRINTF("\n");
1594+ TRACE_AND_STEP();
1595+ *destreg = sbb_word(*destreg, *srcreg);
1596+ }
1597+ break;
1598+ }
1599+ DECODE_CLEAR_SEGOVR();
1600+ END_OF_INSTR();
1601+}
1602+
1603+/****************************************************************************
1604+REMARKS:
1605+Handles opcode 0x1a
1606+****************************************************************************/
1607+static void
1608+x86emuOp_sbb_byte_R_RM(u8 X86EMU_UNUSED(op1))
1609+{
1610+ int mod, rl, rh;
1611+ u8 *destreg, *srcreg;
1612+ uint srcoffset;
1613+ u8 srcval;
1614+
1615+ START_OF_INSTR();
1616+ DECODE_PRINTF("SBB\t");
1617+ FETCH_DECODE_MODRM(mod, rh, rl);
1618+ switch (mod) {
1619+ case 0:
1620+ destreg = DECODE_RM_BYTE_REGISTER(rh);
1621+ DECODE_PRINTF(",");
1622+ srcoffset = decode_rm00_address(rl);
1623+ srcval = fetch_data_byte(srcoffset);
1624+ DECODE_PRINTF("\n");
1625+ TRACE_AND_STEP();
1626+ *destreg = sbb_byte(*destreg, srcval);
1627+ break;
1628+ case 1:
1629+ destreg = DECODE_RM_BYTE_REGISTER(rh);
1630+ DECODE_PRINTF(",");
1631+ srcoffset = decode_rm01_address(rl);
1632+ srcval = fetch_data_byte(srcoffset);
1633+ DECODE_PRINTF("\n");
1634+ TRACE_AND_STEP();
1635+ *destreg = sbb_byte(*destreg, srcval);
1636+ break;
1637+ case 2:
1638+ destreg = DECODE_RM_BYTE_REGISTER(rh);
1639+ DECODE_PRINTF(",");
1640+ srcoffset = decode_rm10_address(rl);
1641+ srcval = fetch_data_byte(srcoffset);
1642+ DECODE_PRINTF("\n");
1643+ TRACE_AND_STEP();
1644+ *destreg = sbb_byte(*destreg, srcval);
1645+ break;
1646+ case 3: /* register to register */
1647+ destreg = DECODE_RM_BYTE_REGISTER(rh);
1648+ DECODE_PRINTF(",");
1649+ srcreg = DECODE_RM_BYTE_REGISTER(rl);
1650+ DECODE_PRINTF("\n");
1651+ TRACE_AND_STEP();
1652+ *destreg = sbb_byte(*destreg, *srcreg);
1653+ break;
1654+ }
1655+ DECODE_CLEAR_SEGOVR();
1656+ END_OF_INSTR();
1657+}
1658+
1659+/****************************************************************************
1660+REMARKS:
1661+Handles opcode 0x1b
1662+****************************************************************************/
1663+static void
1664+x86emuOp_sbb_word_R_RM(u8 X86EMU_UNUSED(op1))
1665+{
1666+ int mod, rl, rh;
1667+ uint srcoffset;
1668+
1669+ START_OF_INSTR();
1670+ DECODE_PRINTF("SBB\t");
1671+ FETCH_DECODE_MODRM(mod, rh, rl);
1672+ switch (mod) {
1673+ case 0:
1674+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1675+ u32 *destreg;
1676+ u32 srcval;
1677+
1678+ destreg = DECODE_RM_LONG_REGISTER(rh);
1679+ DECODE_PRINTF(",");
1680+ srcoffset = decode_rm00_address(rl);
1681+ srcval = fetch_data_long(srcoffset);
1682+ DECODE_PRINTF("\n");
1683+ TRACE_AND_STEP();
1684+ *destreg = sbb_long(*destreg, srcval);
1685+ }
1686+ else {
1687+ u16 *destreg;
1688+ u16 srcval;
1689+
1690+ destreg = DECODE_RM_WORD_REGISTER(rh);
1691+ DECODE_PRINTF(",");
1692+ srcoffset = decode_rm00_address(rl);
1693+ srcval = fetch_data_word(srcoffset);
1694+ DECODE_PRINTF("\n");
1695+ TRACE_AND_STEP();
1696+ *destreg = sbb_word(*destreg, srcval);
1697+ }
1698+ break;
1699+ case 1:
1700+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1701+ u32 *destreg;
1702+ u32 srcval;
1703+
1704+ destreg = DECODE_RM_LONG_REGISTER(rh);
1705+ DECODE_PRINTF(",");
1706+ srcoffset = decode_rm01_address(rl);
1707+ srcval = fetch_data_long(srcoffset);
1708+ DECODE_PRINTF("\n");
1709+ TRACE_AND_STEP();
1710+ *destreg = sbb_long(*destreg, srcval);
1711+ }
1712+ else {
1713+ u16 *destreg;
1714+ u16 srcval;
1715+
1716+ destreg = DECODE_RM_WORD_REGISTER(rh);
1717+ DECODE_PRINTF(",");
1718+ srcoffset = decode_rm01_address(rl);
1719+ srcval = fetch_data_word(srcoffset);
1720+ DECODE_PRINTF("\n");
1721+ TRACE_AND_STEP();
1722+ *destreg = sbb_word(*destreg, srcval);
1723+ }
1724+ break;
1725+ case 2:
1726+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1727+ u32 *destreg;
1728+ u32 srcval;
1729+
1730+ destreg = DECODE_RM_LONG_REGISTER(rh);
1731+ DECODE_PRINTF(",");
1732+ srcoffset = decode_rm10_address(rl);
1733+ srcval = fetch_data_long(srcoffset);
1734+ DECODE_PRINTF("\n");
1735+ TRACE_AND_STEP();
1736+ *destreg = sbb_long(*destreg, srcval);
1737+ }
1738+ else {
1739+ u16 *destreg;
1740+ u16 srcval;
1741+
1742+ destreg = DECODE_RM_WORD_REGISTER(rh);
1743+ DECODE_PRINTF(",");
1744+ srcoffset = decode_rm10_address(rl);
1745+ srcval = fetch_data_word(srcoffset);
1746+ DECODE_PRINTF("\n");
1747+ TRACE_AND_STEP();
1748+ *destreg = sbb_word(*destreg, srcval);
1749+ }
1750+ break;
1751+ case 3: /* register to register */
1752+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1753+ u32 *destreg, *srcreg;
1754+
1755+ destreg = DECODE_RM_LONG_REGISTER(rh);
1756+ DECODE_PRINTF(",");
1757+ srcreg = DECODE_RM_LONG_REGISTER(rl);
1758+ DECODE_PRINTF("\n");
1759+ TRACE_AND_STEP();
1760+ *destreg = sbb_long(*destreg, *srcreg);
1761+ }
1762+ else {
1763+ u16 *destreg, *srcreg;
1764+
1765+ destreg = DECODE_RM_WORD_REGISTER(rh);
1766+ DECODE_PRINTF(",");
1767+ srcreg = DECODE_RM_WORD_REGISTER(rl);
1768+ DECODE_PRINTF("\n");
1769+ TRACE_AND_STEP();
1770+ *destreg = sbb_word(*destreg, *srcreg);
1771+ }
1772+ break;
1773+ }
1774+ DECODE_CLEAR_SEGOVR();
1775+ END_OF_INSTR();
1776+}
1777+
1778+/****************************************************************************
1779+REMARKS:
1780+Handles opcode 0x1c
1781+****************************************************************************/
1782+static void
1783+x86emuOp_sbb_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
1784+{
1785+ u8 srcval;
1786+
1787+ START_OF_INSTR();
1788+ DECODE_PRINTF("SBB\tAL,");
1789+ srcval = fetch_byte_imm();
1790+ DECODE_PRINTF2("%x\n", srcval);
1791+ TRACE_AND_STEP();
1792+ M.x86.R_AL = sbb_byte(M.x86.R_AL, srcval);
1793+ DECODE_CLEAR_SEGOVR();
1794+ END_OF_INSTR();
1795+}
1796+
1797+/****************************************************************************
1798+REMARKS:
1799+Handles opcode 0x1d
1800+****************************************************************************/
1801+static void
1802+x86emuOp_sbb_word_AX_IMM(u8 X86EMU_UNUSED(op1))
1803+{
1804+ u32 srcval;
1805+
1806+ START_OF_INSTR();
1807+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1808+ DECODE_PRINTF("SBB\tEAX,");
1809+ srcval = fetch_long_imm();
1810+ }
1811+ else {
1812+ DECODE_PRINTF("SBB\tAX,");
1813+ srcval = fetch_word_imm();
1814+ }
1815+ DECODE_PRINTF2("%x\n", srcval);
1816+ TRACE_AND_STEP();
1817+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1818+ M.x86.R_EAX = sbb_long(M.x86.R_EAX, srcval);
1819+ }
1820+ else {
1821+ M.x86.R_AX = sbb_word(M.x86.R_AX, (u16) srcval);
1822+ }
1823+ DECODE_CLEAR_SEGOVR();
1824+ END_OF_INSTR();
1825+}
1826+
1827+/****************************************************************************
1828+REMARKS:
1829+Handles opcode 0x1e
1830+****************************************************************************/
1831+static void
1832+x86emuOp_push_DS(u8 X86EMU_UNUSED(op1))
1833+{
1834+ START_OF_INSTR();
1835+ DECODE_PRINTF("PUSH\tDS\n");
1836+ TRACE_AND_STEP();
1837+ push_word(M.x86.R_DS);
1838+ DECODE_CLEAR_SEGOVR();
1839+ END_OF_INSTR();
1840+}
1841+
1842+/****************************************************************************
1843+REMARKS:
1844+Handles opcode 0x1f
1845+****************************************************************************/
1846+static void
1847+x86emuOp_pop_DS(u8 X86EMU_UNUSED(op1))
1848+{
1849+ START_OF_INSTR();
1850+ DECODE_PRINTF("POP\tDS\n");
1851+ TRACE_AND_STEP();
1852+ M.x86.R_DS = pop_word();
1853+ DECODE_CLEAR_SEGOVR();
1854+ END_OF_INSTR();
1855+}
1856+
1857+/****************************************************************************
1858+REMARKS:
1859+Handles opcode 0x20
1860+****************************************************************************/
1861+static void
1862+x86emuOp_and_byte_RM_R(u8 X86EMU_UNUSED(op1))
1863+{
1864+ int mod, rl, rh;
1865+ u8 *destreg, *srcreg;
1866+ uint destoffset;
1867+ u8 destval;
1868+
1869+ START_OF_INSTR();
1870+ DECODE_PRINTF("AND\t");
1871+ FETCH_DECODE_MODRM(mod, rh, rl);
1872+
1873+ switch (mod) {
1874+ case 0:
1875+ destoffset = decode_rm00_address(rl);
1876+ DECODE_PRINTF(",");
1877+ destval = fetch_data_byte(destoffset);
1878+ srcreg = DECODE_RM_BYTE_REGISTER(rh);
1879+ DECODE_PRINTF("\n");
1880+ TRACE_AND_STEP();
1881+ destval = and_byte(destval, *srcreg);
1882+ store_data_byte(destoffset, destval);
1883+ break;
1884+
1885+ case 1:
1886+ destoffset = decode_rm01_address(rl);
1887+ DECODE_PRINTF(",");
1888+ destval = fetch_data_byte(destoffset);
1889+ srcreg = DECODE_RM_BYTE_REGISTER(rh);
1890+ DECODE_PRINTF("\n");
1891+ TRACE_AND_STEP();
1892+ destval = and_byte(destval, *srcreg);
1893+ store_data_byte(destoffset, destval);
1894+ break;
1895+
1896+ case 2:
1897+ destoffset = decode_rm10_address(rl);
1898+ DECODE_PRINTF(",");
1899+ destval = fetch_data_byte(destoffset);
1900+ srcreg = DECODE_RM_BYTE_REGISTER(rh);
1901+ DECODE_PRINTF("\n");
1902+ TRACE_AND_STEP();
1903+ destval = and_byte(destval, *srcreg);
1904+ store_data_byte(destoffset, destval);
1905+ break;
1906+
1907+ case 3: /* register to register */
1908+ destreg = DECODE_RM_BYTE_REGISTER(rl);
1909+ DECODE_PRINTF(",");
1910+ srcreg = DECODE_RM_BYTE_REGISTER(rh);
1911+ DECODE_PRINTF("\n");
1912+ TRACE_AND_STEP();
1913+ *destreg = and_byte(*destreg, *srcreg);
1914+ break;
1915+ }
1916+ DECODE_CLEAR_SEGOVR();
1917+ END_OF_INSTR();
1918+}
1919+
1920+/****************************************************************************
1921+REMARKS:
1922+Handles opcode 0x21
1923+****************************************************************************/
1924+static void
1925+x86emuOp_and_word_RM_R(u8 X86EMU_UNUSED(op1))
1926+{
1927+ int mod, rl, rh;
1928+ uint destoffset;
1929+
1930+ START_OF_INSTR();
1931+ DECODE_PRINTF("AND\t");
1932+ FETCH_DECODE_MODRM(mod, rh, rl);
1933+ switch (mod) {
1934+ case 0:
1935+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1936+ u32 destval;
1937+ u32 *srcreg;
1938+
1939+ destoffset = decode_rm00_address(rl);
1940+ DECODE_PRINTF(",");
1941+ destval = fetch_data_long(destoffset);
1942+ srcreg = DECODE_RM_LONG_REGISTER(rh);
1943+ DECODE_PRINTF("\n");
1944+ TRACE_AND_STEP();
1945+ destval = and_long(destval, *srcreg);
1946+ store_data_long(destoffset, destval);
1947+ }
1948+ else {
1949+ u16 destval;
1950+ u16 *srcreg;
1951+
1952+ destoffset = decode_rm00_address(rl);
1953+ DECODE_PRINTF(",");
1954+ destval = fetch_data_word(destoffset);
1955+ srcreg = DECODE_RM_WORD_REGISTER(rh);
1956+ DECODE_PRINTF("\n");
1957+ TRACE_AND_STEP();
1958+ destval = and_word(destval, *srcreg);
1959+ store_data_word(destoffset, destval);
1960+ }
1961+ break;
1962+ case 1:
1963+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1964+ u32 destval;
1965+ u32 *srcreg;
1966+
1967+ destoffset = decode_rm01_address(rl);
1968+ DECODE_PRINTF(",");
1969+ destval = fetch_data_long(destoffset);
1970+ srcreg = DECODE_RM_LONG_REGISTER(rh);
1971+ DECODE_PRINTF("\n");
1972+ TRACE_AND_STEP();
1973+ destval = and_long(destval, *srcreg);
1974+ store_data_long(destoffset, destval);
1975+ }
1976+ else {
1977+ u16 destval;
1978+ u16 *srcreg;
1979+
1980+ destoffset = decode_rm01_address(rl);
1981+ DECODE_PRINTF(",");
1982+ destval = fetch_data_word(destoffset);
1983+ srcreg = DECODE_RM_WORD_REGISTER(rh);
1984+ DECODE_PRINTF("\n");
1985+ TRACE_AND_STEP();
1986+ destval = and_word(destval, *srcreg);
1987+ store_data_word(destoffset, destval);
1988+ }
1989+ break;
1990+ case 2:
1991+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1992+ u32 destval;
1993+ u32 *srcreg;
1994+
1995+ destoffset = decode_rm10_address(rl);
1996+ DECODE_PRINTF(",");
1997+ destval = fetch_data_long(destoffset);
1998+ srcreg = DECODE_RM_LONG_REGISTER(rh);
1999+ DECODE_PRINTF("\n");
2000+ TRACE_AND_STEP();
2001+ destval = and_long(destval, *srcreg);
2002+ store_data_long(destoffset, destval);
2003+ }
2004+ else {
2005+ u16 destval;
2006+ u16 *srcreg;
2007+
2008+ destoffset = decode_rm10_address(rl);
2009+ DECODE_PRINTF(",");
2010+ destval = fetch_data_word(destoffset);
2011+ srcreg = DECODE_RM_WORD_REGISTER(rh);
2012+ DECODE_PRINTF("\n");
2013+ TRACE_AND_STEP();
2014+ destval = and_word(destval, *srcreg);
2015+ store_data_word(destoffset, destval);
2016+ }
2017+ break;
2018+ case 3: /* register to register */
2019+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2020+ u32 *destreg, *srcreg;
2021+
2022+ destreg = DECODE_RM_LONG_REGISTER(rl);
2023+ DECODE_PRINTF(",");
2024+ srcreg = DECODE_RM_LONG_REGISTER(rh);
2025+ DECODE_PRINTF("\n");
2026+ TRACE_AND_STEP();
2027+ *destreg = and_long(*destreg, *srcreg);
2028+ }
2029+ else {
2030+ u16 *destreg, *srcreg;
2031+
2032+ destreg = DECODE_RM_WORD_REGISTER(rl);
2033+ DECODE_PRINTF(",");
2034+ srcreg = DECODE_RM_WORD_REGISTER(rh);
2035+ DECODE_PRINTF("\n");
2036+ TRACE_AND_STEP();
2037+ *destreg = and_word(*destreg, *srcreg);
2038+ }
2039+ break;
2040+ }
2041+ DECODE_CLEAR_SEGOVR();
2042+ END_OF_INSTR();
2043+}
2044+
2045+/****************************************************************************
2046+REMARKS:
2047+Handles opcode 0x22
2048+****************************************************************************/
2049+static void
2050+x86emuOp_and_byte_R_RM(u8 X86EMU_UNUSED(op1))
2051+{
2052+ int mod, rl, rh;
2053+ u8 *destreg, *srcreg;
2054+ uint srcoffset;
2055+ u8 srcval;
2056+
2057+ START_OF_INSTR();
2058+ DECODE_PRINTF("AND\t");
2059+ FETCH_DECODE_MODRM(mod, rh, rl);
2060+ switch (mod) {
2061+ case 0:
2062+ destreg = DECODE_RM_BYTE_REGISTER(rh);
2063+ DECODE_PRINTF(",");
2064+ srcoffset = decode_rm00_address(rl);
2065+ srcval = fetch_data_byte(srcoffset);
2066+ DECODE_PRINTF("\n");
2067+ TRACE_AND_STEP();
2068+ *destreg = and_byte(*destreg, srcval);
2069+ break;
2070+ case 1:
2071+ destreg = DECODE_RM_BYTE_REGISTER(rh);
2072+ DECODE_PRINTF(",");
2073+ srcoffset = decode_rm01_address(rl);
2074+ srcval = fetch_data_byte(srcoffset);
2075+ DECODE_PRINTF("\n");
2076+ TRACE_AND_STEP();
2077+ *destreg = and_byte(*destreg, srcval);
2078+ break;
2079+ case 2:
2080+ destreg = DECODE_RM_BYTE_REGISTER(rh);
2081+ DECODE_PRINTF(",");
2082+ srcoffset = decode_rm10_address(rl);
2083+ srcval = fetch_data_byte(srcoffset);
2084+ DECODE_PRINTF("\n");
2085+ TRACE_AND_STEP();
2086+ *destreg = and_byte(*destreg, srcval);
2087+ break;
2088+ case 3: /* register to register */
2089+ destreg = DECODE_RM_BYTE_REGISTER(rh);
2090+ DECODE_PRINTF(",");
2091+ srcreg = DECODE_RM_BYTE_REGISTER(rl);
2092+ DECODE_PRINTF("\n");
2093+ TRACE_AND_STEP();
2094+ *destreg = and_byte(*destreg, *srcreg);
2095+ break;
2096+ }
2097+ DECODE_CLEAR_SEGOVR();
2098+ END_OF_INSTR();
2099+}
2100+
2101+/****************************************************************************
2102+REMARKS:
2103+Handles opcode 0x23
2104+****************************************************************************/
2105+static void
2106+x86emuOp_and_word_R_RM(u8 X86EMU_UNUSED(op1))
2107+{
2108+ int mod, rl, rh;
2109+ uint srcoffset;
2110+
2111+ START_OF_INSTR();
2112+ DECODE_PRINTF("AND\t");
2113+ FETCH_DECODE_MODRM(mod, rh, rl);
2114+ switch (mod) {
2115+ case 0:
2116+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2117+ u32 *destreg;
2118+ u32 srcval;
2119+
2120+ destreg = DECODE_RM_LONG_REGISTER(rh);
2121+ DECODE_PRINTF(",");
2122+ srcoffset = decode_rm00_address(rl);
2123+ srcval = fetch_data_long(srcoffset);
2124+ DECODE_PRINTF("\n");
2125+ TRACE_AND_STEP();
2126+ *destreg = and_long(*destreg, srcval);
2127+ }
2128+ else {
2129+ u16 *destreg;
2130+ u16 srcval;
2131+
2132+ destreg = DECODE_RM_WORD_REGISTER(rh);
2133+ DECODE_PRINTF(",");
2134+ srcoffset = decode_rm00_address(rl);
2135+ srcval = fetch_data_word(srcoffset);
2136+ DECODE_PRINTF("\n");
2137+ TRACE_AND_STEP();
2138+ *destreg = and_word(*destreg, srcval);
2139+ }
2140+ break;
2141+ case 1:
2142+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2143+ u32 *destreg;
2144+ u32 srcval;
2145+
2146+ destreg = DECODE_RM_LONG_REGISTER(rh);
2147+ DECODE_PRINTF(",");
2148+ srcoffset = decode_rm01_address(rl);
2149+ srcval = fetch_data_long(srcoffset);
2150+ DECODE_PRINTF("\n");
2151+ TRACE_AND_STEP();
2152+ *destreg = and_long(*destreg, srcval);
2153+ break;
2154+ }
2155+ else {
2156+ u16 *destreg;
2157+ u16 srcval;
2158+
2159+ destreg = DECODE_RM_WORD_REGISTER(rh);
2160+ DECODE_PRINTF(",");
2161+ srcoffset = decode_rm01_address(rl);
2162+ srcval = fetch_data_word(srcoffset);
2163+ DECODE_PRINTF("\n");
2164+ TRACE_AND_STEP();
2165+ *destreg = and_word(*destreg, srcval);
2166+ break;
2167+ }
2168+ case 2:
2169+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2170+ u32 *destreg;
2171+ u32 srcval;
2172+
2173+ destreg = DECODE_RM_LONG_REGISTER(rh);
2174+ DECODE_PRINTF(",");
2175+ srcoffset = decode_rm10_address(rl);
2176+ srcval = fetch_data_long(srcoffset);
2177+ DECODE_PRINTF("\n");
2178+ TRACE_AND_STEP();
2179+ *destreg = and_long(*destreg, srcval);
2180+ }
2181+ else {
2182+ u16 *destreg;
2183+ u16 srcval;
2184+
2185+ destreg = DECODE_RM_WORD_REGISTER(rh);
2186+ DECODE_PRINTF(",");
2187+ srcoffset = decode_rm10_address(rl);
2188+ srcval = fetch_data_word(srcoffset);
2189+ DECODE_PRINTF("\n");
2190+ TRACE_AND_STEP();
2191+ *destreg = and_word(*destreg, srcval);
2192+ }
2193+ break;
2194+ case 3: /* register to register */
2195+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2196+ u32 *destreg, *srcreg;
2197+
2198+ destreg = DECODE_RM_LONG_REGISTER(rh);
2199+ DECODE_PRINTF(",");
2200+ srcreg = DECODE_RM_LONG_REGISTER(rl);
2201+ DECODE_PRINTF("\n");
2202+ TRACE_AND_STEP();
2203+ *destreg = and_long(*destreg, *srcreg);
2204+ }
2205+ else {
2206+ u16 *destreg, *srcreg;
2207+
2208+ destreg = DECODE_RM_WORD_REGISTER(rh);
2209+ DECODE_PRINTF(",");
2210+ srcreg = DECODE_RM_WORD_REGISTER(rl);
2211+ DECODE_PRINTF("\n");
2212+ TRACE_AND_STEP();
2213+ *destreg = and_word(*destreg, *srcreg);
2214+ }
2215+ break;
2216+ }
2217+ DECODE_CLEAR_SEGOVR();
2218+ END_OF_INSTR();
2219+}
2220+
2221+/****************************************************************************
2222+REMARKS:
2223+Handles opcode 0x24
2224+****************************************************************************/
2225+static void
2226+x86emuOp_and_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
2227+{
2228+ u8 srcval;
2229+
2230+ START_OF_INSTR();
2231+ DECODE_PRINTF("AND\tAL,");
2232+ srcval = fetch_byte_imm();
2233+ DECODE_PRINTF2("%x\n", srcval);
2234+ TRACE_AND_STEP();
2235+ M.x86.R_AL = and_byte(M.x86.R_AL, srcval);
2236+ DECODE_CLEAR_SEGOVR();
2237+ END_OF_INSTR();
2238+}
2239+
2240+/****************************************************************************
2241+REMARKS:
2242+Handles opcode 0x25
2243+****************************************************************************/
2244+static void
2245+x86emuOp_and_word_AX_IMM(u8 X86EMU_UNUSED(op1))
2246+{
2247+ u32 srcval;
2248+
2249+ START_OF_INSTR();
2250+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2251+ DECODE_PRINTF("AND\tEAX,");
2252+ srcval = fetch_long_imm();
2253+ }
2254+ else {
2255+ DECODE_PRINTF("AND\tAX,");
2256+ srcval = fetch_word_imm();
2257+ }
2258+ DECODE_PRINTF2("%x\n", srcval);
2259+ TRACE_AND_STEP();
2260+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2261+ M.x86.R_EAX = and_long(M.x86.R_EAX, srcval);
2262+ }
2263+ else {
2264+ M.x86.R_AX = and_word(M.x86.R_AX, (u16) srcval);
2265+ }
2266+ DECODE_CLEAR_SEGOVR();
2267+ END_OF_INSTR();
2268+}
2269+
2270+/****************************************************************************
2271+REMARKS:
2272+Handles opcode 0x26
2273+****************************************************************************/
2274+static void
2275+x86emuOp_segovr_ES(u8 X86EMU_UNUSED(op1))
2276+{
2277+ START_OF_INSTR();
2278+ DECODE_PRINTF("ES:\n");
2279+ TRACE_AND_STEP();
2280+ M.x86.mode |= SYSMODE_SEGOVR_ES;
2281+ /*
2282+ * note the lack of DECODE_CLEAR_SEGOVR(r) since, here is one of 4
2283+ * opcode subroutines we do not want to do this.
2284+ */
2285+ END_OF_INSTR();
2286+}
2287+
2288+/****************************************************************************
2289+REMARKS:
2290+Handles opcode 0x27
2291+****************************************************************************/
2292+static void
2293+x86emuOp_daa(u8 X86EMU_UNUSED(op1))
2294+{
2295+ START_OF_INSTR();
2296+ DECODE_PRINTF("DAA\n");
2297+ TRACE_AND_STEP();
2298+ M.x86.R_AL = daa_byte(M.x86.R_AL);
2299+ DECODE_CLEAR_SEGOVR();
2300+ END_OF_INSTR();
2301+}
2302+
2303+/****************************************************************************
2304+REMARKS:
2305+Handles opcode 0x28
2306+****************************************************************************/
2307+static void
2308+x86emuOp_sub_byte_RM_R(u8 X86EMU_UNUSED(op1))
2309+{
2310+ int mod, rl, rh;
2311+ u8 *destreg, *srcreg;
2312+ uint destoffset;
2313+ u8 destval;
2314+
2315+ START_OF_INSTR();
2316+ DECODE_PRINTF("SUB\t");
2317+ FETCH_DECODE_MODRM(mod, rh, rl);
2318+ switch (mod) {
2319+ case 0:
2320+ destoffset = decode_rm00_address(rl);
2321+ DECODE_PRINTF(",");
2322+ destval = fetch_data_byte(destoffset);
2323+ srcreg = DECODE_RM_BYTE_REGISTER(rh);
2324+ DECODE_PRINTF("\n");
2325+ TRACE_AND_STEP();
2326+ destval = sub_byte(destval, *srcreg);
2327+ store_data_byte(destoffset, destval);
2328+ break;
2329+ case 1:
2330+ destoffset = decode_rm01_address(rl);
2331+ DECODE_PRINTF(",");
2332+ destval = fetch_data_byte(destoffset);
2333+ srcreg = DECODE_RM_BYTE_REGISTER(rh);
2334+ DECODE_PRINTF("\n");
2335+ TRACE_AND_STEP();
2336+ destval = sub_byte(destval, *srcreg);
2337+ store_data_byte(destoffset, destval);
2338+ break;
2339+ case 2:
2340+ destoffset = decode_rm10_address(rl);
2341+ DECODE_PRINTF(",");
2342+ destval = fetch_data_byte(destoffset);
2343+ srcreg = DECODE_RM_BYTE_REGISTER(rh);
2344+ DECODE_PRINTF("\n");
2345+ TRACE_AND_STEP();
2346+ destval = sub_byte(destval, *srcreg);
2347+ store_data_byte(destoffset, destval);
2348+ break;
2349+ case 3: /* register to register */
2350+ destreg = DECODE_RM_BYTE_REGISTER(rl);
2351+ DECODE_PRINTF(",");
2352+ srcreg = DECODE_RM_BYTE_REGISTER(rh);
2353+ DECODE_PRINTF("\n");
2354+ TRACE_AND_STEP();
2355+ *destreg = sub_byte(*destreg, *srcreg);
2356+ break;
2357+ }
2358+ DECODE_CLEAR_SEGOVR();
2359+ END_OF_INSTR();
2360+}
2361+
2362+/****************************************************************************
2363+REMARKS:
2364+Handles opcode 0x29
2365+****************************************************************************/
2366+static void
2367+x86emuOp_sub_word_RM_R(u8 X86EMU_UNUSED(op1))
2368+{
2369+ int mod, rl, rh;
2370+ uint destoffset;
2371+
2372+ START_OF_INSTR();
2373+ DECODE_PRINTF("SUB\t");
2374+ FETCH_DECODE_MODRM(mod, rh, rl);
2375+ switch (mod) {
2376+ case 0:
2377+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2378+ u32 destval;
2379+ u32 *srcreg;
2380+
2381+ destoffset = decode_rm00_address(rl);
2382+ DECODE_PRINTF(",");
2383+ destval = fetch_data_long(destoffset);
2384+ srcreg = DECODE_RM_LONG_REGISTER(rh);
2385+ DECODE_PRINTF("\n");
2386+ TRACE_AND_STEP();
2387+ destval = sub_long(destval, *srcreg);
2388+ store_data_long(destoffset, destval);
2389+ }
2390+ else {
2391+ u16 destval;
2392+ u16 *srcreg;
2393+
2394+ destoffset = decode_rm00_address(rl);
2395+ DECODE_PRINTF(",");
2396+ destval = fetch_data_word(destoffset);
2397+ srcreg = DECODE_RM_WORD_REGISTER(rh);
2398+ DECODE_PRINTF("\n");
2399+ TRACE_AND_STEP();
2400+ destval = sub_word(destval, *srcreg);
2401+ store_data_word(destoffset, destval);
2402+ }
2403+ break;
2404+ case 1:
2405+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2406+ u32 destval;
2407+ u32 *srcreg;
2408+
2409+ destoffset = decode_rm01_address(rl);
2410+ DECODE_PRINTF(",");
2411+ destval = fetch_data_long(destoffset);
2412+ srcreg = DECODE_RM_LONG_REGISTER(rh);
2413+ DECODE_PRINTF("\n");
2414+ TRACE_AND_STEP();
2415+ destval = sub_long(destval, *srcreg);
2416+ store_data_long(destoffset, destval);
2417+ }
2418+ else {
2419+ u16 destval;
2420+ u16 *srcreg;
2421+
2422+ destoffset = decode_rm01_address(rl);
2423+ DECODE_PRINTF(",");
2424+ destval = fetch_data_word(destoffset);
2425+ srcreg = DECODE_RM_WORD_REGISTER(rh);
2426+ DECODE_PRINTF("\n");
2427+ TRACE_AND_STEP();
2428+ destval = sub_word(destval, *srcreg);
2429+ store_data_word(destoffset, destval);
2430+ }
2431+ break;
2432+ case 2:
2433+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2434+ u32 destval;
2435+ u32 *srcreg;
2436+
2437+ destoffset = decode_rm10_address(rl);
2438+ DECODE_PRINTF(",");
2439+ destval = fetch_data_long(destoffset);
2440+ srcreg = DECODE_RM_LONG_REGISTER(rh);
2441+ DECODE_PRINTF("\n");
2442+ TRACE_AND_STEP();
2443+ destval = sub_long(destval, *srcreg);
2444+ store_data_long(destoffset, destval);
2445+ }
2446+ else {
2447+ u16 destval;
2448+ u16 *srcreg;
2449+
2450+ destoffset = decode_rm10_address(rl);
2451+ DECODE_PRINTF(",");
2452+ destval = fetch_data_word(destoffset);
2453+ srcreg = DECODE_RM_WORD_REGISTER(rh);
2454+ DECODE_PRINTF("\n");
2455+ TRACE_AND_STEP();
2456+ destval = sub_word(destval, *srcreg);
2457+ store_data_word(destoffset, destval);
2458+ }
2459+ break;
2460+ case 3: /* register to register */
2461+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2462+ u32 *destreg, *srcreg;
2463+
2464+ destreg = DECODE_RM_LONG_REGISTER(rl);
2465+ DECODE_PRINTF(",");
2466+ srcreg = DECODE_RM_LONG_REGISTER(rh);
2467+ DECODE_PRINTF("\n");
2468+ TRACE_AND_STEP();
2469+ *destreg = sub_long(*destreg, *srcreg);
2470+ }
2471+ else {
2472+ u16 *destreg, *srcreg;
2473+
2474+ destreg = DECODE_RM_WORD_REGISTER(rl);
2475+ DECODE_PRINTF(",");
2476+ srcreg = DECODE_RM_WORD_REGISTER(rh);
2477+ DECODE_PRINTF("\n");
2478+ TRACE_AND_STEP();
2479+ *destreg = sub_word(*destreg, *srcreg);
2480+ }
2481+ break;
2482+ }
2483+ DECODE_CLEAR_SEGOVR();
2484+ END_OF_INSTR();
2485+}
2486+
2487+/****************************************************************************
2488+REMARKS:
2489+Handles opcode 0x2a
2490+****************************************************************************/
2491+static void
2492+x86emuOp_sub_byte_R_RM(u8 X86EMU_UNUSED(op1))
2493+{
2494+ int mod, rl, rh;
2495+ u8 *destreg, *srcreg;
2496+ uint srcoffset;
2497+ u8 srcval;
2498+
2499+ START_OF_INSTR();
2500+ DECODE_PRINTF("SUB\t");
2501+ FETCH_DECODE_MODRM(mod, rh, rl);
2502+ switch (mod) {
2503+ case 0:
2504+ destreg = DECODE_RM_BYTE_REGISTER(rh);
2505+ DECODE_PRINTF(",");
2506+ srcoffset = decode_rm00_address(rl);
2507+ srcval = fetch_data_byte(srcoffset);
2508+ DECODE_PRINTF("\n");
2509+ TRACE_AND_STEP();
2510+ *destreg = sub_byte(*destreg, srcval);
2511+ break;
2512+ case 1:
2513+ destreg = DECODE_RM_BYTE_REGISTER(rh);
2514+ DECODE_PRINTF(",");
2515+ srcoffset = decode_rm01_address(rl);
2516+ srcval = fetch_data_byte(srcoffset);
2517+ DECODE_PRINTF("\n");
2518+ TRACE_AND_STEP();
2519+ *destreg = sub_byte(*destreg, srcval);
2520+ break;
2521+ case 2:
2522+ destreg = DECODE_RM_BYTE_REGISTER(rh);
2523+ DECODE_PRINTF(",");
2524+ srcoffset = decode_rm10_address(rl);
2525+ srcval = fetch_data_byte(srcoffset);
2526+ DECODE_PRINTF("\n");
2527+ TRACE_AND_STEP();
2528+ *destreg = sub_byte(*destreg, srcval);
2529+ break;
2530+ case 3: /* register to register */
2531+ destreg = DECODE_RM_BYTE_REGISTER(rh);
2532+ DECODE_PRINTF(",");
2533+ srcreg = DECODE_RM_BYTE_REGISTER(rl);
2534+ DECODE_PRINTF("\n");
2535+ TRACE_AND_STEP();
2536+ *destreg = sub_byte(*destreg, *srcreg);
2537+ break;
2538+ }
2539+ DECODE_CLEAR_SEGOVR();
2540+ END_OF_INSTR();
2541+}
2542+
2543+/****************************************************************************
2544+REMARKS:
2545+Handles opcode 0x2b
2546+****************************************************************************/
2547+static void
2548+x86emuOp_sub_word_R_RM(u8 X86EMU_UNUSED(op1))
2549+{
2550+ int mod, rl, rh;
2551+ uint srcoffset;
2552+
2553+ START_OF_INSTR();
2554+ DECODE_PRINTF("SUB\t");
2555+ FETCH_DECODE_MODRM(mod, rh, rl);
2556+ switch (mod) {
2557+ case 0:
2558+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2559+ u32 *destreg;
2560+ u32 srcval;
2561+
2562+ destreg = DECODE_RM_LONG_REGISTER(rh);
2563+ DECODE_PRINTF(",");
2564+ srcoffset = decode_rm00_address(rl);
2565+ srcval = fetch_data_long(srcoffset);
2566+ DECODE_PRINTF("\n");
2567+ TRACE_AND_STEP();
2568+ *destreg = sub_long(*destreg, srcval);
2569+ }
2570+ else {
2571+ u16 *destreg;
2572+ u16 srcval;
2573+
2574+ destreg = DECODE_RM_WORD_REGISTER(rh);
2575+ DECODE_PRINTF(",");
2576+ srcoffset = decode_rm00_address(rl);
2577+ srcval = fetch_data_word(srcoffset);
2578+ DECODE_PRINTF("\n");
2579+ TRACE_AND_STEP();
2580+ *destreg = sub_word(*destreg, srcval);
2581+ }
2582+ break;
2583+ case 1:
2584+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2585+ u32 *destreg;
2586+ u32 srcval;
2587+
2588+ destreg = DECODE_RM_LONG_REGISTER(rh);
2589+ DECODE_PRINTF(",");
2590+ srcoffset = decode_rm01_address(rl);
2591+ srcval = fetch_data_long(srcoffset);
2592+ DECODE_PRINTF("\n");
2593+ TRACE_AND_STEP();
2594+ *destreg = sub_long(*destreg, srcval);
2595+ }
2596+ else {
2597+ u16 *destreg;
2598+ u16 srcval;
2599+
2600+ destreg = DECODE_RM_WORD_REGISTER(rh);
2601+ DECODE_PRINTF(",");
2602+ srcoffset = decode_rm01_address(rl);
2603+ srcval = fetch_data_word(srcoffset);
2604+ DECODE_PRINTF("\n");
2605+ TRACE_AND_STEP();
2606+ *destreg = sub_word(*destreg, srcval);
2607+ }
2608+ break;
2609+ case 2:
2610+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2611+ u32 *destreg;
2612+ u32 srcval;
2613+
2614+ destreg = DECODE_RM_LONG_REGISTER(rh);
2615+ DECODE_PRINTF(",");
2616+ srcoffset = decode_rm10_address(rl);
2617+ srcval = fetch_data_long(srcoffset);
2618+ DECODE_PRINTF("\n");
2619+ TRACE_AND_STEP();
2620+ *destreg = sub_long(*destreg, srcval);
2621+ }
2622+ else {
2623+ u16 *destreg;
2624+ u16 srcval;
2625+
2626+ destreg = DECODE_RM_WORD_REGISTER(rh);
2627+ DECODE_PRINTF(",");
2628+ srcoffset = decode_rm10_address(rl);
2629+ srcval = fetch_data_word(srcoffset);
2630+ DECODE_PRINTF("\n");
2631+ TRACE_AND_STEP();
2632+ *destreg = sub_word(*destreg, srcval);
2633+ }
2634+ break;
2635+ case 3: /* register to register */
2636+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2637+ u32 *destreg, *srcreg;
2638+
2639+ destreg = DECODE_RM_LONG_REGISTER(rh);
2640+ DECODE_PRINTF(",");
2641+ srcreg = DECODE_RM_LONG_REGISTER(rl);
2642+ DECODE_PRINTF("\n");
2643+ TRACE_AND_STEP();
2644+ *destreg = sub_long(*destreg, *srcreg);
2645+ }
2646+ else {
2647+ u16 *destreg, *srcreg;
2648+
2649+ destreg = DECODE_RM_WORD_REGISTER(rh);
2650+ DECODE_PRINTF(",");
2651+ srcreg = DECODE_RM_WORD_REGISTER(rl);
2652+ DECODE_PRINTF("\n");
2653+ TRACE_AND_STEP();
2654+ *destreg = sub_word(*destreg, *srcreg);
2655+ }
2656+ break;
2657+ }
2658+ DECODE_CLEAR_SEGOVR();
2659+ END_OF_INSTR();
2660+}
2661+
2662+/****************************************************************************
2663+REMARKS:
2664+Handles opcode 0x2c
2665+****************************************************************************/
2666+static void
2667+x86emuOp_sub_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
2668+{
2669+ u8 srcval;
2670+
2671+ START_OF_INSTR();
2672+ DECODE_PRINTF("SUB\tAL,");
2673+ srcval = fetch_byte_imm();
2674+ DECODE_PRINTF2("%x\n", srcval);
2675+ TRACE_AND_STEP();
2676+ M.x86.R_AL = sub_byte(M.x86.R_AL, srcval);
2677+ DECODE_CLEAR_SEGOVR();
2678+ END_OF_INSTR();
2679+}
2680+
2681+/****************************************************************************
2682+REMARKS:
2683+Handles opcode 0x2d
2684+****************************************************************************/
2685+static void
2686+x86emuOp_sub_word_AX_IMM(u8 X86EMU_UNUSED(op1))
2687+{
2688+ u32 srcval;
2689+
2690+ START_OF_INSTR();
2691+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2692+ DECODE_PRINTF("SUB\tEAX,");
2693+ srcval = fetch_long_imm();
2694+ }
2695+ else {
2696+ DECODE_PRINTF("SUB\tAX,");
2697+ srcval = fetch_word_imm();
2698+ }
2699+ DECODE_PRINTF2("%x\n", srcval);
2700+ TRACE_AND_STEP();
2701+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2702+ M.x86.R_EAX = sub_long(M.x86.R_EAX, srcval);
2703+ }
2704+ else {
2705+ M.x86.R_AX = sub_word(M.x86.R_AX, (u16) srcval);
2706+ }
2707+ DECODE_CLEAR_SEGOVR();
2708+ END_OF_INSTR();
2709+}
2710+
2711+/****************************************************************************
2712+REMARKS:
2713+Handles opcode 0x2e
2714+****************************************************************************/
2715+static void
2716+x86emuOp_segovr_CS(u8 X86EMU_UNUSED(op1))
2717+{
2718+ START_OF_INSTR();
2719+ DECODE_PRINTF("CS:\n");
2720+ TRACE_AND_STEP();
2721+ M.x86.mode |= SYSMODE_SEGOVR_CS;
2722+ /* note no DECODE_CLEAR_SEGOVR here. */
2723+ END_OF_INSTR();
2724+}
2725+
2726+/****************************************************************************
2727+REMARKS:
2728+Handles opcode 0x2f
2729+****************************************************************************/
2730+static void
2731+x86emuOp_das(u8 X86EMU_UNUSED(op1))
2732+{
2733+ START_OF_INSTR();
2734+ DECODE_PRINTF("DAS\n");
2735+ TRACE_AND_STEP();
2736+ M.x86.R_AL = das_byte(M.x86.R_AL);
2737+ DECODE_CLEAR_SEGOVR();
2738+ END_OF_INSTR();
2739+}
2740+
2741+/****************************************************************************
2742+REMARKS:
2743+Handles opcode 0x30
2744+****************************************************************************/
2745+static void
2746+x86emuOp_xor_byte_RM_R(u8 X86EMU_UNUSED(op1))
2747+{
2748+ int mod, rl, rh;
2749+ u8 *destreg, *srcreg;
2750+ uint destoffset;
2751+ u8 destval;
2752+
2753+ START_OF_INSTR();
2754+ DECODE_PRINTF("XOR\t");
2755+ FETCH_DECODE_MODRM(mod, rh, rl);
2756+ switch (mod) {
2757+ case 0:
2758+ destoffset = decode_rm00_address(rl);
2759+ DECODE_PRINTF(",");
2760+ destval = fetch_data_byte(destoffset);
2761+ srcreg = DECODE_RM_BYTE_REGISTER(rh);
2762+ DECODE_PRINTF("\n");
2763+ TRACE_AND_STEP();
2764+ destval = xor_byte(destval, *srcreg);
2765+ store_data_byte(destoffset, destval);
2766+ break;
2767+ case 1:
2768+ destoffset = decode_rm01_address(rl);
2769+ DECODE_PRINTF(",");
2770+ destval = fetch_data_byte(destoffset);
2771+ srcreg = DECODE_RM_BYTE_REGISTER(rh);
2772+ DECODE_PRINTF("\n");
2773+ TRACE_AND_STEP();
2774+ destval = xor_byte(destval, *srcreg);
2775+ store_data_byte(destoffset, destval);
2776+ break;
2777+ case 2:
2778+ destoffset = decode_rm10_address(rl);
2779+ DECODE_PRINTF(",");
2780+ destval = fetch_data_byte(destoffset);
2781+ srcreg = DECODE_RM_BYTE_REGISTER(rh);
2782+ DECODE_PRINTF("\n");
2783+ TRACE_AND_STEP();
2784+ destval = xor_byte(destval, *srcreg);
2785+ store_data_byte(destoffset, destval);
2786+ break;
2787+ case 3: /* register to register */
2788+ destreg = DECODE_RM_BYTE_REGISTER(rl);
2789+ DECODE_PRINTF(",");
2790+ srcreg = DECODE_RM_BYTE_REGISTER(rh);
2791+ DECODE_PRINTF("\n");
2792+ TRACE_AND_STEP();
2793+ *destreg = xor_byte(*destreg, *srcreg);
2794+ break;
2795+ }
2796+ DECODE_CLEAR_SEGOVR();
2797+ END_OF_INSTR();
2798+}
2799+
2800+/****************************************************************************
2801+REMARKS:
2802+Handles opcode 0x31
2803+****************************************************************************/
2804+static void
2805+x86emuOp_xor_word_RM_R(u8 X86EMU_UNUSED(op1))
2806+{
2807+ int mod, rl, rh;
2808+ uint destoffset;
2809+
2810+ START_OF_INSTR();
2811+ DECODE_PRINTF("XOR\t");
2812+ FETCH_DECODE_MODRM(mod, rh, rl);
2813+ switch (mod) {
2814+ case 0:
2815+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2816+ u32 destval;
2817+ u32 *srcreg;
2818+
2819+ destoffset = decode_rm00_address(rl);
2820+ DECODE_PRINTF(",");
2821+ destval = fetch_data_long(destoffset);
2822+ srcreg = DECODE_RM_LONG_REGISTER(rh);
2823+ DECODE_PRINTF("\n");
2824+ TRACE_AND_STEP();
2825+ destval = xor_long(destval, *srcreg);
2826+ store_data_long(destoffset, destval);
2827+ }
2828+ else {
2829+ u16 destval;
2830+ u16 *srcreg;
2831+
2832+ destoffset = decode_rm00_address(rl);
2833+ DECODE_PRINTF(",");
2834+ destval = fetch_data_word(destoffset);
2835+ srcreg = DECODE_RM_WORD_REGISTER(rh);
2836+ DECODE_PRINTF("\n");
2837+ TRACE_AND_STEP();
2838+ destval = xor_word(destval, *srcreg);
2839+ store_data_word(destoffset, destval);
2840+ }
2841+ break;
2842+ case 1:
2843+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2844+ u32 destval;
2845+ u32 *srcreg;
2846+
2847+ destoffset = decode_rm01_address(rl);
2848+ DECODE_PRINTF(",");
2849+ destval = fetch_data_long(destoffset);
2850+ srcreg = DECODE_RM_LONG_REGISTER(rh);
2851+ DECODE_PRINTF("\n");
2852+ TRACE_AND_STEP();
2853+ destval = xor_long(destval, *srcreg);
2854+ store_data_long(destoffset, destval);
2855+ }
2856+ else {
2857+ u16 destval;
2858+ u16 *srcreg;
2859+
2860+ destoffset = decode_rm01_address(rl);
2861+ DECODE_PRINTF(",");
2862+ destval = fetch_data_word(destoffset);
2863+ srcreg = DECODE_RM_WORD_REGISTER(rh);
2864+ DECODE_PRINTF("\n");
2865+ TRACE_AND_STEP();
2866+ destval = xor_word(destval, *srcreg);
2867+ store_data_word(destoffset, destval);
2868+ }
2869+ break;
2870+ case 2:
2871+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2872+ u32 destval;
2873+ u32 *srcreg;
2874+
2875+ destoffset = decode_rm10_address(rl);
2876+ DECODE_PRINTF(",");
2877+ destval = fetch_data_long(destoffset);
2878+ srcreg = DECODE_RM_LONG_REGISTER(rh);
2879+ DECODE_PRINTF("\n");
2880+ TRACE_AND_STEP();
2881+ destval = xor_long(destval, *srcreg);
2882+ store_data_long(destoffset, destval);
2883+ }
2884+ else {
2885+ u16 destval;
2886+ u16 *srcreg;
2887+
2888+ destoffset = decode_rm10_address(rl);
2889+ DECODE_PRINTF(",");
2890+ destval = fetch_data_word(destoffset);
2891+ srcreg = DECODE_RM_WORD_REGISTER(rh);
2892+ DECODE_PRINTF("\n");
2893+ TRACE_AND_STEP();
2894+ destval = xor_word(destval, *srcreg);
2895+ store_data_word(destoffset, destval);
2896+ }
2897+ break;
2898+ case 3: /* register to register */
2899+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2900+ u32 *destreg, *srcreg;
2901+
2902+ destreg = DECODE_RM_LONG_REGISTER(rl);
2903+ DECODE_PRINTF(",");
2904+ srcreg = DECODE_RM_LONG_REGISTER(rh);
2905+ DECODE_PRINTF("\n");
2906+ TRACE_AND_STEP();
2907+ *destreg = xor_long(*destreg, *srcreg);
2908+ }
2909+ else {
2910+ u16 *destreg, *srcreg;
2911+
2912+ destreg = DECODE_RM_WORD_REGISTER(rl);
2913+ DECODE_PRINTF(",");
2914+ srcreg = DECODE_RM_WORD_REGISTER(rh);
2915+ DECODE_PRINTF("\n");
2916+ TRACE_AND_STEP();
2917+ *destreg = xor_word(*destreg, *srcreg);
2918+ }
2919+ break;
2920+ }
2921+ DECODE_CLEAR_SEGOVR();
2922+ END_OF_INSTR();
2923+}
2924+
2925+/****************************************************************************
2926+REMARKS:
2927+Handles opcode 0x32
2928+****************************************************************************/
2929+static void
2930+x86emuOp_xor_byte_R_RM(u8 X86EMU_UNUSED(op1))
2931+{
2932+ int mod, rl, rh;
2933+ u8 *destreg, *srcreg;
2934+ uint srcoffset;
2935+ u8 srcval;
2936+
2937+ START_OF_INSTR();
2938+ DECODE_PRINTF("XOR\t");
2939+ FETCH_DECODE_MODRM(mod, rh, rl);
2940+ switch (mod) {
2941+ case 0:
2942+ destreg = DECODE_RM_BYTE_REGISTER(rh);
2943+ DECODE_PRINTF(",");
2944+ srcoffset = decode_rm00_address(rl);
2945+ srcval = fetch_data_byte(srcoffset);
2946+ DECODE_PRINTF("\n");
2947+ TRACE_AND_STEP();
2948+ *destreg = xor_byte(*destreg, srcval);
2949+ break;
2950+ case 1:
2951+ destreg = DECODE_RM_BYTE_REGISTER(rh);
2952+ DECODE_PRINTF(",");
2953+ srcoffset = decode_rm01_address(rl);
2954+ srcval = fetch_data_byte(srcoffset);
2955+ DECODE_PRINTF("\n");
2956+ TRACE_AND_STEP();
2957+ *destreg = xor_byte(*destreg, srcval);
2958+ break;
2959+ case 2:
2960+ destreg = DECODE_RM_BYTE_REGISTER(rh);
2961+ DECODE_PRINTF(",");
2962+ srcoffset = decode_rm10_address(rl);
2963+ srcval = fetch_data_byte(srcoffset);
2964+ DECODE_PRINTF("\n");
2965+ TRACE_AND_STEP();
2966+ *destreg = xor_byte(*destreg, srcval);
2967+ break;
2968+ case 3: /* register to register */
2969+ destreg = DECODE_RM_BYTE_REGISTER(rh);
2970+ DECODE_PRINTF(",");
2971+ srcreg = DECODE_RM_BYTE_REGISTER(rl);
2972+ DECODE_PRINTF("\n");
2973+ TRACE_AND_STEP();
2974+ *destreg = xor_byte(*destreg, *srcreg);
2975+ break;
2976+ }
2977+ DECODE_CLEAR_SEGOVR();
2978+ END_OF_INSTR();
2979+}
2980+
2981+/****************************************************************************
2982+REMARKS:
2983+Handles opcode 0x33
2984+****************************************************************************/
2985+static void
2986+x86emuOp_xor_word_R_RM(u8 X86EMU_UNUSED(op1))
2987+{
2988+ int mod, rl, rh;
2989+ uint srcoffset;
2990+
2991+ START_OF_INSTR();
2992+ DECODE_PRINTF("XOR\t");
2993+ FETCH_DECODE_MODRM(mod, rh, rl);
2994+ switch (mod) {
2995+ case 0:
2996+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2997+ u32 *destreg;
2998+ u32 srcval;
2999+
3000+ destreg = DECODE_RM_LONG_REGISTER(rh);
3001+ DECODE_PRINTF(",");
3002+ srcoffset = decode_rm00_address(rl);
3003+ srcval = fetch_data_long(srcoffset);
3004+ DECODE_PRINTF("\n");
3005+ TRACE_AND_STEP();
3006+ *destreg = xor_long(*destreg, srcval);
3007+ }
3008+ else {
3009+ u16 *destreg;
3010+ u16 srcval;
3011+
3012+ destreg = DECODE_RM_WORD_REGISTER(rh);
3013+ DECODE_PRINTF(",");
3014+ srcoffset = decode_rm00_address(rl);
3015+ srcval = fetch_data_word(srcoffset);
3016+ DECODE_PRINTF("\n");
3017+ TRACE_AND_STEP();
3018+ *destreg = xor_word(*destreg, srcval);
3019+ }
3020+ break;
3021+ case 1:
3022+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3023+ u32 *destreg;
3024+ u32 srcval;
3025+
3026+ destreg = DECODE_RM_LONG_REGISTER(rh);
3027+ DECODE_PRINTF(",");
3028+ srcoffset = decode_rm01_address(rl);
3029+ srcval = fetch_data_long(srcoffset);
3030+ DECODE_PRINTF("\n");
3031+ TRACE_AND_STEP();
3032+ *destreg = xor_long(*destreg, srcval);
3033+ }
3034+ else {
3035+ u16 *destreg;
3036+ u16 srcval;
3037+
3038+ destreg = DECODE_RM_WORD_REGISTER(rh);
3039+ DECODE_PRINTF(",");
3040+ srcoffset = decode_rm01_address(rl);
3041+ srcval = fetch_data_word(srcoffset);
3042+ DECODE_PRINTF("\n");
3043+ TRACE_AND_STEP();
3044+ *destreg = xor_word(*destreg, srcval);
3045+ }
3046+ break;
3047+ case 2:
3048+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3049+ u32 *destreg;
3050+ u32 srcval;
3051+
3052+ destreg = DECODE_RM_LONG_REGISTER(rh);
3053+ DECODE_PRINTF(",");
3054+ srcoffset = decode_rm10_address(rl);
3055+ srcval = fetch_data_long(srcoffset);
3056+ DECODE_PRINTF("\n");
3057+ TRACE_AND_STEP();
3058+ *destreg = xor_long(*destreg, srcval);
3059+ }
3060+ else {
3061+ u16 *destreg;
3062+ u16 srcval;
3063+
3064+ destreg = DECODE_RM_WORD_REGISTER(rh);
3065+ DECODE_PRINTF(",");
3066+ srcoffset = decode_rm10_address(rl);
3067+ srcval = fetch_data_word(srcoffset);
3068+ DECODE_PRINTF("\n");
3069+ TRACE_AND_STEP();
3070+ *destreg = xor_word(*destreg, srcval);
3071+ }
3072+ break;
3073+ case 3: /* register to register */
3074+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3075+ u32 *destreg, *srcreg;
3076+
3077+ destreg = DECODE_RM_LONG_REGISTER(rh);
3078+ DECODE_PRINTF(",");
3079+ srcreg = DECODE_RM_LONG_REGISTER(rl);
3080+ DECODE_PRINTF("\n");
3081+ TRACE_AND_STEP();
3082+ *destreg = xor_long(*destreg, *srcreg);
3083+ }
3084+ else {
3085+ u16 *destreg, *srcreg;
3086+
3087+ destreg = DECODE_RM_WORD_REGISTER(rh);
3088+ DECODE_PRINTF(",");
3089+ srcreg = DECODE_RM_WORD_REGISTER(rl);
3090+ DECODE_PRINTF("\n");
3091+ TRACE_AND_STEP();
3092+ *destreg = xor_word(*destreg, *srcreg);
3093+ }
3094+ break;
3095+ }
3096+ DECODE_CLEAR_SEGOVR();
3097+ END_OF_INSTR();
3098+}
3099+
3100+/****************************************************************************
3101+REMARKS:
3102+Handles opcode 0x34
3103+****************************************************************************/
3104+static void
3105+x86emuOp_xor_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
3106+{
3107+ u8 srcval;
3108+
3109+ START_OF_INSTR();
3110+ DECODE_PRINTF("XOR\tAL,");
3111+ srcval = fetch_byte_imm();
3112+ DECODE_PRINTF2("%x\n", srcval);
3113+ TRACE_AND_STEP();
3114+ M.x86.R_AL = xor_byte(M.x86.R_AL, srcval);
3115+ DECODE_CLEAR_SEGOVR();
3116+ END_OF_INSTR();
3117+}
3118+
3119+/****************************************************************************
3120+REMARKS:
3121+Handles opcode 0x35
3122+****************************************************************************/
3123+static void
3124+x86emuOp_xor_word_AX_IMM(u8 X86EMU_UNUSED(op1))
3125+{
3126+ u32 srcval;
3127+
3128+ START_OF_INSTR();
3129+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3130+ DECODE_PRINTF("XOR\tEAX,");
3131+ srcval = fetch_long_imm();
3132+ }
3133+ else {
3134+ DECODE_PRINTF("XOR\tAX,");
3135+ srcval = fetch_word_imm();
3136+ }
3137+ DECODE_PRINTF2("%x\n", srcval);
3138+ TRACE_AND_STEP();
3139+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3140+ M.x86.R_EAX = xor_long(M.x86.R_EAX, srcval);
3141+ }
3142+ else {
3143+ M.x86.R_AX = xor_word(M.x86.R_AX, (u16) srcval);
3144+ }
3145+ DECODE_CLEAR_SEGOVR();
3146+ END_OF_INSTR();
3147+}
3148+
3149+/****************************************************************************
3150+REMARKS:
3151+Handles opcode 0x36
3152+****************************************************************************/
3153+static void
3154+x86emuOp_segovr_SS(u8 X86EMU_UNUSED(op1))
3155+{
3156+ START_OF_INSTR();
3157+ DECODE_PRINTF("SS:\n");
3158+ TRACE_AND_STEP();
3159+ M.x86.mode |= SYSMODE_SEGOVR_SS;
3160+ /* no DECODE_CLEAR_SEGOVR ! */
3161+ END_OF_INSTR();
3162+}
3163+
3164+/****************************************************************************
3165+REMARKS:
3166+Handles opcode 0x37
3167+****************************************************************************/
3168+static void
3169+x86emuOp_aaa(u8 X86EMU_UNUSED(op1))
3170+{
3171+ START_OF_INSTR();
3172+ DECODE_PRINTF("AAA\n");
3173+ TRACE_AND_STEP();
3174+ M.x86.R_AX = aaa_word(M.x86.R_AX);
3175+ DECODE_CLEAR_SEGOVR();
3176+ END_OF_INSTR();
3177+}
3178+
3179+/****************************************************************************
3180+REMARKS:
3181+Handles opcode 0x38
3182+****************************************************************************/
3183+static void
3184+x86emuOp_cmp_byte_RM_R(u8 X86EMU_UNUSED(op1))
3185+{
3186+ int mod, rl, rh;
3187+ uint destoffset;
3188+ u8 *destreg, *srcreg;
3189+ u8 destval;
3190+
3191+ START_OF_INSTR();
3192+ DECODE_PRINTF("CMP\t");
3193+ FETCH_DECODE_MODRM(mod, rh, rl);
3194+ switch (mod) {
3195+ case 0:
3196+ destoffset = decode_rm00_address(rl);
3197+ DECODE_PRINTF(",");
3198+ destval = fetch_data_byte(destoffset);
3199+ srcreg = DECODE_RM_BYTE_REGISTER(rh);
3200+ DECODE_PRINTF("\n");
3201+ TRACE_AND_STEP();
3202+ cmp_byte(destval, *srcreg);
3203+ break;
3204+ case 1:
3205+ destoffset = decode_rm01_address(rl);
3206+ DECODE_PRINTF(",");
3207+ destval = fetch_data_byte(destoffset);
3208+ srcreg = DECODE_RM_BYTE_REGISTER(rh);
3209+ DECODE_PRINTF("\n");
3210+ TRACE_AND_STEP();
3211+ cmp_byte(destval, *srcreg);
3212+ break;
3213+ case 2:
3214+ destoffset = decode_rm10_address(rl);
3215+ DECODE_PRINTF(",");
3216+ destval = fetch_data_byte(destoffset);
3217+ srcreg = DECODE_RM_BYTE_REGISTER(rh);
3218+ DECODE_PRINTF("\n");
3219+ TRACE_AND_STEP();
3220+ cmp_byte(destval, *srcreg);
3221+ break;
3222+ case 3: /* register to register */
3223+ destreg = DECODE_RM_BYTE_REGISTER(rl);
3224+ DECODE_PRINTF(",");
3225+ srcreg = DECODE_RM_BYTE_REGISTER(rh);
3226+ DECODE_PRINTF("\n");
3227+ TRACE_AND_STEP();
3228+ cmp_byte(*destreg, *srcreg);
3229+ break;
3230+ }
3231+ DECODE_CLEAR_SEGOVR();
3232+ END_OF_INSTR();
3233+}
3234+
3235+/****************************************************************************
3236+REMARKS:
3237+Handles opcode 0x39
3238+****************************************************************************/
3239+static void
3240+x86emuOp_cmp_word_RM_R(u8 X86EMU_UNUSED(op1))
3241+{
3242+ int mod, rl, rh;
3243+ uint destoffset;
3244+
3245+ START_OF_INSTR();
3246+ DECODE_PRINTF("CMP\t");
3247+ FETCH_DECODE_MODRM(mod, rh, rl);
3248+ switch (mod) {
3249+ case 0:
3250+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3251+ u32 destval;
3252+ u32 *srcreg;
3253+
3254+ destoffset = decode_rm00_address(rl);
3255+ DECODE_PRINTF(",");
3256+ destval = fetch_data_long(destoffset);
3257+ srcreg = DECODE_RM_LONG_REGISTER(rh);
3258+ DECODE_PRINTF("\n");
3259+ TRACE_AND_STEP();
3260+ cmp_long(destval, *srcreg);
3261+ }
3262+ else {
3263+ u16 destval;
3264+ u16 *srcreg;
3265+
3266+ destoffset = decode_rm00_address(rl);
3267+ DECODE_PRINTF(",");
3268+ destval = fetch_data_word(destoffset);
3269+ srcreg = DECODE_RM_WORD_REGISTER(rh);
3270+ DECODE_PRINTF("\n");
3271+ TRACE_AND_STEP();
3272+ cmp_word(destval, *srcreg);
3273+ }
3274+ break;
3275+ case 1:
3276+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3277+ u32 destval;
3278+ u32 *srcreg;
3279+
3280+ destoffset = decode_rm01_address(rl);
3281+ DECODE_PRINTF(",");
3282+ destval = fetch_data_long(destoffset);
3283+ srcreg = DECODE_RM_LONG_REGISTER(rh);
3284+ DECODE_PRINTF("\n");
3285+ TRACE_AND_STEP();
3286+ cmp_long(destval, *srcreg);
3287+ }
3288+ else {
3289+ u16 destval;
3290+ u16 *srcreg;
3291+
3292+ destoffset = decode_rm01_address(rl);
3293+ DECODE_PRINTF(",");
3294+ destval = fetch_data_word(destoffset);
3295+ srcreg = DECODE_RM_WORD_REGISTER(rh);
3296+ DECODE_PRINTF("\n");
3297+ TRACE_AND_STEP();
3298+ cmp_word(destval, *srcreg);
3299+ }
3300+ break;
3301+ case 2:
3302+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3303+ u32 destval;
3304+ u32 *srcreg;
3305+
3306+ destoffset = decode_rm10_address(rl);
3307+ DECODE_PRINTF(",");
3308+ destval = fetch_data_long(destoffset);
3309+ srcreg = DECODE_RM_LONG_REGISTER(rh);
3310+ DECODE_PRINTF("\n");
3311+ TRACE_AND_STEP();
3312+ cmp_long(destval, *srcreg);
3313+ }
3314+ else {
3315+ u16 destval;
3316+ u16 *srcreg;
3317+
3318+ destoffset = decode_rm10_address(rl);
3319+ DECODE_PRINTF(",");
3320+ destval = fetch_data_word(destoffset);
3321+ srcreg = DECODE_RM_WORD_REGISTER(rh);
3322+ DECODE_PRINTF("\n");
3323+ TRACE_AND_STEP();
3324+ cmp_word(destval, *srcreg);
3325+ }
3326+ break;
3327+ case 3: /* register to register */
3328+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3329+ u32 *destreg, *srcreg;
3330+
3331+ destreg = DECODE_RM_LONG_REGISTER(rl);
3332+ DECODE_PRINTF(",");
3333+ srcreg = DECODE_RM_LONG_REGISTER(rh);
3334+ DECODE_PRINTF("\n");
3335+ TRACE_AND_STEP();
3336+ cmp_long(*destreg, *srcreg);
3337+ }
3338+ else {
3339+ u16 *destreg, *srcreg;
3340+
3341+ destreg = DECODE_RM_WORD_REGISTER(rl);
3342+ DECODE_PRINTF(",");
3343+ srcreg = DECODE_RM_WORD_REGISTER(rh);
3344+ DECODE_PRINTF("\n");
3345+ TRACE_AND_STEP();
3346+ cmp_word(*destreg, *srcreg);
3347+ }
3348+ break;
3349+ }
3350+ DECODE_CLEAR_SEGOVR();
3351+ END_OF_INSTR();
3352+}
3353+
3354+/****************************************************************************
3355+REMARKS:
3356+Handles opcode 0x3a
3357+****************************************************************************/
3358+static void
3359+x86emuOp_cmp_byte_R_RM(u8 X86EMU_UNUSED(op1))
3360+{
3361+ int mod, rl, rh;
3362+ u8 *destreg, *srcreg;
3363+ uint srcoffset;
3364+ u8 srcval;
3365+
3366+ START_OF_INSTR();
3367+ DECODE_PRINTF("CMP\t");
3368+ FETCH_DECODE_MODRM(mod, rh, rl);
3369+ switch (mod) {
3370+ case 0:
3371+ destreg = DECODE_RM_BYTE_REGISTER(rh);
3372+ DECODE_PRINTF(",");
3373+ srcoffset = decode_rm00_address(rl);
3374+ srcval = fetch_data_byte(srcoffset);
3375+ DECODE_PRINTF("\n");
3376+ TRACE_AND_STEP();
3377+ cmp_byte(*destreg, srcval);
3378+ break;
3379+ case 1:
3380+ destreg = DECODE_RM_BYTE_REGISTER(rh);
3381+ DECODE_PRINTF(",");
3382+ srcoffset = decode_rm01_address(rl);
3383+ srcval = fetch_data_byte(srcoffset);
3384+ DECODE_PRINTF("\n");
3385+ TRACE_AND_STEP();
3386+ cmp_byte(*destreg, srcval);
3387+ break;
3388+ case 2:
3389+ destreg = DECODE_RM_BYTE_REGISTER(rh);
3390+ DECODE_PRINTF(",");
3391+ srcoffset = decode_rm10_address(rl);
3392+ srcval = fetch_data_byte(srcoffset);
3393+ DECODE_PRINTF("\n");
3394+ TRACE_AND_STEP();
3395+ cmp_byte(*destreg, srcval);
3396+ break;
3397+ case 3: /* register to register */
3398+ destreg = DECODE_RM_BYTE_REGISTER(rh);
3399+ DECODE_PRINTF(",");
3400+ srcreg = DECODE_RM_BYTE_REGISTER(rl);
3401+ DECODE_PRINTF("\n");
3402+ TRACE_AND_STEP();
3403+ cmp_byte(*destreg, *srcreg);
3404+ break;
3405+ }
3406+ DECODE_CLEAR_SEGOVR();
3407+ END_OF_INSTR();
3408+}
3409+
3410+/****************************************************************************
3411+REMARKS:
3412+Handles opcode 0x3b
3413+****************************************************************************/
3414+static void
3415+x86emuOp_cmp_word_R_RM(u8 X86EMU_UNUSED(op1))
3416+{
3417+ int mod, rl, rh;
3418+ uint srcoffset;
3419+
3420+ START_OF_INSTR();
3421+ DECODE_PRINTF("CMP\t");
3422+ FETCH_DECODE_MODRM(mod, rh, rl);
3423+ switch (mod) {
3424+ case 0:
3425+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3426+ u32 *destreg;
3427+ u32 srcval;
3428+
3429+ destreg = DECODE_RM_LONG_REGISTER(rh);
3430+ DECODE_PRINTF(",");
3431+ srcoffset = decode_rm00_address(rl);
3432+ srcval = fetch_data_long(srcoffset);
3433+ DECODE_PRINTF("\n");
3434+ TRACE_AND_STEP();
3435+ cmp_long(*destreg, srcval);
3436+ }
3437+ else {
3438+ u16 *destreg;
3439+ u16 srcval;
3440+
3441+ destreg = DECODE_RM_WORD_REGISTER(rh);
3442+ DECODE_PRINTF(",");
3443+ srcoffset = decode_rm00_address(rl);
3444+ srcval = fetch_data_word(srcoffset);
3445+ DECODE_PRINTF("\n");
3446+ TRACE_AND_STEP();
3447+ cmp_word(*destreg, srcval);
3448+ }
3449+ break;
3450+ case 1:
3451+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3452+ u32 *destreg;
3453+ u32 srcval;
3454+
3455+ destreg = DECODE_RM_LONG_REGISTER(rh);
3456+ DECODE_PRINTF(",");
3457+ srcoffset = decode_rm01_address(rl);
3458+ srcval = fetch_data_long(srcoffset);
3459+ DECODE_PRINTF("\n");
3460+ TRACE_AND_STEP();
3461+ cmp_long(*destreg, srcval);
3462+ }
3463+ else {
3464+ u16 *destreg;
3465+ u16 srcval;
3466+
3467+ destreg = DECODE_RM_WORD_REGISTER(rh);
3468+ DECODE_PRINTF(",");
3469+ srcoffset = decode_rm01_address(rl);
3470+ srcval = fetch_data_word(srcoffset);
3471+ DECODE_PRINTF("\n");
3472+ TRACE_AND_STEP();
3473+ cmp_word(*destreg, srcval);
3474+ }
3475+ break;
3476+ case 2:
3477+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3478+ u32 *destreg;
3479+ u32 srcval;
3480+
3481+ destreg = DECODE_RM_LONG_REGISTER(rh);
3482+ DECODE_PRINTF(",");
3483+ srcoffset = decode_rm10_address(rl);
3484+ srcval = fetch_data_long(srcoffset);
3485+ DECODE_PRINTF("\n");
3486+ TRACE_AND_STEP();
3487+ cmp_long(*destreg, srcval);
3488+ }
3489+ else {
3490+ u16 *destreg;
3491+ u16 srcval;
3492+
3493+ destreg = DECODE_RM_WORD_REGISTER(rh);
3494+ DECODE_PRINTF(",");
3495+ srcoffset = decode_rm10_address(rl);
3496+ srcval = fetch_data_word(srcoffset);
3497+ DECODE_PRINTF("\n");
3498+ TRACE_AND_STEP();
3499+ cmp_word(*destreg, srcval);
3500+ }
3501+ break;
3502+ case 3: /* register to register */
3503+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3504+ u32 *destreg, *srcreg;
3505+
3506+ destreg = DECODE_RM_LONG_REGISTER(rh);
3507+ DECODE_PRINTF(",");
3508+ srcreg = DECODE_RM_LONG_REGISTER(rl);
3509+ DECODE_PRINTF("\n");
3510+ TRACE_AND_STEP();
3511+ cmp_long(*destreg, *srcreg);
3512+ }
3513+ else {
3514+ u16 *destreg, *srcreg;
3515+
3516+ destreg = DECODE_RM_WORD_REGISTER(rh);
3517+ DECODE_PRINTF(",");
3518+ srcreg = DECODE_RM_WORD_REGISTER(rl);
3519+ DECODE_PRINTF("\n");
3520+ TRACE_AND_STEP();
3521+ cmp_word(*destreg, *srcreg);
3522+ }
3523+ break;
3524+ }
3525+ DECODE_CLEAR_SEGOVR();
3526+ END_OF_INSTR();
3527+}
3528+
3529+/****************************************************************************
3530+REMARKS:
3531+Handles opcode 0x3c
3532+****************************************************************************/
3533+static void
3534+x86emuOp_cmp_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
3535+{
3536+ u8 srcval;
3537+
3538+ START_OF_INSTR();
3539+ DECODE_PRINTF("CMP\tAL,");
3540+ srcval = fetch_byte_imm();
3541+ DECODE_PRINTF2("%x\n", srcval);
3542+ TRACE_AND_STEP();
3543+ cmp_byte(M.x86.R_AL, srcval);
3544+ DECODE_CLEAR_SEGOVR();
3545+ END_OF_INSTR();
3546+}
3547+
3548+/****************************************************************************
3549+REMARKS:
3550+Handles opcode 0x3d
3551+****************************************************************************/
3552+static void
3553+x86emuOp_cmp_word_AX_IMM(u8 X86EMU_UNUSED(op1))
3554+{
3555+ u32 srcval;
3556+
3557+ START_OF_INSTR();
3558+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3559+ DECODE_PRINTF("CMP\tEAX,");
3560+ srcval = fetch_long_imm();
3561+ }
3562+ else {
3563+ DECODE_PRINTF("CMP\tAX,");
3564+ srcval = fetch_word_imm();
3565+ }
3566+ DECODE_PRINTF2("%x\n", srcval);
3567+ TRACE_AND_STEP();
3568+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3569+ cmp_long(M.x86.R_EAX, srcval);
3570+ }
3571+ else {
3572+ cmp_word(M.x86.R_AX, (u16) srcval);
3573+ }
3574+ DECODE_CLEAR_SEGOVR();
3575+ END_OF_INSTR();
3576+}
3577+
3578+/****************************************************************************
3579+REMARKS:
3580+Handles opcode 0x3e
3581+****************************************************************************/
3582+static void
3583+x86emuOp_segovr_DS(u8 X86EMU_UNUSED(op1))
3584+{
3585+ START_OF_INSTR();
3586+ DECODE_PRINTF("DS:\n");
3587+ TRACE_AND_STEP();
3588+ M.x86.mode |= SYSMODE_SEGOVR_DS;
3589+ /* NO DECODE_CLEAR_SEGOVR! */
3590+ END_OF_INSTR();
3591+}
3592+
3593+/****************************************************************************
3594+REMARKS:
3595+Handles opcode 0x3f
3596+****************************************************************************/
3597+static void
3598+x86emuOp_aas(u8 X86EMU_UNUSED(op1))
3599+{
3600+ START_OF_INSTR();
3601+ DECODE_PRINTF("AAS\n");
3602+ TRACE_AND_STEP();
3603+ M.x86.R_AX = aas_word(M.x86.R_AX);
3604+ DECODE_CLEAR_SEGOVR();
3605+ END_OF_INSTR();
3606+}
3607+
3608+/****************************************************************************
3609+REMARKS:
3610+Handles opcode 0x40
3611+****************************************************************************/
3612+static void
3613+x86emuOp_inc_AX(u8 X86EMU_UNUSED(op1))
3614+{
3615+ START_OF_INSTR();
3616+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3617+ DECODE_PRINTF("INC\tEAX\n");
3618+ }
3619+ else {
3620+ DECODE_PRINTF("INC\tAX\n");
3621+ }
3622+ TRACE_AND_STEP();
3623+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3624+ M.x86.R_EAX = inc_long(M.x86.R_EAX);
3625+ }
3626+ else {
3627+ M.x86.R_AX = inc_word(M.x86.R_AX);
3628+ }
3629+ DECODE_CLEAR_SEGOVR();
3630+ END_OF_INSTR();
3631+}
3632+
3633+/****************************************************************************
3634+REMARKS:
3635+Handles opcode 0x41
3636+****************************************************************************/
3637+static void
3638+x86emuOp_inc_CX(u8 X86EMU_UNUSED(op1))
3639+{
3640+ START_OF_INSTR();
3641+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3642+ DECODE_PRINTF("INC\tECX\n");
3643+ }
3644+ else {
3645+ DECODE_PRINTF("INC\tCX\n");
3646+ }
3647+ TRACE_AND_STEP();
3648+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3649+ M.x86.R_ECX = inc_long(M.x86.R_ECX);
3650+ }
3651+ else {
3652+ M.x86.R_CX = inc_word(M.x86.R_CX);
3653+ }
3654+ DECODE_CLEAR_SEGOVR();
3655+ END_OF_INSTR();
3656+}
3657+
3658+/****************************************************************************
3659+REMARKS:
3660+Handles opcode 0x42
3661+****************************************************************************/
3662+static void
3663+x86emuOp_inc_DX(u8 X86EMU_UNUSED(op1))
3664+{
3665+ START_OF_INSTR();
3666+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3667+ DECODE_PRINTF("INC\tEDX\n");
3668+ }
3669+ else {
3670+ DECODE_PRINTF("INC\tDX\n");
3671+ }
3672+ TRACE_AND_STEP();
3673+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3674+ M.x86.R_EDX = inc_long(M.x86.R_EDX);
3675+ }
3676+ else {
3677+ M.x86.R_DX = inc_word(M.x86.R_DX);
3678+ }
3679+ DECODE_CLEAR_SEGOVR();
3680+ END_OF_INSTR();
3681+}
3682+
3683+/****************************************************************************
3684+REMARKS:
3685+Handles opcode 0x43
3686+****************************************************************************/
3687+static void
3688+x86emuOp_inc_BX(u8 X86EMU_UNUSED(op1))
3689+{
3690+ START_OF_INSTR();
3691+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3692+ DECODE_PRINTF("INC\tEBX\n");
3693+ }
3694+ else {
3695+ DECODE_PRINTF("INC\tBX\n");
3696+ }
3697+ TRACE_AND_STEP();
3698+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3699+ M.x86.R_EBX = inc_long(M.x86.R_EBX);
3700+ }
3701+ else {
3702+ M.x86.R_BX = inc_word(M.x86.R_BX);
3703+ }
3704+ DECODE_CLEAR_SEGOVR();
3705+ END_OF_INSTR();
3706+}
3707+
3708+/****************************************************************************
3709+REMARKS:
3710+Handles opcode 0x44
3711+****************************************************************************/
3712+static void
3713+x86emuOp_inc_SP(u8 X86EMU_UNUSED(op1))
3714+{
3715+ START_OF_INSTR();
3716+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3717+ DECODE_PRINTF("INC\tESP\n");
3718+ }
3719+ else {
3720+ DECODE_PRINTF("INC\tSP\n");
3721+ }
3722+ TRACE_AND_STEP();
3723+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3724+ M.x86.R_ESP = inc_long(M.x86.R_ESP);
3725+ }
3726+ else {
3727+ M.x86.R_SP = inc_word(M.x86.R_SP);
3728+ }
3729+ DECODE_CLEAR_SEGOVR();
3730+ END_OF_INSTR();
3731+}
3732+
3733+/****************************************************************************
3734+REMARKS:
3735+Handles opcode 0x45
3736+****************************************************************************/
3737+static void
3738+x86emuOp_inc_BP(u8 X86EMU_UNUSED(op1))
3739+{
3740+ START_OF_INSTR();
3741+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3742+ DECODE_PRINTF("INC\tEBP\n");
3743+ }
3744+ else {
3745+ DECODE_PRINTF("INC\tBP\n");
3746+ }
3747+ TRACE_AND_STEP();
3748+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3749+ M.x86.R_EBP = inc_long(M.x86.R_EBP);
3750+ }
3751+ else {
3752+ M.x86.R_BP = inc_word(M.x86.R_BP);
3753+ }
3754+ DECODE_CLEAR_SEGOVR();
3755+ END_OF_INSTR();
3756+}
3757+
3758+/****************************************************************************
3759+REMARKS:
3760+Handles opcode 0x46
3761+****************************************************************************/
3762+static void
3763+x86emuOp_inc_SI(u8 X86EMU_UNUSED(op1))
3764+{
3765+ START_OF_INSTR();
3766+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3767+ DECODE_PRINTF("INC\tESI\n");
3768+ }
3769+ else {
3770+ DECODE_PRINTF("INC\tSI\n");
3771+ }
3772+ TRACE_AND_STEP();
3773+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3774+ M.x86.R_ESI = inc_long(M.x86.R_ESI);
3775+ }
3776+ else {
3777+ M.x86.R_SI = inc_word(M.x86.R_SI);
3778+ }
3779+ DECODE_CLEAR_SEGOVR();
3780+ END_OF_INSTR();
3781+}
3782+
3783+/****************************************************************************
3784+REMARKS:
3785+Handles opcode 0x47
3786+****************************************************************************/
3787+static void
3788+x86emuOp_inc_DI(u8 X86EMU_UNUSED(op1))
3789+{
3790+ START_OF_INSTR();
3791+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3792+ DECODE_PRINTF("INC\tEDI\n");
3793+ }
3794+ else {
3795+ DECODE_PRINTF("INC\tDI\n");
3796+ }
3797+ TRACE_AND_STEP();
3798+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3799+ M.x86.R_EDI = inc_long(M.x86.R_EDI);
3800+ }
3801+ else {
3802+ M.x86.R_DI = inc_word(M.x86.R_DI);
3803+ }
3804+ DECODE_CLEAR_SEGOVR();
3805+ END_OF_INSTR();
3806+}
3807+
3808+/****************************************************************************
3809+REMARKS:
3810+Handles opcode 0x48
3811+****************************************************************************/
3812+static void
3813+x86emuOp_dec_AX(u8 X86EMU_UNUSED(op1))
3814+{
3815+ START_OF_INSTR();
3816+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3817+ DECODE_PRINTF("DEC\tEAX\n");
3818+ }
3819+ else {
3820+ DECODE_PRINTF("DEC\tAX\n");
3821+ }
3822+ TRACE_AND_STEP();
3823+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3824+ M.x86.R_EAX = dec_long(M.x86.R_EAX);
3825+ }
3826+ else {
3827+ M.x86.R_AX = dec_word(M.x86.R_AX);
3828+ }
3829+ DECODE_CLEAR_SEGOVR();
3830+ END_OF_INSTR();
3831+}
3832+
3833+/****************************************************************************
3834+REMARKS:
3835+Handles opcode 0x49
3836+****************************************************************************/
3837+static void
3838+x86emuOp_dec_CX(u8 X86EMU_UNUSED(op1))
3839+{
3840+ START_OF_INSTR();
3841+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3842+ DECODE_PRINTF("DEC\tECX\n");
3843+ }
3844+ else {
3845+ DECODE_PRINTF("DEC\tCX\n");
3846+ }
3847+ TRACE_AND_STEP();
3848+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3849+ M.x86.R_ECX = dec_long(M.x86.R_ECX);
3850+ }
3851+ else {
3852+ M.x86.R_CX = dec_word(M.x86.R_CX);
3853+ }
3854+ DECODE_CLEAR_SEGOVR();
3855+ END_OF_INSTR();
3856+}
3857+
3858+/****************************************************************************
3859+REMARKS:
3860+Handles opcode 0x4a
3861+****************************************************************************/
3862+static void
3863+x86emuOp_dec_DX(u8 X86EMU_UNUSED(op1))
3864+{
3865+ START_OF_INSTR();
3866+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3867+ DECODE_PRINTF("DEC\tEDX\n");
3868+ }
3869+ else {
3870+ DECODE_PRINTF("DEC\tDX\n");
3871+ }
3872+ TRACE_AND_STEP();
3873+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3874+ M.x86.R_EDX = dec_long(M.x86.R_EDX);
3875+ }
3876+ else {
3877+ M.x86.R_DX = dec_word(M.x86.R_DX);
3878+ }
3879+ DECODE_CLEAR_SEGOVR();
3880+ END_OF_INSTR();
3881+}
3882+
3883+/****************************************************************************
3884+REMARKS:
3885+Handles opcode 0x4b
3886+****************************************************************************/
3887+static void
3888+x86emuOp_dec_BX(u8 X86EMU_UNUSED(op1))
3889+{
3890+ START_OF_INSTR();
3891+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3892+ DECODE_PRINTF("DEC\tEBX\n");
3893+ }
3894+ else {
3895+ DECODE_PRINTF("DEC\tBX\n");
3896+ }
3897+ TRACE_AND_STEP();
3898+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3899+ M.x86.R_EBX = dec_long(M.x86.R_EBX);
3900+ }
3901+ else {
3902+ M.x86.R_BX = dec_word(M.x86.R_BX);
3903+ }
3904+ DECODE_CLEAR_SEGOVR();
3905+ END_OF_INSTR();
3906+}
3907+
3908+/****************************************************************************
3909+REMARKS:
3910+Handles opcode 0x4c
3911+****************************************************************************/
3912+static void
3913+x86emuOp_dec_SP(u8 X86EMU_UNUSED(op1))
3914+{
3915+ START_OF_INSTR();
3916+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3917+ DECODE_PRINTF("DEC\tESP\n");
3918+ }
3919+ else {
3920+ DECODE_PRINTF("DEC\tSP\n");
3921+ }
3922+ TRACE_AND_STEP();
3923+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3924+ M.x86.R_ESP = dec_long(M.x86.R_ESP);
3925+ }
3926+ else {
3927+ M.x86.R_SP = dec_word(M.x86.R_SP);
3928+ }
3929+ DECODE_CLEAR_SEGOVR();
3930+ END_OF_INSTR();
3931+}
3932+
3933+/****************************************************************************
3934+REMARKS:
3935+Handles opcode 0x4d
3936+****************************************************************************/
3937+static void
3938+x86emuOp_dec_BP(u8 X86EMU_UNUSED(op1))
3939+{
3940+ START_OF_INSTR();
3941+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3942+ DECODE_PRINTF("DEC\tEBP\n");
3943+ }
3944+ else {
3945+ DECODE_PRINTF("DEC\tBP\n");
3946+ }
3947+ TRACE_AND_STEP();
3948+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3949+ M.x86.R_EBP = dec_long(M.x86.R_EBP);
3950+ }
3951+ else {
3952+ M.x86.R_BP = dec_word(M.x86.R_BP);
3953+ }
3954+ DECODE_CLEAR_SEGOVR();
3955+ END_OF_INSTR();
3956+}
3957+
3958+/****************************************************************************
3959+REMARKS:
3960+Handles opcode 0x4e
3961+****************************************************************************/
3962+static void
3963+x86emuOp_dec_SI(u8 X86EMU_UNUSED(op1))
3964+{
3965+ START_OF_INSTR();
3966+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3967+ DECODE_PRINTF("DEC\tESI\n");
3968+ }
3969+ else {
3970+ DECODE_PRINTF("DEC\tSI\n");
3971+ }
3972+ TRACE_AND_STEP();
3973+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3974+ M.x86.R_ESI = dec_long(M.x86.R_ESI);
3975+ }
3976+ else {
3977+ M.x86.R_SI = dec_word(M.x86.R_SI);
3978+ }
3979+ DECODE_CLEAR_SEGOVR();
3980+ END_OF_INSTR();
3981+}
3982+
3983+/****************************************************************************
3984+REMARKS:
3985+Handles opcode 0x4f
3986+****************************************************************************/
3987+static void
3988+x86emuOp_dec_DI(u8 X86EMU_UNUSED(op1))
3989+{
3990+ START_OF_INSTR();
3991+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3992+ DECODE_PRINTF("DEC\tEDI\n");
3993+ }
3994+ else {
3995+ DECODE_PRINTF("DEC\tDI\n");
3996+ }
3997+ TRACE_AND_STEP();
3998+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3999+ M.x86.R_EDI = dec_long(M.x86.R_EDI);
4000+ }
4001+ else {
4002+ M.x86.R_DI = dec_word(M.x86.R_DI);
4003+ }
4004+ DECODE_CLEAR_SEGOVR();
4005+ END_OF_INSTR();
4006+}
4007+
4008+/****************************************************************************
4009+REMARKS:
4010+Handles opcode 0x50
4011+****************************************************************************/
4012+static void
4013+x86emuOp_push_AX(u8 X86EMU_UNUSED(op1))
4014+{
4015+ START_OF_INSTR();
4016+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4017+ DECODE_PRINTF("PUSH\tEAX\n");
4018+ }
4019+ else {
4020+ DECODE_PRINTF("PUSH\tAX\n");
4021+ }
4022+ TRACE_AND_STEP();
4023+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4024+ push_long(M.x86.R_EAX);
4025+ }
4026+ else {
4027+ push_word(M.x86.R_AX);
4028+ }
4029+ DECODE_CLEAR_SEGOVR();
4030+ END_OF_INSTR();
4031+}
4032+
4033+/****************************************************************************
4034+REMARKS:
4035+Handles opcode 0x51
4036+****************************************************************************/
4037+static void
4038+x86emuOp_push_CX(u8 X86EMU_UNUSED(op1))
4039+{
4040+ START_OF_INSTR();
4041+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4042+ DECODE_PRINTF("PUSH\tECX\n");
4043+ }
4044+ else {
4045+ DECODE_PRINTF("PUSH\tCX\n");
4046+ }
4047+ TRACE_AND_STEP();
4048+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4049+ push_long(M.x86.R_ECX);
4050+ }
4051+ else {
4052+ push_word(M.x86.R_CX);
4053+ }
4054+ DECODE_CLEAR_SEGOVR();
4055+ END_OF_INSTR();
4056+}
4057+
4058+/****************************************************************************
4059+REMARKS:
4060+Handles opcode 0x52
4061+****************************************************************************/
4062+static void
4063+x86emuOp_push_DX(u8 X86EMU_UNUSED(op1))
4064+{
4065+ START_OF_INSTR();
4066+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4067+ DECODE_PRINTF("PUSH\tEDX\n");
4068+ }
4069+ else {
4070+ DECODE_PRINTF("PUSH\tDX\n");
4071+ }
4072+ TRACE_AND_STEP();
4073+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4074+ push_long(M.x86.R_EDX);
4075+ }
4076+ else {
4077+ push_word(M.x86.R_DX);
4078+ }
4079+ DECODE_CLEAR_SEGOVR();
4080+ END_OF_INSTR();
4081+}
4082+
4083+/****************************************************************************
4084+REMARKS:
4085+Handles opcode 0x53
4086+****************************************************************************/
4087+static void
4088+x86emuOp_push_BX(u8 X86EMU_UNUSED(op1))
4089+{
4090+ START_OF_INSTR();
4091+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4092+ DECODE_PRINTF("PUSH\tEBX\n");
4093+ }
4094+ else {
4095+ DECODE_PRINTF("PUSH\tBX\n");
4096+ }
4097+ TRACE_AND_STEP();
4098+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4099+ push_long(M.x86.R_EBX);
4100+ }
4101+ else {
4102+ push_word(M.x86.R_BX);
4103+ }
4104+ DECODE_CLEAR_SEGOVR();
4105+ END_OF_INSTR();
4106+}
4107+
4108+/****************************************************************************
4109+REMARKS:
4110+Handles opcode 0x54
4111+****************************************************************************/
4112+static void
4113+x86emuOp_push_SP(u8 X86EMU_UNUSED(op1))
4114+{
4115+ START_OF_INSTR();
4116+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4117+ DECODE_PRINTF("PUSH\tESP\n");
4118+ }
4119+ else {
4120+ DECODE_PRINTF("PUSH\tSP\n");
4121+ }
4122+ TRACE_AND_STEP();
4123+ /* Always push (E)SP, since we are emulating an i386 and above
4124+ * processor. This is necessary as some BIOS'es use this to check
4125+ * what type of processor is in the system.
4126+ */
4127+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4128+ push_long(M.x86.R_ESP);
4129+ }
4130+ else {
4131+ push_word((u16) (M.x86.R_SP));
4132+ }
4133+ DECODE_CLEAR_SEGOVR();
4134+ END_OF_INSTR();
4135+}
4136+
4137+/****************************************************************************
4138+REMARKS:
4139+Handles opcode 0x55
4140+****************************************************************************/
4141+static void
4142+x86emuOp_push_BP(u8 X86EMU_UNUSED(op1))
4143+{
4144+ START_OF_INSTR();
4145+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4146+ DECODE_PRINTF("PUSH\tEBP\n");
4147+ }
4148+ else {
4149+ DECODE_PRINTF("PUSH\tBP\n");
4150+ }
4151+ TRACE_AND_STEP();
4152+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4153+ push_long(M.x86.R_EBP);
4154+ }
4155+ else {
4156+ push_word(M.x86.R_BP);
4157+ }
4158+ DECODE_CLEAR_SEGOVR();
4159+ END_OF_INSTR();
4160+}
4161+
4162+/****************************************************************************
4163+REMARKS:
4164+Handles opcode 0x56
4165+****************************************************************************/
4166+static void
4167+x86emuOp_push_SI(u8 X86EMU_UNUSED(op1))
4168+{
4169+ START_OF_INSTR();
4170+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4171+ DECODE_PRINTF("PUSH\tESI\n");
4172+ }
4173+ else {
4174+ DECODE_PRINTF("PUSH\tSI\n");
4175+ }
4176+ TRACE_AND_STEP();
4177+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4178+ push_long(M.x86.R_ESI);
4179+ }
4180+ else {
4181+ push_word(M.x86.R_SI);
4182+ }
4183+ DECODE_CLEAR_SEGOVR();
4184+ END_OF_INSTR();
4185+}
4186+
4187+/****************************************************************************
4188+REMARKS:
4189+Handles opcode 0x57
4190+****************************************************************************/
4191+static void
4192+x86emuOp_push_DI(u8 X86EMU_UNUSED(op1))
4193+{
4194+ START_OF_INSTR();
4195+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4196+ DECODE_PRINTF("PUSH\tEDI\n");
4197+ }
4198+ else {
4199+ DECODE_PRINTF("PUSH\tDI\n");
4200+ }
4201+ TRACE_AND_STEP();
4202+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4203+ push_long(M.x86.R_EDI);
4204+ }
4205+ else {
4206+ push_word(M.x86.R_DI);
4207+ }
4208+ DECODE_CLEAR_SEGOVR();
4209+ END_OF_INSTR();
4210+}
4211+
4212+/****************************************************************************
4213+REMARKS:
4214+Handles opcode 0x58
4215+****************************************************************************/
4216+static void
4217+x86emuOp_pop_AX(u8 X86EMU_UNUSED(op1))
4218+{
4219+ START_OF_INSTR();
4220+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4221+ DECODE_PRINTF("POP\tEAX\n");
4222+ }
4223+ else {
4224+ DECODE_PRINTF("POP\tAX\n");
4225+ }
4226+ TRACE_AND_STEP();
4227+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4228+ M.x86.R_EAX = pop_long();
4229+ }
4230+ else {
4231+ M.x86.R_AX = pop_word();
4232+ }
4233+ DECODE_CLEAR_SEGOVR();
4234+ END_OF_INSTR();
4235+}
4236+
4237+/****************************************************************************
4238+REMARKS:
4239+Handles opcode 0x59
4240+****************************************************************************/
4241+static void
4242+x86emuOp_pop_CX(u8 X86EMU_UNUSED(op1))
4243+{
4244+ START_OF_INSTR();
4245+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4246+ DECODE_PRINTF("POP\tECX\n");
4247+ }
4248+ else {
4249+ DECODE_PRINTF("POP\tCX\n");
4250+ }
4251+ TRACE_AND_STEP();
4252+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4253+ M.x86.R_ECX = pop_long();
4254+ }
4255+ else {
4256+ M.x86.R_CX = pop_word();
4257+ }
4258+ DECODE_CLEAR_SEGOVR();
4259+ END_OF_INSTR();
4260+}
4261+
4262+/****************************************************************************
4263+REMARKS:
4264+Handles opcode 0x5a
4265+****************************************************************************/
4266+static void
4267+x86emuOp_pop_DX(u8 X86EMU_UNUSED(op1))
4268+{
4269+ START_OF_INSTR();
4270+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4271+ DECODE_PRINTF("POP\tEDX\n");
4272+ }
4273+ else {
4274+ DECODE_PRINTF("POP\tDX\n");
4275+ }
4276+ TRACE_AND_STEP();
4277+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4278+ M.x86.R_EDX = pop_long();
4279+ }
4280+ else {
4281+ M.x86.R_DX = pop_word();
4282+ }
4283+ DECODE_CLEAR_SEGOVR();
4284+ END_OF_INSTR();
4285+}
4286+
4287+/****************************************************************************
4288+REMARKS:
4289+Handles opcode 0x5b
4290+****************************************************************************/
4291+static void
4292+x86emuOp_pop_BX(u8 X86EMU_UNUSED(op1))
4293+{
4294+ START_OF_INSTR();
4295+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4296+ DECODE_PRINTF("POP\tEBX\n");
4297+ }
4298+ else {
4299+ DECODE_PRINTF("POP\tBX\n");
4300+ }
4301+ TRACE_AND_STEP();
4302+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4303+ M.x86.R_EBX = pop_long();
4304+ }
4305+ else {
4306+ M.x86.R_BX = pop_word();
4307+ }
4308+ DECODE_CLEAR_SEGOVR();
4309+ END_OF_INSTR();
4310+}
4311+
4312+/****************************************************************************
4313+REMARKS:
4314+Handles opcode 0x5c
4315+****************************************************************************/
4316+static void
4317+x86emuOp_pop_SP(u8 X86EMU_UNUSED(op1))
4318+{
4319+ START_OF_INSTR();
4320+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4321+ DECODE_PRINTF("POP\tESP\n");
4322+ }
4323+ else {
4324+ DECODE_PRINTF("POP\tSP\n");
4325+ }
4326+ TRACE_AND_STEP();
4327+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4328+ M.x86.R_ESP = pop_long();
4329+ }
4330+ else {
4331+ M.x86.R_SP = pop_word();
4332+ }
4333+ DECODE_CLEAR_SEGOVR();
4334+ END_OF_INSTR();
4335+}
4336+
4337+/****************************************************************************
4338+REMARKS:
4339+Handles opcode 0x5d
4340+****************************************************************************/
4341+static void
4342+x86emuOp_pop_BP(u8 X86EMU_UNUSED(op1))
4343+{
4344+ START_OF_INSTR();
4345+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4346+ DECODE_PRINTF("POP\tEBP\n");
4347+ }
4348+ else {
4349+ DECODE_PRINTF("POP\tBP\n");
4350+ }
4351+ TRACE_AND_STEP();
4352+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4353+ M.x86.R_EBP = pop_long();
4354+ }
4355+ else {
4356+ M.x86.R_BP = pop_word();
4357+ }
4358+ DECODE_CLEAR_SEGOVR();
4359+ END_OF_INSTR();
4360+}
4361+
4362+/****************************************************************************
4363+REMARKS:
4364+Handles opcode 0x5e
4365+****************************************************************************/
4366+static void
4367+x86emuOp_pop_SI(u8 X86EMU_UNUSED(op1))
4368+{
4369+ START_OF_INSTR();
4370+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4371+ DECODE_PRINTF("POP\tESI\n");
4372+ }
4373+ else {
4374+ DECODE_PRINTF("POP\tSI\n");
4375+ }
4376+ TRACE_AND_STEP();
4377+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4378+ M.x86.R_ESI = pop_long();
4379+ }
4380+ else {
4381+ M.x86.R_SI = pop_word();
4382+ }
4383+ DECODE_CLEAR_SEGOVR();
4384+ END_OF_INSTR();
4385+}
4386+
4387+/****************************************************************************
4388+REMARKS:
4389+Handles opcode 0x5f
4390+****************************************************************************/
4391+static void
4392+x86emuOp_pop_DI(u8 X86EMU_UNUSED(op1))
4393+{
4394+ START_OF_INSTR();
4395+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4396+ DECODE_PRINTF("POP\tEDI\n");
4397+ }
4398+ else {
4399+ DECODE_PRINTF("POP\tDI\n");
4400+ }
4401+ TRACE_AND_STEP();
4402+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4403+ M.x86.R_EDI = pop_long();
4404+ }
4405+ else {
4406+ M.x86.R_DI = pop_word();
4407+ }
4408+ DECODE_CLEAR_SEGOVR();
4409+ END_OF_INSTR();
4410+}
4411+
4412+/****************************************************************************
4413+REMARKS:
4414+Handles opcode 0x60
4415+****************************************************************************/
4416+static void
4417+x86emuOp_push_all(u8 X86EMU_UNUSED(op1))
4418+{
4419+ START_OF_INSTR();
4420+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4421+ DECODE_PRINTF("PUSHAD\n");
4422+ }
4423+ else {
4424+ DECODE_PRINTF("PUSHA\n");
4425+ }
4426+ TRACE_AND_STEP();
4427+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4428+ u32 old_sp = M.x86.R_ESP;
4429+
4430+ push_long(M.x86.R_EAX);
4431+ push_long(M.x86.R_ECX);
4432+ push_long(M.x86.R_EDX);
4433+ push_long(M.x86.R_EBX);
4434+ push_long(old_sp);
4435+ push_long(M.x86.R_EBP);
4436+ push_long(M.x86.R_ESI);
4437+ push_long(M.x86.R_EDI);
4438+ }
4439+ else {
4440+ u16 old_sp = M.x86.R_SP;
4441+
4442+ push_word(M.x86.R_AX);
4443+ push_word(M.x86.R_CX);
4444+ push_word(M.x86.R_DX);
4445+ push_word(M.x86.R_BX);
4446+ push_word(old_sp);
4447+ push_word(M.x86.R_BP);
4448+ push_word(M.x86.R_SI);
4449+ push_word(M.x86.R_DI);
4450+ }
4451+ DECODE_CLEAR_SEGOVR();
4452+ END_OF_INSTR();
4453+}
4454+
4455+/****************************************************************************
4456+REMARKS:
4457+Handles opcode 0x61
4458+****************************************************************************/
4459+static void
4460+x86emuOp_pop_all(u8 X86EMU_UNUSED(op1))
4461+{
4462+ START_OF_INSTR();
4463+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4464+ DECODE_PRINTF("POPAD\n");
4465+ }
4466+ else {
4467+ DECODE_PRINTF("POPA\n");
4468+ }
4469+ TRACE_AND_STEP();
4470+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4471+ M.x86.R_EDI = pop_long();
4472+ M.x86.R_ESI = pop_long();
4473+ M.x86.R_EBP = pop_long();
4474+ M.x86.R_ESP += 4; /* skip ESP */
4475+ M.x86.R_EBX = pop_long();
4476+ M.x86.R_EDX = pop_long();
4477+ M.x86.R_ECX = pop_long();
4478+ M.x86.R_EAX = pop_long();
4479+ }
4480+ else {
4481+ M.x86.R_DI = pop_word();
4482+ M.x86.R_SI = pop_word();
4483+ M.x86.R_BP = pop_word();
4484+ M.x86.R_SP += 2; /* skip SP */
4485+ M.x86.R_BX = pop_word();
4486+ M.x86.R_DX = pop_word();
4487+ M.x86.R_CX = pop_word();
4488+ M.x86.R_AX = pop_word();
4489+ }
4490+ DECODE_CLEAR_SEGOVR();
4491+ END_OF_INSTR();
4492+}
4493+
4494+/*opcode 0x62 ILLEGAL OP, calls x86emuOp_illegal_op() */
4495+/*opcode 0x63 ILLEGAL OP, calls x86emuOp_illegal_op() */
4496+
4497+/****************************************************************************
4498+REMARKS:
4499+Handles opcode 0x64
4500+****************************************************************************/
4501+static void
4502+x86emuOp_segovr_FS(u8 X86EMU_UNUSED(op1))
4503+{
4504+ START_OF_INSTR();
4505+ DECODE_PRINTF("FS:\n");
4506+ TRACE_AND_STEP();
4507+ M.x86.mode |= SYSMODE_SEGOVR_FS;
4508+ /*
4509+ * note the lack of DECODE_CLEAR_SEGOVR(r) since, here is one of 4
4510+ * opcode subroutines we do not want to do this.
4511+ */
4512+ END_OF_INSTR();
4513+}
4514+
4515+/****************************************************************************
4516+REMARKS:
4517+Handles opcode 0x65
4518+****************************************************************************/
4519+static void
4520+x86emuOp_segovr_GS(u8 X86EMU_UNUSED(op1))
4521+{
4522+ START_OF_INSTR();
4523+ DECODE_PRINTF("GS:\n");
4524+ TRACE_AND_STEP();
4525+ M.x86.mode |= SYSMODE_SEGOVR_GS;
4526+ /*
4527+ * note the lack of DECODE_CLEAR_SEGOVR(r) since, here is one of 4
4528+ * opcode subroutines we do not want to do this.
4529+ */
4530+ END_OF_INSTR();
4531+}
4532+
4533+/****************************************************************************
4534+REMARKS:
4535+Handles opcode 0x66 - prefix for 32-bit register
4536+****************************************************************************/
4537+static void
4538+x86emuOp_prefix_data(u8 X86EMU_UNUSED(op1))
4539+{
4540+ START_OF_INSTR();
4541+ DECODE_PRINTF("DATA:\n");
4542+ TRACE_AND_STEP();
4543+ M.x86.mode |= SYSMODE_PREFIX_DATA;
4544+ /* note no DECODE_CLEAR_SEGOVR here. */
4545+ END_OF_INSTR();
4546+}
4547+
4548+/****************************************************************************
4549+REMARKS:
4550+Handles opcode 0x67 - prefix for 32-bit address
4551+****************************************************************************/
4552+static void
4553+x86emuOp_prefix_addr(u8 X86EMU_UNUSED(op1))
4554+{
4555+ START_OF_INSTR();
4556+ DECODE_PRINTF("ADDR:\n");
4557+ TRACE_AND_STEP();
4558+ M.x86.mode |= SYSMODE_PREFIX_ADDR;
4559+ /* note no DECODE_CLEAR_SEGOVR here. */
4560+ END_OF_INSTR();
4561+}
4562+
4563+/****************************************************************************
4564+REMARKS:
4565+Handles opcode 0x68
4566+****************************************************************************/
4567+static void
4568+x86emuOp_push_word_IMM(u8 X86EMU_UNUSED(op1))
4569+{
4570+ u32 imm;
4571+
4572+ START_OF_INSTR();
4573+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4574+ imm = fetch_long_imm();
4575+ }
4576+ else {
4577+ imm = fetch_word_imm();
4578+ }
4579+ DECODE_PRINTF2("PUSH\t%x\n", imm);
4580+ TRACE_AND_STEP();
4581+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4582+ push_long(imm);
4583+ }
4584+ else {
4585+ push_word((u16) imm);
4586+ }
4587+ DECODE_CLEAR_SEGOVR();
4588+ END_OF_INSTR();
4589+}
4590+
4591+/****************************************************************************
4592+REMARKS:
4593+Handles opcode 0x69
4594+****************************************************************************/
4595+static void
4596+x86emuOp_imul_word_IMM(u8 X86EMU_UNUSED(op1))
4597+{
4598+ int mod, rl, rh;
4599+ uint srcoffset;
4600+
4601+ START_OF_INSTR();
4602+ DECODE_PRINTF("IMUL\t");
4603+ FETCH_DECODE_MODRM(mod, rh, rl);
4604+ switch (mod) {
4605+ case 0:
4606+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4607+ u32 *destreg;
4608+ u32 srcval;
4609+ u32 res_lo, res_hi;
4610+ s32 imm;
4611+
4612+ destreg = DECODE_RM_LONG_REGISTER(rh);
4613+ DECODE_PRINTF(",");
4614+ srcoffset = decode_rm00_address(rl);
4615+ srcval = fetch_data_long(srcoffset);
4616+ imm = fetch_long_imm();
4617+ DECODE_PRINTF2(",%d\n", (s32) imm);
4618+ TRACE_AND_STEP();
4619+ imul_long_direct(&res_lo, &res_hi, (s32) srcval, (s32) imm);
4620+ if (res_hi != 0) {
4621+ SET_FLAG(F_CF);
4622+ SET_FLAG(F_OF);
4623+ }
4624+ else {
4625+ CLEAR_FLAG(F_CF);
4626+ CLEAR_FLAG(F_OF);
4627+ }
4628+ *destreg = (u32) res_lo;
4629+ }
4630+ else {
4631+ u16 *destreg;
4632+ u16 srcval;
4633+ u32 res;
4634+ s16 imm;
4635+
4636+ destreg = DECODE_RM_WORD_REGISTER(rh);
4637+ DECODE_PRINTF(",");
4638+ srcoffset = decode_rm00_address(rl);
4639+ srcval = fetch_data_word(srcoffset);
4640+ imm = fetch_word_imm();
4641+ DECODE_PRINTF2(",%d\n", (s32) imm);
4642+ TRACE_AND_STEP();
4643+ res = (s16) srcval *(s16) imm;
4644+
4645+ if (res > 0xFFFF) {
4646+ SET_FLAG(F_CF);
4647+ SET_FLAG(F_OF);
4648+ }
4649+ else {
4650+ CLEAR_FLAG(F_CF);
4651+ CLEAR_FLAG(F_OF);
4652+ }
4653+ *destreg = (u16) res;
4654+ }
4655+ break;
4656+ case 1:
4657+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4658+ u32 *destreg;
4659+ u32 srcval;
4660+ u32 res_lo, res_hi;
4661+ s32 imm;
4662+
4663+ destreg = DECODE_RM_LONG_REGISTER(rh);
4664+ DECODE_PRINTF(",");
4665+ srcoffset = decode_rm01_address(rl);
4666+ srcval = fetch_data_long(srcoffset);
4667+ imm = fetch_long_imm();
4668+ DECODE_PRINTF2(",%d\n", (s32) imm);
4669+ TRACE_AND_STEP();
4670+ imul_long_direct(&res_lo, &res_hi, (s32) srcval, (s32) imm);
4671+ if (res_hi != 0) {
4672+ SET_FLAG(F_CF);
4673+ SET_FLAG(F_OF);
4674+ }
4675+ else {
4676+ CLEAR_FLAG(F_CF);
4677+ CLEAR_FLAG(F_OF);
4678+ }
4679+ *destreg = (u32) res_lo;
4680+ }
4681+ else {
4682+ u16 *destreg;
4683+ u16 srcval;
4684+ u32 res;
4685+ s16 imm;
4686+
4687+ destreg = DECODE_RM_WORD_REGISTER(rh);
4688+ DECODE_PRINTF(",");
4689+ srcoffset = decode_rm01_address(rl);
4690+ srcval = fetch_data_word(srcoffset);
4691+ imm = fetch_word_imm();
4692+ DECODE_PRINTF2(",%d\n", (s32) imm);
4693+ TRACE_AND_STEP();
4694+ res = (s16) srcval *(s16) imm;
4695+
4696+ if (res > 0xFFFF) {
4697+ SET_FLAG(F_CF);
4698+ SET_FLAG(F_OF);
4699+ }
4700+ else {
4701+ CLEAR_FLAG(F_CF);
4702+ CLEAR_FLAG(F_OF);
4703+ }
4704+ *destreg = (u16) res;
4705+ }
4706+ break;
4707+ case 2:
4708+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4709+ u32 *destreg;
4710+ u32 srcval;
4711+ u32 res_lo, res_hi;
4712+ s32 imm;
4713+
4714+ destreg = DECODE_RM_LONG_REGISTER(rh);
4715+ DECODE_PRINTF(",");
4716+ srcoffset = decode_rm10_address(rl);
4717+ srcval = fetch_data_long(srcoffset);
4718+ imm = fetch_long_imm();
4719+ DECODE_PRINTF2(",%d\n", (s32) imm);
4720+ TRACE_AND_STEP();
4721+ imul_long_direct(&res_lo, &res_hi, (s32) srcval, (s32) imm);
4722+ if (res_hi != 0) {
4723+ SET_FLAG(F_CF);
4724+ SET_FLAG(F_OF);
4725+ }
4726+ else {
4727+ CLEAR_FLAG(F_CF);
4728+ CLEAR_FLAG(F_OF);
4729+ }
4730+ *destreg = (u32) res_lo;
4731+ }
4732+ else {
4733+ u16 *destreg;
4734+ u16 srcval;
4735+ u32 res;
4736+ s16 imm;
4737+
4738+ destreg = DECODE_RM_WORD_REGISTER(rh);
4739+ DECODE_PRINTF(",");
4740+ srcoffset = decode_rm10_address(rl);
4741+ srcval = fetch_data_word(srcoffset);
4742+ imm = fetch_word_imm();
4743+ DECODE_PRINTF2(",%d\n", (s32) imm);
4744+ TRACE_AND_STEP();
4745+ res = (s16) srcval *(s16) imm;
4746+
4747+ if (res > 0xFFFF) {
4748+ SET_FLAG(F_CF);
4749+ SET_FLAG(F_OF);
4750+ }
4751+ else {
4752+ CLEAR_FLAG(F_CF);
4753+ CLEAR_FLAG(F_OF);
4754+ }
4755+ *destreg = (u16) res;
4756+ }
4757+ break;
4758+ case 3: /* register to register */
4759+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4760+ u32 *destreg, *srcreg;
4761+ u32 res_lo, res_hi;
4762+ s32 imm;
4763+
4764+ destreg = DECODE_RM_LONG_REGISTER(rh);
4765+ DECODE_PRINTF(",");
4766+ srcreg = DECODE_RM_LONG_REGISTER(rl);
4767+ imm = fetch_long_imm();
4768+ DECODE_PRINTF2(",%d\n", (s32) imm);
4769+ TRACE_AND_STEP();
4770+ imul_long_direct(&res_lo, &res_hi, (s32) * srcreg, (s32) imm);
4771+ if (res_hi != 0) {
4772+ SET_FLAG(F_CF);
4773+ SET_FLAG(F_OF);
4774+ }
4775+ else {
4776+ CLEAR_FLAG(F_CF);
4777+ CLEAR_FLAG(F_OF);
4778+ }
4779+ *destreg = (u32) res_lo;
4780+ }
4781+ else {
4782+ u16 *destreg, *srcreg;
4783+ u32 res;
4784+ s16 imm;
4785+
4786+ destreg = DECODE_RM_WORD_REGISTER(rh);
4787+ DECODE_PRINTF(",");
4788+ srcreg = DECODE_RM_WORD_REGISTER(rl);
4789+ imm = fetch_word_imm();
4790+ DECODE_PRINTF2(",%d\n", (s32) imm);
4791+ res = (s16) * srcreg * (s16) imm;
4792+ if (res > 0xFFFF) {
4793+ SET_FLAG(F_CF);
4794+ SET_FLAG(F_OF);
4795+ }
4796+ else {
4797+ CLEAR_FLAG(F_CF);
4798+ CLEAR_FLAG(F_OF);
4799+ }
4800+ *destreg = (u16) res;
4801+ }
4802+ break;
4803+ }
4804+ DECODE_CLEAR_SEGOVR();
4805+ END_OF_INSTR();
4806+}
4807+
4808+/****************************************************************************
4809+REMARKS:
4810+Handles opcode 0x6a
4811+****************************************************************************/
4812+static void
4813+x86emuOp_push_byte_IMM(u8 X86EMU_UNUSED(op1))
4814+{
4815+ s16 imm;
4816+
4817+ START_OF_INSTR();
4818+ imm = (s8) fetch_byte_imm();
4819+ DECODE_PRINTF2("PUSH\t%d\n", imm);
4820+ TRACE_AND_STEP();
4821+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4822+ push_long((s32) imm);
4823+ }
4824+ else {
4825+ push_word(imm);
4826+ }
4827+ DECODE_CLEAR_SEGOVR();
4828+ END_OF_INSTR();
4829+}
4830+
4831+/****************************************************************************
4832+REMARKS:
4833+Handles opcode 0x6b
4834+****************************************************************************/
4835+static void
4836+x86emuOp_imul_byte_IMM(u8 X86EMU_UNUSED(op1))
4837+{
4838+ int mod, rl, rh;
4839+ uint srcoffset;
4840+ s8 imm;
4841+
4842+ START_OF_INSTR();
4843+ DECODE_PRINTF("IMUL\t");
4844+ FETCH_DECODE_MODRM(mod, rh, rl);
4845+ switch (mod) {
4846+ case 0:
4847+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4848+ u32 *destreg;
4849+ u32 srcval;
4850+ u32 res_lo, res_hi;
4851+
4852+ destreg = DECODE_RM_LONG_REGISTER(rh);
4853+ DECODE_PRINTF(",");
4854+ srcoffset = decode_rm00_address(rl);
4855+ srcval = fetch_data_long(srcoffset);
4856+ imm = fetch_byte_imm();
4857+ DECODE_PRINTF2(",%d\n", (s32) imm);
4858+ TRACE_AND_STEP();
4859+ imul_long_direct(&res_lo, &res_hi, (s32) srcval, (s32) imm);
4860+ if (res_hi != 0) {
4861+ SET_FLAG(F_CF);
4862+ SET_FLAG(F_OF);
4863+ }
4864+ else {
4865+ CLEAR_FLAG(F_CF);
4866+ CLEAR_FLAG(F_OF);
4867+ }
4868+ *destreg = (u32) res_lo;
4869+ }
4870+ else {
4871+ u16 *destreg;
4872+ u16 srcval;
4873+ u32 res;
4874+
4875+ destreg = DECODE_RM_WORD_REGISTER(rh);
4876+ DECODE_PRINTF(",");
4877+ srcoffset = decode_rm00_address(rl);
4878+ srcval = fetch_data_word(srcoffset);
4879+ imm = fetch_byte_imm();
4880+ DECODE_PRINTF2(",%d\n", (s32) imm);
4881+ TRACE_AND_STEP();
4882+ res = (s16) srcval *(s16) imm;
4883+
4884+ if (res > 0xFFFF) {
4885+ SET_FLAG(F_CF);
4886+ SET_FLAG(F_OF);
4887+ }
4888+ else {
4889+ CLEAR_FLAG(F_CF);
4890+ CLEAR_FLAG(F_OF);
4891+ }
4892+ *destreg = (u16) res;
4893+ }
4894+ break;
4895+ case 1:
4896+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4897+ u32 *destreg;
4898+ u32 srcval;
4899+ u32 res_lo, res_hi;
4900+
4901+ destreg = DECODE_RM_LONG_REGISTER(rh);
4902+ DECODE_PRINTF(",");
4903+ srcoffset = decode_rm01_address(rl);
4904+ srcval = fetch_data_long(srcoffset);
4905+ imm = fetch_byte_imm();
4906+ DECODE_PRINTF2(",%d\n", (s32) imm);
4907+ TRACE_AND_STEP();
4908+ imul_long_direct(&res_lo, &res_hi, (s32) srcval, (s32) imm);
4909+ if (res_hi != 0) {
4910+ SET_FLAG(F_CF);
4911+ SET_FLAG(F_OF);
4912+ }
4913+ else {
4914+ CLEAR_FLAG(F_CF);
4915+ CLEAR_FLAG(F_OF);
4916+ }
4917+ *destreg = (u32) res_lo;
4918+ }
4919+ else {
4920+ u16 *destreg;
4921+ u16 srcval;
4922+ u32 res;
4923+
4924+ destreg = DECODE_RM_WORD_REGISTER(rh);
4925+ DECODE_PRINTF(",");
4926+ srcoffset = decode_rm01_address(rl);
4927+ srcval = fetch_data_word(srcoffset);
4928+ imm = fetch_byte_imm();
4929+ DECODE_PRINTF2(",%d\n", (s32) imm);
4930+ TRACE_AND_STEP();
4931+ res = (s16) srcval *(s16) imm;
4932+
4933+ if (res > 0xFFFF) {
4934+ SET_FLAG(F_CF);
4935+ SET_FLAG(F_OF);
4936+ }
4937+ else {
4938+ CLEAR_FLAG(F_CF);
4939+ CLEAR_FLAG(F_OF);
4940+ }
4941+ *destreg = (u16) res;
4942+ }
4943+ break;
4944+ case 2:
4945+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4946+ u32 *destreg;
4947+ u32 srcval;
4948+ u32 res_lo, res_hi;
4949+
4950+ destreg = DECODE_RM_LONG_REGISTER(rh);
4951+ DECODE_PRINTF(",");
4952+ srcoffset = decode_rm10_address(rl);
4953+ srcval = fetch_data_long(srcoffset);
4954+ imm = fetch_byte_imm();
4955+ DECODE_PRINTF2(",%d\n", (s32) imm);
4956+ TRACE_AND_STEP();
4957+ imul_long_direct(&res_lo, &res_hi, (s32) srcval, (s32) imm);
4958+ if (res_hi != 0) {
4959+ SET_FLAG(F_CF);
4960+ SET_FLAG(F_OF);
4961+ }
4962+ else {
4963+ CLEAR_FLAG(F_CF);
4964+ CLEAR_FLAG(F_OF);
4965+ }
4966+ *destreg = (u32) res_lo;
4967+ }
4968+ else {
4969+ u16 *destreg;
4970+ u16 srcval;
4971+ u32 res;
4972+
4973+ destreg = DECODE_RM_WORD_REGISTER(rh);
4974+ DECODE_PRINTF(",");
4975+ srcoffset = decode_rm10_address(rl);
4976+ srcval = fetch_data_word(srcoffset);
4977+ imm = fetch_byte_imm();
4978+ DECODE_PRINTF2(",%d\n", (s32) imm);
4979+ TRACE_AND_STEP();
4980+ res = (s16) srcval *(s16) imm;
4981+
4982+ if (res > 0xFFFF) {
4983+ SET_FLAG(F_CF);
4984+ SET_FLAG(F_OF);
4985+ }
4986+ else {
4987+ CLEAR_FLAG(F_CF);
4988+ CLEAR_FLAG(F_OF);
4989+ }
4990+ *destreg = (u16) res;
4991+ }
4992+ break;
4993+ case 3: /* register to register */
4994+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4995+ u32 *destreg, *srcreg;
4996+ u32 res_lo, res_hi;
4997+
4998+ destreg = DECODE_RM_LONG_REGISTER(rh);
4999+ DECODE_PRINTF(",");
5000+ srcreg = DECODE_RM_LONG_REGISTER(rl);
5001+ imm = fetch_byte_imm();
5002+ DECODE_PRINTF2(",%d\n", (s32) imm);
5003+ TRACE_AND_STEP();
5004+ imul_long_direct(&res_lo, &res_hi, (s32) * srcreg, (s32) imm);
5005+ if (res_hi != 0) {
5006+ SET_FLAG(F_CF);
5007+ SET_FLAG(F_OF);
5008+ }
5009+ else {
5010+ CLEAR_FLAG(F_CF);
5011+ CLEAR_FLAG(F_OF);
5012+ }
5013+ *destreg = (u32) res_lo;
5014+ }
5015+ else {
5016+ u16 *destreg, *srcreg;
5017+ u32 res;
5018+
5019+ destreg = DECODE_RM_WORD_REGISTER(rh);
5020+ DECODE_PRINTF(",");
5021+ srcreg = DECODE_RM_WORD_REGISTER(rl);
5022+ imm = fetch_byte_imm();
5023+ DECODE_PRINTF2(",%d\n", (s32) imm);
5024+ res = (s16) * srcreg * (s16) imm;
5025+ if (res > 0xFFFF) {
5026+ SET_FLAG(F_CF);
5027+ SET_FLAG(F_OF);
5028+ }
5029+ else {
5030+ CLEAR_FLAG(F_CF);
5031+ CLEAR_FLAG(F_OF);
5032+ }
5033+ *destreg = (u16) res;
5034+ }
5035+ break;
5036+ }
5037+ DECODE_CLEAR_SEGOVR();
5038+ END_OF_INSTR();
5039+}
5040+
5041+/****************************************************************************
5042+REMARKS:
5043+Handles opcode 0x6c
5044+****************************************************************************/
5045+static void
5046+x86emuOp_ins_byte(u8 X86EMU_UNUSED(op1))
5047+{
5048+ START_OF_INSTR();
5049+ DECODE_PRINTF("INSB\n");
5050+ ins(1);
5051+ TRACE_AND_STEP();
5052+ DECODE_CLEAR_SEGOVR();
5053+ END_OF_INSTR();
5054+}
5055+
5056+/****************************************************************************
5057+REMARKS:
5058+Handles opcode 0x6d
5059+****************************************************************************/
5060+static void
5061+x86emuOp_ins_word(u8 X86EMU_UNUSED(op1))
5062+{
5063+ START_OF_INSTR();
5064+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5065+ DECODE_PRINTF("INSD\n");
5066+ ins(4);
5067+ }
5068+ else {
5069+ DECODE_PRINTF("INSW\n");
5070+ ins(2);
5071+ }
5072+ TRACE_AND_STEP();
5073+ DECODE_CLEAR_SEGOVR();
5074+ END_OF_INSTR();
5075+}
5076+
5077+/****************************************************************************
5078+REMARKS:
5079+Handles opcode 0x6e
5080+****************************************************************************/
5081+static void
5082+x86emuOp_outs_byte(u8 X86EMU_UNUSED(op1))
5083+{
5084+ START_OF_INSTR();
5085+ DECODE_PRINTF("OUTSB\n");
5086+ outs(1);
5087+ TRACE_AND_STEP();
5088+ DECODE_CLEAR_SEGOVR();
5089+ END_OF_INSTR();
5090+}
5091+
5092+/****************************************************************************
5093+REMARKS:
5094+Handles opcode 0x6f
5095+****************************************************************************/
5096+static void
5097+x86emuOp_outs_word(u8 X86EMU_UNUSED(op1))
5098+{
5099+ START_OF_INSTR();
5100+ if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5101+ DECODE_PRINTF("OUTSD\n");
5102+ outs(4);
5103+ }
5104+ else {
5105+ DECODE_PRINTF("OUTSW\n");
5106+ outs(2);
5107+ }
5108+ TRACE_AND_STEP();
5109+ DECODE_CLEAR_SEGOVR();
5110+ END_OF_INSTR();
5111+}
5112+
5113+/****************************************************************************
5114+REMARKS:
5115+Handles opcode 0x70
5116+****************************************************************************/
5117+static void
5118+x86emuOp_jump_near_O(u8 X86EMU_UNUSED(op1))
5119+{
5120+ s8 offset;
5121+ u16 target;
5122+
5123+ /* jump to byte offset if overflow flag is set */
5124+ START_OF_INSTR();
5125+ DECODE_PRINTF("JO\t");
5126+ offset = (s8) fetch_byte_imm();
5127+ target = (u16) (M.x86.R_IP + (s16) offset);
5128+ DECODE_PRINTF2("%x\n", target);
5129+ TRACE_AND_STEP();
5130+ if (ACCESS_FLAG(F_OF))
5131+ M.x86.R_IP = target;
5132+ DECODE_CLEAR_SEGOVR();
5133+ END_OF_INSTR();
5134+}
5135+
5136+/****************************************************************************
5137+REMARKS:
5138+Handles opcode 0x71
5139+****************************************************************************/
5140+static void
5141+x86emuOp_jump_near_NO(u8 X86EMU_UNUSED(op1))
5142+{
5143+ s8 offset;
5144+ u16 target;
5145+
5146+ /* jump to byte offset if overflow is not set */
5147+ START_OF_INSTR();
5148+ DECODE_PRINTF("JNO\t");
5149+ offset = (s8) fetch_byte_imm();
5150+ target = (u16) (M.x86.R_IP + (s16) offset);
5151+ DECODE_PRINTF2("%x\n", target);
5152+ TRACE_AND_STEP();
5153+ if (!ACCESS_FLAG(F_OF))
5154+ M.x86.R_IP = target;
5155+ DECODE_CLEAR_SEGOVR();
5156+ END_OF_INSTR();
5157+}
5158+
5159+/****************************************************************************
5160+REMARKS:
5161+Handles opcode 0x72
5162+****************************************************************************/
5163+static void
5164+x86emuOp_jump_near_B(u8 X86EMU_UNUSED(op1))
5165+{
5166+ s8 offset;
5167+ u16 target;
5168+
5169+ /* jump to byte offset if carry flag is set. */
5170+ START_OF_INSTR();
5171+ DECODE_PRINTF("JB\t");
5172+ offset = (s8) fetch_byte_imm();
5173+ target = (u16) (M.x86.R_IP + (s16) offset);
5174+ DECODE_PRINTF2("%x\n", target);
5175+ TRACE_AND_STEP();
5176+ if (ACCESS_FLAG(F_CF))
5177+ M.x86.R_IP = target;
5178+ DECODE_CLEAR_SEGOVR();
5179+ END_OF_INSTR();
5180+}
5181+
5182+/****************************************************************************
5183+REMARKS:
5184+Handles opcode 0x73
5185+****************************************************************************/
5186+static void
5187+x86emuOp_jump_near_NB(u8 X86EMU_UNUSED(op1))
5188+{
5189+ s8 offset;
5190+ u16 target;
5191+
5192+ /* jump to byte offset if carry flag is clear. */
5193+ START_OF_INSTR();
5194+ DECODE_PRINTF("JNB\t");
5195+ offset = (s8) fetch_byte_imm();
5196+ target = (u16) (M.x86.R_IP + (s16) offset);
5197+ DECODE_PRINTF2("%x\n", target);
5198+ TRACE_AND_STEP();
5199+ if (!ACCESS_FLAG(F_CF))
5200+ M.x86.R_IP = target;
5201+ DECODE_CLEAR_SEGOVR();
5202+ END_OF_INSTR();
5203+}
5204+
5205+/****************************************************************************
5206+REMARKS:
5207+Handles opcode 0x74
5208+****************************************************************************/
5209+static void
5210+x86emuOp_jump_near_Z(u8 X86EMU_UNUSED(op1))
5211+{
5212+ s8 offset;
5213+ u16 target;
5214+
5215+ /* jump to byte offset if zero flag is set. */
5216+ START_OF_INSTR();
5217+ DECODE_PRINTF("JZ\t");
5218+ offset = (s8) fetch_byte_imm();
5219+ target = (u16) (M.x86.R_IP + (s16) offset);
5220+ DECODE_PRINTF2("%x\n", target);
5221+ TRACE_AND_STEP();
5222+ if (ACCESS_FLAG(F_ZF))
5223+ M.x86.R_IP = target;
5224+ DECODE_CLEAR_SEGOVR();
5225+ END_OF_INSTR();
5226+}
5227+
5228+/****************************************************************************
5229+REMARKS:
5230+Handles opcode 0x75
5231+****************************************************************************/
5232+static void
5233+x86emuOp_jump_near_NZ(u8 X86EMU_UNUSED(op1))
5234+{
5235+ s8 offset;
5236+ u16 target;
5237+
5238+ /* jump to byte offset if zero flag is clear. */
5239+ START_OF_INSTR();
5240+ DECODE_PRINTF("JNZ\t");
5241+ offset = (s8) fetch_byte_imm();
5242+ target = (u16) (M.x86.R_IP + (s16) offset);
5243+ DECODE_PRINTF2("%x\n", target);
5244+ TRACE_AND_STEP();
5245+ if (!ACCESS_FLAG(F_ZF))
5246+ M.x86.R_IP = target;
5247+ DECODE_CLEAR_SEGOVR();
5248+ END_OF_INSTR();
5249+}
5250+
5251+/****************************************************************************
5252+REMARKS:
5253+Handles opcode 0x76
5254+****************************************************************************/
5255+static void
5256+x86emuOp_jump_near_BE(u8 X86EMU_UNUSED(op1))
5257+{
5258+ s8 offset;
5259+ u16 target;
5260+
5261+ /* jump to byte offset if carry flag is set or if the zero
5262+ flag is set. */
5263+ START_OF_INSTR();
5264+ DECODE_PRINTF("JBE\t");
5265+ offset = (s8) fetch_byte_imm();
5266+ target = (u16) (M.x86.R_IP + (s16) offset);
5267+ DECODE_PRINTF2("%x\n", target);
5268+ TRACE_AND_STEP();
5269+ if (ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF))
5270+ M.x86.R_IP = target;
5271+ DECODE_CLEAR_SEGOVR();
5272+ END_OF_INSTR();
5273+}
5274+
5275+/****************************************************************************
5276+REMARKS:
5277+Handles opcode 0x77
5278+****************************************************************************/
5279+static void
5280+x86emuOp_jump_near_NBE(u8 X86EMU_UNUSED(op1))
5281+{
5282+ s8 offset;
5283+ u16 target;
5284+
5285+ /* jump to byte offset if carry flag is clear and if the zero
5286+ flag is clear */
5287+ START_OF_INSTR();
5288+ DECODE_PRINTF("JNBE\t");
5289+ offset = (s8) fetch_byte_imm();
5290+ target = (u16) (M.x86.R_IP + (s16) offset);
5291+ DECODE_PRINTF2("%x\n", target);
5292+ TRACE_AND_STEP();
5293+ if (!(ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF)))
5294+ M.x86.R_IP = target;
5295+ DECODE_CLEAR_SEGOVR();
5296+ END_OF_INSTR();
5297+}
5298+
5299+/****************************************************************************
5300+REMARKS:
5301+Handles opcode 0x78
5302+****************************************************************************/
5303+static void
5304+x86emuOp_jump_near_S(u8 X86EMU_UNUSED(op1))
5305+{
5306+ s8 offset;
5307+ u16 target;
5308+
5309+ /* jump to byte offset if sign flag is set */
5310+ START_OF_INSTR();
5311+ DECODE_PRINTF("JS\t");
5312+ offset = (s8) fetch_byte_imm();
5313+ target = (u16) (M.x86.R_IP + (s16) offset);
5314+ DECODE_PRINTF2("%x\n", target);
5315+ TRACE_AND_STEP();
5316+ if (ACCESS_FLAG(F_SF))
5317+ M.x86.R_IP = target;
5318+ DECODE_CLEAR_SEGOVR();
5319+ END_OF_INSTR();
5320+}
5321+
5322+/****************************************************************************
5323+REMARKS:
5324+Handles opcode 0x79
5325+****************************************************************************/
5326+static void
5327+x86emuOp_jump_near_NS(u8 X86EMU_UNUSED(op1))
5328+{
5329+ s8 offset;
5330+ u16 target;
5331+
5332+ /* jump to byte offset if sign flag is clear */
5333+ START_OF_INSTR();
5334+ DECODE_PRINTF("JNS\t");
5335+ offset = (s8) fetch_byte_imm();
5336+ target = (u16) (M.x86.R_IP + (s16) offset);
5337+ DECODE_PRINTF2("%x\n", target);
5338+ TRACE_AND_STEP();
5339+ if (!ACCESS_FLAG(F_SF))
5340+ M.x86.R_IP = target;
5341+ DECODE_CLEAR_SEGOVR();
5342+ END_OF_INSTR();
5343+}
5344+
5345+/****************************************************************************
5346+REMARKS:
5347+Handles opcode 0x7a
5348+****************************************************************************/
5349+static void
5350+x86emuOp_jump_near_P(u8 X86EMU_UNUSED(op1))
5351+{
5352+ s8 offset;
5353+ u16 target;
5354+
5355+ /* jump to byte offset if parity flag is set (even parity) */
5356+ START_OF_INSTR();
5357+ DECODE_PRINTF("JP\t");
5358+ offset = (s8) fetch_byte_imm();
5359+ target = (u16) (M.x86.R_IP + (s16) offset);
5360+ DECODE_PRINTF2("%x\n", target);
5361+ TRACE_AND_STEP();
5362+ if (ACCESS_FLAG(F_PF))
5363+ M.x86.R_IP = target;
5364+ DECODE_CLEAR_SEGOVR();
5365+ END_OF_INSTR();
5366+}
5367+
5368+/****************************************************************************
5369+REMARKS:
5370+Handles opcode 0x7b
5371+****************************************************************************/
5372+static void
5373+x86emuOp_jump_near_NP(u8 X86EMU_UNUSED(op1))
5374+{
5375+ s8 offset;
5376+ u16 target;
5377+
5378+ /* jump to byte offset if parity flag is clear (odd parity) */
5379+ START_OF_INSTR();
5380+ DECODE_PRINTF("JNP\t");
5381+ offset = (s8) fetch_byte_imm();
5382+ target = (u16) (M.x86.R_IP + (s16) offset);
5383+ DECODE_PRINTF2("%x\n", target);
5384+ TRACE_AND_STEP();
5385+ if (!ACCESS_FLAG(F_PF))
5386+ M.x86.R_IP = target;
5387+ DECODE_CLEAR_SEGOVR();
5388+ END_OF_INSTR();
5389+}
5390+
5391+/****************************************************************************
5392+REMARKS:
5393+Handles opcode 0x7c
5394+****************************************************************************/
5395+static void
5396+x86emuOp_jump_near_L(u8 X86EMU_UNUSED(op1))
5397+{
5398+ s8 offset;
5399+ u16 target;
5400+ int sf, of;
5401+
5402+ /* jump to byte offset if sign flag not equal to overflow flag. */
5403+ START_OF_INSTR();
5404+ DECODE_PRINTF("JL\t");
5405+ offset = (s8) fetch_byte_imm();
5406+ target = (u16) (M.x86.R_IP + (s16) offset);
5407+ DECODE_PRINTF2("%x\n", target);
5408+ TRACE_AND_STEP();
5409+ sf = ACCESS_FLAG(F_SF) != 0;
5410+ of = ACCESS_FLAG(F_OF) != 0;
5411+ if (sf ^ of)
5412+ M.x86.R_IP = target;
5413+ DECODE_CLEAR_SEGOVR();
5414+ END_OF_INSTR();
5415+}
5416+
5417+/****************************************************************************
5418+REMARKS:
5419+Handles opcode 0x7d
5420+****************************************************************************/
5421+static void
5422+x86emuOp_jump_near_NL(u8 X86EMU_UNUSED(op1))
5423+{
5424+ s8 offset;
5425+ u16 target;
5426+ int sf, of;
5427+
5428+ /* jump to byte offset if sign flag not equal to overflow flag. */
5429+ START_OF_INSTR();
5430+ DECODE_PRINTF("JNL\t");
5431+ offset = (s8) fetch_byte_imm();
5432+ target = (u16) (M.x86.R_IP + (s16) offset);
5433+ DECODE_PRINTF2("%x\n", target);
5434+ TRACE_AND_STEP();
5435+ sf = ACCESS_FLAG(F_SF) != 0;
5436+ of = ACCESS_FLAG(F_OF) != 0;
5437+ /* note: inverse of above, but using == instead of xor. */
5438+ if (sf == of)
5439+ M.x86.R_IP = target;
5440+ DECODE_CLEAR_SEGOVR();
5441+ END_OF_INSTR();
5442+}
5443+
5444+/****************************************************************************
5445+REMARKS:
5446+Handles opcode 0x7e
5447+****************************************************************************/
5448+static void
5449+x86emuOp_jump_near_LE(u8 X86EMU_UNUSED(op1))
5450+{
5451+ s8 offset;
5452+ u16 target;
5453+ int sf, of;
5454+
5455+ /* jump to byte offset if sign flag not equal to overflow flag
5456+ or the zero flag is set */
5457+ START_OF_INSTR();
5458+ DECODE_PRINTF("JLE\t");
5459+ offset = (s8) fetch_byte_imm();
5460+ target = (u16) (M.x86.R_IP + (s16) offset);
5461+ DECODE_PRINTF2("%x\n", target);
5462+ TRACE_AND_STEP();
5463+ sf = ACCESS_FLAG(F_SF) != 0;
5464+ of = ACCESS_FLAG(F_OF) != 0;
5465+ if ((sf ^ of) || ACCESS_FLAG(F_ZF))
5466+ M.x86.R_IP = target;
5467+ DECODE_CLEAR_SEGOVR();
5468+ END_OF_INSTR();
5469+}
5470+
5471+/****************************************************************************
5472+REMARKS:
5473+Handles opcode 0x7f
5474+****************************************************************************/
5475+static void
5476+x86emuOp_jump_near_NLE(u8 X86EMU_UNUSED(op1))
5477+{
5478+ s8 offset;
5479+ u16 target;
5480+ int sf, of;
5481+
5482+ /* jump to byte offset if sign flag equal to overflow flag.
5483+ and the zero flag is clear */
5484+ START_OF_INSTR();
5485+ DECODE_PRINTF("JNLE\t");
5486+ offset = (s8) fetch_byte_imm();
5487+ target = (u16) (M.x86.R_IP + (s16) offset);
5488+ DECODE_PRINTF2("%x\n", target);
5489+ TRACE_AND_STEP();
5490+ sf = ACCESS_FLAG(F_SF) != 0;
5491+ of = ACCESS_FLAG(F_OF) != 0;
5492+ if ((sf == of) && !ACCESS_FLAG(F_ZF))
5493+ M.x86.R_IP = target;
5494+ DECODE_CLEAR_SEGOVR();
5495+ END_OF_INSTR();
5496+}
5497+
5498+static u8(*opc80_byte_operation[]) (u8 d, u8 s) = {
5499+ add_byte, /* 00 */
5500+ or_byte, /* 01 */
5501+ adc_byte, /* 02 */
5502+ sbb_byte, /* 03 */
5503+ and_byte, /* 04 */
5504+ sub_byte, /* 05 */
5505+ xor_byte, /* 06 */
5506+ cmp_byte, /* 07 */
5507+};
5508+
5509+/****************************************************************************
5510+REMARKS:
5511+Handles opcode 0x80
5512+****************************************************************************/
5513+static void
5514+x86emuOp_opc80_byte_RM_IMM(u8 X86EMU_UNUSED(op1))
5515+{
5516+ int mod, rl, rh;
5517+ u8 *destreg;
5518+ uint destoffset;
5519+ u8 imm;
5520+ u8 destval;
5521+
5522+ /*
5523+ * Weirdo special case instruction format. Part of the opcode
5524+ * held below in "RH". Doubly nested case would result, except
5525+ * that the decoded instruction
5526+ */
5527+ START_OF_INSTR();
5528+ FETCH_DECODE_MODRM(mod, rh, rl);
5529+#ifdef DEBUG
5530+ if (DEBUG_DECODE()) {
5531+ /* XXX DECODE_PRINTF may be changed to something more
5532+ general, so that it is important to leave the strings
5533+ in the same format, even though the result is that the
5534+ above test is done twice. */
5535+
5536+ switch (rh) {
5537+ case 0:
5538+ DECODE_PRINTF("ADD\t");
5539+ break;
5540+ case 1:
5541+ DECODE_PRINTF("OR\t");
5542+ break;
5543+ case 2:
5544+ DECODE_PRINTF("ADC\t");
5545+ break;
5546+ case 3:
5547+ DECODE_PRINTF("SBB\t");
5548+ break;
5549+ case 4:
5550+ DECODE_PRINTF("AND\t");
5551+ break;
5552+ case 5:
5553+ DECODE_PRINTF("SUB\t");
5554+ break;
5555+ case 6:
5556+ DECODE_PRINTF("XOR\t");
5557+ break;
5558+ case 7:
5559+ DECODE_PRINTF("CMP\t");
5560+ break;
5561+ }
5562+ }
5563+#endif
5564+ /* know operation, decode the mod byte to find the addressing
5565+ mode. */
5566+ switch (mod) {
5567+ case 0:
5568+ DECODE_PRINTF("BYTE PTR ");
5569+ destoffset = decode_rm00_address(rl);
5570+ DECODE_PRINTF(",");
5571+ destval = fetch_data_byte(destoffset);
5572+ imm = fetch_byte_imm();
5573+ DECODE_PRINTF2("%x\n", imm);
5574+ TRACE_AND_STEP();
5575+ destval = (*opc80_byte_operation[rh]) (destval, imm);
5576+ if (rh != 7)
5577+ store_data_byte(destoffset, destval);
5578+ break;
5579+ case 1:
5580+ DECODE_PRINTF("BYTE PTR ");
5581+ destoffset = decode_rm01_address(rl);
5582+ DECODE_PRINTF(",");
5583+ destval = fetch_data_byte(destoffset);
5584+ imm = fetch_byte_imm();
5585+ DECODE_PRINTF2("%x\n", imm);
5586+ TRACE_AND_STEP();
5587+ destval = (*opc80_byte_operation[rh]) (destval, imm);
5588+ if (rh != 7)
5589+ store_data_byte(destoffset, destval);
5590+ break;
5591+ case 2:
5592+ DECODE_PRINTF("BYTE PTR ");
5593+ destoffset = decode_rm10_address(rl);
5594+ DECODE_PRINTF(",");
5595+ destval = fetch_data_byte(destoffset);
5596+ imm = fetch_byte_imm();
5597+ DECODE_PRINTF2("%x\n", imm);
5598+ TRACE_AND_STEP();
5599+ destval = (*opc80_byte_operation[rh]) (destval, imm);
5600+ if (rh != 7)
5601+ store_data_byte(destoffset, destval);
5602+ break;
5603+ case 3: /* register to register */
5604+ destreg = DECODE_RM_BYTE_REGISTER(rl);
5605+ DECODE_PRINTF(",");
5606+ imm = fetch_byte_imm();
5607+ DECODE_PRINTF2("%x\n", imm);
5608+ TRACE_AND_STEP();
5609+ destval = (*opc80_byte_operation[rh]) (*destreg, imm);
5610+ if (rh != 7)
5611+ *destreg = destval;
5612+ break;
5613+ }
5614+ DECODE_CLEAR_SEGOVR();
5615+ END_OF_INSTR();
5616+}
5617+
5618+static u16(*opc81_word_operation[]) (u16 d, u16 s) = {
5619+ add_word, /*00 */
5620+ or_word, /*01 */
5621+ adc_word, /*02 */
5622+ sbb_word, /*03 */
5623+ and_word, /*04 */
5624+ sub_word, /*05 */
5625+ xor_word, /*06 */
5626+ cmp_word, /*07 */
5627+};
5628+
5629+static u32(*opc81_long_operation[]) (u32 d, u32 s) = {
5630+ add_long, /*00 */
5631+ or_long, /*01 */
5632+ adc_long, /*02 */
5633+ sbb_long, /*03 */
5634+ and_long, /*04 */
5635+ sub_long, /*05 */
5636+ xor_long, /*06 */
5637+ cmp_long, /*07 */
5638+};
5639+
5640+/****************************************************************************
5641+REMARKS:
5642+Handles opcode 0x81
5643+****************************************************************************/
5644+static void
5645+x86emuOp_opc81_word_RM_IMM(u8 X86EMU_UNUSED(op1))
5646+{
5647+ int mod, rl, rh;
5648+ uint destoffset;
5649+
5650+ /*
5651+ * Weirdo special case instruction format. Part of the opcode
5652+ * held below in "RH". Doubly nested case would result, except
5653+ * that the decoded instruction
5654+ */
5655+ START_OF_INSTR();
5656+ FETCH_DECODE_MODRM(mod, rh, rl);
5657+#ifdef DEBUG
5658+ if (DEBUG_DECODE()) {
5659+ /* XXX DECODE_PRINTF may be changed to something more
5660+ general, so that it is important to leave the strings
5661+ in the same format, even though the result is that the
5662+ above test is done twice. */
5663+
5664+ switch (rh) {
5665+ case 0:
5666+ DECODE_PRINTF("ADD\t");
5667+ break;
5668+ case 1:
5669+ DECODE_PRINTF("OR\t");
5670+ break;
5671+ case 2:
5672+ DECODE_PRINTF("ADC\t");
5673+ break;
5674+ case 3:
5675+ DECODE_PRINTF("SBB\t");
5676+ break;
5677+ case 4:
5678+ DECODE_PRINTF("AND\t");
5679+ break;
5680+ case 5:
5681+ DECODE_PRINTF("SUB\t");
5682+ break;
5683+ case 6:
5684+ DECODE_PRINTF("XOR\t");
5685+ break;
5686+ case 7:
5687+ DECODE_PRINTF("CMP\t");