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