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