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