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