]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - drivers/bios_emulator/x86emu/ops.c
Merge branch 'master' of git://git.denx.de/u-boot-mpc83xx
[karo-tx-uboot.git] / drivers / bios_emulator / x86emu / ops.c
1 /****************************************************************************
2 *                       Realmode X86 Emulator Library
3 *
4 *  Copyright (C) 2007 Freescale Semiconductor, Inc.
5 *  Jason Jin <Jason.jin@freescale.com>
6 *
7 *               Copyright (C) 1991-2004 SciTech Software, Inc.
8 *                                    Copyright (C) David Mosberger-Tang
9 *                                          Copyright (C) 1999 Egbert Eich
10 *
11 *  ========================================================================
12 *
13 *  Permission to use, copy, modify, distribute, and sell this software and
14 *  its documentation for any purpose is hereby granted without fee,
15 *  provided that the above copyright notice appear in all copies and that
16 *  both that copyright notice and this permission notice appear in
17 *  supporting documentation, and that the name of the authors not be used
18 *  in advertising or publicity pertaining to distribution of the software
19 *  without specific, written prior permission.  The authors makes no
20 *  representations about the suitability of this software for any purpose.
21 *  It is provided "as is" without express or implied warranty.
22 *
23 *  THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
24 *  INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
25 *  EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
26 *  CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
27 *  USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
28 *  OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
29 *  PERFORMANCE OF THIS SOFTWARE.
30 *
31 *  ========================================================================
32 *
33 * Language:             ANSI C
34 * Environment:  Any
35 * Developer:    Kendall Bennett
36 *
37 * Description:  This file includes subroutines to implement the decoding
38 *               and emulation of all the x86 processor instructions.
39 *
40 * There are approximately 250 subroutines in here, which correspond
41 * to the 256 byte-"opcodes" found on the 8086.  The table which
42 * dispatches this is found in the files optab.[ch].
43 *
44 * Each opcode proc has a comment preceeding it which gives it's table
45 * address.  Several opcodes are missing (undefined) in the table.
46 *
47 * Each proc includes information for decoding (DECODE_PRINTF and
48 * DECODE_PRINTF2), debugging (TRACE_REGS, SINGLE_STEP), and misc
49 * functions (START_OF_INSTR, END_OF_INSTR).
50 *
51 * Many of the procedures are *VERY* similar in coding.  This has
52 * allowed for a very large amount of code to be generated in a fairly
53 * short amount of time (i.e. cut, paste, and modify).  The result is
54 * that much of the code below could have been folded into subroutines
55 * for a large reduction in size of this file.  The downside would be
56 * that there would be a penalty in execution speed.  The file could
57 * also have been *MUCH* larger by inlining certain functions which
58 * were called.  This could have resulted even faster execution.  The
59 * prime directive I used to decide whether to inline the code or to
60 * modularize it, was basically: 1) no unnecessary subroutine calls,
61 * 2) no routines more than about 200 lines in size, and 3) modularize
62 * any code that I might not get right the first time.  The fetch_*
63 * subroutines fall into the latter category.  The The decode_* fall
64 * into the second category.  The coding of the "switch(mod){ .... }"
65 * in many of the subroutines below falls into the first category.
66 * Especially, the coding of {add,and,or,sub,...}_{byte,word}
67 * subroutines are an especially glaring case of the third guideline.
68 * Since so much of the code is cloned from other modules (compare
69 * opcode #00 to opcode #01), making the basic operations subroutine
70 * calls is especially important; otherwise mistakes in coding an
71 * "add" would represent a nightmare in maintenance.
72 *
73 ****************************************************************************/
74
75 #include <common.h>
76 #include "x86emu/x86emui.h"
77
78 /*----------------------------- Implementation ----------------------------*/
79
80 /* constant arrays to do several instructions in just one function */
81
82 #ifdef DEBUG
83 static char *x86emu_GenOpName[8] = {
84     "ADD", "OR", "ADC", "SBB", "AND", "SUB", "XOR", "CMP"};
85 #endif
86
87 /* used by several opcodes  */
88 static u8 (*genop_byte_operation[])(u8 d, u8 s) =
89 {
90     add_byte,           /* 00 */
91     or_byte,            /* 01 */
92     adc_byte,           /* 02 */
93     sbb_byte,           /* 03 */
94     and_byte,           /* 04 */
95     sub_byte,           /* 05 */
96     xor_byte,           /* 06 */
97     cmp_byte,           /* 07 */
98 };
99
100 static u16 (*genop_word_operation[])(u16 d, u16 s) =
101 {
102     add_word,           /*00 */
103     or_word,            /*01 */
104     adc_word,           /*02 */
105     sbb_word,           /*03 */
106     and_word,           /*04 */
107     sub_word,           /*05 */
108     xor_word,           /*06 */
109     cmp_word,           /*07 */
110 };
111
112 static u32 (*genop_long_operation[])(u32 d, u32 s) =
113 {
114     add_long,           /*00 */
115     or_long,            /*01 */
116     adc_long,           /*02 */
117     sbb_long,           /*03 */
118     and_long,           /*04 */
119     sub_long,           /*05 */
120     xor_long,           /*06 */
121     cmp_long,           /*07 */
122 };
123
124 /* used by opcodes 80, c0, d0, and d2. */
125 static u8(*opcD0_byte_operation[])(u8 d, u8 s) =
126 {
127     rol_byte,
128     ror_byte,
129     rcl_byte,
130     rcr_byte,
131     shl_byte,
132     shr_byte,
133     shl_byte,           /* sal_byte === shl_byte  by definition */
134     sar_byte,
135 };
136
137 /* used by opcodes c1, d1, and d3. */
138 static u16(*opcD1_word_operation[])(u16 s, u8 d) =
139 {
140     rol_word,
141     ror_word,
142     rcl_word,
143     rcr_word,
144     shl_word,
145     shr_word,
146     shl_word,           /* sal_byte === shl_byte  by definition */
147     sar_word,
148 };
149
150 /* used by opcodes c1, d1, and d3. */
151 static u32 (*opcD1_long_operation[])(u32 s, u8 d) =
152 {
153     rol_long,
154     ror_long,
155     rcl_long,
156     rcr_long,
157     shl_long,
158     shr_long,
159     shl_long,           /* sal_byte === shl_byte  by definition */
160     sar_long,
161 };
162
163 #ifdef DEBUG
164
165 static char *opF6_names[8] =
166   { "TEST\t", "", "NOT\t", "NEG\t", "MUL\t", "IMUL\t", "DIV\t", "IDIV\t" };
167
168 #endif
169
170 /****************************************************************************
171 PARAMETERS:
172 op1 - Instruction op code
173
174 REMARKS:
175 Handles illegal opcodes.
176 ****************************************************************************/
177 void x86emuOp_illegal_op(
178     u8 op1)
179 {
180     START_OF_INSTR();
181     if (M.x86.R_SP != 0) {
182         DECODE_PRINTF("ILLEGAL X86 OPCODE\n");
183         TRACE_REGS();
184         DB( printk("%04x:%04x: %02X ILLEGAL X86 OPCODE!\n",
185             M.x86.R_CS, M.x86.R_IP-1,op1));
186         HALT_SYS();
187         }
188     else {
189         /* If we get here, it means the stack pointer is back to zero
190          * so we are just returning from an emulator service call
191          * so therte is no need to display an error message. We trap
192          * the emulator with an 0xF1 opcode to finish the service
193          * call.
194          */
195         X86EMU_halt_sys();
196         }
197     END_OF_INSTR();
198 }
199
200 /****************************************************************************
201 REMARKS:
202 Handles opcodes 0x00, 0x08, 0x10, 0x18, 0x20, 0x28, 0x30, 0x38
203 ****************************************************************************/
204 void x86emuOp_genop_byte_RM_R(u8 op1)
205 {
206     int mod, rl, rh;
207     uint destoffset;
208     u8 *destreg, *srcreg;
209     u8 destval;
210
211     op1 = (op1 >> 3) & 0x7;
212
213     START_OF_INSTR();
214     DECODE_PRINTF(x86emu_GenOpName[op1]);
215     DECODE_PRINTF("\t");
216     FETCH_DECODE_MODRM(mod, rh, rl);
217     if(mod<3)
218         { destoffset = decode_rmXX_address(mod,rl);
219         DECODE_PRINTF(",");
220         destval = fetch_data_byte(destoffset);
221         srcreg = DECODE_RM_BYTE_REGISTER(rh);
222         DECODE_PRINTF("\n");
223         TRACE_AND_STEP();
224         destval = genop_byte_operation[op1](destval, *srcreg);
225         store_data_byte(destoffset, destval);
226         }
227     else
228         {                       /* register to register */
229         destreg = DECODE_RM_BYTE_REGISTER(rl);
230         DECODE_PRINTF(",");
231         srcreg = DECODE_RM_BYTE_REGISTER(rh);
232         DECODE_PRINTF("\n");
233         TRACE_AND_STEP();
234         *destreg = genop_byte_operation[op1](*destreg, *srcreg);
235         }
236     DECODE_CLEAR_SEGOVR();
237     END_OF_INSTR();
238 }
239
240 /****************************************************************************
241 REMARKS:
242 Handles opcodes 0x01, 0x09, 0x11, 0x19, 0x21, 0x29, 0x31, 0x39
243 ****************************************************************************/
244 void x86emuOp_genop_word_RM_R(u8 op1)
245 {
246     int mod, rl, rh;
247     uint destoffset;
248
249     op1 = (op1 >> 3) & 0x7;
250
251     START_OF_INSTR();
252     DECODE_PRINTF(x86emu_GenOpName[op1]);
253     DECODE_PRINTF("\t");
254     FETCH_DECODE_MODRM(mod, rh, rl);
255
256     if(mod<3) {
257         destoffset = decode_rmXX_address(mod,rl);
258         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
259             u32 destval;
260             u32 *srcreg;
261
262             DECODE_PRINTF(",");
263             destval = fetch_data_long(destoffset);
264             srcreg = DECODE_RM_LONG_REGISTER(rh);
265             DECODE_PRINTF("\n");
266             TRACE_AND_STEP();
267             destval = genop_long_operation[op1](destval, *srcreg);
268             store_data_long(destoffset, destval);
269         } else {
270             u16 destval;
271             u16 *srcreg;
272
273             DECODE_PRINTF(",");
274             destval = fetch_data_word(destoffset);
275             srcreg = DECODE_RM_WORD_REGISTER(rh);
276             DECODE_PRINTF("\n");
277             TRACE_AND_STEP();
278             destval = genop_word_operation[op1](destval, *srcreg);
279             store_data_word(destoffset, destval);
280         }
281     } else {                    /* register to register */
282         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
283             u32 *destreg,*srcreg;
284
285             destreg = DECODE_RM_LONG_REGISTER(rl);
286             DECODE_PRINTF(",");
287             srcreg = DECODE_RM_LONG_REGISTER(rh);
288             DECODE_PRINTF("\n");
289             TRACE_AND_STEP();
290             *destreg = genop_long_operation[op1](*destreg, *srcreg);
291         } else {
292             u16 *destreg,*srcreg;
293
294             destreg = DECODE_RM_WORD_REGISTER(rl);
295             DECODE_PRINTF(",");
296             srcreg = DECODE_RM_WORD_REGISTER(rh);
297             DECODE_PRINTF("\n");
298             TRACE_AND_STEP();
299             *destreg = genop_word_operation[op1](*destreg, *srcreg);
300         }
301     }
302     DECODE_CLEAR_SEGOVR();
303     END_OF_INSTR();
304 }
305
306 /****************************************************************************
307 REMARKS:
308 Handles opcodes 0x02, 0x0a, 0x12, 0x1a, 0x22, 0x2a, 0x32, 0x3a
309 ****************************************************************************/
310 void x86emuOp_genop_byte_R_RM(u8 op1)
311 {
312     int mod, rl, rh;
313     u8 *destreg, *srcreg;
314     uint srcoffset;
315     u8 srcval;
316
317     op1 = (op1 >> 3) & 0x7;
318
319     START_OF_INSTR();
320     DECODE_PRINTF(x86emu_GenOpName[op1]);
321     DECODE_PRINTF("\t");
322     FETCH_DECODE_MODRM(mod, rh, rl);
323     if (mod < 3) {
324         destreg = DECODE_RM_BYTE_REGISTER(rh);
325         DECODE_PRINTF(",");
326         srcoffset = decode_rmXX_address(mod,rl);
327         srcval = fetch_data_byte(srcoffset);
328     } else {     /* register to register */
329         destreg = DECODE_RM_BYTE_REGISTER(rh);
330         DECODE_PRINTF(",");
331         srcreg = DECODE_RM_BYTE_REGISTER(rl);
332         srcval = *srcreg;
333     }
334     DECODE_PRINTF("\n");
335     TRACE_AND_STEP();
336     *destreg = genop_byte_operation[op1](*destreg, srcval);
337
338     DECODE_CLEAR_SEGOVR();
339     END_OF_INSTR();
340 }
341
342 /****************************************************************************
343 REMARKS:
344 Handles opcodes 0x03, 0x0b, 0x13, 0x1b, 0x23, 0x2b, 0x33, 0x3b
345 ****************************************************************************/
346 void x86emuOp_genop_word_R_RM(u8 op1)
347 {
348     int mod, rl, rh;
349     uint srcoffset;
350     u32 *destreg32, srcval;
351     u16 *destreg;
352
353     op1 = (op1 >> 3) & 0x7;
354
355     START_OF_INSTR();
356     DECODE_PRINTF(x86emu_GenOpName[op1]);
357     DECODE_PRINTF("\t");
358     FETCH_DECODE_MODRM(mod, rh, rl);
359     if (mod < 3) {
360         srcoffset = decode_rmXX_address(mod,rl);
361         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
362             destreg32 = DECODE_RM_LONG_REGISTER(rh);
363             DECODE_PRINTF(",");
364             srcval = fetch_data_long(srcoffset);
365             DECODE_PRINTF("\n");
366             TRACE_AND_STEP();
367             *destreg32 = genop_long_operation[op1](*destreg32, srcval);
368         } else {
369             destreg = DECODE_RM_WORD_REGISTER(rh);
370             DECODE_PRINTF(",");
371             srcval = fetch_data_word(srcoffset);
372             DECODE_PRINTF("\n");
373             TRACE_AND_STEP();
374             *destreg = genop_word_operation[op1](*destreg, srcval);
375         }
376     } else {                     /* register to register */
377         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
378             u32 *srcreg;
379             destreg32 = DECODE_RM_LONG_REGISTER(rh);
380             DECODE_PRINTF(",");
381             srcreg = DECODE_RM_LONG_REGISTER(rl);
382             DECODE_PRINTF("\n");
383             TRACE_AND_STEP();
384             *destreg32 = genop_long_operation[op1](*destreg32, *srcreg);
385         } else {
386             u16 *srcreg;
387             destreg = DECODE_RM_WORD_REGISTER(rh);
388             DECODE_PRINTF(",");
389             srcreg = DECODE_RM_WORD_REGISTER(rl);
390             DECODE_PRINTF("\n");
391             TRACE_AND_STEP();
392             *destreg = genop_word_operation[op1](*destreg, *srcreg);
393         }
394     }
395     DECODE_CLEAR_SEGOVR();
396     END_OF_INSTR();
397 }
398
399 /****************************************************************************
400 REMARKS:
401 Handles opcodes 0x04, 0x0c, 0x14, 0x1c, 0x24, 0x2c, 0x34, 0x3c
402 ****************************************************************************/
403 void x86emuOp_genop_byte_AL_IMM(u8 op1)
404 {
405     u8 srcval;
406
407     op1 = (op1 >> 3) & 0x7;
408
409     START_OF_INSTR();
410     DECODE_PRINTF(x86emu_GenOpName[op1]);
411     DECODE_PRINTF("\tAL,");
412     srcval = fetch_byte_imm();
413     DECODE_PRINTF2("%x\n", srcval);
414     TRACE_AND_STEP();
415     M.x86.R_AL = genop_byte_operation[op1](M.x86.R_AL, srcval);
416     DECODE_CLEAR_SEGOVR();
417     END_OF_INSTR();
418 }
419
420 /****************************************************************************
421 REMARKS:
422 Handles opcodes 0x05, 0x0d, 0x15, 0x1d, 0x25, 0x2d, 0x35, 0x3d
423 ****************************************************************************/
424 void x86emuOp_genop_word_AX_IMM(u8 op1)
425 {
426     u32 srcval;
427
428     op1 = (op1 >> 3) & 0x7;
429
430     START_OF_INSTR();
431     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
432         DECODE_PRINTF(x86emu_GenOpName[op1]);
433         DECODE_PRINTF("\tEAX,");
434         srcval = fetch_long_imm();
435     } else {
436         DECODE_PRINTF(x86emu_GenOpName[op1]);
437         DECODE_PRINTF("\tAX,");
438         srcval = fetch_word_imm();
439     }
440     DECODE_PRINTF2("%x\n", srcval);
441     TRACE_AND_STEP();
442     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
443         M.x86.R_EAX = genop_long_operation[op1](M.x86.R_EAX, srcval);
444     } else {
445         M.x86.R_AX = genop_word_operation[op1](M.x86.R_AX, (u16)srcval);
446     }
447     DECODE_CLEAR_SEGOVR();
448     END_OF_INSTR();
449 }
450
451 /****************************************************************************
452 REMARKS:
453 Handles opcode 0x06
454 ****************************************************************************/
455 void x86emuOp_push_ES(u8 X86EMU_UNUSED(op1))
456 {
457     START_OF_INSTR();
458     DECODE_PRINTF("PUSH\tES\n");
459     TRACE_AND_STEP();
460     push_word(M.x86.R_ES);
461     DECODE_CLEAR_SEGOVR();
462     END_OF_INSTR();
463 }
464
465 /****************************************************************************
466 REMARKS:
467 Handles opcode 0x07
468 ****************************************************************************/
469 void x86emuOp_pop_ES(u8 X86EMU_UNUSED(op1))
470 {
471     START_OF_INSTR();
472     DECODE_PRINTF("POP\tES\n");
473     TRACE_AND_STEP();
474     M.x86.R_ES = pop_word();
475     DECODE_CLEAR_SEGOVR();
476     END_OF_INSTR();
477 }
478
479 /****************************************************************************
480 REMARKS:
481 Handles opcode 0x0e
482 ****************************************************************************/
483 void x86emuOp_push_CS(u8 X86EMU_UNUSED(op1))
484 {
485     START_OF_INSTR();
486     DECODE_PRINTF("PUSH\tCS\n");
487     TRACE_AND_STEP();
488     push_word(M.x86.R_CS);
489     DECODE_CLEAR_SEGOVR();
490     END_OF_INSTR();
491 }
492
493 /****************************************************************************
494 REMARKS:
495 Handles opcode 0x0f. Escape for two-byte opcode (286 or better)
496 ****************************************************************************/
497 void x86emuOp_two_byte(u8 X86EMU_UNUSED(op1))
498 {
499     u8 op2 = (*sys_rdb)(((u32)M.x86.R_CS << 4) + (M.x86.R_IP++));
500     INC_DECODED_INST_LEN(1);
501     (*x86emu_optab2[op2])(op2);
502 }
503
504 /****************************************************************************
505 REMARKS:
506 Handles opcode 0x16
507 ****************************************************************************/
508 void x86emuOp_push_SS(u8 X86EMU_UNUSED(op1))
509 {
510     START_OF_INSTR();
511     DECODE_PRINTF("PUSH\tSS\n");
512     TRACE_AND_STEP();
513     push_word(M.x86.R_SS);
514     DECODE_CLEAR_SEGOVR();
515     END_OF_INSTR();
516 }
517
518 /****************************************************************************
519 REMARKS:
520 Handles opcode 0x17
521 ****************************************************************************/
522 void x86emuOp_pop_SS(u8 X86EMU_UNUSED(op1))
523 {
524     START_OF_INSTR();
525     DECODE_PRINTF("POP\tSS\n");
526     TRACE_AND_STEP();
527     M.x86.R_SS = pop_word();
528     DECODE_CLEAR_SEGOVR();
529     END_OF_INSTR();
530 }
531
532 /****************************************************************************
533 REMARKS:
534 Handles opcode 0x1e
535 ****************************************************************************/
536 void x86emuOp_push_DS(u8 X86EMU_UNUSED(op1))
537 {
538     START_OF_INSTR();
539     DECODE_PRINTF("PUSH\tDS\n");
540     TRACE_AND_STEP();
541     push_word(M.x86.R_DS);
542     DECODE_CLEAR_SEGOVR();
543     END_OF_INSTR();
544 }
545
546 /****************************************************************************
547 REMARKS:
548 Handles opcode 0x1f
549 ****************************************************************************/
550 void x86emuOp_pop_DS(u8 X86EMU_UNUSED(op1))
551 {
552     START_OF_INSTR();
553     DECODE_PRINTF("POP\tDS\n");
554     TRACE_AND_STEP();
555     M.x86.R_DS = pop_word();
556     DECODE_CLEAR_SEGOVR();
557     END_OF_INSTR();
558 }
559
560 /****************************************************************************
561 REMARKS:
562 Handles opcode 0x26
563 ****************************************************************************/
564 void x86emuOp_segovr_ES(u8 X86EMU_UNUSED(op1))
565 {
566     START_OF_INSTR();
567     DECODE_PRINTF("ES:\n");
568     TRACE_AND_STEP();
569     M.x86.mode |= SYSMODE_SEGOVR_ES;
570     /*
571      * note the lack of DECODE_CLEAR_SEGOVR(r) since, here is one of 4
572      * opcode subroutines we do not want to do this.
573      */
574     END_OF_INSTR();
575 }
576
577 /****************************************************************************
578 REMARKS:
579 Handles opcode 0x27
580 ****************************************************************************/
581 void x86emuOp_daa(u8 X86EMU_UNUSED(op1))
582 {
583     START_OF_INSTR();
584     DECODE_PRINTF("DAA\n");
585     TRACE_AND_STEP();
586     M.x86.R_AL = daa_byte(M.x86.R_AL);
587     DECODE_CLEAR_SEGOVR();
588     END_OF_INSTR();
589 }
590
591 /****************************************************************************
592 REMARKS:
593 Handles opcode 0x2e
594 ****************************************************************************/
595 void x86emuOp_segovr_CS(u8 X86EMU_UNUSED(op1))
596 {
597     START_OF_INSTR();
598     DECODE_PRINTF("CS:\n");
599     TRACE_AND_STEP();
600     M.x86.mode |= SYSMODE_SEGOVR_CS;
601     /* note no DECODE_CLEAR_SEGOVR here. */
602     END_OF_INSTR();
603 }
604
605 /****************************************************************************
606 REMARKS:
607 Handles opcode 0x2f
608 ****************************************************************************/
609 void x86emuOp_das(u8 X86EMU_UNUSED(op1))
610 {
611     START_OF_INSTR();
612     DECODE_PRINTF("DAS\n");
613     TRACE_AND_STEP();
614     M.x86.R_AL = das_byte(M.x86.R_AL);
615     DECODE_CLEAR_SEGOVR();
616     END_OF_INSTR();
617 }
618
619 /****************************************************************************
620 REMARKS:
621 Handles opcode 0x36
622 ****************************************************************************/
623 void x86emuOp_segovr_SS(u8 X86EMU_UNUSED(op1))
624 {
625     START_OF_INSTR();
626     DECODE_PRINTF("SS:\n");
627     TRACE_AND_STEP();
628     M.x86.mode |= SYSMODE_SEGOVR_SS;
629     /* no DECODE_CLEAR_SEGOVR ! */
630     END_OF_INSTR();
631 }
632
633 /****************************************************************************
634 REMARKS:
635 Handles opcode 0x37
636 ****************************************************************************/
637 void x86emuOp_aaa(u8 X86EMU_UNUSED(op1))
638 {
639     START_OF_INSTR();
640     DECODE_PRINTF("AAA\n");
641     TRACE_AND_STEP();
642     M.x86.R_AX = aaa_word(M.x86.R_AX);
643     DECODE_CLEAR_SEGOVR();
644     END_OF_INSTR();
645 }
646
647 /****************************************************************************
648 REMARKS:
649 Handles opcode 0x3e
650 ****************************************************************************/
651 void x86emuOp_segovr_DS(u8 X86EMU_UNUSED(op1))
652 {
653     START_OF_INSTR();
654     DECODE_PRINTF("DS:\n");
655     TRACE_AND_STEP();
656     M.x86.mode |= SYSMODE_SEGOVR_DS;
657     /* NO DECODE_CLEAR_SEGOVR! */
658     END_OF_INSTR();
659 }
660
661 /****************************************************************************
662 REMARKS:
663 Handles opcode 0x3f
664 ****************************************************************************/
665 void x86emuOp_aas(u8 X86EMU_UNUSED(op1))
666 {
667     START_OF_INSTR();
668     DECODE_PRINTF("AAS\n");
669     TRACE_AND_STEP();
670     M.x86.R_AX = aas_word(M.x86.R_AX);
671     DECODE_CLEAR_SEGOVR();
672     END_OF_INSTR();
673 }
674
675 /****************************************************************************
676 REMARKS:
677 Handles opcode 0x40 - 0x47
678 ****************************************************************************/
679 void x86emuOp_inc_register(u8 op1)
680 {
681     START_OF_INSTR();
682     op1 &= 0x7;
683     DECODE_PRINTF("INC\t");
684     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
685         u32 *reg;
686         reg = DECODE_RM_LONG_REGISTER(op1);
687         DECODE_PRINTF("\n");
688         TRACE_AND_STEP();
689         *reg = inc_long(*reg);
690     } else {
691         u16 *reg;
692         reg = DECODE_RM_WORD_REGISTER(op1);
693         DECODE_PRINTF("\n");
694         TRACE_AND_STEP();
695         *reg = inc_word(*reg);
696     }
697     DECODE_CLEAR_SEGOVR();
698     END_OF_INSTR();
699 }
700
701 /****************************************************************************
702 REMARKS:
703 Handles opcode 0x48 - 0x4F
704 ****************************************************************************/
705 void x86emuOp_dec_register(u8 op1)
706 {
707     START_OF_INSTR();
708     op1 &= 0x7;
709     DECODE_PRINTF("DEC\t");
710     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
711         u32 *reg;
712         reg = DECODE_RM_LONG_REGISTER(op1);
713         DECODE_PRINTF("\n");
714         TRACE_AND_STEP();
715         *reg = dec_long(*reg);
716     } else {
717         u16 *reg;
718         reg = DECODE_RM_WORD_REGISTER(op1);
719         DECODE_PRINTF("\n");
720         TRACE_AND_STEP();
721         *reg = dec_word(*reg);
722     }
723     DECODE_CLEAR_SEGOVR();
724     END_OF_INSTR();
725 }
726
727 /****************************************************************************
728 REMARKS:
729 Handles opcode 0x50 - 0x57
730 ****************************************************************************/
731 void x86emuOp_push_register(u8 op1)
732 {
733     START_OF_INSTR();
734     op1 &= 0x7;
735     DECODE_PRINTF("PUSH\t");
736     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
737         u32 *reg;
738         reg = DECODE_RM_LONG_REGISTER(op1);
739         DECODE_PRINTF("\n");
740         TRACE_AND_STEP();
741         push_long(*reg);
742     } else {
743         u16 *reg;
744         reg = DECODE_RM_WORD_REGISTER(op1);
745         DECODE_PRINTF("\n");
746         TRACE_AND_STEP();
747         push_word(*reg);
748     }
749     DECODE_CLEAR_SEGOVR();
750     END_OF_INSTR();
751 }
752
753 /****************************************************************************
754 REMARKS:
755 Handles opcode 0x58 - 0x5F
756 ****************************************************************************/
757 void x86emuOp_pop_register(u8 op1)
758 {
759     START_OF_INSTR();
760     op1 &= 0x7;
761     DECODE_PRINTF("POP\t");
762     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
763         u32 *reg;
764         reg = DECODE_RM_LONG_REGISTER(op1);
765         DECODE_PRINTF("\n");
766         TRACE_AND_STEP();
767         *reg = pop_long();
768     } else {
769         u16 *reg;
770         reg = DECODE_RM_WORD_REGISTER(op1);
771         DECODE_PRINTF("\n");
772         TRACE_AND_STEP();
773         *reg = pop_word();
774     }
775     DECODE_CLEAR_SEGOVR();
776     END_OF_INSTR();
777 }
778
779 /****************************************************************************
780 REMARKS:
781 Handles opcode 0x60
782 ****************************************************************************/
783 void x86emuOp_push_all(u8 X86EMU_UNUSED(op1))
784 {
785     START_OF_INSTR();
786     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
787         DECODE_PRINTF("PUSHAD\n");
788     } else {
789         DECODE_PRINTF("PUSHA\n");
790     }
791     TRACE_AND_STEP();
792     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
793         u32 old_sp = M.x86.R_ESP;
794
795         push_long(M.x86.R_EAX);
796         push_long(M.x86.R_ECX);
797         push_long(M.x86.R_EDX);
798         push_long(M.x86.R_EBX);
799         push_long(old_sp);
800         push_long(M.x86.R_EBP);
801         push_long(M.x86.R_ESI);
802         push_long(M.x86.R_EDI);
803     } else {
804         u16 old_sp = M.x86.R_SP;
805
806         push_word(M.x86.R_AX);
807         push_word(M.x86.R_CX);
808         push_word(M.x86.R_DX);
809         push_word(M.x86.R_BX);
810         push_word(old_sp);
811         push_word(M.x86.R_BP);
812         push_word(M.x86.R_SI);
813         push_word(M.x86.R_DI);
814     }
815     DECODE_CLEAR_SEGOVR();
816     END_OF_INSTR();
817 }
818
819 /****************************************************************************
820 REMARKS:
821 Handles opcode 0x61
822 ****************************************************************************/
823 void x86emuOp_pop_all(u8 X86EMU_UNUSED(op1))
824 {
825     START_OF_INSTR();
826     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
827         DECODE_PRINTF("POPAD\n");
828     } else {
829         DECODE_PRINTF("POPA\n");
830     }
831     TRACE_AND_STEP();
832     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
833         M.x86.R_EDI = pop_long();
834         M.x86.R_ESI = pop_long();
835         M.x86.R_EBP = pop_long();
836         M.x86.R_ESP += 4;              /* skip ESP */
837         M.x86.R_EBX = pop_long();
838         M.x86.R_EDX = pop_long();
839         M.x86.R_ECX = pop_long();
840         M.x86.R_EAX = pop_long();
841     } else {
842         M.x86.R_DI = pop_word();
843         M.x86.R_SI = pop_word();
844         M.x86.R_BP = pop_word();
845         M.x86.R_SP += 2;               /* skip SP */
846         M.x86.R_BX = pop_word();
847         M.x86.R_DX = pop_word();
848         M.x86.R_CX = pop_word();
849         M.x86.R_AX = pop_word();
850     }
851     DECODE_CLEAR_SEGOVR();
852     END_OF_INSTR();
853 }
854
855 /*opcode 0x62   ILLEGAL OP, calls x86emuOp_illegal_op() */
856 /*opcode 0x63   ILLEGAL OP, calls x86emuOp_illegal_op() */
857
858 /****************************************************************************
859 REMARKS:
860 Handles opcode 0x64
861 ****************************************************************************/
862 void x86emuOp_segovr_FS(u8 X86EMU_UNUSED(op1))
863 {
864     START_OF_INSTR();
865     DECODE_PRINTF("FS:\n");
866     TRACE_AND_STEP();
867     M.x86.mode |= SYSMODE_SEGOVR_FS;
868     /*
869      * note the lack of DECODE_CLEAR_SEGOVR(r) since, here is one of 4
870      * opcode subroutines we do not want to do this.
871      */
872     END_OF_INSTR();
873 }
874
875 /****************************************************************************
876 REMARKS:
877 Handles opcode 0x65
878 ****************************************************************************/
879 void x86emuOp_segovr_GS(u8 X86EMU_UNUSED(op1))
880 {
881     START_OF_INSTR();
882     DECODE_PRINTF("GS:\n");
883     TRACE_AND_STEP();
884     M.x86.mode |= SYSMODE_SEGOVR_GS;
885     /*
886      * note the lack of DECODE_CLEAR_SEGOVR(r) since, here is one of 4
887      * opcode subroutines we do not want to do this.
888      */
889     END_OF_INSTR();
890 }
891
892 /****************************************************************************
893 REMARKS:
894 Handles opcode 0x66 - prefix for 32-bit register
895 ****************************************************************************/
896 void x86emuOp_prefix_data(u8 X86EMU_UNUSED(op1))
897 {
898     START_OF_INSTR();
899     DECODE_PRINTF("DATA:\n");
900     TRACE_AND_STEP();
901     M.x86.mode |= SYSMODE_PREFIX_DATA;
902     /* note no DECODE_CLEAR_SEGOVR here. */
903     END_OF_INSTR();
904 }
905
906 /****************************************************************************
907 REMARKS:
908 Handles opcode 0x67 - prefix for 32-bit address
909 ****************************************************************************/
910 void x86emuOp_prefix_addr(u8 X86EMU_UNUSED(op1))
911 {
912     START_OF_INSTR();
913     DECODE_PRINTF("ADDR:\n");
914     TRACE_AND_STEP();
915     M.x86.mode |= SYSMODE_PREFIX_ADDR;
916     /* note no DECODE_CLEAR_SEGOVR here. */
917     END_OF_INSTR();
918 }
919
920 /****************************************************************************
921 REMARKS:
922 Handles opcode 0x68
923 ****************************************************************************/
924 void x86emuOp_push_word_IMM(u8 X86EMU_UNUSED(op1))
925 {
926     u32 imm;
927
928     START_OF_INSTR();
929     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
930         imm = fetch_long_imm();
931     } else {
932         imm = fetch_word_imm();
933     }
934     DECODE_PRINTF2("PUSH\t%x\n", imm);
935     TRACE_AND_STEP();
936     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
937         push_long(imm);
938     } else {
939         push_word((u16)imm);
940     }
941     DECODE_CLEAR_SEGOVR();
942     END_OF_INSTR();
943 }
944
945 /****************************************************************************
946 REMARKS:
947 Handles opcode 0x69
948 ****************************************************************************/
949 void x86emuOp_imul_word_IMM(u8 X86EMU_UNUSED(op1))
950 {
951     int mod, rl, rh;
952     uint srcoffset;
953
954     START_OF_INSTR();
955     DECODE_PRINTF("IMUL\t");
956     FETCH_DECODE_MODRM(mod, rh, rl);
957     if (mod < 3) {
958         srcoffset = decode_rmXX_address(mod, rl);
959         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
960             u32 *destreg;
961             u32 srcval;
962             u32 res_lo,res_hi;
963             s32 imm;
964
965             destreg = DECODE_RM_LONG_REGISTER(rh);
966             DECODE_PRINTF(",");
967             srcval = fetch_data_long(srcoffset);
968             imm = fetch_long_imm();
969             DECODE_PRINTF2(",%d\n", (s32)imm);
970             TRACE_AND_STEP();
971             imul_long_direct(&res_lo,&res_hi,(s32)srcval,(s32)imm);
972             if ((((res_lo & 0x80000000) == 0) && (res_hi == 0x00000000)) ||
973                 (((res_lo & 0x80000000) != 0) && (res_hi == 0xFFFFFFFF))) {
974                 CLEAR_FLAG(F_CF);
975                 CLEAR_FLAG(F_OF);
976             } else {
977                 SET_FLAG(F_CF);
978                 SET_FLAG(F_OF);
979             }
980             *destreg = (u32)res_lo;
981         } else {
982             u16 *destreg;
983             u16 srcval;
984             u32 res;
985             s16 imm;
986
987             destreg = DECODE_RM_WORD_REGISTER(rh);
988             DECODE_PRINTF(",");
989             srcval = fetch_data_word(srcoffset);
990             imm = fetch_word_imm();
991             DECODE_PRINTF2(",%d\n", (s32)imm);
992             TRACE_AND_STEP();
993             res = (s16)srcval * (s16)imm;
994             if ((((res & 0x8000) == 0) && ((res >> 16) == 0x0000)) ||
995                 (((res & 0x8000) != 0) && ((res >> 16) == 0xFFFF))) {
996                 CLEAR_FLAG(F_CF);
997                 CLEAR_FLAG(F_OF);
998             } else {
999                 SET_FLAG(F_CF);
1000                 SET_FLAG(F_OF);
1001             }
1002             *destreg = (u16)res;
1003         }
1004     } else {                     /* register to register */
1005         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1006             u32 *destreg,*srcreg;
1007             u32 res_lo,res_hi;
1008             s32 imm;
1009
1010             destreg = DECODE_RM_LONG_REGISTER(rh);
1011             DECODE_PRINTF(",");
1012             srcreg = DECODE_RM_LONG_REGISTER(rl);
1013             imm = fetch_long_imm();
1014             DECODE_PRINTF2(",%d\n", (s32)imm);
1015             TRACE_AND_STEP();
1016             imul_long_direct(&res_lo,&res_hi,(s32)*srcreg,(s32)imm);
1017             if ((((res_lo & 0x80000000) == 0) && (res_hi == 0x00000000)) ||
1018                 (((res_lo & 0x80000000) != 0) && (res_hi == 0xFFFFFFFF))) {
1019                 CLEAR_FLAG(F_CF);
1020                 CLEAR_FLAG(F_OF);
1021             } else {
1022                 SET_FLAG(F_CF);
1023                 SET_FLAG(F_OF);
1024             }
1025             *destreg = (u32)res_lo;
1026         } else {
1027             u16 *destreg,*srcreg;
1028             u32 res;
1029             s16 imm;
1030
1031             destreg = DECODE_RM_WORD_REGISTER(rh);
1032             DECODE_PRINTF(",");
1033             srcreg = DECODE_RM_WORD_REGISTER(rl);
1034             imm = fetch_word_imm();
1035             DECODE_PRINTF2(",%d\n", (s32)imm);
1036             res = (s16)*srcreg * (s16)imm;
1037             if ((((res & 0x8000) == 0) && ((res >> 16) == 0x0000)) ||
1038                 (((res & 0x8000) != 0) && ((res >> 16) == 0xFFFF))) {
1039                 CLEAR_FLAG(F_CF);
1040                 CLEAR_FLAG(F_OF);
1041             } else {
1042                 SET_FLAG(F_CF);
1043                 SET_FLAG(F_OF);
1044             }
1045             *destreg = (u16)res;
1046         }
1047     }
1048     DECODE_CLEAR_SEGOVR();
1049     END_OF_INSTR();
1050 }
1051
1052 /****************************************************************************
1053 REMARKS:
1054 Handles opcode 0x6a
1055 ****************************************************************************/
1056 void x86emuOp_push_byte_IMM(u8 X86EMU_UNUSED(op1))
1057 {
1058     s16 imm;
1059
1060     START_OF_INSTR();
1061     imm = (s8)fetch_byte_imm();
1062     DECODE_PRINTF2("PUSH\t%d\n", imm);
1063     TRACE_AND_STEP();
1064     push_word(imm);
1065     DECODE_CLEAR_SEGOVR();
1066     END_OF_INSTR();
1067 }
1068
1069 /****************************************************************************
1070 REMARKS:
1071 Handles opcode 0x6b
1072 ****************************************************************************/
1073 void x86emuOp_imul_byte_IMM(u8 X86EMU_UNUSED(op1))
1074 {
1075     int mod, rl, rh;
1076     uint srcoffset;
1077     s8  imm;
1078
1079     START_OF_INSTR();
1080     DECODE_PRINTF("IMUL\t");
1081     FETCH_DECODE_MODRM(mod, rh, rl);
1082     if (mod < 3) {
1083         srcoffset = decode_rmXX_address(mod, rl);
1084         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1085             u32 *destreg;
1086             u32 srcval;
1087             u32 res_lo,res_hi;
1088
1089             destreg = DECODE_RM_LONG_REGISTER(rh);
1090             DECODE_PRINTF(",");
1091             srcval = fetch_data_long(srcoffset);
1092             imm = fetch_byte_imm();
1093             DECODE_PRINTF2(",%d\n", (s32)imm);
1094             TRACE_AND_STEP();
1095             imul_long_direct(&res_lo,&res_hi,(s32)srcval,(s32)imm);
1096             if ((((res_lo & 0x80000000) == 0) && (res_hi == 0x00000000)) ||
1097                 (((res_lo & 0x80000000) != 0) && (res_hi == 0xFFFFFFFF))) {
1098                 CLEAR_FLAG(F_CF);
1099                 CLEAR_FLAG(F_OF);
1100             } else {
1101                 SET_FLAG(F_CF);
1102                 SET_FLAG(F_OF);
1103             }
1104             *destreg = (u32)res_lo;
1105         } else {
1106             u16 *destreg;
1107             u16 srcval;
1108             u32 res;
1109
1110             destreg = DECODE_RM_WORD_REGISTER(rh);
1111             DECODE_PRINTF(",");
1112             srcval = fetch_data_word(srcoffset);
1113             imm = fetch_byte_imm();
1114             DECODE_PRINTF2(",%d\n", (s32)imm);
1115             TRACE_AND_STEP();
1116             res = (s16)srcval * (s16)imm;
1117             if ((((res & 0x8000) == 0) && ((res >> 16) == 0x0000)) ||
1118                 (((res & 0x8000) != 0) && ((res >> 16) == 0xFFFF))) {
1119                 CLEAR_FLAG(F_CF);
1120                 CLEAR_FLAG(F_OF);
1121             } else {
1122                 SET_FLAG(F_CF);
1123                 SET_FLAG(F_OF);
1124             }
1125             *destreg = (u16)res;
1126         }
1127     } else {                     /* register to register */
1128         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1129             u32 *destreg,*srcreg;
1130             u32 res_lo,res_hi;
1131
1132             destreg = DECODE_RM_LONG_REGISTER(rh);
1133             DECODE_PRINTF(",");
1134             srcreg = DECODE_RM_LONG_REGISTER(rl);
1135             imm = fetch_byte_imm();
1136             DECODE_PRINTF2(",%d\n", (s32)imm);
1137             TRACE_AND_STEP();
1138             imul_long_direct(&res_lo,&res_hi,(s32)*srcreg,(s32)imm);
1139             if ((((res_lo & 0x80000000) == 0) && (res_hi == 0x00000000)) ||
1140                 (((res_lo & 0x80000000) != 0) && (res_hi == 0xFFFFFFFF))) {
1141                 CLEAR_FLAG(F_CF);
1142                 CLEAR_FLAG(F_OF);
1143             } else {
1144                 SET_FLAG(F_CF);
1145                 SET_FLAG(F_OF);
1146             }
1147             *destreg = (u32)res_lo;
1148         } else {
1149             u16 *destreg,*srcreg;
1150             u32 res;
1151
1152             destreg = DECODE_RM_WORD_REGISTER(rh);
1153             DECODE_PRINTF(",");
1154             srcreg = DECODE_RM_WORD_REGISTER(rl);
1155             imm = fetch_byte_imm();
1156             DECODE_PRINTF2(",%d\n", (s32)imm);
1157             TRACE_AND_STEP();
1158             res = (s16)*srcreg * (s16)imm;
1159             if ((((res & 0x8000) == 0) && ((res >> 16) == 0x0000)) ||
1160                 (((res & 0x8000) != 0) && ((res >> 16) == 0xFFFF))) {
1161                 CLEAR_FLAG(F_CF);
1162                 CLEAR_FLAG(F_OF);
1163             } else {
1164                 SET_FLAG(F_CF);
1165                 SET_FLAG(F_OF);
1166             }
1167             *destreg = (u16)res;
1168         }
1169     }
1170     DECODE_CLEAR_SEGOVR();
1171     END_OF_INSTR();
1172 }
1173
1174 /****************************************************************************
1175 REMARKS:
1176 Handles opcode 0x6c
1177 ****************************************************************************/
1178 void x86emuOp_ins_byte(u8 X86EMU_UNUSED(op1))
1179 {
1180     START_OF_INSTR();
1181     DECODE_PRINTF("INSB\n");
1182     ins(1);
1183     TRACE_AND_STEP();
1184     DECODE_CLEAR_SEGOVR();
1185     END_OF_INSTR();
1186 }
1187
1188 /****************************************************************************
1189 REMARKS:
1190 Handles opcode 0x6d
1191 ****************************************************************************/
1192 void x86emuOp_ins_word(u8 X86EMU_UNUSED(op1))
1193 {
1194     START_OF_INSTR();
1195     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1196         DECODE_PRINTF("INSD\n");
1197         ins(4);
1198     } else {
1199         DECODE_PRINTF("INSW\n");
1200         ins(2);
1201     }
1202     TRACE_AND_STEP();
1203     DECODE_CLEAR_SEGOVR();
1204     END_OF_INSTR();
1205 }
1206
1207 /****************************************************************************
1208 REMARKS:
1209 Handles opcode 0x6e
1210 ****************************************************************************/
1211 void x86emuOp_outs_byte(u8 X86EMU_UNUSED(op1))
1212 {
1213     START_OF_INSTR();
1214     DECODE_PRINTF("OUTSB\n");
1215     outs(1);
1216     TRACE_AND_STEP();
1217     DECODE_CLEAR_SEGOVR();
1218     END_OF_INSTR();
1219 }
1220
1221 /****************************************************************************
1222 REMARKS:
1223 Handles opcode 0x6f
1224 ****************************************************************************/
1225 void x86emuOp_outs_word(u8 X86EMU_UNUSED(op1))
1226 {
1227     START_OF_INSTR();
1228     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1229         DECODE_PRINTF("OUTSD\n");
1230         outs(4);
1231     } else {
1232         DECODE_PRINTF("OUTSW\n");
1233         outs(2);
1234     }
1235     TRACE_AND_STEP();
1236     DECODE_CLEAR_SEGOVR();
1237     END_OF_INSTR();
1238 }
1239
1240 /****************************************************************************
1241 REMARKS:
1242 Handles opcode 0x70 - 0x7F
1243 ****************************************************************************/
1244 int x86emu_check_jump_condition(u8 op);
1245
1246 void x86emuOp_jump_near_cond(u8 op1)
1247 {
1248     s8 offset;
1249     u16 target;
1250     int cond;
1251
1252     /* jump to byte offset if overflow flag is set */
1253     START_OF_INSTR();
1254     cond = x86emu_check_jump_condition(op1 & 0xF);
1255     offset = (s8)fetch_byte_imm();
1256     target = (u16)(M.x86.R_IP + (s16)offset);
1257     DECODE_PRINTF2("%x\n", target);
1258     TRACE_AND_STEP();
1259     if (cond)
1260         M.x86.R_IP = target;
1261     DECODE_CLEAR_SEGOVR();
1262     END_OF_INSTR();
1263 }
1264
1265 /****************************************************************************
1266 REMARKS:
1267 Handles opcode 0x80
1268 ****************************************************************************/
1269 void x86emuOp_opc80_byte_RM_IMM(u8 X86EMU_UNUSED(op1))
1270 {
1271     int mod, rl, rh;
1272     u8 *destreg;
1273     uint destoffset;
1274     u8 imm;
1275     u8 destval;
1276
1277     /*
1278      * Weirdo special case instruction format.  Part of the opcode
1279      * held below in "RH".  Doubly nested case would result, except
1280      * that the decoded instruction
1281      */
1282     START_OF_INSTR();
1283     FETCH_DECODE_MODRM(mod, rh, rl);
1284 #ifdef DEBUG
1285     if (DEBUG_DECODE()) {
1286         /* XXX DECODE_PRINTF may be changed to something more
1287            general, so that it is important to leave the strings
1288            in the same format, even though the result is that the
1289            above test is done twice. */
1290
1291         switch (rh) {
1292         case 0:
1293             DECODE_PRINTF("ADD\t");
1294             break;
1295         case 1:
1296             DECODE_PRINTF("OR\t");
1297             break;
1298         case 2:
1299             DECODE_PRINTF("ADC\t");
1300             break;
1301         case 3:
1302             DECODE_PRINTF("SBB\t");
1303             break;
1304         case 4:
1305             DECODE_PRINTF("AND\t");
1306             break;
1307         case 5:
1308             DECODE_PRINTF("SUB\t");
1309             break;
1310         case 6:
1311             DECODE_PRINTF("XOR\t");
1312             break;
1313         case 7:
1314             DECODE_PRINTF("CMP\t");
1315             break;
1316         }
1317     }
1318 #endif
1319     /* know operation, decode the mod byte to find the addressing
1320        mode. */
1321     if (mod < 3) {
1322         DECODE_PRINTF("BYTE PTR ");
1323         destoffset = decode_rmXX_address(mod, rl);
1324         DECODE_PRINTF(",");
1325         destval = fetch_data_byte(destoffset);
1326         imm = fetch_byte_imm();
1327         DECODE_PRINTF2("%x\n", imm);
1328         TRACE_AND_STEP();
1329         destval = (*genop_byte_operation[rh]) (destval, imm);
1330         if (rh != 7)
1331             store_data_byte(destoffset, destval);
1332     } else {                     /* register to register */
1333         destreg = DECODE_RM_BYTE_REGISTER(rl);
1334         DECODE_PRINTF(",");
1335         imm = fetch_byte_imm();
1336         DECODE_PRINTF2("%x\n", imm);
1337         TRACE_AND_STEP();
1338         destval = (*genop_byte_operation[rh]) (*destreg, imm);
1339         if (rh != 7)
1340             *destreg = destval;
1341     }
1342     DECODE_CLEAR_SEGOVR();
1343     END_OF_INSTR();
1344 }
1345
1346 /****************************************************************************
1347 REMARKS:
1348 Handles opcode 0x81
1349 ****************************************************************************/
1350 void x86emuOp_opc81_word_RM_IMM(u8 X86EMU_UNUSED(op1))
1351 {
1352     int mod, rl, rh;
1353     uint destoffset;
1354
1355     /*
1356      * Weirdo special case instruction format.  Part of the opcode
1357      * held below in "RH".  Doubly nested case would result, except
1358      * that the decoded instruction
1359      */
1360     START_OF_INSTR();
1361     FETCH_DECODE_MODRM(mod, rh, rl);
1362 #ifdef DEBUG
1363     if (DEBUG_DECODE()) {
1364         /* XXX DECODE_PRINTF may be changed to something more
1365            general, so that it is important to leave the strings
1366            in the same format, even though the result is that the
1367            above test is done twice. */
1368
1369         switch (rh) {
1370         case 0:
1371             DECODE_PRINTF("ADD\t");
1372             break;
1373         case 1:
1374             DECODE_PRINTF("OR\t");
1375             break;
1376         case 2:
1377             DECODE_PRINTF("ADC\t");
1378             break;
1379         case 3:
1380             DECODE_PRINTF("SBB\t");
1381             break;
1382         case 4:
1383             DECODE_PRINTF("AND\t");
1384             break;
1385         case 5:
1386             DECODE_PRINTF("SUB\t");
1387             break;
1388         case 6:
1389             DECODE_PRINTF("XOR\t");
1390             break;
1391         case 7:
1392             DECODE_PRINTF("CMP\t");
1393             break;
1394         }
1395     }
1396 #endif
1397     /*
1398      * Know operation, decode the mod byte to find the addressing
1399      * mode.
1400      */
1401     if (mod < 3) {
1402         DECODE_PRINTF("DWORD PTR ");
1403         destoffset = decode_rmXX_address(mod, rl);
1404         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1405             u32 destval,imm;
1406
1407             DECODE_PRINTF(",");
1408             destval = fetch_data_long(destoffset);
1409             imm = fetch_long_imm();
1410             DECODE_PRINTF2("%x\n", imm);
1411             TRACE_AND_STEP();
1412             destval = (*genop_long_operation[rh]) (destval, imm);
1413             if (rh != 7)
1414                 store_data_long(destoffset, destval);
1415         } else {
1416             u16 destval,imm;
1417
1418             DECODE_PRINTF(",");
1419             destval = fetch_data_word(destoffset);
1420             imm = fetch_word_imm();
1421             DECODE_PRINTF2("%x\n", imm);
1422             TRACE_AND_STEP();
1423             destval = (*genop_word_operation[rh]) (destval, imm);
1424             if (rh != 7)
1425                 store_data_word(destoffset, destval);
1426         }
1427     } else {                     /* register to register */
1428         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1429             u32 *destreg;
1430             u32 destval,imm;
1431
1432             destreg = DECODE_RM_LONG_REGISTER(rl);
1433             DECODE_PRINTF(",");
1434             imm = fetch_long_imm();
1435             DECODE_PRINTF2("%x\n", imm);
1436             TRACE_AND_STEP();
1437             destval = (*genop_long_operation[rh]) (*destreg, imm);
1438             if (rh != 7)
1439                 *destreg = destval;
1440         } else {
1441             u16 *destreg;
1442             u16 destval,imm;
1443
1444             destreg = DECODE_RM_WORD_REGISTER(rl);
1445             DECODE_PRINTF(",");
1446             imm = fetch_word_imm();
1447             DECODE_PRINTF2("%x\n", imm);
1448             TRACE_AND_STEP();
1449             destval = (*genop_word_operation[rh]) (*destreg, imm);
1450             if (rh != 7)
1451                 *destreg = destval;
1452         }
1453     }
1454     DECODE_CLEAR_SEGOVR();
1455     END_OF_INSTR();
1456 }
1457
1458 /****************************************************************************
1459 REMARKS:
1460 Handles opcode 0x82
1461 ****************************************************************************/
1462 void x86emuOp_opc82_byte_RM_IMM(u8 X86EMU_UNUSED(op1))
1463 {
1464     int mod, rl, rh;
1465     u8 *destreg;
1466     uint destoffset;
1467     u8 imm;
1468     u8 destval;
1469
1470     /*
1471      * Weirdo special case instruction format.  Part of the opcode
1472      * held below in "RH".  Doubly nested case would result, except
1473      * that the decoded instruction Similar to opcode 81, except that
1474      * the immediate byte is sign extended to a word length.
1475      */
1476     START_OF_INSTR();
1477     FETCH_DECODE_MODRM(mod, rh, rl);
1478 #ifdef DEBUG
1479     if (DEBUG_DECODE()) {
1480         /* XXX DECODE_PRINTF may be changed to something more
1481            general, so that it is important to leave the strings
1482            in the same format, even though the result is that the
1483            above test is done twice. */
1484         switch (rh) {
1485         case 0:
1486             DECODE_PRINTF("ADD\t");
1487             break;
1488         case 1:
1489             DECODE_PRINTF("OR\t");
1490             break;
1491         case 2:
1492             DECODE_PRINTF("ADC\t");
1493             break;
1494         case 3:
1495             DECODE_PRINTF("SBB\t");
1496             break;
1497         case 4:
1498             DECODE_PRINTF("AND\t");
1499             break;
1500         case 5:
1501             DECODE_PRINTF("SUB\t");
1502             break;
1503         case 6:
1504             DECODE_PRINTF("XOR\t");
1505             break;
1506         case 7:
1507             DECODE_PRINTF("CMP\t");
1508             break;
1509         }
1510     }
1511 #endif
1512     /* know operation, decode the mod byte to find the addressing
1513        mode. */
1514     if (mod < 3) {
1515         DECODE_PRINTF("BYTE PTR ");
1516         destoffset = decode_rmXX_address(mod, rl);
1517         destval = fetch_data_byte(destoffset);
1518         imm = fetch_byte_imm();
1519         DECODE_PRINTF2(",%x\n", imm);
1520         TRACE_AND_STEP();
1521         destval = (*genop_byte_operation[rh]) (destval, imm);
1522         if (rh != 7)
1523             store_data_byte(destoffset, destval);
1524     } else {                     /* register to register */
1525         destreg = DECODE_RM_BYTE_REGISTER(rl);
1526         imm = fetch_byte_imm();
1527         DECODE_PRINTF2(",%x\n", imm);
1528         TRACE_AND_STEP();
1529         destval = (*genop_byte_operation[rh]) (*destreg, imm);
1530         if (rh != 7)
1531             *destreg = destval;
1532     }
1533     DECODE_CLEAR_SEGOVR();
1534     END_OF_INSTR();
1535 }
1536
1537 /****************************************************************************
1538 REMARKS:
1539 Handles opcode 0x83
1540 ****************************************************************************/
1541 void x86emuOp_opc83_word_RM_IMM(u8 X86EMU_UNUSED(op1))
1542 {
1543     int mod, rl, rh;
1544     uint destoffset;
1545
1546     /*
1547      * Weirdo special case instruction format.  Part of the opcode
1548      * held below in "RH".  Doubly nested case would result, except
1549      * that the decoded instruction Similar to opcode 81, except that
1550      * the immediate byte is sign extended to a word length.
1551      */
1552     START_OF_INSTR();
1553     FETCH_DECODE_MODRM(mod, rh, rl);
1554 #ifdef DEBUG
1555     if (DEBUG_DECODE()) {
1556         /* XXX DECODE_PRINTF may be changed to something more
1557            general, so that it is important to leave the strings
1558            in the same format, even though the result is that the
1559            above test is done twice. */
1560        switch (rh) {
1561         case 0:
1562             DECODE_PRINTF("ADD\t");
1563             break;
1564         case 1:
1565             DECODE_PRINTF("OR\t");
1566             break;
1567         case 2:
1568             DECODE_PRINTF("ADC\t");
1569             break;
1570         case 3:
1571             DECODE_PRINTF("SBB\t");
1572             break;
1573         case 4:
1574             DECODE_PRINTF("AND\t");
1575             break;
1576         case 5:
1577             DECODE_PRINTF("SUB\t");
1578             break;
1579         case 6:
1580             DECODE_PRINTF("XOR\t");
1581             break;
1582         case 7:
1583             DECODE_PRINTF("CMP\t");
1584             break;
1585         }
1586     }
1587 #endif
1588     /* know operation, decode the mod byte to find the addressing
1589        mode. */
1590     if (mod < 3) {
1591         DECODE_PRINTF("DWORD PTR ");
1592         destoffset = decode_rmXX_address(mod,rl);
1593
1594         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1595             u32 destval,imm;
1596
1597             destval = fetch_data_long(destoffset);
1598             imm = (s8) fetch_byte_imm();
1599             DECODE_PRINTF2(",%x\n", imm);
1600             TRACE_AND_STEP();
1601             destval = (*genop_long_operation[rh]) (destval, imm);
1602             if (rh != 7)
1603                 store_data_long(destoffset, destval);
1604         } else {
1605             u16 destval,imm;
1606
1607             destval = fetch_data_word(destoffset);
1608             imm = (s8) fetch_byte_imm();
1609             DECODE_PRINTF2(",%x\n", imm);
1610             TRACE_AND_STEP();
1611             destval = (*genop_word_operation[rh]) (destval, imm);
1612             if (rh != 7)
1613                 store_data_word(destoffset, destval);
1614         }
1615     } else {                     /* register to register */
1616         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1617             u32 *destreg;
1618             u32 destval,imm;
1619
1620             destreg = DECODE_RM_LONG_REGISTER(rl);
1621             imm = (s8) fetch_byte_imm();
1622             DECODE_PRINTF2(",%x\n", imm);
1623             TRACE_AND_STEP();
1624             destval = (*genop_long_operation[rh]) (*destreg, imm);
1625             if (rh != 7)
1626                 *destreg = destval;
1627         } else {
1628             u16 *destreg;
1629             u16 destval,imm;
1630
1631             destreg = DECODE_RM_WORD_REGISTER(rl);
1632             imm = (s8) fetch_byte_imm();
1633             DECODE_PRINTF2(",%x\n", imm);
1634             TRACE_AND_STEP();
1635             destval = (*genop_word_operation[rh]) (*destreg, imm);
1636             if (rh != 7)
1637                 *destreg = destval;
1638         }
1639     }
1640     DECODE_CLEAR_SEGOVR();
1641     END_OF_INSTR();
1642 }
1643
1644 /****************************************************************************
1645 REMARKS:
1646 Handles opcode 0x84
1647 ****************************************************************************/
1648 void x86emuOp_test_byte_RM_R(u8 X86EMU_UNUSED(op1))
1649 {
1650     int mod, rl, rh;
1651     u8 *destreg, *srcreg;
1652     uint destoffset;
1653     u8 destval;
1654
1655     START_OF_INSTR();
1656     DECODE_PRINTF("TEST\t");
1657     FETCH_DECODE_MODRM(mod, rh, rl);
1658     if (mod < 3) {
1659         destoffset = decode_rmXX_address(mod, rl);
1660         DECODE_PRINTF(",");
1661         destval = fetch_data_byte(destoffset);
1662         srcreg = DECODE_RM_BYTE_REGISTER(rh);
1663         DECODE_PRINTF("\n");
1664         TRACE_AND_STEP();
1665         test_byte(destval, *srcreg);
1666     } else {                     /* register to register */
1667         destreg = DECODE_RM_BYTE_REGISTER(rl);
1668         DECODE_PRINTF(",");
1669         srcreg = DECODE_RM_BYTE_REGISTER(rh);
1670         DECODE_PRINTF("\n");
1671         TRACE_AND_STEP();
1672         test_byte(*destreg, *srcreg);
1673     }
1674     DECODE_CLEAR_SEGOVR();
1675     END_OF_INSTR();
1676 }
1677
1678 /****************************************************************************
1679 REMARKS:
1680 Handles opcode 0x85
1681 ****************************************************************************/
1682 void x86emuOp_test_word_RM_R(u8 X86EMU_UNUSED(op1))
1683 {
1684     int mod, rl, rh;
1685     uint destoffset;
1686
1687     START_OF_INSTR();
1688     DECODE_PRINTF("TEST\t");
1689     FETCH_DECODE_MODRM(mod, rh, rl);
1690     if (mod < 3) {
1691         destoffset = decode_rmXX_address(mod, rl);
1692         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1693             u32 destval;
1694             u32 *srcreg;
1695
1696             DECODE_PRINTF(",");
1697             destval = fetch_data_long(destoffset);
1698             srcreg = DECODE_RM_LONG_REGISTER(rh);
1699             DECODE_PRINTF("\n");
1700             TRACE_AND_STEP();
1701             test_long(destval, *srcreg);
1702         } else {
1703             u16 destval;
1704             u16 *srcreg;
1705
1706             DECODE_PRINTF(",");
1707             destval = fetch_data_word(destoffset);
1708             srcreg = DECODE_RM_WORD_REGISTER(rh);
1709             DECODE_PRINTF("\n");
1710             TRACE_AND_STEP();
1711             test_word(destval, *srcreg);
1712         }
1713     } else {                     /* register to register */
1714         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1715             u32 *destreg,*srcreg;
1716
1717             destreg = DECODE_RM_LONG_REGISTER(rl);
1718             DECODE_PRINTF(",");
1719             srcreg = DECODE_RM_LONG_REGISTER(rh);
1720             DECODE_PRINTF("\n");
1721             TRACE_AND_STEP();
1722             test_long(*destreg, *srcreg);
1723         } else {
1724             u16 *destreg,*srcreg;
1725
1726             destreg = DECODE_RM_WORD_REGISTER(rl);
1727             DECODE_PRINTF(",");
1728             srcreg = DECODE_RM_WORD_REGISTER(rh);
1729             DECODE_PRINTF("\n");
1730             TRACE_AND_STEP();
1731             test_word(*destreg, *srcreg);
1732         }
1733     }
1734     DECODE_CLEAR_SEGOVR();
1735     END_OF_INSTR();
1736 }
1737
1738 /****************************************************************************
1739 REMARKS:
1740 Handles opcode 0x86
1741 ****************************************************************************/
1742 void x86emuOp_xchg_byte_RM_R(u8 X86EMU_UNUSED(op1))
1743 {
1744     int mod, rl, rh;
1745     u8 *destreg, *srcreg;
1746     uint destoffset;
1747     u8 destval;
1748     u8 tmp;
1749
1750     START_OF_INSTR();
1751     DECODE_PRINTF("XCHG\t");
1752     FETCH_DECODE_MODRM(mod, rh, rl);
1753     if (mod < 3) {
1754         destoffset = decode_rmXX_address(mod, rl);
1755         DECODE_PRINTF(",");
1756         destval = fetch_data_byte(destoffset);
1757         srcreg = DECODE_RM_BYTE_REGISTER(rh);
1758         DECODE_PRINTF("\n");
1759         TRACE_AND_STEP();
1760         tmp = *srcreg;
1761         *srcreg = destval;
1762         destval = tmp;
1763         store_data_byte(destoffset, destval);
1764     } else {                     /* register to register */
1765         destreg = DECODE_RM_BYTE_REGISTER(rl);
1766         DECODE_PRINTF(",");
1767         srcreg = DECODE_RM_BYTE_REGISTER(rh);
1768         DECODE_PRINTF("\n");
1769         TRACE_AND_STEP();
1770         tmp = *srcreg;
1771         *srcreg = *destreg;
1772         *destreg = tmp;
1773     }
1774     DECODE_CLEAR_SEGOVR();
1775     END_OF_INSTR();
1776 }
1777
1778 /****************************************************************************
1779 REMARKS:
1780 Handles opcode 0x87
1781 ****************************************************************************/
1782 void x86emuOp_xchg_word_RM_R(u8 X86EMU_UNUSED(op1))
1783 {
1784     int mod, rl, rh;
1785     uint destoffset;
1786
1787     START_OF_INSTR();
1788     DECODE_PRINTF("XCHG\t");
1789     FETCH_DECODE_MODRM(mod, rh, rl);
1790     if (mod < 3) {
1791         destoffset = decode_rmXX_address(mod, rl);
1792         DECODE_PRINTF(",");
1793         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1794             u32 *srcreg;
1795             u32 destval,tmp;
1796
1797             destval = fetch_data_long(destoffset);
1798             srcreg = DECODE_RM_LONG_REGISTER(rh);
1799             DECODE_PRINTF("\n");
1800             TRACE_AND_STEP();
1801             tmp = *srcreg;
1802             *srcreg = destval;
1803             destval = tmp;
1804             store_data_long(destoffset, destval);
1805         } else {
1806             u16 *srcreg;
1807             u16 destval,tmp;
1808
1809             destval = fetch_data_word(destoffset);
1810             srcreg = DECODE_RM_WORD_REGISTER(rh);
1811             DECODE_PRINTF("\n");
1812             TRACE_AND_STEP();
1813             tmp = *srcreg;
1814             *srcreg = destval;
1815             destval = tmp;
1816             store_data_word(destoffset, destval);
1817         }
1818     } else {                     /* register to register */
1819         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1820             u32 *destreg,*srcreg;
1821             u32 tmp;
1822
1823             destreg = DECODE_RM_LONG_REGISTER(rl);
1824             DECODE_PRINTF(",");
1825             srcreg = DECODE_RM_LONG_REGISTER(rh);
1826             DECODE_PRINTF("\n");
1827             TRACE_AND_STEP();
1828             tmp = *srcreg;
1829             *srcreg = *destreg;
1830             *destreg = tmp;
1831         } else {
1832             u16 *destreg,*srcreg;
1833             u16 tmp;
1834
1835             destreg = DECODE_RM_WORD_REGISTER(rl);
1836             DECODE_PRINTF(",");
1837             srcreg = DECODE_RM_WORD_REGISTER(rh);
1838             DECODE_PRINTF("\n");
1839             TRACE_AND_STEP();
1840             tmp = *srcreg;
1841             *srcreg = *destreg;
1842             *destreg = tmp;
1843         }
1844     }
1845     DECODE_CLEAR_SEGOVR();
1846     END_OF_INSTR();
1847 }
1848
1849 /****************************************************************************
1850 REMARKS:
1851 Handles opcode 0x88
1852 ****************************************************************************/
1853 void x86emuOp_mov_byte_RM_R(u8 X86EMU_UNUSED(op1))
1854 {
1855     int mod, rl, rh;
1856     u8 *destreg, *srcreg;
1857     uint destoffset;
1858
1859     START_OF_INSTR();
1860     DECODE_PRINTF("MOV\t");
1861     FETCH_DECODE_MODRM(mod, rh, rl);
1862     if (mod < 3) {
1863         destoffset = decode_rmXX_address(mod, rl);
1864         DECODE_PRINTF(",");
1865         srcreg = DECODE_RM_BYTE_REGISTER(rh);
1866         DECODE_PRINTF("\n");
1867         TRACE_AND_STEP();
1868         store_data_byte(destoffset, *srcreg);
1869     } else {                     /* register to register */
1870         destreg = DECODE_RM_BYTE_REGISTER(rl);
1871         DECODE_PRINTF(",");
1872         srcreg = DECODE_RM_BYTE_REGISTER(rh);
1873         DECODE_PRINTF("\n");
1874         TRACE_AND_STEP();
1875         *destreg = *srcreg;
1876     }
1877     DECODE_CLEAR_SEGOVR();
1878     END_OF_INSTR();
1879 }
1880
1881 /****************************************************************************
1882 REMARKS:
1883 Handles opcode 0x89
1884 ****************************************************************************/
1885 void x86emuOp_mov_word_RM_R(u8 X86EMU_UNUSED(op1))
1886 {
1887     int mod, rl, rh;
1888     uint destoffset;
1889
1890     START_OF_INSTR();
1891     DECODE_PRINTF("MOV\t");
1892     FETCH_DECODE_MODRM(mod, rh, rl);
1893     if (mod < 3) {
1894         destoffset = decode_rmXX_address(mod, rl);
1895         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1896             u32 *srcreg;
1897
1898             DECODE_PRINTF(",");
1899             srcreg = DECODE_RM_LONG_REGISTER(rh);
1900             DECODE_PRINTF("\n");
1901             TRACE_AND_STEP();
1902             store_data_long(destoffset, *srcreg);
1903         } else {
1904             u16 *srcreg;
1905
1906             DECODE_PRINTF(",");
1907             srcreg = DECODE_RM_WORD_REGISTER(rh);
1908             DECODE_PRINTF("\n");
1909             TRACE_AND_STEP();
1910             store_data_word(destoffset, *srcreg);
1911         }
1912     } else {                     /* register to register */
1913         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1914             u32 *destreg,*srcreg;
1915
1916             destreg = DECODE_RM_LONG_REGISTER(rl);
1917             DECODE_PRINTF(",");
1918             srcreg = DECODE_RM_LONG_REGISTER(rh);
1919             DECODE_PRINTF("\n");
1920             TRACE_AND_STEP();
1921             *destreg = *srcreg;
1922         } else {
1923             u16 *destreg,*srcreg;
1924
1925             destreg = DECODE_RM_WORD_REGISTER(rl);
1926             DECODE_PRINTF(",");
1927             srcreg = DECODE_RM_WORD_REGISTER(rh);
1928             DECODE_PRINTF("\n");
1929             TRACE_AND_STEP();
1930             *destreg = *srcreg;
1931         }
1932     }
1933     DECODE_CLEAR_SEGOVR();
1934     END_OF_INSTR();
1935 }
1936
1937 /****************************************************************************
1938 REMARKS:
1939 Handles opcode 0x8a
1940 ****************************************************************************/
1941 void x86emuOp_mov_byte_R_RM(u8 X86EMU_UNUSED(op1))
1942 {
1943     int mod, rl, rh;
1944     u8 *destreg, *srcreg;
1945     uint srcoffset;
1946     u8 srcval;
1947
1948     START_OF_INSTR();
1949     DECODE_PRINTF("MOV\t");
1950     FETCH_DECODE_MODRM(mod, rh, rl);
1951     if (mod < 3) {
1952         destreg = DECODE_RM_BYTE_REGISTER(rh);
1953         DECODE_PRINTF(",");
1954         srcoffset = decode_rmXX_address(mod, rl);
1955         srcval = fetch_data_byte(srcoffset);
1956         DECODE_PRINTF("\n");
1957         TRACE_AND_STEP();
1958         *destreg = srcval;
1959     } else {                     /* register to register */
1960         destreg = DECODE_RM_BYTE_REGISTER(rh);
1961         DECODE_PRINTF(",");
1962         srcreg = DECODE_RM_BYTE_REGISTER(rl);
1963         DECODE_PRINTF("\n");
1964         TRACE_AND_STEP();
1965         *destreg = *srcreg;
1966     }
1967     DECODE_CLEAR_SEGOVR();
1968     END_OF_INSTR();
1969 }
1970
1971 /****************************************************************************
1972 REMARKS:
1973 Handles opcode 0x8b
1974 ****************************************************************************/
1975 void x86emuOp_mov_word_R_RM(u8 X86EMU_UNUSED(op1))
1976 {
1977     int mod, rl, rh;
1978     uint srcoffset;
1979
1980     START_OF_INSTR();
1981     DECODE_PRINTF("MOV\t");
1982     FETCH_DECODE_MODRM(mod, rh, rl);
1983     if (mod < 3) {
1984         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1985             u32 *destreg;
1986             u32 srcval;
1987
1988             destreg = DECODE_RM_LONG_REGISTER(rh);
1989             DECODE_PRINTF(",");
1990             srcoffset = decode_rmXX_address(mod, rl);
1991             srcval = fetch_data_long(srcoffset);
1992             DECODE_PRINTF("\n");
1993             TRACE_AND_STEP();
1994             *destreg = srcval;
1995         } else {
1996             u16 *destreg;
1997             u16 srcval;
1998
1999             destreg = DECODE_RM_WORD_REGISTER(rh);
2000             DECODE_PRINTF(",");
2001             srcoffset = decode_rmXX_address(mod, rl);
2002             srcval = fetch_data_word(srcoffset);
2003             DECODE_PRINTF("\n");
2004             TRACE_AND_STEP();
2005             *destreg = srcval;
2006         }
2007     } else {                     /* register to register */
2008         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2009             u32 *destreg, *srcreg;
2010
2011             destreg = DECODE_RM_LONG_REGISTER(rh);
2012             DECODE_PRINTF(",");
2013             srcreg = DECODE_RM_LONG_REGISTER(rl);
2014             DECODE_PRINTF("\n");
2015             TRACE_AND_STEP();
2016             *destreg = *srcreg;
2017         } else {
2018             u16 *destreg, *srcreg;
2019
2020             destreg = DECODE_RM_WORD_REGISTER(rh);
2021             DECODE_PRINTF(",");
2022             srcreg = DECODE_RM_WORD_REGISTER(rl);
2023             DECODE_PRINTF("\n");
2024             TRACE_AND_STEP();
2025             *destreg = *srcreg;
2026         }
2027     }
2028     DECODE_CLEAR_SEGOVR();
2029     END_OF_INSTR();
2030 }
2031
2032 /****************************************************************************
2033 REMARKS:
2034 Handles opcode 0x8c
2035 ****************************************************************************/
2036 void x86emuOp_mov_word_RM_SR(u8 X86EMU_UNUSED(op1))
2037 {
2038     int mod, rl, rh;
2039     u16 *destreg, *srcreg;
2040     uint destoffset;
2041     u16 destval;
2042
2043     START_OF_INSTR();
2044     DECODE_PRINTF("MOV\t");
2045     FETCH_DECODE_MODRM(mod, rh, rl);
2046     if (mod < 3) {
2047         destoffset = decode_rmXX_address(mod, rl);
2048         DECODE_PRINTF(",");
2049         srcreg = decode_rm_seg_register(rh);
2050         DECODE_PRINTF("\n");
2051         TRACE_AND_STEP();
2052         destval = *srcreg;
2053         store_data_word(destoffset, destval);
2054     } else {                     /* register to register */
2055         destreg = DECODE_RM_WORD_REGISTER(rl);
2056         DECODE_PRINTF(",");
2057         srcreg = decode_rm_seg_register(rh);
2058         DECODE_PRINTF("\n");
2059         TRACE_AND_STEP();
2060         *destreg = *srcreg;
2061     }
2062     DECODE_CLEAR_SEGOVR();
2063     END_OF_INSTR();
2064 }
2065
2066 /****************************************************************************
2067 REMARKS:
2068 Handles opcode 0x8d
2069 ****************************************************************************/
2070 void x86emuOp_lea_word_R_M(u8 X86EMU_UNUSED(op1))
2071 {
2072     int mod, rl, rh;
2073     u16 *srcreg;
2074     uint destoffset;
2075
2076 /*
2077  * TODO: Need to handle address size prefix!
2078  *
2079  * lea  eax,[eax+ebx*2] ??
2080  */
2081
2082     START_OF_INSTR();
2083     DECODE_PRINTF("LEA\t");
2084     FETCH_DECODE_MODRM(mod, rh, rl);
2085     if (mod < 3) {
2086         srcreg = DECODE_RM_WORD_REGISTER(rh);
2087         DECODE_PRINTF(",");
2088         destoffset = decode_rmXX_address(mod, rl);
2089         DECODE_PRINTF("\n");
2090         TRACE_AND_STEP();
2091         *srcreg = (u16)destoffset;
2092         }
2093     /* } else { undefined.  Do nothing. } */
2094     DECODE_CLEAR_SEGOVR();
2095     END_OF_INSTR();
2096 }
2097
2098 /****************************************************************************
2099 REMARKS:
2100 Handles opcode 0x8e
2101 ****************************************************************************/
2102 void x86emuOp_mov_word_SR_RM(u8 X86EMU_UNUSED(op1))
2103 {
2104     int mod, rl, rh;
2105     u16 *destreg, *srcreg;
2106     uint srcoffset;
2107     u16 srcval;
2108
2109     START_OF_INSTR();
2110     DECODE_PRINTF("MOV\t");
2111     FETCH_DECODE_MODRM(mod, rh, rl);
2112     if (mod < 3) {
2113         destreg = decode_rm_seg_register(rh);
2114         DECODE_PRINTF(",");
2115         srcoffset = decode_rmXX_address(mod, rl);
2116         srcval = fetch_data_word(srcoffset);
2117         DECODE_PRINTF("\n");
2118         TRACE_AND_STEP();
2119         *destreg = srcval;
2120     } else {                     /* register to register */
2121         destreg = decode_rm_seg_register(rh);
2122         DECODE_PRINTF(",");
2123         srcreg = DECODE_RM_WORD_REGISTER(rl);
2124         DECODE_PRINTF("\n");
2125         TRACE_AND_STEP();
2126         *destreg = *srcreg;
2127     }
2128     /*
2129      * Clean up, and reset all the R_xSP pointers to the correct
2130      * locations.  This is about 3x too much overhead (doing all the
2131      * segreg ptrs when only one is needed, but this instruction
2132      * *cannot* be that common, and this isn't too much work anyway.
2133      */
2134     DECODE_CLEAR_SEGOVR();
2135     END_OF_INSTR();
2136 }
2137
2138 /****************************************************************************
2139 REMARKS:
2140 Handles opcode 0x8f
2141 ****************************************************************************/
2142 void x86emuOp_pop_RM(u8 X86EMU_UNUSED(op1))
2143 {
2144     int mod, rl, rh;
2145     uint destoffset;
2146
2147     START_OF_INSTR();
2148     DECODE_PRINTF("POP\t");
2149     FETCH_DECODE_MODRM(mod, rh, rl);
2150     if (rh != 0) {
2151         DECODE_PRINTF("ILLEGAL DECODE OF OPCODE 8F\n");
2152         HALT_SYS();
2153     }
2154     if (mod < 3) {
2155         destoffset = decode_rmXX_address(mod, rl);
2156         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2157             u32 destval;
2158
2159             DECODE_PRINTF("\n");
2160             TRACE_AND_STEP();
2161             destval = pop_long();
2162             store_data_long(destoffset, destval);
2163         } else {
2164             u16 destval;
2165
2166             DECODE_PRINTF("\n");
2167             TRACE_AND_STEP();
2168             destval = pop_word();
2169             store_data_word(destoffset, destval);
2170         }
2171     } else {                    /* register to register */
2172         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2173             u32 *destreg;
2174
2175             destreg = DECODE_RM_LONG_REGISTER(rl);
2176             DECODE_PRINTF("\n");
2177             TRACE_AND_STEP();
2178             *destreg = pop_long();
2179         } else {
2180             u16 *destreg;
2181
2182             destreg = DECODE_RM_WORD_REGISTER(rl);
2183             DECODE_PRINTF("\n");
2184             TRACE_AND_STEP();
2185             *destreg = pop_word();
2186         }
2187     }
2188     DECODE_CLEAR_SEGOVR();
2189     END_OF_INSTR();
2190 }
2191
2192 /****************************************************************************
2193 REMARKS:
2194 Handles opcode 0x90
2195 ****************************************************************************/
2196 void x86emuOp_nop(u8 X86EMU_UNUSED(op1))
2197 {
2198     START_OF_INSTR();
2199     DECODE_PRINTF("NOP\n");
2200     TRACE_AND_STEP();
2201     DECODE_CLEAR_SEGOVR();
2202     END_OF_INSTR();
2203 }
2204
2205 /****************************************************************************
2206 REMARKS:
2207 Handles opcode 0x91-0x97
2208 ****************************************************************************/
2209 void x86emuOp_xchg_word_AX_register(u8 X86EMU_UNUSED(op1))
2210 {
2211     u32 tmp;
2212
2213     op1 &= 0x7;
2214
2215     START_OF_INSTR();
2216
2217     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2218         u32 *reg32;
2219         DECODE_PRINTF("XCHG\tEAX,");
2220         reg32 = DECODE_RM_LONG_REGISTER(op1);
2221         DECODE_PRINTF("\n");
2222         TRACE_AND_STEP();
2223         tmp = M.x86.R_EAX;
2224         M.x86.R_EAX = *reg32;
2225         *reg32 = tmp;
2226     } else {
2227         u16 *reg16;
2228         DECODE_PRINTF("XCHG\tAX,");
2229         reg16 = DECODE_RM_WORD_REGISTER(op1);
2230         DECODE_PRINTF("\n");
2231         TRACE_AND_STEP();
2232         tmp = M.x86.R_AX;
2233         M.x86.R_EAX = *reg16;
2234         *reg16 = (u16)tmp;
2235     }
2236     DECODE_CLEAR_SEGOVR();
2237     END_OF_INSTR();
2238 }
2239
2240 /****************************************************************************
2241 REMARKS:
2242 Handles opcode 0x98
2243 ****************************************************************************/
2244 void x86emuOp_cbw(u8 X86EMU_UNUSED(op1))
2245 {
2246     START_OF_INSTR();
2247     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2248         DECODE_PRINTF("CWDE\n");
2249     } else {
2250         DECODE_PRINTF("CBW\n");
2251     }
2252     TRACE_AND_STEP();
2253     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2254         if (M.x86.R_AX & 0x8000) {
2255             M.x86.R_EAX |= 0xffff0000;
2256         } else {
2257             M.x86.R_EAX &= 0x0000ffff;
2258         }
2259     } else {
2260         if (M.x86.R_AL & 0x80) {
2261             M.x86.R_AH = 0xff;
2262         } else {
2263             M.x86.R_AH = 0x0;
2264         }
2265     }
2266     DECODE_CLEAR_SEGOVR();
2267     END_OF_INSTR();
2268 }
2269
2270 /****************************************************************************
2271 REMARKS:
2272 Handles opcode 0x99
2273 ****************************************************************************/
2274 void x86emuOp_cwd(u8 X86EMU_UNUSED(op1))
2275 {
2276     START_OF_INSTR();
2277     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2278         DECODE_PRINTF("CDQ\n");
2279     } else {
2280         DECODE_PRINTF("CWD\n");
2281     }
2282     DECODE_PRINTF("CWD\n");
2283     TRACE_AND_STEP();
2284     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2285         if (M.x86.R_EAX & 0x80000000) {
2286             M.x86.R_EDX = 0xffffffff;
2287         } else {
2288             M.x86.R_EDX = 0x0;
2289         }
2290     } else {
2291         if (M.x86.R_AX & 0x8000) {
2292             M.x86.R_DX = 0xffff;
2293         } else {
2294             M.x86.R_DX = 0x0;
2295         }
2296     }
2297     DECODE_CLEAR_SEGOVR();
2298     END_OF_INSTR();
2299 }
2300
2301 /****************************************************************************
2302 REMARKS:
2303 Handles opcode 0x9a
2304 ****************************************************************************/
2305 void x86emuOp_call_far_IMM(u8 X86EMU_UNUSED(op1))
2306 {
2307     u16 farseg, faroff;
2308
2309     START_OF_INSTR();
2310         DECODE_PRINTF("CALL\t");
2311         faroff = fetch_word_imm();
2312         farseg = fetch_word_imm();
2313         DECODE_PRINTF2("%04x:", farseg);
2314         DECODE_PRINTF2("%04x\n", faroff);
2315         CALL_TRACE(M.x86.saved_cs, M.x86.saved_ip, farseg, faroff, "FAR ");
2316
2317     /* XXX
2318      *
2319      * Hooked interrupt vectors calling into our "BIOS" will cause
2320      * problems unless all intersegment stuff is checked for BIOS
2321      * access.  Check needed here.  For moment, let it alone.
2322      */
2323     TRACE_AND_STEP();
2324     push_word(M.x86.R_CS);
2325     M.x86.R_CS = farseg;
2326     push_word(M.x86.R_IP);
2327     M.x86.R_IP = faroff;
2328     DECODE_CLEAR_SEGOVR();
2329     END_OF_INSTR();
2330 }
2331
2332 /****************************************************************************
2333 REMARKS:
2334 Handles opcode 0x9b
2335 ****************************************************************************/
2336 void x86emuOp_wait(u8 X86EMU_UNUSED(op1))
2337 {
2338     START_OF_INSTR();
2339     DECODE_PRINTF("WAIT");
2340     TRACE_AND_STEP();
2341     /* NADA.  */
2342     DECODE_CLEAR_SEGOVR();
2343     END_OF_INSTR();
2344 }
2345
2346 /****************************************************************************
2347 REMARKS:
2348 Handles opcode 0x9c
2349 ****************************************************************************/
2350 void x86emuOp_pushf_word(u8 X86EMU_UNUSED(op1))
2351 {
2352     u32 flags;
2353
2354     START_OF_INSTR();
2355     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2356         DECODE_PRINTF("PUSHFD\n");
2357     } else {
2358         DECODE_PRINTF("PUSHF\n");
2359     }
2360     TRACE_AND_STEP();
2361
2362     /* clear out *all* bits not representing flags, and turn on real bits */
2363     flags = (M.x86.R_EFLG & F_MSK) | F_ALWAYS_ON;
2364     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2365         push_long(flags);
2366     } else {
2367         push_word((u16)flags);
2368     }
2369     DECODE_CLEAR_SEGOVR();
2370     END_OF_INSTR();
2371 }
2372
2373 /****************************************************************************
2374 REMARKS:
2375 Handles opcode 0x9d
2376 ****************************************************************************/
2377 void x86emuOp_popf_word(u8 X86EMU_UNUSED(op1))
2378 {
2379     START_OF_INSTR();
2380     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2381         DECODE_PRINTF("POPFD\n");
2382     } else {
2383         DECODE_PRINTF("POPF\n");
2384     }
2385     TRACE_AND_STEP();
2386     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2387         M.x86.R_EFLG = pop_long();
2388     } else {
2389         M.x86.R_FLG = pop_word();
2390     }
2391     DECODE_CLEAR_SEGOVR();
2392     END_OF_INSTR();
2393 }
2394
2395 /****************************************************************************
2396 REMARKS:
2397 Handles opcode 0x9e
2398 ****************************************************************************/
2399 void x86emuOp_sahf(u8 X86EMU_UNUSED(op1))
2400 {
2401     START_OF_INSTR();
2402     DECODE_PRINTF("SAHF\n");
2403     TRACE_AND_STEP();
2404     /* clear the lower bits of the flag register */
2405     M.x86.R_FLG &= 0xffffff00;
2406     /* or in the AH register into the flags register */
2407     M.x86.R_FLG |= M.x86.R_AH;
2408     DECODE_CLEAR_SEGOVR();
2409     END_OF_INSTR();
2410 }
2411
2412 /****************************************************************************
2413 REMARKS:
2414 Handles opcode 0x9f
2415 ****************************************************************************/
2416 void x86emuOp_lahf(u8 X86EMU_UNUSED(op1))
2417 {
2418     START_OF_INSTR();
2419     DECODE_PRINTF("LAHF\n");
2420     TRACE_AND_STEP();
2421         M.x86.R_AH = (u8)(M.x86.R_FLG & 0xff);
2422     /*undocumented TC++ behavior??? Nope.  It's documented, but
2423        you have too look real hard to notice it. */
2424     M.x86.R_AH |= 0x2;
2425     DECODE_CLEAR_SEGOVR();
2426     END_OF_INSTR();
2427 }
2428
2429 /****************************************************************************
2430 REMARKS:
2431 Handles opcode 0xa0
2432 ****************************************************************************/
2433 void x86emuOp_mov_AL_M_IMM(u8 X86EMU_UNUSED(op1))
2434 {
2435     u16 offset;
2436
2437     START_OF_INSTR();
2438     DECODE_PRINTF("MOV\tAL,");
2439     offset = fetch_word_imm();
2440     DECODE_PRINTF2("[%04x]\n", offset);
2441     TRACE_AND_STEP();
2442     M.x86.R_AL = fetch_data_byte(offset);
2443     DECODE_CLEAR_SEGOVR();
2444     END_OF_INSTR();
2445 }
2446
2447 /****************************************************************************
2448 REMARKS:
2449 Handles opcode 0xa1
2450 ****************************************************************************/
2451 void x86emuOp_mov_AX_M_IMM(u8 X86EMU_UNUSED(op1))
2452 {
2453     u16 offset;
2454
2455     START_OF_INSTR();
2456     offset = fetch_word_imm();
2457     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2458         DECODE_PRINTF2("MOV\tEAX,[%04x]\n", offset);
2459     } else {
2460         DECODE_PRINTF2("MOV\tAX,[%04x]\n", offset);
2461     }
2462     TRACE_AND_STEP();
2463     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2464         M.x86.R_EAX = fetch_data_long(offset);
2465     } else {
2466         M.x86.R_AX = fetch_data_word(offset);
2467     }
2468     DECODE_CLEAR_SEGOVR();
2469     END_OF_INSTR();
2470 }
2471
2472 /****************************************************************************
2473 REMARKS:
2474 Handles opcode 0xa2
2475 ****************************************************************************/
2476 void x86emuOp_mov_M_AL_IMM(u8 X86EMU_UNUSED(op1))
2477 {
2478     u16 offset;
2479
2480     START_OF_INSTR();
2481     DECODE_PRINTF("MOV\t");
2482     offset = fetch_word_imm();
2483     DECODE_PRINTF2("[%04x],AL\n", offset);
2484     TRACE_AND_STEP();
2485     store_data_byte(offset, M.x86.R_AL);
2486     DECODE_CLEAR_SEGOVR();
2487     END_OF_INSTR();
2488 }
2489
2490 /****************************************************************************
2491 REMARKS:
2492 Handles opcode 0xa3
2493 ****************************************************************************/
2494 void x86emuOp_mov_M_AX_IMM(u8 X86EMU_UNUSED(op1))
2495 {
2496     u16 offset;
2497
2498     START_OF_INSTR();
2499     offset = fetch_word_imm();
2500     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2501         DECODE_PRINTF2("MOV\t[%04x],EAX\n", offset);
2502     } else {
2503         DECODE_PRINTF2("MOV\t[%04x],AX\n", offset);
2504     }
2505     TRACE_AND_STEP();
2506     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2507         store_data_long(offset, M.x86.R_EAX);
2508     } else {
2509         store_data_word(offset, M.x86.R_AX);
2510     }
2511     DECODE_CLEAR_SEGOVR();
2512     END_OF_INSTR();
2513 }
2514
2515 /****************************************************************************
2516 REMARKS:
2517 Handles opcode 0xa4
2518 ****************************************************************************/
2519 void x86emuOp_movs_byte(u8 X86EMU_UNUSED(op1))
2520 {
2521     u8  val;
2522     u32 count;
2523     int inc;
2524
2525     START_OF_INSTR();
2526     DECODE_PRINTF("MOVS\tBYTE\n");
2527     if (ACCESS_FLAG(F_DF))   /* down */
2528         inc = -1;
2529     else
2530         inc = 1;
2531     TRACE_AND_STEP();
2532     count = 1;
2533     if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
2534         /* dont care whether REPE or REPNE */
2535         /* move them until CX is ZERO. */
2536         count = M.x86.R_CX;
2537         M.x86.R_CX = 0;
2538         M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
2539     }
2540     while (count--) {
2541         val = fetch_data_byte(M.x86.R_SI);
2542         store_data_byte_abs(M.x86.R_ES, M.x86.R_DI, val);
2543         M.x86.R_SI += inc;
2544         M.x86.R_DI += inc;
2545     }
2546     DECODE_CLEAR_SEGOVR();
2547     END_OF_INSTR();
2548 }
2549
2550 /****************************************************************************
2551 REMARKS:
2552 Handles opcode 0xa5
2553 ****************************************************************************/
2554 void x86emuOp_movs_word(u8 X86EMU_UNUSED(op1))
2555 {
2556     u32 val;
2557     int inc;
2558     u32 count;
2559
2560     START_OF_INSTR();
2561     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2562         DECODE_PRINTF("MOVS\tDWORD\n");
2563         if (ACCESS_FLAG(F_DF))      /* down */
2564             inc = -4;
2565         else
2566             inc = 4;
2567     } else {
2568         DECODE_PRINTF("MOVS\tWORD\n");
2569         if (ACCESS_FLAG(F_DF))      /* down */
2570             inc = -2;
2571         else
2572             inc = 2;
2573     }
2574     TRACE_AND_STEP();
2575     count = 1;
2576     if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
2577         /* dont care whether REPE or REPNE */
2578         /* move them until CX is ZERO. */
2579         count = M.x86.R_CX;
2580         M.x86.R_CX = 0;
2581         M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
2582     }
2583     while (count--) {
2584         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2585             val = fetch_data_long(M.x86.R_SI);
2586             store_data_long_abs(M.x86.R_ES, M.x86.R_DI, val);
2587         } else {
2588             val = fetch_data_word(M.x86.R_SI);
2589             store_data_word_abs(M.x86.R_ES, M.x86.R_DI, (u16)val);
2590         }
2591         M.x86.R_SI += inc;
2592         M.x86.R_DI += inc;
2593     }
2594     DECODE_CLEAR_SEGOVR();
2595     END_OF_INSTR();
2596 }
2597
2598 /****************************************************************************
2599 REMARKS:
2600 Handles opcode 0xa6
2601 ****************************************************************************/
2602 void x86emuOp_cmps_byte(u8 X86EMU_UNUSED(op1))
2603 {
2604     s8 val1, val2;
2605     int inc;
2606
2607     START_OF_INSTR();
2608     DECODE_PRINTF("CMPS\tBYTE\n");
2609     TRACE_AND_STEP();
2610     if (ACCESS_FLAG(F_DF))   /* down */
2611         inc = -1;
2612     else
2613         inc = 1;
2614
2615     if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
2616         /* REPE  */
2617         /* move them until CX is ZERO. */
2618         while (M.x86.R_CX != 0) {
2619             val1 = fetch_data_byte(M.x86.R_SI);
2620             val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
2621                      cmp_byte(val1, val2);
2622             M.x86.R_CX -= 1;
2623             M.x86.R_SI += inc;
2624             M.x86.R_DI += inc;
2625             if ( (M.x86.mode & SYSMODE_PREFIX_REPE) && (ACCESS_FLAG(F_ZF) == 0) ) break;
2626             if ( (M.x86.mode & SYSMODE_PREFIX_REPNE) && ACCESS_FLAG(F_ZF) ) break;
2627         }
2628         M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
2629     } else {
2630         val1 = fetch_data_byte(M.x86.R_SI);
2631         val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
2632         cmp_byte(val1, val2);
2633         M.x86.R_SI += inc;
2634         M.x86.R_DI += inc;
2635     }
2636     DECODE_CLEAR_SEGOVR();
2637     END_OF_INSTR();
2638 }
2639
2640 /****************************************************************************
2641 REMARKS:
2642 Handles opcode 0xa7
2643 ****************************************************************************/
2644 void x86emuOp_cmps_word(u8 X86EMU_UNUSED(op1))
2645 {
2646     u32 val1,val2;
2647     int inc;
2648
2649     START_OF_INSTR();
2650     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2651         DECODE_PRINTF("CMPS\tDWORD\n");
2652         inc = 4;
2653     } else {
2654         DECODE_PRINTF("CMPS\tWORD\n");
2655         inc = 2;
2656     }
2657     if (ACCESS_FLAG(F_DF))   /* down */
2658         inc = -inc;
2659
2660     TRACE_AND_STEP();
2661     if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
2662         /* REPE  */
2663         /* move them until CX is ZERO. */
2664         while (M.x86.R_CX != 0) {
2665             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2666                 val1 = fetch_data_long(M.x86.R_SI);
2667                 val2 = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
2668                 cmp_long(val1, val2);
2669             } else {
2670                 val1 = fetch_data_word(M.x86.R_SI);
2671                 val2 = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
2672                 cmp_word((u16)val1, (u16)val2);
2673             }
2674             M.x86.R_CX -= 1;
2675             M.x86.R_SI += inc;
2676             M.x86.R_DI += inc;
2677             if ( (M.x86.mode & SYSMODE_PREFIX_REPE) && ACCESS_FLAG(F_ZF) == 0 ) break;
2678             if ( (M.x86.mode & SYSMODE_PREFIX_REPNE) && ACCESS_FLAG(F_ZF) ) break;
2679         }
2680         M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
2681     } else {
2682         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2683             val1 = fetch_data_long(M.x86.R_SI);
2684             val2 = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
2685             cmp_long(val1, val2);
2686         } else {
2687             val1 = fetch_data_word(M.x86.R_SI);
2688             val2 = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
2689             cmp_word((u16)val1, (u16)val2);
2690         }
2691         M.x86.R_SI += inc;
2692         M.x86.R_DI += inc;
2693     }
2694     DECODE_CLEAR_SEGOVR();
2695     END_OF_INSTR();
2696 }
2697
2698 /****************************************************************************
2699 REMARKS:
2700 Handles opcode 0xa8
2701 ****************************************************************************/
2702 void x86emuOp_test_AL_IMM(u8 X86EMU_UNUSED(op1))
2703 {
2704     int imm;
2705
2706     START_OF_INSTR();
2707     DECODE_PRINTF("TEST\tAL,");
2708     imm = fetch_byte_imm();
2709     DECODE_PRINTF2("%04x\n", imm);
2710     TRACE_AND_STEP();
2711         test_byte(M.x86.R_AL, (u8)imm);
2712     DECODE_CLEAR_SEGOVR();
2713     END_OF_INSTR();
2714 }
2715
2716 /****************************************************************************
2717 REMARKS:
2718 Handles opcode 0xa9
2719 ****************************************************************************/
2720 void x86emuOp_test_AX_IMM(u8 X86EMU_UNUSED(op1))
2721 {
2722     u32 srcval;
2723
2724     START_OF_INSTR();
2725     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2726         DECODE_PRINTF("TEST\tEAX,");
2727         srcval = fetch_long_imm();
2728     } else {
2729         DECODE_PRINTF("TEST\tAX,");
2730         srcval = fetch_word_imm();
2731     }
2732     DECODE_PRINTF2("%x\n", srcval);
2733     TRACE_AND_STEP();
2734     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2735         test_long(M.x86.R_EAX, srcval);
2736     } else {
2737         test_word(M.x86.R_AX, (u16)srcval);
2738     }
2739     DECODE_CLEAR_SEGOVR();
2740     END_OF_INSTR();
2741 }
2742
2743 /****************************************************************************
2744 REMARKS:
2745 Handles opcode 0xaa
2746 ****************************************************************************/
2747 void x86emuOp_stos_byte(u8 X86EMU_UNUSED(op1))
2748 {
2749     int inc;
2750
2751     START_OF_INSTR();
2752     DECODE_PRINTF("STOS\tBYTE\n");
2753     if (ACCESS_FLAG(F_DF))   /* down */
2754         inc = -1;
2755     else
2756         inc = 1;
2757     TRACE_AND_STEP();
2758     if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
2759         /* dont care whether REPE or REPNE */
2760         /* move them until CX is ZERO. */
2761         while (M.x86.R_CX != 0) {
2762             store_data_byte_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_AL);
2763             M.x86.R_CX -= 1;
2764             M.x86.R_DI += inc;
2765         }
2766         M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
2767     } else {
2768         store_data_byte_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_AL);
2769         M.x86.R_DI += inc;
2770     }
2771     DECODE_CLEAR_SEGOVR();
2772     END_OF_INSTR();
2773 }
2774
2775 /****************************************************************************
2776 REMARKS:
2777 Handles opcode 0xab
2778 ****************************************************************************/
2779 void x86emuOp_stos_word(u8 X86EMU_UNUSED(op1))
2780 {
2781     int inc;
2782     u32 count;
2783
2784     START_OF_INSTR();
2785     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2786         DECODE_PRINTF("STOS\tDWORD\n");
2787         if (ACCESS_FLAG(F_DF))   /* down */
2788             inc = -4;
2789         else
2790             inc = 4;
2791     } else {
2792         DECODE_PRINTF("STOS\tWORD\n");
2793         if (ACCESS_FLAG(F_DF))   /* down */
2794             inc = -2;
2795         else
2796             inc = 2;
2797     }
2798     TRACE_AND_STEP();
2799     count = 1;
2800     if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
2801         /* dont care whether REPE or REPNE */
2802         /* move them until CX is ZERO. */
2803         count = M.x86.R_CX;
2804         M.x86.R_CX = 0;
2805         M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
2806     }
2807     while (count--) {
2808         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2809             store_data_long_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_EAX);
2810         } else {
2811             store_data_word_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_AX);
2812         }
2813         M.x86.R_DI += inc;
2814     }
2815     DECODE_CLEAR_SEGOVR();
2816     END_OF_INSTR();
2817 }
2818
2819 /****************************************************************************
2820 REMARKS:
2821 Handles opcode 0xac
2822 ****************************************************************************/
2823 void x86emuOp_lods_byte(u8 X86EMU_UNUSED(op1))
2824 {
2825     int inc;
2826
2827     START_OF_INSTR();
2828     DECODE_PRINTF("LODS\tBYTE\n");
2829     TRACE_AND_STEP();
2830     if (ACCESS_FLAG(F_DF))   /* down */
2831         inc = -1;
2832     else
2833         inc = 1;
2834     if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
2835         /* dont care whether REPE or REPNE */
2836         /* move them until CX is ZERO. */
2837         while (M.x86.R_CX != 0) {
2838             M.x86.R_AL = fetch_data_byte(M.x86.R_SI);
2839             M.x86.R_CX -= 1;
2840             M.x86.R_SI += inc;
2841         }
2842         M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
2843     } else {
2844         M.x86.R_AL = fetch_data_byte(M.x86.R_SI);
2845         M.x86.R_SI += inc;
2846     }
2847     DECODE_CLEAR_SEGOVR();
2848     END_OF_INSTR();
2849 }
2850
2851 /****************************************************************************
2852 REMARKS:
2853 Handles opcode 0xad
2854 ****************************************************************************/
2855 void x86emuOp_lods_word(u8 X86EMU_UNUSED(op1))
2856 {
2857     int inc;
2858     u32 count;
2859
2860     START_OF_INSTR();
2861     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2862         DECODE_PRINTF("LODS\tDWORD\n");
2863         if (ACCESS_FLAG(F_DF))   /* down */
2864             inc = -4;
2865         else
2866             inc = 4;
2867     } else {
2868         DECODE_PRINTF("LODS\tWORD\n");
2869         if (ACCESS_FLAG(F_DF))   /* down */
2870             inc = -2;
2871         else
2872             inc = 2;
2873     }
2874     TRACE_AND_STEP();
2875     count = 1;
2876     if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
2877         /* dont care whether REPE or REPNE */
2878         /* move them until CX is ZERO. */
2879         count = M.x86.R_CX;
2880         M.x86.R_CX = 0;
2881         M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
2882     }
2883     while (count--) {
2884         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2885             M.x86.R_EAX = fetch_data_long(M.x86.R_SI);
2886         } else {
2887             M.x86.R_AX = fetch_data_word(M.x86.R_SI);
2888         }
2889         M.x86.R_SI += inc;
2890     }
2891     DECODE_CLEAR_SEGOVR();
2892     END_OF_INSTR();
2893 }
2894
2895 /****************************************************************************
2896 REMARKS:
2897 Handles opcode 0xae
2898 ****************************************************************************/
2899 void x86emuOp_scas_byte(u8 X86EMU_UNUSED(op1))
2900 {
2901     s8 val2;
2902     int inc;
2903
2904     START_OF_INSTR();
2905     DECODE_PRINTF("SCAS\tBYTE\n");
2906     TRACE_AND_STEP();
2907     if (ACCESS_FLAG(F_DF))   /* down */
2908         inc = -1;
2909     else
2910         inc = 1;
2911     if (M.x86.mode & SYSMODE_PREFIX_REPE) {
2912         /* REPE  */
2913         /* move them until CX is ZERO. */
2914         while (M.x86.R_CX != 0) {
2915             val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
2916             cmp_byte(M.x86.R_AL, val2);
2917             M.x86.R_CX -= 1;
2918             M.x86.R_DI += inc;
2919             if (ACCESS_FLAG(F_ZF) == 0)
2920                 break;
2921         }
2922         M.x86.mode &= ~SYSMODE_PREFIX_REPE;
2923     } else if (M.x86.mode & SYSMODE_PREFIX_REPNE) {
2924         /* REPNE  */
2925         /* move them until CX is ZERO. */
2926         while (M.x86.R_CX != 0) {
2927             val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
2928             cmp_byte(M.x86.R_AL, val2);
2929             M.x86.R_CX -= 1;
2930             M.x86.R_DI += inc;
2931             if (ACCESS_FLAG(F_ZF))
2932                 break;          /* zero flag set means equal */
2933         }
2934         M.x86.mode &= ~SYSMODE_PREFIX_REPNE;
2935     } else {
2936         val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
2937         cmp_byte(M.x86.R_AL, val2);
2938         M.x86.R_DI += inc;
2939     }
2940     DECODE_CLEAR_SEGOVR();
2941     END_OF_INSTR();
2942 }
2943
2944 /****************************************************************************
2945 REMARKS:
2946 Handles opcode 0xaf
2947 ****************************************************************************/
2948 void x86emuOp_scas_word(u8 X86EMU_UNUSED(op1))
2949 {
2950     int inc;
2951     u32 val;
2952
2953     START_OF_INSTR();
2954     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2955         DECODE_PRINTF("SCAS\tDWORD\n");
2956         if (ACCESS_FLAG(F_DF))   /* down */
2957             inc = -4;
2958         else
2959             inc = 4;
2960     } else {
2961         DECODE_PRINTF("SCAS\tWORD\n");
2962         if (ACCESS_FLAG(F_DF))   /* down */
2963             inc = -2;
2964         else
2965             inc = 2;
2966     }
2967     TRACE_AND_STEP();
2968     if (M.x86.mode & SYSMODE_PREFIX_REPE) {
2969         /* REPE  */
2970         /* move them until CX is ZERO. */
2971         while (M.x86.R_CX != 0) {
2972             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2973                 val = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
2974                 cmp_long(M.x86.R_EAX, val);
2975             } else {
2976                 val = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
2977                 cmp_word(M.x86.R_AX, (u16)val);
2978             }
2979             M.x86.R_CX -= 1;
2980             M.x86.R_DI += inc;
2981             if (ACCESS_FLAG(F_ZF) == 0)
2982                 break;
2983         }
2984         M.x86.mode &= ~SYSMODE_PREFIX_REPE;
2985     } else if (M.x86.mode & SYSMODE_PREFIX_REPNE) {
2986         /* REPNE  */
2987         /* move them until CX is ZERO. */
2988         while (M.x86.R_CX != 0) {
2989             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2990                 val = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
2991                 cmp_long(M.x86.R_EAX, val);
2992             } else {
2993                 val = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
2994                 cmp_word(M.x86.R_AX, (u16)val);
2995             }
2996             M.x86.R_CX -= 1;
2997             M.x86.R_DI += inc;
2998             if (ACCESS_FLAG(F_ZF))
2999                 break;          /* zero flag set means equal */
3000         }
3001         M.x86.mode &= ~SYSMODE_PREFIX_REPNE;
3002     } else {
3003         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3004             val = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
3005             cmp_long(M.x86.R_EAX, val);
3006         } else {
3007             val = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
3008             cmp_word(M.x86.R_AX, (u16)val);
3009         }
3010         M.x86.R_DI += inc;
3011     }
3012     DECODE_CLEAR_SEGOVR();
3013     END_OF_INSTR();
3014 }
3015
3016 /****************************************************************************
3017 REMARKS:
3018 Handles opcode 0xb0 - 0xb7
3019 ****************************************************************************/
3020 void x86emuOp_mov_byte_register_IMM(u8 op1)
3021 {
3022     u8 imm, *ptr;
3023
3024     START_OF_INSTR();
3025     DECODE_PRINTF("MOV\t");
3026     ptr = DECODE_RM_BYTE_REGISTER(op1 & 0x7);
3027     DECODE_PRINTF(",");
3028     imm = fetch_byte_imm();
3029     DECODE_PRINTF2("%x\n", imm);
3030     TRACE_AND_STEP();
3031     *ptr = imm;
3032     DECODE_CLEAR_SEGOVR();
3033     END_OF_INSTR();
3034 }
3035
3036 /****************************************************************************
3037 REMARKS:
3038 Handles opcode 0xb8 - 0xbf
3039 ****************************************************************************/
3040 void x86emuOp_mov_word_register_IMM(u8 X86EMU_UNUSED(op1))
3041 {
3042     u32 srcval;
3043
3044     op1 &= 0x7;
3045
3046     START_OF_INSTR();
3047     DECODE_PRINTF("MOV\t");
3048     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3049         u32 *reg32;
3050         reg32 = DECODE_RM_LONG_REGISTER(op1);
3051         srcval = fetch_long_imm();
3052         DECODE_PRINTF2(",%x\n", srcval);
3053         TRACE_AND_STEP();
3054         *reg32 = srcval;
3055     } else {
3056         u16 *reg16;
3057         reg16 = DECODE_RM_WORD_REGISTER(op1);
3058         srcval = fetch_word_imm();
3059         DECODE_PRINTF2(",%x\n", srcval);
3060         TRACE_AND_STEP();
3061         *reg16 = (u16)srcval;
3062     }
3063     DECODE_CLEAR_SEGOVR();
3064     END_OF_INSTR();
3065 }
3066
3067 /****************************************************************************
3068 REMARKS:
3069 Handles opcode 0xc0
3070 ****************************************************************************/
3071 void x86emuOp_opcC0_byte_RM_MEM(u8 X86EMU_UNUSED(op1))
3072 {
3073     int mod, rl, rh;
3074     u8 *destreg;
3075     uint destoffset;
3076     u8 destval;
3077     u8 amt;
3078
3079     /*
3080      * Yet another weirdo special case instruction format.  Part of
3081      * the opcode held below in "RH".  Doubly nested case would
3082      * result, except that the decoded instruction
3083      */
3084     START_OF_INSTR();
3085     FETCH_DECODE_MODRM(mod, rh, rl);
3086 #ifdef DEBUG
3087     if (DEBUG_DECODE()) {
3088         /* XXX DECODE_PRINTF may be changed to something more
3089            general, so that it is important to leave the strings
3090            in the same format, even though the result is that the
3091            above test is done twice. */
3092
3093         switch (rh) {
3094         case 0:
3095             DECODE_PRINTF("ROL\t");
3096             break;
3097         case 1:
3098             DECODE_PRINTF("ROR\t");
3099             break;
3100         case 2:
3101             DECODE_PRINTF("RCL\t");
3102             break;
3103         case 3:
3104             DECODE_PRINTF("RCR\t");
3105             break;
3106         case 4:
3107             DECODE_PRINTF("SHL\t");
3108             break;
3109         case 5:
3110             DECODE_PRINTF("SHR\t");
3111             break;
3112         case 6:
3113             DECODE_PRINTF("SAL\t");
3114             break;
3115         case 7:
3116             DECODE_PRINTF("SAR\t");
3117             break;
3118         }
3119     }
3120 #endif
3121     /* know operation, decode the mod byte to find the addressing
3122        mode. */
3123     if (mod < 3) {
3124         DECODE_PRINTF("BYTE PTR ");
3125         destoffset = decode_rmXX_address(mod, rl);
3126         amt = fetch_byte_imm();
3127         DECODE_PRINTF2(",%x\n", amt);
3128         destval = fetch_data_byte(destoffset);
3129         TRACE_AND_STEP();
3130         destval = (*opcD0_byte_operation[rh]) (destval, amt);
3131         store_data_byte(destoffset, destval);
3132     } else {                     /* register to register */
3133         destreg = DECODE_RM_BYTE_REGISTER(rl);
3134         amt = fetch_byte_imm();
3135         DECODE_PRINTF2(",%x\n", amt);
3136         TRACE_AND_STEP();
3137         destval = (*opcD0_byte_operation[rh]) (*destreg, amt);
3138         *destreg = destval;
3139     }
3140     DECODE_CLEAR_SEGOVR();
3141     END_OF_INSTR();
3142 }
3143
3144 /****************************************************************************
3145 REMARKS:
3146 Handles opcode 0xc1
3147 ****************************************************************************/
3148 void x86emuOp_opcC1_word_RM_MEM(u8 X86EMU_UNUSED(op1))
3149 {
3150     int mod, rl, rh;
3151     uint destoffset;
3152     u8 amt;
3153
3154     /*
3155      * Yet another weirdo special case instruction format.  Part of
3156      * the opcode held below in "RH".  Doubly nested case would
3157      * result, except that the decoded instruction
3158      */
3159     START_OF_INSTR();
3160     FETCH_DECODE_MODRM(mod, rh, rl);
3161 #ifdef DEBUG
3162     if (DEBUG_DECODE()) {
3163         /* XXX DECODE_PRINTF may be changed to something more
3164            general, so that it is important to leave the strings
3165            in the same format, even though the result is that the
3166            above test is done twice. */
3167
3168         switch (rh) {
3169         case 0:
3170             DECODE_PRINTF("ROL\t");
3171             break;
3172         case 1:
3173             DECODE_PRINTF("ROR\t");
3174             break;
3175         case 2:
3176             DECODE_PRINTF("RCL\t");
3177             break;
3178         case 3:
3179             DECODE_PRINTF("RCR\t");
3180             break;
3181         case 4:
3182             DECODE_PRINTF("SHL\t");
3183             break;
3184         case 5:
3185             DECODE_PRINTF("SHR\t");
3186             break;
3187         case 6:
3188             DECODE_PRINTF("SAL\t");
3189             break;
3190         case 7:
3191             DECODE_PRINTF("SAR\t");
3192             break;
3193         }
3194     }
3195 #endif
3196     /* know operation, decode the mod byte to find the addressing
3197        mode. */
3198     if (mod < 3) {
3199         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3200             u32 destval;
3201
3202             DECODE_PRINTF("DWORD PTR ");
3203             destoffset = decode_rmXX_address(mod, rl);
3204             amt = fetch_byte_imm();
3205             DECODE_PRINTF2(",%x\n", amt);
3206             destval = fetch_data_long(destoffset);
3207             TRACE_AND_STEP();
3208             destval = (*opcD1_long_operation[rh]) (destval, amt);
3209             store_data_long(destoffset, destval);
3210         } else {
3211             u16 destval;
3212
3213             DECODE_PRINTF("WORD PTR ");
3214             destoffset = decode_rmXX_address(mod, rl);
3215             amt = fetch_byte_imm();
3216             DECODE_PRINTF2(",%x\n", amt);
3217             destval = fetch_data_word(destoffset);
3218             TRACE_AND_STEP();
3219             destval = (*opcD1_word_operation[rh]) (destval, amt);
3220             store_data_word(destoffset, destval);
3221         }
3222     } else {                     /* register to register */
3223         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3224             u32 *destreg;
3225
3226             destreg = DECODE_RM_LONG_REGISTER(rl);
3227             amt = fetch_byte_imm();
3228             DECODE_PRINTF2(",%x\n", amt);
3229             TRACE_AND_STEP();
3230             *destreg = (*opcD1_long_operation[rh]) (*destreg, amt);
3231         } else {
3232             u16 *destreg;
3233
3234             destreg = DECODE_RM_WORD_REGISTER(rl);
3235             amt = fetch_byte_imm();
3236             DECODE_PRINTF2(",%x\n", amt);
3237             TRACE_AND_STEP();
3238             *destreg = (*opcD1_word_operation[rh]) (*destreg, amt);
3239         }
3240     }
3241     DECODE_CLEAR_SEGOVR();
3242     END_OF_INSTR();
3243 }
3244
3245 /****************************************************************************
3246 REMARKS:
3247 Handles opcode 0xc2
3248 ****************************************************************************/
3249 void x86emuOp_ret_near_IMM(u8 X86EMU_UNUSED(op1))
3250 {
3251     u16 imm;
3252
3253     START_OF_INSTR();
3254     DECODE_PRINTF("RET\t");
3255     imm = fetch_word_imm();
3256     DECODE_PRINTF2("%x\n", imm);
3257         RETURN_TRACE("RET",M.x86.saved_cs,M.x86.saved_ip);
3258         TRACE_AND_STEP();
3259     M.x86.R_IP = pop_word();
3260     M.x86.R_SP += imm;
3261     DECODE_CLEAR_SEGOVR();
3262     END_OF_INSTR();
3263 }
3264
3265 /****************************************************************************
3266 REMARKS:
3267 Handles opcode 0xc3
3268 ****************************************************************************/
3269 void x86emuOp_ret_near(u8 X86EMU_UNUSED(op1))
3270 {
3271     START_OF_INSTR();
3272     DECODE_PRINTF("RET\n");
3273         RETURN_TRACE("RET",M.x86.saved_cs,M.x86.saved_ip);
3274         TRACE_AND_STEP();
3275     M.x86.R_IP = pop_word();
3276     DECODE_CLEAR_SEGOVR();
3277     END_OF_INSTR();
3278 }
3279
3280 /****************************************************************************
3281 REMARKS:
3282 Handles opcode 0xc4
3283 ****************************************************************************/
3284 void x86emuOp_les_R_IMM(u8 X86EMU_UNUSED(op1))
3285 {
3286     int mod, rh, rl;
3287     u16 *dstreg;
3288     uint srcoffset;
3289
3290     START_OF_INSTR();
3291     DECODE_PRINTF("LES\t");
3292     FETCH_DECODE_MODRM(mod, rh, rl);
3293     if (mod < 3) {
3294         dstreg = DECODE_RM_WORD_REGISTER(rh);
3295         DECODE_PRINTF(",");
3296         srcoffset = decode_rmXX_address(mod, rl);
3297         DECODE_PRINTF("\n");
3298         TRACE_AND_STEP();
3299         *dstreg = fetch_data_word(srcoffset);
3300         M.x86.R_ES = fetch_data_word(srcoffset + 2);
3301     }
3302     /* else UNDEFINED!                   register to register */
3303
3304     DECODE_CLEAR_SEGOVR();
3305     END_OF_INSTR();
3306 }
3307
3308 /****************************************************************************
3309 REMARKS:
3310 Handles opcode 0xc5
3311 ****************************************************************************/
3312 void x86emuOp_lds_R_IMM(u8 X86EMU_UNUSED(op1))
3313 {
3314     int mod, rh, rl;
3315     u16 *dstreg;
3316     uint srcoffset;
3317
3318     START_OF_INSTR();
3319     DECODE_PRINTF("LDS\t");
3320     FETCH_DECODE_MODRM(mod, rh, rl);
3321     if (mod < 3) {
3322         dstreg = DECODE_RM_WORD_REGISTER(rh);
3323         DECODE_PRINTF(",");
3324         srcoffset = decode_rmXX_address(mod, rl);
3325         DECODE_PRINTF("\n");
3326         TRACE_AND_STEP();
3327         *dstreg = fetch_data_word(srcoffset);
3328         M.x86.R_DS = fetch_data_word(srcoffset + 2);
3329     }
3330     /* else UNDEFINED! */
3331     DECODE_CLEAR_SEGOVR();
3332     END_OF_INSTR();
3333 }
3334
3335 /****************************************************************************
3336 REMARKS:
3337 Handles opcode 0xc6
3338 ****************************************************************************/
3339 void x86emuOp_mov_byte_RM_IMM(u8 X86EMU_UNUSED(op1))
3340 {
3341     int mod, rl, rh;
3342     u8 *destreg;
3343     uint destoffset;
3344     u8 imm;
3345
3346     START_OF_INSTR();
3347     DECODE_PRINTF("MOV\t");
3348     FETCH_DECODE_MODRM(mod, rh, rl);
3349     if (rh != 0) {
3350         DECODE_PRINTF("ILLEGAL DECODE OF OPCODE c6\n");
3351         HALT_SYS();
3352     }
3353     if (mod < 3) {
3354         DECODE_PRINTF("BYTE PTR ");
3355         destoffset = decode_rmXX_address(mod, rl);
3356         imm = fetch_byte_imm();
3357         DECODE_PRINTF2(",%2x\n", imm);
3358         TRACE_AND_STEP();
3359         store_data_byte(destoffset, imm);
3360     } else {                     /* register to register */
3361         destreg = DECODE_RM_BYTE_REGISTER(rl);
3362         imm = fetch_byte_imm();
3363         DECODE_PRINTF2(",%2x\n", imm);
3364         TRACE_AND_STEP();
3365         *destreg = imm;
3366     }
3367     DECODE_CLEAR_SEGOVR();
3368     END_OF_INSTR();
3369 }
3370
3371 /****************************************************************************
3372 REMARKS:
3373 Handles opcode 0xc7
3374 ****************************************************************************/
3375 void x86emuOp_mov_word_RM_IMM(u8 X86EMU_UNUSED(op1))
3376 {
3377     int mod, rl, rh;
3378     uint destoffset;
3379
3380     START_OF_INSTR();
3381     DECODE_PRINTF("MOV\t");
3382     FETCH_DECODE_MODRM(mod, rh, rl);
3383     if (rh != 0) {
3384         DECODE_PRINTF("ILLEGAL DECODE OF OPCODE 8F\n");
3385         HALT_SYS();
3386     }
3387     if (mod < 3) {
3388         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3389             u32 imm;
3390
3391             DECODE_PRINTF("DWORD PTR ");
3392             destoffset = decode_rmXX_address(mod, rl);
3393             imm = fetch_long_imm();
3394             DECODE_PRINTF2(",%x\n", imm);
3395             TRACE_AND_STEP();
3396             store_data_long(destoffset, imm);
3397         } else {
3398             u16 imm;
3399
3400             DECODE_PRINTF("WORD PTR ");
3401             destoffset = decode_rmXX_address(mod, rl);
3402             imm = fetch_word_imm();
3403             DECODE_PRINTF2(",%x\n", imm);
3404             TRACE_AND_STEP();
3405             store_data_word(destoffset, imm);
3406         }
3407     } else {                     /* register to register */
3408         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3409                         u32 *destreg;
3410                         u32 imm;
3411
3412             destreg = DECODE_RM_LONG_REGISTER(rl);
3413             imm = fetch_long_imm();
3414             DECODE_PRINTF2(",%x\n", imm);
3415             TRACE_AND_STEP();
3416             *destreg = imm;
3417         } else {
3418                         u16 *destreg;
3419                         u16 imm;
3420
3421             destreg = DECODE_RM_WORD_REGISTER(rl);
3422             imm = fetch_word_imm();
3423             DECODE_PRINTF2(",%x\n", imm);
3424             TRACE_AND_STEP();
3425             *destreg = imm;
3426         }
3427     }
3428     DECODE_CLEAR_SEGOVR();
3429     END_OF_INSTR();
3430 }
3431
3432 /****************************************************************************
3433 REMARKS:
3434 Handles opcode 0xc8
3435 ****************************************************************************/
3436 void x86emuOp_enter(u8 X86EMU_UNUSED(op1))
3437 {
3438     u16 local,frame_pointer;
3439     u8  nesting;
3440     int i;
3441
3442     START_OF_INSTR();
3443     local = fetch_word_imm();
3444     nesting = fetch_byte_imm();
3445     DECODE_PRINTF2("ENTER %x\n", local);
3446     DECODE_PRINTF2(",%x\n", nesting);
3447     TRACE_AND_STEP();
3448     push_word(M.x86.R_BP);
3449     frame_pointer = M.x86.R_SP;
3450     if (nesting > 0) {
3451         for (i = 1; i < nesting; i++) {
3452             M.x86.R_BP -= 2;
3453             push_word(fetch_data_word_abs(M.x86.R_SS, M.x86.R_BP));
3454             }
3455         push_word(frame_pointer);
3456         }
3457     M.x86.R_BP = frame_pointer;
3458     M.x86.R_SP = (u16)(M.x86.R_SP - local);
3459     DECODE_CLEAR_SEGOVR();
3460     END_OF_INSTR();
3461 }
3462
3463 /****************************************************************************
3464 REMARKS:
3465 Handles opcode 0xc9
3466 ****************************************************************************/
3467 void x86emuOp_leave(u8 X86EMU_UNUSED(op1))
3468 {
3469     START_OF_INSTR();
3470     DECODE_PRINTF("LEAVE\n");
3471     TRACE_AND_STEP();
3472     M.x86.R_SP = M.x86.R_BP;
3473     M.x86.R_BP = pop_word();
3474     DECODE_CLEAR_SEGOVR();
3475     END_OF_INSTR();
3476 }
3477
3478 /****************************************************************************
3479 REMARKS:
3480 Handles opcode 0xca
3481 ****************************************************************************/
3482 void x86emuOp_ret_far_IMM(u8 X86EMU_UNUSED(op1))
3483 {
3484     u16 imm;
3485
3486     START_OF_INSTR();
3487     DECODE_PRINTF("RETF\t");
3488     imm = fetch_word_imm();
3489     DECODE_PRINTF2("%x\n", imm);
3490         RETURN_TRACE("RETF",M.x86.saved_cs,M.x86.saved_ip);
3491         TRACE_AND_STEP();
3492     M.x86.R_IP = pop_word();
3493     M.x86.R_CS = pop_word();
3494     M.x86.R_SP += imm;
3495     DECODE_CLEAR_SEGOVR();
3496     END_OF_INSTR();
3497 }
3498
3499 /****************************************************************************
3500 REMARKS:
3501 Handles opcode 0xcb
3502 ****************************************************************************/
3503 void x86emuOp_ret_far(u8 X86EMU_UNUSED(op1))
3504 {
3505     START_OF_INSTR();
3506     DECODE_PRINTF("RETF\n");
3507         RETURN_TRACE("RETF",M.x86.saved_cs,M.x86.saved_ip);
3508         TRACE_AND_STEP();
3509     M.x86.R_IP = pop_word();
3510     M.x86.R_CS = pop_word();
3511     DECODE_CLEAR_SEGOVR();
3512     END_OF_INSTR();
3513 }
3514
3515 /****************************************************************************
3516 REMARKS:
3517 Handles opcode 0xcc
3518 ****************************************************************************/
3519 void x86emuOp_int3(u8 X86EMU_UNUSED(op1))
3520 {
3521     START_OF_INSTR();
3522     DECODE_PRINTF("INT 3\n");
3523     (void)mem_access_word(3 * 4 + 2);
3524     /* access the segment register */
3525     TRACE_AND_STEP();
3526         if (_X86EMU_intrTab[3]) {
3527                 (*_X86EMU_intrTab[3])(3);
3528     } else {
3529         push_word((u16)M.x86.R_FLG);
3530         CLEAR_FLAG(F_IF);
3531         CLEAR_FLAG(F_TF);
3532         push_word(M.x86.R_CS);
3533         M.x86.R_CS = mem_access_word(3 * 4 + 2);
3534         push_word(M.x86.R_IP);
3535         M.x86.R_IP = mem_access_word(3 * 4);
3536     }
3537     DECODE_CLEAR_SEGOVR();
3538     END_OF_INSTR();
3539 }
3540
3541 /****************************************************************************
3542 REMARKS:
3543 Handles opcode 0xcd
3544 ****************************************************************************/
3545 void x86emuOp_int_IMM(u8 X86EMU_UNUSED(op1))
3546 {
3547     u8 intnum;
3548
3549     START_OF_INSTR();
3550     DECODE_PRINTF("INT\t");
3551     intnum = fetch_byte_imm();
3552     DECODE_PRINTF2("%x\n", intnum);
3553     (void)mem_access_word(intnum * 4 + 2);
3554     TRACE_AND_STEP();
3555         if (_X86EMU_intrTab[intnum]) {
3556                 (*_X86EMU_intrTab[intnum])(intnum);
3557     } else {
3558         push_word((u16)M.x86.R_FLG);
3559         CLEAR_FLAG(F_IF);
3560         CLEAR_FLAG(F_TF);
3561         push_word(M.x86.R_CS);
3562         M.x86.R_CS = mem_access_word(intnum * 4 + 2);
3563         push_word(M.x86.R_IP);
3564         M.x86.R_IP = mem_access_word(intnum * 4);
3565     }
3566     DECODE_CLEAR_SEGOVR();
3567     END_OF_INSTR();
3568 }
3569
3570 /****************************************************************************
3571 REMARKS:
3572 Handles opcode 0xce
3573 ****************************************************************************/
3574 void x86emuOp_into(u8 X86EMU_UNUSED(op1))
3575 {
3576     START_OF_INSTR();
3577     DECODE_PRINTF("INTO\n");
3578     TRACE_AND_STEP();
3579     if (ACCESS_FLAG(F_OF)) {
3580         (void)mem_access_word(4 * 4 + 2);
3581                 if (_X86EMU_intrTab[4]) {
3582                         (*_X86EMU_intrTab[4])(4);
3583         } else {
3584             push_word((u16)M.x86.R_FLG);
3585             CLEAR_FLAG(F_IF);
3586             CLEAR_FLAG(F_TF);
3587             push_word(M.x86.R_CS);
3588             M.x86.R_CS = mem_access_word(4 * 4 + 2);
3589             push_word(M.x86.R_IP);
3590             M.x86.R_IP = mem_access_word(4 * 4);
3591         }
3592     }
3593     DECODE_CLEAR_SEGOVR();
3594     END_OF_INSTR();
3595 }
3596
3597 /****************************************************************************
3598 REMARKS:
3599 Handles opcode 0xcf
3600 ****************************************************************************/
3601 void x86emuOp_iret(u8 X86EMU_UNUSED(op1))
3602 {
3603     START_OF_INSTR();
3604     DECODE_PRINTF("IRET\n");
3605
3606     TRACE_AND_STEP();
3607
3608     M.x86.R_IP = pop_word();
3609     M.x86.R_CS = pop_word();
3610     M.x86.R_FLG = pop_word();
3611     DECODE_CLEAR_SEGOVR();
3612     END_OF_INSTR();
3613 }
3614
3615 /****************************************************************************
3616 REMARKS:
3617 Handles opcode 0xd0
3618 ****************************************************************************/
3619 void x86emuOp_opcD0_byte_RM_1(u8 X86EMU_UNUSED(op1))
3620 {
3621     int mod, rl, rh;
3622     u8 *destreg;
3623     uint destoffset;
3624     u8 destval;
3625
3626     /*
3627      * Yet another weirdo special case instruction format.  Part of
3628      * the opcode held below in "RH".  Doubly nested case would
3629      * result, except that the decoded instruction
3630      */
3631     START_OF_INSTR();
3632     FETCH_DECODE_MODRM(mod, rh, rl);
3633 #ifdef DEBUG
3634     if (DEBUG_DECODE()) {
3635         /* XXX DECODE_PRINTF may be changed to something more
3636            general, so that it is important to leave the strings
3637            in the same format, even though the result is that the
3638            above test is done twice. */
3639         switch (rh) {
3640         case 0:
3641             DECODE_PRINTF("ROL\t");
3642             break;
3643         case 1:
3644             DECODE_PRINTF("ROR\t");
3645             break;
3646         case 2:
3647             DECODE_PRINTF("RCL\t");
3648             break;
3649         case 3:
3650             DECODE_PRINTF("RCR\t");
3651             break;
3652         case 4:
3653             DECODE_PRINTF("SHL\t");
3654             break;
3655         case 5:
3656             DECODE_PRINTF("SHR\t");
3657             break;
3658         case 6:
3659             DECODE_PRINTF("SAL\t");
3660             break;
3661         case 7:
3662             DECODE_PRINTF("SAR\t");
3663             break;
3664         }
3665     }
3666 #endif
3667     /* know operation, decode the mod byte to find the addressing
3668        mode. */
3669     if (mod < 3) {
3670         DECODE_PRINTF("BYTE PTR ");
3671         destoffset = decode_rmXX_address(mod, rl);
3672         DECODE_PRINTF(",1\n");
3673         destval = fetch_data_byte(destoffset);
3674         TRACE_AND_STEP();
3675         destval = (*opcD0_byte_operation[rh]) (destval, 1);
3676         store_data_byte(destoffset, destval);
3677     } else {                     /* register to register */
3678         destreg = DECODE_RM_BYTE_REGISTER(rl);
3679         DECODE_PRINTF(",1\n");
3680         TRACE_AND_STEP();
3681         destval = (*opcD0_byte_operation[rh]) (*destreg, 1);
3682         *destreg = destval;
3683     }
3684     DECODE_CLEAR_SEGOVR();
3685     END_OF_INSTR();
3686 }
3687
3688 /****************************************************************************
3689 REMARKS:
3690 Handles opcode 0xd1
3691 ****************************************************************************/
3692 void x86emuOp_opcD1_word_RM_1(u8 X86EMU_UNUSED(op1))
3693 {
3694     int mod, rl, rh;
3695     uint destoffset;
3696
3697     /*
3698      * Yet another weirdo special case instruction format.  Part of
3699      * the opcode held below in "RH".  Doubly nested case would
3700      * result, except that the decoded instruction
3701      */
3702     START_OF_INSTR();
3703     FETCH_DECODE_MODRM(mod, rh, rl);
3704 #ifdef DEBUG
3705     if (DEBUG_DECODE()) {
3706         /* XXX DECODE_PRINTF may be changed to something more
3707            general, so that it is important to leave the strings
3708            in the same format, even though the result is that the
3709            above test is done twice. */
3710         switch (rh) {
3711         case 0:
3712             DECODE_PRINTF("ROL\t");
3713             break;
3714         case 1:
3715             DECODE_PRINTF("ROR\t");
3716             break;
3717         case 2:
3718             DECODE_PRINTF("RCL\t");
3719             break;
3720         case 3:
3721             DECODE_PRINTF("RCR\t");
3722             break;
3723         case 4:
3724             DECODE_PRINTF("SHL\t");
3725             break;
3726         case 5:
3727             DECODE_PRINTF("SHR\t");
3728             break;
3729         case 6:
3730             DECODE_PRINTF("SAL\t");
3731             break;
3732         case 7:
3733             DECODE_PRINTF("SAR\t");
3734             break;
3735         }
3736     }
3737 #endif
3738     /* know operation, decode the mod byte to find the addressing
3739        mode. */
3740     if (mod < 3) {
3741         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3742             u32 destval;
3743
3744             DECODE_PRINTF("DWORD PTR ");
3745             destoffset = decode_rmXX_address(mod, rl);
3746             DECODE_PRINTF(",1\n");
3747             destval = fetch_data_long(destoffset);
3748             TRACE_AND_STEP();
3749             destval = (*opcD1_long_operation[rh]) (destval, 1);
3750             store_data_long(destoffset, destval);
3751         } else {
3752             u16 destval;
3753
3754             DECODE_PRINTF("WORD PTR ");
3755             destoffset = decode_rmXX_address(mod, rl);
3756             DECODE_PRINTF(",1\n");
3757             destval = fetch_data_word(destoffset);
3758             TRACE_AND_STEP();
3759             destval = (*opcD1_word_operation[rh]) (destval, 1);
3760             store_data_word(destoffset, destval);
3761         }
3762     } else {                     /* register to register */
3763         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3764                         u32 destval;
3765                         u32 *destreg;
3766
3767             destreg = DECODE_RM_LONG_REGISTER(rl);
3768             DECODE_PRINTF(",1\n");
3769             TRACE_AND_STEP();
3770             destval = (*opcD1_long_operation[rh]) (*destreg, 1);
3771             *destreg = destval;
3772         } else {
3773                         u16 destval;
3774                         u16 *destreg;
3775
3776             destreg = DECODE_RM_WORD_REGISTER(rl);
3777             DECODE_PRINTF(",1\n");
3778             TRACE_AND_STEP();
3779             destval = (*opcD1_word_operation[rh]) (*destreg, 1);
3780             *destreg = destval;
3781         }
3782     }
3783     DECODE_CLEAR_SEGOVR();
3784     END_OF_INSTR();
3785 }
3786
3787 /****************************************************************************
3788 REMARKS:
3789 Handles opcode 0xd2
3790 ****************************************************************************/
3791 void x86emuOp_opcD2_byte_RM_CL(u8 X86EMU_UNUSED(op1))
3792 {
3793     int mod, rl, rh;
3794     u8 *destreg;
3795     uint destoffset;
3796     u8 destval;
3797     u8 amt;
3798
3799     /*
3800      * Yet another weirdo special case instruction format.  Part of
3801      * the opcode held below in "RH".  Doubly nested case would
3802      * result, except that the decoded instruction
3803      */
3804     START_OF_INSTR();
3805     FETCH_DECODE_MODRM(mod, rh, rl);
3806 #ifdef DEBUG
3807     if (DEBUG_DECODE()) {
3808         /* XXX DECODE_PRINTF may be changed to something more
3809            general, so that it is important to leave the strings
3810            in the same format, even though the result is that the
3811            above test is done twice. */
3812         switch (rh) {
3813         case 0:
3814             DECODE_PRINTF("ROL\t");
3815             break;
3816         case 1:
3817             DECODE_PRINTF("ROR\t");
3818             break;
3819         case 2:
3820             DECODE_PRINTF("RCL\t");
3821             break;
3822         case 3:
3823             DECODE_PRINTF("RCR\t");
3824             break;
3825         case 4:
3826             DECODE_PRINTF("SHL\t");
3827             break;
3828         case 5:
3829             DECODE_PRINTF("SHR\t");
3830             break;
3831         case 6:
3832             DECODE_PRINTF("SAL\t");
3833             break;
3834         case 7:
3835             DECODE_PRINTF("SAR\t");
3836             break;
3837         }
3838     }
3839 #endif
3840     /* know operation, decode the mod byte to find the addressing
3841        mode. */
3842     amt = M.x86.R_CL;
3843     if (mod < 3) {
3844         DECODE_PRINTF("BYTE PTR ");
3845         destoffset = decode_rmXX_address(mod, rl);
3846         DECODE_PRINTF(",CL\n");
3847         destval = fetch_data_byte(destoffset);
3848         TRACE_AND_STEP();
3849         destval = (*opcD0_byte_operation[rh]) (destval, amt);
3850         store_data_byte(destoffset, destval);
3851     } else {                     /* register to register */
3852         destreg = DECODE_RM_BYTE_REGISTER(rl);
3853         DECODE_PRINTF(",CL\n");
3854         TRACE_AND_STEP();
3855         destval = (*opcD0_byte_operation[rh]) (*destreg, amt);
3856         *destreg = destval;
3857     }
3858     DECODE_CLEAR_SEGOVR();
3859     END_OF_INSTR();
3860 }
3861
3862 /****************************************************************************
3863 REMARKS:
3864 Handles opcode 0xd3
3865 ****************************************************************************/
3866 void x86emuOp_opcD3_word_RM_CL(u8 X86EMU_UNUSED(op1))
3867 {
3868     int mod, rl, rh;
3869     uint destoffset;
3870     u8 amt;
3871
3872     /*
3873      * Yet another weirdo special case instruction format.  Part of
3874      * the opcode held below in "RH".  Doubly nested case would
3875      * result, except that the decoded instruction
3876      */
3877     START_OF_INSTR();
3878     FETCH_DECODE_MODRM(mod, rh, rl);
3879 #ifdef DEBUG
3880     if (DEBUG_DECODE()) {
3881         /* XXX DECODE_PRINTF may be changed to something more
3882            general, so that it is important to leave the strings
3883            in the same format, even though the result is that the
3884            above test is done twice. */
3885         switch (rh) {
3886         case 0:
3887             DECODE_PRINTF("ROL\t");
3888             break;
3889         case 1:
3890             DECODE_PRINTF("ROR\t");
3891             break;
3892         case 2:
3893             DECODE_PRINTF("RCL\t");
3894             break;
3895         case 3:
3896             DECODE_PRINTF("RCR\t");
3897             break;
3898         case 4:
3899             DECODE_PRINTF("SHL\t");
3900             break;
3901         case 5:
3902             DECODE_PRINTF("SHR\t");
3903             break;
3904         case 6:
3905             DECODE_PRINTF("SAL\t");
3906             break;
3907         case 7:
3908             DECODE_PRINTF("SAR\t");
3909             break;
3910         }
3911     }
3912 #endif
3913     /* know operation, decode the mod byte to find the addressing
3914        mode. */
3915     amt = M.x86.R_CL;
3916     if (mod < 3) {
3917         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3918             u32 destval;
3919
3920             DECODE_PRINTF("DWORD PTR ");
3921             destoffset = decode_rmXX_address(mod, rl);
3922             DECODE_PRINTF(",CL\n");
3923             destval = fetch_data_long(destoffset);
3924             TRACE_AND_STEP();
3925             destval = (*opcD1_long_operation[rh]) (destval, amt);
3926             store_data_long(destoffset, destval);
3927         } else {
3928             u16 destval;
3929
3930             DECODE_PRINTF("WORD PTR ");
3931             destoffset = decode_rmXX_address(mod, rl);
3932             DECODE_PRINTF(",CL\n");
3933             destval = fetch_data_word(destoffset);
3934             TRACE_AND_STEP();
3935             destval = (*opcD1_word_operation[rh]) (destval, amt);
3936             store_data_word(destoffset, destval);
3937         }
3938     } else {                     /* register to register */
3939         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3940             u32 *destreg;
3941
3942             destreg = DECODE_RM_LONG_REGISTER(rl);
3943             DECODE_PRINTF(",CL\n");
3944             TRACE_AND_STEP();
3945             *destreg = (*opcD1_long_operation[rh]) (*destreg, amt);
3946         } else {
3947             u16 *destreg;
3948
3949             destreg = DECODE_RM_WORD_REGISTER(rl);
3950             DECODE_PRINTF(",CL\n");
3951             TRACE_AND_STEP();
3952             *destreg = (*opcD1_word_operation[rh]) (*destreg, amt);
3953         }
3954     }
3955     DECODE_CLEAR_SEGOVR();
3956     END_OF_INSTR();
3957 }
3958
3959 /****************************************************************************
3960 REMARKS:
3961 Handles opcode 0xd4
3962 ****************************************************************************/
3963 void x86emuOp_aam(u8 X86EMU_UNUSED(op1))
3964 {
3965     u8 a;
3966
3967     START_OF_INSTR();
3968     DECODE_PRINTF("AAM\n");
3969     a = fetch_byte_imm();      /* this is a stupid encoding. */
3970     if (a != 10) {
3971         DECODE_PRINTF("ERROR DECODING AAM\n");
3972         TRACE_REGS();
3973         HALT_SYS();
3974     }
3975     TRACE_AND_STEP();
3976     /* note the type change here --- returning AL and AH in AX. */
3977     M.x86.R_AX = aam_word(M.x86.R_AL);
3978     DECODE_CLEAR_SEGOVR();
3979     END_OF_INSTR();
3980 }
3981
3982 /****************************************************************************
3983 REMARKS:
3984 Handles opcode 0xd5
3985 ****************************************************************************/
3986 void x86emuOp_aad(u8 X86EMU_UNUSED(op1))
3987 {
3988     START_OF_INSTR();
3989     DECODE_PRINTF("AAD\n");
3990     (void)fetch_byte_imm();
3991     TRACE_AND_STEP();
3992     M.x86.R_AX = aad_word(M.x86.R_AX);
3993     DECODE_CLEAR_SEGOVR();
3994     END_OF_INSTR();
3995 }
3996
3997 /* opcode 0xd6 ILLEGAL OPCODE */
3998
3999 /****************************************************************************
4000 REMARKS:
4001 Handles opcode 0xd7
4002 ****************************************************************************/
4003 void x86emuOp_xlat(u8 X86EMU_UNUSED(op1))
4004 {
4005     u16 addr;
4006
4007     START_OF_INSTR();
4008     DECODE_PRINTF("XLAT\n");
4009     TRACE_AND_STEP();
4010         addr = (u16)(M.x86.R_BX + (u8)M.x86.R_AL);
4011     M.x86.R_AL = fetch_data_byte(addr);
4012     DECODE_CLEAR_SEGOVR();
4013     END_OF_INSTR();
4014 }
4015
4016 /* instuctions  D8 .. DF are in i87_ops.c */
4017
4018 /****************************************************************************
4019 REMARKS:
4020 Handles opcode 0xe0
4021 ****************************************************************************/
4022 void x86emuOp_loopne(u8 X86EMU_UNUSED(op1))
4023 {
4024     s16 ip;
4025
4026     START_OF_INSTR();
4027     DECODE_PRINTF("LOOPNE\t");
4028     ip = (s8) fetch_byte_imm();
4029     ip += (s16) M.x86.R_IP;
4030     DECODE_PRINTF2("%04x\n", ip);
4031     TRACE_AND_STEP();
4032     M.x86.R_CX -= 1;
4033     if (M.x86.R_CX != 0 && !ACCESS_FLAG(F_ZF))      /* CX != 0 and !ZF */
4034         M.x86.R_IP = ip;
4035     DECODE_CLEAR_SEGOVR();
4036     END_OF_INSTR();
4037 }
4038
4039 /****************************************************************************
4040 REMARKS:
4041 Handles opcode 0xe1
4042 ****************************************************************************/
4043 void x86emuOp_loope(u8 X86EMU_UNUSED(op1))
4044 {
4045     s16 ip;
4046
4047     START_OF_INSTR();
4048     DECODE_PRINTF("LOOPE\t");
4049     ip = (s8) fetch_byte_imm();
4050     ip += (s16) M.x86.R_IP;
4051     DECODE_PRINTF2("%04x\n", ip);
4052     TRACE_AND_STEP();
4053     M.x86.R_CX -= 1;
4054     if (M.x86.R_CX != 0 && ACCESS_FLAG(F_ZF))       /* CX != 0 and ZF */
4055         M.x86.R_IP = ip;
4056     DECODE_CLEAR_SEGOVR();
4057     END_OF_INSTR();
4058 }
4059
4060 /****************************************************************************
4061 REMARKS:
4062 Handles opcode 0xe2
4063 ****************************************************************************/
4064 void x86emuOp_loop(u8 X86EMU_UNUSED(op1))
4065 {
4066     s16 ip;
4067
4068     START_OF_INSTR();
4069     DECODE_PRINTF("LOOP\t");
4070     ip = (s8) fetch_byte_imm();
4071     ip += (s16) M.x86.R_IP;
4072     DECODE_PRINTF2("%04x\n", ip);
4073     TRACE_AND_STEP();
4074     M.x86.R_CX -= 1;
4075     if (M.x86.R_CX != 0)
4076         M.x86.R_IP = ip;
4077     DECODE_CLEAR_SEGOVR();
4078     END_OF_INSTR();
4079 }
4080
4081 /****************************************************************************
4082 REMARKS:
4083 Handles opcode 0xe3
4084 ****************************************************************************/
4085 void x86emuOp_jcxz(u8 X86EMU_UNUSED(op1))
4086 {
4087     u16 target;
4088     s8  offset;
4089
4090     /* jump to byte offset if overflow flag is set */
4091     START_OF_INSTR();
4092     DECODE_PRINTF("JCXZ\t");
4093     offset = (s8)fetch_byte_imm();
4094     target = (u16)(M.x86.R_IP + offset);
4095     DECODE_PRINTF2("%x\n", target);
4096     TRACE_AND_STEP();
4097     if (M.x86.R_CX == 0)
4098         M.x86.R_IP = target;
4099     DECODE_CLEAR_SEGOVR();
4100     END_OF_INSTR();
4101 }
4102
4103 /****************************************************************************
4104 REMARKS:
4105 Handles opcode 0xe4
4106 ****************************************************************************/
4107 void x86emuOp_in_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
4108 {
4109     u8 port;
4110
4111     START_OF_INSTR();
4112     DECODE_PRINTF("IN\t");
4113         port = (u8) fetch_byte_imm();
4114     DECODE_PRINTF2("%x,AL\n", port);
4115     TRACE_AND_STEP();
4116     M.x86.R_AL = (*sys_inb)(port);
4117     DECODE_CLEAR_SEGOVR();
4118     END_OF_INSTR();
4119 }
4120
4121 /****************************************************************************
4122 REMARKS:
4123 Handles opcode 0xe5
4124 ****************************************************************************/
4125 void x86emuOp_in_word_AX_IMM(u8 X86EMU_UNUSED(op1))
4126 {
4127     u8 port;
4128
4129     START_OF_INSTR();
4130     DECODE_PRINTF("IN\t");
4131         port = (u8) fetch_byte_imm();
4132     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4133         DECODE_PRINTF2("EAX,%x\n", port);
4134     } else {
4135         DECODE_PRINTF2("AX,%x\n", port);
4136     }
4137     TRACE_AND_STEP();
4138     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4139         M.x86.R_EAX = (*sys_inl)(port);
4140     } else {
4141         M.x86.R_AX = (*sys_inw)(port);
4142     }
4143     DECODE_CLEAR_SEGOVR();
4144     END_OF_INSTR();
4145 }
4146
4147 /****************************************************************************
4148 REMARKS:
4149 Handles opcode 0xe6
4150 ****************************************************************************/
4151 void x86emuOp_out_byte_IMM_AL(u8 X86EMU_UNUSED(op1))
4152 {
4153     u8 port;
4154
4155     START_OF_INSTR();
4156     DECODE_PRINTF("OUT\t");
4157         port = (u8) fetch_byte_imm();
4158     DECODE_PRINTF2("%x,AL\n", port);
4159     TRACE_AND_STEP();
4160     (*sys_outb)(port, M.x86.R_AL);
4161     DECODE_CLEAR_SEGOVR();
4162     END_OF_INSTR();
4163 }
4164
4165 /****************************************************************************
4166 REMARKS:
4167 Handles opcode 0xe7
4168 ****************************************************************************/
4169 void x86emuOp_out_word_IMM_AX(u8 X86EMU_UNUSED(op1))
4170 {
4171     u8 port;
4172
4173     START_OF_INSTR();
4174     DECODE_PRINTF("OUT\t");
4175         port = (u8) fetch_byte_imm();
4176     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4177         DECODE_PRINTF2("%x,EAX\n", port);
4178     } else {
4179         DECODE_PRINTF2("%x,AX\n", port);
4180     }
4181     TRACE_AND_STEP();
4182     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4183         (*sys_outl)(port, M.x86.R_EAX);
4184     } else {
4185         (*sys_outw)(port, M.x86.R_AX);
4186     }
4187     DECODE_CLEAR_SEGOVR();
4188     END_OF_INSTR();
4189 }
4190
4191 /****************************************************************************
4192 REMARKS:
4193 Handles opcode 0xe8
4194 ****************************************************************************/
4195 void x86emuOp_call_near_IMM(u8 X86EMU_UNUSED(op1))
4196 {
4197     s16 ip;
4198
4199     START_OF_INSTR();
4200         DECODE_PRINTF("CALL\t");
4201         ip = (s16) fetch_word_imm();
4202         ip += (s16) M.x86.R_IP;    /* CHECK SIGN */
4203         DECODE_PRINTF2("%04x\n", ip);
4204         CALL_TRACE(M.x86.saved_cs, M.x86.saved_ip, M.x86.R_CS, ip, "");
4205     TRACE_AND_STEP();
4206     push_word(M.x86.R_IP);
4207     M.x86.R_IP = ip;
4208     DECODE_CLEAR_SEGOVR();
4209     END_OF_INSTR();
4210 }
4211
4212 /****************************************************************************
4213 REMARKS:
4214 Handles opcode 0xe9
4215 ****************************************************************************/
4216 void x86emuOp_jump_near_IMM(u8 X86EMU_UNUSED(op1))
4217 {
4218     int ip;
4219
4220     START_OF_INSTR();
4221     DECODE_PRINTF("JMP\t");
4222     ip = (s16)fetch_word_imm();
4223     ip += (s16)M.x86.R_IP;
4224     DECODE_PRINTF2("%04x\n", ip);
4225     TRACE_AND_STEP();
4226     M.x86.R_IP = (u16)ip;
4227     DECODE_CLEAR_SEGOVR();
4228     END_OF_INSTR();
4229 }
4230
4231 /****************************************************************************
4232 REMARKS:
4233 Handles opcode 0xea
4234 ****************************************************************************/
4235 void x86emuOp_jump_far_IMM(u8 X86EMU_UNUSED(op1))
4236 {
4237     u16 cs, ip;
4238
4239     START_OF_INSTR();
4240     DECODE_PRINTF("JMP\tFAR ");
4241     ip = fetch_word_imm();
4242     cs = fetch_word_imm();
4243     DECODE_PRINTF2("%04x:", cs);
4244     DECODE_PRINTF2("%04x\n", ip);
4245     TRACE_AND_STEP();
4246     M.x86.R_IP = ip;
4247     M.x86.R_CS = cs;
4248     DECODE_CLEAR_SEGOVR();
4249     END_OF_INSTR();
4250 }
4251
4252 /****************************************************************************
4253 REMARKS:
4254 Handles opcode 0xeb
4255 ****************************************************************************/
4256 void x86emuOp_jump_byte_IMM(u8 X86EMU_UNUSED(op1))
4257 {
4258     u16 target;
4259     s8 offset;
4260
4261     START_OF_INSTR();
4262     DECODE_PRINTF("JMP\t");
4263     offset = (s8)fetch_byte_imm();
4264     target = (u16)(M.x86.R_IP + offset);
4265     DECODE_PRINTF2("%x\n", target);
4266     TRACE_AND_STEP();
4267     M.x86.R_IP = target;
4268     DECODE_CLEAR_SEGOVR();
4269     END_OF_INSTR();
4270 }
4271
4272 /****************************************************************************
4273 REMARKS:
4274 Handles opcode 0xec
4275 ****************************************************************************/
4276 void x86emuOp_in_byte_AL_DX(u8 X86EMU_UNUSED(op1))
4277 {
4278     START_OF_INSTR();
4279     DECODE_PRINTF("IN\tAL,DX\n");
4280     TRACE_AND_STEP();
4281     M.x86.R_AL = (*sys_inb)(M.x86.R_DX);
4282     DECODE_CLEAR_SEGOVR();
4283     END_OF_INSTR();
4284 }
4285
4286 /****************************************************************************
4287 REMARKS:
4288 Handles opcode 0xed
4289 ****************************************************************************/
4290 void x86emuOp_in_word_AX_DX(u8 X86EMU_UNUSED(op1))
4291 {
4292     START_OF_INSTR();
4293     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4294         DECODE_PRINTF("IN\tEAX,DX\n");
4295     } else {
4296         DECODE_PRINTF("IN\tAX,DX\n");
4297     }
4298     TRACE_AND_STEP();
4299     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4300         M.x86.R_EAX = (*sys_inl)(M.x86.R_DX);
4301     } else {
4302         M.x86.R_AX = (*sys_inw)(M.x86.R_DX);
4303     }
4304     DECODE_CLEAR_SEGOVR();
4305     END_OF_INSTR();
4306 }
4307
4308 /****************************************************************************
4309 REMARKS:
4310 Handles opcode 0xee
4311 ****************************************************************************/
4312 void x86emuOp_out_byte_DX_AL(u8 X86EMU_UNUSED(op1))
4313 {
4314     START_OF_INSTR();
4315     DECODE_PRINTF("OUT\tDX,AL\n");
4316     TRACE_AND_STEP();
4317     (*sys_outb)(M.x86.R_DX, M.x86.R_AL);
4318     DECODE_CLEAR_SEGOVR();
4319     END_OF_INSTR();
4320 }
4321
4322 /****************************************************************************
4323 REMARKS:
4324 Handles opcode 0xef
4325 ****************************************************************************/
4326 void x86emuOp_out_word_DX_AX(u8 X86EMU_UNUSED(op1))
4327 {
4328     START_OF_INSTR();
4329     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4330         DECODE_PRINTF("OUT\tDX,EAX\n");
4331     } else {
4332         DECODE_PRINTF("OUT\tDX,AX\n");
4333     }
4334     TRACE_AND_STEP();
4335     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4336         (*sys_outl)(M.x86.R_DX, M.x86.R_EAX);
4337     } else {
4338         (*sys_outw)(M.x86.R_DX, M.x86.R_AX);
4339     }
4340     DECODE_CLEAR_SEGOVR();
4341     END_OF_INSTR();
4342 }
4343
4344 /****************************************************************************
4345 REMARKS:
4346 Handles opcode 0xf0
4347 ****************************************************************************/
4348 void x86emuOp_lock(u8 X86EMU_UNUSED(op1))
4349 {
4350     START_OF_INSTR();
4351     DECODE_PRINTF("LOCK:\n");
4352     TRACE_AND_STEP();
4353     DECODE_CLEAR_SEGOVR();
4354     END_OF_INSTR();
4355 }
4356
4357 /*opcode 0xf1 ILLEGAL OPERATION */
4358
4359 /****************************************************************************
4360 REMARKS:
4361 Handles opcode 0xf2
4362 ****************************************************************************/
4363 void x86emuOp_repne(u8 X86EMU_UNUSED(op1))
4364 {
4365     START_OF_INSTR();
4366     DECODE_PRINTF("REPNE\n");
4367     TRACE_AND_STEP();
4368     M.x86.mode |= SYSMODE_PREFIX_REPNE;
4369     DECODE_CLEAR_SEGOVR();
4370     END_OF_INSTR();
4371 }
4372
4373 /****************************************************************************
4374 REMARKS:
4375 Handles opcode 0xf3
4376 ****************************************************************************/
4377 void x86emuOp_repe(u8 X86EMU_UNUSED(op1))
4378 {
4379     START_OF_INSTR();
4380     DECODE_PRINTF("REPE\n");
4381     TRACE_AND_STEP();
4382     M.x86.mode |= SYSMODE_PREFIX_REPE;
4383     DECODE_CLEAR_SEGOVR();
4384     END_OF_INSTR();
4385 }
4386
4387 /****************************************************************************
4388 REMARKS:
4389 Handles opcode 0xf4
4390 ****************************************************************************/
4391 void x86emuOp_halt(u8 X86EMU_UNUSED(op1))
4392 {
4393     START_OF_INSTR();
4394     DECODE_PRINTF("HALT\n");
4395     TRACE_AND_STEP();
4396     HALT_SYS();
4397     DECODE_CLEAR_SEGOVR();
4398     END_OF_INSTR();
4399 }
4400
4401 /****************************************************************************
4402 REMARKS:
4403 Handles opcode 0xf5
4404 ****************************************************************************/
4405 void x86emuOp_cmc(u8 X86EMU_UNUSED(op1))
4406 {
4407     /* complement the carry flag. */
4408     START_OF_INSTR();
4409     DECODE_PRINTF("CMC\n");
4410     TRACE_AND_STEP();
4411     TOGGLE_FLAG(F_CF);
4412     DECODE_CLEAR_SEGOVR();
4413     END_OF_INSTR();
4414 }
4415
4416 /****************************************************************************
4417 REMARKS:
4418 Handles opcode 0xf6
4419 ****************************************************************************/
4420 void x86emuOp_opcF6_byte_RM(u8 X86EMU_UNUSED(op1))
4421 {
4422     int mod, rl, rh;
4423     u8 *destreg;
4424     uint destoffset;
4425     u8 destval, srcval;
4426
4427     /* long, drawn out code follows.  Double switch for a total
4428        of 32 cases.  */
4429     START_OF_INSTR();
4430     FETCH_DECODE_MODRM(mod, rh, rl);
4431     DECODE_PRINTF(opF6_names[rh]);
4432     if (mod < 3) {
4433         DECODE_PRINTF("BYTE PTR ");
4434         destoffset = decode_rmXX_address(mod, rl);
4435         destval = fetch_data_byte(destoffset);
4436
4437         switch (rh) {
4438         case 0:         /* test byte imm */
4439             DECODE_PRINTF(",");
4440             srcval = fetch_byte_imm();
4441             DECODE_PRINTF2("%02x\n", srcval);
4442             TRACE_AND_STEP();
4443             test_byte(destval, srcval);
4444             break;
4445         case 1:
4446             DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n");
4447             HALT_SYS();
4448             break;
4449         case 2:
4450             DECODE_PRINTF("\n");
4451             TRACE_AND_STEP();
4452             destval = not_byte(destval);
4453             store_data_byte(destoffset, destval);
4454             break;
4455         case 3:
4456             DECODE_PRINTF("\n");
4457             TRACE_AND_STEP();
4458             destval = neg_byte(destval);
4459             store_data_byte(destoffset, destval);
4460             break;
4461         case 4:
4462             DECODE_PRINTF("\n");
4463             TRACE_AND_STEP();
4464             mul_byte(destval);
4465             break;
4466         case 5:
4467             DECODE_PRINTF("\n");
4468             TRACE_AND_STEP();
4469             imul_byte(destval);
4470             break;
4471         case 6:
4472             DECODE_PRINTF("\n");
4473             TRACE_AND_STEP();
4474             div_byte(destval);
4475             break;
4476         default:
4477             DECODE_PRINTF("\n");
4478             TRACE_AND_STEP();
4479             idiv_byte(destval);
4480             break;
4481         }
4482     } else {                     /* mod=11 */
4483         destreg = DECODE_RM_BYTE_REGISTER(rl);
4484         switch (rh) {
4485         case 0:         /* test byte imm */
4486             DECODE_PRINTF(",");
4487             srcval = fetch_byte_imm();
4488             DECODE_PRINTF2("%02x\n", srcval);
4489             TRACE_AND_STEP();
4490             test_byte(*destreg, srcval);
4491             break;
4492         case 1:
4493             DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n");
4494             HALT_SYS();
4495             break;
4496         case 2:
4497             DECODE_PRINTF("\n");
4498             TRACE_AND_STEP();
4499             *destreg = not_byte(*destreg);
4500             break;
4501         case 3:
4502             DECODE_PRINTF("\n");
4503             TRACE_AND_STEP();
4504             *destreg = neg_byte(*destreg);
4505             break;
4506         case 4:
4507             DECODE_PRINTF("\n");
4508             TRACE_AND_STEP();
4509             mul_byte(*destreg);      /*!!!  */
4510             break;
4511         case 5:
4512             DECODE_PRINTF("\n");
4513             TRACE_AND_STEP();
4514             imul_byte(*destreg);
4515             break;
4516         case 6:
4517             DECODE_PRINTF("\n");
4518             TRACE_AND_STEP();
4519             div_byte(*destreg);
4520             break;
4521         default:
4522             DECODE_PRINTF("\n");
4523             TRACE_AND_STEP();
4524             idiv_byte(*destreg);
4525             break;
4526         }
4527     }
4528     DECODE_CLEAR_SEGOVR();
4529     END_OF_INSTR();
4530 }
4531
4532 /****************************************************************************
4533 REMARKS:
4534 Handles opcode 0xf7
4535 ****************************************************************************/
4536 void x86emuOp_opcF7_word_RM(u8 X86EMU_UNUSED(op1))
4537 {
4538     int mod, rl, rh;
4539     uint destoffset;
4540
4541     START_OF_INSTR();
4542     FETCH_DECODE_MODRM(mod, rh, rl);
4543     DECODE_PRINTF(opF6_names[rh]);
4544     if (mod < 3) {
4545
4546         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4547             u32 destval, srcval;
4548
4549             DECODE_PRINTF("DWORD PTR ");
4550             destoffset = decode_rmXX_address(mod, rl);
4551             destval = fetch_data_long(destoffset);
4552
4553             switch (rh) {
4554             case 0:
4555                 DECODE_PRINTF(",");
4556                 srcval = fetch_long_imm();
4557                 DECODE_PRINTF2("%x\n", srcval);
4558                 TRACE_AND_STEP();
4559                 test_long(destval, srcval);
4560                 break;
4561             case 1:
4562                 DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F7\n");
4563                 HALT_SYS();
4564                 break;
4565             case 2:
4566                 DECODE_PRINTF("\n");
4567                 TRACE_AND_STEP();
4568                 destval = not_long(destval);
4569                 store_data_long(destoffset, destval);
4570                 break;
4571             case 3:
4572                 DECODE_PRINTF("\n");
4573                 TRACE_AND_STEP();
4574                 destval = neg_long(destval);
4575                 store_data_long(destoffset, destval);
4576                 break;
4577             case 4:
4578                 DECODE_PRINTF("\n");
4579                 TRACE_AND_STEP();
4580                 mul_long(destval);
4581                 break;
4582             case 5:
4583                 DECODE_PRINTF("\n");
4584                 TRACE_AND_STEP();
4585                 imul_long(destval);
4586                 break;
4587             case 6:
4588                 DECODE_PRINTF("\n");
4589                 TRACE_AND_STEP();
4590                 div_long(destval);
4591                 break;
4592             case 7:
4593                 DECODE_PRINTF("\n");
4594                 TRACE_AND_STEP();
4595                 idiv_long(destval);
4596                 break;
4597             }
4598         } else {
4599             u16 destval, srcval;
4600
4601             DECODE_PRINTF("WORD PTR ");
4602             destoffset = decode_rmXX_address(mod, rl);
4603             destval = fetch_data_word(destoffset);
4604
4605             switch (rh) {
4606             case 0:         /* test word imm */
4607                 DECODE_PRINTF(",");
4608                 srcval = fetch_word_imm();
4609                 DECODE_PRINTF2("%x\n", srcval);
4610                 TRACE_AND_STEP();
4611                 test_word(destval, srcval);
4612                 break;
4613             case 1:
4614                 DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F7\n");
4615                 HALT_SYS();
4616                 break;
4617             case 2:
4618                 DECODE_PRINTF("\n");
4619                 TRACE_AND_STEP();
4620                 destval = not_word(destval);
4621                 store_data_word(destoffset, destval);
4622                 break;
4623             case 3:
4624                 DECODE_PRINTF("\n");
4625                 TRACE_AND_STEP();
4626                 destval = neg_word(destval);
4627                 store_data_word(destoffset, destval);
4628                 break;
4629             case 4:
4630                 DECODE_PRINTF("\n");
4631                 TRACE_AND_STEP();
4632                 mul_word(destval);
4633                 break;
4634             case 5:
4635                 DECODE_PRINTF("\n");
4636                 TRACE_AND_STEP();
4637                 imul_word(destval);
4638                 break;
4639             case 6:
4640                 DECODE_PRINTF("\n");
4641                 TRACE_AND_STEP();
4642                 div_word(destval);
4643                 break;
4644             case 7:
4645                 DECODE_PRINTF("\n");
4646                 TRACE_AND_STEP();
4647                 idiv_word(destval);
4648                 break;
4649             }
4650         }
4651
4652     } else {                     /* mod=11 */
4653
4654         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4655             u32 *destreg;
4656             u32 srcval;
4657
4658             destreg = DECODE_RM_LONG_REGISTER(rl);
4659
4660             switch (rh) {
4661             case 0:         /* test word imm */
4662                 DECODE_PRINTF(",");
4663                 srcval = fetch_long_imm();
4664                 DECODE_PRINTF2("%x\n", srcval);
4665                 TRACE_AND_STEP();
4666                 test_long(*destreg, srcval);
4667                 break;
4668             case 1:
4669                 DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n");
4670                 HALT_SYS();
4671                 break;
4672             case 2:
4673                 DECODE_PRINTF("\n");
4674                 TRACE_AND_STEP();
4675                 *destreg = not_long(*destreg);
4676                 break;
4677             case 3:
4678                 DECODE_PRINTF("\n");
4679                 TRACE_AND_STEP();
4680                 *destreg = neg_long(*destreg);
4681                 break;
4682             case 4:
4683                 DECODE_PRINTF("\n");
4684                 TRACE_AND_STEP();
4685                 mul_long(*destreg);      /*!!!  */
4686                 break;
4687             case 5:
4688                 DECODE_PRINTF("\n");
4689                 TRACE_AND_STEP();
4690                 imul_long(*destreg);
4691                 break;
4692             case 6:
4693                 DECODE_PRINTF("\n");
4694                 TRACE_AND_STEP();
4695                 div_long(*destreg);
4696                 break;
4697             case 7:
4698                 DECODE_PRINTF("\n");
4699                 TRACE_AND_STEP();
4700                 idiv_long(*destreg);
4701                 break;
4702             }
4703         } else {
4704             u16 *destreg;
4705             u16 srcval;
4706
4707             destreg = DECODE_RM_WORD_REGISTER(rl);
4708
4709             switch (rh) {
4710             case 0:         /* test word imm */
4711                 DECODE_PRINTF(",");
4712                 srcval = fetch_word_imm();
4713                 DECODE_PRINTF2("%x\n", srcval);
4714                 TRACE_AND_STEP();
4715                 test_word(*destreg, srcval);
4716                 break;
4717             case 1:
4718                 DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n");
4719                 HALT_SYS();
4720                 break;
4721             case 2:
4722                 DECODE_PRINTF("\n");
4723                 TRACE_AND_STEP();
4724                 *destreg = not_word(*destreg);
4725                 break;
4726             case 3:
4727                 DECODE_PRINTF("\n");
4728                 TRACE_AND_STEP();
4729                 *destreg = neg_word(*destreg);
4730                 break;
4731             case 4:
4732                 DECODE_PRINTF("\n");
4733                 TRACE_AND_STEP();
4734                 mul_word(*destreg);      /*!!!  */
4735                 break;
4736             case 5:
4737                 DECODE_PRINTF("\n");
4738                 TRACE_AND_STEP();
4739                 imul_word(*destreg);
4740                 break;
4741             case 6:
4742                 DECODE_PRINTF("\n");
4743                 TRACE_AND_STEP();
4744                 div_word(*destreg);
4745                 break;
4746             case 7:
4747                 DECODE_PRINTF("\n");
4748                 TRACE_AND_STEP();
4749                 idiv_word(*destreg);
4750                 break;
4751             }
4752         }
4753     }
4754     DECODE_CLEAR_SEGOVR();
4755     END_OF_INSTR();
4756 }
4757
4758 /****************************************************************************
4759 REMARKS:
4760 Handles opcode 0xf8
4761 ****************************************************************************/
4762 void x86emuOp_clc(u8 X86EMU_UNUSED(op1))
4763 {
4764     /* clear the carry flag. */
4765     START_OF_INSTR();
4766     DECODE_PRINTF("CLC\n");
4767     TRACE_AND_STEP();
4768     CLEAR_FLAG(F_CF);
4769     DECODE_CLEAR_SEGOVR();
4770     END_OF_INSTR();
4771 }
4772
4773 /****************************************************************************
4774 REMARKS:
4775 Handles opcode 0xf9
4776 ****************************************************************************/
4777 void x86emuOp_stc(u8 X86EMU_UNUSED(op1))
4778 {
4779     /* set the carry flag. */
4780     START_OF_INSTR();
4781     DECODE_PRINTF("STC\n");
4782     TRACE_AND_STEP();
4783     SET_FLAG(F_CF);
4784     DECODE_CLEAR_SEGOVR();
4785     END_OF_INSTR();
4786 }
4787
4788 /****************************************************************************
4789 REMARKS:
4790 Handles opcode 0xfa
4791 ****************************************************************************/
4792 void x86emuOp_cli(u8 X86EMU_UNUSED(op1))
4793 {
4794     /* clear interrupts. */
4795     START_OF_INSTR();
4796     DECODE_PRINTF("CLI\n");
4797     TRACE_AND_STEP();
4798     CLEAR_FLAG(F_IF);
4799     DECODE_CLEAR_SEGOVR();
4800     END_OF_INSTR();
4801 }
4802
4803 /****************************************************************************
4804 REMARKS:
4805 Handles opcode 0xfb
4806 ****************************************************************************/
4807 void x86emuOp_sti(u8 X86EMU_UNUSED(op1))
4808 {
4809     /* enable  interrupts. */
4810     START_OF_INSTR();
4811     DECODE_PRINTF("STI\n");
4812     TRACE_AND_STEP();
4813     SET_FLAG(F_IF);
4814     DECODE_CLEAR_SEGOVR();
4815     END_OF_INSTR();
4816 }
4817
4818 /****************************************************************************
4819 REMARKS:
4820 Handles opcode 0xfc
4821 ****************************************************************************/
4822 void x86emuOp_cld(u8 X86EMU_UNUSED(op1))
4823 {
4824     /* clear interrupts. */
4825     START_OF_INSTR();
4826     DECODE_PRINTF("CLD\n");
4827     TRACE_AND_STEP();
4828     CLEAR_FLAG(F_DF);
4829     DECODE_CLEAR_SEGOVR();
4830     END_OF_INSTR();
4831 }
4832
4833 /****************************************************************************
4834 REMARKS:
4835 Handles opcode 0xfd
4836 ****************************************************************************/
4837 void x86emuOp_std(u8 X86EMU_UNUSED(op1))
4838 {
4839     /* clear interrupts. */
4840     START_OF_INSTR();
4841     DECODE_PRINTF("STD\n");
4842     TRACE_AND_STEP();
4843     SET_FLAG(F_DF);
4844     DECODE_CLEAR_SEGOVR();
4845     END_OF_INSTR();
4846 }
4847
4848 /****************************************************************************
4849 REMARKS:
4850 Handles opcode 0xfe
4851 ****************************************************************************/
4852 void x86emuOp_opcFE_byte_RM(u8 X86EMU_UNUSED(op1))
4853 {
4854     int mod, rh, rl;
4855     u8 destval;
4856     uint destoffset;
4857     u8 *destreg;
4858
4859     /* Yet another special case instruction. */
4860     START_OF_INSTR();
4861     FETCH_DECODE_MODRM(mod, rh, rl);
4862 #ifdef DEBUG
4863     if (DEBUG_DECODE()) {
4864         /* XXX DECODE_PRINTF may be changed to something more
4865            general, so that it is important to leave the strings
4866            in the same format, even though the result is that the
4867            above test is done twice. */
4868
4869         switch (rh) {
4870         case 0:
4871             DECODE_PRINTF("INC\t");
4872             break;
4873         case 1:
4874             DECODE_PRINTF("DEC\t");
4875             break;
4876         case 2:
4877         case 3:
4878         case 4:
4879         case 5:
4880         case 6:
4881         case 7:
4882             DECODE_PRINTF2("ILLEGAL OP MAJOR OP 0xFE MINOR OP %x \n", mod);
4883             HALT_SYS();
4884             break;
4885         }
4886     }
4887 #endif
4888     if (mod < 3) {
4889         DECODE_PRINTF("BYTE PTR ");
4890         destoffset = decode_rmXX_address(mod, rl);
4891         DECODE_PRINTF("\n");
4892         destval = fetch_data_byte(destoffset);
4893         TRACE_AND_STEP();
4894         if (rh == 0)
4895           destval = inc_byte(destval);
4896         else
4897           destval = dec_byte(destval);
4898         store_data_byte(destoffset, destval);
4899     } else {
4900         destreg = DECODE_RM_BYTE_REGISTER(rl);
4901         DECODE_PRINTF("\n");
4902         TRACE_AND_STEP();
4903         if (rh == 0)
4904           *destreg = inc_byte(*destreg);
4905         else
4906           *destreg = dec_byte(*destreg);
4907     }
4908     DECODE_CLEAR_SEGOVR();
4909     END_OF_INSTR();
4910 }
4911
4912 /****************************************************************************
4913 REMARKS:
4914 Handles opcode 0xff
4915 ****************************************************************************/
4916 void x86emuOp_opcFF_word_RM(u8 X86EMU_UNUSED(op1))
4917 {
4918     int mod, rh, rl;
4919     uint destoffset = 0;
4920         u16 *destreg;
4921         u16 destval,destval2;
4922
4923     /* Yet another special case instruction. */
4924     START_OF_INSTR();
4925     FETCH_DECODE_MODRM(mod, rh, rl);
4926 #ifdef DEBUG
4927     if (DEBUG_DECODE()) {
4928         /* XXX DECODE_PRINTF may be changed to something more
4929            general, so that it is important to leave the strings
4930            in the same format, even though the result is that the
4931            above test is done twice. */
4932
4933         switch (rh) {
4934         case 0:
4935             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4936                 DECODE_PRINTF("INC\tDWORD PTR ");
4937             } else {
4938                 DECODE_PRINTF("INC\tWORD PTR ");
4939             }
4940             break;
4941         case 1:
4942             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4943                 DECODE_PRINTF("DEC\tDWORD PTR ");
4944             } else {
4945                 DECODE_PRINTF("DEC\tWORD PTR ");
4946             }
4947             break;
4948         case 2:
4949             DECODE_PRINTF("CALL\t ");
4950             break;
4951         case 3:
4952             DECODE_PRINTF("CALL\tFAR ");
4953             break;
4954         case 4:
4955             DECODE_PRINTF("JMP\t");
4956             break;
4957         case 5:
4958             DECODE_PRINTF("JMP\tFAR ");
4959             break;
4960         case 6:
4961             DECODE_PRINTF("PUSH\t");
4962             break;
4963         case 7:
4964             DECODE_PRINTF("ILLEGAL DECODING OF OPCODE FF\t");
4965             HALT_SYS();
4966             break;
4967         }
4968     }
4969 #endif
4970     if (mod < 3) {
4971         destoffset = decode_rmXX_address(mod, rl);
4972         DECODE_PRINTF("\n");
4973         switch (rh) {
4974         case 0:         /* inc word ptr ... */
4975             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4976                 u32 destval;
4977
4978                 destval = fetch_data_long(destoffset);
4979                 TRACE_AND_STEP();
4980                 destval = inc_long(destval);
4981                 store_data_long(destoffset, destval);
4982             } else {
4983                 u16 destval;
4984
4985                 destval = fetch_data_word(destoffset);
4986                 TRACE_AND_STEP();
4987                 destval = inc_word(destval);
4988                 store_data_word(destoffset, destval);
4989             }
4990             break;
4991         case 1:         /* dec word ptr ... */
4992             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4993                 u32 destval;
4994
4995                 destval = fetch_data_long(destoffset);
4996                 TRACE_AND_STEP();
4997                 destval = dec_long(destval);
4998                 store_data_long(destoffset, destval);
4999             } else {
5000                 u16 destval;
5001
5002                 destval = fetch_data_word(destoffset);
5003                 TRACE_AND_STEP();
5004                 destval = dec_word(destval);
5005                 store_data_word(destoffset, destval);
5006             }
5007             break;
5008         case 2:         /* call word ptr ... */
5009             destval = fetch_data_word(destoffset);
5010             TRACE_AND_STEP();
5011             push_word(M.x86.R_IP);
5012             M.x86.R_IP = destval;
5013             break;
5014         case 3:         /* call far ptr ... */
5015             destval = fetch_data_word(destoffset);
5016             destval2 = fetch_data_word(destoffset + 2);
5017             TRACE_AND_STEP();
5018             push_word(M.x86.R_CS);
5019             M.x86.R_CS = destval2;
5020             push_word(M.x86.R_IP);
5021             M.x86.R_IP = destval;
5022             break;
5023         case 4:         /* jmp word ptr ... */
5024             destval = fetch_data_word(destoffset);
5025             TRACE_AND_STEP();
5026             M.x86.R_IP = destval;
5027             break;
5028         case 5:         /* jmp far ptr ... */
5029             destval = fetch_data_word(destoffset);
5030             destval2 = fetch_data_word(destoffset + 2);
5031             TRACE_AND_STEP();
5032             M.x86.R_IP = destval;
5033             M.x86.R_CS = destval2;
5034             break;
5035         case 6:         /*  push word ptr ... */
5036             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5037                 u32 destval;
5038
5039                 destval = fetch_data_long(destoffset);
5040                 TRACE_AND_STEP();
5041                 push_long(destval);
5042             } else {
5043                 u16 destval;
5044
5045                 destval = fetch_data_word(destoffset);
5046                 TRACE_AND_STEP();
5047                 push_word(destval);
5048             }
5049             break;
5050         }
5051     } else {
5052         switch (rh) {
5053         case 0:
5054             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5055                 u32 *destreg;
5056
5057                 destreg = DECODE_RM_LONG_REGISTER(rl);
5058                 DECODE_PRINTF("\n");
5059                 TRACE_AND_STEP();
5060                 *destreg = inc_long(*destreg);
5061             } else {
5062                 u16 *destreg;
5063
5064                 destreg = DECODE_RM_WORD_REGISTER(rl);
5065                 DECODE_PRINTF("\n");
5066                 TRACE_AND_STEP();
5067                 *destreg = inc_word(*destreg);
5068             }
5069             break;
5070         case 1:
5071             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5072                 u32 *destreg;
5073
5074                 destreg = DECODE_RM_LONG_REGISTER(rl);
5075                 DECODE_PRINTF("\n");
5076                 TRACE_AND_STEP();
5077                 *destreg = dec_long(*destreg);
5078             } else {
5079                 u16 *destreg;
5080
5081                 destreg = DECODE_RM_WORD_REGISTER(rl);
5082                 DECODE_PRINTF("\n");
5083                 TRACE_AND_STEP();
5084                 *destreg = dec_word(*destreg);
5085             }
5086             break;
5087         case 2:         /* call word ptr ... */
5088             destreg = DECODE_RM_WORD_REGISTER(rl);
5089             DECODE_PRINTF("\n");
5090             TRACE_AND_STEP();
5091             push_word(M.x86.R_IP);
5092             M.x86.R_IP = *destreg;
5093             break;
5094         case 3:         /* jmp far ptr ... */
5095             DECODE_PRINTF("OPERATION UNDEFINED 0XFF \n");
5096             TRACE_AND_STEP();
5097             HALT_SYS();
5098             break;
5099
5100         case 4:         /* jmp  ... */
5101             destreg = DECODE_RM_WORD_REGISTER(rl);
5102             DECODE_PRINTF("\n");
5103             TRACE_AND_STEP();
5104             M.x86.R_IP = (u16) (*destreg);
5105             break;
5106         case 5:         /* jmp far ptr ... */
5107             DECODE_PRINTF("OPERATION UNDEFINED 0XFF \n");
5108             TRACE_AND_STEP();
5109             HALT_SYS();
5110             break;
5111         case 6:
5112             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5113                 u32 *destreg;
5114
5115                 destreg = DECODE_RM_LONG_REGISTER(rl);
5116                 DECODE_PRINTF("\n");
5117                 TRACE_AND_STEP();
5118                 push_long(*destreg);
5119             } else {
5120                 u16 *destreg;
5121
5122                 destreg = DECODE_RM_WORD_REGISTER(rl);
5123                 DECODE_PRINTF("\n");
5124                 TRACE_AND_STEP();
5125                 push_word(*destreg);
5126             }
5127             break;
5128         }
5129     }
5130     DECODE_CLEAR_SEGOVR();
5131     END_OF_INSTR();
5132 }
5133
5134 /***************************************************************************
5135  * Single byte operation code table:
5136  **************************************************************************/
5137 void (*x86emu_optab[256])(u8) =
5138 {
5139 /*  0x00 */ x86emuOp_genop_byte_RM_R,
5140 /*  0x01 */ x86emuOp_genop_word_RM_R,
5141 /*  0x02 */ x86emuOp_genop_byte_R_RM,
5142 /*  0x03 */ x86emuOp_genop_word_R_RM,
5143 /*  0x04 */ x86emuOp_genop_byte_AL_IMM,
5144 /*  0x05 */ x86emuOp_genop_word_AX_IMM,
5145 /*  0x06 */ x86emuOp_push_ES,
5146 /*  0x07 */ x86emuOp_pop_ES,
5147
5148 /*  0x08 */ x86emuOp_genop_byte_RM_R,
5149 /*  0x09 */ x86emuOp_genop_word_RM_R,
5150 /*  0x0a */ x86emuOp_genop_byte_R_RM,
5151 /*  0x0b */ x86emuOp_genop_word_R_RM,
5152 /*  0x0c */ x86emuOp_genop_byte_AL_IMM,
5153 /*  0x0d */ x86emuOp_genop_word_AX_IMM,
5154 /*  0x0e */ x86emuOp_push_CS,
5155 /*  0x0f */ x86emuOp_two_byte,
5156
5157 /*  0x10 */ x86emuOp_genop_byte_RM_R,
5158 /*  0x11 */ x86emuOp_genop_word_RM_R,
5159 /*  0x12 */ x86emuOp_genop_byte_R_RM,
5160 /*  0x13 */ x86emuOp_genop_word_R_RM,
5161 /*  0x14 */ x86emuOp_genop_byte_AL_IMM,
5162 /*  0x15 */ x86emuOp_genop_word_AX_IMM,
5163 /*  0x16 */ x86emuOp_push_SS,
5164 /*  0x17 */ x86emuOp_pop_SS,
5165
5166 /*  0x18 */ x86emuOp_genop_byte_RM_R,
5167 /*  0x19 */ x86emuOp_genop_word_RM_R,
5168 /*  0x1a */ x86emuOp_genop_byte_R_RM,
5169 /*  0x1b */ x86emuOp_genop_word_R_RM,
5170 /*  0x1c */ x86emuOp_genop_byte_AL_IMM,
5171 /*  0x1d */ x86emuOp_genop_word_AX_IMM,
5172 /*  0x1e */ x86emuOp_push_DS,
5173 /*  0x1f */ x86emuOp_pop_DS,
5174
5175 /*  0x20 */ x86emuOp_genop_byte_RM_R,
5176 /*  0x21 */ x86emuOp_genop_word_RM_R,
5177 /*  0x22 */ x86emuOp_genop_byte_R_RM,
5178 /*  0x23 */ x86emuOp_genop_word_R_RM,
5179 /*  0x24 */ x86emuOp_genop_byte_AL_IMM,
5180 /*  0x25 */ x86emuOp_genop_word_AX_IMM,
5181 /*  0x26 */ x86emuOp_segovr_ES,
5182 /*  0x27 */ x86emuOp_daa,
5183
5184 /*  0x28 */ x86emuOp_genop_byte_RM_R,
5185 /*  0x29 */ x86emuOp_genop_word_RM_R,
5186 /*  0x2a */ x86emuOp_genop_byte_R_RM,
5187 /*  0x2b */ x86emuOp_genop_word_R_RM,
5188 /*  0x2c */ x86emuOp_genop_byte_AL_IMM,
5189 /*  0x2d */ x86emuOp_genop_word_AX_IMM,
5190 /*  0x2e */ x86emuOp_segovr_CS,
5191 /*  0x2f */ x86emuOp_das,
5192
5193 /*  0x30 */ x86emuOp_genop_byte_RM_R,
5194 /*  0x31 */ x86emuOp_genop_word_RM_R,
5195 /*  0x32 */ x86emuOp_genop_byte_R_RM,
5196 /*  0x33 */ x86emuOp_genop_word_R_RM,
5197 /*  0x34 */ x86emuOp_genop_byte_AL_IMM,
5198 /*  0x35 */ x86emuOp_genop_word_AX_IMM,
5199 /*  0x36 */ x86emuOp_segovr_SS,
5200 /*  0x37 */ x86emuOp_aaa,
5201
5202 /*  0x38 */ x86emuOp_genop_byte_RM_R,
5203 /*  0x39 */ x86emuOp_genop_word_RM_R,
5204 /*  0x3a */ x86emuOp_genop_byte_R_RM,
5205 /*  0x3b */ x86emuOp_genop_word_R_RM,
5206 /*  0x3c */ x86emuOp_genop_byte_AL_IMM,
5207 /*  0x3d */ x86emuOp_genop_word_AX_IMM,
5208 /*  0x3e */ x86emuOp_segovr_DS,
5209 /*  0x3f */ x86emuOp_aas,
5210
5211 /*  0x40 */ x86emuOp_inc_register,
5212 /*  0x41 */ x86emuOp_inc_register,
5213 /*  0x42 */ x86emuOp_inc_register,
5214 /*  0x43 */ x86emuOp_inc_register,
5215 /*  0x44 */ x86emuOp_inc_register,
5216 /*  0x45 */ x86emuOp_inc_register,
5217 /*  0x46 */ x86emuOp_inc_register,
5218 /*  0x47 */ x86emuOp_inc_register,
5219
5220 /*  0x48 */ x86emuOp_dec_register,
5221 /*  0x49 */ x86emuOp_dec_register,
5222 /*  0x4a */ x86emuOp_dec_register,
5223 /*  0x4b */ x86emuOp_dec_register,
5224 /*  0x4c */ x86emuOp_dec_register,
5225 /*  0x4d */ x86emuOp_dec_register,
5226 /*  0x4e */ x86emuOp_dec_register,
5227 /*  0x4f */ x86emuOp_dec_register,
5228
5229 /*  0x50 */ x86emuOp_push_register,
5230 /*  0x51 */ x86emuOp_push_register,
5231 /*  0x52 */ x86emuOp_push_register,
5232 /*  0x53 */ x86emuOp_push_register,
5233 /*  0x54 */ x86emuOp_push_register,
5234 /*  0x55 */ x86emuOp_push_register,
5235 /*  0x56 */ x86emuOp_push_register,
5236 /*  0x57 */ x86emuOp_push_register,
5237
5238 /*  0x58 */ x86emuOp_pop_register,
5239 /*  0x59 */ x86emuOp_pop_register,
5240 /*  0x5a */ x86emuOp_pop_register,
5241 /*  0x5b */ x86emuOp_pop_register,
5242 /*  0x5c */ x86emuOp_pop_register,
5243 /*  0x5d */ x86emuOp_pop_register,
5244 /*  0x5e */ x86emuOp_pop_register,
5245 /*  0x5f */ x86emuOp_pop_register,
5246
5247 /*  0x60 */ x86emuOp_push_all,
5248 /*  0x61 */ x86emuOp_pop_all,
5249 /*  0x62 */ x86emuOp_illegal_op,   /* bound */
5250 /*  0x63 */ x86emuOp_illegal_op,   /* arpl */
5251 /*  0x64 */ x86emuOp_segovr_FS,
5252 /*  0x65 */ x86emuOp_segovr_GS,
5253 /*  0x66 */ x86emuOp_prefix_data,
5254 /*  0x67 */ x86emuOp_prefix_addr,
5255
5256 /*  0x68 */ x86emuOp_push_word_IMM,
5257 /*  0x69 */ x86emuOp_imul_word_IMM,
5258 /*  0x6a */ x86emuOp_push_byte_IMM,
5259 /*  0x6b */ x86emuOp_imul_byte_IMM,
5260 /*  0x6c */ x86emuOp_ins_byte,
5261 /*  0x6d */ x86emuOp_ins_word,
5262 /*  0x6e */ x86emuOp_outs_byte,
5263 /*  0x6f */ x86emuOp_outs_word,
5264
5265 /*  0x70 */ x86emuOp_jump_near_cond,
5266 /*  0x71 */ x86emuOp_jump_near_cond,
5267 /*  0x72 */ x86emuOp_jump_near_cond,
5268 /*  0x73 */ x86emuOp_jump_near_cond,
5269 /*  0x74 */ x86emuOp_jump_near_cond,
5270 /*  0x75 */ x86emuOp_jump_near_cond,
5271 /*  0x76 */ x86emuOp_jump_near_cond,
5272 /*  0x77 */ x86emuOp_jump_near_cond,
5273
5274 /*  0x78 */ x86emuOp_jump_near_cond,
5275 /*  0x79 */ x86emuOp_jump_near_cond,
5276 /*  0x7a */ x86emuOp_jump_near_cond,
5277 /*  0x7b */ x86emuOp_jump_near_cond,
5278 /*  0x7c */ x86emuOp_jump_near_cond,
5279 /*  0x7d */ x86emuOp_jump_near_cond,
5280 /*  0x7e */ x86emuOp_jump_near_cond,
5281 /*  0x7f */ x86emuOp_jump_near_cond,
5282
5283 /*  0x80 */ x86emuOp_opc80_byte_RM_IMM,
5284 /*  0x81 */ x86emuOp_opc81_word_RM_IMM,
5285 /*  0x82 */ x86emuOp_opc82_byte_RM_IMM,
5286 /*  0x83 */ x86emuOp_opc83_word_RM_IMM,
5287 /*  0x84 */ x86emuOp_test_byte_RM_R,
5288 /*  0x85 */ x86emuOp_test_word_RM_R,
5289 /*  0x86 */ x86emuOp_xchg_byte_RM_R,
5290 /*  0x87 */ x86emuOp_xchg_word_RM_R,
5291
5292 /*  0x88 */ x86emuOp_mov_byte_RM_R,
5293 /*  0x89 */ x86emuOp_mov_word_RM_R,
5294 /*  0x8a */ x86emuOp_mov_byte_R_RM,
5295 /*  0x8b */ x86emuOp_mov_word_R_RM,
5296 /*  0x8c */ x86emuOp_mov_word_RM_SR,
5297 /*  0x8d */ x86emuOp_lea_word_R_M,
5298 /*  0x8e */ x86emuOp_mov_word_SR_RM,
5299 /*  0x8f */ x86emuOp_pop_RM,
5300
5301 /*  0x90 */ x86emuOp_nop,
5302 /*  0x91 */ x86emuOp_xchg_word_AX_register,
5303 /*  0x92 */ x86emuOp_xchg_word_AX_register,
5304 /*  0x93 */ x86emuOp_xchg_word_AX_register,
5305 /*  0x94 */ x86emuOp_xchg_word_AX_register,
5306 /*  0x95 */ x86emuOp_xchg_word_AX_register,
5307 /*  0x96 */ x86emuOp_xchg_word_AX_register,
5308 /*  0x97 */ x86emuOp_xchg_word_AX_register,
5309
5310 /*  0x98 */ x86emuOp_cbw,
5311 /*  0x99 */ x86emuOp_cwd,
5312 /*  0x9a */ x86emuOp_call_far_IMM,
5313 /*  0x9b */ x86emuOp_wait,
5314 /*  0x9c */ x86emuOp_pushf_word,
5315 /*  0x9d */ x86emuOp_popf_word,
5316 /*  0x9e */ x86emuOp_sahf,
5317 /*  0x9f */ x86emuOp_lahf,
5318
5319 /*  0xa0 */ x86emuOp_mov_AL_M_IMM,
5320 /*  0xa1 */ x86emuOp_mov_AX_M_IMM,
5321 /*  0xa2 */ x86emuOp_mov_M_AL_IMM,
5322 /*  0xa3 */ x86emuOp_mov_M_AX_IMM,
5323 /*  0xa4 */ x86emuOp_movs_byte,
5324 /*  0xa5 */ x86emuOp_movs_word,
5325 /*  0xa6 */ x86emuOp_cmps_byte,
5326 /*  0xa7 */ x86emuOp_cmps_word,
5327 /*  0xa8 */ x86emuOp_test_AL_IMM,
5328 /*  0xa9 */ x86emuOp_test_AX_IMM,
5329 /*  0xaa */ x86emuOp_stos_byte,
5330 /*  0xab */ x86emuOp_stos_word,
5331 /*  0xac */ x86emuOp_lods_byte,
5332 /*  0xad */ x86emuOp_lods_word,
5333 /*  0xac */ x86emuOp_scas_byte,
5334 /*  0xad */ x86emuOp_scas_word,
5335
5336 /*  0xb0 */ x86emuOp_mov_byte_register_IMM,
5337 /*  0xb1 */ x86emuOp_mov_byte_register_IMM,
5338 /*  0xb2 */ x86emuOp_mov_byte_register_IMM,
5339 /*  0xb3 */ x86emuOp_mov_byte_register_IMM,
5340 /*  0xb4 */ x86emuOp_mov_byte_register_IMM,
5341 /*  0xb5 */ x86emuOp_mov_byte_register_IMM,
5342 /*  0xb6 */ x86emuOp_mov_byte_register_IMM,
5343 /*  0xb7 */ x86emuOp_mov_byte_register_IMM,
5344
5345 /*  0xb8 */ x86emuOp_mov_word_register_IMM,
5346 /*  0xb9 */ x86emuOp_mov_word_register_IMM,
5347 /*  0xba */ x86emuOp_mov_word_register_IMM,
5348 /*  0xbb */ x86emuOp_mov_word_register_IMM,
5349 /*  0xbc */ x86emuOp_mov_word_register_IMM,
5350 /*  0xbd */ x86emuOp_mov_word_register_IMM,
5351 /*  0xbe */ x86emuOp_mov_word_register_IMM,
5352 /*  0xbf */ x86emuOp_mov_word_register_IMM,
5353
5354 /*  0xc0 */ x86emuOp_opcC0_byte_RM_MEM,
5355 /*  0xc1 */ x86emuOp_opcC1_word_RM_MEM,
5356 /*  0xc2 */ x86emuOp_ret_near_IMM,
5357 /*  0xc3 */ x86emuOp_ret_near,
5358 /*  0xc4 */ x86emuOp_les_R_IMM,
5359 /*  0xc5 */ x86emuOp_lds_R_IMM,
5360 /*  0xc6 */ x86emuOp_mov_byte_RM_IMM,
5361 /*  0xc7 */ x86emuOp_mov_word_RM_IMM,
5362 /*  0xc8 */ x86emuOp_enter,
5363 /*  0xc9 */ x86emuOp_leave,
5364 /*  0xca */ x86emuOp_ret_far_IMM,
5365 /*  0xcb */ x86emuOp_ret_far,
5366 /*  0xcc */ x86emuOp_int3,
5367 /*  0xcd */ x86emuOp_int_IMM,
5368 /*  0xce */ x86emuOp_into,
5369 /*  0xcf */ x86emuOp_iret,
5370
5371 /*  0xd0 */ x86emuOp_opcD0_byte_RM_1,
5372 /*  0xd1 */ x86emuOp_opcD1_word_RM_1,
5373 /*  0xd2 */ x86emuOp_opcD2_byte_RM_CL,
5374 /*  0xd3 */ x86emuOp_opcD3_word_RM_CL,
5375 /*  0xd4 */ x86emuOp_aam,
5376 /*  0xd5 */ x86emuOp_aad,
5377 /*  0xd6 */ x86emuOp_illegal_op,   /* Undocumented SETALC instruction */
5378 /*  0xd7 */ x86emuOp_xlat,
5379 /*  0xd8 */ NULL, /*x86emuOp_esc_coprocess_d8,*/
5380 /*  0xd9 */ NULL, /*x86emuOp_esc_coprocess_d9,*/
5381 /*  0xda */ NULL, /*x86emuOp_esc_coprocess_da,*/
5382 /*  0xdb */ NULL, /*x86emuOp_esc_coprocess_db,*/
5383 /*  0xdc */ NULL, /*x86emuOp_esc_coprocess_dc,*/
5384 /*  0xdd */ NULL, /*x86emuOp_esc_coprocess_dd,*/
5385 /*  0xde */ NULL, /*x86emuOp_esc_coprocess_de,*/
5386 /*  0xdf */ NULL, /*x86emuOp_esc_coprocess_df,*/
5387
5388 /*  0xe0 */ x86emuOp_loopne,
5389 /*  0xe1 */ x86emuOp_loope,
5390 /*  0xe2 */ x86emuOp_loop,
5391 /*  0xe3 */ x86emuOp_jcxz,
5392 /*  0xe4 */ x86emuOp_in_byte_AL_IMM,
5393 /*  0xe5 */ x86emuOp_in_word_AX_IMM,
5394 /*  0xe6 */ x86emuOp_out_byte_IMM_AL,
5395 /*  0xe7 */ x86emuOp_out_word_IMM_AX,
5396
5397 /*  0xe8 */ x86emuOp_call_near_IMM,
5398 /*  0xe9 */ x86emuOp_jump_near_IMM,
5399 /*  0xea */ x86emuOp_jump_far_IMM,
5400 /*  0xeb */ x86emuOp_jump_byte_IMM,
5401 /*  0xec */ x86emuOp_in_byte_AL_DX,
5402 /*  0xed */ x86emuOp_in_word_AX_DX,
5403 /*  0xee */ x86emuOp_out_byte_DX_AL,
5404 /*  0xef */ x86emuOp_out_word_DX_AX,
5405
5406 /*  0xf0 */ x86emuOp_lock,
5407 /*  0xf1 */ x86emuOp_illegal_op,
5408 /*  0xf2 */ x86emuOp_repne,
5409 /*  0xf3 */ x86emuOp_repe,
5410 /*  0xf4 */ x86emuOp_halt,
5411 /*  0xf5 */ x86emuOp_cmc,
5412 /*  0xf6 */ x86emuOp_opcF6_byte_RM,
5413 /*  0xf7 */ x86emuOp_opcF7_word_RM,
5414
5415 /*  0xf8 */ x86emuOp_clc,
5416 /*  0xf9 */ x86emuOp_stc,
5417 /*  0xfa */ x86emuOp_cli,
5418 /*  0xfb */ x86emuOp_sti,
5419 /*  0xfc */ x86emuOp_cld,
5420 /*  0xfd */ x86emuOp_std,
5421 /*  0xfe */ x86emuOp_opcFE_byte_RM,
5422 /*  0xff */ x86emuOp_opcFF_word_RM,
5423 };