]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - board/MAI/bios_emulator/scitech/src/x86emu/ops.c
* Patch by Thomas Frieden, 13 Nov 2002:
[karo-tx-uboot.git] / board / MAI / bios_emulator / scitech / src / x86emu / ops.c
1 /****************************************************************************
2 *
3 *                                               Realmode X86 Emulator Library
4 *
5 *               Copyright (C) 1996-1999 SciTech Software, Inc.
6 *                                    Copyright (C) David Mosberger-Tang
7 *                                          Copyright (C) 1999 Egbert Eich
8 *
9 *  ========================================================================
10 *
11 *  Permission to use, copy, modify, distribute, and sell this software and
12 *  its documentation for any purpose is hereby granted without fee,
13 *  provided that the above copyright notice appear in all copies and that
14 *  both that copyright notice and this permission notice appear in
15 *  supporting documentation, and that the name of the authors not be used
16 *  in advertising or publicity pertaining to distribution of the software
17 *  without specific, written prior permission.  The authors makes no
18 *  representations about the suitability of this software for any purpose.
19 *  It is provided "as is" without express or implied warranty.
20 *
21 *  THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
22 *  INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
23 *  EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
24 *  CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
25 *  USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
26 *  OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
27 *  PERFORMANCE OF THIS SOFTWARE.
28 *
29 *  ========================================================================
30 *
31 * Language:             ANSI C
32 * Environment:  Any
33 * Developer:    Kendall Bennett
34 *
35 * Description:  This file includes subroutines to implement the decoding
36 *               and emulation of all the x86 processor instructions.
37 *
38 * There are approximately 250 subroutines in here, which correspond
39 * to the 256 byte-"opcodes" found on the 8086.  The table which
40 * dispatches this is found in the files optab.[ch].
41 *
42 * Each opcode proc has a comment preceeding it which gives it's table
43 * address.  Several opcodes are missing (undefined) in the table.
44 *
45 * Each proc includes information for decoding (DECODE_PRINTF and
46 * DECODE_PRINTF2), debugging (TRACE_REGS, SINGLE_STEP), and misc
47 * functions (START_OF_INSTR, END_OF_INSTR).
48 *
49 * Many of the procedures are *VERY* similar in coding.  This has
50 * allowed for a very large amount of code to be generated in a fairly
51 * short amount of time (i.e. cut, paste, and modify).  The result is
52 * that much of the code below could have been folded into subroutines
53 * for a large reduction in size of this file.  The downside would be
54 * that there would be a penalty in execution speed.  The file could
55 * also have been *MUCH* larger by inlining certain functions which
56 * were called.  This could have resulted even faster execution.  The
57 * prime directive I used to decide whether to inline the code or to
58 * modularize it, was basically: 1) no unnecessary subroutine calls,
59 * 2) no routines more than about 200 lines in size, and 3) modularize
60 * any code that I might not get right the first time.  The fetch_*
61 * subroutines fall into the latter category.  The The decode_* fall
62 * into the second category.  The coding of the "switch(mod){ .... }"
63 * in many of the subroutines below falls into the first category.
64 * Especially, the coding of {add,and,or,sub,...}_{byte,word}
65 * subroutines are an especially glaring case of the third guideline.
66 * Since so much of the code is cloned from other modules (compare
67 * opcode #00 to opcode #01), making the basic operations subroutine
68 * calls is especially important; otherwise mistakes in coding an
69 * "add" would represent a nightmare in maintenance.
70 *
71 ****************************************************************************/
72
73 #include "x86emu/x86emui.h"
74
75 /*----------------------------- Implementation ----------------------------*/
76
77 /****************************************************************************
78 PARAMETERS:
79 op1 - Instruction op code
80
81 REMARKS:
82 Handles illegal opcodes.
83 ****************************************************************************/
84 void x86emuOp_illegal_op(
85     u8 op1)
86 {
87     START_OF_INSTR();
88     DECODE_PRINTF("ILLEGAL X86 OPCODE\n");
89     TRACE_REGS();
90     printk("%04x:%04x: %02X ILLEGAL X86 OPCODE!\n",
91         M.x86.R_CS, M.x86.R_IP-1,op1);
92     HALT_SYS();
93     END_OF_INSTR();
94 }
95
96 /****************************************************************************
97 REMARKS:
98 Handles opcode 0x00
99 ****************************************************************************/
100 void x86emuOp_add_byte_RM_R(u8 X86EMU_UNUSED(op1))
101 {
102     int mod, rl, rh;
103     uint destoffset;
104     u8 *destreg, *srcreg;
105     u8 destval;
106
107     START_OF_INSTR();
108     DECODE_PRINTF("ADD\t");
109     FETCH_DECODE_MODRM(mod, rh, rl);
110     switch (mod) {
111     case 0:
112         destoffset = decode_rm00_address(rl);
113         DECODE_PRINTF(",");
114         destval = fetch_data_byte(destoffset);
115         srcreg = DECODE_RM_BYTE_REGISTER(rh);
116         DECODE_PRINTF("\n");
117         TRACE_AND_STEP();
118         destval = add_byte(destval, *srcreg);
119         store_data_byte(destoffset, destval);
120         break;
121     case 1:
122         destoffset = decode_rm01_address(rl);
123         DECODE_PRINTF(",");
124         destval = fetch_data_byte(destoffset);
125         srcreg = DECODE_RM_BYTE_REGISTER(rh);
126         DECODE_PRINTF("\n");
127         TRACE_AND_STEP();
128         destval = add_byte(destval, *srcreg);
129         store_data_byte(destoffset, destval);
130         break;
131     case 2:
132         destoffset = decode_rm10_address(rl);
133         DECODE_PRINTF(",");
134         destval = fetch_data_byte(destoffset);
135         srcreg = DECODE_RM_BYTE_REGISTER(rh);
136         DECODE_PRINTF("\n");
137         TRACE_AND_STEP();
138         destval = add_byte(destval, *srcreg);
139         store_data_byte(destoffset, destval);
140         break;
141     case 3:                     /* register to register */
142         destreg = DECODE_RM_BYTE_REGISTER(rl);
143         DECODE_PRINTF(",");
144         srcreg = DECODE_RM_BYTE_REGISTER(rh);
145         DECODE_PRINTF("\n");
146         TRACE_AND_STEP();
147         *destreg = add_byte(*destreg, *srcreg);
148         break;
149     }
150     DECODE_CLEAR_SEGOVR();
151     END_OF_INSTR();
152 }
153
154 /****************************************************************************
155 REMARKS:
156 Handles opcode 0x01
157 ****************************************************************************/
158 void x86emuOp_add_word_RM_R(u8 X86EMU_UNUSED(op1))
159 {
160     int mod, rl, rh;
161     uint destoffset;
162
163     START_OF_INSTR();
164     DECODE_PRINTF("ADD\t");
165     FETCH_DECODE_MODRM(mod, rh, rl);
166     switch (mod) {
167     case 0:
168         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
169             u32 destval;
170             u32 *srcreg;
171
172             destoffset = decode_rm00_address(rl);
173             DECODE_PRINTF(",");
174             destval = fetch_data_long(destoffset);
175             srcreg = DECODE_RM_LONG_REGISTER(rh);
176             DECODE_PRINTF("\n");
177             TRACE_AND_STEP();
178             destval = add_long(destval, *srcreg);
179             store_data_long(destoffset, destval);
180         } else {
181             u16 destval;
182             u16 *srcreg;
183
184             destoffset = decode_rm00_address(rl);
185             DECODE_PRINTF(",");
186             destval = fetch_data_word(destoffset);
187             srcreg = DECODE_RM_WORD_REGISTER(rh);
188             DECODE_PRINTF("\n");
189             TRACE_AND_STEP();
190             destval = add_word(destval, *srcreg);
191             store_data_word(destoffset, destval);
192         }
193         break;
194     case 1:
195         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
196             u32 destval;
197             u32 *srcreg;
198
199             destoffset = decode_rm01_address(rl);
200             DECODE_PRINTF(",");
201             destval = fetch_data_long(destoffset);
202             srcreg = DECODE_RM_LONG_REGISTER(rh);
203             DECODE_PRINTF("\n");
204             TRACE_AND_STEP();
205             destval = add_long(destval, *srcreg);
206             store_data_long(destoffset, destval);
207         } else {
208             u16 destval;
209             u16 *srcreg;
210
211             destoffset = decode_rm01_address(rl);
212             DECODE_PRINTF(",");
213             destval = fetch_data_word(destoffset);
214             srcreg = DECODE_RM_WORD_REGISTER(rh);
215             DECODE_PRINTF("\n");
216             TRACE_AND_STEP();
217             destval = add_word(destval, *srcreg);
218             store_data_word(destoffset, destval);
219         }
220         break;
221     case 2:
222         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
223             u32 destval;
224             u32 *srcreg;
225
226             destoffset = decode_rm10_address(rl);
227             DECODE_PRINTF(",");
228             destval = fetch_data_long(destoffset);
229             srcreg = DECODE_RM_LONG_REGISTER(rh);
230             DECODE_PRINTF("\n");
231             TRACE_AND_STEP();
232             destval = add_long(destval, *srcreg);
233             store_data_long(destoffset, destval);
234         } else {
235             u16 destval;
236             u16 *srcreg;
237
238             destoffset = decode_rm10_address(rl);
239             DECODE_PRINTF(",");
240             destval = fetch_data_word(destoffset);
241             srcreg = DECODE_RM_WORD_REGISTER(rh);
242             DECODE_PRINTF("\n");
243             TRACE_AND_STEP();
244             destval = add_word(destval, *srcreg);
245             store_data_word(destoffset, destval);
246         }
247         break;
248     case 3:                     /* register to register */
249         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
250             u32 *destreg,*srcreg;
251
252             destreg = DECODE_RM_LONG_REGISTER(rl);
253             DECODE_PRINTF(",");
254             srcreg = DECODE_RM_LONG_REGISTER(rh);
255             DECODE_PRINTF("\n");
256             TRACE_AND_STEP();
257             *destreg = add_long(*destreg, *srcreg);
258         } else {
259             u16 *destreg,*srcreg;
260
261             destreg = DECODE_RM_WORD_REGISTER(rl);
262             DECODE_PRINTF(",");
263             srcreg = DECODE_RM_WORD_REGISTER(rh);
264             DECODE_PRINTF("\n");
265             TRACE_AND_STEP();
266             *destreg = add_word(*destreg, *srcreg);
267         }
268         break;
269     }
270     DECODE_CLEAR_SEGOVR();
271     END_OF_INSTR();
272 }
273
274 /****************************************************************************
275 REMARKS:
276 Handles opcode 0x02
277 ****************************************************************************/
278 void x86emuOp_add_byte_R_RM(u8 X86EMU_UNUSED(op1))
279 {
280     int mod, rl, rh;
281     u8 *destreg, *srcreg;
282     uint srcoffset;
283     u8 srcval;
284
285     START_OF_INSTR();
286     DECODE_PRINTF("ADD\t");
287     FETCH_DECODE_MODRM(mod, rh, rl);
288     switch (mod) {
289     case 0:
290         destreg = DECODE_RM_BYTE_REGISTER(rh);
291         DECODE_PRINTF(",");
292         srcoffset = decode_rm00_address(rl);
293         srcval = fetch_data_byte(srcoffset);
294         DECODE_PRINTF("\n");
295         TRACE_AND_STEP();
296         *destreg = add_byte(*destreg, srcval);
297         break;
298     case 1:
299         destreg = DECODE_RM_BYTE_REGISTER(rh);
300         DECODE_PRINTF(",");
301         srcoffset = decode_rm01_address(rl);
302         srcval = fetch_data_byte(srcoffset);
303         DECODE_PRINTF("\n");
304         TRACE_AND_STEP();
305         *destreg = add_byte(*destreg, srcval);
306         break;
307     case 2:
308         destreg = DECODE_RM_BYTE_REGISTER(rh);
309         DECODE_PRINTF(",");
310         srcoffset = decode_rm10_address(rl);
311         srcval = fetch_data_byte(srcoffset);
312         DECODE_PRINTF("\n");
313         TRACE_AND_STEP();
314         *destreg = add_byte(*destreg, srcval);
315         break;
316     case 3:                     /* register to register */
317         destreg = DECODE_RM_BYTE_REGISTER(rh);
318         DECODE_PRINTF(",");
319         srcreg = DECODE_RM_BYTE_REGISTER(rl);
320         DECODE_PRINTF("\n");
321         TRACE_AND_STEP();
322         *destreg = add_byte(*destreg, *srcreg);
323         break;
324     }
325     DECODE_CLEAR_SEGOVR();
326     END_OF_INSTR();
327 }
328
329 /****************************************************************************
330 REMARKS:
331 Handles opcode 0x03
332 ****************************************************************************/
333 void x86emuOp_add_word_R_RM(u8 X86EMU_UNUSED(op1))
334 {
335     int mod, rl, rh;
336     uint srcoffset;
337
338     START_OF_INSTR();
339     DECODE_PRINTF("ADD\t");
340     FETCH_DECODE_MODRM(mod, rh, rl);
341     switch (mod) {
342     case 0:
343         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
344             u32 *destreg;
345             u32 srcval;
346
347             destreg = DECODE_RM_LONG_REGISTER(rh);
348             DECODE_PRINTF(",");
349             srcoffset = decode_rm00_address(rl);
350             srcval = fetch_data_long(srcoffset);
351             DECODE_PRINTF("\n");
352             TRACE_AND_STEP();
353             *destreg = add_long(*destreg, srcval);
354         } else {
355             u16 *destreg;
356             u16 srcval;
357
358             destreg = DECODE_RM_WORD_REGISTER(rh);
359             DECODE_PRINTF(",");
360             srcoffset = decode_rm00_address(rl);
361             srcval = fetch_data_word(srcoffset);
362             DECODE_PRINTF("\n");
363             TRACE_AND_STEP();
364             *destreg = add_word(*destreg, srcval);
365         }
366         break;
367     case 1:
368         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
369             u32 *destreg;
370             u32 srcval;
371
372             destreg = DECODE_RM_LONG_REGISTER(rh);
373             DECODE_PRINTF(",");
374             srcoffset = decode_rm01_address(rl);
375             srcval = fetch_data_long(srcoffset);
376             DECODE_PRINTF("\n");
377             TRACE_AND_STEP();
378             *destreg = add_long(*destreg, srcval);
379         } else {
380             u16 *destreg;
381             u16 srcval;
382
383             destreg = DECODE_RM_WORD_REGISTER(rh);
384             DECODE_PRINTF(",");
385             srcoffset = decode_rm01_address(rl);
386             srcval = fetch_data_word(srcoffset);
387             DECODE_PRINTF("\n");
388             TRACE_AND_STEP();
389             *destreg = add_word(*destreg, srcval);
390         }
391         break;
392     case 2:
393         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
394             u32 *destreg;
395             u32 srcval;
396
397             destreg = DECODE_RM_LONG_REGISTER(rh);
398             DECODE_PRINTF(",");
399             srcoffset = decode_rm10_address(rl);
400             srcval = fetch_data_long(srcoffset);
401             DECODE_PRINTF("\n");
402             TRACE_AND_STEP();
403             *destreg = add_long(*destreg, srcval);
404         } else {
405             u16 *destreg;
406             u16 srcval;
407
408             destreg = DECODE_RM_WORD_REGISTER(rh);
409             DECODE_PRINTF(",");
410             srcoffset = decode_rm10_address(rl);
411             srcval = fetch_data_word(srcoffset);
412             DECODE_PRINTF("\n");
413             TRACE_AND_STEP();
414             *destreg = add_word(*destreg, srcval);
415         }
416         break;
417     case 3:                     /* register to register */
418         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
419             u32 *destreg,*srcreg;
420
421             destreg = DECODE_RM_LONG_REGISTER(rh);
422             DECODE_PRINTF(",");
423             srcreg = DECODE_RM_LONG_REGISTER(rl);
424             DECODE_PRINTF("\n");
425             TRACE_AND_STEP();
426             *destreg = add_long(*destreg, *srcreg);
427         } else {
428             u16 *destreg,*srcreg;
429
430             destreg = DECODE_RM_WORD_REGISTER(rh);
431             DECODE_PRINTF(",");
432             srcreg = DECODE_RM_WORD_REGISTER(rl);
433             DECODE_PRINTF("\n");
434             TRACE_AND_STEP();
435             *destreg = add_word(*destreg, *srcreg);
436         }
437         break;
438     }
439     DECODE_CLEAR_SEGOVR();
440     END_OF_INSTR();
441 }
442
443 /****************************************************************************
444 REMARKS:
445 Handles opcode 0x04
446 ****************************************************************************/
447 void x86emuOp_add_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
448 {
449     u8 srcval;
450
451     START_OF_INSTR();
452     DECODE_PRINTF("ADD\tAL,");
453     srcval = fetch_byte_imm();
454     DECODE_PRINTF2("%x\n", srcval);
455     TRACE_AND_STEP();
456     M.x86.R_AL = add_byte(M.x86.R_AL, srcval);
457     DECODE_CLEAR_SEGOVR();
458     END_OF_INSTR();
459 }
460
461 /****************************************************************************
462 REMARKS:
463 Handles opcode 0x05
464 ****************************************************************************/
465 void x86emuOp_add_word_AX_IMM(u8 X86EMU_UNUSED(op1))
466 {
467     u32 srcval;
468
469     START_OF_INSTR();
470     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
471         DECODE_PRINTF("ADD\tEAX,");
472         srcval = fetch_long_imm();
473     } else {
474         DECODE_PRINTF("ADD\tAX,");
475         srcval = fetch_word_imm();
476     }
477     DECODE_PRINTF2("%x\n", srcval);
478     TRACE_AND_STEP();
479     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
480         M.x86.R_EAX = add_long(M.x86.R_EAX, srcval);
481     } else {
482         M.x86.R_AX = add_word(M.x86.R_AX, (u16)srcval);
483     }
484     DECODE_CLEAR_SEGOVR();
485     END_OF_INSTR();
486 }
487
488 /****************************************************************************
489 REMARKS:
490 Handles opcode 0x06
491 ****************************************************************************/
492 void x86emuOp_push_ES(u8 X86EMU_UNUSED(op1))
493 {
494     START_OF_INSTR();
495     DECODE_PRINTF("PUSH\tES\n");
496     TRACE_AND_STEP();
497     push_word(M.x86.R_ES);
498     DECODE_CLEAR_SEGOVR();
499     END_OF_INSTR();
500 }
501
502 /****************************************************************************
503 REMARKS:
504 Handles opcode 0x07
505 ****************************************************************************/
506 void x86emuOp_pop_ES(u8 X86EMU_UNUSED(op1))
507 {
508     START_OF_INSTR();
509     DECODE_PRINTF("POP\tES\n");
510     TRACE_AND_STEP();
511     M.x86.R_ES = pop_word();
512     DECODE_CLEAR_SEGOVR();
513     END_OF_INSTR();
514 }
515
516 /****************************************************************************
517 REMARKS:
518 Handles opcode 0x08
519 ****************************************************************************/
520 void x86emuOp_or_byte_RM_R(u8 X86EMU_UNUSED(op1))
521 {
522     int mod, rl, rh;
523     u8 *destreg, *srcreg;
524     uint destoffset;
525     u8 destval;
526
527     START_OF_INSTR();
528     DECODE_PRINTF("OR\t");
529     FETCH_DECODE_MODRM(mod, rh, rl);
530     switch (mod) {
531     case 0:
532         destoffset = decode_rm00_address(rl);
533         DECODE_PRINTF(",");
534         destval = fetch_data_byte(destoffset);
535         srcreg = DECODE_RM_BYTE_REGISTER(rh);
536         DECODE_PRINTF("\n");
537         TRACE_AND_STEP();
538         destval = or_byte(destval, *srcreg);
539         store_data_byte(destoffset, destval);
540         break;
541     case 1:
542         destoffset = decode_rm01_address(rl);
543         DECODE_PRINTF(",");
544         destval = fetch_data_byte(destoffset);
545         srcreg = DECODE_RM_BYTE_REGISTER(rh);
546         DECODE_PRINTF("\n");
547         TRACE_AND_STEP();
548         destval = or_byte(destval, *srcreg);
549         store_data_byte(destoffset, destval);
550         break;
551     case 2:
552         destoffset = decode_rm10_address(rl);
553         DECODE_PRINTF(",");
554         destval = fetch_data_byte(destoffset);
555         srcreg = DECODE_RM_BYTE_REGISTER(rh);
556         DECODE_PRINTF("\n");
557         TRACE_AND_STEP();
558         destval = or_byte(destval, *srcreg);
559         store_data_byte(destoffset, destval);
560         break;
561     case 3:                     /* register to register */
562         destreg = DECODE_RM_BYTE_REGISTER(rl);
563         DECODE_PRINTF(",");
564         srcreg = DECODE_RM_BYTE_REGISTER(rh);
565         DECODE_PRINTF("\n");
566         TRACE_AND_STEP();
567         *destreg = or_byte(*destreg, *srcreg);
568         break;
569     }
570     DECODE_CLEAR_SEGOVR();
571     END_OF_INSTR();
572 }
573
574 /****************************************************************************
575 REMARKS:
576 Handles opcode 0x09
577 ****************************************************************************/
578 void x86emuOp_or_word_RM_R(u8 X86EMU_UNUSED(op1))
579 {
580     int mod, rl, rh;
581     uint destoffset;
582
583     START_OF_INSTR();
584     DECODE_PRINTF("OR\t");
585     FETCH_DECODE_MODRM(mod, rh, rl);
586     switch (mod) {
587     case 0:
588         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
589             u32 destval;
590             u32 *srcreg;
591
592             destoffset = decode_rm00_address(rl);
593             DECODE_PRINTF(",");
594             destval = fetch_data_long(destoffset);
595             srcreg = DECODE_RM_LONG_REGISTER(rh);
596             DECODE_PRINTF("\n");
597             TRACE_AND_STEP();
598             destval = or_long(destval, *srcreg);
599             store_data_long(destoffset, destval);
600         } else {
601             u16 destval;
602             u16 *srcreg;
603
604             destoffset = decode_rm00_address(rl);
605             DECODE_PRINTF(",");
606             destval = fetch_data_word(destoffset);
607             srcreg = DECODE_RM_WORD_REGISTER(rh);
608             DECODE_PRINTF("\n");
609             TRACE_AND_STEP();
610             destval = or_word(destval, *srcreg);
611             store_data_word(destoffset, destval);
612         }
613         break;
614     case 1:
615         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
616             u32 destval;
617             u32 *srcreg;
618
619             destoffset = decode_rm01_address(rl);
620             DECODE_PRINTF(",");
621             destval = fetch_data_long(destoffset);
622             srcreg = DECODE_RM_LONG_REGISTER(rh);
623             DECODE_PRINTF("\n");
624             TRACE_AND_STEP();
625             destval = or_long(destval, *srcreg);
626             store_data_long(destoffset, destval);
627         } else {
628             u16 destval;
629             u16 *srcreg;
630
631             destoffset = decode_rm01_address(rl);
632             DECODE_PRINTF(",");
633             destval = fetch_data_word(destoffset);
634             srcreg = DECODE_RM_WORD_REGISTER(rh);
635             DECODE_PRINTF("\n");
636             TRACE_AND_STEP();
637             destval = or_word(destval, *srcreg);
638             store_data_word(destoffset, destval);
639         }
640         break;
641     case 2:
642         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
643             u32 destval;
644             u32 *srcreg;
645
646             destoffset = decode_rm10_address(rl);
647             DECODE_PRINTF(",");
648             destval = fetch_data_long(destoffset);
649             srcreg = DECODE_RM_LONG_REGISTER(rh);
650             DECODE_PRINTF("\n");
651             TRACE_AND_STEP();
652             destval = or_long(destval, *srcreg);
653             store_data_long(destoffset, destval);
654         } else {
655             u16 destval;
656             u16 *srcreg;
657
658             destoffset = decode_rm10_address(rl);
659             DECODE_PRINTF(",");
660             destval = fetch_data_word(destoffset);
661             srcreg = DECODE_RM_WORD_REGISTER(rh);
662             DECODE_PRINTF("\n");
663             TRACE_AND_STEP();
664             destval = or_word(destval, *srcreg);
665             store_data_word(destoffset, destval);
666         }
667         break;
668     case 3:                     /* register to register */
669         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
670             u32 *destreg,*srcreg;
671
672             destreg = DECODE_RM_LONG_REGISTER(rl);
673             DECODE_PRINTF(",");
674             srcreg = DECODE_RM_LONG_REGISTER(rh);
675             DECODE_PRINTF("\n");
676             TRACE_AND_STEP();
677             *destreg = or_long(*destreg, *srcreg);
678         } else {
679             u16 *destreg,*srcreg;
680
681             destreg = DECODE_RM_WORD_REGISTER(rl);
682             DECODE_PRINTF(",");
683             srcreg = DECODE_RM_WORD_REGISTER(rh);
684             DECODE_PRINTF("\n");
685             TRACE_AND_STEP();
686             *destreg = or_word(*destreg, *srcreg);
687         }
688         break;
689     }
690     DECODE_CLEAR_SEGOVR();
691     END_OF_INSTR();
692 }
693
694 /****************************************************************************
695 REMARKS:
696 Handles opcode 0x0a
697 ****************************************************************************/
698 void x86emuOp_or_byte_R_RM(u8 X86EMU_UNUSED(op1))
699 {
700     int mod, rl, rh;
701     u8 *destreg, *srcreg;
702     uint srcoffset;
703     u8 srcval;
704
705     START_OF_INSTR();
706     DECODE_PRINTF("OR\t");
707     FETCH_DECODE_MODRM(mod, rh, rl);
708     switch (mod) {
709     case 0:
710         destreg = DECODE_RM_BYTE_REGISTER(rh);
711         DECODE_PRINTF(",");
712         srcoffset = decode_rm00_address(rl);
713         srcval = fetch_data_byte(srcoffset);
714         DECODE_PRINTF("\n");
715         TRACE_AND_STEP();
716         *destreg = or_byte(*destreg, srcval);
717         break;
718     case 1:
719         destreg = DECODE_RM_BYTE_REGISTER(rh);
720         DECODE_PRINTF(",");
721         srcoffset = decode_rm01_address(rl);
722         srcval = fetch_data_byte(srcoffset);
723         DECODE_PRINTF("\n");
724         TRACE_AND_STEP();
725         *destreg = or_byte(*destreg, srcval);
726         break;
727     case 2:
728         destreg = DECODE_RM_BYTE_REGISTER(rh);
729         DECODE_PRINTF(",");
730         srcoffset = decode_rm10_address(rl);
731         srcval = fetch_data_byte(srcoffset);
732         DECODE_PRINTF("\n");
733         TRACE_AND_STEP();
734         *destreg = or_byte(*destreg, srcval);
735         break;
736     case 3:                     /* register to register */
737         destreg = DECODE_RM_BYTE_REGISTER(rh);
738         DECODE_PRINTF(",");
739         srcreg = DECODE_RM_BYTE_REGISTER(rl);
740         DECODE_PRINTF("\n");
741         TRACE_AND_STEP();
742         *destreg = or_byte(*destreg, *srcreg);
743         break;
744     }
745     DECODE_CLEAR_SEGOVR();
746     END_OF_INSTR();
747 }
748
749 /****************************************************************************
750 REMARKS:
751 Handles opcode 0x0b
752 ****************************************************************************/
753 void x86emuOp_or_word_R_RM(u8 X86EMU_UNUSED(op1))
754 {
755     int mod, rl, rh;
756     uint srcoffset;
757
758     START_OF_INSTR();
759     DECODE_PRINTF("OR\t");
760     FETCH_DECODE_MODRM(mod, rh, rl);
761     switch (mod) {
762     case 0:
763         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
764             u32 *destreg;
765             u32 srcval;
766
767             destreg = DECODE_RM_LONG_REGISTER(rh);
768             DECODE_PRINTF(",");
769             srcoffset = decode_rm00_address(rl);
770             srcval = fetch_data_long(srcoffset);
771             DECODE_PRINTF("\n");
772             TRACE_AND_STEP();
773             *destreg = or_long(*destreg, srcval);
774         } else {
775             u16 *destreg;
776             u16 srcval;
777
778             destreg = DECODE_RM_WORD_REGISTER(rh);
779             DECODE_PRINTF(",");
780             srcoffset = decode_rm00_address(rl);
781             srcval = fetch_data_word(srcoffset);
782             DECODE_PRINTF("\n");
783             TRACE_AND_STEP();
784             *destreg = or_word(*destreg, srcval);
785         }
786         break;
787     case 1:
788         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
789             u32 *destreg;
790             u32 srcval;
791
792             destreg = DECODE_RM_LONG_REGISTER(rh);
793             DECODE_PRINTF(",");
794             srcoffset = decode_rm01_address(rl);
795             srcval = fetch_data_long(srcoffset);
796             DECODE_PRINTF("\n");
797             TRACE_AND_STEP();
798             *destreg = or_long(*destreg, srcval);
799         } else {
800             u16 *destreg;
801             u16 srcval;
802
803             destreg = DECODE_RM_WORD_REGISTER(rh);
804             DECODE_PRINTF(",");
805             srcoffset = decode_rm01_address(rl);
806             srcval = fetch_data_word(srcoffset);
807             DECODE_PRINTF("\n");
808             TRACE_AND_STEP();
809             *destreg = or_word(*destreg, srcval);
810         }
811         break;
812     case 2:
813         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
814             u32 *destreg;
815             u32 srcval;
816
817             destreg = DECODE_RM_LONG_REGISTER(rh);
818             DECODE_PRINTF(",");
819             srcoffset = decode_rm10_address(rl);
820             srcval = fetch_data_long(srcoffset);
821             DECODE_PRINTF("\n");
822             TRACE_AND_STEP();
823             *destreg = or_long(*destreg, srcval);
824         } else {
825             u16 *destreg;
826             u16 srcval;
827
828             destreg = DECODE_RM_WORD_REGISTER(rh);
829             DECODE_PRINTF(",");
830             srcoffset = decode_rm10_address(rl);
831             srcval = fetch_data_word(srcoffset);
832             DECODE_PRINTF("\n");
833             TRACE_AND_STEP();
834             *destreg = or_word(*destreg, srcval);
835         }
836         break;
837     case 3:                     /* register to register */
838         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
839             u32 *destreg,*srcreg;
840
841             destreg = DECODE_RM_LONG_REGISTER(rh);
842             DECODE_PRINTF(",");
843             srcreg = DECODE_RM_LONG_REGISTER(rl);
844             DECODE_PRINTF("\n");
845             TRACE_AND_STEP();
846             *destreg = or_long(*destreg, *srcreg);
847         } else {
848             u16 *destreg,*srcreg;
849
850             destreg = DECODE_RM_WORD_REGISTER(rh);
851             DECODE_PRINTF(",");
852             srcreg = DECODE_RM_WORD_REGISTER(rl);
853             DECODE_PRINTF("\n");
854             TRACE_AND_STEP();
855             *destreg = or_word(*destreg, *srcreg);
856         }
857         break;
858     }
859     DECODE_CLEAR_SEGOVR();
860     END_OF_INSTR();
861 }
862
863 /****************************************************************************
864 REMARKS:
865 Handles opcode 0x0c
866 ****************************************************************************/
867 void x86emuOp_or_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
868 {
869     u8 srcval;
870
871     START_OF_INSTR();
872     DECODE_PRINTF("OR\tAL,");
873     srcval = fetch_byte_imm();
874     DECODE_PRINTF2("%x\n", srcval);
875     TRACE_AND_STEP();
876     M.x86.R_AL = or_byte(M.x86.R_AL, srcval);
877     DECODE_CLEAR_SEGOVR();
878     END_OF_INSTR();
879 }
880
881 /****************************************************************************
882 REMARKS:
883 Handles opcode 0x0d
884 ****************************************************************************/
885 void x86emuOp_or_word_AX_IMM(u8 X86EMU_UNUSED(op1))
886 {
887     u32 srcval;
888
889     START_OF_INSTR();
890     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
891         DECODE_PRINTF("OR\tEAX,");
892         srcval = fetch_long_imm();
893     } else {
894         DECODE_PRINTF("OR\tAX,");
895         srcval = fetch_word_imm();
896     }
897     DECODE_PRINTF2("%x\n", srcval);
898     TRACE_AND_STEP();
899     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
900         M.x86.R_EAX = or_long(M.x86.R_EAX, srcval);
901     } else {
902         M.x86.R_AX = or_word(M.x86.R_AX, (u16)srcval);
903     }
904     DECODE_CLEAR_SEGOVR();
905     END_OF_INSTR();
906 }
907
908 /****************************************************************************
909 REMARKS:
910 Handles opcode 0x0e
911 ****************************************************************************/
912 void x86emuOp_push_CS(u8 X86EMU_UNUSED(op1))
913 {
914     START_OF_INSTR();
915     DECODE_PRINTF("PUSH\tCS\n");
916     TRACE_AND_STEP();
917     push_word(M.x86.R_CS);
918     DECODE_CLEAR_SEGOVR();
919     END_OF_INSTR();
920 }
921
922 /****************************************************************************
923 REMARKS:
924 Handles opcode 0x0f. Escape for two-byte opcode (286 or better)
925 ****************************************************************************/
926 void x86emuOp_two_byte(u8 X86EMU_UNUSED(op1))
927 {
928     u8 op2 = (*sys_rdb)(((u32)M.x86.R_CS << 4) + (M.x86.R_IP++));
929     INC_DECODED_INST_LEN(1);
930     (*x86emu_optab2[op2])(op2);
931 }
932
933 /****************************************************************************
934 REMARKS:
935 Handles opcode 0x10
936 ****************************************************************************/
937 void x86emuOp_adc_byte_RM_R(u8 X86EMU_UNUSED(op1))
938 {
939     int mod, rl, rh;
940     u8 *destreg, *srcreg;
941     uint destoffset;
942     u8 destval;
943
944     START_OF_INSTR();
945     DECODE_PRINTF("ADC\t");
946     FETCH_DECODE_MODRM(mod, rh, rl);
947     switch (mod) {
948     case 0:
949         destoffset = decode_rm00_address(rl);
950         DECODE_PRINTF(",");
951         destval = fetch_data_byte(destoffset);
952         srcreg = DECODE_RM_BYTE_REGISTER(rh);
953         DECODE_PRINTF("\n");
954         TRACE_AND_STEP();
955         destval = adc_byte(destval, *srcreg);
956         store_data_byte(destoffset, destval);
957         break;
958     case 1:
959         destoffset = decode_rm01_address(rl);
960         DECODE_PRINTF(",");
961         destval = fetch_data_byte(destoffset);
962         srcreg = DECODE_RM_BYTE_REGISTER(rh);
963         DECODE_PRINTF("\n");
964         TRACE_AND_STEP();
965         destval = adc_byte(destval, *srcreg);
966         store_data_byte(destoffset, destval);
967         break;
968     case 2:
969         destoffset = decode_rm10_address(rl);
970         DECODE_PRINTF(",");
971         destval = fetch_data_byte(destoffset);
972         srcreg = DECODE_RM_BYTE_REGISTER(rh);
973         DECODE_PRINTF("\n");
974         TRACE_AND_STEP();
975         destval = adc_byte(destval, *srcreg);
976         store_data_byte(destoffset, destval);
977         break;
978     case 3:                     /* register to register */
979         destreg = DECODE_RM_BYTE_REGISTER(rl);
980         DECODE_PRINTF(",");
981         srcreg = DECODE_RM_BYTE_REGISTER(rh);
982         DECODE_PRINTF("\n");
983         TRACE_AND_STEP();
984         *destreg = adc_byte(*destreg, *srcreg);
985         break;
986     }
987     DECODE_CLEAR_SEGOVR();
988     END_OF_INSTR();
989 }
990
991 /****************************************************************************
992 REMARKS:
993 Handles opcode 0x11
994 ****************************************************************************/
995 void x86emuOp_adc_word_RM_R(u8 X86EMU_UNUSED(op1))
996 {
997     int mod, rl, rh;
998     uint destoffset;
999
1000     START_OF_INSTR();
1001     DECODE_PRINTF("ADC\t");
1002     FETCH_DECODE_MODRM(mod, rh, rl);
1003     switch (mod) {
1004     case 0:
1005         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1006             u32 destval;
1007             u32 *srcreg;
1008
1009             destoffset = decode_rm00_address(rl);
1010             DECODE_PRINTF(",");
1011             destval = fetch_data_long(destoffset);
1012             srcreg = DECODE_RM_LONG_REGISTER(rh);
1013             DECODE_PRINTF("\n");
1014             TRACE_AND_STEP();
1015             destval = adc_long(destval, *srcreg);
1016             store_data_long(destoffset, destval);
1017         } else {
1018             u16 destval;
1019             u16 *srcreg;
1020
1021             destoffset = decode_rm00_address(rl);
1022             DECODE_PRINTF(",");
1023             destval = fetch_data_word(destoffset);
1024             srcreg = DECODE_RM_WORD_REGISTER(rh);
1025             DECODE_PRINTF("\n");
1026             TRACE_AND_STEP();
1027             destval = adc_word(destval, *srcreg);
1028             store_data_word(destoffset, destval);
1029         }
1030         break;
1031     case 1:
1032         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1033             u32 destval;
1034             u32 *srcreg;
1035
1036             destoffset = decode_rm01_address(rl);
1037             DECODE_PRINTF(",");
1038             destval = fetch_data_long(destoffset);
1039             srcreg = DECODE_RM_LONG_REGISTER(rh);
1040             DECODE_PRINTF("\n");
1041             TRACE_AND_STEP();
1042             destval = adc_long(destval, *srcreg);
1043             store_data_long(destoffset, destval);
1044         } else {
1045             u16 destval;
1046             u16 *srcreg;
1047
1048             destoffset = decode_rm01_address(rl);
1049             DECODE_PRINTF(",");
1050             destval = fetch_data_word(destoffset);
1051             srcreg = DECODE_RM_WORD_REGISTER(rh);
1052             DECODE_PRINTF("\n");
1053             TRACE_AND_STEP();
1054             destval = adc_word(destval, *srcreg);
1055             store_data_word(destoffset, destval);
1056         }
1057         break;
1058     case 2:
1059         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1060             u32 destval;
1061             u32 *srcreg;
1062
1063             destoffset = decode_rm10_address(rl);
1064             DECODE_PRINTF(",");
1065             destval = fetch_data_long(destoffset);
1066             srcreg = DECODE_RM_LONG_REGISTER(rh);
1067             DECODE_PRINTF("\n");
1068             TRACE_AND_STEP();
1069             destval = adc_long(destval, *srcreg);
1070             store_data_long(destoffset, destval);
1071         } else {
1072             u16 destval;
1073             u16 *srcreg;
1074
1075             destoffset = decode_rm10_address(rl);
1076             DECODE_PRINTF(",");
1077             destval = fetch_data_word(destoffset);
1078             srcreg = DECODE_RM_WORD_REGISTER(rh);
1079             DECODE_PRINTF("\n");
1080             TRACE_AND_STEP();
1081             destval = adc_word(destval, *srcreg);
1082             store_data_word(destoffset, destval);
1083         }
1084         break;
1085     case 3:                     /* register to register */
1086         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1087             u32 *destreg,*srcreg;
1088
1089             destreg = DECODE_RM_LONG_REGISTER(rl);
1090             DECODE_PRINTF(",");
1091             srcreg = DECODE_RM_LONG_REGISTER(rh);
1092             DECODE_PRINTF("\n");
1093             TRACE_AND_STEP();
1094             *destreg = adc_long(*destreg, *srcreg);
1095         } else {
1096             u16 *destreg,*srcreg;
1097
1098             destreg = DECODE_RM_WORD_REGISTER(rl);
1099             DECODE_PRINTF(",");
1100             srcreg = DECODE_RM_WORD_REGISTER(rh);
1101             DECODE_PRINTF("\n");
1102             TRACE_AND_STEP();
1103             *destreg = adc_word(*destreg, *srcreg);
1104         }
1105         break;
1106     }
1107     DECODE_CLEAR_SEGOVR();
1108     END_OF_INSTR();
1109 }
1110
1111 /****************************************************************************
1112 REMARKS:
1113 Handles opcode 0x12
1114 ****************************************************************************/
1115 void x86emuOp_adc_byte_R_RM(u8 X86EMU_UNUSED(op1))
1116 {
1117     int mod, rl, rh;
1118     u8 *destreg, *srcreg;
1119     uint srcoffset;
1120     u8 srcval;
1121
1122     START_OF_INSTR();
1123     DECODE_PRINTF("ADC\t");
1124     FETCH_DECODE_MODRM(mod, rh, rl);
1125     switch (mod) {
1126     case 0:
1127         destreg = DECODE_RM_BYTE_REGISTER(rh);
1128         DECODE_PRINTF(",");
1129         srcoffset = decode_rm00_address(rl);
1130         srcval = fetch_data_byte(srcoffset);
1131         DECODE_PRINTF("\n");
1132         TRACE_AND_STEP();
1133         *destreg = adc_byte(*destreg, srcval);
1134         break;
1135     case 1:
1136         destreg = DECODE_RM_BYTE_REGISTER(rh);
1137         DECODE_PRINTF(",");
1138         srcoffset = decode_rm01_address(rl);
1139         srcval = fetch_data_byte(srcoffset);
1140         DECODE_PRINTF("\n");
1141         TRACE_AND_STEP();
1142         *destreg = adc_byte(*destreg, srcval);
1143         break;
1144     case 2:
1145         destreg = DECODE_RM_BYTE_REGISTER(rh);
1146         DECODE_PRINTF(",");
1147         srcoffset = decode_rm10_address(rl);
1148         srcval = fetch_data_byte(srcoffset);
1149         DECODE_PRINTF("\n");
1150         TRACE_AND_STEP();
1151         *destreg = adc_byte(*destreg, srcval);
1152         break;
1153     case 3:                     /* register to register */
1154         destreg = DECODE_RM_BYTE_REGISTER(rh);
1155         DECODE_PRINTF(",");
1156         srcreg = DECODE_RM_BYTE_REGISTER(rl);
1157         DECODE_PRINTF("\n");
1158         TRACE_AND_STEP();
1159         *destreg = adc_byte(*destreg, *srcreg);
1160         break;
1161     }
1162     DECODE_CLEAR_SEGOVR();
1163     END_OF_INSTR();
1164 }
1165
1166 /****************************************************************************
1167 REMARKS:
1168 Handles opcode 0x13
1169 ****************************************************************************/
1170 void x86emuOp_adc_word_R_RM(u8 X86EMU_UNUSED(op1))
1171 {
1172     int mod, rl, rh;
1173     uint srcoffset;
1174
1175     START_OF_INSTR();
1176     DECODE_PRINTF("ADC\t");
1177     FETCH_DECODE_MODRM(mod, rh, rl);
1178     switch (mod) {
1179     case 0:
1180         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1181             u32 *destreg;
1182             u32 srcval;
1183
1184             destreg = DECODE_RM_LONG_REGISTER(rh);
1185             DECODE_PRINTF(",");
1186             srcoffset = decode_rm00_address(rl);
1187             srcval = fetch_data_long(srcoffset);
1188             DECODE_PRINTF("\n");
1189             TRACE_AND_STEP();
1190             *destreg = adc_long(*destreg, srcval);
1191         } else {
1192             u16 *destreg;
1193             u16 srcval;
1194
1195             destreg = DECODE_RM_WORD_REGISTER(rh);
1196             DECODE_PRINTF(",");
1197             srcoffset = decode_rm00_address(rl);
1198             srcval = fetch_data_word(srcoffset);
1199             DECODE_PRINTF("\n");
1200             TRACE_AND_STEP();
1201             *destreg = adc_word(*destreg, srcval);
1202         }
1203         break;
1204     case 1:
1205         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1206             u32 *destreg;
1207             u32 srcval;
1208
1209             destreg = DECODE_RM_LONG_REGISTER(rh);
1210             DECODE_PRINTF(",");
1211             srcoffset = decode_rm01_address(rl);
1212             srcval = fetch_data_long(srcoffset);
1213             DECODE_PRINTF("\n");
1214             TRACE_AND_STEP();
1215             *destreg = adc_long(*destreg, srcval);
1216         } else {
1217             u16 *destreg;
1218             u16 srcval;
1219
1220             destreg = DECODE_RM_WORD_REGISTER(rh);
1221             DECODE_PRINTF(",");
1222             srcoffset = decode_rm01_address(rl);
1223             srcval = fetch_data_word(srcoffset);
1224             DECODE_PRINTF("\n");
1225             TRACE_AND_STEP();
1226             *destreg = adc_word(*destreg, srcval);
1227         }
1228         break;
1229     case 2:
1230         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1231             u32 *destreg;
1232             u32 srcval;
1233
1234             destreg = DECODE_RM_LONG_REGISTER(rh);
1235             DECODE_PRINTF(",");
1236             srcoffset = decode_rm10_address(rl);
1237             srcval = fetch_data_long(srcoffset);
1238             DECODE_PRINTF("\n");
1239             TRACE_AND_STEP();
1240             *destreg = adc_long(*destreg, srcval);
1241         } else {
1242             u16 *destreg;
1243             u16 srcval;
1244
1245             destreg = DECODE_RM_WORD_REGISTER(rh);
1246             DECODE_PRINTF(",");
1247             srcoffset = decode_rm10_address(rl);
1248             srcval = fetch_data_word(srcoffset);
1249             DECODE_PRINTF("\n");
1250             TRACE_AND_STEP();
1251             *destreg = adc_word(*destreg, srcval);
1252         }
1253         break;
1254     case 3:                     /* register to register */
1255         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1256             u32 *destreg,*srcreg;
1257
1258             destreg = DECODE_RM_LONG_REGISTER(rh);
1259             DECODE_PRINTF(",");
1260             srcreg = DECODE_RM_LONG_REGISTER(rl);
1261             DECODE_PRINTF("\n");
1262             TRACE_AND_STEP();
1263             *destreg = adc_long(*destreg, *srcreg);
1264         } else {
1265             u16 *destreg,*srcreg;
1266
1267             destreg = DECODE_RM_WORD_REGISTER(rh);
1268             DECODE_PRINTF(",");
1269             srcreg = DECODE_RM_WORD_REGISTER(rl);
1270             DECODE_PRINTF("\n");
1271             TRACE_AND_STEP();
1272             *destreg = adc_word(*destreg, *srcreg);
1273         }
1274         break;
1275     }
1276     DECODE_CLEAR_SEGOVR();
1277     END_OF_INSTR();
1278 }
1279
1280 /****************************************************************************
1281 REMARKS:
1282 Handles opcode 0x14
1283 ****************************************************************************/
1284 void x86emuOp_adc_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
1285 {
1286     u8 srcval;
1287
1288     START_OF_INSTR();
1289     DECODE_PRINTF("ADC\tAL,");
1290     srcval = fetch_byte_imm();
1291     DECODE_PRINTF2("%x\n", srcval);
1292     TRACE_AND_STEP();
1293     M.x86.R_AL = adc_byte(M.x86.R_AL, srcval);
1294     DECODE_CLEAR_SEGOVR();
1295     END_OF_INSTR();
1296 }
1297
1298 /****************************************************************************
1299 REMARKS:
1300 Handles opcode 0x15
1301 ****************************************************************************/
1302 void x86emuOp_adc_word_AX_IMM(u8 X86EMU_UNUSED(op1))
1303 {
1304     u32 srcval;
1305
1306     START_OF_INSTR();
1307     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1308         DECODE_PRINTF("ADC\tEAX,");
1309         srcval = fetch_long_imm();
1310     } else {
1311         DECODE_PRINTF("ADC\tAX,");
1312         srcval = fetch_word_imm();
1313     }
1314     DECODE_PRINTF2("%x\n", srcval);
1315     TRACE_AND_STEP();
1316     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1317         M.x86.R_EAX = adc_long(M.x86.R_EAX, srcval);
1318     } else {
1319         M.x86.R_AX = adc_word(M.x86.R_AX, (u16)srcval);
1320     }
1321     DECODE_CLEAR_SEGOVR();
1322     END_OF_INSTR();
1323 }
1324
1325 /****************************************************************************
1326 REMARKS:
1327 Handles opcode 0x16
1328 ****************************************************************************/
1329 void x86emuOp_push_SS(u8 X86EMU_UNUSED(op1))
1330 {
1331     START_OF_INSTR();
1332     DECODE_PRINTF("PUSH\tSS\n");
1333     TRACE_AND_STEP();
1334     push_word(M.x86.R_SS);
1335     DECODE_CLEAR_SEGOVR();
1336     END_OF_INSTR();
1337 }
1338
1339 /****************************************************************************
1340 REMARKS:
1341 Handles opcode 0x17
1342 ****************************************************************************/
1343 void x86emuOp_pop_SS(u8 X86EMU_UNUSED(op1))
1344 {
1345     START_OF_INSTR();
1346     DECODE_PRINTF("POP\tSS\n");
1347     TRACE_AND_STEP();
1348     M.x86.R_SS = pop_word();
1349     DECODE_CLEAR_SEGOVR();
1350     END_OF_INSTR();
1351 }
1352
1353 /****************************************************************************
1354 REMARKS:
1355 Handles opcode 0x18
1356 ****************************************************************************/
1357 void x86emuOp_sbb_byte_RM_R(u8 X86EMU_UNUSED(op1))
1358 {
1359     int mod, rl, rh;
1360     u8 *destreg, *srcreg;
1361     uint destoffset;
1362     u8 destval;
1363
1364     START_OF_INSTR();
1365     DECODE_PRINTF("SBB\t");
1366     FETCH_DECODE_MODRM(mod, rh, rl);
1367     switch (mod) {
1368     case 0:
1369         destoffset = decode_rm00_address(rl);
1370         DECODE_PRINTF(",");
1371         destval = fetch_data_byte(destoffset);
1372         srcreg = DECODE_RM_BYTE_REGISTER(rh);
1373         DECODE_PRINTF("\n");
1374         TRACE_AND_STEP();
1375         destval = sbb_byte(destval, *srcreg);
1376         store_data_byte(destoffset, destval);
1377         break;
1378     case 1:
1379         destoffset = decode_rm01_address(rl);
1380         DECODE_PRINTF(",");
1381         destval = fetch_data_byte(destoffset);
1382         srcreg = DECODE_RM_BYTE_REGISTER(rh);
1383         DECODE_PRINTF("\n");
1384         TRACE_AND_STEP();
1385         destval = sbb_byte(destval, *srcreg);
1386         store_data_byte(destoffset, destval);
1387         break;
1388     case 2:
1389         destoffset = decode_rm10_address(rl);
1390         DECODE_PRINTF(",");
1391         destval = fetch_data_byte(destoffset);
1392         srcreg = DECODE_RM_BYTE_REGISTER(rh);
1393         DECODE_PRINTF("\n");
1394         TRACE_AND_STEP();
1395         destval = sbb_byte(destval, *srcreg);
1396         store_data_byte(destoffset, destval);
1397         break;
1398     case 3:                     /* register to register */
1399         destreg = DECODE_RM_BYTE_REGISTER(rl);
1400         DECODE_PRINTF(",");
1401         srcreg = DECODE_RM_BYTE_REGISTER(rh);
1402         DECODE_PRINTF("\n");
1403         TRACE_AND_STEP();
1404         *destreg = sbb_byte(*destreg, *srcreg);
1405         break;
1406     }
1407     DECODE_CLEAR_SEGOVR();
1408     END_OF_INSTR();
1409 }
1410
1411 /****************************************************************************
1412 REMARKS:
1413 Handles opcode 0x19
1414 ****************************************************************************/
1415 void x86emuOp_sbb_word_RM_R(u8 X86EMU_UNUSED(op1))
1416 {
1417     int mod, rl, rh;
1418     uint destoffset;
1419
1420     START_OF_INSTR();
1421     DECODE_PRINTF("SBB\t");
1422     FETCH_DECODE_MODRM(mod, rh, rl);
1423     switch (mod) {
1424     case 0:
1425         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1426             u32 destval;
1427             u32 *srcreg;
1428
1429             destoffset = decode_rm00_address(rl);
1430             DECODE_PRINTF(",");
1431             destval = fetch_data_long(destoffset);
1432             srcreg = DECODE_RM_LONG_REGISTER(rh);
1433             DECODE_PRINTF("\n");
1434             TRACE_AND_STEP();
1435             destval = sbb_long(destval, *srcreg);
1436             store_data_long(destoffset, destval);
1437         } else {
1438             u16 destval;
1439             u16 *srcreg;
1440
1441             destoffset = decode_rm00_address(rl);
1442             DECODE_PRINTF(",");
1443             destval = fetch_data_word(destoffset);
1444             srcreg = DECODE_RM_WORD_REGISTER(rh);
1445             DECODE_PRINTF("\n");
1446             TRACE_AND_STEP();
1447             destval = sbb_word(destval, *srcreg);
1448             store_data_word(destoffset, destval);
1449         }
1450         break;
1451     case 1:
1452         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1453             u32 destval;
1454             u32 *srcreg;
1455
1456             destoffset = decode_rm01_address(rl);
1457             DECODE_PRINTF(",");
1458             destval = fetch_data_long(destoffset);
1459             srcreg = DECODE_RM_LONG_REGISTER(rh);
1460             DECODE_PRINTF("\n");
1461             TRACE_AND_STEP();
1462             destval = sbb_long(destval, *srcreg);
1463             store_data_long(destoffset, destval);
1464         } else {
1465             u16 destval;
1466             u16 *srcreg;
1467
1468             destoffset = decode_rm01_address(rl);
1469             DECODE_PRINTF(",");
1470             destval = fetch_data_word(destoffset);
1471             srcreg = DECODE_RM_WORD_REGISTER(rh);
1472             DECODE_PRINTF("\n");
1473             TRACE_AND_STEP();
1474             destval = sbb_word(destval, *srcreg);
1475             store_data_word(destoffset, destval);
1476         }
1477         break;
1478     case 2:
1479         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1480             u32 destval;
1481             u32 *srcreg;
1482
1483             destoffset = decode_rm10_address(rl);
1484             DECODE_PRINTF(",");
1485             destval = fetch_data_long(destoffset);
1486             srcreg = DECODE_RM_LONG_REGISTER(rh);
1487             DECODE_PRINTF("\n");
1488             TRACE_AND_STEP();
1489             destval = sbb_long(destval, *srcreg);
1490             store_data_long(destoffset, destval);
1491         } else {
1492             u16 destval;
1493             u16 *srcreg;
1494
1495             destoffset = decode_rm10_address(rl);
1496             DECODE_PRINTF(",");
1497             destval = fetch_data_word(destoffset);
1498             srcreg = DECODE_RM_WORD_REGISTER(rh);
1499             DECODE_PRINTF("\n");
1500             TRACE_AND_STEP();
1501             destval = sbb_word(destval, *srcreg);
1502             store_data_word(destoffset, destval);
1503         }
1504         break;
1505     case 3:                     /* register to register */
1506         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1507             u32 *destreg,*srcreg;
1508
1509             destreg = DECODE_RM_LONG_REGISTER(rl);
1510             DECODE_PRINTF(",");
1511             srcreg = DECODE_RM_LONG_REGISTER(rh);
1512             DECODE_PRINTF("\n");
1513             TRACE_AND_STEP();
1514             *destreg = sbb_long(*destreg, *srcreg);
1515         } else {
1516             u16 *destreg,*srcreg;
1517
1518             destreg = DECODE_RM_WORD_REGISTER(rl);
1519             DECODE_PRINTF(",");
1520             srcreg = DECODE_RM_WORD_REGISTER(rh);
1521             DECODE_PRINTF("\n");
1522             TRACE_AND_STEP();
1523             *destreg = sbb_word(*destreg, *srcreg);
1524         }
1525         break;
1526     }
1527     DECODE_CLEAR_SEGOVR();
1528     END_OF_INSTR();
1529 }
1530
1531 /****************************************************************************
1532 REMARKS:
1533 Handles opcode 0x1a
1534 ****************************************************************************/
1535 void x86emuOp_sbb_byte_R_RM(u8 X86EMU_UNUSED(op1))
1536 {
1537     int mod, rl, rh;
1538     u8 *destreg, *srcreg;
1539     uint srcoffset;
1540     u8 srcval;
1541
1542     START_OF_INSTR();
1543     DECODE_PRINTF("SBB\t");
1544     FETCH_DECODE_MODRM(mod, rh, rl);
1545     switch (mod) {
1546     case 0:
1547         destreg = DECODE_RM_BYTE_REGISTER(rh);
1548         DECODE_PRINTF(",");
1549         srcoffset = decode_rm00_address(rl);
1550         srcval = fetch_data_byte(srcoffset);
1551         DECODE_PRINTF("\n");
1552         TRACE_AND_STEP();
1553         *destreg = sbb_byte(*destreg, srcval);
1554         break;
1555     case 1:
1556         destreg = DECODE_RM_BYTE_REGISTER(rh);
1557         DECODE_PRINTF(",");
1558         srcoffset = decode_rm01_address(rl);
1559         srcval = fetch_data_byte(srcoffset);
1560         DECODE_PRINTF("\n");
1561         TRACE_AND_STEP();
1562         *destreg = sbb_byte(*destreg, srcval);
1563         break;
1564     case 2:
1565         destreg = DECODE_RM_BYTE_REGISTER(rh);
1566         DECODE_PRINTF(",");
1567         srcoffset = decode_rm10_address(rl);
1568         srcval = fetch_data_byte(srcoffset);
1569         DECODE_PRINTF("\n");
1570         TRACE_AND_STEP();
1571         *destreg = sbb_byte(*destreg, srcval);
1572         break;
1573     case 3:                     /* register to register */
1574         destreg = DECODE_RM_BYTE_REGISTER(rh);
1575         DECODE_PRINTF(",");
1576         srcreg = DECODE_RM_BYTE_REGISTER(rl);
1577         DECODE_PRINTF("\n");
1578         TRACE_AND_STEP();
1579         *destreg = sbb_byte(*destreg, *srcreg);
1580         break;
1581     }
1582     DECODE_CLEAR_SEGOVR();
1583     END_OF_INSTR();
1584 }
1585
1586 /****************************************************************************
1587 REMARKS:
1588 Handles opcode 0x1b
1589 ****************************************************************************/
1590 void x86emuOp_sbb_word_R_RM(u8 X86EMU_UNUSED(op1))
1591 {
1592     int mod, rl, rh;
1593     uint srcoffset;
1594
1595     START_OF_INSTR();
1596     DECODE_PRINTF("SBB\t");
1597     FETCH_DECODE_MODRM(mod, rh, rl);
1598     switch (mod) {
1599     case 0:
1600         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1601             u32 *destreg;
1602             u32 srcval;
1603
1604             destreg = DECODE_RM_LONG_REGISTER(rh);
1605             DECODE_PRINTF(",");
1606             srcoffset = decode_rm00_address(rl);
1607             srcval = fetch_data_long(srcoffset);
1608             DECODE_PRINTF("\n");
1609             TRACE_AND_STEP();
1610             *destreg = sbb_long(*destreg, srcval);
1611         } else {
1612             u16 *destreg;
1613             u16 srcval;
1614
1615             destreg = DECODE_RM_WORD_REGISTER(rh);
1616             DECODE_PRINTF(",");
1617             srcoffset = decode_rm00_address(rl);
1618             srcval = fetch_data_word(srcoffset);
1619             DECODE_PRINTF("\n");
1620             TRACE_AND_STEP();
1621             *destreg = sbb_word(*destreg, srcval);
1622         }
1623         break;
1624     case 1:
1625         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1626             u32 *destreg;
1627             u32 srcval;
1628
1629             destreg = DECODE_RM_LONG_REGISTER(rh);
1630             DECODE_PRINTF(",");
1631             srcoffset = decode_rm01_address(rl);
1632             srcval = fetch_data_long(srcoffset);
1633             DECODE_PRINTF("\n");
1634             TRACE_AND_STEP();
1635             *destreg = sbb_long(*destreg, srcval);
1636         } else {
1637             u16 *destreg;
1638             u16 srcval;
1639
1640             destreg = DECODE_RM_WORD_REGISTER(rh);
1641             DECODE_PRINTF(",");
1642             srcoffset = decode_rm01_address(rl);
1643             srcval = fetch_data_word(srcoffset);
1644             DECODE_PRINTF("\n");
1645             TRACE_AND_STEP();
1646             *destreg = sbb_word(*destreg, srcval);
1647         }
1648         break;
1649     case 2:
1650         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1651             u32 *destreg;
1652             u32 srcval;
1653
1654             destreg = DECODE_RM_LONG_REGISTER(rh);
1655             DECODE_PRINTF(",");
1656             srcoffset = decode_rm10_address(rl);
1657             srcval = fetch_data_long(srcoffset);
1658             DECODE_PRINTF("\n");
1659             TRACE_AND_STEP();
1660             *destreg = sbb_long(*destreg, srcval);
1661         } else {
1662             u16 *destreg;
1663             u16 srcval;
1664
1665             destreg = DECODE_RM_WORD_REGISTER(rh);
1666             DECODE_PRINTF(",");
1667             srcoffset = decode_rm10_address(rl);
1668             srcval = fetch_data_word(srcoffset);
1669             DECODE_PRINTF("\n");
1670             TRACE_AND_STEP();
1671             *destreg = sbb_word(*destreg, srcval);
1672         }
1673         break;
1674     case 3:                     /* register to register */
1675         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1676             u32 *destreg,*srcreg;
1677
1678             destreg = DECODE_RM_LONG_REGISTER(rh);
1679             DECODE_PRINTF(",");
1680             srcreg = DECODE_RM_LONG_REGISTER(rl);
1681             DECODE_PRINTF("\n");
1682             TRACE_AND_STEP();
1683             *destreg = sbb_long(*destreg, *srcreg);
1684         } else {
1685             u16 *destreg,*srcreg;
1686
1687             destreg = DECODE_RM_WORD_REGISTER(rh);
1688             DECODE_PRINTF(",");
1689             srcreg = DECODE_RM_WORD_REGISTER(rl);
1690             DECODE_PRINTF("\n");
1691             TRACE_AND_STEP();
1692             *destreg = sbb_word(*destreg, *srcreg);
1693         }
1694         break;
1695     }
1696     DECODE_CLEAR_SEGOVR();
1697     END_OF_INSTR();
1698 }
1699
1700 /****************************************************************************
1701 REMARKS:
1702 Handles opcode 0x1c
1703 ****************************************************************************/
1704 void x86emuOp_sbb_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
1705 {
1706     u8 srcval;
1707
1708     START_OF_INSTR();
1709     DECODE_PRINTF("SBB\tAL,");
1710     srcval = fetch_byte_imm();
1711     DECODE_PRINTF2("%x\n", srcval);
1712     TRACE_AND_STEP();
1713     M.x86.R_AL = sbb_byte(M.x86.R_AL, srcval);
1714     DECODE_CLEAR_SEGOVR();
1715     END_OF_INSTR();
1716 }
1717
1718 /****************************************************************************
1719 REMARKS:
1720 Handles opcode 0x1d
1721 ****************************************************************************/
1722 void x86emuOp_sbb_word_AX_IMM(u8 X86EMU_UNUSED(op1))
1723 {
1724     u32 srcval;
1725
1726     START_OF_INSTR();
1727     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1728         DECODE_PRINTF("SBB\tEAX,");
1729         srcval = fetch_long_imm();
1730     } else {
1731         DECODE_PRINTF("SBB\tAX,");
1732         srcval = fetch_word_imm();
1733     }
1734     DECODE_PRINTF2("%x\n", srcval);
1735     TRACE_AND_STEP();
1736     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1737         M.x86.R_EAX = sbb_long(M.x86.R_EAX, srcval);
1738     } else {
1739         M.x86.R_AX = sbb_word(M.x86.R_AX, (u16)srcval);
1740     }
1741     DECODE_CLEAR_SEGOVR();
1742     END_OF_INSTR();
1743 }
1744
1745 /****************************************************************************
1746 REMARKS:
1747 Handles opcode 0x1e
1748 ****************************************************************************/
1749 void x86emuOp_push_DS(u8 X86EMU_UNUSED(op1))
1750 {
1751     START_OF_INSTR();
1752     DECODE_PRINTF("PUSH\tDS\n");
1753     TRACE_AND_STEP();
1754     push_word(M.x86.R_DS);
1755     DECODE_CLEAR_SEGOVR();
1756     END_OF_INSTR();
1757 }
1758
1759 /****************************************************************************
1760 REMARKS:
1761 Handles opcode 0x1f
1762 ****************************************************************************/
1763 void x86emuOp_pop_DS(u8 X86EMU_UNUSED(op1))
1764 {
1765     START_OF_INSTR();
1766     DECODE_PRINTF("POP\tDS\n");
1767     TRACE_AND_STEP();
1768     M.x86.R_DS = pop_word();
1769     DECODE_CLEAR_SEGOVR();
1770     END_OF_INSTR();
1771 }
1772
1773 /****************************************************************************
1774 REMARKS:
1775 Handles opcode 0x20
1776 ****************************************************************************/
1777 void x86emuOp_and_byte_RM_R(u8 X86EMU_UNUSED(op1))
1778 {
1779     int mod, rl, rh;
1780     u8 *destreg, *srcreg;
1781     uint destoffset;
1782     u8 destval;
1783
1784     START_OF_INSTR();
1785     DECODE_PRINTF("AND\t");
1786     FETCH_DECODE_MODRM(mod, rh, rl);
1787
1788     switch (mod) {
1789     case 0:
1790         destoffset = decode_rm00_address(rl);
1791         DECODE_PRINTF(",");
1792         destval = fetch_data_byte(destoffset);
1793         srcreg = DECODE_RM_BYTE_REGISTER(rh);
1794         DECODE_PRINTF("\n");
1795         TRACE_AND_STEP();
1796         destval = and_byte(destval, *srcreg);
1797         store_data_byte(destoffset, destval);
1798         break;
1799
1800     case 1:
1801         destoffset = decode_rm01_address(rl);
1802         DECODE_PRINTF(",");
1803         destval = fetch_data_byte(destoffset);
1804         srcreg = DECODE_RM_BYTE_REGISTER(rh);
1805         DECODE_PRINTF("\n");
1806         TRACE_AND_STEP();
1807         destval = and_byte(destval, *srcreg);
1808         store_data_byte(destoffset, destval);
1809         break;
1810
1811     case 2:
1812         destoffset = decode_rm10_address(rl);
1813         DECODE_PRINTF(",");
1814         destval = fetch_data_byte(destoffset);
1815         srcreg = DECODE_RM_BYTE_REGISTER(rh);
1816         DECODE_PRINTF("\n");
1817         TRACE_AND_STEP();
1818         destval = and_byte(destval, *srcreg);
1819         store_data_byte(destoffset, destval);
1820         break;
1821
1822     case 3:                     /* register to register */
1823         destreg = DECODE_RM_BYTE_REGISTER(rl);
1824         DECODE_PRINTF(",");
1825         srcreg = DECODE_RM_BYTE_REGISTER(rh);
1826         DECODE_PRINTF("\n");
1827         TRACE_AND_STEP();
1828         *destreg = and_byte(*destreg, *srcreg);
1829         break;
1830     }
1831     DECODE_CLEAR_SEGOVR();
1832     END_OF_INSTR();
1833 }
1834
1835 /****************************************************************************
1836 REMARKS:
1837 Handles opcode 0x21
1838 ****************************************************************************/
1839 void x86emuOp_and_word_RM_R(u8 X86EMU_UNUSED(op1))
1840 {
1841     int mod, rl, rh;
1842     uint destoffset;
1843
1844     START_OF_INSTR();
1845     DECODE_PRINTF("AND\t");
1846     FETCH_DECODE_MODRM(mod, rh, rl);
1847     switch (mod) {
1848     case 0:
1849         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1850             u32 destval;
1851             u32 *srcreg;
1852
1853             destoffset = decode_rm00_address(rl);
1854             DECODE_PRINTF(",");
1855             destval = fetch_data_long(destoffset);
1856             srcreg = DECODE_RM_LONG_REGISTER(rh);
1857             DECODE_PRINTF("\n");
1858             TRACE_AND_STEP();
1859             destval = and_long(destval, *srcreg);
1860             store_data_long(destoffset, destval);
1861         } else {
1862             u16 destval;
1863             u16 *srcreg;
1864
1865             destoffset = decode_rm00_address(rl);
1866             DECODE_PRINTF(",");
1867             destval = fetch_data_word(destoffset);
1868             srcreg = DECODE_RM_WORD_REGISTER(rh);
1869             DECODE_PRINTF("\n");
1870             TRACE_AND_STEP();
1871             destval = and_word(destval, *srcreg);
1872             store_data_word(destoffset, destval);
1873         }
1874         break;
1875     case 1:
1876         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1877             u32 destval;
1878             u32 *srcreg;
1879
1880             destoffset = decode_rm01_address(rl);
1881             DECODE_PRINTF(",");
1882             destval = fetch_data_long(destoffset);
1883             srcreg = DECODE_RM_LONG_REGISTER(rh);
1884             DECODE_PRINTF("\n");
1885             TRACE_AND_STEP();
1886             destval = and_long(destval, *srcreg);
1887             store_data_long(destoffset, destval);
1888         } else {
1889             u16 destval;
1890             u16 *srcreg;
1891
1892             destoffset = decode_rm01_address(rl);
1893             DECODE_PRINTF(",");
1894             destval = fetch_data_word(destoffset);
1895             srcreg = DECODE_RM_WORD_REGISTER(rh);
1896             DECODE_PRINTF("\n");
1897             TRACE_AND_STEP();
1898             destval = and_word(destval, *srcreg);
1899             store_data_word(destoffset, destval);
1900         }
1901         break;
1902     case 2:
1903         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1904             u32 destval;
1905             u32 *srcreg;
1906
1907             destoffset = decode_rm10_address(rl);
1908             DECODE_PRINTF(",");
1909             destval = fetch_data_long(destoffset);
1910             srcreg = DECODE_RM_LONG_REGISTER(rh);
1911             DECODE_PRINTF("\n");
1912             TRACE_AND_STEP();
1913             destval = and_long(destval, *srcreg);
1914             store_data_long(destoffset, destval);
1915         } else {
1916             u16 destval;
1917             u16 *srcreg;
1918
1919             destoffset = decode_rm10_address(rl);
1920             DECODE_PRINTF(",");
1921             destval = fetch_data_word(destoffset);
1922             srcreg = DECODE_RM_WORD_REGISTER(rh);
1923             DECODE_PRINTF("\n");
1924             TRACE_AND_STEP();
1925             destval = and_word(destval, *srcreg);
1926             store_data_word(destoffset, destval);
1927         }
1928         break;
1929     case 3:                     /* register to register */
1930         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1931             u32 *destreg,*srcreg;
1932
1933             destreg = DECODE_RM_LONG_REGISTER(rl);
1934             DECODE_PRINTF(",");
1935             srcreg = DECODE_RM_LONG_REGISTER(rh);
1936             DECODE_PRINTF("\n");
1937             TRACE_AND_STEP();
1938             *destreg = and_long(*destreg, *srcreg);
1939         } else {
1940             u16 *destreg,*srcreg;
1941
1942             destreg = DECODE_RM_WORD_REGISTER(rl);
1943             DECODE_PRINTF(",");
1944             srcreg = DECODE_RM_WORD_REGISTER(rh);
1945             DECODE_PRINTF("\n");
1946             TRACE_AND_STEP();
1947             *destreg = and_word(*destreg, *srcreg);
1948         }
1949         break;
1950     }
1951     DECODE_CLEAR_SEGOVR();
1952     END_OF_INSTR();
1953 }
1954
1955 /****************************************************************************
1956 REMARKS:
1957 Handles opcode 0x22
1958 ****************************************************************************/
1959 void x86emuOp_and_byte_R_RM(u8 X86EMU_UNUSED(op1))
1960 {
1961     int mod, rl, rh;
1962     u8 *destreg, *srcreg;
1963     uint srcoffset;
1964     u8 srcval;
1965
1966     START_OF_INSTR();
1967     DECODE_PRINTF("AND\t");
1968     FETCH_DECODE_MODRM(mod, rh, rl);
1969     switch (mod) {
1970     case 0:
1971         destreg = DECODE_RM_BYTE_REGISTER(rh);
1972         DECODE_PRINTF(",");
1973         srcoffset = decode_rm00_address(rl);
1974         srcval = fetch_data_byte(srcoffset);
1975         DECODE_PRINTF("\n");
1976         TRACE_AND_STEP();
1977         *destreg = and_byte(*destreg, srcval);
1978         break;
1979     case 1:
1980         destreg = DECODE_RM_BYTE_REGISTER(rh);
1981         DECODE_PRINTF(",");
1982         srcoffset = decode_rm01_address(rl);
1983         srcval = fetch_data_byte(srcoffset);
1984         DECODE_PRINTF("\n");
1985         TRACE_AND_STEP();
1986         *destreg = and_byte(*destreg, srcval);
1987         break;
1988     case 2:
1989         destreg = DECODE_RM_BYTE_REGISTER(rh);
1990         DECODE_PRINTF(",");
1991         srcoffset = decode_rm10_address(rl);
1992         srcval = fetch_data_byte(srcoffset);
1993         DECODE_PRINTF("\n");
1994         TRACE_AND_STEP();
1995         *destreg = and_byte(*destreg, srcval);
1996         break;
1997     case 3:                     /* register to register */
1998         destreg = DECODE_RM_BYTE_REGISTER(rh);
1999         DECODE_PRINTF(",");
2000         srcreg = DECODE_RM_BYTE_REGISTER(rl);
2001         DECODE_PRINTF("\n");
2002         TRACE_AND_STEP();
2003         *destreg = and_byte(*destreg, *srcreg);
2004         break;
2005     }
2006     DECODE_CLEAR_SEGOVR();
2007     END_OF_INSTR();
2008 }
2009
2010 /****************************************************************************
2011 REMARKS:
2012 Handles opcode 0x23
2013 ****************************************************************************/
2014 void x86emuOp_and_word_R_RM(u8 X86EMU_UNUSED(op1))
2015 {
2016     int mod, rl, rh;
2017     uint srcoffset;
2018
2019     START_OF_INSTR();
2020     DECODE_PRINTF("AND\t");
2021     FETCH_DECODE_MODRM(mod, rh, rl);
2022     switch (mod) {
2023     case 0:
2024         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2025             u32 *destreg;
2026             u32 srcval;
2027
2028             destreg = DECODE_RM_LONG_REGISTER(rh);
2029             DECODE_PRINTF(",");
2030             srcoffset = decode_rm00_address(rl);
2031             srcval = fetch_data_long(srcoffset);
2032             DECODE_PRINTF("\n");
2033             TRACE_AND_STEP();
2034             *destreg = and_long(*destreg, srcval);
2035         } else {
2036             u16 *destreg;
2037             u16 srcval;
2038
2039             destreg = DECODE_RM_WORD_REGISTER(rh);
2040             DECODE_PRINTF(",");
2041             srcoffset = decode_rm00_address(rl);
2042             srcval = fetch_data_word(srcoffset);
2043             DECODE_PRINTF("\n");
2044             TRACE_AND_STEP();
2045             *destreg = and_word(*destreg, srcval);
2046         }
2047         break;
2048     case 1:
2049         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2050             u32 *destreg;
2051             u32 srcval;
2052
2053             destreg = DECODE_RM_LONG_REGISTER(rh);
2054             DECODE_PRINTF(",");
2055             srcoffset = decode_rm01_address(rl);
2056             srcval = fetch_data_long(srcoffset);
2057             DECODE_PRINTF("\n");
2058             TRACE_AND_STEP();
2059             *destreg = and_long(*destreg, srcval);
2060             break;
2061         } else {
2062             u16 *destreg;
2063             u16 srcval;
2064
2065             destreg = DECODE_RM_WORD_REGISTER(rh);
2066             DECODE_PRINTF(",");
2067             srcoffset = decode_rm01_address(rl);
2068             srcval = fetch_data_word(srcoffset);
2069             DECODE_PRINTF("\n");
2070             TRACE_AND_STEP();
2071             *destreg = and_word(*destreg, srcval);
2072             break;
2073         }
2074     case 2:
2075         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2076             u32 *destreg;
2077             u32 srcval;
2078
2079             destreg = DECODE_RM_LONG_REGISTER(rh);
2080             DECODE_PRINTF(",");
2081             srcoffset = decode_rm10_address(rl);
2082             srcval = fetch_data_long(srcoffset);
2083             DECODE_PRINTF("\n");
2084             TRACE_AND_STEP();
2085             *destreg = and_long(*destreg, srcval);
2086         } else {
2087             u16 *destreg;
2088             u16 srcval;
2089
2090             destreg = DECODE_RM_WORD_REGISTER(rh);
2091             DECODE_PRINTF(",");
2092             srcoffset = decode_rm10_address(rl);
2093             srcval = fetch_data_word(srcoffset);
2094             DECODE_PRINTF("\n");
2095             TRACE_AND_STEP();
2096             *destreg = and_word(*destreg, srcval);
2097         }
2098         break;
2099     case 3:                     /* register to register */
2100         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2101             u32 *destreg,*srcreg;
2102
2103             destreg = DECODE_RM_LONG_REGISTER(rh);
2104             DECODE_PRINTF(",");
2105             srcreg = DECODE_RM_LONG_REGISTER(rl);
2106             DECODE_PRINTF("\n");
2107             TRACE_AND_STEP();
2108             *destreg = and_long(*destreg, *srcreg);
2109         } else {
2110             u16 *destreg,*srcreg;
2111
2112             destreg = DECODE_RM_WORD_REGISTER(rh);
2113             DECODE_PRINTF(",");
2114             srcreg = DECODE_RM_WORD_REGISTER(rl);
2115             DECODE_PRINTF("\n");
2116             TRACE_AND_STEP();
2117             *destreg = and_word(*destreg, *srcreg);
2118         }
2119         break;
2120     }
2121     DECODE_CLEAR_SEGOVR();
2122     END_OF_INSTR();
2123 }
2124
2125 /****************************************************************************
2126 REMARKS:
2127 Handles opcode 0x24
2128 ****************************************************************************/
2129 void x86emuOp_and_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
2130 {
2131     u8 srcval;
2132
2133     START_OF_INSTR();
2134     DECODE_PRINTF("AND\tAL,");
2135     srcval = fetch_byte_imm();
2136     DECODE_PRINTF2("%x\n", srcval);
2137     TRACE_AND_STEP();
2138     M.x86.R_AL = and_byte(M.x86.R_AL, srcval);
2139     DECODE_CLEAR_SEGOVR();
2140     END_OF_INSTR();
2141 }
2142
2143 /****************************************************************************
2144 REMARKS:
2145 Handles opcode 0x25
2146 ****************************************************************************/
2147 void x86emuOp_and_word_AX_IMM(u8 X86EMU_UNUSED(op1))
2148 {
2149     u32 srcval;
2150
2151     START_OF_INSTR();
2152     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2153         DECODE_PRINTF("AND\tEAX,");
2154         srcval = fetch_long_imm();
2155     } else {
2156         DECODE_PRINTF("AND\tAX,");
2157         srcval = fetch_word_imm();
2158     }
2159     DECODE_PRINTF2("%x\n", srcval);
2160     TRACE_AND_STEP();
2161     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2162         M.x86.R_EAX = and_long(M.x86.R_EAX, srcval);
2163     } else {
2164         M.x86.R_AX = and_word(M.x86.R_AX, (u16)srcval);
2165     }
2166     DECODE_CLEAR_SEGOVR();
2167     END_OF_INSTR();
2168 }
2169
2170 /****************************************************************************
2171 REMARKS:
2172 Handles opcode 0x26
2173 ****************************************************************************/
2174 void x86emuOp_segovr_ES(u8 X86EMU_UNUSED(op1))
2175 {
2176     START_OF_INSTR();
2177     DECODE_PRINTF("ES:\n");
2178     TRACE_AND_STEP();
2179     M.x86.mode |= SYSMODE_SEGOVR_ES;
2180     /*
2181      * note the lack of DECODE_CLEAR_SEGOVR(r) since, here is one of 4
2182      * opcode subroutines we do not want to do this.
2183      */
2184     END_OF_INSTR();
2185 }
2186
2187 /****************************************************************************
2188 REMARKS:
2189 Handles opcode 0x27
2190 ****************************************************************************/
2191 void x86emuOp_daa(u8 X86EMU_UNUSED(op1))
2192 {
2193     START_OF_INSTR();
2194     DECODE_PRINTF("DAA\n");
2195     TRACE_AND_STEP();
2196     M.x86.R_AL = daa_byte(M.x86.R_AL);
2197     DECODE_CLEAR_SEGOVR();
2198     END_OF_INSTR();
2199 }
2200
2201 /****************************************************************************
2202 REMARKS:
2203 Handles opcode 0x28
2204 ****************************************************************************/
2205 void x86emuOp_sub_byte_RM_R(u8 X86EMU_UNUSED(op1))
2206 {
2207     int mod, rl, rh;
2208     u8 *destreg, *srcreg;
2209     uint destoffset;
2210     u8 destval;
2211
2212     START_OF_INSTR();
2213     DECODE_PRINTF("SUB\t");
2214     FETCH_DECODE_MODRM(mod, rh, rl);
2215     switch (mod) {
2216     case 0:
2217         destoffset = decode_rm00_address(rl);
2218         DECODE_PRINTF(",");
2219         destval = fetch_data_byte(destoffset);
2220         srcreg = DECODE_RM_BYTE_REGISTER(rh);
2221         DECODE_PRINTF("\n");
2222         TRACE_AND_STEP();
2223         destval = sub_byte(destval, *srcreg);
2224         store_data_byte(destoffset, destval);
2225         break;
2226     case 1:
2227         destoffset = decode_rm01_address(rl);
2228         DECODE_PRINTF(",");
2229         destval = fetch_data_byte(destoffset);
2230         srcreg = DECODE_RM_BYTE_REGISTER(rh);
2231         DECODE_PRINTF("\n");
2232         TRACE_AND_STEP();
2233         destval = sub_byte(destval, *srcreg);
2234         store_data_byte(destoffset, destval);
2235         break;
2236     case 2:
2237         destoffset = decode_rm10_address(rl);
2238         DECODE_PRINTF(",");
2239         destval = fetch_data_byte(destoffset);
2240         srcreg = DECODE_RM_BYTE_REGISTER(rh);
2241         DECODE_PRINTF("\n");
2242         TRACE_AND_STEP();
2243         destval = sub_byte(destval, *srcreg);
2244         store_data_byte(destoffset, destval);
2245         break;
2246     case 3:                     /* register to register */
2247         destreg = DECODE_RM_BYTE_REGISTER(rl);
2248         DECODE_PRINTF(",");
2249         srcreg = DECODE_RM_BYTE_REGISTER(rh);
2250         DECODE_PRINTF("\n");
2251         TRACE_AND_STEP();
2252         *destreg = sub_byte(*destreg, *srcreg);
2253         break;
2254     }
2255     DECODE_CLEAR_SEGOVR();
2256     END_OF_INSTR();
2257 }
2258
2259 /****************************************************************************
2260 REMARKS:
2261 Handles opcode 0x29
2262 ****************************************************************************/
2263 void x86emuOp_sub_word_RM_R(u8 X86EMU_UNUSED(op1))
2264 {
2265     int mod, rl, rh;
2266     uint destoffset;
2267
2268     START_OF_INSTR();
2269     DECODE_PRINTF("SUB\t");
2270     FETCH_DECODE_MODRM(mod, rh, rl);
2271     switch (mod) {
2272     case 0:
2273         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2274             u32 destval;
2275             u32 *srcreg;
2276
2277             destoffset = decode_rm00_address(rl);
2278             DECODE_PRINTF(",");
2279             destval = fetch_data_long(destoffset);
2280             srcreg = DECODE_RM_LONG_REGISTER(rh);
2281             DECODE_PRINTF("\n");
2282             TRACE_AND_STEP();
2283             destval = sub_long(destval, *srcreg);
2284             store_data_long(destoffset, destval);
2285         } else {
2286             u16 destval;
2287             u16 *srcreg;
2288
2289             destoffset = decode_rm00_address(rl);
2290             DECODE_PRINTF(",");
2291             destval = fetch_data_word(destoffset);
2292             srcreg = DECODE_RM_WORD_REGISTER(rh);
2293             DECODE_PRINTF("\n");
2294             TRACE_AND_STEP();
2295             destval = sub_word(destval, *srcreg);
2296             store_data_word(destoffset, destval);
2297         }
2298         break;
2299     case 1:
2300         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2301             u32 destval;
2302             u32 *srcreg;
2303
2304             destoffset = decode_rm01_address(rl);
2305             DECODE_PRINTF(",");
2306             destval = fetch_data_long(destoffset);
2307             srcreg = DECODE_RM_LONG_REGISTER(rh);
2308             DECODE_PRINTF("\n");
2309             TRACE_AND_STEP();
2310             destval = sub_long(destval, *srcreg);
2311             store_data_long(destoffset, destval);
2312         } else {
2313             u16 destval;
2314             u16 *srcreg;
2315
2316             destoffset = decode_rm01_address(rl);
2317             DECODE_PRINTF(",");
2318             destval = fetch_data_word(destoffset);
2319             srcreg = DECODE_RM_WORD_REGISTER(rh);
2320             DECODE_PRINTF("\n");
2321             TRACE_AND_STEP();
2322             destval = sub_word(destval, *srcreg);
2323             store_data_word(destoffset, destval);
2324         }
2325         break;
2326     case 2:
2327         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2328             u32 destval;
2329             u32 *srcreg;
2330
2331             destoffset = decode_rm10_address(rl);
2332             DECODE_PRINTF(",");
2333             destval = fetch_data_long(destoffset);
2334             srcreg = DECODE_RM_LONG_REGISTER(rh);
2335             DECODE_PRINTF("\n");
2336             TRACE_AND_STEP();
2337             destval = sub_long(destval, *srcreg);
2338             store_data_long(destoffset, destval);
2339         } else {
2340             u16 destval;
2341             u16 *srcreg;
2342
2343             destoffset = decode_rm10_address(rl);
2344             DECODE_PRINTF(",");
2345             destval = fetch_data_word(destoffset);
2346             srcreg = DECODE_RM_WORD_REGISTER(rh);
2347             DECODE_PRINTF("\n");
2348             TRACE_AND_STEP();
2349             destval = sub_word(destval, *srcreg);
2350             store_data_word(destoffset, destval);
2351         }
2352         break;
2353     case 3:                     /* register to register */
2354         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2355             u32 *destreg,*srcreg;
2356
2357             destreg = DECODE_RM_LONG_REGISTER(rl);
2358             DECODE_PRINTF(",");
2359             srcreg = DECODE_RM_LONG_REGISTER(rh);
2360             DECODE_PRINTF("\n");
2361             TRACE_AND_STEP();
2362             *destreg = sub_long(*destreg, *srcreg);
2363         } else {
2364             u16 *destreg,*srcreg;
2365
2366             destreg = DECODE_RM_WORD_REGISTER(rl);
2367             DECODE_PRINTF(",");
2368             srcreg = DECODE_RM_WORD_REGISTER(rh);
2369             DECODE_PRINTF("\n");
2370             TRACE_AND_STEP();
2371             *destreg = sub_word(*destreg, *srcreg);
2372         }
2373         break;
2374     }
2375     DECODE_CLEAR_SEGOVR();
2376     END_OF_INSTR();
2377 }
2378
2379 /****************************************************************************
2380 REMARKS:
2381 Handles opcode 0x2a
2382 ****************************************************************************/
2383 void x86emuOp_sub_byte_R_RM(u8 X86EMU_UNUSED(op1))
2384 {
2385     int mod, rl, rh;
2386     u8 *destreg, *srcreg;
2387     uint srcoffset;
2388     u8 srcval;
2389
2390     START_OF_INSTR();
2391     DECODE_PRINTF("SUB\t");
2392     FETCH_DECODE_MODRM(mod, rh, rl);
2393     switch (mod) {
2394     case 0:
2395         destreg = DECODE_RM_BYTE_REGISTER(rh);
2396         DECODE_PRINTF(",");
2397         srcoffset = decode_rm00_address(rl);
2398         srcval = fetch_data_byte(srcoffset);
2399         DECODE_PRINTF("\n");
2400         TRACE_AND_STEP();
2401         *destreg = sub_byte(*destreg, srcval);
2402         break;
2403     case 1:
2404         destreg = DECODE_RM_BYTE_REGISTER(rh);
2405         DECODE_PRINTF(",");
2406         srcoffset = decode_rm01_address(rl);
2407         srcval = fetch_data_byte(srcoffset);
2408         DECODE_PRINTF("\n");
2409         TRACE_AND_STEP();
2410         *destreg = sub_byte(*destreg, srcval);
2411         break;
2412     case 2:
2413         destreg = DECODE_RM_BYTE_REGISTER(rh);
2414         DECODE_PRINTF(",");
2415         srcoffset = decode_rm10_address(rl);
2416         srcval = fetch_data_byte(srcoffset);
2417         DECODE_PRINTF("\n");
2418         TRACE_AND_STEP();
2419         *destreg = sub_byte(*destreg, srcval);
2420         break;
2421     case 3:                     /* register to register */
2422         destreg = DECODE_RM_BYTE_REGISTER(rh);
2423         DECODE_PRINTF(",");
2424         srcreg = DECODE_RM_BYTE_REGISTER(rl);
2425         DECODE_PRINTF("\n");
2426         TRACE_AND_STEP();
2427         *destreg = sub_byte(*destreg, *srcreg);
2428         break;
2429     }
2430     DECODE_CLEAR_SEGOVR();
2431     END_OF_INSTR();
2432 }
2433
2434 /****************************************************************************
2435 REMARKS:
2436 Handles opcode 0x2b
2437 ****************************************************************************/
2438 void x86emuOp_sub_word_R_RM(u8 X86EMU_UNUSED(op1))
2439 {
2440     int mod, rl, rh;
2441     uint srcoffset;
2442
2443     START_OF_INSTR();
2444     DECODE_PRINTF("SUB\t");
2445     FETCH_DECODE_MODRM(mod, rh, rl);
2446     switch (mod) {
2447     case 0:
2448         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2449             u32 *destreg;
2450             u32 srcval;
2451
2452             destreg = DECODE_RM_LONG_REGISTER(rh);
2453             DECODE_PRINTF(",");
2454             srcoffset = decode_rm00_address(rl);
2455             srcval = fetch_data_long(srcoffset);
2456             DECODE_PRINTF("\n");
2457             TRACE_AND_STEP();
2458             *destreg = sub_long(*destreg, srcval);
2459         } else {
2460             u16 *destreg;
2461             u16 srcval;
2462
2463             destreg = DECODE_RM_WORD_REGISTER(rh);
2464             DECODE_PRINTF(",");
2465             srcoffset = decode_rm00_address(rl);
2466             srcval = fetch_data_word(srcoffset);
2467             DECODE_PRINTF("\n");
2468             TRACE_AND_STEP();
2469             *destreg = sub_word(*destreg, srcval);
2470         }
2471         break;
2472     case 1:
2473         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2474             u32 *destreg;
2475             u32 srcval;
2476
2477             destreg = DECODE_RM_LONG_REGISTER(rh);
2478             DECODE_PRINTF(",");
2479             srcoffset = decode_rm01_address(rl);
2480             srcval = fetch_data_long(srcoffset);
2481             DECODE_PRINTF("\n");
2482             TRACE_AND_STEP();
2483             *destreg = sub_long(*destreg, srcval);
2484         } else {
2485             u16 *destreg;
2486             u16 srcval;
2487
2488             destreg = DECODE_RM_WORD_REGISTER(rh);
2489             DECODE_PRINTF(",");
2490             srcoffset = decode_rm01_address(rl);
2491             srcval = fetch_data_word(srcoffset);
2492             DECODE_PRINTF("\n");
2493             TRACE_AND_STEP();
2494             *destreg = sub_word(*destreg, srcval);
2495         }
2496         break;
2497     case 2:
2498         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2499             u32 *destreg;
2500             u32 srcval;
2501
2502             destreg = DECODE_RM_LONG_REGISTER(rh);
2503             DECODE_PRINTF(",");
2504             srcoffset = decode_rm10_address(rl);
2505             srcval = fetch_data_long(srcoffset);
2506             DECODE_PRINTF("\n");
2507             TRACE_AND_STEP();
2508             *destreg = sub_long(*destreg, srcval);
2509         } else {
2510             u16 *destreg;
2511             u16 srcval;
2512
2513             destreg = DECODE_RM_WORD_REGISTER(rh);
2514             DECODE_PRINTF(",");
2515             srcoffset = decode_rm10_address(rl);
2516             srcval = fetch_data_word(srcoffset);
2517             DECODE_PRINTF("\n");
2518             TRACE_AND_STEP();
2519             *destreg = sub_word(*destreg, srcval);
2520         }
2521         break;
2522     case 3:                     /* register to register */
2523         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2524             u32 *destreg,*srcreg;
2525
2526             destreg = DECODE_RM_LONG_REGISTER(rh);
2527             DECODE_PRINTF(",");
2528             srcreg = DECODE_RM_LONG_REGISTER(rl);
2529             DECODE_PRINTF("\n");
2530             TRACE_AND_STEP();
2531             *destreg = sub_long(*destreg, *srcreg);
2532         } else {
2533             u16 *destreg,*srcreg;
2534
2535             destreg = DECODE_RM_WORD_REGISTER(rh);
2536             DECODE_PRINTF(",");
2537             srcreg = DECODE_RM_WORD_REGISTER(rl);
2538             DECODE_PRINTF("\n");
2539             TRACE_AND_STEP();
2540             *destreg = sub_word(*destreg, *srcreg);
2541         }
2542         break;
2543     }
2544     DECODE_CLEAR_SEGOVR();
2545     END_OF_INSTR();
2546 }
2547
2548 /****************************************************************************
2549 REMARKS:
2550 Handles opcode 0x2c
2551 ****************************************************************************/
2552 void x86emuOp_sub_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
2553 {
2554     u8 srcval;
2555
2556     START_OF_INSTR();
2557     DECODE_PRINTF("SUB\tAL,");
2558     srcval = fetch_byte_imm();
2559     DECODE_PRINTF2("%x\n", srcval);
2560     TRACE_AND_STEP();
2561     M.x86.R_AL = sub_byte(M.x86.R_AL, srcval);
2562     DECODE_CLEAR_SEGOVR();
2563     END_OF_INSTR();
2564 }
2565
2566 /****************************************************************************
2567 REMARKS:
2568 Handles opcode 0x2d
2569 ****************************************************************************/
2570 void x86emuOp_sub_word_AX_IMM(u8 X86EMU_UNUSED(op1))
2571 {
2572     u32 srcval;
2573
2574     START_OF_INSTR();
2575     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2576         DECODE_PRINTF("SUB\tEAX,");
2577         srcval = fetch_long_imm();
2578     } else {
2579         DECODE_PRINTF("SUB\tAX,");
2580         srcval = fetch_word_imm();
2581     }
2582     DECODE_PRINTF2("%x\n", srcval);
2583     TRACE_AND_STEP();
2584     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2585         M.x86.R_EAX = sub_long(M.x86.R_EAX, srcval);
2586     } else {
2587         M.x86.R_AX = sub_word(M.x86.R_AX, (u16)srcval);
2588     }
2589     DECODE_CLEAR_SEGOVR();
2590     END_OF_INSTR();
2591 }
2592
2593 /****************************************************************************
2594 REMARKS:
2595 Handles opcode 0x2e
2596 ****************************************************************************/
2597 void x86emuOp_segovr_CS(u8 X86EMU_UNUSED(op1))
2598 {
2599     START_OF_INSTR();
2600     DECODE_PRINTF("CS:\n");
2601     TRACE_AND_STEP();
2602     M.x86.mode |= SYSMODE_SEGOVR_CS;
2603     /* note no DECODE_CLEAR_SEGOVR here. */
2604     END_OF_INSTR();
2605 }
2606
2607 /****************************************************************************
2608 REMARKS:
2609 Handles opcode 0x2f
2610 ****************************************************************************/
2611 void x86emuOp_das(u8 X86EMU_UNUSED(op1))
2612 {
2613     START_OF_INSTR();
2614     DECODE_PRINTF("DAS\n");
2615     TRACE_AND_STEP();
2616     M.x86.R_AL = das_byte(M.x86.R_AL);
2617     DECODE_CLEAR_SEGOVR();
2618     END_OF_INSTR();
2619 }
2620
2621 /****************************************************************************
2622 REMARKS:
2623 Handles opcode 0x30
2624 ****************************************************************************/
2625 void x86emuOp_xor_byte_RM_R(u8 X86EMU_UNUSED(op1))
2626 {
2627     int mod, rl, rh;
2628     u8 *destreg, *srcreg;
2629     uint destoffset;
2630     u8 destval;
2631
2632     START_OF_INSTR();
2633     DECODE_PRINTF("XOR\t");
2634     FETCH_DECODE_MODRM(mod, rh, rl);
2635     switch (mod) {
2636     case 0:
2637         destoffset = decode_rm00_address(rl);
2638         DECODE_PRINTF(",");
2639         destval = fetch_data_byte(destoffset);
2640         srcreg = DECODE_RM_BYTE_REGISTER(rh);
2641         DECODE_PRINTF("\n");
2642         TRACE_AND_STEP();
2643         destval = xor_byte(destval, *srcreg);
2644         store_data_byte(destoffset, destval);
2645         break;
2646     case 1:
2647         destoffset = decode_rm01_address(rl);
2648         DECODE_PRINTF(",");
2649         destval = fetch_data_byte(destoffset);
2650         srcreg = DECODE_RM_BYTE_REGISTER(rh);
2651         DECODE_PRINTF("\n");
2652         TRACE_AND_STEP();
2653         destval = xor_byte(destval, *srcreg);
2654         store_data_byte(destoffset, destval);
2655         break;
2656     case 2:
2657         destoffset = decode_rm10_address(rl);
2658         DECODE_PRINTF(",");
2659         destval = fetch_data_byte(destoffset);
2660         srcreg = DECODE_RM_BYTE_REGISTER(rh);
2661         DECODE_PRINTF("\n");
2662         TRACE_AND_STEP();
2663         destval = xor_byte(destval, *srcreg);
2664         store_data_byte(destoffset, destval);
2665         break;
2666     case 3:                     /* register to register */
2667         destreg = DECODE_RM_BYTE_REGISTER(rl);
2668         DECODE_PRINTF(",");
2669         srcreg = DECODE_RM_BYTE_REGISTER(rh);
2670         DECODE_PRINTF("\n");
2671         TRACE_AND_STEP();
2672         *destreg = xor_byte(*destreg, *srcreg);
2673         break;
2674     }
2675     DECODE_CLEAR_SEGOVR();
2676     END_OF_INSTR();
2677 }
2678
2679 /****************************************************************************
2680 REMARKS:
2681 Handles opcode 0x31
2682 ****************************************************************************/
2683 void x86emuOp_xor_word_RM_R(u8 X86EMU_UNUSED(op1))
2684 {
2685     int mod, rl, rh;
2686     uint destoffset;
2687
2688     START_OF_INSTR();
2689     DECODE_PRINTF("XOR\t");
2690     FETCH_DECODE_MODRM(mod, rh, rl);
2691     switch (mod) {
2692     case 0:
2693         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2694             u32 destval;
2695             u32 *srcreg;
2696
2697             destoffset = decode_rm00_address(rl);
2698             DECODE_PRINTF(",");
2699             destval = fetch_data_long(destoffset);
2700             srcreg = DECODE_RM_LONG_REGISTER(rh);
2701             DECODE_PRINTF("\n");
2702             TRACE_AND_STEP();
2703             destval = xor_long(destval, *srcreg);
2704             store_data_long(destoffset, destval);
2705         } else {
2706             u16 destval;
2707             u16 *srcreg;
2708
2709             destoffset = decode_rm00_address(rl);
2710             DECODE_PRINTF(",");
2711             destval = fetch_data_word(destoffset);
2712             srcreg = DECODE_RM_WORD_REGISTER(rh);
2713             DECODE_PRINTF("\n");
2714             TRACE_AND_STEP();
2715             destval = xor_word(destval, *srcreg);
2716             store_data_word(destoffset, destval);
2717         }
2718         break;
2719     case 1:
2720         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2721             u32 destval;
2722             u32 *srcreg;
2723
2724             destoffset = decode_rm01_address(rl);
2725             DECODE_PRINTF(",");
2726             destval = fetch_data_long(destoffset);
2727             srcreg = DECODE_RM_LONG_REGISTER(rh);
2728             DECODE_PRINTF("\n");
2729             TRACE_AND_STEP();
2730             destval = xor_long(destval, *srcreg);
2731             store_data_long(destoffset, destval);
2732         } else {
2733             u16 destval;
2734             u16 *srcreg;
2735
2736             destoffset = decode_rm01_address(rl);
2737             DECODE_PRINTF(",");
2738             destval = fetch_data_word(destoffset);
2739             srcreg = DECODE_RM_WORD_REGISTER(rh);
2740             DECODE_PRINTF("\n");
2741             TRACE_AND_STEP();
2742             destval = xor_word(destval, *srcreg);
2743             store_data_word(destoffset, destval);
2744         }
2745         break;
2746     case 2:
2747         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2748             u32 destval;
2749             u32 *srcreg;
2750
2751             destoffset = decode_rm10_address(rl);
2752             DECODE_PRINTF(",");
2753             destval = fetch_data_long(destoffset);
2754             srcreg = DECODE_RM_LONG_REGISTER(rh);
2755             DECODE_PRINTF("\n");
2756             TRACE_AND_STEP();
2757             destval = xor_long(destval, *srcreg);
2758             store_data_long(destoffset, destval);
2759         } else {
2760             u16 destval;
2761             u16 *srcreg;
2762
2763             destoffset = decode_rm10_address(rl);
2764             DECODE_PRINTF(",");
2765             destval = fetch_data_word(destoffset);
2766             srcreg = DECODE_RM_WORD_REGISTER(rh);
2767             DECODE_PRINTF("\n");
2768             TRACE_AND_STEP();
2769             destval = xor_word(destval, *srcreg);
2770             store_data_word(destoffset, destval);
2771         }
2772         break;
2773     case 3:                     /* register to register */
2774         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2775             u32 *destreg,*srcreg;
2776
2777             destreg = DECODE_RM_LONG_REGISTER(rl);
2778             DECODE_PRINTF(",");
2779             srcreg = DECODE_RM_LONG_REGISTER(rh);
2780             DECODE_PRINTF("\n");
2781             TRACE_AND_STEP();
2782             *destreg = xor_long(*destreg, *srcreg);
2783         } else {
2784             u16 *destreg,*srcreg;
2785
2786             destreg = DECODE_RM_WORD_REGISTER(rl);
2787             DECODE_PRINTF(",");
2788             srcreg = DECODE_RM_WORD_REGISTER(rh);
2789             DECODE_PRINTF("\n");
2790             TRACE_AND_STEP();
2791             *destreg = xor_word(*destreg, *srcreg);
2792         }
2793         break;
2794     }
2795     DECODE_CLEAR_SEGOVR();
2796     END_OF_INSTR();
2797 }
2798
2799 /****************************************************************************
2800 REMARKS:
2801 Handles opcode 0x32
2802 ****************************************************************************/
2803 void x86emuOp_xor_byte_R_RM(u8 X86EMU_UNUSED(op1))
2804 {
2805     int mod, rl, rh;
2806     u8 *destreg, *srcreg;
2807     uint srcoffset;
2808     u8 srcval;
2809
2810     START_OF_INSTR();
2811     DECODE_PRINTF("XOR\t");
2812     FETCH_DECODE_MODRM(mod, rh, rl);
2813     switch (mod) {
2814     case 0:
2815         destreg = DECODE_RM_BYTE_REGISTER(rh);
2816         DECODE_PRINTF(",");
2817         srcoffset = decode_rm00_address(rl);
2818         srcval = fetch_data_byte(srcoffset);
2819         DECODE_PRINTF("\n");
2820         TRACE_AND_STEP();
2821         *destreg = xor_byte(*destreg, srcval);
2822         break;
2823     case 1:
2824         destreg = DECODE_RM_BYTE_REGISTER(rh);
2825         DECODE_PRINTF(",");
2826         srcoffset = decode_rm01_address(rl);
2827         srcval = fetch_data_byte(srcoffset);
2828         DECODE_PRINTF("\n");
2829         TRACE_AND_STEP();
2830         *destreg = xor_byte(*destreg, srcval);
2831         break;
2832     case 2:
2833         destreg = DECODE_RM_BYTE_REGISTER(rh);
2834         DECODE_PRINTF(",");
2835         srcoffset = decode_rm10_address(rl);
2836         srcval = fetch_data_byte(srcoffset);
2837         DECODE_PRINTF("\n");
2838         TRACE_AND_STEP();
2839         *destreg = xor_byte(*destreg, srcval);
2840         break;
2841     case 3:                     /* register to register */
2842         destreg = DECODE_RM_BYTE_REGISTER(rh);
2843         DECODE_PRINTF(",");
2844         srcreg = DECODE_RM_BYTE_REGISTER(rl);
2845         DECODE_PRINTF("\n");
2846         TRACE_AND_STEP();
2847         *destreg = xor_byte(*destreg, *srcreg);
2848         break;
2849     }
2850     DECODE_CLEAR_SEGOVR();
2851     END_OF_INSTR();
2852 }
2853
2854 /****************************************************************************
2855 REMARKS:
2856 Handles opcode 0x33
2857 ****************************************************************************/
2858 void x86emuOp_xor_word_R_RM(u8 X86EMU_UNUSED(op1))
2859 {
2860     int mod, rl, rh;
2861     uint srcoffset;
2862
2863     START_OF_INSTR();
2864     DECODE_PRINTF("XOR\t");
2865     FETCH_DECODE_MODRM(mod, rh, rl);
2866     switch (mod) {
2867     case 0:
2868         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2869             u32 *destreg;
2870             u32 srcval;
2871
2872             destreg = DECODE_RM_LONG_REGISTER(rh);
2873             DECODE_PRINTF(",");
2874             srcoffset = decode_rm00_address(rl);
2875             srcval = fetch_data_long(srcoffset);
2876             DECODE_PRINTF("\n");
2877             TRACE_AND_STEP();
2878             *destreg = xor_long(*destreg, srcval);
2879         } else {
2880             u16 *destreg;
2881             u16 srcval;
2882
2883             destreg = DECODE_RM_WORD_REGISTER(rh);
2884             DECODE_PRINTF(",");
2885             srcoffset = decode_rm00_address(rl);
2886             srcval = fetch_data_word(srcoffset);
2887             DECODE_PRINTF("\n");
2888             TRACE_AND_STEP();
2889             *destreg = xor_word(*destreg, srcval);
2890         }
2891         break;
2892     case 1:
2893         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2894             u32 *destreg;
2895             u32 srcval;
2896
2897             destreg = DECODE_RM_LONG_REGISTER(rh);
2898             DECODE_PRINTF(",");
2899             srcoffset = decode_rm01_address(rl);
2900             srcval = fetch_data_long(srcoffset);
2901             DECODE_PRINTF("\n");
2902             TRACE_AND_STEP();
2903             *destreg = xor_long(*destreg, srcval);
2904         } else {
2905             u16 *destreg;
2906             u16 srcval;
2907
2908             destreg = DECODE_RM_WORD_REGISTER(rh);
2909             DECODE_PRINTF(",");
2910             srcoffset = decode_rm01_address(rl);
2911             srcval = fetch_data_word(srcoffset);
2912             DECODE_PRINTF("\n");
2913             TRACE_AND_STEP();
2914             *destreg = xor_word(*destreg, srcval);
2915         }
2916         break;
2917     case 2:
2918         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2919             u32 *destreg;
2920             u32 srcval;
2921
2922             destreg = DECODE_RM_LONG_REGISTER(rh);
2923             DECODE_PRINTF(",");
2924             srcoffset = decode_rm10_address(rl);
2925             srcval = fetch_data_long(srcoffset);
2926             DECODE_PRINTF("\n");
2927             TRACE_AND_STEP();
2928             *destreg = xor_long(*destreg, srcval);
2929         } else {
2930             u16 *destreg;
2931             u16 srcval;
2932
2933             destreg = DECODE_RM_WORD_REGISTER(rh);
2934             DECODE_PRINTF(",");
2935             srcoffset = decode_rm10_address(rl);
2936             srcval = fetch_data_word(srcoffset);
2937             DECODE_PRINTF("\n");
2938             TRACE_AND_STEP();
2939             *destreg = xor_word(*destreg, srcval);
2940         }
2941         break;
2942     case 3:                     /* register to register */
2943         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2944             u32 *destreg,*srcreg;
2945
2946             destreg = DECODE_RM_LONG_REGISTER(rh);
2947             DECODE_PRINTF(",");
2948             srcreg = DECODE_RM_LONG_REGISTER(rl);
2949             DECODE_PRINTF("\n");
2950             TRACE_AND_STEP();
2951             *destreg = xor_long(*destreg, *srcreg);
2952         } else {
2953             u16 *destreg,*srcreg;
2954
2955             destreg = DECODE_RM_WORD_REGISTER(rh);
2956             DECODE_PRINTF(",");
2957             srcreg = DECODE_RM_WORD_REGISTER(rl);
2958             DECODE_PRINTF("\n");
2959             TRACE_AND_STEP();
2960             *destreg = xor_word(*destreg, *srcreg);
2961         }
2962         break;
2963     }
2964     DECODE_CLEAR_SEGOVR();
2965     END_OF_INSTR();
2966 }
2967
2968 /****************************************************************************
2969 REMARKS:
2970 Handles opcode 0x34
2971 ****************************************************************************/
2972 void x86emuOp_xor_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
2973 {
2974     u8 srcval;
2975
2976     START_OF_INSTR();
2977     DECODE_PRINTF("XOR\tAL,");
2978     srcval = fetch_byte_imm();
2979     DECODE_PRINTF2("%x\n", srcval);
2980     TRACE_AND_STEP();
2981     M.x86.R_AL = xor_byte(M.x86.R_AL, srcval);
2982     DECODE_CLEAR_SEGOVR();
2983     END_OF_INSTR();
2984 }
2985
2986 /****************************************************************************
2987 REMARKS:
2988 Handles opcode 0x35
2989 ****************************************************************************/
2990 void x86emuOp_xor_word_AX_IMM(u8 X86EMU_UNUSED(op1))
2991 {
2992     u32 srcval;
2993
2994     START_OF_INSTR();
2995     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2996         DECODE_PRINTF("XOR\tEAX,");
2997         srcval = fetch_long_imm();
2998     } else {
2999         DECODE_PRINTF("XOR\tAX,");
3000         srcval = fetch_word_imm();
3001     }
3002     DECODE_PRINTF2("%x\n", srcval);
3003     TRACE_AND_STEP();
3004     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3005         M.x86.R_EAX = xor_long(M.x86.R_EAX, srcval);
3006     } else {
3007         M.x86.R_AX = xor_word(M.x86.R_AX, (u16)srcval);
3008     }
3009     DECODE_CLEAR_SEGOVR();
3010     END_OF_INSTR();
3011 }
3012
3013 /****************************************************************************
3014 REMARKS:
3015 Handles opcode 0x36
3016 ****************************************************************************/
3017 void x86emuOp_segovr_SS(u8 X86EMU_UNUSED(op1))
3018 {
3019     START_OF_INSTR();
3020     DECODE_PRINTF("SS:\n");
3021     TRACE_AND_STEP();
3022     M.x86.mode |= SYSMODE_SEGOVR_SS;
3023     /* no DECODE_CLEAR_SEGOVR ! */
3024     END_OF_INSTR();
3025 }
3026
3027 /****************************************************************************
3028 REMARKS:
3029 Handles opcode 0x37
3030 ****************************************************************************/
3031 void x86emuOp_aaa(u8 X86EMU_UNUSED(op1))
3032 {
3033     START_OF_INSTR();
3034     DECODE_PRINTF("AAA\n");
3035     TRACE_AND_STEP();
3036     M.x86.R_AX = aaa_word(M.x86.R_AX);
3037     DECODE_CLEAR_SEGOVR();
3038     END_OF_INSTR();
3039 }
3040
3041 /****************************************************************************
3042 REMARKS:
3043 Handles opcode 0x38
3044 ****************************************************************************/
3045 void x86emuOp_cmp_byte_RM_R(u8 X86EMU_UNUSED(op1))
3046 {
3047     int mod, rl, rh;
3048     uint destoffset;
3049     u8 *destreg, *srcreg;
3050     u8 destval;
3051
3052     START_OF_INSTR();
3053     DECODE_PRINTF("CMP\t");
3054     FETCH_DECODE_MODRM(mod, rh, rl);
3055     switch (mod) {
3056     case 0:
3057         destoffset = decode_rm00_address(rl);
3058         DECODE_PRINTF(",");
3059         destval = fetch_data_byte(destoffset);
3060         srcreg = DECODE_RM_BYTE_REGISTER(rh);
3061         DECODE_PRINTF("\n");
3062         TRACE_AND_STEP();
3063         cmp_byte(destval, *srcreg);
3064         break;
3065     case 1:
3066         destoffset = decode_rm01_address(rl);
3067         DECODE_PRINTF(",");
3068         destval = fetch_data_byte(destoffset);
3069         srcreg = DECODE_RM_BYTE_REGISTER(rh);
3070         DECODE_PRINTF("\n");
3071         TRACE_AND_STEP();
3072         cmp_byte(destval, *srcreg);
3073         break;
3074     case 2:
3075         destoffset = decode_rm10_address(rl);
3076         DECODE_PRINTF(",");
3077         destval = fetch_data_byte(destoffset);
3078         srcreg = DECODE_RM_BYTE_REGISTER(rh);
3079         DECODE_PRINTF("\n");
3080         TRACE_AND_STEP();
3081         cmp_byte(destval, *srcreg);
3082         break;
3083     case 3:                     /* register to register */
3084         destreg = DECODE_RM_BYTE_REGISTER(rl);
3085         DECODE_PRINTF(",");
3086         srcreg = DECODE_RM_BYTE_REGISTER(rh);
3087         DECODE_PRINTF("\n");
3088         TRACE_AND_STEP();
3089         cmp_byte(*destreg, *srcreg);
3090         break;
3091     }
3092     DECODE_CLEAR_SEGOVR();
3093     END_OF_INSTR();
3094 }
3095
3096 /****************************************************************************
3097 REMARKS:
3098 Handles opcode 0x39
3099 ****************************************************************************/
3100 void x86emuOp_cmp_word_RM_R(u8 X86EMU_UNUSED(op1))
3101 {
3102     int mod, rl, rh;
3103     uint destoffset;
3104
3105     START_OF_INSTR();
3106     DECODE_PRINTF("CMP\t");
3107     FETCH_DECODE_MODRM(mod, rh, rl);
3108     switch (mod) {
3109     case 0:
3110         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3111             u32 destval;
3112             u32 *srcreg;
3113
3114             destoffset = decode_rm00_address(rl);
3115             DECODE_PRINTF(",");
3116             destval = fetch_data_long(destoffset);
3117             srcreg = DECODE_RM_LONG_REGISTER(rh);
3118             DECODE_PRINTF("\n");
3119             TRACE_AND_STEP();
3120             cmp_long(destval, *srcreg);
3121         } else {
3122             u16 destval;
3123             u16 *srcreg;
3124
3125             destoffset = decode_rm00_address(rl);
3126             DECODE_PRINTF(",");
3127             destval = fetch_data_word(destoffset);
3128             srcreg = DECODE_RM_WORD_REGISTER(rh);
3129             DECODE_PRINTF("\n");
3130             TRACE_AND_STEP();
3131             cmp_word(destval, *srcreg);
3132         }
3133         break;
3134     case 1:
3135         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3136             u32 destval;
3137             u32 *srcreg;
3138
3139             destoffset = decode_rm01_address(rl);
3140             DECODE_PRINTF(",");
3141             destval = fetch_data_long(destoffset);
3142             srcreg = DECODE_RM_LONG_REGISTER(rh);
3143             DECODE_PRINTF("\n");
3144             TRACE_AND_STEP();
3145             cmp_long(destval, *srcreg);
3146         } else {
3147             u16 destval;
3148             u16 *srcreg;
3149
3150             destoffset = decode_rm01_address(rl);
3151             DECODE_PRINTF(",");
3152             destval = fetch_data_word(destoffset);
3153             srcreg = DECODE_RM_WORD_REGISTER(rh);
3154             DECODE_PRINTF("\n");
3155             TRACE_AND_STEP();
3156             cmp_word(destval, *srcreg);
3157         }
3158         break;
3159     case 2:
3160         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3161             u32 destval;
3162             u32 *srcreg;
3163
3164             destoffset = decode_rm10_address(rl);
3165             DECODE_PRINTF(",");
3166             destval = fetch_data_long(destoffset);
3167             srcreg = DECODE_RM_LONG_REGISTER(rh);
3168             DECODE_PRINTF("\n");
3169             TRACE_AND_STEP();
3170             cmp_long(destval, *srcreg);
3171         } else {
3172             u16 destval;
3173             u16 *srcreg;
3174
3175             destoffset = decode_rm10_address(rl);
3176             DECODE_PRINTF(",");
3177             destval = fetch_data_word(destoffset);
3178             srcreg = DECODE_RM_WORD_REGISTER(rh);
3179             DECODE_PRINTF("\n");
3180             TRACE_AND_STEP();
3181             cmp_word(destval, *srcreg);
3182         }
3183         break;
3184     case 3:                     /* register to register */
3185         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3186             u32 *destreg,*srcreg;
3187
3188             destreg = DECODE_RM_LONG_REGISTER(rl);
3189             DECODE_PRINTF(",");
3190             srcreg = DECODE_RM_LONG_REGISTER(rh);
3191             DECODE_PRINTF("\n");
3192             TRACE_AND_STEP();
3193             cmp_long(*destreg, *srcreg);
3194         } else {
3195             u16 *destreg,*srcreg;
3196
3197             destreg = DECODE_RM_WORD_REGISTER(rl);
3198             DECODE_PRINTF(",");
3199             srcreg = DECODE_RM_WORD_REGISTER(rh);
3200             DECODE_PRINTF("\n");
3201             TRACE_AND_STEP();
3202             cmp_word(*destreg, *srcreg);
3203         }
3204         break;
3205     }
3206     DECODE_CLEAR_SEGOVR();
3207     END_OF_INSTR();
3208 }
3209
3210 /****************************************************************************
3211 REMARKS:
3212 Handles opcode 0x3a
3213 ****************************************************************************/
3214 void x86emuOp_cmp_byte_R_RM(u8 X86EMU_UNUSED(op1))
3215 {
3216     int mod, rl, rh;
3217     u8 *destreg, *srcreg;
3218     uint srcoffset;
3219     u8 srcval;
3220
3221     START_OF_INSTR();
3222     DECODE_PRINTF("CMP\t");
3223     FETCH_DECODE_MODRM(mod, rh, rl);
3224     switch (mod) {
3225     case 0:
3226         destreg = DECODE_RM_BYTE_REGISTER(rh);
3227         DECODE_PRINTF(",");
3228         srcoffset = decode_rm00_address(rl);
3229         srcval = fetch_data_byte(srcoffset);
3230         DECODE_PRINTF("\n");
3231         TRACE_AND_STEP();
3232         cmp_byte(*destreg, srcval);
3233         break;
3234     case 1:
3235         destreg = DECODE_RM_BYTE_REGISTER(rh);
3236         DECODE_PRINTF(",");
3237         srcoffset = decode_rm01_address(rl);
3238         srcval = fetch_data_byte(srcoffset);
3239         DECODE_PRINTF("\n");
3240         TRACE_AND_STEP();
3241         cmp_byte(*destreg, srcval);
3242         break;
3243     case 2:
3244         destreg = DECODE_RM_BYTE_REGISTER(rh);
3245         DECODE_PRINTF(",");
3246         srcoffset = decode_rm10_address(rl);
3247         srcval = fetch_data_byte(srcoffset);
3248         DECODE_PRINTF("\n");
3249         TRACE_AND_STEP();
3250         cmp_byte(*destreg, srcval);
3251         break;
3252     case 3:                     /* register to register */
3253         destreg = DECODE_RM_BYTE_REGISTER(rh);
3254         DECODE_PRINTF(",");
3255         srcreg = DECODE_RM_BYTE_REGISTER(rl);
3256         DECODE_PRINTF("\n");
3257         TRACE_AND_STEP();
3258         cmp_byte(*destreg, *srcreg);
3259         break;
3260     }
3261     DECODE_CLEAR_SEGOVR();
3262     END_OF_INSTR();
3263 }
3264
3265 /****************************************************************************
3266 REMARKS:
3267 Handles opcode 0x3b
3268 ****************************************************************************/
3269 void x86emuOp_cmp_word_R_RM(u8 X86EMU_UNUSED(op1))
3270 {
3271     int mod, rl, rh;
3272     uint srcoffset;
3273
3274     START_OF_INSTR();
3275     DECODE_PRINTF("CMP\t");
3276     FETCH_DECODE_MODRM(mod, rh, rl);
3277     switch (mod) {
3278     case 0:
3279         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3280             u32 *destreg;
3281             u32 srcval;
3282
3283             destreg = DECODE_RM_LONG_REGISTER(rh);
3284             DECODE_PRINTF(",");
3285             srcoffset = decode_rm00_address(rl);
3286             srcval = fetch_data_long(srcoffset);
3287             DECODE_PRINTF("\n");
3288             TRACE_AND_STEP();
3289             cmp_long(*destreg, srcval);
3290         } else {
3291             u16 *destreg;
3292             u16 srcval;
3293
3294             destreg = DECODE_RM_WORD_REGISTER(rh);
3295             DECODE_PRINTF(",");
3296             srcoffset = decode_rm00_address(rl);
3297             srcval = fetch_data_word(srcoffset);
3298             DECODE_PRINTF("\n");
3299             TRACE_AND_STEP();
3300             cmp_word(*destreg, srcval);
3301         }
3302         break;
3303     case 1:
3304         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3305             u32 *destreg;
3306             u32 srcval;
3307
3308             destreg = DECODE_RM_LONG_REGISTER(rh);
3309             DECODE_PRINTF(",");
3310             srcoffset = decode_rm01_address(rl);
3311             srcval = fetch_data_long(srcoffset);
3312             DECODE_PRINTF("\n");
3313             TRACE_AND_STEP();
3314             cmp_long(*destreg, srcval);
3315         } else {
3316             u16 *destreg;
3317             u16 srcval;
3318
3319             destreg = DECODE_RM_WORD_REGISTER(rh);
3320             DECODE_PRINTF(",");
3321             srcoffset = decode_rm01_address(rl);
3322             srcval = fetch_data_word(srcoffset);
3323             DECODE_PRINTF("\n");
3324             TRACE_AND_STEP();
3325             cmp_word(*destreg, srcval);
3326         }
3327         break;
3328     case 2:
3329         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3330             u32 *destreg;
3331             u32 srcval;
3332
3333             destreg = DECODE_RM_LONG_REGISTER(rh);
3334             DECODE_PRINTF(",");
3335             srcoffset = decode_rm10_address(rl);
3336             srcval = fetch_data_long(srcoffset);
3337             DECODE_PRINTF("\n");
3338             TRACE_AND_STEP();
3339             cmp_long(*destreg, srcval);
3340         } else {
3341             u16 *destreg;
3342             u16 srcval;
3343
3344             destreg = DECODE_RM_WORD_REGISTER(rh);
3345             DECODE_PRINTF(",");
3346             srcoffset = decode_rm10_address(rl);
3347             srcval = fetch_data_word(srcoffset);
3348             DECODE_PRINTF("\n");
3349             TRACE_AND_STEP();
3350             cmp_word(*destreg, srcval);
3351         }
3352         break;
3353     case 3:                     /* register to register */
3354         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3355             u32 *destreg,*srcreg;
3356
3357             destreg = DECODE_RM_LONG_REGISTER(rh);
3358             DECODE_PRINTF(",");
3359             srcreg = DECODE_RM_LONG_REGISTER(rl);
3360             DECODE_PRINTF("\n");
3361             TRACE_AND_STEP();
3362             cmp_long(*destreg, *srcreg);
3363         } else {
3364             u16 *destreg,*srcreg;
3365
3366             destreg = DECODE_RM_WORD_REGISTER(rh);
3367             DECODE_PRINTF(",");
3368             srcreg = DECODE_RM_WORD_REGISTER(rl);
3369             DECODE_PRINTF("\n");
3370             TRACE_AND_STEP();
3371             cmp_word(*destreg, *srcreg);
3372         }
3373         break;
3374     }
3375     DECODE_CLEAR_SEGOVR();
3376     END_OF_INSTR();
3377 }
3378
3379 /****************************************************************************
3380 REMARKS:
3381 Handles opcode 0x3c
3382 ****************************************************************************/
3383 void x86emuOp_cmp_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
3384 {
3385     u8 srcval;
3386
3387     START_OF_INSTR();
3388     DECODE_PRINTF("CMP\tAL,");
3389     srcval = fetch_byte_imm();
3390     DECODE_PRINTF2("%x\n", srcval);
3391     TRACE_AND_STEP();
3392     cmp_byte(M.x86.R_AL, srcval);
3393     DECODE_CLEAR_SEGOVR();
3394     END_OF_INSTR();
3395 }
3396
3397 /****************************************************************************
3398 REMARKS:
3399 Handles opcode 0x3d
3400 ****************************************************************************/
3401 void x86emuOp_cmp_word_AX_IMM(u8 X86EMU_UNUSED(op1))
3402 {
3403     u32 srcval;
3404
3405     START_OF_INSTR();
3406     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3407         DECODE_PRINTF("CMP\tEAX,");
3408         srcval = fetch_long_imm();
3409     } else {
3410         DECODE_PRINTF("CMP\tAX,");
3411         srcval = fetch_word_imm();
3412     }
3413     DECODE_PRINTF2("%x\n", srcval);
3414     TRACE_AND_STEP();
3415     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3416         cmp_long(M.x86.R_EAX, srcval);
3417     } else {
3418         cmp_word(M.x86.R_AX, (u16)srcval);
3419     }
3420     DECODE_CLEAR_SEGOVR();
3421     END_OF_INSTR();
3422 }
3423
3424 /****************************************************************************
3425 REMARKS:
3426 Handles opcode 0x3e
3427 ****************************************************************************/
3428 void x86emuOp_segovr_DS(u8 X86EMU_UNUSED(op1))
3429 {
3430     START_OF_INSTR();
3431     DECODE_PRINTF("DS:\n");
3432     TRACE_AND_STEP();
3433     M.x86.mode |= SYSMODE_SEGOVR_DS;
3434     /* NO DECODE_CLEAR_SEGOVR! */
3435     END_OF_INSTR();
3436 }
3437
3438 /****************************************************************************
3439 REMARKS:
3440 Handles opcode 0x3f
3441 ****************************************************************************/
3442 void x86emuOp_aas(u8 X86EMU_UNUSED(op1))
3443 {
3444     START_OF_INSTR();
3445     DECODE_PRINTF("AAS\n");
3446     TRACE_AND_STEP();
3447     M.x86.R_AX = aas_word(M.x86.R_AX);
3448     DECODE_CLEAR_SEGOVR();
3449     END_OF_INSTR();
3450 }
3451
3452 /****************************************************************************
3453 REMARKS:
3454 Handles opcode 0x40
3455 ****************************************************************************/
3456 void x86emuOp_inc_AX(u8 X86EMU_UNUSED(op1))
3457 {
3458     START_OF_INSTR();
3459     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3460         DECODE_PRINTF("INC\tEAX\n");
3461     } else {
3462         DECODE_PRINTF("INC\tAX\n");
3463     }
3464     TRACE_AND_STEP();
3465     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3466         M.x86.R_EAX = inc_long(M.x86.R_EAX);
3467     } else {
3468         M.x86.R_AX = inc_word(M.x86.R_AX);
3469     }
3470     DECODE_CLEAR_SEGOVR();
3471     END_OF_INSTR();
3472 }
3473
3474 /****************************************************************************
3475 REMARKS:
3476 Handles opcode 0x41
3477 ****************************************************************************/
3478 void x86emuOp_inc_CX(u8 X86EMU_UNUSED(op1))
3479 {
3480     START_OF_INSTR();
3481     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3482         DECODE_PRINTF("INC\tECX\n");
3483     } else {
3484         DECODE_PRINTF("INC\tCX\n");
3485     }
3486     TRACE_AND_STEP();
3487     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3488         M.x86.R_ECX = inc_long(M.x86.R_ECX);
3489     } else {
3490         M.x86.R_CX = inc_word(M.x86.R_CX);
3491     }
3492     DECODE_CLEAR_SEGOVR();
3493     END_OF_INSTR();
3494 }
3495
3496 /****************************************************************************
3497 REMARKS:
3498 Handles opcode 0x42
3499 ****************************************************************************/
3500 void x86emuOp_inc_DX(u8 X86EMU_UNUSED(op1))
3501 {
3502     START_OF_INSTR();
3503     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3504         DECODE_PRINTF("INC\tEDX\n");
3505     } else {
3506         DECODE_PRINTF("INC\tDX\n");
3507     }
3508     TRACE_AND_STEP();
3509     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3510         M.x86.R_EDX = inc_long(M.x86.R_EDX);
3511     } else {
3512         M.x86.R_DX = inc_word(M.x86.R_DX);
3513     }
3514     DECODE_CLEAR_SEGOVR();
3515     END_OF_INSTR();
3516 }
3517
3518 /****************************************************************************
3519 REMARKS:
3520 Handles opcode 0x43
3521 ****************************************************************************/
3522 void x86emuOp_inc_BX(u8 X86EMU_UNUSED(op1))
3523 {
3524     START_OF_INSTR();
3525     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3526         DECODE_PRINTF("INC\tEBX\n");
3527     } else {
3528         DECODE_PRINTF("INC\tBX\n");
3529     }
3530     TRACE_AND_STEP();
3531     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3532         M.x86.R_EBX = inc_long(M.x86.R_EBX);
3533     } else {
3534         M.x86.R_BX = inc_word(M.x86.R_BX);
3535     }
3536     DECODE_CLEAR_SEGOVR();
3537     END_OF_INSTR();
3538 }
3539
3540 /****************************************************************************
3541 REMARKS:
3542 Handles opcode 0x44
3543 ****************************************************************************/
3544 void x86emuOp_inc_SP(u8 X86EMU_UNUSED(op1))
3545 {
3546     START_OF_INSTR();
3547     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3548         DECODE_PRINTF("INC\tESP\n");
3549     } else {
3550         DECODE_PRINTF("INC\tSP\n");
3551     }
3552     TRACE_AND_STEP();
3553     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3554         M.x86.R_ESP = inc_long(M.x86.R_ESP);
3555     } else {
3556         M.x86.R_SP = inc_word(M.x86.R_SP);
3557     }
3558     DECODE_CLEAR_SEGOVR();
3559     END_OF_INSTR();
3560 }
3561
3562 /****************************************************************************
3563 REMARKS:
3564 Handles opcode 0x45
3565 ****************************************************************************/
3566 void x86emuOp_inc_BP(u8 X86EMU_UNUSED(op1))
3567 {
3568     START_OF_INSTR();
3569     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3570         DECODE_PRINTF("INC\tEBP\n");
3571     } else {
3572         DECODE_PRINTF("INC\tBP\n");
3573     }
3574     TRACE_AND_STEP();
3575     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3576         M.x86.R_EBP = inc_long(M.x86.R_EBP);
3577     } else {
3578         M.x86.R_BP = inc_word(M.x86.R_BP);
3579     }
3580     DECODE_CLEAR_SEGOVR();
3581     END_OF_INSTR();
3582 }
3583
3584 /****************************************************************************
3585 REMARKS:
3586 Handles opcode 0x46
3587 ****************************************************************************/
3588 void x86emuOp_inc_SI(u8 X86EMU_UNUSED(op1))
3589 {
3590     START_OF_INSTR();
3591     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3592         DECODE_PRINTF("INC\tESI\n");
3593     } else {
3594         DECODE_PRINTF("INC\tSI\n");
3595     }
3596     TRACE_AND_STEP();
3597     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3598         M.x86.R_ESI = inc_long(M.x86.R_ESI);
3599     } else {
3600         M.x86.R_SI = inc_word(M.x86.R_SI);
3601     }
3602     DECODE_CLEAR_SEGOVR();
3603     END_OF_INSTR();
3604 }
3605
3606 /****************************************************************************
3607 REMARKS:
3608 Handles opcode 0x47
3609 ****************************************************************************/
3610 void x86emuOp_inc_DI(u8 X86EMU_UNUSED(op1))
3611 {
3612     START_OF_INSTR();
3613     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3614         DECODE_PRINTF("INC\tEDI\n");
3615     } else {
3616         DECODE_PRINTF("INC\tDI\n");
3617     }
3618     TRACE_AND_STEP();
3619     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3620         M.x86.R_EDI = inc_long(M.x86.R_EDI);
3621     } else {
3622         M.x86.R_DI = inc_word(M.x86.R_DI);
3623     }
3624     DECODE_CLEAR_SEGOVR();
3625     END_OF_INSTR();
3626 }
3627
3628 /****************************************************************************
3629 REMARKS:
3630 Handles opcode 0x48
3631 ****************************************************************************/
3632 void x86emuOp_dec_AX(u8 X86EMU_UNUSED(op1))
3633 {
3634     START_OF_INSTR();
3635     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3636         DECODE_PRINTF("DEC\tEAX\n");
3637     } else {
3638         DECODE_PRINTF("DEC\tAX\n");
3639     }
3640     TRACE_AND_STEP();
3641     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3642         M.x86.R_EAX = dec_long(M.x86.R_EAX);
3643     } else {
3644         M.x86.R_AX = dec_word(M.x86.R_AX);
3645     }
3646     DECODE_CLEAR_SEGOVR();
3647     END_OF_INSTR();
3648 }
3649
3650 /****************************************************************************
3651 REMARKS:
3652 Handles opcode 0x49
3653 ****************************************************************************/
3654 void x86emuOp_dec_CX(u8 X86EMU_UNUSED(op1))
3655 {
3656     START_OF_INSTR();
3657     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3658         DECODE_PRINTF("DEC\tECX\n");
3659     } else {
3660         DECODE_PRINTF("DEC\tCX\n");
3661     }
3662     TRACE_AND_STEP();
3663     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3664         M.x86.R_ECX = dec_long(M.x86.R_ECX);
3665     } else {
3666         M.x86.R_CX = dec_word(M.x86.R_CX);
3667     }
3668     DECODE_CLEAR_SEGOVR();
3669     END_OF_INSTR();
3670 }
3671
3672 /****************************************************************************
3673 REMARKS:
3674 Handles opcode 0x4a
3675 ****************************************************************************/
3676 void x86emuOp_dec_DX(u8 X86EMU_UNUSED(op1))
3677 {
3678     START_OF_INSTR();
3679     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3680         DECODE_PRINTF("DEC\tEDX\n");
3681     } else {
3682         DECODE_PRINTF("DEC\tDX\n");
3683     }
3684     TRACE_AND_STEP();
3685     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3686         M.x86.R_EDX = dec_long(M.x86.R_EDX);
3687     } else {
3688         M.x86.R_DX = dec_word(M.x86.R_DX);
3689     }
3690     DECODE_CLEAR_SEGOVR();
3691     END_OF_INSTR();
3692 }
3693
3694 /****************************************************************************
3695 REMARKS:
3696 Handles opcode 0x4b
3697 ****************************************************************************/
3698 void x86emuOp_dec_BX(u8 X86EMU_UNUSED(op1))
3699 {
3700     START_OF_INSTR();
3701     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3702         DECODE_PRINTF("DEC\tEBX\n");
3703     } else {
3704         DECODE_PRINTF("DEC\tBX\n");
3705     }
3706     TRACE_AND_STEP();
3707     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3708         M.x86.R_EBX = dec_long(M.x86.R_EBX);
3709     } else {
3710         M.x86.R_BX = dec_word(M.x86.R_BX);
3711     }
3712     DECODE_CLEAR_SEGOVR();
3713     END_OF_INSTR();
3714 }
3715
3716 /****************************************************************************
3717 REMARKS:
3718 Handles opcode 0x4c
3719 ****************************************************************************/
3720 void x86emuOp_dec_SP(u8 X86EMU_UNUSED(op1))
3721 {
3722     START_OF_INSTR();
3723     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3724         DECODE_PRINTF("DEC\tESP\n");
3725     } else {
3726         DECODE_PRINTF("DEC\tSP\n");
3727     }
3728     TRACE_AND_STEP();
3729     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3730         M.x86.R_ESP = dec_long(M.x86.R_ESP);
3731     } else {
3732         M.x86.R_SP = dec_word(M.x86.R_SP);
3733     }
3734     DECODE_CLEAR_SEGOVR();
3735     END_OF_INSTR();
3736 }
3737
3738 /****************************************************************************
3739 REMARKS:
3740 Handles opcode 0x4d
3741 ****************************************************************************/
3742 void x86emuOp_dec_BP(u8 X86EMU_UNUSED(op1))
3743 {
3744     START_OF_INSTR();
3745     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3746         DECODE_PRINTF("DEC\tEBP\n");
3747     } else {
3748         DECODE_PRINTF("DEC\tBP\n");
3749     }
3750     TRACE_AND_STEP();
3751     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3752         M.x86.R_EBP = dec_long(M.x86.R_EBP);
3753     } else {
3754         M.x86.R_BP = dec_word(M.x86.R_BP);
3755     }
3756     DECODE_CLEAR_SEGOVR();
3757     END_OF_INSTR();
3758 }
3759
3760 /****************************************************************************
3761 REMARKS:
3762 Handles opcode 0x4e
3763 ****************************************************************************/
3764 void x86emuOp_dec_SI(u8 X86EMU_UNUSED(op1))
3765 {
3766     START_OF_INSTR();
3767     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3768         DECODE_PRINTF("DEC\tESI\n");
3769     } else {
3770         DECODE_PRINTF("DEC\tSI\n");
3771     }
3772     TRACE_AND_STEP();
3773     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3774         M.x86.R_ESI = dec_long(M.x86.R_ESI);
3775     } else {
3776         M.x86.R_SI = dec_word(M.x86.R_SI);
3777     }
3778     DECODE_CLEAR_SEGOVR();
3779     END_OF_INSTR();
3780 }
3781
3782 /****************************************************************************
3783 REMARKS:
3784 Handles opcode 0x4f
3785 ****************************************************************************/
3786 void x86emuOp_dec_DI(u8 X86EMU_UNUSED(op1))
3787 {
3788     START_OF_INSTR();
3789     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3790         DECODE_PRINTF("DEC\tEDI\n");
3791     } else {
3792         DECODE_PRINTF("DEC\tDI\n");
3793     }
3794     TRACE_AND_STEP();
3795     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3796         M.x86.R_EDI = dec_long(M.x86.R_EDI);
3797     } else {
3798         M.x86.R_DI = dec_word(M.x86.R_DI);
3799     }
3800     DECODE_CLEAR_SEGOVR();
3801     END_OF_INSTR();
3802 }
3803
3804 /****************************************************************************
3805 REMARKS:
3806 Handles opcode 0x50
3807 ****************************************************************************/
3808 void x86emuOp_push_AX(u8 X86EMU_UNUSED(op1))
3809 {
3810     START_OF_INSTR();
3811     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3812         DECODE_PRINTF("PUSH\tEAX\n");
3813     } else {
3814         DECODE_PRINTF("PUSH\tAX\n");
3815     }
3816     TRACE_AND_STEP();
3817     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3818         push_long(M.x86.R_EAX);
3819     } else {
3820         push_word(M.x86.R_AX);
3821     }
3822     DECODE_CLEAR_SEGOVR();
3823     END_OF_INSTR();
3824 }
3825
3826 /****************************************************************************
3827 REMARKS:
3828 Handles opcode 0x51
3829 ****************************************************************************/
3830 void x86emuOp_push_CX(u8 X86EMU_UNUSED(op1))
3831 {
3832     START_OF_INSTR();
3833     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3834         DECODE_PRINTF("PUSH\tECX\n");
3835     } else {
3836         DECODE_PRINTF("PUSH\tCX\n");
3837     }
3838     TRACE_AND_STEP();
3839     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3840         push_long(M.x86.R_ECX);
3841     } else {
3842         push_word(M.x86.R_CX);
3843     }
3844     DECODE_CLEAR_SEGOVR();
3845     END_OF_INSTR();
3846 }
3847
3848 /****************************************************************************
3849 REMARKS:
3850 Handles opcode 0x52
3851 ****************************************************************************/
3852 void x86emuOp_push_DX(u8 X86EMU_UNUSED(op1))
3853 {
3854     START_OF_INSTR();
3855     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3856         DECODE_PRINTF("PUSH\tEDX\n");
3857     } else {
3858         DECODE_PRINTF("PUSH\tDX\n");
3859     }
3860     TRACE_AND_STEP();
3861     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3862         push_long(M.x86.R_EDX);
3863     } else {
3864         push_word(M.x86.R_DX);
3865     }
3866     DECODE_CLEAR_SEGOVR();
3867     END_OF_INSTR();
3868 }
3869
3870 /****************************************************************************
3871 REMARKS:
3872 Handles opcode 0x53
3873 ****************************************************************************/
3874 void x86emuOp_push_BX(u8 X86EMU_UNUSED(op1))
3875 {
3876     START_OF_INSTR();
3877     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3878         DECODE_PRINTF("PUSH\tEBX\n");
3879     } else {
3880         DECODE_PRINTF("PUSH\tBX\n");
3881     }
3882     TRACE_AND_STEP();
3883     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3884         push_long(M.x86.R_EBX);
3885     } else {
3886         push_word(M.x86.R_BX);
3887     }
3888     DECODE_CLEAR_SEGOVR();
3889     END_OF_INSTR();
3890 }
3891
3892 /****************************************************************************
3893 REMARKS:
3894 Handles opcode 0x54
3895 ****************************************************************************/
3896 void x86emuOp_push_SP(u8 X86EMU_UNUSED(op1))
3897 {
3898     START_OF_INSTR();
3899     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3900         DECODE_PRINTF("PUSH\tESP\n");
3901     } else {
3902         DECODE_PRINTF("PUSH\tSP\n");
3903     }
3904     TRACE_AND_STEP();
3905         /* Always push (E)SP, since we are emulating an i386 and above
3906          * processor. This is necessary as some BIOS'es use this to check
3907          * what type of processor is in the system.
3908          */
3909         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3910                 push_long(M.x86.R_ESP);
3911         } else {
3912                 push_word((u16)(M.x86.R_SP));
3913     }
3914     DECODE_CLEAR_SEGOVR();
3915     END_OF_INSTR();
3916 }
3917
3918 /****************************************************************************
3919 REMARKS:
3920 Handles opcode 0x55
3921 ****************************************************************************/
3922 void x86emuOp_push_BP(u8 X86EMU_UNUSED(op1))
3923 {
3924     START_OF_INSTR();
3925     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3926         DECODE_PRINTF("PUSH\tEBP\n");
3927     } else {
3928         DECODE_PRINTF("PUSH\tBP\n");
3929     }
3930     TRACE_AND_STEP();
3931     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3932         push_long(M.x86.R_EBP);
3933     } else {
3934         push_word(M.x86.R_BP);
3935     }
3936     DECODE_CLEAR_SEGOVR();
3937     END_OF_INSTR();
3938 }
3939
3940 /****************************************************************************
3941 REMARKS:
3942 Handles opcode 0x56
3943 ****************************************************************************/
3944 void x86emuOp_push_SI(u8 X86EMU_UNUSED(op1))
3945 {
3946     START_OF_INSTR();
3947     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3948         DECODE_PRINTF("PUSH\tESI\n");
3949     } else {
3950         DECODE_PRINTF("PUSH\tSI\n");
3951     }
3952     TRACE_AND_STEP();
3953     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3954         push_long(M.x86.R_ESI);
3955     } else {
3956         push_word(M.x86.R_SI);
3957     }
3958     DECODE_CLEAR_SEGOVR();
3959     END_OF_INSTR();
3960 }
3961
3962 /****************************************************************************
3963 REMARKS:
3964 Handles opcode 0x57
3965 ****************************************************************************/
3966 void x86emuOp_push_DI(u8 X86EMU_UNUSED(op1))
3967 {
3968     START_OF_INSTR();
3969     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3970         DECODE_PRINTF("PUSH\tEDI\n");
3971     } else {
3972         DECODE_PRINTF("PUSH\tDI\n");
3973     }
3974     TRACE_AND_STEP();
3975     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3976         push_long(M.x86.R_EDI);
3977     } else {
3978         push_word(M.x86.R_DI);
3979     }
3980     DECODE_CLEAR_SEGOVR();
3981     END_OF_INSTR();
3982 }
3983
3984 /****************************************************************************
3985 REMARKS:
3986 Handles opcode 0x58
3987 ****************************************************************************/
3988 void x86emuOp_pop_AX(u8 X86EMU_UNUSED(op1))
3989 {
3990     START_OF_INSTR();
3991     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3992         DECODE_PRINTF("POP\tEAX\n");
3993     } else {
3994         DECODE_PRINTF("POP\tAX\n");
3995     }
3996     TRACE_AND_STEP();
3997     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3998         M.x86.R_EAX = pop_long();
3999     } else {
4000         M.x86.R_AX = pop_word();
4001     }
4002     DECODE_CLEAR_SEGOVR();
4003     END_OF_INSTR();
4004 }
4005
4006 /****************************************************************************
4007 REMARKS:
4008 Handles opcode 0x59
4009 ****************************************************************************/
4010 void x86emuOp_pop_CX(u8 X86EMU_UNUSED(op1))
4011 {
4012     START_OF_INSTR();
4013     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4014         DECODE_PRINTF("POP\tECX\n");
4015     } else {
4016         DECODE_PRINTF("POP\tCX\n");
4017     }
4018     TRACE_AND_STEP();
4019     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4020         M.x86.R_ECX = pop_long();
4021     } else {
4022         M.x86.R_CX = pop_word();
4023     }
4024     DECODE_CLEAR_SEGOVR();
4025     END_OF_INSTR();
4026 }
4027
4028 /****************************************************************************
4029 REMARKS:
4030 Handles opcode 0x5a
4031 ****************************************************************************/
4032 void x86emuOp_pop_DX(u8 X86EMU_UNUSED(op1))
4033 {
4034     START_OF_INSTR();
4035     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4036         DECODE_PRINTF("POP\tEDX\n");
4037     } else {
4038         DECODE_PRINTF("POP\tDX\n");
4039     }
4040     TRACE_AND_STEP();
4041     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4042         M.x86.R_EDX = pop_long();
4043     } else {
4044         M.x86.R_DX = pop_word();
4045     }
4046     DECODE_CLEAR_SEGOVR();
4047     END_OF_INSTR();
4048 }
4049
4050 /****************************************************************************
4051 REMARKS:
4052 Handles opcode 0x5b
4053 ****************************************************************************/
4054 void x86emuOp_pop_BX(u8 X86EMU_UNUSED(op1))
4055 {
4056     START_OF_INSTR();
4057     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4058         DECODE_PRINTF("POP\tEBX\n");
4059     } else {
4060         DECODE_PRINTF("POP\tBX\n");
4061     }
4062     TRACE_AND_STEP();
4063     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4064         M.x86.R_EBX = pop_long();
4065     } else {
4066         M.x86.R_BX = pop_word();
4067     }
4068     DECODE_CLEAR_SEGOVR();
4069     END_OF_INSTR();
4070 }
4071
4072 /****************************************************************************
4073 REMARKS:
4074 Handles opcode 0x5c
4075 ****************************************************************************/
4076 void x86emuOp_pop_SP(u8 X86EMU_UNUSED(op1))
4077 {
4078     START_OF_INSTR();
4079     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4080         DECODE_PRINTF("POP\tESP\n");
4081     } else {
4082         DECODE_PRINTF("POP\tSP\n");
4083     }
4084     TRACE_AND_STEP();
4085     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4086         M.x86.R_ESP = pop_long();
4087     } else {
4088         M.x86.R_SP = pop_word();
4089     }
4090     DECODE_CLEAR_SEGOVR();
4091     END_OF_INSTR();
4092 }
4093
4094 /****************************************************************************
4095 REMARKS:
4096 Handles opcode 0x5d
4097 ****************************************************************************/
4098 void x86emuOp_pop_BP(u8 X86EMU_UNUSED(op1))
4099 {
4100     START_OF_INSTR();
4101     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4102         DECODE_PRINTF("POP\tEBP\n");
4103     } else {
4104         DECODE_PRINTF("POP\tBP\n");
4105     }
4106     TRACE_AND_STEP();
4107     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4108         M.x86.R_EBP = pop_long();
4109     } else {
4110         M.x86.R_BP = pop_word();
4111     }
4112     DECODE_CLEAR_SEGOVR();
4113     END_OF_INSTR();
4114 }
4115
4116 /****************************************************************************
4117 REMARKS:
4118 Handles opcode 0x5e
4119 ****************************************************************************/
4120 void x86emuOp_pop_SI(u8 X86EMU_UNUSED(op1))
4121 {
4122     START_OF_INSTR();
4123     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4124         DECODE_PRINTF("POP\tESI\n");
4125     } else {
4126         DECODE_PRINTF("POP\tSI\n");
4127     }
4128     TRACE_AND_STEP();
4129     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4130         M.x86.R_ESI = pop_long();
4131     } else {
4132         M.x86.R_SI = pop_word();
4133     }
4134     DECODE_CLEAR_SEGOVR();
4135     END_OF_INSTR();
4136 }
4137
4138 /****************************************************************************
4139 REMARKS:
4140 Handles opcode 0x5f
4141 ****************************************************************************/
4142 void x86emuOp_pop_DI(u8 X86EMU_UNUSED(op1))
4143 {
4144     START_OF_INSTR();
4145     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4146         DECODE_PRINTF("POP\tEDI\n");
4147     } else {
4148         DECODE_PRINTF("POP\tDI\n");
4149     }
4150     TRACE_AND_STEP();
4151     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4152         M.x86.R_EDI = pop_long();
4153     } else {
4154         M.x86.R_DI = pop_word();
4155     }
4156     DECODE_CLEAR_SEGOVR();
4157     END_OF_INSTR();
4158 }
4159
4160 /****************************************************************************
4161 REMARKS:
4162 Handles opcode 0x60
4163 ****************************************************************************/
4164 void x86emuOp_push_all(u8 X86EMU_UNUSED(op1))
4165 {
4166     START_OF_INSTR();
4167     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4168         DECODE_PRINTF("PUSHAD\n");
4169     } else {
4170         DECODE_PRINTF("PUSHA\n");
4171     }
4172     TRACE_AND_STEP();
4173     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4174         u32 old_sp = M.x86.R_ESP;
4175
4176         push_long(M.x86.R_EAX);
4177         push_long(M.x86.R_ECX);
4178         push_long(M.x86.R_EDX);
4179         push_long(M.x86.R_EBX);
4180         push_long(old_sp);
4181         push_long(M.x86.R_EBP);
4182         push_long(M.x86.R_ESI);
4183         push_long(M.x86.R_EDI);
4184     } else {
4185         u16 old_sp = M.x86.R_SP;
4186
4187         push_word(M.x86.R_AX);
4188         push_word(M.x86.R_CX);
4189         push_word(M.x86.R_DX);
4190         push_word(M.x86.R_BX);
4191         push_word(old_sp);
4192         push_word(M.x86.R_BP);
4193         push_word(M.x86.R_SI);
4194         push_word(M.x86.R_DI);
4195     }
4196     DECODE_CLEAR_SEGOVR();
4197     END_OF_INSTR();
4198 }
4199
4200 /****************************************************************************
4201 REMARKS:
4202 Handles opcode 0x61
4203 ****************************************************************************/
4204 void x86emuOp_pop_all(u8 X86EMU_UNUSED(op1))
4205 {
4206     START_OF_INSTR();
4207     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4208         DECODE_PRINTF("POPAD\n");
4209     } else {
4210         DECODE_PRINTF("POPA\n");
4211     }
4212     TRACE_AND_STEP();
4213     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4214         M.x86.R_EDI = pop_long();
4215         M.x86.R_ESI = pop_long();
4216         M.x86.R_EBP = pop_long();
4217         M.x86.R_ESP += 4;              /* skip ESP */
4218         M.x86.R_EBX = pop_long();
4219         M.x86.R_EDX = pop_long();
4220         M.x86.R_ECX = pop_long();
4221         M.x86.R_EAX = pop_long();
4222     } else {
4223         M.x86.R_DI = pop_word();
4224         M.x86.R_SI = pop_word();
4225         M.x86.R_BP = pop_word();
4226         M.x86.R_SP += 2;               /* skip SP */
4227         M.x86.R_BX = pop_word();
4228         M.x86.R_DX = pop_word();
4229         M.x86.R_CX = pop_word();
4230         M.x86.R_AX = pop_word();
4231     }
4232     DECODE_CLEAR_SEGOVR();
4233     END_OF_INSTR();
4234 }
4235
4236 /*opcode 0x62   ILLEGAL OP, calls x86emuOp_illegal_op() */
4237 /*opcode 0x63   ILLEGAL OP, calls x86emuOp_illegal_op() */
4238
4239 /****************************************************************************
4240 REMARKS:
4241 Handles opcode 0x64
4242 ****************************************************************************/
4243 void x86emuOp_segovr_FS(u8 X86EMU_UNUSED(op1))
4244 {
4245     START_OF_INSTR();
4246     DECODE_PRINTF("FS:\n");
4247     TRACE_AND_STEP();
4248     M.x86.mode |= SYSMODE_SEGOVR_FS;
4249     /*
4250      * note the lack of DECODE_CLEAR_SEGOVR(r) since, here is one of 4
4251      * opcode subroutines we do not want to do this.
4252      */
4253     END_OF_INSTR();
4254 }
4255
4256 /****************************************************************************
4257 REMARKS:
4258 Handles opcode 0x65
4259 ****************************************************************************/
4260 void x86emuOp_segovr_GS(u8 X86EMU_UNUSED(op1))
4261 {
4262     START_OF_INSTR();
4263     DECODE_PRINTF("GS:\n");
4264     TRACE_AND_STEP();
4265     M.x86.mode |= SYSMODE_SEGOVR_GS;
4266     /*
4267      * note the lack of DECODE_CLEAR_SEGOVR(r) since, here is one of 4
4268      * opcode subroutines we do not want to do this.
4269      */
4270     END_OF_INSTR();
4271 }
4272
4273 /****************************************************************************
4274 REMARKS:
4275 Handles opcode 0x66 - prefix for 32-bit register
4276 ****************************************************************************/
4277 void x86emuOp_prefix_data(u8 X86EMU_UNUSED(op1))
4278 {
4279     START_OF_INSTR();
4280     DECODE_PRINTF("DATA:\n");
4281     TRACE_AND_STEP();
4282     M.x86.mode |= SYSMODE_PREFIX_DATA;
4283     /* note no DECODE_CLEAR_SEGOVR here. */
4284     END_OF_INSTR();
4285 }
4286
4287 /****************************************************************************
4288 REMARKS:
4289 Handles opcode 0x67 - prefix for 32-bit address
4290 ****************************************************************************/
4291 void x86emuOp_prefix_addr(u8 X86EMU_UNUSED(op1))
4292 {
4293     START_OF_INSTR();
4294     DECODE_PRINTF("ADDR:\n");
4295     TRACE_AND_STEP();
4296     M.x86.mode |= SYSMODE_PREFIX_ADDR;
4297     /* note no DECODE_CLEAR_SEGOVR here. */
4298     END_OF_INSTR();
4299 }
4300
4301 /****************************************************************************
4302 REMARKS:
4303 Handles opcode 0x68
4304 ****************************************************************************/
4305 void x86emuOp_push_word_IMM(u8 X86EMU_UNUSED(op1))
4306 {
4307     u32 imm;
4308
4309     START_OF_INSTR();
4310     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4311         imm = fetch_long_imm();
4312     } else {
4313         imm = fetch_word_imm();
4314     }
4315     DECODE_PRINTF2("PUSH\t%x\n", imm);
4316     TRACE_AND_STEP();
4317     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4318         push_long(imm);
4319     } else {
4320         push_word((u16)imm);
4321     }
4322     DECODE_CLEAR_SEGOVR();
4323     END_OF_INSTR();
4324 }
4325
4326 /****************************************************************************
4327 REMARKS:
4328 Handles opcode 0x69
4329 ****************************************************************************/
4330 void x86emuOp_imul_word_IMM(u8 X86EMU_UNUSED(op1))
4331 {
4332     int mod, rl, rh;
4333     uint srcoffset;
4334
4335     START_OF_INSTR();
4336     DECODE_PRINTF("IMUL\t");
4337     FETCH_DECODE_MODRM(mod, rh, rl);
4338     switch (mod) {
4339     case 0:
4340         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4341             u32 *destreg;
4342             u32 srcval;
4343             u32 res_lo,res_hi;
4344             s32 imm;
4345
4346             destreg = DECODE_RM_LONG_REGISTER(rh);
4347             DECODE_PRINTF(",");
4348             srcoffset = decode_rm00_address(rl);
4349             srcval = fetch_data_long(srcoffset);
4350             imm = fetch_long_imm();
4351             DECODE_PRINTF2(",%d\n", (s32)imm);
4352             TRACE_AND_STEP();
4353             imul_long_direct(&res_lo,&res_hi,(s32)srcval,(s32)imm);
4354             if (res_hi != 0) {
4355                 SET_FLAG(F_CF);
4356                 SET_FLAG(F_OF);
4357             } else {
4358                 CLEAR_FLAG(F_CF);
4359                 CLEAR_FLAG(F_OF);
4360             }
4361             *destreg = (u32)res_lo;
4362         } else {
4363             u16 *destreg;
4364             u16 srcval;
4365             u32 res;
4366             s16 imm;
4367
4368             destreg = DECODE_RM_WORD_REGISTER(rh);
4369             DECODE_PRINTF(",");
4370             srcoffset = decode_rm00_address(rl);
4371             srcval = fetch_data_word(srcoffset);
4372             imm = fetch_word_imm();
4373             DECODE_PRINTF2(",%d\n", (s32)imm);
4374             TRACE_AND_STEP();
4375             res = (s16)srcval * (s16)imm;
4376             if (res > 0xFFFF) {
4377                 SET_FLAG(F_CF);
4378                 SET_FLAG(F_OF);
4379             } else {
4380                 CLEAR_FLAG(F_CF);
4381                 CLEAR_FLAG(F_OF);
4382             }
4383             *destreg = (u16)res;
4384         }
4385         break;
4386     case 1:
4387         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4388             u32 *destreg;
4389             u32 srcval;
4390             u32 res_lo,res_hi;
4391             s32 imm;
4392
4393             destreg = DECODE_RM_LONG_REGISTER(rh);
4394             DECODE_PRINTF(",");
4395             srcoffset = decode_rm01_address(rl);
4396             srcval = fetch_data_long(srcoffset);
4397             imm = fetch_long_imm();
4398             DECODE_PRINTF2(",%d\n", (s32)imm);
4399             TRACE_AND_STEP();
4400             imul_long_direct(&res_lo,&res_hi,(s32)srcval,(s32)imm);
4401             if (res_hi != 0) {
4402                 SET_FLAG(F_CF);
4403                 SET_FLAG(F_OF);
4404             } else {
4405                 CLEAR_FLAG(F_CF);
4406                 CLEAR_FLAG(F_OF);
4407             }
4408             *destreg = (u32)res_lo;
4409         } else {
4410             u16 *destreg;
4411             u16 srcval;
4412             u32 res;
4413             s16 imm;
4414
4415             destreg = DECODE_RM_WORD_REGISTER(rh);
4416             DECODE_PRINTF(",");
4417             srcoffset = decode_rm01_address(rl);
4418             srcval = fetch_data_word(srcoffset);
4419             imm = fetch_word_imm();
4420             DECODE_PRINTF2(",%d\n", (s32)imm);
4421             TRACE_AND_STEP();
4422             res = (s16)srcval * (s16)imm;
4423             if (res > 0xFFFF) {
4424                 SET_FLAG(F_CF);
4425                 SET_FLAG(F_OF);
4426             } else {
4427                 CLEAR_FLAG(F_CF);
4428                 CLEAR_FLAG(F_OF);
4429             }
4430             *destreg = (u16)res;
4431         }
4432         break;
4433     case 2:
4434         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4435             u32 *destreg;
4436             u32 srcval;
4437             u32 res_lo,res_hi;
4438             s32 imm;
4439
4440             destreg = DECODE_RM_LONG_REGISTER(rh);
4441             DECODE_PRINTF(",");
4442             srcoffset = decode_rm10_address(rl);
4443             srcval = fetch_data_long(srcoffset);
4444             imm = fetch_long_imm();
4445             DECODE_PRINTF2(",%d\n", (s32)imm);
4446             TRACE_AND_STEP();
4447             imul_long_direct(&res_lo,&res_hi,(s32)srcval,(s32)imm);
4448             if (res_hi != 0) {
4449                 SET_FLAG(F_CF);
4450                 SET_FLAG(F_OF);
4451             } else {
4452                 CLEAR_FLAG(F_CF);
4453                 CLEAR_FLAG(F_OF);
4454             }
4455             *destreg = (u32)res_lo;
4456         } else {
4457             u16 *destreg;
4458             u16 srcval;
4459             u32 res;
4460             s16 imm;
4461
4462             destreg = DECODE_RM_WORD_REGISTER(rh);
4463             DECODE_PRINTF(",");
4464             srcoffset = decode_rm10_address(rl);
4465             srcval = fetch_data_word(srcoffset);
4466             imm = fetch_word_imm();
4467             DECODE_PRINTF2(",%d\n", (s32)imm);
4468             TRACE_AND_STEP();
4469             res = (s16)srcval * (s16)imm;
4470             if (res > 0xFFFF) {
4471                 SET_FLAG(F_CF);
4472                 SET_FLAG(F_OF);
4473             } else {
4474                 CLEAR_FLAG(F_CF);
4475                 CLEAR_FLAG(F_OF);
4476             }
4477             *destreg = (u16)res;
4478         }
4479         break;
4480     case 3:                     /* register to register */
4481         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4482             u32 *destreg,*srcreg;
4483             u32 res_lo,res_hi;
4484             s32 imm;
4485
4486             destreg = DECODE_RM_LONG_REGISTER(rh);
4487             DECODE_PRINTF(",");
4488             srcreg = DECODE_RM_LONG_REGISTER(rl);
4489             imm = fetch_long_imm();
4490             DECODE_PRINTF2(",%d\n", (s32)imm);
4491             TRACE_AND_STEP();
4492             imul_long_direct(&res_lo,&res_hi,(s32)*srcreg,(s32)imm);
4493             if (res_hi != 0) {
4494                 SET_FLAG(F_CF);
4495                 SET_FLAG(F_OF);
4496             } else {
4497                 CLEAR_FLAG(F_CF);
4498                 CLEAR_FLAG(F_OF);
4499             }
4500             *destreg = (u32)res_lo;
4501         } else {
4502             u16 *destreg,*srcreg;
4503             u32 res;
4504             s16 imm;
4505
4506             destreg = DECODE_RM_WORD_REGISTER(rh);
4507             DECODE_PRINTF(",");
4508             srcreg = DECODE_RM_WORD_REGISTER(rl);
4509             imm = fetch_word_imm();
4510             DECODE_PRINTF2(",%d\n", (s32)imm);
4511             res = (s16)*srcreg * (s16)imm;
4512             if (res > 0xFFFF) {
4513                 SET_FLAG(F_CF);
4514                 SET_FLAG(F_OF);
4515             } else {
4516                 CLEAR_FLAG(F_CF);
4517                 CLEAR_FLAG(F_OF);
4518             }
4519             *destreg = (u16)res;
4520         }
4521         break;
4522     }
4523     DECODE_CLEAR_SEGOVR();
4524     END_OF_INSTR();
4525 }
4526
4527 /****************************************************************************
4528 REMARKS:
4529 Handles opcode 0x6a
4530 ****************************************************************************/
4531 void x86emuOp_push_byte_IMM(u8 X86EMU_UNUSED(op1))
4532 {
4533     s16 imm;
4534
4535     START_OF_INSTR();
4536     imm = (s8)fetch_byte_imm();
4537     DECODE_PRINTF2("PUSH\t%d\n", imm);
4538     TRACE_AND_STEP();
4539     push_word(imm);
4540     DECODE_CLEAR_SEGOVR();
4541     END_OF_INSTR();
4542 }
4543
4544 /****************************************************************************
4545 REMARKS:
4546 Handles opcode 0x6b
4547 ****************************************************************************/
4548 void x86emuOp_imul_byte_IMM(u8 X86EMU_UNUSED(op1))
4549 {
4550     int mod, rl, rh;
4551     uint srcoffset;
4552     s8  imm;
4553
4554     START_OF_INSTR();
4555     DECODE_PRINTF("IMUL\t");
4556     FETCH_DECODE_MODRM(mod, rh, rl);
4557     switch (mod) {
4558     case 0:
4559         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4560             u32 *destreg;
4561             u32 srcval;
4562             u32 res_lo,res_hi;
4563
4564             destreg = DECODE_RM_LONG_REGISTER(rh);
4565             DECODE_PRINTF(",");
4566             srcoffset = decode_rm00_address(rl);
4567             srcval = fetch_data_long(srcoffset);
4568             imm = fetch_byte_imm();
4569             DECODE_PRINTF2(",%d\n", (s32)imm);
4570             TRACE_AND_STEP();
4571             imul_long_direct(&res_lo,&res_hi,(s32)srcval,(s32)imm);
4572             if (res_hi != 0) {
4573                 SET_FLAG(F_CF);
4574                 SET_FLAG(F_OF);
4575             } else {
4576                 CLEAR_FLAG(F_CF);
4577                 CLEAR_FLAG(F_OF);
4578             }
4579             *destreg = (u32)res_lo;
4580         } else {
4581             u16 *destreg;
4582             u16 srcval;
4583             u32 res;
4584
4585             destreg = DECODE_RM_WORD_REGISTER(rh);
4586             DECODE_PRINTF(",");
4587             srcoffset = decode_rm00_address(rl);
4588             srcval = fetch_data_word(srcoffset);
4589             imm = fetch_byte_imm();
4590             DECODE_PRINTF2(",%d\n", (s32)imm);
4591             TRACE_AND_STEP();
4592             res = (s16)srcval * (s16)imm;
4593             if (res > 0xFFFF) {
4594                 SET_FLAG(F_CF);
4595                 SET_FLAG(F_OF);
4596             } else {
4597                 CLEAR_FLAG(F_CF);
4598                 CLEAR_FLAG(F_OF);
4599             }
4600             *destreg = (u16)res;
4601         }
4602         break;
4603     case 1:
4604         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4605             u32 *destreg;
4606             u32 srcval;
4607             u32 res_lo,res_hi;
4608
4609             destreg = DECODE_RM_LONG_REGISTER(rh);
4610             DECODE_PRINTF(",");
4611             srcoffset = decode_rm01_address(rl);
4612             srcval = fetch_data_long(srcoffset);
4613             imm = fetch_byte_imm();
4614             DECODE_PRINTF2(",%d\n", (s32)imm);
4615             TRACE_AND_STEP();
4616             imul_long_direct(&res_lo,&res_hi,(s32)srcval,(s32)imm);
4617             if (res_hi != 0) {
4618                 SET_FLAG(F_CF);
4619                 SET_FLAG(F_OF);
4620             } else {
4621                 CLEAR_FLAG(F_CF);
4622                 CLEAR_FLAG(F_OF);
4623             }
4624             *destreg = (u32)res_lo;
4625         } else {
4626             u16 *destreg;
4627             u16 srcval;
4628             u32 res;
4629
4630             destreg = DECODE_RM_WORD_REGISTER(rh);
4631             DECODE_PRINTF(",");
4632             srcoffset = decode_rm01_address(rl);
4633             srcval = fetch_data_word(srcoffset);
4634             imm = fetch_byte_imm();
4635             DECODE_PRINTF2(",%d\n", (s32)imm);
4636             TRACE_AND_STEP();
4637             res = (s16)srcval * (s16)imm;
4638             if (res > 0xFFFF) {
4639                 SET_FLAG(F_CF);
4640                 SET_FLAG(F_OF);
4641             } else {
4642                 CLEAR_FLAG(F_CF);
4643                 CLEAR_FLAG(F_OF);
4644             }
4645             *destreg = (u16)res;
4646         }
4647         break;
4648     case 2:
4649         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4650             u32 *destreg;
4651             u32 srcval;
4652             u32 res_lo,res_hi;
4653
4654             destreg = DECODE_RM_LONG_REGISTER(rh);
4655             DECODE_PRINTF(",");
4656             srcoffset = decode_rm10_address(rl);
4657             srcval = fetch_data_long(srcoffset);
4658             imm = fetch_byte_imm();
4659             DECODE_PRINTF2(",%d\n", (s32)imm);
4660             TRACE_AND_STEP();
4661             imul_long_direct(&res_lo,&res_hi,(s32)srcval,(s32)imm);
4662             if (res_hi != 0) {
4663                 SET_FLAG(F_CF);
4664                 SET_FLAG(F_OF);
4665             } else {
4666                 CLEAR_FLAG(F_CF);
4667                 CLEAR_FLAG(F_OF);
4668             }
4669             *destreg = (u32)res_lo;
4670         } else {
4671             u16 *destreg;
4672             u16 srcval;
4673             u32 res;
4674
4675             destreg = DECODE_RM_WORD_REGISTER(rh);
4676             DECODE_PRINTF(",");
4677             srcoffset = decode_rm10_address(rl);
4678             srcval = fetch_data_word(srcoffset);
4679             imm = fetch_byte_imm();
4680             DECODE_PRINTF2(",%d\n", (s32)imm);
4681             TRACE_AND_STEP();
4682             res = (s16)srcval * (s16)imm;
4683             if (res > 0xFFFF) {
4684                 SET_FLAG(F_CF);
4685                 SET_FLAG(F_OF);
4686             } else {
4687                 CLEAR_FLAG(F_CF);
4688                 CLEAR_FLAG(F_OF);
4689             }
4690             *destreg = (u16)res;
4691         }
4692         break;
4693     case 3:                     /* register to register */
4694         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4695             u32 *destreg,*srcreg;
4696             u32 res_lo,res_hi;
4697
4698             destreg = DECODE_RM_LONG_REGISTER(rh);
4699             DECODE_PRINTF(",");
4700             srcreg = DECODE_RM_LONG_REGISTER(rl);
4701             imm = fetch_byte_imm();
4702             DECODE_PRINTF2(",%d\n", (s32)imm);
4703             TRACE_AND_STEP();
4704             imul_long_direct(&res_lo,&res_hi,(s32)*srcreg,(s32)imm);
4705             if (res_hi != 0) {
4706                 SET_FLAG(F_CF);
4707                 SET_FLAG(F_OF);
4708             } else {
4709                 CLEAR_FLAG(F_CF);
4710                 CLEAR_FLAG(F_OF);
4711             }
4712             *destreg = (u32)res_lo;
4713         } else {
4714             u16 *destreg,*srcreg;
4715             u32 res;
4716
4717             destreg = DECODE_RM_WORD_REGISTER(rh);
4718             DECODE_PRINTF(",");
4719             srcreg = DECODE_RM_WORD_REGISTER(rl);
4720             imm = fetch_byte_imm();
4721             DECODE_PRINTF2(",%d\n", (s32)imm);
4722             res = (s16)*srcreg * (s16)imm;
4723             if (res > 0xFFFF) {
4724                 SET_FLAG(F_CF);
4725                 SET_FLAG(F_OF);
4726             } else {
4727                 CLEAR_FLAG(F_CF);
4728                 CLEAR_FLAG(F_OF);
4729             }
4730             *destreg = (u16)res;
4731         }
4732         break;
4733     }
4734     DECODE_CLEAR_SEGOVR();
4735     END_OF_INSTR();
4736 }
4737
4738 /****************************************************************************
4739 REMARKS:
4740 Handles opcode 0x6c
4741 ****************************************************************************/
4742 void x86emuOp_ins_byte(u8 X86EMU_UNUSED(op1))
4743 {
4744     START_OF_INSTR();
4745     DECODE_PRINTF("INSB\n");
4746     ins(1);
4747     TRACE_AND_STEP();
4748     DECODE_CLEAR_SEGOVR();
4749     END_OF_INSTR();
4750 }
4751
4752 /****************************************************************************
4753 REMARKS:
4754 Handles opcode 0x6d
4755 ****************************************************************************/
4756 void x86emuOp_ins_word(u8 X86EMU_UNUSED(op1))
4757 {
4758     START_OF_INSTR();
4759     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4760         DECODE_PRINTF("INSD\n");
4761         ins(4);
4762     } else {
4763         DECODE_PRINTF("INSW\n");
4764         ins(2);
4765     }
4766     TRACE_AND_STEP();
4767     DECODE_CLEAR_SEGOVR();
4768     END_OF_INSTR();
4769 }
4770
4771 /****************************************************************************
4772 REMARKS:
4773 Handles opcode 0x6e
4774 ****************************************************************************/
4775 void x86emuOp_outs_byte(u8 X86EMU_UNUSED(op1))
4776 {
4777     START_OF_INSTR();
4778     DECODE_PRINTF("OUTSB\n");
4779     outs(1);
4780     TRACE_AND_STEP();
4781     DECODE_CLEAR_SEGOVR();
4782     END_OF_INSTR();
4783 }
4784
4785 /****************************************************************************
4786 REMARKS:
4787 Handles opcode 0x6f
4788 ****************************************************************************/
4789 void x86emuOp_outs_word(u8 X86EMU_UNUSED(op1))
4790 {
4791     START_OF_INSTR();
4792     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4793         DECODE_PRINTF("OUTSD\n");
4794         outs(4);
4795     } else {
4796         DECODE_PRINTF("OUTSW\n");
4797         outs(2);
4798     }
4799     TRACE_AND_STEP();
4800     DECODE_CLEAR_SEGOVR();
4801     END_OF_INSTR();
4802 }
4803
4804 /****************************************************************************
4805 REMARKS:
4806 Handles opcode 0x70
4807 ****************************************************************************/
4808 void x86emuOp_jump_near_O(u8 X86EMU_UNUSED(op1))
4809 {
4810     s8 offset;
4811     u16 target;
4812
4813     /* jump to byte offset if overflow flag is set */
4814     START_OF_INSTR();
4815     DECODE_PRINTF("JO\t");
4816     offset = (s8)fetch_byte_imm();
4817     target = (u16)(M.x86.R_IP + (s16)offset);
4818     DECODE_PRINTF2("%x\n", target);
4819     TRACE_AND_STEP();
4820     if (ACCESS_FLAG(F_OF))
4821         M.x86.R_IP = target;
4822     DECODE_CLEAR_SEGOVR();
4823     END_OF_INSTR();
4824 }
4825
4826 /****************************************************************************
4827 REMARKS:
4828 Handles opcode 0x71
4829 ****************************************************************************/
4830 void x86emuOp_jump_near_NO(u8 X86EMU_UNUSED(op1))
4831 {
4832     s8 offset;
4833     u16 target;
4834
4835     /* jump to byte offset if overflow is not set */
4836     START_OF_INSTR();
4837     DECODE_PRINTF("JNO\t");
4838     offset = (s8)fetch_byte_imm();
4839     target = (u16)(M.x86.R_IP + (s16)offset);
4840     DECODE_PRINTF2("%x\n", target);
4841     TRACE_AND_STEP();
4842     if (!ACCESS_FLAG(F_OF))
4843         M.x86.R_IP = target;
4844     DECODE_CLEAR_SEGOVR();
4845     END_OF_INSTR();
4846 }
4847
4848 /****************************************************************************
4849 REMARKS:
4850 Handles opcode 0x72
4851 ****************************************************************************/
4852 void x86emuOp_jump_near_B(u8 X86EMU_UNUSED(op1))
4853 {
4854     s8 offset;
4855     u16 target;
4856
4857     /* jump to byte offset if carry flag is set. */
4858     START_OF_INSTR();
4859     DECODE_PRINTF("JB\t");
4860     offset = (s8)fetch_byte_imm();
4861     target = (u16)(M.x86.R_IP + (s16)offset);
4862     DECODE_PRINTF2("%x\n", target);
4863     TRACE_AND_STEP();
4864     if (ACCESS_FLAG(F_CF))
4865         M.x86.R_IP = target;
4866     DECODE_CLEAR_SEGOVR();
4867     END_OF_INSTR();
4868 }
4869
4870 /****************************************************************************
4871 REMARKS:
4872 Handles opcode 0x73
4873 ****************************************************************************/
4874 void x86emuOp_jump_near_NB(u8 X86EMU_UNUSED(op1))
4875 {
4876     s8 offset;
4877     u16 target;
4878
4879     /* jump to byte offset if carry flag is clear. */
4880     START_OF_INSTR();
4881     DECODE_PRINTF("JNB\t");
4882     offset = (s8)fetch_byte_imm();
4883     target = (u16)(M.x86.R_IP + (s16)offset);
4884     DECODE_PRINTF2("%x\n", target);
4885     TRACE_AND_STEP();
4886     if (!ACCESS_FLAG(F_CF))
4887         M.x86.R_IP = target;
4888     DECODE_CLEAR_SEGOVR();
4889     END_OF_INSTR();
4890 }
4891
4892 /****************************************************************************
4893 REMARKS:
4894 Handles opcode 0x74
4895 ****************************************************************************/
4896 void x86emuOp_jump_near_Z(u8 X86EMU_UNUSED(op1))
4897 {
4898     s8 offset;
4899     u16 target;
4900
4901     /* jump to byte offset if zero flag is set. */
4902     START_OF_INSTR();
4903     DECODE_PRINTF("JZ\t");
4904     offset = (s8)fetch_byte_imm();
4905     target = (u16)(M.x86.R_IP + (s16)offset);
4906     DECODE_PRINTF2("%x\n", target);
4907     TRACE_AND_STEP();
4908     if (ACCESS_FLAG(F_ZF))
4909         M.x86.R_IP = target;
4910     DECODE_CLEAR_SEGOVR();
4911     END_OF_INSTR();
4912 }
4913
4914 /****************************************************************************
4915 REMARKS:
4916 Handles opcode 0x75
4917 ****************************************************************************/
4918 void x86emuOp_jump_near_NZ(u8 X86EMU_UNUSED(op1))
4919 {
4920     s8 offset;
4921     u16 target;
4922
4923     /* jump to byte offset if zero flag is clear. */
4924     START_OF_INSTR();
4925     DECODE_PRINTF("JNZ\t");
4926     offset = (s8)fetch_byte_imm();
4927     target = (u16)(M.x86.R_IP + (s16)offset);
4928     DECODE_PRINTF2("%x\n", target);
4929     TRACE_AND_STEP();
4930     if (!ACCESS_FLAG(F_ZF))
4931         M.x86.R_IP = target;
4932     DECODE_CLEAR_SEGOVR();
4933     END_OF_INSTR();
4934 }
4935
4936 /****************************************************************************
4937 REMARKS:
4938 Handles opcode 0x76
4939 ****************************************************************************/
4940 void x86emuOp_jump_near_BE(u8 X86EMU_UNUSED(op1))
4941 {
4942     s8 offset;
4943     u16 target;
4944
4945     /* jump to byte offset if carry flag is set or if the zero
4946        flag is set. */
4947     START_OF_INSTR();
4948     DECODE_PRINTF("JBE\t");
4949     offset = (s8)fetch_byte_imm();
4950     target = (u16)(M.x86.R_IP + (s16)offset);
4951     DECODE_PRINTF2("%x\n", target);
4952     TRACE_AND_STEP();
4953     if (ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF))
4954         M.x86.R_IP = target;
4955     DECODE_CLEAR_SEGOVR();
4956     END_OF_INSTR();
4957 }
4958
4959 /****************************************************************************
4960 REMARKS:
4961 Handles opcode 0x77
4962 ****************************************************************************/
4963 void x86emuOp_jump_near_NBE(u8 X86EMU_UNUSED(op1))
4964 {
4965     s8 offset;
4966     u16 target;
4967
4968     /* jump to byte offset if carry flag is clear and if the zero
4969        flag is clear */
4970     START_OF_INSTR();
4971     DECODE_PRINTF("JNBE\t");
4972     offset = (s8)fetch_byte_imm();
4973     target = (u16)(M.x86.R_IP + (s16)offset);
4974     DECODE_PRINTF2("%x\n", target);
4975     TRACE_AND_STEP();
4976     if (!(ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF)))
4977         M.x86.R_IP = target;
4978     DECODE_CLEAR_SEGOVR();
4979     END_OF_INSTR();
4980 }
4981
4982 /****************************************************************************
4983 REMARKS:
4984 Handles opcode 0x78
4985 ****************************************************************************/
4986 void x86emuOp_jump_near_S(u8 X86EMU_UNUSED(op1))
4987 {
4988     s8 offset;
4989     u16 target;
4990
4991     /* jump to byte offset if sign flag is set */
4992     START_OF_INSTR();
4993     DECODE_PRINTF("JS\t");
4994     offset = (s8)fetch_byte_imm();
4995     target = (u16)(M.x86.R_IP + (s16)offset);
4996     DECODE_PRINTF2("%x\n", target);
4997     TRACE_AND_STEP();
4998     if (ACCESS_FLAG(F_SF))
4999         M.x86.R_IP = target;
5000     DECODE_CLEAR_SEGOVR();
5001     END_OF_INSTR();
5002 }
5003
5004 /****************************************************************************
5005 REMARKS:
5006 Handles opcode 0x79
5007 ****************************************************************************/
5008 void x86emuOp_jump_near_NS(u8 X86EMU_UNUSED(op1))
5009 {
5010     s8 offset;
5011     u16 target;
5012
5013     /* jump to byte offset if sign flag is clear */
5014     START_OF_INSTR();
5015     DECODE_PRINTF("JNS\t");
5016     offset = (s8)fetch_byte_imm();
5017     target = (u16)(M.x86.R_IP + (s16)offset);
5018     DECODE_PRINTF2("%x\n", target);
5019     TRACE_AND_STEP();
5020     if (!ACCESS_FLAG(F_SF))
5021         M.x86.R_IP = target;
5022     DECODE_CLEAR_SEGOVR();
5023     END_OF_INSTR();
5024 }
5025
5026 /****************************************************************************
5027 REMARKS:
5028 Handles opcode 0x7a
5029 ****************************************************************************/
5030 void x86emuOp_jump_near_P(u8 X86EMU_UNUSED(op1))
5031 {
5032     s8 offset;
5033     u16 target;
5034
5035     /* jump to byte offset if parity flag is set (even parity) */
5036     START_OF_INSTR();
5037     DECODE_PRINTF("JP\t");
5038     offset = (s8)fetch_byte_imm();
5039     target = (u16)(M.x86.R_IP + (s16)offset);
5040     DECODE_PRINTF2("%x\n", target);
5041     TRACE_AND_STEP();
5042     if (ACCESS_FLAG(F_PF))
5043         M.x86.R_IP = target;
5044     DECODE_CLEAR_SEGOVR();
5045     END_OF_INSTR();
5046 }
5047
5048 /****************************************************************************
5049 REMARKS:
5050 Handles opcode 0x7b
5051 ****************************************************************************/
5052 void x86emuOp_jump_near_NP(u8 X86EMU_UNUSED(op1))
5053 {
5054     s8 offset;
5055     u16 target;
5056
5057     /* jump to byte offset if parity flag is clear (odd parity) */
5058     START_OF_INSTR();
5059     DECODE_PRINTF("JNP\t");
5060     offset = (s8)fetch_byte_imm();
5061     target = (u16)(M.x86.R_IP + (s16)offset);
5062     DECODE_PRINTF2("%x\n", target);
5063     TRACE_AND_STEP();
5064     if (!ACCESS_FLAG(F_PF))
5065         M.x86.R_IP = target;
5066     DECODE_CLEAR_SEGOVR();
5067     END_OF_INSTR();
5068 }
5069
5070 /****************************************************************************
5071 REMARKS:
5072 Handles opcode 0x7c
5073 ****************************************************************************/
5074 void x86emuOp_jump_near_L(u8 X86EMU_UNUSED(op1))
5075 {
5076     s8 offset;
5077     u16 target;
5078     int sf, of;
5079
5080     /* jump to byte offset if sign flag not equal to overflow flag. */
5081     START_OF_INSTR();
5082     DECODE_PRINTF("JL\t");
5083     offset = (s8)fetch_byte_imm();
5084     target = (u16)(M.x86.R_IP + (s16)offset);
5085     DECODE_PRINTF2("%x\n", target);
5086     TRACE_AND_STEP();
5087     sf = ACCESS_FLAG(F_SF) != 0;
5088     of = ACCESS_FLAG(F_OF) != 0;
5089     if (sf ^ of)
5090         M.x86.R_IP = target;
5091     DECODE_CLEAR_SEGOVR();
5092     END_OF_INSTR();
5093 }
5094
5095 /****************************************************************************
5096 REMARKS:
5097 Handles opcode 0x7d
5098 ****************************************************************************/
5099 void x86emuOp_jump_near_NL(u8 X86EMU_UNUSED(op1))
5100 {
5101     s8 offset;
5102     u16 target;
5103     int sf, of;
5104
5105     /* jump to byte offset if sign flag not equal to overflow flag. */
5106     START_OF_INSTR();
5107     DECODE_PRINTF("JNL\t");
5108     offset = (s8)fetch_byte_imm();
5109     target = (u16)(M.x86.R_IP + (s16)offset);
5110     DECODE_PRINTF2("%x\n", target);
5111     TRACE_AND_STEP();
5112     sf = ACCESS_FLAG(F_SF) != 0;
5113     of = ACCESS_FLAG(F_OF) != 0;
5114     /* note: inverse of above, but using == instead of xor. */
5115     if (sf == of)
5116         M.x86.R_IP = target;
5117     DECODE_CLEAR_SEGOVR();
5118     END_OF_INSTR();
5119 }
5120
5121 /****************************************************************************
5122 REMARKS:
5123 Handles opcode 0x7e
5124 ****************************************************************************/
5125 void x86emuOp_jump_near_LE(u8 X86EMU_UNUSED(op1))
5126 {
5127     s8 offset;
5128     u16 target;
5129     int sf, of;
5130
5131     /* jump to byte offset if sign flag not equal to overflow flag
5132        or the zero flag is set */
5133     START_OF_INSTR();
5134     DECODE_PRINTF("JLE\t");
5135     offset = (s8)fetch_byte_imm();
5136     target = (u16)(M.x86.R_IP + (s16)offset);
5137     DECODE_PRINTF2("%x\n", target);
5138     TRACE_AND_STEP();
5139     sf = ACCESS_FLAG(F_SF) != 0;
5140     of = ACCESS_FLAG(F_OF) != 0;
5141     if ((sf ^ of) || ACCESS_FLAG(F_ZF))
5142         M.x86.R_IP = target;
5143     DECODE_CLEAR_SEGOVR();
5144     END_OF_INSTR();
5145 }
5146
5147 /****************************************************************************
5148 REMARKS:
5149 Handles opcode 0x7f
5150 ****************************************************************************/
5151 void x86emuOp_jump_near_NLE(u8 X86EMU_UNUSED(op1))
5152 {
5153     s8 offset;
5154     u16 target;
5155     int sf, of;
5156
5157     /* jump to byte offset if sign flag equal to overflow flag.
5158        and the zero flag is clear */
5159     START_OF_INSTR();
5160     DECODE_PRINTF("JNLE\t");
5161     offset = (s8)fetch_byte_imm();
5162     target = (u16)(M.x86.R_IP + (s16)offset);
5163     DECODE_PRINTF2("%x\n", target);
5164     TRACE_AND_STEP();
5165     sf = ACCESS_FLAG(F_SF) != 0;
5166     of = ACCESS_FLAG(F_OF) != 0;
5167     if ((sf == of) && !ACCESS_FLAG(F_ZF))
5168         M.x86.R_IP = target;
5169     DECODE_CLEAR_SEGOVR();
5170     END_OF_INSTR();
5171 }
5172
5173 static u8 (*opc80_byte_operation[])(u8 d, u8 s) =
5174 {
5175     add_byte,           /* 00 */
5176     or_byte,            /* 01 */
5177     adc_byte,           /* 02 */
5178     sbb_byte,           /* 03 */
5179     and_byte,           /* 04 */
5180     sub_byte,           /* 05 */
5181     xor_byte,           /* 06 */
5182     cmp_byte,           /* 07 */
5183 };
5184
5185 /****************************************************************************
5186 REMARKS:
5187 Handles opcode 0x80
5188 ****************************************************************************/
5189 void x86emuOp_opc80_byte_RM_IMM(u8 X86EMU_UNUSED(op1))
5190 {
5191     int mod, rl, rh;
5192     u8 *destreg;
5193     uint destoffset;
5194     u8 imm;
5195     u8 destval;
5196
5197     /*
5198      * Weirdo special case instruction format.  Part of the opcode
5199      * held below in "RH".  Doubly nested case would result, except
5200      * that the decoded instruction
5201      */
5202     START_OF_INSTR();
5203     FETCH_DECODE_MODRM(mod, rh, rl);
5204 #ifdef DEBUG
5205     if (DEBUG_DECODE()) {
5206         /* XXX DECODE_PRINTF may be changed to something more
5207            general, so that it is important to leave the strings
5208            in the same format, even though the result is that the 
5209            above test is done twice. */
5210
5211         switch (rh) {
5212         case 0:
5213             DECODE_PRINTF("ADD\t");
5214             break;
5215         case 1:
5216             DECODE_PRINTF("OR\t");
5217             break;
5218         case 2:
5219             DECODE_PRINTF("ADC\t");
5220             break;
5221         case 3:
5222             DECODE_PRINTF("SBB\t");
5223             break;
5224         case 4:
5225             DECODE_PRINTF("AND\t");
5226             break;
5227         case 5:
5228             DECODE_PRINTF("SUB\t");
5229             break;
5230         case 6:
5231             DECODE_PRINTF("XOR\t");
5232             break;
5233         case 7:
5234             DECODE_PRINTF("CMP\t");
5235             break;
5236         }
5237     }
5238 #endif
5239     /* know operation, decode the mod byte to find the addressing
5240        mode. */
5241     switch (mod) {
5242     case 0:
5243         DECODE_PRINTF("BYTE PTR ");
5244         destoffset = decode_rm00_address(rl);
5245         DECODE_PRINTF(",");
5246         destval = fetch_data_byte(destoffset);
5247         imm = fetch_byte_imm();
5248         DECODE_PRINTF2("%x\n", imm);
5249         TRACE_AND_STEP();
5250         destval = (*opc80_byte_operation[rh]) (destval, imm);
5251         if (rh != 7)
5252             store_data_byte(destoffset, destval);
5253         break;
5254     case 1:
5255         DECODE_PRINTF("BYTE PTR ");
5256         destoffset = decode_rm01_address(rl);
5257         DECODE_PRINTF(",");
5258         destval = fetch_data_byte(destoffset);
5259         imm = fetch_byte_imm();
5260         DECODE_PRINTF2("%x\n", imm);
5261         TRACE_AND_STEP();
5262         destval = (*opc80_byte_operation[rh]) (destval, imm);
5263         if (rh != 7)
5264             store_data_byte(destoffset, destval);
5265         break;
5266     case 2:
5267         DECODE_PRINTF("BYTE PTR ");
5268         destoffset = decode_rm10_address(rl);
5269         DECODE_PRINTF(",");
5270         destval = fetch_data_byte(destoffset);
5271         imm = fetch_byte_imm();
5272         DECODE_PRINTF2("%x\n", imm);
5273         TRACE_AND_STEP();
5274         destval = (*opc80_byte_operation[rh]) (destval, imm);
5275         if (rh != 7)
5276             store_data_byte(destoffset, destval);
5277         break;
5278     case 3:                     /* register to register */
5279         destreg = DECODE_RM_BYTE_REGISTER(rl);
5280         DECODE_PRINTF(",");
5281         imm = fetch_byte_imm();
5282         DECODE_PRINTF2("%x\n", imm);
5283         TRACE_AND_STEP();
5284         destval = (*opc80_byte_operation[rh]) (*destreg, imm);
5285         if (rh != 7)
5286             *destreg = destval;
5287         break;
5288     }
5289     DECODE_CLEAR_SEGOVR();
5290     END_OF_INSTR();
5291 }
5292
5293 static u16 (*opc81_word_operation[])(u16 d, u16 s) =
5294 {
5295     add_word,           /*00 */
5296     or_word,            /*01 */
5297     adc_word,           /*02 */
5298     sbb_word,           /*03 */
5299     and_word,           /*04 */
5300     sub_word,           /*05 */
5301     xor_word,           /*06 */
5302     cmp_word,           /*07 */
5303 };
5304
5305 static u32 (*opc81_long_operation[])(u32 d, u32 s) =
5306 {
5307     add_long,           /*00 */
5308     or_long,            /*01 */
5309     adc_long,           /*02 */
5310     sbb_long,           /*03 */
5311     and_long,           /*04 */
5312     sub_long,           /*05 */
5313     xor_long,           /*06 */
5314     cmp_long,           /*07 */
5315 };
5316
5317 /****************************************************************************
5318 REMARKS:
5319 Handles opcode 0x81
5320 ****************************************************************************/
5321 void x86emuOp_opc81_word_RM_IMM(u8 X86EMU_UNUSED(op1))
5322 {
5323     int mod, rl, rh;
5324     uint destoffset;
5325
5326     /*
5327      * Weirdo special case instruction format.  Part of the opcode
5328      * held below in "RH".  Doubly nested case would result, except
5329      * that the decoded instruction
5330      */
5331     START_OF_INSTR();
5332     FETCH_DECODE_MODRM(mod, rh, rl);
5333 #ifdef DEBUG
5334     if (DEBUG_DECODE()) {
5335         /* XXX DECODE_PRINTF may be changed to something more
5336            general, so that it is important to leave the strings
5337            in the same format, even though the result is that the 
5338            above test is done twice. */
5339
5340         switch (rh) {
5341         case 0:
5342             DECODE_PRINTF("ADD\t");
5343             break;
5344         case 1:
5345             DECODE_PRINTF("OR\t");
5346             break;
5347         case 2:
5348             DECODE_PRINTF("ADC\t");
5349             break;
5350         case 3:
5351             DECODE_PRINTF("SBB\t");
5352             break;
5353         case 4:
5354             DECODE_PRINTF("AND\t");
5355             break;
5356         case 5:
5357             DECODE_PRINTF("SUB\t");
5358             break;
5359         case 6:
5360             DECODE_PRINTF("XOR\t");
5361             break;
5362         case 7:
5363             DECODE_PRINTF("CMP\t");
5364             break;
5365         }
5366     }
5367 #endif
5368     /*
5369      * Know operation, decode the mod byte to find the addressing 
5370      * mode.
5371      */
5372     switch (mod) {
5373     case 0:
5374         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5375             u32 destval,imm;
5376
5377             DECODE_PRINTF("DWORD PTR ");
5378             destoffset = decode_rm00_address(rl);
5379             DECODE_PRINTF(",");
5380             destval = fetch_data_long(destoffset);
5381             imm = fetch_long_imm();
5382             DECODE_PRINTF2("%x\n", imm);
5383             TRACE_AND_STEP();
5384             destval = (*opc81_long_operation[rh]) (destval, imm);
5385             if (rh != 7)
5386                 store_data_long(destoffset, destval);
5387         } else {
5388             u16 destval,imm;
5389
5390             DECODE_PRINTF("WORD PTR ");
5391             destoffset = decode_rm00_address(rl);
5392             DECODE_PRINTF(",");
5393             destval = fetch_data_word(destoffset);
5394             imm = fetch_word_imm();
5395             DECODE_PRINTF2("%x\n", imm);
5396             TRACE_AND_STEP();
5397             destval = (*opc81_word_operation[rh]) (destval, imm);
5398             if (rh != 7)
5399                 store_data_word(destoffset, destval);
5400         }
5401         break;
5402     case 1:
5403         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5404             u32 destval,imm;
5405
5406             DECODE_PRINTF("DWORD PTR ");
5407             destoffset = decode_rm01_address(rl);
5408             DECODE_PRINTF(",");
5409             destval = fetch_data_long(destoffset);
5410             imm = fetch_long_imm();
5411             DECODE_PRINTF2("%x\n", imm);
5412             TRACE_AND_STEP();
5413             destval = (*opc81_long_operation[rh]) (destval, imm);
5414             if (rh != 7)
5415                 store_data_long(destoffset, destval);
5416         } else {
5417             u16 destval,imm;
5418
5419             DECODE_PRINTF("WORD PTR ");
5420             destoffset = decode_rm01_address(rl);
5421             DECODE_PRINTF(",");
5422             destval = fetch_data_word(destoffset);
5423             imm = fetch_word_imm();
5424             DECODE_PRINTF2("%x\n", imm);
5425             TRACE_AND_STEP();
5426             destval = (*opc81_word_operation[rh]) (destval, imm);
5427             if (rh != 7)
5428                 store_data_word(destoffset, destval);
5429         }
5430         break;
5431     case 2:
5432         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5433             u32 destval,imm;
5434
5435             DECODE_PRINTF("DWORD PTR ");
5436             destoffset = decode_rm10_address(rl);
5437             DECODE_PRINTF(",");
5438             destval = fetch_data_long(destoffset);
5439             imm = fetch_long_imm();
5440             DECODE_PRINTF2("%x\n", imm);
5441             TRACE_AND_STEP();
5442             destval = (*opc81_long_operation[rh]) (destval, imm);
5443             if (rh != 7)
5444                 store_data_long(destoffset, destval);
5445         } else {
5446             u16 destval,imm;
5447
5448             DECODE_PRINTF("WORD PTR ");
5449             destoffset = decode_rm10_address(rl);
5450             DECODE_PRINTF(",");
5451             destval = fetch_data_word(destoffset);
5452             imm = fetch_word_imm();
5453             DECODE_PRINTF2("%x\n", imm);
5454             TRACE_AND_STEP();
5455             destval = (*opc81_word_operation[rh]) (destval, imm);
5456             if (rh != 7)
5457                 store_data_word(destoffset, destval);
5458         }
5459         break;
5460     case 3:                     /* register to register */
5461         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5462             u32 *destreg;
5463             u32 destval,imm;
5464
5465             destreg = DECODE_RM_LONG_REGISTER(rl);
5466             DECODE_PRINTF(",");
5467             imm = fetch_long_imm();
5468             DECODE_PRINTF2("%x\n", imm);
5469             TRACE_AND_STEP();
5470             destval = (*opc81_long_operation[rh]) (*destreg, imm);
5471             if (rh != 7)
5472                 *destreg = destval;
5473         } else {
5474             u16 *destreg;
5475             u16 destval,imm;
5476
5477             destreg = DECODE_RM_WORD_REGISTER(rl);
5478             DECODE_PRINTF(",");
5479             imm = fetch_word_imm();
5480             DECODE_PRINTF2("%x\n", imm);
5481             TRACE_AND_STEP();
5482             destval = (*opc81_word_operation[rh]) (*destreg, imm);
5483             if (rh != 7)
5484                 *destreg = destval;
5485         }
5486         break;
5487     }
5488     DECODE_CLEAR_SEGOVR();
5489     END_OF_INSTR();
5490 }
5491
5492 static u8 (*opc82_byte_operation[])(u8 s, u8 d) =
5493 {
5494     add_byte,           /*00 */
5495     or_byte,            /*01 *//*YYY UNUSED ???? */
5496     adc_byte,           /*02 */
5497     sbb_byte,           /*03 */
5498     and_byte,           /*04 *//*YYY UNUSED ???? */
5499     sub_byte,           /*05 */
5500     xor_byte,           /*06 *//*YYY UNUSED ???? */
5501     cmp_byte,           /*07 */
5502 };
5503
5504 /****************************************************************************
5505 REMARKS:
5506 Handles opcode 0x82
5507 ****************************************************************************/
5508 void x86emuOp_opc82_byte_RM_IMM(u8 X86EMU_UNUSED(op1))
5509 {
5510     int mod, rl, rh;
5511     u8 *destreg;
5512     uint destoffset;
5513     u8 imm;
5514     u8 destval;
5515
5516     /*
5517      * Weirdo special case instruction format.  Part of the opcode
5518      * held below in "RH".  Doubly nested case would result, except
5519      * that the decoded instruction Similar to opcode 81, except that
5520      * the immediate byte is sign extended to a word length.
5521      */
5522     START_OF_INSTR();
5523     FETCH_DECODE_MODRM(mod, rh, rl);
5524 #ifdef DEBUG
5525     if (DEBUG_DECODE()) {
5526         /* XXX DECODE_PRINTF may be changed to something more
5527            general, so that it is important to leave the strings
5528            in the same format, even though the result is that the 
5529            above test is done twice. */
5530         switch (rh) {
5531         case 0:
5532             DECODE_PRINTF("ADD\t");
5533             break;
5534         case 1:
5535             DECODE_PRINTF("OR\t");
5536             break;
5537         case 2:
5538             DECODE_PRINTF("ADC\t");
5539             break;
5540         case 3:
5541             DECODE_PRINTF("SBB\t");
5542             break;
5543         case 4:
5544             DECODE_PRINTF("AND\t");
5545             break;
5546         case 5:
5547             DECODE_PRINTF("SUB\t");
5548             break;
5549         case 6:
5550             DECODE_PRINTF("XOR\t");
5551             break;
5552         case 7:
5553             DECODE_PRINTF("CMP\t");
5554             break;
5555         }
5556     }
5557 #endif
5558     /* know operation, decode the mod byte to find the addressing
5559        mode. */
5560     switch (mod) {
5561     case 0:
5562         DECODE_PRINTF("BYTE PTR ");
5563         destoffset = decode_rm00_address(rl);
5564         destval = fetch_data_byte(destoffset);
5565         imm = fetch_byte_imm();
5566         DECODE_PRINTF2(",%x\n", imm);
5567         TRACE_AND_STEP();
5568         destval = (*opc82_byte_operation[rh]) (destval, imm);
5569         if (rh != 7)
5570             store_data_byte(destoffset, destval);
5571         break;
5572     case 1:
5573         DECODE_PRINTF("BYTE PTR ");
5574         destoffset = decode_rm01_address(rl);
5575         destval = fetch_data_byte(destoffset);
5576         imm = fetch_byte_imm();
5577         DECODE_PRINTF2(",%x\n", imm);
5578         TRACE_AND_STEP();
5579         destval = (*opc82_byte_operation[rh]) (destval, imm);
5580         if (rh != 7)
5581             store_data_byte(destoffset, destval);
5582         break;
5583     case 2:
5584         DECODE_PRINTF("BYTE PTR ");
5585         destoffset = decode_rm10_address(rl);
5586         destval = fetch_data_byte(destoffset);
5587         imm = fetch_byte_imm();
5588         DECODE_PRINTF2(",%x\n", imm);
5589         TRACE_AND_STEP();
5590         destval = (*opc82_byte_operation[rh]) (destval, imm);
5591         if (rh != 7)
5592             store_data_byte(destoffset, destval);
5593         break;
5594     case 3:                     /* register to register */
5595         destreg = DECODE_RM_BYTE_REGISTER(rl);
5596         imm = fetch_byte_imm();
5597         DECODE_PRINTF2(",%x\n", imm);
5598         TRACE_AND_STEP();
5599         destval = (*opc82_byte_operation[rh]) (*destreg, imm);
5600         if (rh != 7)
5601             *destreg = destval;
5602         break;
5603     }
5604     DECODE_CLEAR_SEGOVR();
5605     END_OF_INSTR();
5606 }
5607
5608 static u16 (*opc83_word_operation[])(u16 s, u16 d) =
5609 {
5610     add_word,           /*00 */
5611     or_word,            /*01 *//*YYY UNUSED ???? */
5612     adc_word,           /*02 */
5613     sbb_word,           /*03 */
5614     and_word,           /*04 *//*YYY UNUSED ???? */
5615     sub_word,           /*05 */
5616     xor_word,           /*06 *//*YYY UNUSED ???? */
5617     cmp_word,           /*07 */
5618 };
5619
5620 static u32 (*opc83_long_operation[])(u32 s, u32 d) =
5621 {
5622     add_long,           /*00 */
5623     or_long,            /*01 *//*YYY UNUSED ???? */
5624     adc_long,           /*02 */
5625     sbb_long,           /*03 */
5626     and_long,           /*04 *//*YYY UNUSED ???? */
5627     sub_long,           /*05 */
5628     xor_long,           /*06 *//*YYY UNUSED ???? */
5629     cmp_long,           /*07 */
5630 };
5631
5632 /****************************************************************************
5633 REMARKS:
5634 Handles opcode 0x83
5635 ****************************************************************************/
5636 void x86emuOp_opc83_word_RM_IMM(u8 X86EMU_UNUSED(op1))
5637 {
5638     int mod, rl, rh;
5639     uint destoffset;
5640
5641     /*
5642      * Weirdo special case instruction format.  Part of the opcode
5643      * held below in "RH".  Doubly nested case would result, except
5644      * that the decoded instruction Similar to opcode 81, except that
5645      * the immediate byte is sign extended to a word length.
5646      */
5647     START_OF_INSTR();
5648     FETCH_DECODE_MODRM(mod, rh, rl);
5649 #ifdef DEBUG
5650     if (DEBUG_DECODE()) {
5651         /* XXX DECODE_PRINTF may be changed to something more
5652            general, so that it is important to leave the strings
5653            in the same format, even though the result is that the 
5654            above test is done twice. */
5655        switch (rh) {
5656         case 0:
5657             DECODE_PRINTF("ADD\t");
5658             break;
5659         case 1:
5660             DECODE_PRINTF("OR\t");
5661             break;
5662         case 2:
5663             DECODE_PRINTF("ADC\t");
5664             break;
5665         case 3:
5666             DECODE_PRINTF("SBB\t");
5667             break;
5668         case 4:
5669             DECODE_PRINTF("AND\t");
5670             break;
5671         case 5:
5672             DECODE_PRINTF("SUB\t");
5673             break;
5674         case 6:
5675             DECODE_PRINTF("XOR\t");
5676             break;
5677         case 7:
5678             DECODE_PRINTF("CMP\t");
5679             break;
5680         }
5681     }
5682 #endif
5683     /* know operation, decode the mod byte to find the addressing
5684        mode. */
5685     switch (mod) {
5686     case 0:
5687         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5688             u32 destval,imm;
5689
5690             DECODE_PRINTF("DWORD PTR ");
5691             destoffset = decode_rm00_address(rl);
5692             destval = fetch_data_long(destoffset);
5693             imm = (s8) fetch_byte_imm();
5694             DECODE_PRINTF2(",%x\n", imm);
5695             TRACE_AND_STEP();
5696             destval = (*opc83_long_operation[rh]) (destval, imm);
5697             if (rh != 7)
5698                 store_data_long(destoffset, destval);
5699         } else {
5700             u16 destval,imm;
5701
5702             DECODE_PRINTF("WORD PTR ");
5703             destoffset = decode_rm00_address(rl);
5704             destval = fetch_data_word(destoffset);
5705             imm = (s8) fetch_byte_imm();
5706             DECODE_PRINTF2(",%x\n", imm);
5707             TRACE_AND_STEP();
5708             destval = (*opc83_word_operation[rh]) (destval, imm);
5709             if (rh != 7)
5710                 store_data_word(destoffset, destval);
5711         }
5712         break;
5713     case 1:
5714         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5715             u32 destval,imm;
5716
5717             DECODE_PRINTF("DWORD PTR ");
5718             destoffset = decode_rm01_address(rl);
5719             destval = fetch_data_long(destoffset);
5720             imm = (s8) fetch_byte_imm();
5721             DECODE_PRINTF2(",%x\n", imm);
5722             TRACE_AND_STEP();
5723             destval = (*opc83_long_operation[rh]) (destval, imm);
5724             if (rh != 7)
5725                 store_data_long(destoffset, destval);
5726         } else {
5727             u16 destval,imm;
5728
5729             DECODE_PRINTF("WORD PTR ");
5730             destoffset = decode_rm01_address(rl);
5731             destval = fetch_data_word(destoffset);
5732             imm = (s8) fetch_byte_imm();
5733             DECODE_PRINTF2(",%x\n", imm);
5734             TRACE_AND_STEP();
5735             destval = (*opc83_word_operation[rh]) (destval, imm);
5736             if (rh != 7)
5737                 store_data_word(destoffset, destval);
5738         }
5739         break;
5740     case 2:
5741         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5742             u32 destval,imm;
5743
5744             DECODE_PRINTF("DWORD PTR ");
5745             destoffset = decode_rm10_address(rl);
5746             destval = fetch_data_long(destoffset);
5747             imm = (s8) fetch_byte_imm();
5748             DECODE_PRINTF2(",%x\n", imm);
5749             TRACE_AND_STEP();
5750             destval = (*opc83_long_operation[rh]) (destval, imm);
5751             if (rh != 7)
5752                 store_data_long(destoffset, destval);
5753         } else {
5754             u16 destval,imm;
5755
5756             DECODE_PRINTF("WORD PTR ");
5757             destoffset = decode_rm10_address(rl);
5758             destval = fetch_data_word(destoffset);
5759             imm = (s8) fetch_byte_imm();
5760             DECODE_PRINTF2(",%x\n", imm);
5761             TRACE_AND_STEP();
5762             destval = (*opc83_word_operation[rh]) (destval, imm);
5763             if (rh != 7)
5764                 store_data_word(destoffset, destval);
5765         }
5766         break;
5767     case 3:                     /* register to register */
5768         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5769             u32 *destreg;
5770             u32 destval,imm;
5771
5772             destreg = DECODE_RM_LONG_REGISTER(rl);
5773             imm = (s8) fetch_byte_imm();
5774             DECODE_PRINTF2(",%x\n", imm);
5775             TRACE_AND_STEP();
5776             destval = (*opc83_long_operation[rh]) (*destreg, imm);
5777             if (rh != 7)
5778                 *destreg = destval;
5779         } else {
5780             u16 *destreg;
5781             u16 destval,imm;
5782
5783             destreg = DECODE_RM_WORD_REGISTER(rl);
5784             imm = (s8) fetch_byte_imm();
5785             DECODE_PRINTF2(",%x\n", imm);
5786             TRACE_AND_STEP();
5787             destval = (*opc83_word_operation[rh]) (*destreg, imm);
5788             if (rh != 7)
5789                 *destreg = destval;
5790         }
5791         break;
5792     }
5793     DECODE_CLEAR_SEGOVR();
5794     END_OF_INSTR();
5795 }
5796
5797 /****************************************************************************
5798 REMARKS:
5799 Handles opcode 0x84
5800 ****************************************************************************/
5801 void x86emuOp_test_byte_RM_R(u8 X86EMU_UNUSED(op1))
5802 {
5803     int mod, rl, rh;
5804     u8 *destreg, *srcreg;
5805     uint destoffset;
5806     u8 destval;
5807
5808     START_OF_INSTR();
5809     DECODE_PRINTF("TEST\t");
5810     FETCH_DECODE_MODRM(mod, rh, rl);
5811     switch (mod) {
5812     case 0:
5813         destoffset = decode_rm00_address(rl);
5814         DECODE_PRINTF(",");
5815         destval = fetch_data_byte(destoffset);
5816         srcreg = DECODE_RM_BYTE_REGISTER(rh);
5817         DECODE_PRINTF("\n");
5818         TRACE_AND_STEP();
5819         test_byte(destval, *srcreg);
5820         break;
5821     case 1:
5822         destoffset = decode_rm01_address(rl);
5823         DECODE_PRINTF(",");
5824         destval = fetch_data_byte(destoffset);
5825         srcreg = DECODE_RM_BYTE_REGISTER(rh);
5826         DECODE_PRINTF("\n");
5827         TRACE_AND_STEP();
5828         test_byte(destval, *srcreg);
5829         break;
5830     case 2:
5831         destoffset = decode_rm10_address(rl);
5832         DECODE_PRINTF(",");
5833         destval = fetch_data_byte(destoffset);
5834         srcreg = DECODE_RM_BYTE_REGISTER(rh);
5835         DECODE_PRINTF("\n");
5836         TRACE_AND_STEP();
5837         test_byte(destval, *srcreg);
5838         break;
5839     case 3:                     /* register to register */
5840         destreg = DECODE_RM_BYTE_REGISTER(rl);
5841         DECODE_PRINTF(",");
5842         srcreg = DECODE_RM_BYTE_REGISTER(rh);
5843         DECODE_PRINTF("\n");
5844         TRACE_AND_STEP();
5845         test_byte(*destreg, *srcreg);
5846         break;
5847     }
5848     DECODE_CLEAR_SEGOVR();
5849     END_OF_INSTR();
5850 }
5851
5852 /****************************************************************************
5853 REMARKS:
5854 Handles opcode 0x85
5855 ****************************************************************************/
5856 void x86emuOp_test_word_RM_R(u8 X86EMU_UNUSED(op1))
5857 {
5858     int mod, rl, rh;
5859     uint destoffset;
5860
5861     START_OF_INSTR();
5862     DECODE_PRINTF("TEST\t");
5863     FETCH_DECODE_MODRM(mod, rh, rl);
5864     switch (mod) {
5865     case 0:
5866         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5867             u32 destval;
5868             u32 *srcreg;
5869
5870             destoffset = decode_rm00_address(rl);
5871             DECODE_PRINTF(",");
5872             destval = fetch_data_long(destoffset);
5873             srcreg = DECODE_RM_LONG_REGISTER(rh);
5874             DECODE_PRINTF("\n");
5875             TRACE_AND_STEP();
5876             test_long(destval, *srcreg);
5877         } else {
5878             u16 destval;
5879             u16 *srcreg;
5880
5881             destoffset = decode_rm00_address(rl);
5882             DECODE_PRINTF(",");
5883             destval = fetch_data_word(destoffset);
5884             srcreg = DECODE_RM_WORD_REGISTER(rh);
5885             DECODE_PRINTF("\n");
5886             TRACE_AND_STEP();
5887             test_word(destval, *srcreg);
5888         }
5889         break;
5890     case 1:
5891         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5892             u32 destval;
5893             u32 *srcreg;
5894
5895             destoffset = decode_rm01_address(rl);
5896             DECODE_PRINTF(",");
5897             destval = fetch_data_long(destoffset);
5898             srcreg = DECODE_RM_LONG_REGISTER(rh);
5899             DECODE_PRINTF("\n");
5900             TRACE_AND_STEP();
5901             test_long(destval, *srcreg);
5902         } else {
5903             u16 destval;
5904             u16 *srcreg;
5905
5906             destoffset = decode_rm01_address(rl);
5907             DECODE_PRINTF(",");
5908             destval = fetch_data_word(destoffset);
5909             srcreg = DECODE_RM_WORD_REGISTER(rh);
5910             DECODE_PRINTF("\n");
5911             TRACE_AND_STEP();
5912             test_word(destval, *srcreg);
5913         }
5914         break;
5915     case 2:
5916         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5917             u32 destval;
5918             u32 *srcreg;
5919
5920             destoffset = decode_rm10_address(rl);
5921             DECODE_PRINTF(",");
5922             destval = fetch_data_long(destoffset);
5923             srcreg = DECODE_RM_LONG_REGISTER(rh);
5924             DECODE_PRINTF("\n");
5925             TRACE_AND_STEP();
5926             test_long(destval, *srcreg);
5927         } else {
5928             u16 destval;
5929             u16 *srcreg;
5930
5931             destoffset = decode_rm10_address(rl);
5932             DECODE_PRINTF(",");
5933             destval = fetch_data_word(destoffset);
5934             srcreg = DECODE_RM_WORD_REGISTER(rh);
5935             DECODE_PRINTF("\n");
5936             TRACE_AND_STEP();
5937             test_word(destval, *srcreg);
5938         }
5939         break;
5940     case 3:                     /* register to register */
5941         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5942             u32 *destreg,*srcreg;
5943
5944             destreg = DECODE_RM_LONG_REGISTER(rl);
5945             DECODE_PRINTF(",");
5946             srcreg = DECODE_RM_LONG_REGISTER(rh);
5947             DECODE_PRINTF("\n");
5948             TRACE_AND_STEP();
5949             test_long(*destreg, *srcreg);
5950         } else {
5951             u16 *destreg,*srcreg;
5952
5953             destreg = DECODE_RM_WORD_REGISTER(rl);
5954             DECODE_PRINTF(",");
5955             srcreg = DECODE_RM_WORD_REGISTER(rh);
5956             DECODE_PRINTF("\n");
5957             TRACE_AND_STEP();
5958             test_word(*destreg, *srcreg);
5959         }
5960         break;
5961     }
5962     DECODE_CLEAR_SEGOVR();
5963     END_OF_INSTR();
5964 }
5965
5966 /****************************************************************************
5967 REMARKS:
5968 Handles opcode 0x86
5969 ****************************************************************************/
5970 void x86emuOp_xchg_byte_RM_R(u8 X86EMU_UNUSED(op1))
5971 {
5972     int mod, rl, rh;
5973     u8 *destreg, *srcreg;
5974     uint destoffset;
5975     u8 destval;
5976     u8 tmp;
5977
5978     START_OF_INSTR();
5979     DECODE_PRINTF("XCHG\t");
5980     FETCH_DECODE_MODRM(mod, rh, rl);
5981     switch (mod) {
5982     case 0:
5983         destoffset = decode_rm00_address(rl);
5984         DECODE_PRINTF(",");
5985         destval = fetch_data_byte(destoffset);
5986         srcreg = DECODE_RM_BYTE_REGISTER(rh);
5987         DECODE_PRINTF("\n");
5988         TRACE_AND_STEP();
5989         tmp = *srcreg;
5990         *srcreg = destval;
5991         destval = tmp;
5992         store_data_byte(destoffset, destval);
5993         break;
5994     case 1:
5995         destoffset = decode_rm01_address(rl);
5996         DECODE_PRINTF(",");
5997         destval = fetch_data_byte(destoffset);
5998         srcreg = DECODE_RM_BYTE_REGISTER(rh);
5999         DECODE_PRINTF("\n");
6000         TRACE_AND_STEP();
6001         tmp = *srcreg;
6002         *srcreg = destval;
6003         destval = tmp;
6004         store_data_byte(destoffset, destval);
6005         break;
6006     case 2:
6007         destoffset = decode_rm10_address(rl);
6008         DECODE_PRINTF(",");
6009         destval = fetch_data_byte(destoffset);
6010         srcreg = DECODE_RM_BYTE_REGISTER(rh);
6011         DECODE_PRINTF("\n");
6012         TRACE_AND_STEP();
6013         tmp = *srcreg;
6014         *srcreg = destval;
6015         destval = tmp;
6016         store_data_byte(destoffset, destval);
6017         break;
6018     case 3:                     /* register to register */
6019         destreg = DECODE_RM_BYTE_REGISTER(rl);
6020         DECODE_PRINTF(",");
6021         srcreg = DECODE_RM_BYTE_REGISTER(rh);
6022         DECODE_PRINTF("\n");
6023         TRACE_AND_STEP();
6024         tmp = *srcreg;
6025         *srcreg = *destreg;
6026         *destreg = tmp;
6027         break;
6028     }
6029     DECODE_CLEAR_SEGOVR();
6030     END_OF_INSTR();
6031 }
6032
6033 /****************************************************************************
6034 REMARKS:
6035 Handles opcode 0x87
6036 ****************************************************************************/
6037 void x86emuOp_xchg_word_RM_R(u8 X86EMU_UNUSED(op1))
6038 {
6039     int mod, rl, rh;
6040     uint destoffset;
6041
6042     START_OF_INSTR();
6043     DECODE_PRINTF("XCHG\t");
6044     FETCH_DECODE_MODRM(mod, rh, rl);
6045     switch (mod) {
6046     case 0:
6047         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6048             u32 *srcreg;
6049             u32 destval,tmp;
6050
6051             destoffset = decode_rm00_address(rl);
6052             DECODE_PRINTF(",");
6053             destval = fetch_data_long(destoffset);
6054             srcreg = DECODE_RM_LONG_REGISTER(rh);
6055             DECODE_PRINTF("\n");
6056             TRACE_AND_STEP();
6057             tmp = *srcreg;
6058             *srcreg = destval;
6059             destval = tmp;
6060             store_data_long(destoffset, destval);
6061         } else {
6062             u16 *srcreg;
6063             u16 destval,tmp;
6064
6065             destoffset = decode_rm00_address(rl);
6066             DECODE_PRINTF(",");
6067             destval = fetch_data_word(destoffset);
6068             srcreg = DECODE_RM_WORD_REGISTER(rh);
6069             DECODE_PRINTF("\n");
6070             TRACE_AND_STEP();
6071             tmp = *srcreg;
6072             *srcreg = destval;
6073             destval = tmp;
6074             store_data_word(destoffset, destval);
6075         }
6076         break;
6077     case 1:
6078         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6079             u32 *srcreg;
6080             u32 destval,tmp;
6081
6082             destoffset = decode_rm01_address(rl);
6083             DECODE_PRINTF(",");
6084             destval = fetch_data_long(destoffset);
6085             srcreg = DECODE_RM_LONG_REGISTER(rh);
6086             DECODE_PRINTF("\n");
6087             TRACE_AND_STEP();
6088             tmp = *srcreg;
6089             *srcreg = destval;
6090             destval = tmp;
6091             store_data_long(destoffset, destval);
6092         } else {
6093             u16 *srcreg;
6094             u16 destval,tmp;
6095
6096             destoffset = decode_rm01_address(rl);
6097             DECODE_PRINTF(",");
6098             destval = fetch_data_word(destoffset);
6099             srcreg = DECODE_RM_WORD_REGISTER(rh);
6100             DECODE_PRINTF("\n");
6101             TRACE_AND_STEP();
6102             tmp = *srcreg;
6103             *srcreg = destval;
6104             destval = tmp;
6105             store_data_word(destoffset, destval);
6106         }
6107         break;
6108     case 2:
6109         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6110             u32 *srcreg;
6111             u32 destval,tmp;
6112
6113             destoffset = decode_rm10_address(rl);
6114             DECODE_PRINTF(",");
6115             destval = fetch_data_long(destoffset);
6116             srcreg = DECODE_RM_LONG_REGISTER(rh);
6117             DECODE_PRINTF("\n");
6118             TRACE_AND_STEP();
6119             tmp = *srcreg;
6120             *srcreg = destval;
6121             destval = tmp;
6122             store_data_long(destoffset, destval);
6123         } else {
6124             u16 *srcreg;
6125             u16 destval,tmp;
6126
6127             destoffset = decode_rm10_address(rl);
6128             DECODE_PRINTF(",");
6129             destval = fetch_data_word(destoffset);
6130             srcreg = DECODE_RM_WORD_REGISTER(rh);
6131             DECODE_PRINTF("\n");
6132             TRACE_AND_STEP();
6133             tmp = *srcreg;
6134             *srcreg = destval;
6135             destval = tmp;
6136             store_data_word(destoffset, destval);
6137         }
6138         break;
6139     case 3:                     /* register to register */
6140         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6141             u32 *destreg,*srcreg;
6142             u32 tmp;
6143
6144             destreg = DECODE_RM_LONG_REGISTER(rl);
6145             DECODE_PRINTF(",");
6146             srcreg = DECODE_RM_LONG_REGISTER(rh);
6147             DECODE_PRINTF("\n");
6148             TRACE_AND_STEP();
6149             tmp = *srcreg;
6150             *srcreg = *destreg;
6151             *destreg = tmp;
6152         } else {
6153             u16 *destreg,*srcreg;
6154             u16 tmp;
6155
6156             destreg = DECODE_RM_WORD_REGISTER(rl);
6157             DECODE_PRINTF(",");
6158             srcreg = DECODE_RM_WORD_REGISTER(rh);
6159             DECODE_PRINTF("\n");
6160             TRACE_AND_STEP();
6161             tmp = *srcreg;
6162             *srcreg = *destreg;
6163             *destreg = tmp;
6164         }
6165         break;
6166     }
6167     DECODE_CLEAR_SEGOVR();
6168     END_OF_INSTR();
6169 }
6170
6171 /****************************************************************************
6172 REMARKS:
6173 Handles opcode 0x88
6174 ****************************************************************************/
6175 void x86emuOp_mov_byte_RM_R(u8 X86EMU_UNUSED(op1))
6176 {
6177     int mod, rl, rh;
6178     u8 *destreg, *srcreg;
6179     uint destoffset;
6180
6181     START_OF_INSTR();
6182     DECODE_PRINTF("MOV\t");
6183     FETCH_DECODE_MODRM(mod, rh, rl);
6184     switch (mod) {
6185     case 0:
6186         destoffset = decode_rm00_address(rl);
6187         DECODE_PRINTF(",");
6188         srcreg = DECODE_RM_BYTE_REGISTER(rh);
6189         DECODE_PRINTF("\n");
6190         TRACE_AND_STEP();
6191         store_data_byte(destoffset, *srcreg);
6192         break;
6193     case 1:
6194         destoffset = decode_rm01_address(rl);
6195         DECODE_PRINTF(",");
6196         srcreg = DECODE_RM_BYTE_REGISTER(rh);
6197         DECODE_PRINTF("\n");
6198         TRACE_AND_STEP();
6199         store_data_byte(destoffset, *srcreg);
6200         break;
6201     case 2:
6202         destoffset = decode_rm10_address(rl);
6203         DECODE_PRINTF(",");
6204         srcreg = DECODE_RM_BYTE_REGISTER(rh);
6205         DECODE_PRINTF("\n");
6206         TRACE_AND_STEP();
6207         store_data_byte(destoffset, *srcreg);
6208         break;
6209     case 3:                     /* register to register */
6210         destreg = DECODE_RM_BYTE_REGISTER(rl);
6211         DECODE_PRINTF(",");
6212         srcreg = DECODE_RM_BYTE_REGISTER(rh);
6213         DECODE_PRINTF("\n");
6214         TRACE_AND_STEP();
6215         *destreg = *srcreg;
6216         break;
6217     }
6218     DECODE_CLEAR_SEGOVR();
6219     END_OF_INSTR();
6220 }
6221
6222 /****************************************************************************
6223 REMARKS:
6224 Handles opcode 0x89
6225 ****************************************************************************/
6226 void x86emuOp_mov_word_RM_R(u8 X86EMU_UNUSED(op1))
6227 {
6228     int mod, rl, rh;
6229     uint destoffset;
6230
6231     START_OF_INSTR();
6232     DECODE_PRINTF("MOV\t");
6233     FETCH_DECODE_MODRM(mod, rh, rl);
6234     switch (mod) {
6235     case 0:
6236         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6237             u32 *srcreg;
6238
6239             destoffset = decode_rm00_address(rl);
6240             DECODE_PRINTF(",");
6241             srcreg = DECODE_RM_LONG_REGISTER(rh);
6242             DECODE_PRINTF("\n");
6243             TRACE_AND_STEP();
6244             store_data_long(destoffset, *srcreg);
6245         } else {
6246             u16 *srcreg;
6247
6248             destoffset = decode_rm00_address(rl);
6249             DECODE_PRINTF(",");
6250             srcreg = DECODE_RM_WORD_REGISTER(rh);
6251             DECODE_PRINTF("\n");
6252             TRACE_AND_STEP();
6253             store_data_word(destoffset, *srcreg);
6254         }
6255         break;
6256     case 1:
6257         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6258             u32 *srcreg;
6259
6260             destoffset = decode_rm01_address(rl);
6261             DECODE_PRINTF(",");
6262             srcreg = DECODE_RM_LONG_REGISTER(rh);
6263             DECODE_PRINTF("\n");
6264             TRACE_AND_STEP();
6265             store_data_long(destoffset, *srcreg);
6266         } else {
6267             u16 *srcreg;
6268
6269             destoffset = decode_rm01_address(rl);
6270             DECODE_PRINTF(",");
6271             srcreg = DECODE_RM_WORD_REGISTER(rh);
6272             DECODE_PRINTF("\n");
6273             TRACE_AND_STEP();
6274             store_data_word(destoffset, *srcreg);
6275         }
6276         break;
6277     case 2:
6278         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6279             u32 *srcreg;
6280
6281             destoffset = decode_rm10_address(rl);
6282             DECODE_PRINTF(",");
6283             srcreg = DECODE_RM_LONG_REGISTER(rh);
6284             DECODE_PRINTF("\n");
6285             TRACE_AND_STEP();
6286             store_data_long(destoffset, *srcreg);
6287         } else {
6288             u16 *srcreg;
6289
6290             destoffset = decode_rm10_address(rl);
6291             DECODE_PRINTF(",");
6292             srcreg = DECODE_RM_WORD_REGISTER(rh);
6293             DECODE_PRINTF("\n");
6294             TRACE_AND_STEP();
6295             store_data_word(destoffset, *srcreg);
6296         }
6297         break;
6298     case 3:                     /* register to register */
6299         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6300             u32 *destreg,*srcreg;
6301
6302             destreg = DECODE_RM_LONG_REGISTER(rl);
6303             DECODE_PRINTF(",");
6304             srcreg = DECODE_RM_LONG_REGISTER(rh);
6305             DECODE_PRINTF("\n");
6306             TRACE_AND_STEP();
6307             *destreg = *srcreg;
6308         } else {
6309             u16 *destreg,*srcreg;
6310
6311             destreg = DECODE_RM_WORD_REGISTER(rl);
6312             DECODE_PRINTF(",");
6313             srcreg = DECODE_RM_WORD_REGISTER(rh);
6314             DECODE_PRINTF("\n");
6315             TRACE_AND_STEP();
6316             *destreg = *srcreg;
6317         }
6318         break;
6319     }
6320     DECODE_CLEAR_SEGOVR();
6321     END_OF_INSTR();
6322 }
6323
6324 /****************************************************************************
6325 REMARKS:
6326 Handles opcode 0x8a
6327 ****************************************************************************/
6328 void x86emuOp_mov_byte_R_RM(u8 X86EMU_UNUSED(op1))
6329 {
6330     int mod, rl, rh;
6331     u8 *destreg, *srcreg;
6332     uint srcoffset;
6333     u8 srcval;
6334
6335     START_OF_INSTR();
6336     DECODE_PRINTF("MOV\t");
6337     FETCH_DECODE_MODRM(mod, rh, rl);
6338     switch (mod) {
6339     case 0:
6340         destreg = DECODE_RM_BYTE_REGISTER(rh);
6341         DECODE_PRINTF(",");
6342         srcoffset = decode_rm00_address(rl);
6343         srcval = fetch_data_byte(srcoffset);
6344         DECODE_PRINTF("\n");
6345         TRACE_AND_STEP();
6346         *destreg = srcval;
6347         break;
6348     case 1:
6349         destreg = DECODE_RM_BYTE_REGISTER(rh);
6350         DECODE_PRINTF(",");
6351         srcoffset = decode_rm01_address(rl);
6352         srcval = fetch_data_byte(srcoffset);
6353         DECODE_PRINTF("\n");
6354         TRACE_AND_STEP();
6355         *destreg = srcval;
6356         break;
6357     case 2:
6358         destreg = DECODE_RM_BYTE_REGISTER(rh);
6359         DECODE_PRINTF(",");
6360         srcoffset = decode_rm10_address(rl);
6361         srcval = fetch_data_byte(srcoffset);
6362         DECODE_PRINTF("\n");
6363         TRACE_AND_STEP();
6364         *destreg = srcval;
6365         break;
6366     case 3:                     /* register to register */
6367         destreg = DECODE_RM_BYTE_REGISTER(rh);
6368         DECODE_PRINTF(",");
6369         srcreg = DECODE_RM_BYTE_REGISTER(rl);
6370         DECODE_PRINTF("\n");
6371         TRACE_AND_STEP();
6372         *destreg = *srcreg;
6373         break;
6374     }
6375     DECODE_CLEAR_SEGOVR();
6376     END_OF_INSTR();
6377 }
6378
6379 /****************************************************************************
6380 REMARKS:
6381 Handles opcode 0x8b
6382 ****************************************************************************/
6383 void x86emuOp_mov_word_R_RM(u8 X86EMU_UNUSED(op1))
6384 {
6385     int mod, rl, rh;
6386     uint srcoffset;
6387
6388     START_OF_INSTR();
6389     DECODE_PRINTF("MOV\t");
6390     FETCH_DECODE_MODRM(mod, rh, rl);
6391     switch (mod) {
6392     case 0:
6393         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6394             u32 *destreg;
6395             u32 srcval;
6396
6397             destreg = DECODE_RM_LONG_REGISTER(rh);
6398             DECODE_PRINTF(",");
6399             srcoffset = decode_rm00_address(rl);
6400             srcval = fetch_data_long(srcoffset);
6401             DECODE_PRINTF("\n");
6402             TRACE_AND_STEP();
6403             *destreg = srcval;
6404         } else {
6405             u16 *destreg;
6406             u16 srcval;
6407
6408             destreg = DECODE_RM_WORD_REGISTER(rh);
6409             DECODE_PRINTF(",");
6410             srcoffset = decode_rm00_address(rl);
6411             srcval = fetch_data_word(srcoffset);
6412             DECODE_PRINTF("\n");
6413             TRACE_AND_STEP();
6414             *destreg = srcval;
6415         }
6416         break;
6417     case 1:
6418         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6419             u32 *destreg;
6420             u32 srcval;
6421
6422             destreg = DECODE_RM_LONG_REGISTER(rh);
6423             DECODE_PRINTF(",");
6424             srcoffset = decode_rm01_address(rl);
6425             srcval = fetch_data_long(srcoffset);
6426             DECODE_PRINTF("\n");
6427             TRACE_AND_STEP();
6428             *destreg = srcval;
6429         } else {
6430             u16 *destreg;
6431             u16 srcval;
6432
6433             destreg = DECODE_RM_WORD_REGISTER(rh);
6434             DECODE_PRINTF(",");
6435             srcoffset = decode_rm01_address(rl);
6436             srcval = fetch_data_word(srcoffset);
6437             DECODE_PRINTF("\n");
6438             TRACE_AND_STEP();
6439             *destreg = srcval;
6440         }
6441         break;
6442     case 2:
6443         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6444             u32 *destreg;
6445             u32 srcval;
6446
6447             destreg = DECODE_RM_LONG_REGISTER(rh);
6448             DECODE_PRINTF(",");
6449             srcoffset = decode_rm10_address(rl);
6450             srcval = fetch_data_long(srcoffset);
6451             DECODE_PRINTF("\n");
6452             TRACE_AND_STEP();
6453             *destreg = srcval;
6454         } else {
6455             u16 *destreg;
6456             u16 srcval;
6457
6458             destreg = DECODE_RM_WORD_REGISTER(rh);
6459             DECODE_PRINTF(",");
6460             srcoffset = decode_rm10_address(rl);
6461             srcval = fetch_data_word(srcoffset);
6462             DECODE_PRINTF("\n");
6463             TRACE_AND_STEP();
6464             *destreg = srcval;
6465         }
6466         break;
6467     case 3:                     /* register to register */
6468         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6469             u32 *destreg, *srcreg;
6470
6471             destreg = DECODE_RM_LONG_REGISTER(rh);
6472             DECODE_PRINTF(",");
6473             srcreg = DECODE_RM_LONG_REGISTER(rl);
6474             DECODE_PRINTF("\n");
6475             TRACE_AND_STEP();
6476             *destreg = *srcreg;
6477         } else {
6478             u16 *destreg, *srcreg;
6479
6480             destreg = DECODE_RM_WORD_REGISTER(rh);
6481             DECODE_PRINTF(",");
6482             srcreg = DECODE_RM_WORD_REGISTER(rl);
6483             DECODE_PRINTF("\n");
6484             TRACE_AND_STEP();
6485             *destreg = *srcreg;
6486         }
6487         break;
6488     }
6489     DECODE_CLEAR_SEGOVR();
6490     END_OF_INSTR();
6491 }
6492
6493 /****************************************************************************
6494 REMARKS:
6495 Handles opcode 0x8c
6496 ****************************************************************************/
6497 void x86emuOp_mov_word_RM_SR(u8 X86EMU_UNUSED(op1))
6498 {
6499     int mod, rl, rh;
6500     u16 *destreg, *srcreg;
6501     uint destoffset;
6502     u16 destval;
6503
6504     START_OF_INSTR();
6505     DECODE_PRINTF("MOV\t");
6506     FETCH_DECODE_MODRM(mod, rh, rl);
6507     switch (mod) {
6508     case 0:
6509         destoffset = decode_rm00_address(rl);
6510         DECODE_PRINTF(",");
6511         srcreg = decode_rm_seg_register(rh);
6512         DECODE_PRINTF("\n");
6513         TRACE_AND_STEP();
6514         destval = *srcreg;
6515         store_data_word(destoffset, destval);
6516         break;
6517     case 1:
6518         destoffset = decode_rm01_address(rl);
6519         DECODE_PRINTF(",");
6520         srcreg = decode_rm_seg_register(rh);
6521         DECODE_PRINTF("\n");
6522         TRACE_AND_STEP();
6523         destval = *srcreg;
6524         store_data_word(destoffset, destval);
6525         break;
6526     case 2:
6527         destoffset = decode_rm10_address(rl);
6528         DECODE_PRINTF(",");
6529         srcreg = decode_rm_seg_register(rh);
6530         DECODE_PRINTF("\n");
6531         TRACE_AND_STEP();
6532         destval = *srcreg;
6533         store_data_word(destoffset, destval);
6534         break;
6535     case 3:                     /* register to register */
6536         destreg = DECODE_RM_WORD_REGISTER(rl);
6537         DECODE_PRINTF(",");
6538         srcreg = decode_rm_seg_register(rh);
6539         DECODE_PRINTF("\n");
6540         TRACE_AND_STEP();
6541         *destreg = *srcreg;
6542         break;
6543     }
6544     DECODE_CLEAR_SEGOVR();
6545     END_OF_INSTR();
6546 }
6547
6548 /****************************************************************************
6549 REMARKS:
6550 Handles opcode 0x8d
6551 ****************************************************************************/
6552 void x86emuOp_lea_word_R_M(u8 X86EMU_UNUSED(op1))
6553 {
6554     int mod, rl, rh;
6555     u16 *srcreg;
6556     uint destoffset;
6557
6558 /*
6559  * TODO: Need to handle address size prefix!
6560  *
6561  * lea  eax,[eax+ebx*2] ??
6562  */
6563     
6564     START_OF_INSTR();
6565     DECODE_PRINTF("LEA\t");
6566     FETCH_DECODE_MODRM(mod, rh, rl);
6567     switch (mod) {
6568     case 0:
6569         srcreg = DECODE_RM_WORD_REGISTER(rh);
6570         DECODE_PRINTF(",");
6571         destoffset = decode_rm00_address(rl);
6572         DECODE_PRINTF("\n");
6573         TRACE_AND_STEP();
6574         *srcreg = (u16)destoffset;
6575         break;
6576     case 1:
6577         srcreg = DECODE_RM_WORD_REGISTER(rh);
6578         DECODE_PRINTF(",");
6579         destoffset = decode_rm01_address(rl);
6580         DECODE_PRINTF("\n");
6581         TRACE_AND_STEP();
6582         *srcreg = (u16)destoffset;
6583         break;
6584     case 2:
6585         srcreg = DECODE_RM_WORD_REGISTER(rh);
6586         DECODE_PRINTF(",");
6587         destoffset = decode_rm10_address(rl);
6588         DECODE_PRINTF("\n");
6589         TRACE_AND_STEP();
6590         *srcreg = (u16)destoffset;
6591         break;
6592     case 3:                     /* register to register */
6593         /* undefined.  Do nothing. */
6594         break;
6595     }
6596     DECODE_CLEAR_SEGOVR();
6597     END_OF_INSTR();
6598 }
6599
6600 /****************************************************************************
6601 REMARKS:
6602 Handles opcode 0x8e
6603 ****************************************************************************/
6604 void x86emuOp_mov_word_SR_RM(u8 X86EMU_UNUSED(op1))
6605 {
6606     int mod, rl, rh;
6607     u16 *destreg, *srcreg;
6608     uint srcoffset;
6609     u16 srcval;
6610
6611     START_OF_INSTR();
6612     DECODE_PRINTF("MOV\t");
6613     FETCH_DECODE_MODRM(mod, rh, rl);
6614     switch (mod) {
6615     case 0:
6616         destreg = decode_rm_seg_register(rh);
6617         DECODE_PRINTF(",");
6618         srcoffset = decode_rm00_address(rl);
6619         srcval = fetch_data_word(srcoffset);
6620         DECODE_PRINTF("\n");
6621         TRACE_AND_STEP();
6622         *destreg = srcval;
6623         break;
6624     case 1:
6625         destreg = decode_rm_seg_register(rh);
6626         DECODE_PRINTF(",");
6627         srcoffset = decode_rm01_address(rl);
6628         srcval = fetch_data_word(srcoffset);
6629         DECODE_PRINTF("\n");
6630         TRACE_AND_STEP();
6631         *destreg = srcval;
6632         break;
6633     case 2:
6634         destreg = decode_rm_seg_register(rh);
6635         DECODE_PRINTF(",");
6636         srcoffset = decode_rm10_address(rl);
6637         srcval = fetch_data_word(srcoffset);
6638         DECODE_PRINTF("\n");
6639         TRACE_AND_STEP();
6640         *destreg = srcval;
6641         break;
6642     case 3:                     /* register to register */
6643         destreg = decode_rm_seg_register(rh);
6644         DECODE_PRINTF(",");
6645         srcreg = DECODE_RM_WORD_REGISTER(rl);
6646         DECODE_PRINTF("\n");
6647         TRACE_AND_STEP();
6648         *destreg = *srcreg;
6649         break;
6650     }
6651     /*
6652      * Clean up, and reset all the R_xSP pointers to the correct
6653      * locations.  This is about 3x too much overhead (doing all the
6654      * segreg ptrs when only one is needed, but this instruction
6655      * *cannot* be that common, and this isn't too much work anyway.
6656      */
6657     DECODE_CLEAR_SEGOVR();
6658     END_OF_INSTR();
6659 }
6660
6661 /****************************************************************************
6662 REMARKS:
6663 Handles opcode 0x8f
6664 ****************************************************************************/
6665 void x86emuOp_pop_RM(u8 X86EMU_UNUSED(op1))
6666 {
6667     int mod, rl, rh;
6668     uint destoffset;
6669
6670     START_OF_INSTR();
6671     DECODE_PRINTF("POP\t");
6672     FETCH_DECODE_MODRM(mod, rh, rl);
6673     if (rh != 0) {
6674         DECODE_PRINTF("ILLEGAL DECODE OF OPCODE 8F\n");
6675         HALT_SYS();
6676     }
6677     switch (mod) {
6678     case 0:
6679         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6680             u32 destval;
6681
6682             destoffset = decode_rm00_address(rl);
6683             DECODE_PRINTF("\n");
6684             TRACE_AND_STEP();
6685             destval = pop_long();
6686             store_data_long(destoffset, destval);
6687         } else {
6688             u16 destval;
6689
6690             destoffset = decode_rm00_address(rl);
6691             DECODE_PRINTF("\n");
6692             TRACE_AND_STEP();
6693             destval = pop_word();
6694             store_data_word(destoffset, destval);
6695         }
6696         break;
6697     case 1:
6698         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6699             u32 destval;
6700
6701             destoffset = decode_rm01_address(rl);
6702             DECODE_PRINTF("\n");
6703             TRACE_AND_STEP();
6704             destval = pop_long();
6705             store_data_long(destoffset, destval);
6706         } else {
6707             u16 destval;
6708
6709             destoffset = decode_rm01_address(rl);
6710             DECODE_PRINTF("\n");
6711             TRACE_AND_STEP();
6712             destval = pop_word();
6713             store_data_word(destoffset, destval);
6714         }
6715         break;
6716     case 2:
6717         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6718             u32 destval;
6719
6720             destoffset = decode_rm10_address(rl);
6721             DECODE_PRINTF("\n");
6722             TRACE_AND_STEP();
6723             destval = pop_long();
6724             store_data_long(destoffset, destval);
6725         } else {
6726             u16 destval;
6727
6728             destoffset = decode_rm10_address(rl);
6729             DECODE_PRINTF("\n");
6730             TRACE_AND_STEP();
6731             destval = pop_word();
6732             store_data_word(destoffset, destval);
6733         }
6734         break;
6735     case 3:                     /* register to register */
6736         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6737             u32 *destreg;
6738
6739             destreg = DECODE_RM_LONG_REGISTER(rl);
6740             DECODE_PRINTF("\n");
6741             TRACE_AND_STEP();
6742             *destreg = pop_long();
6743         } else {
6744             u16 *destreg;
6745
6746             destreg = DECODE_RM_WORD_REGISTER(rl);
6747             DECODE_PRINTF("\n");
6748             TRACE_AND_STEP();
6749             *destreg = pop_word();
6750         }
6751         break;
6752     }
6753     DECODE_CLEAR_SEGOVR();
6754     END_OF_INSTR();
6755 }
6756
6757 /****************************************************************************
6758 REMARKS:
6759 Handles opcode 0x90
6760 ****************************************************************************/
6761 void x86emuOp_nop(u8 X86EMU_UNUSED(op1))
6762 {
6763     START_OF_INSTR();
6764     DECODE_PRINTF("NOP\n");
6765     TRACE_AND_STEP();
6766     DECODE_CLEAR_SEGOVR();
6767     END_OF_INSTR();
6768 }
6769
6770 /****************************************************************************
6771 REMARKS:
6772 Handles opcode 0x91
6773 ****************************************************************************/
6774 void x86emuOp_xchg_word_AX_CX(u8 X86EMU_UNUSED(op1))
6775 {
6776     u32 tmp;
6777
6778     START_OF_INSTR();
6779     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6780         DECODE_PRINTF("XCHG\tEAX,ECX\n");
6781     } else {
6782         DECODE_PRINTF("XCHG\tAX,CX\n");
6783     }
6784     TRACE_AND_STEP();
6785     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6786         tmp = M.x86.R_EAX;
6787         M.x86.R_EAX = M.x86.R_ECX;
6788         M.x86.R_ECX = tmp;
6789     } else {
6790         tmp = M.x86.R_AX;
6791         M.x86.R_AX = M.x86.R_CX;
6792         M.x86.R_CX = (u16)tmp;
6793     }
6794     DECODE_CLEAR_SEGOVR();
6795     END_OF_INSTR();
6796 }
6797
6798 /****************************************************************************
6799 REMARKS:
6800 Handles opcode 0x92
6801 ****************************************************************************/
6802 void x86emuOp_xchg_word_AX_DX(u8 X86EMU_UNUSED(op1))
6803 {
6804     u32 tmp;
6805
6806     START_OF_INSTR();
6807     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6808         DECODE_PRINTF("XCHG\tEAX,EDX\n");
6809     } else {
6810         DECODE_PRINTF("XCHG\tAX,DX\n");
6811     }
6812     TRACE_AND_STEP();
6813     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6814         tmp = M.x86.R_EAX;
6815         M.x86.R_EAX = M.x86.R_EDX;
6816         M.x86.R_EDX = tmp;
6817     } else {
6818         tmp = M.x86.R_AX;
6819         M.x86.R_AX = M.x86.R_DX;
6820         M.x86.R_DX = (u16)tmp;
6821     }
6822     DECODE_CLEAR_SEGOVR();
6823     END_OF_INSTR();
6824 }
6825
6826 /****************************************************************************
6827 REMARKS:
6828 Handles opcode 0x93
6829 ****************************************************************************/
6830 void x86emuOp_xchg_word_AX_BX(u8 X86EMU_UNUSED(op1))
6831 {
6832     u32 tmp;
6833
6834     START_OF_INSTR();
6835     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6836         DECODE_PRINTF("XCHG\tEAX,EBX\n");
6837     } else {
6838         DECODE_PRINTF("XCHG\tAX,BX\n");
6839     }
6840     TRACE_AND_STEP();
6841     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6842         tmp = M.x86.R_EAX;
6843         M.x86.R_EAX = M.x86.R_EBX;
6844         M.x86.R_EBX = tmp;
6845     } else {
6846         tmp = M.x86.R_AX;
6847         M.x86.R_AX = M.x86.R_BX;
6848         M.x86.R_BX = (u16)tmp;
6849     }
6850     DECODE_CLEAR_SEGOVR();
6851     END_OF_INSTR();
6852 }
6853
6854 /****************************************************************************
6855 REMARKS:
6856 Handles opcode 0x94
6857 ****************************************************************************/
6858 void x86emuOp_xchg_word_AX_SP(u8 X86EMU_UNUSED(op1))
6859 {
6860     u32 tmp;
6861
6862     START_OF_INSTR();
6863     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6864         DECODE_PRINTF("XCHG\tEAX,ESP\n");
6865     } else {
6866         DECODE_PRINTF("XCHG\tAX,SP\n");
6867     }
6868     TRACE_AND_STEP();
6869     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6870         tmp = M.x86.R_EAX;
6871         M.x86.R_EAX = M.x86.R_ESP;
6872         M.x86.R_ESP = tmp;
6873     } else {
6874         tmp = M.x86.R_AX;
6875         M.x86.R_AX = M.x86.R_SP;
6876         M.x86.R_SP = (u16)tmp;
6877     }
6878     DECODE_CLEAR_SEGOVR();
6879     END_OF_INSTR();
6880 }
6881
6882 /****************************************************************************
6883 REMARKS:
6884 Handles opcode 0x95
6885 ****************************************************************************/
6886 void x86emuOp_xchg_word_AX_BP(u8 X86EMU_UNUSED(op1))
6887 {
6888     u32 tmp;
6889
6890     START_OF_INSTR();
6891     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6892         DECODE_PRINTF("XCHG\tEAX,EBP\n");
6893     } else {
6894         DECODE_PRINTF("XCHG\tAX,BP\n");
6895     }
6896     TRACE_AND_STEP();
6897     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6898         tmp = M.x86.R_EAX;
6899         M.x86.R_EAX = M.x86.R_EBP;
6900         M.x86.R_EBP = tmp;
6901     } else {
6902         tmp = M.x86.R_AX;
6903         M.x86.R_AX = M.x86.R_BP;
6904         M.x86.R_BP = (u16)tmp;
6905     }
6906     DECODE_CLEAR_SEGOVR();
6907     END_OF_INSTR();
6908 }
6909
6910 /****************************************************************************
6911 REMARKS:
6912 Handles opcode 0x96
6913 ****************************************************************************/
6914 void x86emuOp_xchg_word_AX_SI(u8 X86EMU_UNUSED(op1))
6915 {
6916     u32 tmp;
6917
6918     START_OF_INSTR();
6919     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6920         DECODE_PRINTF("XCHG\tEAX,ESI\n");
6921     } else {
6922         DECODE_PRINTF("XCHG\tAX,SI\n");
6923     }
6924     TRACE_AND_STEP();
6925     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6926         tmp = M.x86.R_EAX;
6927         M.x86.R_EAX = M.x86.R_ESI;
6928         M.x86.R_ESI = tmp;
6929     } else {
6930         tmp = M.x86.R_AX;
6931         M.x86.R_AX = M.x86.R_SI;
6932         M.x86.R_SI = (u16)tmp;
6933     }
6934     DECODE_CLEAR_SEGOVR();
6935     END_OF_INSTR();
6936 }
6937
6938 /****************************************************************************
6939 REMARKS:
6940 Handles opcode 0x97
6941 ****************************************************************************/
6942 void x86emuOp_xchg_word_AX_DI(u8 X86EMU_UNUSED(op1))
6943 {
6944     u32 tmp;
6945
6946     START_OF_INSTR();
6947     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6948         DECODE_PRINTF("XCHG\tEAX,EDI\n");
6949     } else {
6950         DECODE_PRINTF("XCHG\tAX,DI\n");
6951     }
6952     TRACE_AND_STEP();
6953     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6954         tmp = M.x86.R_EAX;
6955         M.x86.R_EAX = M.x86.R_EDI;
6956         M.x86.R_EDI = tmp;
6957     } else {
6958         tmp = M.x86.R_AX;
6959         M.x86.R_AX = M.x86.R_DI;
6960         M.x86.R_DI = (u16)tmp;
6961     }
6962     DECODE_CLEAR_SEGOVR();
6963     END_OF_INSTR();
6964 }
6965
6966 /****************************************************************************
6967 REMARKS:
6968 Handles opcode 0x98
6969 ****************************************************************************/
6970 void x86emuOp_cbw(u8 X86EMU_UNUSED(op1))
6971 {
6972     START_OF_INSTR();
6973     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6974         DECODE_PRINTF("CWDE\n");
6975     } else {
6976         DECODE_PRINTF("CBW\n");
6977     }
6978     TRACE_AND_STEP();
6979     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6980         if (M.x86.R_AX & 0x8000) {
6981             M.x86.R_EAX |= 0xffff0000;
6982         } else {
6983             M.x86.R_EAX &= 0x0000ffff;
6984         }
6985     } else {
6986         if (M.x86.R_AL & 0x80) {
6987             M.x86.R_AH = 0xff;
6988         } else {
6989             M.x86.R_AH = 0x0;
6990         }
6991     }
6992     DECODE_CLEAR_SEGOVR();
6993     END_OF_INSTR();
6994 }
6995
6996 /****************************************************************************
6997 REMARKS:
6998 Handles opcode 0x99
6999 ****************************************************************************/
7000 void x86emuOp_cwd(u8 X86EMU_UNUSED(op1))
7001 {
7002     START_OF_INSTR();
7003     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7004         DECODE_PRINTF("CDQ\n");
7005     } else {
7006         DECODE_PRINTF("CWD\n");
7007     }
7008     DECODE_PRINTF("CWD\n");
7009     TRACE_AND_STEP();
7010     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7011         if (M.x86.R_EAX & 0x80000000) {
7012             M.x86.R_EDX = 0xffffffff;
7013         } else {
7014             M.x86.R_EDX = 0x0;
7015         }
7016     } else {
7017         if (M.x86.R_AX & 0x8000) {
7018             M.x86.R_DX = 0xffff;
7019         } else {
7020             M.x86.R_DX = 0x0;
7021         }
7022     }
7023     DECODE_CLEAR_SEGOVR();
7024     END_OF_INSTR();
7025 }
7026
7027 /****************************************************************************
7028 REMARKS:
7029 Handles opcode 0x9a
7030 ****************************************************************************/
7031 void x86emuOp_call_far_IMM(u8 X86EMU_UNUSED(op1))
7032 {
7033     u16 farseg, faroff;
7034
7035     START_OF_INSTR();
7036         DECODE_PRINTF("CALL\t");
7037         faroff = fetch_word_imm();
7038         farseg = fetch_word_imm();
7039         DECODE_PRINTF2("%04x:", farseg);
7040         DECODE_PRINTF2("%04x\n", faroff);
7041         CALL_TRACE(M.x86.saved_cs, M.x86.saved_ip, farseg, faroff, "FAR ");
7042
7043     /* XXX
7044      * 
7045      * Hooked interrupt vectors calling into our "BIOS" will cause
7046      * problems unless all intersegment stuff is checked for BIOS
7047      * access.  Check needed here.  For moment, let it alone.
7048      */
7049     TRACE_AND_STEP();
7050     push_word(M.x86.R_CS);
7051     M.x86.R_CS = farseg;
7052     push_word(M.x86.R_IP);
7053     M.x86.R_IP = faroff;
7054     DECODE_CLEAR_SEGOVR();
7055     END_OF_INSTR();
7056 }
7057
7058 /****************************************************************************
7059 REMARKS:
7060 Handles opcode 0x9b
7061 ****************************************************************************/
7062 void x86emuOp_wait(u8 X86EMU_UNUSED(op1))
7063 {
7064     START_OF_INSTR();
7065     DECODE_PRINTF("WAIT");
7066     TRACE_AND_STEP();
7067     /* NADA.  */
7068     DECODE_CLEAR_SEGOVR();
7069     END_OF_INSTR();
7070 }
7071
7072 /****************************************************************************
7073 REMARKS:
7074 Handles opcode 0x9c
7075 ****************************************************************************/
7076 void x86emuOp_pushf_word(u8 X86EMU_UNUSED(op1))
7077 {
7078     u32 flags;
7079
7080     START_OF_INSTR();
7081     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7082         DECODE_PRINTF("PUSHFD\n");
7083     } else {
7084         DECODE_PRINTF("PUSHF\n");
7085     }
7086     TRACE_AND_STEP();
7087
7088     /* clear out *all* bits not representing flags, and turn on real bits */
7089     flags = (M.x86.R_EFLG & F_MSK) | F_ALWAYS_ON;
7090     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7091         push_long(flags);
7092     } else {
7093         push_word((u16)flags);
7094     }
7095     DECODE_CLEAR_SEGOVR();
7096     END_OF_INSTR();
7097 }
7098
7099 /****************************************************************************
7100 REMARKS:
7101 Handles opcode 0x9d
7102 ****************************************************************************/
7103 void x86emuOp_popf_word(u8 X86EMU_UNUSED(op1))
7104 {
7105     START_OF_INSTR();
7106     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7107         DECODE_PRINTF("POPFD\n");
7108     } else {
7109         DECODE_PRINTF("POPF\n");
7110     }
7111     TRACE_AND_STEP();
7112     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7113         M.x86.R_EFLG = pop_long();
7114     } else {
7115         M.x86.R_FLG = pop_word();
7116     }
7117     DECODE_CLEAR_SEGOVR();
7118     END_OF_INSTR();
7119 }
7120
7121 /****************************************************************************
7122 REMARKS:
7123 Handles opcode 0x9e
7124 ****************************************************************************/
7125 void x86emuOp_sahf(u8 X86EMU_UNUSED(op1))
7126 {
7127     START_OF_INSTR();
7128     DECODE_PRINTF("SAHF\n");
7129     TRACE_AND_STEP();
7130     /* clear the lower bits of the flag register */
7131     M.x86.R_FLG &= 0xffffff00;
7132     /* or in the AH register into the flags register */
7133     M.x86.R_FLG |= M.x86.R_AH;
7134     DECODE_CLEAR_SEGOVR();
7135     END_OF_INSTR();
7136 }
7137
7138 /****************************************************************************
7139 REMARKS:
7140 Handles opcode 0x9f
7141 ****************************************************************************/
7142 void x86emuOp_lahf(u8 X86EMU_UNUSED(op1))
7143 {
7144     START_OF_INSTR();
7145     DECODE_PRINTF("LAHF\n");
7146     TRACE_AND_STEP();
7147         M.x86.R_AH = (u8)(M.x86.R_FLG & 0xff);
7148     /*undocumented TC++ behavior??? Nope.  It's documented, but
7149        you have too look real hard to notice it. */
7150     M.x86.R_AH |= 0x2;
7151     DECODE_CLEAR_SEGOVR();
7152     END_OF_INSTR();
7153 }
7154
7155 /****************************************************************************
7156 REMARKS:
7157 Handles opcode 0xa0
7158 ****************************************************************************/
7159 void x86emuOp_mov_AL_M_IMM(u8 X86EMU_UNUSED(op1))
7160 {
7161     u16 offset;
7162
7163     START_OF_INSTR();
7164     DECODE_PRINTF("MOV\tAL,");
7165     offset = fetch_word_imm();
7166     DECODE_PRINTF2("[%04x]\n", offset);
7167     TRACE_AND_STEP();
7168     M.x86.R_AL = fetch_data_byte(offset);
7169     DECODE_CLEAR_SEGOVR();
7170     END_OF_INSTR();
7171 }
7172
7173 /****************************************************************************
7174 REMARKS:
7175 Handles opcode 0xa1
7176 ****************************************************************************/
7177 void x86emuOp_mov_AX_M_IMM(u8 X86EMU_UNUSED(op1))
7178 {
7179     u16 offset;
7180
7181     START_OF_INSTR();
7182     offset = fetch_word_imm();
7183     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7184         DECODE_PRINTF2("MOV\tEAX,[%04x]\n", offset);
7185     } else {
7186         DECODE_PRINTF2("MOV\tAX,[%04x]\n", offset);
7187     }
7188     TRACE_AND_STEP();
7189     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7190         M.x86.R_EAX = fetch_data_long(offset);
7191     } else {
7192         M.x86.R_AX = fetch_data_word(offset);
7193     }
7194     DECODE_CLEAR_SEGOVR();
7195     END_OF_INSTR();
7196 }
7197
7198 /****************************************************************************
7199 REMARKS:
7200 Handles opcode 0xa2
7201 ****************************************************************************/
7202 void x86emuOp_mov_M_AL_IMM(u8 X86EMU_UNUSED(op1))
7203 {
7204     u16 offset;
7205
7206     START_OF_INSTR();
7207     DECODE_PRINTF("MOV\t");
7208     offset = fetch_word_imm();
7209     DECODE_PRINTF2("[%04x],AL\n", offset);
7210     TRACE_AND_STEP();
7211     store_data_byte(offset, M.x86.R_AL);
7212     DECODE_CLEAR_SEGOVR();
7213     END_OF_INSTR();
7214 }
7215
7216 /****************************************************************************
7217 REMARKS:
7218 Handles opcode 0xa3
7219 ****************************************************************************/
7220 void x86emuOp_mov_M_AX_IMM(u8 X86EMU_UNUSED(op1))
7221 {
7222     u16 offset;
7223
7224     START_OF_INSTR();
7225     offset = fetch_word_imm();
7226     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7227         DECODE_PRINTF2("MOV\t[%04x],EAX\n", offset);
7228     } else {
7229         DECODE_PRINTF2("MOV\t[%04x],AX\n", offset);
7230     }
7231     TRACE_AND_STEP();
7232     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7233         store_data_long(offset, M.x86.R_EAX);
7234     } else {
7235         store_data_word(offset, M.x86.R_AX);
7236     }
7237     DECODE_CLEAR_SEGOVR();
7238     END_OF_INSTR();
7239 }
7240
7241 /****************************************************************************
7242 REMARKS:
7243 Handles opcode 0xa4
7244 ****************************************************************************/
7245 void x86emuOp_movs_byte(u8 X86EMU_UNUSED(op1))
7246 {
7247     u8  val;
7248     u32 count;
7249     int inc;
7250
7251     START_OF_INSTR();
7252     DECODE_PRINTF("MOVS\tBYTE\n");
7253     if (ACCESS_FLAG(F_DF))   /* down */
7254         inc = -1;
7255     else
7256         inc = 1;
7257     TRACE_AND_STEP();
7258     count = 1;
7259     if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
7260         /* dont care whether REPE or REPNE */
7261         /* move them until CX is ZERO. */
7262         count = M.x86.R_CX;
7263         M.x86.R_CX = 0;
7264         M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
7265     }
7266     while (count--) {
7267         val = fetch_data_byte(M.x86.R_SI);
7268         store_data_byte_abs(M.x86.R_ES, M.x86.R_DI, val);
7269         M.x86.R_SI += inc;
7270         M.x86.R_DI += inc;
7271     }
7272     DECODE_CLEAR_SEGOVR();
7273     END_OF_INSTR();
7274 }
7275
7276 /****************************************************************************
7277 REMARKS:
7278 Handles opcode 0xa5
7279 ****************************************************************************/
7280 void x86emuOp_movs_word(u8 X86EMU_UNUSED(op1))
7281 {
7282     u32 val;
7283     int inc;
7284     u32 count;
7285
7286     START_OF_INSTR();
7287     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7288         DECODE_PRINTF("MOVS\tDWORD\n");
7289         if (ACCESS_FLAG(F_DF))      /* down */
7290             inc = -4;
7291         else
7292             inc = 4;
7293     } else {
7294         DECODE_PRINTF("MOVS\tWORD\n");
7295         if (ACCESS_FLAG(F_DF))      /* down */
7296             inc = -2;
7297         else
7298             inc = 2;
7299     }
7300     TRACE_AND_STEP();
7301     count = 1;
7302     if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
7303         /* dont care whether REPE or REPNE */
7304         /* move them until CX is ZERO. */
7305         count = M.x86.R_CX;
7306         M.x86.R_CX = 0;
7307         M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
7308     }
7309     while (count--) {
7310         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7311             val = fetch_data_long(M.x86.R_SI);
7312             store_data_long_abs(M.x86.R_ES, M.x86.R_DI, val);
7313         } else {
7314             val = fetch_data_word(M.x86.R_SI);
7315             store_data_word_abs(M.x86.R_ES, M.x86.R_DI, (u16)val);
7316         }
7317         M.x86.R_SI += inc;
7318         M.x86.R_DI += inc;
7319     }
7320     DECODE_CLEAR_SEGOVR();
7321     END_OF_INSTR();
7322 }
7323
7324 /****************************************************************************
7325 REMARKS:
7326 Handles opcode 0xa6
7327 ****************************************************************************/
7328 void x86emuOp_cmps_byte(u8 X86EMU_UNUSED(op1))
7329 {
7330     s8 val1, val2;
7331     int inc;
7332
7333     START_OF_INSTR();
7334     DECODE_PRINTF("CMPS\tBYTE\n");
7335     TRACE_AND_STEP();
7336     if (ACCESS_FLAG(F_DF))   /* down */
7337         inc = -1;
7338     else
7339         inc = 1;
7340
7341     if (M.x86.mode & SYSMODE_PREFIX_REPE) {
7342         /* REPE  */
7343         /* move them until CX is ZERO. */
7344         while (M.x86.R_CX != 0) {
7345             val1 = fetch_data_byte(M.x86.R_SI);
7346             val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
7347                      cmp_byte(val1, val2);
7348             M.x86.R_CX -= 1;
7349             M.x86.R_SI += inc;
7350             M.x86.R_DI += inc;
7351             if (ACCESS_FLAG(F_ZF) == 0)
7352                 break;
7353         }
7354         M.x86.mode &= ~SYSMODE_PREFIX_REPE;
7355     } else if (M.x86.mode & SYSMODE_PREFIX_REPNE) {
7356         /* REPNE  */
7357         /* move them until CX is ZERO. */
7358         while (M.x86.R_CX != 0) {
7359             val1 = fetch_data_byte(M.x86.R_SI);
7360             val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
7361             cmp_byte(val1, val2);
7362             M.x86.R_CX -= 1;
7363             M.x86.R_SI += inc;
7364             M.x86.R_DI += inc;
7365             if (ACCESS_FLAG(F_ZF))
7366                 break;          /* zero flag set means equal */
7367         }
7368         M.x86.mode &= ~SYSMODE_PREFIX_REPNE;
7369     } else {
7370         val1 = fetch_data_byte(M.x86.R_SI);
7371         val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
7372         cmp_byte(val1, val2);
7373         M.x86.R_SI += inc;
7374         M.x86.R_DI += inc;
7375     }
7376     DECODE_CLEAR_SEGOVR();
7377     END_OF_INSTR();
7378 }
7379
7380 /****************************************************************************
7381 REMARKS:
7382 Handles opcode 0xa7
7383 ****************************************************************************/
7384 void x86emuOp_cmps_word(u8 X86EMU_UNUSED(op1))
7385 {
7386     u32 val1,val2;
7387     int inc;
7388
7389     START_OF_INSTR();
7390     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7391         DECODE_PRINTF("CMPS\tDWORD\n");
7392         if (ACCESS_FLAG(F_DF))   /* down */
7393             inc = -4;
7394         else
7395             inc = 4;
7396     } else {
7397         DECODE_PRINTF("CMPS\tWORD\n");
7398         if (ACCESS_FLAG(F_DF))   /* down */
7399             inc = -2;
7400         else
7401             inc = 2;
7402     }
7403     TRACE_AND_STEP();
7404     if (M.x86.mode & SYSMODE_PREFIX_REPE) {
7405         /* REPE  */
7406         /* move them until CX is ZERO. */
7407         while (M.x86.R_CX != 0) {
7408             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7409                 val1 = fetch_data_long(M.x86.R_SI);
7410                 val2 = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
7411                 cmp_long(val1, val2);
7412             } else {
7413                 val1 = fetch_data_word(M.x86.R_SI);
7414                 val2 = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
7415                 cmp_word((u16)val1, (u16)val2);
7416             }
7417             M.x86.R_CX -= 1;
7418             M.x86.R_SI += inc;
7419             M.x86.R_DI += inc;
7420             if (ACCESS_FLAG(F_ZF) == 0)
7421                 break;
7422         }
7423         M.x86.mode &= ~SYSMODE_PREFIX_REPE;
7424     } else if (M.x86.mode & SYSMODE_PREFIX_REPNE) {
7425         /* REPNE  */
7426         /* move them until CX is ZERO. */
7427         while (M.x86.R_CX != 0) {
7428             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7429                 val1 = fetch_data_long(M.x86.R_SI);
7430                 val2 = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
7431                 cmp_long(val1, val2);
7432             } else {
7433                 val1 = fetch_data_word(M.x86.R_SI);
7434                 val2 = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
7435                 cmp_word((u16)val1, (u16)val2);
7436             }
7437             M.x86.R_CX -= 1;
7438             M.x86.R_SI += inc;
7439             M.x86.R_DI += inc;
7440             if (ACCESS_FLAG(F_ZF))
7441                 break;          /* zero flag set means equal */
7442         }
7443         M.x86.mode &= ~SYSMODE_PREFIX_REPNE;
7444     } else {
7445         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7446             val1 = fetch_data_long(M.x86.R_SI);
7447             val2 = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
7448             cmp_long(val1, val2);
7449         } else {
7450             val1 = fetch_data_word(M.x86.R_SI);
7451             val2 = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
7452             cmp_word((u16)val1, (u16)val2);
7453         }
7454         M.x86.R_SI += inc;
7455         M.x86.R_DI += inc;
7456     }
7457     DECODE_CLEAR_SEGOVR();
7458     END_OF_INSTR();
7459 }
7460
7461 /****************************************************************************
7462 REMARKS:
7463 Handles opcode 0xa8
7464 ****************************************************************************/
7465 void x86emuOp_test_AL_IMM(u8 X86EMU_UNUSED(op1))
7466 {
7467     int imm;
7468
7469     START_OF_INSTR();
7470     DECODE_PRINTF("TEST\tAL,");
7471     imm = fetch_byte_imm();
7472     DECODE_PRINTF2("%04x\n", imm);
7473     TRACE_AND_STEP();
7474         test_byte(M.x86.R_AL, (u8)imm);
7475     DECODE_CLEAR_SEGOVR();
7476     END_OF_INSTR();
7477 }
7478
7479 /****************************************************************************
7480 REMARKS:
7481 Handles opcode 0xa9
7482 ****************************************************************************/
7483 void x86emuOp_test_AX_IMM(u8 X86EMU_UNUSED(op1))
7484 {
7485     u32 srcval;
7486
7487     START_OF_INSTR();
7488     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7489         DECODE_PRINTF("TEST\tEAX,");
7490         srcval = fetch_long_imm();
7491     } else {
7492         DECODE_PRINTF("TEST\tAX,");
7493         srcval = fetch_word_imm();
7494     }
7495     DECODE_PRINTF2("%x\n", srcval);
7496     TRACE_AND_STEP();
7497     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7498         test_long(M.x86.R_EAX, srcval);
7499     } else {
7500         test_word(M.x86.R_AX, (u16)srcval);
7501     }
7502     DECODE_CLEAR_SEGOVR();
7503     END_OF_INSTR();
7504 }
7505
7506 /****************************************************************************
7507 REMARKS:
7508 Handles opcode 0xaa
7509 ****************************************************************************/
7510 void x86emuOp_stos_byte(u8 X86EMU_UNUSED(op1))
7511 {
7512     int inc;
7513
7514     START_OF_INSTR();
7515     DECODE_PRINTF("STOS\tBYTE\n");
7516     if (ACCESS_FLAG(F_DF))   /* down */
7517         inc = -1;
7518     else
7519         inc = 1;
7520     TRACE_AND_STEP();
7521     if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
7522         /* dont care whether REPE or REPNE */
7523         /* move them until CX is ZERO. */
7524         while (M.x86.R_CX != 0) {
7525             store_data_byte_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_AL);
7526             M.x86.R_CX -= 1;
7527             M.x86.R_DI += inc;
7528         }
7529         M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
7530     } else {
7531         store_data_byte_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_AL);
7532         M.x86.R_DI += inc;
7533     }
7534     DECODE_CLEAR_SEGOVR();
7535     END_OF_INSTR();
7536 }
7537
7538 /****************************************************************************
7539 REMARKS:
7540 Handles opcode 0xab
7541 ****************************************************************************/
7542 void x86emuOp_stos_word(u8 X86EMU_UNUSED(op1))
7543 {
7544     int inc;
7545     u32 count;
7546
7547     START_OF_INSTR();
7548     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7549         DECODE_PRINTF("STOS\tDWORD\n");
7550         if (ACCESS_FLAG(F_DF))   /* down */
7551             inc = -4;
7552         else
7553             inc = 4;
7554     } else {
7555         DECODE_PRINTF("STOS\tWORD\n");
7556         if (ACCESS_FLAG(F_DF))   /* down */
7557             inc = -2;
7558         else
7559             inc = 2;
7560     }
7561     TRACE_AND_STEP();
7562     count = 1;
7563     if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
7564         /* dont care whether REPE or REPNE */
7565         /* move them until CX is ZERO. */
7566         count = M.x86.R_CX;
7567         M.x86.R_CX = 0;
7568         M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
7569     }
7570     while (count--) {
7571         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7572             store_data_long_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_EAX);
7573         } else {
7574             store_data_word_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_AX);
7575         }
7576         M.x86.R_DI += inc;
7577     }
7578     DECODE_CLEAR_SEGOVR();
7579     END_OF_INSTR();
7580 }
7581
7582 /****************************************************************************
7583 REMARKS:
7584 Handles opcode 0xac
7585 ****************************************************************************/
7586 void x86emuOp_lods_byte(u8 X86EMU_UNUSED(op1))
7587 {
7588     int inc;
7589
7590     START_OF_INSTR();
7591     DECODE_PRINTF("LODS\tBYTE\n");
7592     TRACE_AND_STEP();
7593     if (ACCESS_FLAG(F_DF))   /* down */
7594         inc = -1;
7595     else
7596         inc = 1;
7597     if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
7598         /* dont care whether REPE or REPNE */
7599         /* move them until CX is ZERO. */
7600         while (M.x86.R_CX != 0) {
7601             M.x86.R_AL = fetch_data_byte(M.x86.R_SI);
7602             M.x86.R_CX -= 1;
7603             M.x86.R_SI += inc;
7604         }
7605         M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
7606     } else {
7607         M.x86.R_AL = fetch_data_byte(M.x86.R_SI);
7608         M.x86.R_SI += inc;
7609     }
7610     DECODE_CLEAR_SEGOVR();
7611     END_OF_INSTR();
7612 }
7613
7614 /****************************************************************************
7615 REMARKS:
7616 Handles opcode 0xad
7617 ****************************************************************************/
7618 void x86emuOp_lods_word(u8 X86EMU_UNUSED(op1))
7619 {
7620     int inc;
7621     u32 count;
7622
7623     START_OF_INSTR();
7624     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7625         DECODE_PRINTF("LODS\tDWORD\n");
7626         if (ACCESS_FLAG(F_DF))   /* down */
7627             inc = -4;
7628         else
7629             inc = 4;
7630     } else {
7631         DECODE_PRINTF("LODS\tWORD\n");
7632         if (ACCESS_FLAG(F_DF))   /* down */
7633             inc = -2;
7634         else
7635             inc = 2;
7636     }
7637     TRACE_AND_STEP();
7638     count = 1;
7639     if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
7640         /* dont care whether REPE or REPNE */
7641         /* move them until CX is ZERO. */
7642         count = M.x86.R_CX;
7643         M.x86.R_CX = 0;
7644         M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
7645     }
7646     while (count--) {
7647         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7648             M.x86.R_EAX = fetch_data_long(M.x86.R_SI);
7649         } else {
7650             M.x86.R_AX = fetch_data_word(M.x86.R_SI);
7651         }
7652         M.x86.R_SI += inc;
7653     }
7654     DECODE_CLEAR_SEGOVR();
7655     END_OF_INSTR();
7656 }
7657
7658 /****************************************************************************
7659 REMARKS:
7660 Handles opcode 0xae
7661 ****************************************************************************/
7662 void x86emuOp_scas_byte(u8 X86EMU_UNUSED(op1))
7663 {
7664     s8 val2;
7665     int inc;
7666
7667     START_OF_INSTR();
7668     DECODE_PRINTF("SCAS\tBYTE\n");
7669     TRACE_AND_STEP();
7670     if (ACCESS_FLAG(F_DF))   /* down */
7671         inc = -1;
7672     else
7673         inc = 1;
7674     if (M.x86.mode & SYSMODE_PREFIX_REPE) {
7675         /* REPE  */
7676         /* move them until CX is ZERO. */
7677         while (M.x86.R_CX != 0) {
7678             val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
7679             cmp_byte(M.x86.R_AL, val2);
7680             M.x86.R_CX -= 1;
7681             M.x86.R_DI += inc;
7682             if (ACCESS_FLAG(F_ZF) == 0)
7683                 break;
7684         }
7685         M.x86.mode &= ~SYSMODE_PREFIX_REPE;
7686     } else if (M.x86.mode & SYSMODE_PREFIX_REPNE) {
7687         /* REPNE  */
7688         /* move them until CX is ZERO. */
7689         while (M.x86.R_CX != 0) {
7690             val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
7691             cmp_byte(M.x86.R_AL, val2);
7692             M.x86.R_CX -= 1;
7693             M.x86.R_DI += inc;
7694             if (ACCESS_FLAG(F_ZF))
7695                 break;          /* zero flag set means equal */
7696         }
7697         M.x86.mode &= ~SYSMODE_PREFIX_REPNE;
7698     } else {
7699         val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
7700         cmp_byte(M.x86.R_AL, val2);
7701         M.x86.R_DI += inc;
7702     }
7703     DECODE_CLEAR_SEGOVR();
7704     END_OF_INSTR();
7705 }
7706
7707 /****************************************************************************
7708 REMARKS:
7709 Handles opcode 0xaf
7710 ****************************************************************************/
7711 void x86emuOp_scas_word(u8 X86EMU_UNUSED(op1))
7712 {
7713     int inc;
7714     u32 val;
7715
7716     START_OF_INSTR();
7717     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7718         DECODE_PRINTF("SCAS\tDWORD\n");
7719         if (ACCESS_FLAG(F_DF))   /* down */
7720             inc = -4;
7721         else
7722             inc = 4;
7723     } else {
7724         DECODE_PRINTF("SCAS\tWORD\n");
7725         if (ACCESS_FLAG(F_DF))   /* down */
7726             inc = -2;
7727         else
7728             inc = 2;
7729     }
7730     TRACE_AND_STEP();
7731     if (M.x86.mode & SYSMODE_PREFIX_REPE) {
7732         /* REPE  */
7733         /* move them until CX is ZERO. */
7734         while (M.x86.R_CX != 0) {
7735             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7736                 val = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
7737                 cmp_long(M.x86.R_EAX, val);
7738             } else {
7739                 val = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
7740                 cmp_word(M.x86.R_AX, (u16)val);
7741             }
7742             M.x86.R_CX -= 1;
7743             M.x86.R_DI += inc;
7744             if (ACCESS_FLAG(F_ZF) == 0)
7745                 break;
7746         }
7747         M.x86.mode &= ~SYSMODE_PREFIX_REPE;
7748     } else if (M.x86.mode & SYSMODE_PREFIX_REPNE) {
7749         /* REPNE  */
7750         /* move them until CX is ZERO. */
7751         while (M.x86.R_CX != 0) {
7752             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7753                 val = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
7754                 cmp_long(M.x86.R_EAX, val);
7755             } else {
7756                 val = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
7757                 cmp_word(M.x86.R_AX, (u16)val);
7758             }
7759             M.x86.R_CX -= 1;
7760             M.x86.R_DI += inc;
7761             if (ACCESS_FLAG(F_ZF))
7762                 break;          /* zero flag set means equal */
7763         }
7764         M.x86.mode &= ~SYSMODE_PREFIX_REPNE;
7765     } else {
7766         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7767             val = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
7768             cmp_long(M.x86.R_EAX, val);
7769         } else {
7770             val = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
7771             cmp_word(M.x86.R_AX, (u16)val);
7772         }
7773         M.x86.R_DI += inc;
7774     }
7775     DECODE_CLEAR_SEGOVR();
7776     END_OF_INSTR();
7777 }
7778
7779 /****************************************************************************
7780 REMARKS:
7781 Handles opcode 0xb0
7782 ****************************************************************************/
7783 void x86emuOp_mov_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
7784 {
7785     u8 imm;
7786
7787     START_OF_INSTR();
7788     DECODE_PRINTF("MOV\tAL,");
7789     imm = fetch_byte_imm();
7790     DECODE_PRINTF2("%x\n", imm);
7791     TRACE_AND_STEP();
7792     M.x86.R_AL = imm;
7793     DECODE_CLEAR_SEGOVR();
7794     END_OF_INSTR();
7795 }
7796
7797 /****************************************************************************
7798 REMARKS:
7799 Handles opcode 0xb1
7800 ****************************************************************************/
7801 void x86emuOp_mov_byte_CL_IMM(u8 X86EMU_UNUSED(op1))
7802 {
7803     u8 imm;
7804
7805     START_OF_INSTR();
7806     DECODE_PRINTF("MOV\tCL,");
7807     imm = fetch_byte_imm();
7808     DECODE_PRINTF2("%x\n", imm);
7809     TRACE_AND_STEP();
7810     M.x86.R_CL = imm;
7811     DECODE_CLEAR_SEGOVR();
7812     END_OF_INSTR();
7813 }
7814
7815 /****************************************************************************
7816 REMARKS:
7817 Handles opcode 0xb2
7818 ****************************************************************************/
7819 void x86emuOp_mov_byte_DL_IMM(u8 X86EMU_UNUSED(op1))
7820 {
7821     u8 imm;
7822
7823     START_OF_INSTR();
7824     DECODE_PRINTF("MOV\tDL,");
7825     imm = fetch_byte_imm();
7826     DECODE_PRINTF2("%x\n", imm);
7827     TRACE_AND_STEP();
7828     M.x86.R_DL = imm;
7829     DECODE_CLEAR_SEGOVR();
7830     END_OF_INSTR();
7831 }
7832
7833 /****************************************************************************
7834 REMARKS:
7835 Handles opcode 0xb3
7836 ****************************************************************************/
7837 void x86emuOp_mov_byte_BL_IMM(u8 X86EMU_UNUSED(op1))
7838 {
7839     u8 imm;
7840
7841     START_OF_INSTR();
7842     DECODE_PRINTF("MOV\tBL,");
7843     imm = fetch_byte_imm();
7844     DECODE_PRINTF2("%x\n", imm);
7845     TRACE_AND_STEP();
7846     M.x86.R_BL = imm;
7847     DECODE_CLEAR_SEGOVR();
7848     END_OF_INSTR();
7849 }
7850
7851 /****************************************************************************
7852 REMARKS:
7853 Handles opcode 0xb4
7854 ****************************************************************************/
7855 void x86emuOp_mov_byte_AH_IMM(u8 X86EMU_UNUSED(op1))
7856 {
7857     u8 imm;
7858
7859     START_OF_INSTR();
7860     DECODE_PRINTF("MOV\tAH,");
7861     imm = fetch_byte_imm();
7862     DECODE_PRINTF2("%x\n", imm);
7863     TRACE_AND_STEP();
7864     M.x86.R_AH = imm;
7865     DECODE_CLEAR_SEGOVR();
7866     END_OF_INSTR();
7867 }
7868
7869 /****************************************************************************
7870 REMARKS:
7871 Handles opcode 0xb5
7872 ****************************************************************************/
7873 void x86emuOp_mov_byte_CH_IMM(u8 X86EMU_UNUSED(op1))
7874 {
7875     u8 imm;
7876
7877     START_OF_INSTR();
7878     DECODE_PRINTF("MOV\tCH,");
7879     imm = fetch_byte_imm();
7880     DECODE_PRINTF2("%x\n", imm);
7881     TRACE_AND_STEP();
7882     M.x86.R_CH = imm;
7883     DECODE_CLEAR_SEGOVR();
7884     END_OF_INSTR();
7885 }
7886
7887 /****************************************************************************
7888 REMARKS:
7889 Handles opcode 0xb6
7890 ****************************************************************************/
7891 void x86emuOp_mov_byte_DH_IMM(u8 X86EMU_UNUSED(op1))
7892 {
7893     u8 imm;
7894
7895     START_OF_INSTR();
7896     DECODE_PRINTF("MOV\tDH,");
7897     imm = fetch_byte_imm();
7898     DECODE_PRINTF2("%x\n", imm);
7899     TRACE_AND_STEP();
7900     M.x86.R_DH = imm;
7901     DECODE_CLEAR_SEGOVR();
7902     END_OF_INSTR();
7903 }
7904
7905 /****************************************************************************
7906 REMARKS:
7907 Handles opcode 0xb7
7908 ****************************************************************************/
7909 void x86emuOp_mov_byte_BH_IMM(u8 X86EMU_UNUSED(op1))
7910 {
7911     u8 imm;
7912
7913     START_OF_INSTR();
7914     DECODE_PRINTF("MOV\tBH,");
7915     imm = fetch_byte_imm();
7916     DECODE_PRINTF2("%x\n", imm);
7917     TRACE_AND_STEP();
7918     M.x86.R_BH = imm;
7919     DECODE_CLEAR_SEGOVR();
7920     END_OF_INSTR();
7921 }
7922
7923 /****************************************************************************
7924 REMARKS:
7925 Handles opcode 0xb8
7926 ****************************************************************************/
7927 void x86emuOp_mov_word_AX_IMM(u8 X86EMU_UNUSED(op1))
7928 {
7929     u32 srcval;
7930
7931     START_OF_INSTR();
7932     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7933         DECODE_PRINTF("MOV\tEAX,");
7934         srcval = fetch_long_imm();
7935     } else {
7936         DECODE_PRINTF("MOV\tAX,");
7937         srcval = fetch_word_imm();
7938     }
7939     DECODE_PRINTF2("%x\n", srcval);
7940     TRACE_AND_STEP();
7941     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7942         M.x86.R_EAX = srcval;
7943     } else {
7944         M.x86.R_AX = (u16)srcval;
7945     }
7946     DECODE_CLEAR_SEGOVR();
7947     END_OF_INSTR();
7948 }
7949
7950 /****************************************************************************
7951 REMARKS:
7952 Handles opcode 0xb9
7953 ****************************************************************************/
7954 void x86emuOp_mov_word_CX_IMM(u8 X86EMU_UNUSED(op1))
7955 {
7956     u32 srcval;
7957
7958     START_OF_INSTR();
7959     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7960         DECODE_PRINTF("MOV\tECX,");
7961         srcval = fetch_long_imm();
7962     } else {
7963         DECODE_PRINTF("MOV\tCX,");
7964         srcval = fetch_word_imm();
7965     }
7966     DECODE_PRINTF2("%x\n", srcval);
7967     TRACE_AND_STEP();
7968     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7969         M.x86.R_ECX = srcval;
7970     } else {
7971         M.x86.R_CX = (u16)srcval;
7972     }
7973     DECODE_CLEAR_SEGOVR();
7974     END_OF_INSTR();
7975 }
7976
7977 /****************************************************************************
7978 REMARKS:
7979 Handles opcode 0xba
7980 ****************************************************************************/
7981 void x86emuOp_mov_word_DX_IMM(u8 X86EMU_UNUSED(op1))
7982 {
7983     u32 srcval;
7984
7985     START_OF_INSTR();
7986     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7987         DECODE_PRINTF("MOV\tEDX,");
7988         srcval = fetch_long_imm();
7989     } else {
7990         DECODE_PRINTF("MOV\tDX,");
7991         srcval = fetch_word_imm();
7992     }
7993     DECODE_PRINTF2("%x\n", srcval);
7994     TRACE_AND_STEP();
7995     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7996         M.x86.R_EDX = srcval;
7997     } else {
7998         M.x86.R_DX = (u16)srcval;
7999     }
8000     DECODE_CLEAR_SEGOVR();
8001     END_OF_INSTR();
8002 }
8003
8004 /****************************************************************************
8005 REMARKS:
8006 Handles opcode 0xbb
8007 ****************************************************************************/
8008 void x86emuOp_mov_word_BX_IMM(u8 X86EMU_UNUSED(op1))
8009 {
8010     u32 srcval;
8011
8012     START_OF_INSTR();
8013     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8014         DECODE_PRINTF("MOV\tEBX,");
8015         srcval = fetch_long_imm();
8016     } else {
8017         DECODE_PRINTF("MOV\tBX,");
8018         srcval = fetch_word_imm();
8019     }
8020     DECODE_PRINTF2("%x\n", srcval);
8021     TRACE_AND_STEP();
8022     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8023         M.x86.R_EBX = srcval;
8024     } else {
8025         M.x86.R_BX = (u16)srcval;
8026     }
8027     DECODE_CLEAR_SEGOVR();
8028     END_OF_INSTR();
8029 }
8030
8031 /****************************************************************************
8032 REMARKS:
8033 Handles opcode 0xbc
8034 ****************************************************************************/
8035 void x86emuOp_mov_word_SP_IMM(u8 X86EMU_UNUSED(op1))
8036 {
8037     u32 srcval;
8038
8039     START_OF_INSTR();
8040     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8041         DECODE_PRINTF("MOV\tESP,");
8042         srcval = fetch_long_imm();
8043     } else {
8044         DECODE_PRINTF("MOV\tSP,");
8045         srcval = fetch_word_imm();
8046     }
8047     DECODE_PRINTF2("%x\n", srcval);
8048     TRACE_AND_STEP();
8049     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8050         M.x86.R_ESP = srcval;
8051     } else {
8052         M.x86.R_SP = (u16)srcval;
8053     }
8054     DECODE_CLEAR_SEGOVR();
8055     END_OF_INSTR();
8056 }
8057
8058 /****************************************************************************
8059 REMARKS:
8060 Handles opcode 0xbd
8061 ****************************************************************************/
8062 void x86emuOp_mov_word_BP_IMM(u8 X86EMU_UNUSED(op1))
8063 {
8064     u32 srcval;
8065
8066     START_OF_INSTR();
8067     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8068         DECODE_PRINTF("MOV\tEBP,");
8069         srcval = fetch_long_imm();
8070     } else {
8071         DECODE_PRINTF("MOV\tBP,");
8072         srcval = fetch_word_imm();
8073     }
8074     DECODE_PRINTF2("%x\n", srcval);
8075     TRACE_AND_STEP();
8076     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8077         M.x86.R_EBP = srcval;
8078     } else {
8079         M.x86.R_BP = (u16)srcval;
8080     }
8081     DECODE_CLEAR_SEGOVR();
8082     END_OF_INSTR();
8083 }
8084
8085 /****************************************************************************
8086 REMARKS:
8087 Handles opcode 0xbe
8088 ****************************************************************************/
8089 void x86emuOp_mov_word_SI_IMM(u8 X86EMU_UNUSED(op1))
8090 {
8091     u32 srcval;
8092
8093     START_OF_INSTR();
8094     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8095         DECODE_PRINTF("MOV\tESI,");
8096         srcval = fetch_long_imm();
8097     } else {
8098         DECODE_PRINTF("MOV\tSI,");
8099         srcval = fetch_word_imm();
8100     }
8101     DECODE_PRINTF2("%x\n", srcval);
8102     TRACE_AND_STEP();
8103     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8104         M.x86.R_ESI = srcval;
8105     } else {
8106         M.x86.R_SI = (u16)srcval;
8107     }
8108     DECODE_CLEAR_SEGOVR();
8109     END_OF_INSTR();
8110 }
8111
8112 /****************************************************************************
8113 REMARKS:
8114 Handles opcode 0xbf
8115 ****************************************************************************/
8116 void x86emuOp_mov_word_DI_IMM(u8 X86EMU_UNUSED(op1))
8117 {
8118     u32 srcval;
8119
8120     START_OF_INSTR();
8121     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8122         DECODE_PRINTF("MOV\tEDI,");
8123         srcval = fetch_long_imm();
8124     } else {
8125         DECODE_PRINTF("MOV\tDI,");
8126         srcval = fetch_word_imm();
8127     }
8128     DECODE_PRINTF2("%x\n", srcval);
8129     TRACE_AND_STEP();
8130     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8131         M.x86.R_EDI = srcval;
8132     } else {
8133         M.x86.R_DI = (u16)srcval;
8134     }
8135     DECODE_CLEAR_SEGOVR();
8136     END_OF_INSTR();
8137 }
8138
8139 /* used by opcodes c0, d0, and d2. */
8140 static u8(*opcD0_byte_operation[])(u8 d, u8 s) =
8141 {
8142     rol_byte,
8143     ror_byte,
8144     rcl_byte,
8145     rcr_byte,
8146     shl_byte,
8147     shr_byte,
8148     shl_byte,           /* sal_byte === shl_byte  by definition */
8149     sar_byte,
8150 };
8151
8152 /****************************************************************************
8153 REMARKS:
8154 Handles opcode 0xc0
8155 ****************************************************************************/
8156 void x86emuOp_opcC0_byte_RM_MEM(u8 X86EMU_UNUSED(op1))
8157 {
8158     int mod, rl, rh;
8159     u8 *destreg;
8160     uint destoffset;
8161     u8 destval;
8162     u8 amt;
8163
8164     /*
8165      * Yet another weirdo special case instruction format.  Part of
8166      * the opcode held below in "RH".  Doubly nested case would
8167      * result, except that the decoded instruction
8168      */
8169     START_OF_INSTR();
8170     FETCH_DECODE_MODRM(mod, rh, rl);
8171 #ifdef DEBUG
8172     if (DEBUG_DECODE()) {
8173         /* XXX DECODE_PRINTF may be changed to something more
8174            general, so that it is important to leave the strings
8175            in the same format, even though the result is that the 
8176            above test is done twice. */
8177
8178         switch (rh) {
8179         case 0:
8180             DECODE_PRINTF("ROL\t");
8181             break;
8182         case 1:
8183             DECODE_PRINTF("ROR\t");
8184             break;
8185         case 2:
8186             DECODE_PRINTF("RCL\t");
8187             break;
8188         case 3:
8189             DECODE_PRINTF("RCR\t");
8190             break;
8191         case 4:
8192             DECODE_PRINTF("SHL\t");
8193             break;
8194         case 5:
8195             DECODE_PRINTF("SHR\t");
8196             break;
8197         case 6:
8198             DECODE_PRINTF("SAL\t");
8199             break;
8200         case 7:
8201             DECODE_PRINTF("SAR\t");
8202             break;
8203         }
8204     }
8205 #endif
8206     /* know operation, decode the mod byte to find the addressing
8207        mode. */
8208     switch (mod) {
8209     case 0:
8210         DECODE_PRINTF("BYTE PTR ");
8211         destoffset = decode_rm00_address(rl);
8212         amt = fetch_byte_imm();
8213         DECODE_PRINTF2(",%x\n", amt);
8214         destval = fetch_data_byte(destoffset);
8215         TRACE_AND_STEP();
8216         destval = (*opcD0_byte_operation[rh]) (destval, amt);
8217         store_data_byte(destoffset, destval);
8218         break;
8219     case 1:
8220         DECODE_PRINTF("BYTE PTR ");
8221         destoffset = decode_rm01_address(rl);
8222         amt = fetch_byte_imm();
8223         DECODE_PRINTF2(",%x\n", amt);
8224         destval = fetch_data_byte(destoffset);
8225         TRACE_AND_STEP();
8226         destval = (*opcD0_byte_operation[rh]) (destval, amt);
8227         store_data_byte(destoffset, destval);
8228         break;
8229     case 2:
8230         DECODE_PRINTF("BYTE PTR ");
8231         destoffset = decode_rm10_address(rl);
8232         amt = fetch_byte_imm();
8233         DECODE_PRINTF2(",%x\n", amt);
8234         destval = fetch_data_byte(destoffset);
8235         TRACE_AND_STEP();
8236         destval = (*opcD0_byte_operation[rh]) (destval, amt);
8237         store_data_byte(destoffset, destval);
8238         break;
8239     case 3:                     /* register to register */
8240         destreg = DECODE_RM_BYTE_REGISTER(rl);
8241         amt = fetch_byte_imm();
8242         DECODE_PRINTF2(",%x\n", amt);
8243         TRACE_AND_STEP();
8244         destval = (*opcD0_byte_operation[rh]) (*destreg, amt);
8245         *destreg = destval;
8246         break;
8247     }
8248     DECODE_CLEAR_SEGOVR();
8249     END_OF_INSTR();
8250 }
8251
8252 /* used by opcodes c1, d1, and d3. */
8253 static u16(*opcD1_word_operation[])(u16 s, u8 d) =
8254 {
8255     rol_word,
8256     ror_word,
8257     rcl_word,
8258     rcr_word,
8259     shl_word,
8260     shr_word,
8261     shl_word,           /* sal_byte === shl_byte  by definition */
8262     sar_word,
8263 };
8264
8265 /* used by opcodes c1, d1, and d3. */
8266 static u32 (*opcD1_long_operation[])(u32 s, u8 d) =
8267 {
8268     rol_long,
8269     ror_long,
8270     rcl_long,
8271     rcr_long,
8272     shl_long,
8273     shr_long,
8274     shl_long,           /* sal_byte === shl_byte  by definition */
8275     sar_long,
8276 };
8277
8278 /****************************************************************************
8279 REMARKS:
8280 Handles opcode 0xc1
8281 ****************************************************************************/
8282 void x86emuOp_opcC1_word_RM_MEM(u8 X86EMU_UNUSED(op1))
8283 {
8284     int mod, rl, rh;
8285     uint destoffset;
8286     u8 amt;
8287
8288     /*
8289      * Yet another weirdo special case instruction format.  Part of
8290      * the opcode held below in "RH".  Doubly nested case would
8291      * result, except that the decoded instruction
8292      */
8293     START_OF_INSTR();
8294     FETCH_DECODE_MODRM(mod, rh, rl);
8295 #ifdef DEBUG
8296     if (DEBUG_DECODE()) {
8297         /* XXX DECODE_PRINTF may be changed to something more
8298            general, so that it is important to leave the strings
8299            in the same format, even though the result is that the 
8300            above test is done twice. */
8301
8302         switch (rh) {
8303         case 0:
8304             DECODE_PRINTF("ROL\t");
8305             break;
8306         case 1:
8307             DECODE_PRINTF("ROR\t");
8308             break;
8309         case 2:
8310             DECODE_PRINTF("RCL\t");
8311             break;
8312         case 3:
8313             DECODE_PRINTF("RCR\t");
8314             break;
8315         case 4:
8316             DECODE_PRINTF("SHL\t");
8317             break;
8318         case 5:
8319             DECODE_PRINTF("SHR\t");
8320             break;
8321         case 6:
8322             DECODE_PRINTF("SAL\t");
8323             break;
8324         case 7:
8325             DECODE_PRINTF("SAR\t");
8326             break;
8327         }
8328     }
8329 #endif
8330     /* know operation, decode the mod byte to find the addressing
8331        mode. */
8332     switch (mod) {
8333     case 0:
8334         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8335             u32 destval;
8336
8337             DECODE_PRINTF("DWORD PTR ");
8338             destoffset = decode_rm00_address(rl);
8339             amt = fetch_byte_imm();
8340             DECODE_PRINTF2(",%x\n", amt);
8341             destval = fetch_data_long(destoffset);
8342             TRACE_AND_STEP();
8343             destval = (*opcD1_long_operation[rh]) (destval, amt);
8344             store_data_long(destoffset, destval);
8345         } else {
8346             u16 destval;
8347
8348             DECODE_PRINTF("WORD PTR ");
8349             destoffset = decode_rm00_address(rl);
8350             amt = fetch_byte_imm();
8351             DECODE_PRINTF2(",%x\n", amt);
8352             destval = fetch_data_word(destoffset);
8353             TRACE_AND_STEP();
8354             destval = (*opcD1_word_operation[rh]) (destval, amt);
8355             store_data_word(destoffset, destval);
8356         }
8357         break;
8358     case 1:
8359         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8360             u32 destval;
8361
8362             DECODE_PRINTF("DWORD PTR ");
8363             destoffset = decode_rm01_address(rl);
8364             amt = fetch_byte_imm();
8365             DECODE_PRINTF2(",%x\n", amt);
8366             destval = fetch_data_long(destoffset);
8367             TRACE_AND_STEP();
8368             destval = (*opcD1_long_operation[rh]) (destval, amt);
8369             store_data_long(destoffset, destval);
8370         } else {
8371             u16 destval;
8372
8373             DECODE_PRINTF("WORD PTR ");
8374             destoffset = decode_rm01_address(rl);
8375             amt = fetch_byte_imm();
8376             DECODE_PRINTF2(",%x\n", amt);
8377             destval = fetch_data_word(destoffset);
8378             TRACE_AND_STEP();
8379             destval = (*opcD1_word_operation[rh]) (destval, amt);
8380             store_data_word(destoffset, destval);
8381         }
8382         break;
8383     case 2:
8384         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8385             u32 destval;
8386
8387             DECODE_PRINTF("DWORD PTR ");
8388             destoffset = decode_rm10_address(rl);
8389             amt = fetch_byte_imm();
8390             DECODE_PRINTF2(",%x\n", amt);
8391             destval = fetch_data_long(destoffset);
8392             TRACE_AND_STEP();
8393             destval = (*opcD1_long_operation[rh]) (destval, amt);
8394             store_data_long(destoffset, destval);
8395         } else {
8396             u16 destval;
8397
8398             DECODE_PRINTF("WORD PTR ");
8399             destoffset = decode_rm10_address(rl);
8400             amt = fetch_byte_imm();
8401             DECODE_PRINTF2(",%x\n", amt);
8402             destval = fetch_data_word(destoffset);
8403             TRACE_AND_STEP();
8404             destval = (*opcD1_word_operation[rh]) (destval, amt);
8405             store_data_word(destoffset, destval);
8406         }
8407         break;
8408     case 3:                     /* register to register */
8409         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8410             u32 *destreg;
8411
8412             destreg = DECODE_RM_LONG_REGISTER(rl);
8413             amt = fetch_byte_imm();
8414             DECODE_PRINTF2(",%x\n", amt);
8415             TRACE_AND_STEP();
8416             *destreg = (*opcD1_long_operation[rh]) (*destreg, amt);
8417         } else {
8418             u16 *destreg;
8419
8420             destreg = DECODE_RM_WORD_REGISTER(rl);
8421             amt = fetch_byte_imm();
8422             DECODE_PRINTF2(",%x\n", amt);
8423             TRACE_AND_STEP();
8424             *destreg = (*opcD1_word_operation[rh]) (*destreg, amt);
8425         }
8426         break;
8427     }
8428     DECODE_CLEAR_SEGOVR();
8429     END_OF_INSTR();
8430 }
8431
8432 /****************************************************************************
8433 REMARKS:
8434 Handles opcode 0xc2
8435 ****************************************************************************/
8436 void x86emuOp_ret_near_IMM(u8 X86EMU_UNUSED(op1))
8437 {
8438     u16 imm;
8439
8440     START_OF_INSTR();
8441     DECODE_PRINTF("RET\t");
8442     imm = fetch_word_imm();
8443     DECODE_PRINTF2("%x\n", imm);
8444         RETURN_TRACE("RET",M.x86.saved_cs,M.x86.saved_ip);
8445         TRACE_AND_STEP();
8446     M.x86.R_IP = pop_word();
8447     M.x86.R_SP += imm;
8448     DECODE_CLEAR_SEGOVR();
8449     END_OF_INSTR();
8450 }
8451
8452 /****************************************************************************
8453 REMARKS:
8454 Handles opcode 0xc3
8455 ****************************************************************************/
8456 void x86emuOp_ret_near(u8 X86EMU_UNUSED(op1))
8457 {
8458     START_OF_INSTR();
8459     DECODE_PRINTF("RET\n");
8460         RETURN_TRACE("RET",M.x86.saved_cs,M.x86.saved_ip);
8461         TRACE_AND_STEP();
8462     M.x86.R_IP = pop_word();
8463     DECODE_CLEAR_SEGOVR();
8464     END_OF_INSTR();
8465 }
8466
8467 /****************************************************************************
8468 REMARKS:
8469 Handles opcode 0xc4
8470 ****************************************************************************/
8471 void x86emuOp_les_R_IMM(u8 X86EMU_UNUSED(op1))
8472 {
8473     int mod, rh, rl;
8474     u16 *dstreg;
8475     uint srcoffset;
8476
8477     START_OF_INSTR();
8478     DECODE_PRINTF("LES\t");
8479     FETCH_DECODE_MODRM(mod, rh, rl);
8480     switch (mod) {
8481     case 0:
8482         dstreg = DECODE_RM_WORD_REGISTER(rh);
8483         DECODE_PRINTF(",");
8484         srcoffset = decode_rm00_address(rl);
8485         DECODE_PRINTF("\n");
8486         TRACE_AND_STEP();
8487         *dstreg = fetch_data_word(srcoffset);
8488         M.x86.R_ES = fetch_data_word(srcoffset + 2);
8489         break;
8490     case 1:
8491         dstreg = DECODE_RM_WORD_REGISTER(rh);
8492         DECODE_PRINTF(",");
8493         srcoffset = decode_rm01_address(rl);
8494         DECODE_PRINTF("\n");
8495         TRACE_AND_STEP();
8496         *dstreg = fetch_data_word(srcoffset);
8497         M.x86.R_ES = fetch_data_word(srcoffset + 2);
8498         break;
8499     case 2:
8500         dstreg = DECODE_RM_WORD_REGISTER(rh);
8501         DECODE_PRINTF(",");
8502         srcoffset = decode_rm10_address(rl);
8503         DECODE_PRINTF("\n");
8504         TRACE_AND_STEP();
8505         *dstreg = fetch_data_word(srcoffset);
8506         M.x86.R_ES = fetch_data_word(srcoffset + 2);
8507         break;
8508     case 3:                     /* register to register */
8509         /* UNDEFINED! */
8510         TRACE_AND_STEP();
8511     }
8512     DECODE_CLEAR_SEGOVR();
8513     END_OF_INSTR();
8514 }
8515
8516 /****************************************************************************
8517 REMARKS:
8518 Handles opcode 0xc5
8519 ****************************************************************************/
8520 void x86emuOp_lds_R_IMM(u8 X86EMU_UNUSED(op1))
8521 {
8522     int mod, rh, rl;
8523     u16 *dstreg;
8524     uint srcoffset;
8525
8526     START_OF_INSTR();
8527     DECODE_PRINTF("LDS\t");
8528     FETCH_DECODE_MODRM(mod, rh, rl);
8529     switch (mod) {
8530     case 0:
8531         dstreg = DECODE_RM_WORD_REGISTER(rh);
8532         DECODE_PRINTF(",");
8533         srcoffset = decode_rm00_address(rl);
8534         DECODE_PRINTF("\n");
8535         TRACE_AND_STEP();
8536         *dstreg = fetch_data_word(srcoffset);
8537         M.x86.R_DS = fetch_data_word(srcoffset + 2);
8538         break;
8539     case 1:
8540         dstreg = DECODE_RM_WORD_REGISTER(rh);
8541         DECODE_PRINTF(",");
8542         srcoffset = decode_rm01_address(rl);
8543         DECODE_PRINTF("\n");
8544         TRACE_AND_STEP();
8545         *dstreg = fetch_data_word(srcoffset);
8546         M.x86.R_DS = fetch_data_word(srcoffset + 2);
8547         break;
8548     case 2:
8549         dstreg = DECODE_RM_WORD_REGISTER(rh);
8550         DECODE_PRINTF(",");
8551         srcoffset = decode_rm10_address(rl);
8552         DECODE_PRINTF("\n");
8553         TRACE_AND_STEP();
8554         *dstreg = fetch_data_word(srcoffset);
8555         M.x86.R_DS = fetch_data_word(srcoffset + 2);
8556         break;
8557     case 3:                     /* register to register */
8558         /* UNDEFINED! */
8559         TRACE_AND_STEP();
8560     }
8561     DECODE_CLEAR_SEGOVR();
8562     END_OF_INSTR();
8563 }
8564
8565 /****************************************************************************
8566 REMARKS:
8567 Handles opcode 0xc6
8568 ****************************************************************************/
8569 void x86emuOp_mov_byte_RM_IMM(u8 X86EMU_UNUSED(op1))
8570 {
8571     int mod, rl, rh;
8572     u8 *destreg;
8573     uint destoffset;
8574     u8 imm;
8575
8576     START_OF_INSTR();
8577     DECODE_PRINTF("MOV\t");
8578     FETCH_DECODE_MODRM(mod, rh, rl);
8579     if (rh != 0) {
8580         DECODE_PRINTF("ILLEGAL DECODE OF OPCODE c6\n");
8581         HALT_SYS();
8582     }
8583     switch (mod) {
8584     case 0:
8585         DECODE_PRINTF("BYTE PTR ");
8586         destoffset = decode_rm00_address(rl);
8587         imm = fetch_byte_imm();
8588         DECODE_PRINTF2(",%2x\n", imm);
8589         TRACE_AND_STEP();
8590         store_data_byte(destoffset, imm);
8591         break;
8592     case 1:
8593         DECODE_PRINTF("BYTE PTR ");
8594         destoffset = decode_rm01_address(rl);
8595         imm = fetch_byte_imm();
8596         DECODE_PRINTF2(",%2x\n", imm);
8597         TRACE_AND_STEP();
8598         store_data_byte(destoffset, imm);
8599         break;
8600     case 2:
8601         DECODE_PRINTF("BYTE PTR ");
8602         destoffset = decode_rm10_address(rl);
8603         imm = fetch_byte_imm();
8604         DECODE_PRINTF2(",%2x\n", imm);
8605         TRACE_AND_STEP();
8606         store_data_byte(destoffset, imm);
8607         break;
8608     case 3:                     /* register to register */
8609         destreg = DECODE_RM_BYTE_REGISTER(rl);
8610         imm = fetch_byte_imm();
8611         DECODE_PRINTF2(",%2x\n", imm);
8612         TRACE_AND_STEP();
8613         *destreg = imm;
8614         break;
8615     }
8616     DECODE_CLEAR_SEGOVR();
8617     END_OF_INSTR();
8618 }
8619
8620 /****************************************************************************
8621 REMARKS:
8622 Handles opcode 0xc7
8623 ****************************************************************************/
8624 void x86emuOp_mov_word_RM_IMM(u8 X86EMU_UNUSED(op1))
8625 {
8626     int mod, rl, rh;
8627     uint destoffset;
8628
8629     START_OF_INSTR();
8630     DECODE_PRINTF("MOV\t");
8631     FETCH_DECODE_MODRM(mod, rh, rl);
8632     if (rh != 0) {
8633         DECODE_PRINTF("ILLEGAL DECODE OF OPCODE 8F\n");
8634         HALT_SYS();
8635     }
8636     switch (mod) {
8637     case 0:
8638         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8639             u32 imm;
8640
8641             DECODE_PRINTF("DWORD PTR ");
8642             destoffset = decode_rm00_address(rl);
8643             imm = fetch_long_imm();
8644             DECODE_PRINTF2(",%x\n", imm);
8645             TRACE_AND_STEP();
8646             store_data_long(destoffset, imm);
8647         } else {
8648             u16 imm;
8649
8650             DECODE_PRINTF("WORD PTR ");
8651             destoffset = decode_rm00_address(rl);
8652             imm = fetch_word_imm();
8653             DECODE_PRINTF2(",%x\n", imm);
8654             TRACE_AND_STEP();
8655             store_data_word(destoffset, imm);
8656         }
8657         break;
8658     case 1:
8659         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8660             u32 imm;
8661
8662             DECODE_PRINTF("DWORD PTR ");
8663             destoffset = decode_rm01_address(rl);
8664             imm = fetch_long_imm();
8665             DECODE_PRINTF2(",%x\n", imm);
8666             TRACE_AND_STEP();
8667             store_data_long(destoffset, imm);
8668         } else {
8669             u16 imm;
8670
8671             DECODE_PRINTF("WORD PTR ");
8672             destoffset = decode_rm01_address(rl);
8673             imm = fetch_word_imm();
8674             DECODE_PRINTF2(",%x\n", imm);
8675             TRACE_AND_STEP();
8676             store_data_word(destoffset, imm);
8677         }
8678         break;
8679     case 2:
8680         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8681             u32 imm;
8682
8683             DECODE_PRINTF("DWORD PTR ");
8684             destoffset = decode_rm10_address(rl);
8685             imm = fetch_long_imm();
8686             DECODE_PRINTF2(",%x\n", imm);
8687             TRACE_AND_STEP();
8688             store_data_long(destoffset, imm);
8689         } else {
8690             u16 imm;
8691
8692             DECODE_PRINTF("WORD PTR ");
8693             destoffset = decode_rm10_address(rl);
8694             imm = fetch_word_imm();
8695             DECODE_PRINTF2(",%x\n", imm);
8696             TRACE_AND_STEP();
8697             store_data_word(destoffset, imm);
8698         }
8699         break;
8700     case 3:                     /* register to register */
8701         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8702                         u32 *destreg;
8703                         u32 imm;
8704
8705             destreg = DECODE_RM_LONG_REGISTER(rl);
8706             imm = fetch_long_imm();
8707             DECODE_PRINTF2(",%x\n", imm);
8708             TRACE_AND_STEP();
8709             *destreg = imm;
8710         } else {
8711                         u16 *destreg;
8712                         u16 imm;
8713
8714             destreg = DECODE_RM_WORD_REGISTER(rl);
8715             imm = fetch_word_imm();
8716             DECODE_PRINTF2(",%x\n", imm);
8717             TRACE_AND_STEP();
8718             *destreg = imm;
8719         }
8720         break;
8721     }
8722     DECODE_CLEAR_SEGOVR();
8723     END_OF_INSTR();
8724 }
8725
8726 /****************************************************************************
8727 REMARKS:
8728 Handles opcode 0xc8
8729 ****************************************************************************/
8730 void x86emuOp_enter(u8 X86EMU_UNUSED(op1))
8731 {
8732     u16 local,frame_pointer;
8733     u8  nesting;
8734     int i;
8735
8736     START_OF_INSTR();
8737     local = fetch_word_imm();
8738     nesting = fetch_byte_imm();
8739     DECODE_PRINTF2("ENTER %x\n", local);
8740     DECODE_PRINTF2(",%x\n", nesting);
8741     TRACE_AND_STEP();
8742     push_word(M.x86.R_BP);
8743     frame_pointer = M.x86.R_SP;
8744     if (nesting > 0) {
8745         for (i = 1; i < nesting; i++) {
8746             M.x86.R_BP -= 2;
8747             push_word(fetch_data_word_abs(M.x86.R_SS, M.x86.R_BP));
8748             }
8749         push_word(frame_pointer);
8750         }
8751     M.x86.R_BP = frame_pointer;
8752     M.x86.R_SP = (u16)(M.x86.R_SP - local);
8753     DECODE_CLEAR_SEGOVR();
8754     END_OF_INSTR();
8755 }
8756
8757 /****************************************************************************
8758 REMARKS:
8759 Handles opcode 0xc9
8760 ****************************************************************************/
8761 void x86emuOp_leave(u8 X86EMU_UNUSED(op1))
8762 {
8763     START_OF_INSTR();
8764     DECODE_PRINTF("LEAVE\n");
8765     TRACE_AND_STEP();
8766     M.x86.R_SP = M.x86.R_BP;
8767     M.x86.R_BP = pop_word();
8768     DECODE_CLEAR_SEGOVR();
8769     END_OF_INSTR();
8770 }
8771
8772 /****************************************************************************
8773 REMARKS:
8774 Handles opcode 0xca
8775 ****************************************************************************/
8776 void x86emuOp_ret_far_IMM(u8 X86EMU_UNUSED(op1))
8777 {
8778     u16 imm;
8779
8780     START_OF_INSTR();
8781     DECODE_PRINTF("RETF\t");
8782     imm = fetch_word_imm();
8783     DECODE_PRINTF2("%x\n", imm);
8784         RETURN_TRACE("RETF",M.x86.saved_cs,M.x86.saved_ip);
8785         TRACE_AND_STEP();
8786     M.x86.R_IP = pop_word();
8787     M.x86.R_CS = pop_word();
8788     M.x86.R_SP += imm;
8789     DECODE_CLEAR_SEGOVR();
8790     END_OF_INSTR();
8791 }
8792
8793 /****************************************************************************
8794 REMARKS:
8795 Handles opcode 0xcb
8796 ****************************************************************************/
8797 void x86emuOp_ret_far(u8 X86EMU_UNUSED(op1))
8798 {
8799     START_OF_INSTR();
8800     DECODE_PRINTF("RETF\n");
8801         RETURN_TRACE("RETF",M.x86.saved_cs,M.x86.saved_ip);
8802         TRACE_AND_STEP();
8803     M.x86.R_IP = pop_word();
8804     M.x86.R_CS = pop_word();
8805     DECODE_CLEAR_SEGOVR();
8806     END_OF_INSTR();
8807 }
8808
8809 /****************************************************************************
8810 REMARKS:
8811 Handles opcode 0xcc
8812 ****************************************************************************/
8813 void x86emuOp_int3(u8 X86EMU_UNUSED(op1))
8814 {
8815     u16 tmp;
8816
8817     START_OF_INSTR();
8818     DECODE_PRINTF("INT 3\n");
8819     tmp = (u16) mem_access_word(3 * 4 + 2);
8820     /* access the segment register */
8821     TRACE_AND_STEP();
8822         if (_X86EMU_intrTab[3]) {
8823                 (*_X86EMU_intrTab[3])(3);
8824     } else {
8825         push_word((u16)M.x86.R_FLG);
8826         CLEAR_FLAG(F_IF);
8827         CLEAR_FLAG(F_TF);
8828         push_word(M.x86.R_CS);
8829         M.x86.R_CS = mem_access_word(3 * 4 + 2);
8830         push_word(M.x86.R_IP);
8831         M.x86.R_IP = mem_access_word(3 * 4);
8832     }
8833     DECODE_CLEAR_SEGOVR();
8834     END_OF_INSTR();
8835 }
8836
8837 /****************************************************************************
8838 REMARKS:
8839 Handles opcode 0xcd
8840 ****************************************************************************/
8841 void x86emuOp_int_IMM(u8 X86EMU_UNUSED(op1))
8842 {
8843     u16 tmp;
8844     u8 intnum;
8845
8846     START_OF_INSTR();
8847     DECODE_PRINTF("INT\t");
8848     intnum = fetch_byte_imm();
8849     DECODE_PRINTF2("%x\n", intnum);
8850     tmp = mem_access_word(intnum * 4 + 2);
8851     TRACE_AND_STEP();
8852         if (_X86EMU_intrTab[intnum]) {
8853                 (*_X86EMU_intrTab[intnum])(intnum);
8854     } else {
8855         push_word((u16)M.x86.R_FLG);
8856         CLEAR_FLAG(F_IF);
8857         CLEAR_FLAG(F_TF);
8858         push_word(M.x86.R_CS);
8859         M.x86.R_CS = mem_access_word(intnum * 4 + 2);
8860         push_word(M.x86.R_IP);
8861         M.x86.R_IP = mem_access_word(intnum * 4);
8862     }
8863     DECODE_CLEAR_SEGOVR();
8864     END_OF_INSTR();
8865 }
8866
8867 /****************************************************************************
8868 REMARKS:
8869 Handles opcode 0xce
8870 ****************************************************************************/
8871 void x86emuOp_into(u8 X86EMU_UNUSED(op1))
8872 {
8873     u16 tmp;
8874
8875     START_OF_INSTR();
8876     DECODE_PRINTF("INTO\n");
8877     TRACE_AND_STEP();
8878     if (ACCESS_FLAG(F_OF)) {
8879         tmp = mem_access_word(4 * 4 + 2);
8880                 if (_X86EMU_intrTab[4]) {
8881                         (*_X86EMU_intrTab[4])(4);
8882         } else {
8883             push_word((u16)M.x86.R_FLG);
8884             CLEAR_FLAG(F_IF);
8885             CLEAR_FLAG(F_TF);
8886             push_word(M.x86.R_CS);
8887             M.x86.R_CS = mem_access_word(4 * 4 + 2);
8888             push_word(M.x86.R_IP);
8889             M.x86.R_IP = mem_access_word(4 * 4);
8890         }
8891     }
8892     DECODE_CLEAR_SEGOVR();
8893     END_OF_INSTR();
8894 }
8895
8896 /****************************************************************************
8897 REMARKS:
8898 Handles opcode 0xcf
8899 ****************************************************************************/
8900 void x86emuOp_iret(u8 X86EMU_UNUSED(op1))
8901 {
8902     START_OF_INSTR();
8903     DECODE_PRINTF("IRET\n");
8904
8905     TRACE_AND_STEP();
8906
8907     M.x86.R_IP = pop_word();
8908     M.x86.R_CS = pop_word();
8909     M.x86.R_FLG = pop_word();
8910     DECODE_CLEAR_SEGOVR();
8911     END_OF_INSTR();
8912 }
8913
8914 /****************************************************************************
8915 REMARKS:
8916 Handles opcode 0xd0
8917 ****************************************************************************/
8918 void x86emuOp_opcD0_byte_RM_1(u8 X86EMU_UNUSED(op1))
8919 {
8920     int mod, rl, rh;
8921     u8 *destreg;
8922     uint destoffset;
8923     u8 destval;
8924
8925     /*
8926      * Yet another weirdo special case instruction format.  Part of
8927      * the opcode held below in "RH".  Doubly nested case would
8928      * result, except that the decoded instruction
8929      */
8930     START_OF_INSTR();
8931     FETCH_DECODE_MODRM(mod, rh, rl);
8932 #ifdef DEBUG
8933     if (DEBUG_DECODE()) {
8934         /* XXX DECODE_PRINTF may be changed to something more
8935            general, so that it is important to leave the strings
8936            in the same format, even though the result is that the
8937            above test is done twice. */
8938         switch (rh) {
8939         case 0:
8940             DECODE_PRINTF("ROL\t");
8941             break;
8942         case 1:
8943             DECODE_PRINTF("ROR\t");
8944             break;
8945         case 2:
8946             DECODE_PRINTF("RCL\t");
8947             break;
8948         case 3:
8949             DECODE_PRINTF("RCR\t");
8950             break;
8951         case 4:
8952             DECODE_PRINTF("SHL\t");
8953             break;
8954         case 5:
8955             DECODE_PRINTF("SHR\t");
8956             break;
8957         case 6:
8958             DECODE_PRINTF("SAL\t");
8959             break;
8960         case 7:
8961             DECODE_PRINTF("SAR\t");
8962             break;
8963         }
8964     }
8965 #endif
8966     /* know operation, decode the mod byte to find the addressing
8967        mode. */
8968     switch (mod) {
8969     case 0:
8970         DECODE_PRINTF("BYTE PTR ");
8971         destoffset = decode_rm00_address(rl);
8972         DECODE_PRINTF(",1\n");
8973         destval = fetch_data_byte(destoffset);
8974         TRACE_AND_STEP();
8975         destval = (*opcD0_byte_operation[rh]) (destval, 1);
8976         store_data_byte(destoffset, destval);
8977         break;
8978     case 1:
8979         DECODE_PRINTF("BYTE PTR ");
8980         destoffset = decode_rm01_address(rl);
8981         DECODE_PRINTF(",1\n");
8982         destval = fetch_data_byte(destoffset);
8983         TRACE_AND_STEP();
8984         destval = (*opcD0_byte_operation[rh]) (destval, 1);
8985         store_data_byte(destoffset, destval);
8986         break;
8987     case 2:
8988         DECODE_PRINTF("BYTE PTR ");
8989         destoffset = decode_rm10_address(rl);
8990         DECODE_PRINTF(",1\n");
8991         destval = fetch_data_byte(destoffset);
8992         TRACE_AND_STEP();
8993         destval = (*opcD0_byte_operation[rh]) (destval, 1);
8994         store_data_byte(destoffset, destval);
8995         break;
8996     case 3:                     /* register to register */
8997         destreg = DECODE_RM_BYTE_REGISTER(rl);
8998         DECODE_PRINTF(",1\n");
8999         TRACE_AND_STEP();
9000         destval = (*opcD0_byte_operation[rh]) (*destreg, 1);
9001         *destreg = destval;
9002         break;
9003     }
9004     DECODE_CLEAR_SEGOVR();
9005     END_OF_INSTR();
9006 }
9007
9008 /****************************************************************************
9009 REMARKS:
9010 Handles opcode 0xd1
9011 ****************************************************************************/
9012 void x86emuOp_opcD1_word_RM_1(u8 X86EMU_UNUSED(op1))
9013 {
9014     int mod, rl, rh;
9015     uint destoffset;
9016
9017     /*
9018      * Yet another weirdo special case instruction format.  Part of
9019      * the opcode held below in "RH".  Doubly nested case would
9020      * result, except that the decoded instruction
9021      */
9022     START_OF_INSTR();
9023     FETCH_DECODE_MODRM(mod, rh, rl);
9024 #ifdef DEBUG
9025     if (DEBUG_DECODE()) {
9026         /* XXX DECODE_PRINTF may be changed to something more
9027            general, so that it is important to leave the strings
9028            in the same format, even though the result is that the
9029            above test is done twice. */
9030         switch (rh) {
9031         case 0:
9032             DECODE_PRINTF("ROL\t");
9033             break;
9034         case 1:
9035             DECODE_PRINTF("ROR\t");
9036             break;
9037         case 2:
9038             DECODE_PRINTF("RCL\t");
9039             break;
9040         case 3:
9041             DECODE_PRINTF("RCR\t");
9042             break;
9043         case 4:
9044             DECODE_PRINTF("SHL\t");
9045             break;
9046         case 5:
9047             DECODE_PRINTF("SHR\t");
9048             break;
9049         case 6:
9050             DECODE_PRINTF("SAL\t");
9051             break;
9052         case 7:
9053             DECODE_PRINTF("SAR\t");
9054             break;
9055         }
9056     }
9057 #endif
9058     /* know operation, decode the mod byte to find the addressing
9059        mode. */
9060     switch (mod) {
9061     case 0:
9062         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9063             u32 destval;
9064
9065             DECODE_PRINTF("DWORD PTR ");
9066             destoffset = decode_rm00_address(rl);
9067             DECODE_PRINTF(",1\n");
9068             destval = fetch_data_long(destoffset);
9069             TRACE_AND_STEP();
9070             destval = (*opcD1_long_operation[rh]) (destval, 1);
9071             store_data_long(destoffset, destval);
9072         } else {
9073             u16 destval;
9074
9075             DECODE_PRINTF("WORD PTR ");
9076             destoffset = decode_rm00_address(rl);
9077             DECODE_PRINTF(",1\n");
9078             destval = fetch_data_word(destoffset);
9079             TRACE_AND_STEP();
9080             destval = (*opcD1_word_operation[rh]) (destval, 1);
9081             store_data_word(destoffset, destval);
9082         }
9083         break;
9084     case 1:
9085         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9086             u32 destval;
9087
9088             DECODE_PRINTF("DWORD PTR ");
9089             destoffset = decode_rm01_address(rl);
9090             DECODE_PRINTF(",1\n");
9091             destval = fetch_data_long(destoffset);
9092             TRACE_AND_STEP();
9093             destval = (*opcD1_long_operation[rh]) (destval, 1);
9094             store_data_long(destoffset, destval);
9095         } else {
9096             u16 destval;
9097
9098             DECODE_PRINTF("WORD PTR ");
9099             destoffset = decode_rm01_address(rl);
9100             DECODE_PRINTF(",1\n");
9101             destval = fetch_data_word(destoffset);
9102             TRACE_AND_STEP();
9103             destval = (*opcD1_word_operation[rh]) (destval, 1);
9104             store_data_word(destoffset, destval);
9105         }
9106         break;
9107     case 2:
9108         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9109             u32 destval;
9110
9111             DECODE_PRINTF("DWORD PTR ");
9112             destoffset = decode_rm10_address(rl);
9113             DECODE_PRINTF(",1\n");
9114             destval = fetch_data_long(destoffset);
9115             TRACE_AND_STEP();
9116             destval = (*opcD1_long_operation[rh]) (destval, 1);
9117             store_data_long(destoffset, destval);
9118         } else {
9119             u16 destval;
9120
9121             DECODE_PRINTF("BYTE PTR ");
9122             destoffset = decode_rm10_address(rl);
9123             DECODE_PRINTF(",1\n");
9124             destval = fetch_data_word(destoffset);
9125             TRACE_AND_STEP();
9126             destval = (*opcD1_word_operation[rh]) (destval, 1);
9127             store_data_word(destoffset, destval);
9128         }
9129         break;
9130     case 3:                     /* register to register */
9131         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9132                         u32 destval;
9133                         u32 *destreg;
9134
9135             destreg = DECODE_RM_LONG_REGISTER(rl);
9136             DECODE_PRINTF(",1\n");
9137             TRACE_AND_STEP();
9138             destval = (*opcD1_long_operation[rh]) (*destreg, 1);
9139             *destreg = destval;
9140         } else {
9141                         u16 destval;
9142                         u16 *destreg;
9143
9144             destreg = DECODE_RM_WORD_REGISTER(rl);
9145             DECODE_PRINTF(",1\n");
9146             TRACE_AND_STEP();
9147             destval = (*opcD1_word_operation[rh]) (*destreg, 1);
9148             *destreg = destval;
9149         }
9150         break;
9151     }
9152     DECODE_CLEAR_SEGOVR();
9153     END_OF_INSTR();
9154 }
9155
9156 /****************************************************************************
9157 REMARKS:
9158 Handles opcode 0xd2
9159 ****************************************************************************/
9160 void x86emuOp_opcD2_byte_RM_CL(u8 X86EMU_UNUSED(op1))
9161 {
9162     int mod, rl, rh;
9163     u8 *destreg;
9164     uint destoffset;
9165     u8 destval;
9166     u8 amt;
9167
9168     /*
9169      * Yet another weirdo special case instruction format.  Part of
9170      * the opcode held below in "RH".  Doubly nested case would
9171      * result, except that the decoded instruction
9172      */
9173     START_OF_INSTR();
9174     FETCH_DECODE_MODRM(mod, rh, rl);
9175 #ifdef DEBUG
9176     if (DEBUG_DECODE()) {
9177         /* XXX DECODE_PRINTF may be changed to something more
9178            general, so that it is important to leave the strings
9179            in the same format, even though the result is that the 
9180            above test is done twice. */
9181         switch (rh) {
9182         case 0:
9183             DECODE_PRINTF("ROL\t");
9184             break;
9185         case 1:
9186             DECODE_PRINTF("ROR\t");
9187             break;
9188         case 2:
9189             DECODE_PRINTF("RCL\t");
9190             break;
9191         case 3:
9192             DECODE_PRINTF("RCR\t");
9193             break;
9194         case 4:
9195             DECODE_PRINTF("SHL\t");
9196             break;
9197         case 5:
9198             DECODE_PRINTF("SHR\t");
9199             break;
9200         case 6:
9201             DECODE_PRINTF("SAL\t");
9202             break;
9203         case 7:
9204             DECODE_PRINTF("SAR\t");
9205             break;
9206         }
9207     }
9208 #endif
9209     /* know operation, decode the mod byte to find the addressing
9210        mode. */
9211     amt = M.x86.R_CL;
9212     switch (mod) {
9213     case 0:
9214         DECODE_PRINTF("BYTE PTR ");
9215         destoffset = decode_rm00_address(rl);
9216         DECODE_PRINTF(",CL\n");
9217         destval = fetch_data_byte(destoffset);
9218         TRACE_AND_STEP();
9219         destval = (*opcD0_byte_operation[rh]) (destval, amt);
9220         store_data_byte(destoffset, destval);
9221         break;
9222     case 1:
9223         DECODE_PRINTF("BYTE PTR ");
9224         destoffset = decode_rm01_address(rl);
9225         DECODE_PRINTF(",CL\n");
9226         destval = fetch_data_byte(destoffset);
9227         TRACE_AND_STEP();
9228         destval = (*opcD0_byte_operation[rh]) (destval, amt);
9229         store_data_byte(destoffset, destval);
9230         break;
9231     case 2:
9232         DECODE_PRINTF("BYTE PTR ");
9233         destoffset = decode_rm10_address(rl);
9234         DECODE_PRINTF(",CL\n");
9235         destval = fetch_data_byte(destoffset);
9236         TRACE_AND_STEP();
9237         destval = (*opcD0_byte_operation[rh]) (destval, amt);
9238         store_data_byte(destoffset, destval);
9239         break;
9240     case 3:                     /* register to register */
9241         destreg = DECODE_RM_BYTE_REGISTER(rl);
9242         DECODE_PRINTF(",CL\n");
9243         TRACE_AND_STEP();
9244         destval = (*opcD0_byte_operation[rh]) (*destreg, amt);
9245         *destreg = destval;
9246         break;
9247     }
9248     DECODE_CLEAR_SEGOVR();
9249     END_OF_INSTR();
9250 }
9251
9252 /****************************************************************************
9253 REMARKS:
9254 Handles opcode 0xd3
9255 ****************************************************************************/
9256 void x86emuOp_opcD3_word_RM_CL(u8 X86EMU_UNUSED(op1))
9257 {
9258     int mod, rl, rh;
9259     uint destoffset;
9260     u8 amt;
9261
9262     /*
9263      * Yet another weirdo special case instruction format.  Part of
9264      * the opcode held below in "RH".  Doubly nested case would
9265      * result, except that the decoded instruction
9266      */
9267     START_OF_INSTR();
9268     FETCH_DECODE_MODRM(mod, rh, rl);
9269 #ifdef DEBUG
9270     if (DEBUG_DECODE()) {
9271         /* XXX DECODE_PRINTF may be changed to something more
9272            general, so that it is important to leave the strings
9273            in the same format, even though the result is that the 
9274            above test is done twice. */
9275         switch (rh) {
9276         case 0:
9277             DECODE_PRINTF("ROL\t");
9278             break;
9279         case 1:
9280             DECODE_PRINTF("ROR\t");
9281             break;
9282         case 2:
9283             DECODE_PRINTF("RCL\t");
9284             break;
9285         case 3:
9286             DECODE_PRINTF("RCR\t");
9287             break;
9288         case 4:
9289             DECODE_PRINTF("SHL\t");
9290             break;
9291         case 5:
9292             DECODE_PRINTF("SHR\t");
9293             break;
9294         case 6:
9295             DECODE_PRINTF("SAL\t");
9296             break;
9297         case 7:
9298             DECODE_PRINTF("SAR\t");
9299             break;
9300         }
9301     }
9302 #endif
9303     /* know operation, decode the mod byte to find the addressing
9304        mode. */
9305     amt = M.x86.R_CL;
9306     switch (mod) {
9307     case 0:
9308         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9309             u32 destval;
9310
9311             DECODE_PRINTF("DWORD PTR ");
9312             destoffset = decode_rm00_address(rl);
9313             DECODE_PRINTF(",CL\n");
9314             destval = fetch_data_long(destoffset);
9315             TRACE_AND_STEP();
9316             destval = (*opcD1_long_operation[rh]) (destval, amt);
9317             store_data_long(destoffset, destval);
9318         } else {
9319             u16 destval;
9320
9321             DECODE_PRINTF("WORD PTR ");
9322             destoffset = decode_rm00_address(rl);
9323             DECODE_PRINTF(",CL\n");
9324             destval = fetch_data_word(destoffset);
9325             TRACE_AND_STEP();
9326             destval = (*opcD1_word_operation[rh]) (destval, amt);
9327             store_data_word(destoffset, destval);
9328         }
9329         break;
9330     case 1:
9331         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9332             u32 destval;
9333
9334             DECODE_PRINTF("DWORD PTR ");
9335             destoffset = decode_rm01_address(rl);
9336             DECODE_PRINTF(",CL\n");
9337             destval = fetch_data_long(destoffset);
9338             TRACE_AND_STEP();
9339             destval = (*opcD1_long_operation[rh]) (destval, amt);
9340             store_data_long(destoffset, destval);
9341         } else {
9342             u16 destval;
9343
9344             DECODE_PRINTF("WORD PTR ");
9345             destoffset = decode_rm01_address(rl);
9346             DECODE_PRINTF(",CL\n");
9347             destval = fetch_data_word(destoffset);
9348             TRACE_AND_STEP();
9349             destval = (*opcD1_word_operation[rh]) (destval, amt);
9350             store_data_word(destoffset, destval);
9351         }
9352         break;
9353     case 2:
9354         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9355             u32 destval;
9356
9357             DECODE_PRINTF("DWORD PTR ");
9358             destoffset = decode_rm10_address(rl);
9359             DECODE_PRINTF(",CL\n");
9360             destval = fetch_data_long(destoffset);
9361             TRACE_AND_STEP();
9362             destval = (*opcD1_long_operation[rh]) (destval, amt);
9363             store_data_long(destoffset, destval);
9364         } else {
9365             u16 destval;
9366
9367             DECODE_PRINTF("WORD PTR ");
9368             destoffset = decode_rm10_address(rl);
9369             DECODE_PRINTF(",CL\n");
9370             destval = fetch_data_word(destoffset);
9371             TRACE_AND_STEP();
9372             destval = (*opcD1_word_operation[rh]) (destval, amt);
9373             store_data_word(destoffset, destval);
9374         }
9375         break;
9376     case 3:                     /* register to register */
9377         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9378             u32 *destreg;
9379
9380             destreg = DECODE_RM_LONG_REGISTER(rl);
9381             DECODE_PRINTF(",CL\n");
9382             TRACE_AND_STEP();
9383             *destreg = (*opcD1_long_operation[rh]) (*destreg, amt);
9384         } else {
9385             u16 *destreg;
9386
9387             destreg = DECODE_RM_WORD_REGISTER(rl);
9388             DECODE_PRINTF(",CL\n");
9389             TRACE_AND_STEP();
9390             *destreg = (*opcD1_word_operation[rh]) (*destreg, amt);
9391         }
9392         break;
9393     }
9394     DECODE_CLEAR_SEGOVR();
9395     END_OF_INSTR();
9396 }
9397
9398 /****************************************************************************
9399 REMARKS:
9400 Handles opcode 0xd4
9401 ****************************************************************************/
9402 void x86emuOp_aam(u8 X86EMU_UNUSED(op1))
9403 {
9404     u8 a;
9405
9406     START_OF_INSTR();
9407     DECODE_PRINTF("AAM\n");
9408     a = fetch_byte_imm();      /* this is a stupid encoding. */
9409     if (a != 10) {
9410         DECODE_PRINTF("ERROR DECODING AAM\n");
9411         TRACE_REGS();
9412         HALT_SYS();
9413     }
9414     TRACE_AND_STEP();
9415     /* note the type change here --- returning AL and AH in AX. */
9416     M.x86.R_AX = aam_word(M.x86.R_AL);
9417     DECODE_CLEAR_SEGOVR();
9418     END_OF_INSTR();
9419 }
9420
9421 /****************************************************************************
9422 REMARKS:
9423 Handles opcode 0xd5
9424 ****************************************************************************/
9425 void x86emuOp_aad(u8 X86EMU_UNUSED(op1))
9426 {
9427     u8 a;
9428
9429     START_OF_INSTR();
9430     DECODE_PRINTF("AAD\n");
9431     a = fetch_byte_imm();
9432     TRACE_AND_STEP();
9433     M.x86.R_AX = aad_word(M.x86.R_AX);
9434     DECODE_CLEAR_SEGOVR();
9435     END_OF_INSTR();
9436 }
9437
9438 /* opcode 0xd6 ILLEGAL OPCODE */
9439
9440 /****************************************************************************
9441 REMARKS:
9442 Handles opcode 0xd7
9443 ****************************************************************************/
9444 void x86emuOp_xlat(u8 X86EMU_UNUSED(op1))
9445 {
9446     u16 addr;
9447
9448     START_OF_INSTR();
9449     DECODE_PRINTF("XLAT\n");
9450     TRACE_AND_STEP();
9451         addr = (u16)(M.x86.R_BX + (u8)M.x86.R_AL);
9452     M.x86.R_AL = fetch_data_byte(addr);
9453     DECODE_CLEAR_SEGOVR();
9454     END_OF_INSTR();
9455 }
9456
9457 /* instuctions  D8 .. DF are in i87_ops.c */
9458
9459 /****************************************************************************
9460 REMARKS:
9461 Handles opcode 0xe0
9462 ****************************************************************************/
9463 void x86emuOp_loopne(u8 X86EMU_UNUSED(op1))
9464 {
9465     s16 ip;
9466
9467     START_OF_INSTR();
9468     DECODE_PRINTF("LOOPNE\t");
9469     ip = (s8) fetch_byte_imm();
9470     ip += (s16) M.x86.R_IP;
9471     DECODE_PRINTF2("%04x\n", ip);
9472     TRACE_AND_STEP();
9473     M.x86.R_CX -= 1;
9474     if (M.x86.R_CX != 0 && !ACCESS_FLAG(F_ZF))      /* CX != 0 and !ZF */
9475         M.x86.R_IP = ip;
9476     DECODE_CLEAR_SEGOVR();
9477     END_OF_INSTR();
9478 }
9479
9480 /****************************************************************************
9481 REMARKS:
9482 Handles opcode 0xe1
9483 ****************************************************************************/
9484 void x86emuOp_loope(u8 X86EMU_UNUSED(op1))
9485 {
9486     s16 ip;
9487
9488     START_OF_INSTR();
9489     DECODE_PRINTF("LOOPE\t");
9490     ip = (s8) fetch_byte_imm();
9491     ip += (s16) M.x86.R_IP;
9492     DECODE_PRINTF2("%04x\n", ip);
9493     TRACE_AND_STEP();
9494     M.x86.R_CX -= 1;
9495     if (M.x86.R_CX != 0 && ACCESS_FLAG(F_ZF))       /* CX != 0 and ZF */
9496         M.x86.R_IP = ip;
9497     DECODE_CLEAR_SEGOVR();
9498     END_OF_INSTR();
9499 }
9500
9501 /****************************************************************************
9502 REMARKS:
9503 Handles opcode 0xe2
9504 ****************************************************************************/
9505 void x86emuOp_loop(u8 X86EMU_UNUSED(op1))
9506 {
9507     s16 ip;
9508
9509     START_OF_INSTR();
9510     DECODE_PRINTF("LOOP\t");
9511     ip = (s8) fetch_byte_imm();
9512     ip += (s16) M.x86.R_IP;
9513     DECODE_PRINTF2("%04x\n", ip);
9514     TRACE_AND_STEP();
9515     M.x86.R_CX -= 1;
9516     if (M.x86.R_CX != 0)
9517         M.x86.R_IP = ip;
9518     DECODE_CLEAR_SEGOVR();
9519     END_OF_INSTR();
9520 }
9521
9522 /****************************************************************************
9523 REMARKS:
9524 Handles opcode 0xe3
9525 ****************************************************************************/
9526 void x86emuOp_jcxz(u8 X86EMU_UNUSED(op1))
9527 {
9528     u16 target;
9529     s8  offset;
9530
9531     /* jump to byte offset if overflow flag is set */
9532     START_OF_INSTR();
9533     DECODE_PRINTF("JCXZ\t");
9534     offset = (s8)fetch_byte_imm();
9535     target = (u16)(M.x86.R_IP + offset);
9536     DECODE_PRINTF2("%x\n", target);
9537     TRACE_AND_STEP();
9538     if (M.x86.R_CX == 0)
9539         M.x86.R_IP = target;
9540     DECODE_CLEAR_SEGOVR();
9541     END_OF_INSTR();
9542 }
9543
9544 /****************************************************************************
9545 REMARKS:
9546 Handles opcode 0xe4
9547 ****************************************************************************/
9548 void x86emuOp_in_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
9549 {
9550     u8 port;
9551
9552     START_OF_INSTR();
9553     DECODE_PRINTF("IN\t");
9554         port = (u8) fetch_byte_imm();
9555     DECODE_PRINTF2("%x,AL\n", port);
9556     TRACE_AND_STEP();
9557     M.x86.R_AL = (*sys_inb)(port);
9558     DECODE_CLEAR_SEGOVR();
9559     END_OF_INSTR();
9560 }
9561
9562 /****************************************************************************
9563 REMARKS:
9564 Handles opcode 0xe5
9565 ****************************************************************************/
9566 void x86emuOp_in_word_AX_IMM(u8 X86EMU_UNUSED(op1))
9567 {
9568     u8 port;
9569
9570     START_OF_INSTR();
9571     DECODE_PRINTF("IN\t");
9572         port = (u8) fetch_byte_imm();
9573     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9574         DECODE_PRINTF2("EAX,%x\n", port);
9575     } else {
9576         DECODE_PRINTF2("AX,%x\n", port);
9577     }
9578     TRACE_AND_STEP();
9579     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9580         M.x86.R_EAX = (*sys_inl)(port);
9581     } else {
9582         M.x86.R_AX = (*sys_inw)(port);
9583     }
9584     DECODE_CLEAR_SEGOVR();
9585     END_OF_INSTR();
9586 }
9587
9588 /****************************************************************************
9589 REMARKS:
9590 Handles opcode 0xe6
9591 ****************************************************************************/
9592 void x86emuOp_out_byte_IMM_AL(u8 X86EMU_UNUSED(op1))
9593 {
9594     u8 port;
9595
9596     START_OF_INSTR();
9597     DECODE_PRINTF("OUT\t");
9598         port = (u8) fetch_byte_imm();
9599     DECODE_PRINTF2("%x,AL\n", port);
9600     TRACE_AND_STEP();
9601     (*sys_outb)(port, M.x86.R_AL);
9602     DECODE_CLEAR_SEGOVR();
9603     END_OF_INSTR();
9604 }
9605
9606 /****************************************************************************
9607 REMARKS:
9608 Handles opcode 0xe7
9609 ****************************************************************************/
9610 void x86emuOp_out_word_IMM_AX(u8 X86EMU_UNUSED(op1))
9611 {
9612     u8 port;
9613
9614     START_OF_INSTR();
9615     DECODE_PRINTF("OUT\t");
9616         port = (u8) fetch_byte_imm();
9617     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9618         DECODE_PRINTF2("%x,EAX\n", port);
9619     } else {
9620         DECODE_PRINTF2("%x,AX\n", port);
9621     }
9622     TRACE_AND_STEP();
9623     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9624         (*sys_outl)(port, M.x86.R_EAX);
9625     } else {
9626         (*sys_outw)(port, M.x86.R_AX);
9627     }
9628     DECODE_CLEAR_SEGOVR();
9629     END_OF_INSTR();
9630 }
9631
9632 /****************************************************************************
9633 REMARKS:
9634 Handles opcode 0xe8
9635 ****************************************************************************/
9636 void x86emuOp_call_near_IMM(u8 X86EMU_UNUSED(op1))
9637 {
9638     s16 ip;
9639
9640     START_OF_INSTR();
9641         DECODE_PRINTF("CALL\t");
9642         ip = (s16) fetch_word_imm();
9643         ip += (s16) M.x86.R_IP;    /* CHECK SIGN */
9644         DECODE_PRINTF2("%04x\n", ip);
9645         CALL_TRACE(M.x86.saved_cs, M.x86.saved_ip, M.x86.R_CS, ip, "");
9646     TRACE_AND_STEP();
9647     push_word(M.x86.R_IP);
9648     M.x86.R_IP = ip;
9649     DECODE_CLEAR_SEGOVR();
9650     END_OF_INSTR();
9651 }
9652
9653 /****************************************************************************
9654 REMARKS:
9655 Handles opcode 0xe9
9656 ****************************************************************************/
9657 void x86emuOp_jump_near_IMM(u8 X86EMU_UNUSED(op1))
9658 {
9659     int ip;
9660
9661     START_OF_INSTR();
9662     DECODE_PRINTF("JMP\t");
9663     ip = (s16)fetch_word_imm();
9664     ip += (s16)M.x86.R_IP;
9665     DECODE_PRINTF2("%04x\n", ip);
9666     TRACE_AND_STEP();
9667     M.x86.R_IP = (u16)ip;
9668     DECODE_CLEAR_SEGOVR();
9669     END_OF_INSTR();
9670 }
9671
9672 /****************************************************************************
9673 REMARKS:
9674 Handles opcode 0xea
9675 ****************************************************************************/
9676 void x86emuOp_jump_far_IMM(u8 X86EMU_UNUSED(op1))
9677 {
9678     u16 cs, ip;
9679
9680     START_OF_INSTR();
9681     DECODE_PRINTF("JMP\tFAR ");
9682     ip = fetch_word_imm();
9683     cs = fetch_word_imm();
9684     DECODE_PRINTF2("%04x:", cs);
9685     DECODE_PRINTF2("%04x\n", ip);
9686     TRACE_AND_STEP();
9687     M.x86.R_IP = ip;
9688     M.x86.R_CS = cs;
9689     DECODE_CLEAR_SEGOVR();
9690     END_OF_INSTR();
9691 }
9692
9693 /****************************************************************************
9694 REMARKS:
9695 Handles opcode 0xeb
9696 ****************************************************************************/
9697 void x86emuOp_jump_byte_IMM(u8 X86EMU_UNUSED(op1))
9698 {
9699     u16 target;
9700     s8 offset;
9701
9702     START_OF_INSTR();
9703     DECODE_PRINTF("JMP\t");
9704     offset = (s8)fetch_byte_imm();
9705     target = (u16)(M.x86.R_IP + offset);
9706     DECODE_PRINTF2("%x\n", target);
9707     TRACE_AND_STEP();
9708     M.x86.R_IP = target;
9709     DECODE_CLEAR_SEGOVR();
9710     END_OF_INSTR();
9711 }
9712
9713 /****************************************************************************
9714 REMARKS:
9715 Handles opcode 0xec
9716 ****************************************************************************/
9717 void x86emuOp_in_byte_AL_DX(u8 X86EMU_UNUSED(op1))
9718 {
9719     START_OF_INSTR();
9720     DECODE_PRINTF("IN\tAL,DX\n");
9721     TRACE_AND_STEP();
9722     M.x86.R_AL = (*sys_inb)(M.x86.R_DX);
9723     DECODE_CLEAR_SEGOVR();
9724     END_OF_INSTR();
9725 }
9726
9727 /****************************************************************************
9728 REMARKS:
9729 Handles opcode 0xed
9730 ****************************************************************************/
9731 void x86emuOp_in_word_AX_DX(u8 X86EMU_UNUSED(op1))
9732 {
9733     START_OF_INSTR();
9734     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9735         DECODE_PRINTF("IN\tEAX,DX\n");
9736     } else {
9737         DECODE_PRINTF("IN\tAX,DX\n");
9738     }
9739     TRACE_AND_STEP();
9740     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9741         M.x86.R_EAX = (*sys_inl)(M.x86.R_DX);
9742     } else {
9743         M.x86.R_AX = (*sys_inw)(M.x86.R_DX);
9744     }
9745     DECODE_CLEAR_SEGOVR();
9746     END_OF_INSTR();
9747 }
9748
9749 /****************************************************************************
9750 REMARKS:
9751 Handles opcode 0xee
9752 ****************************************************************************/
9753 void x86emuOp_out_byte_DX_AL(u8 X86EMU_UNUSED(op1))
9754 {
9755     START_OF_INSTR();
9756     DECODE_PRINTF("OUT\tDX,AL\n");
9757     TRACE_AND_STEP();
9758     (*sys_outb)(M.x86.R_DX, M.x86.R_AL);
9759     DECODE_CLEAR_SEGOVR();
9760     END_OF_INSTR();
9761 }
9762
9763 /****************************************************************************
9764 REMARKS:
9765 Handles opcode 0xef
9766 ****************************************************************************/
9767 void x86emuOp_out_word_DX_AX(u8 X86EMU_UNUSED(op1))
9768 {
9769     START_OF_INSTR();
9770     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9771         DECODE_PRINTF("OUT\tDX,EAX\n");
9772     } else {
9773         DECODE_PRINTF("OUT\tDX,AX\n");
9774     }
9775     TRACE_AND_STEP();
9776     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9777         (*sys_outl)(M.x86.R_DX, M.x86.R_EAX);
9778     } else {
9779         (*sys_outw)(M.x86.R_DX, M.x86.R_AX);
9780     }
9781     DECODE_CLEAR_SEGOVR();
9782     END_OF_INSTR();
9783 }
9784
9785 /****************************************************************************
9786 REMARKS:
9787 Handles opcode 0xf0
9788 ****************************************************************************/
9789 void x86emuOp_lock(u8 X86EMU_UNUSED(op1))
9790 {
9791     START_OF_INSTR();
9792     DECODE_PRINTF("LOCK:\n");
9793     TRACE_AND_STEP();
9794     DECODE_CLEAR_SEGOVR();
9795     END_OF_INSTR();
9796 }
9797
9798 /*opcode 0xf1 ILLEGAL OPERATION */
9799
9800 /****************************************************************************
9801 REMARKS:
9802 Handles opcode 0xf2
9803 ****************************************************************************/
9804 void x86emuOp_repne(u8 X86EMU_UNUSED(op1))
9805 {
9806     START_OF_INSTR();
9807     DECODE_PRINTF("REPNE\n");
9808     TRACE_AND_STEP();
9809     M.x86.mode |= SYSMODE_PREFIX_REPNE;
9810     DECODE_CLEAR_SEGOVR();
9811     END_OF_INSTR();
9812 }
9813
9814 /****************************************************************************
9815 REMARKS:
9816 Handles opcode 0xf3
9817 ****************************************************************************/
9818 void x86emuOp_repe(u8 X86EMU_UNUSED(op1))
9819 {
9820     START_OF_INSTR();
9821     DECODE_PRINTF("REPE\n");
9822     TRACE_AND_STEP();
9823     M.x86.mode |= SYSMODE_PREFIX_REPE;
9824     DECODE_CLEAR_SEGOVR();
9825     END_OF_INSTR();
9826 }
9827
9828 /****************************************************************************
9829 REMARKS:
9830 Handles opcode 0xf4
9831 ****************************************************************************/
9832 void x86emuOp_halt(u8 X86EMU_UNUSED(op1))
9833 {
9834     START_OF_INSTR();
9835     DECODE_PRINTF("HALT\n");
9836     TRACE_AND_STEP();
9837     HALT_SYS();
9838     DECODE_CLEAR_SEGOVR();
9839     END_OF_INSTR();
9840 }
9841
9842 /****************************************************************************
9843 REMARKS:
9844 Handles opcode 0xf5
9845 ****************************************************************************/
9846 void x86emuOp_cmc(u8 X86EMU_UNUSED(op1))
9847 {
9848     /* complement the carry flag. */
9849     START_OF_INSTR();
9850     DECODE_PRINTF("CMC\n");
9851     TRACE_AND_STEP();
9852     TOGGLE_FLAG(F_CF);
9853     DECODE_CLEAR_SEGOVR();
9854     END_OF_INSTR();
9855 }
9856
9857 /****************************************************************************
9858 REMARKS:
9859 Handles opcode 0xf6
9860 ****************************************************************************/
9861 void x86emuOp_opcF6_byte_RM(u8 X86EMU_UNUSED(op1))
9862 {
9863     int mod, rl, rh;
9864     u8 *destreg;
9865     uint destoffset;
9866     u8 destval, srcval;
9867
9868     /* long, drawn out code follows.  Double switch for a total
9869        of 32 cases.  */
9870     START_OF_INSTR();
9871     FETCH_DECODE_MODRM(mod, rh, rl);
9872     switch (mod) {
9873     case 0:                     /* mod=00 */
9874         switch (rh) {
9875         case 0:         /* test byte imm */
9876             DECODE_PRINTF("TEST\tBYTE PTR ");
9877             destoffset = decode_rm00_address(rl);
9878             DECODE_PRINTF(",");
9879             srcval = fetch_byte_imm();
9880             DECODE_PRINTF2("%02x\n", srcval);
9881             destval = fetch_data_byte(destoffset);
9882             TRACE_AND_STEP();
9883             test_byte(destval, srcval);
9884             break;
9885         case 1:
9886             DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n");
9887             HALT_SYS();
9888             break;
9889         case 2:
9890             DECODE_PRINTF("NOT\tBYTE PTR ");
9891             destoffset = decode_rm00_address(rl);
9892             DECODE_PRINTF("\n");
9893             destval = fetch_data_byte(destoffset);
9894             TRACE_AND_STEP();
9895             destval = not_byte(destval);
9896             store_data_byte(destoffset, destval);
9897             break;
9898         case 3:
9899             DECODE_PRINTF("NEG\tBYTE PTR ");
9900             destoffset = decode_rm00_address(rl);
9901             DECODE_PRINTF("\n");
9902             destval = fetch_data_byte(destoffset);
9903             TRACE_AND_STEP();
9904             destval = neg_byte(destval);
9905             store_data_byte(destoffset, destval);
9906             break;
9907         case 4:
9908             DECODE_PRINTF("MUL\tBYTE PTR ");
9909             destoffset = decode_rm00_address(rl);
9910             DECODE_PRINTF("\n");
9911             destval = fetch_data_byte(destoffset);
9912             TRACE_AND_STEP();
9913             mul_byte(destval);
9914             break;
9915         case 5:
9916             DECODE_PRINTF("IMUL\tBYTE PTR ");
9917             destoffset = decode_rm00_address(rl);
9918             DECODE_PRINTF("\n");
9919             destval = fetch_data_byte(destoffset);
9920             TRACE_AND_STEP();
9921             imul_byte(destval);
9922             break;
9923         case 6:
9924             DECODE_PRINTF("DIV\tBYTE PTR ");
9925             destoffset = decode_rm00_address(rl);
9926             DECODE_PRINTF("\n");
9927             destval = fetch_data_byte(destoffset);
9928             TRACE_AND_STEP();
9929             div_byte(destval);
9930             break;
9931         case 7:
9932             DECODE_PRINTF("IDIV\tBYTE PTR ");
9933             destoffset = decode_rm00_address(rl);
9934             DECODE_PRINTF("\n");
9935             destval = fetch_data_byte(destoffset);
9936             TRACE_AND_STEP();
9937             idiv_byte(destval);
9938             break;
9939         }
9940         break;                  /* end mod==00 */
9941     case 1:                     /* mod=01 */
9942         switch (rh) {
9943         case 0:         /* test byte imm */
9944             DECODE_PRINTF("TEST\tBYTE PTR ");
9945             destoffset = decode_rm01_address(rl);
9946             DECODE_PRINTF(",");
9947             srcval = fetch_byte_imm();
9948             DECODE_PRINTF2("%02x\n", srcval);
9949             destval = fetch_data_byte(destoffset);
9950             TRACE_AND_STEP();
9951             test_byte(destval, srcval);
9952             break;
9953         case 1:
9954             DECODE_PRINTF("ILLEGAL OP MOD=01 RH=01 OP=F6\n");
9955             HALT_SYS();
9956             break;
9957         case 2:
9958             DECODE_PRINTF("NOT\tBYTE PTR ");
9959             destoffset = decode_rm01_address(rl);
9960             DECODE_PRINTF("\n");
9961             destval = fetch_data_byte(destoffset);
9962             TRACE_AND_STEP();
9963             destval = not_byte(destval);
9964             store_data_byte(destoffset, destval);
9965             break;
9966         case 3:
9967             DECODE_PRINTF("NEG\tBYTE PTR ");
9968             destoffset = decode_rm01_address(rl);
9969             DECODE_PRINTF("\n");
9970             destval = fetch_data_byte(destoffset);
9971             TRACE_AND_STEP();
9972             destval = neg_byte(destval);
9973             store_data_byte(destoffset, destval);
9974             break;
9975         case 4:
9976             DECODE_PRINTF("MUL\tBYTE PTR ");
9977             destoffset = decode_rm01_address(rl);
9978             DECODE_PRINTF("\n");
9979             destval = fetch_data_byte(destoffset);
9980             TRACE_AND_STEP();
9981             mul_byte(destval);
9982             break;
9983         case 5:
9984             DECODE_PRINTF("IMUL\tBYTE PTR ");
9985             destoffset = decode_rm01_address(rl);
9986             DECODE_PRINTF("\n");
9987             destval = fetch_data_byte(destoffset);
9988             TRACE_AND_STEP();
9989             imul_byte(destval);
9990             break;
9991         case 6:
9992             DECODE_PRINTF("DIV\tBYTE PTR ");
9993             destoffset = decode_rm01_address(rl);
9994             DECODE_PRINTF("\n");
9995             destval = fetch_data_byte(destoffset);
9996             TRACE_AND_STEP();
9997             div_byte(destval);
9998             break;
9999         case 7:
10000             DECODE_PRINTF("IDIV\tBYTE PTR ");
10001             destoffset = decode_rm01_address(rl);
10002             DECODE_PRINTF("\n");
10003             destval = fetch_data_byte(destoffset);
10004             TRACE_AND_STEP();
10005             idiv_byte(destval);
10006             break;
10007         }
10008         break;                  /* end mod==01 */
10009     case 2:                     /* mod=10 */
10010         switch (rh) {
10011         case 0:         /* test byte imm */
10012             DECODE_PRINTF("TEST\tBYTE PTR ");
10013             destoffset = decode_rm10_address(rl);
10014             DECODE_PRINTF(",");
10015             srcval = fetch_byte_imm();
10016             DECODE_PRINTF2("%02x\n", srcval);
10017             destval = fetch_data_byte(destoffset);
10018             TRACE_AND_STEP();
10019             test_byte(destval, srcval);
10020             break;
10021         case 1:
10022             DECODE_PRINTF("ILLEGAL OP MOD=10 RH=01 OP=F6\n");
10023             HALT_SYS();
10024             break;
10025         case 2:
10026             DECODE_PRINTF("NOT\tBYTE PTR ");
10027             destoffset = decode_rm10_address(rl);
10028             DECODE_PRINTF("\n");
10029             destval = fetch_data_byte(destoffset);
10030             TRACE_AND_STEP();
10031             destval = not_byte(destval);
10032             store_data_byte(destoffset, destval);
10033             break;
10034         case 3:
10035             DECODE_PRINTF("NEG\tBYTE PTR ");
10036             destoffset = decode_rm10_address(rl);
10037             DECODE_PRINTF("\n");
10038             destval = fetch_data_byte(destoffset);
10039             TRACE_AND_STEP();
10040             destval = neg_byte(destval);
10041             store_data_byte(destoffset, destval);
10042             break;
10043         case 4:
10044             DECODE_PRINTF("MUL\tBYTE PTR ");
10045             destoffset = decode_rm10_address(rl);
10046             DECODE_PRINTF("\n");
10047             destval = fetch_data_byte(destoffset);
10048             TRACE_AND_STEP();
10049             mul_byte(destval);
10050             break;
10051         case 5:
10052             DECODE_PRINTF("IMUL\tBYTE PTR ");
10053             destoffset = decode_rm10_address(rl);
10054             DECODE_PRINTF("\n");
10055             destval = fetch_data_byte(destoffset);
10056             TRACE_AND_STEP();
10057             imul_byte(destval);
10058             break;
10059         case 6:
10060             DECODE_PRINTF("DIV\tBYTE PTR ");
10061             destoffset = decode_rm10_address(rl);
10062             DECODE_PRINTF("\n");
10063             destval = fetch_data_byte(destoffset);
10064             TRACE_AND_STEP();
10065             div_byte(destval);
10066             break;
10067         case 7:
10068             DECODE_PRINTF("IDIV\tBYTE PTR ");
10069             destoffset = decode_rm10_address(rl);
10070             DECODE_PRINTF("\n");
10071             destval = fetch_data_byte(destoffset);
10072             TRACE_AND_STEP();
10073             idiv_byte(destval);
10074             break;
10075         }
10076         break;                  /* end mod==10 */
10077     case 3:                     /* mod=11 */
10078         switch (rh) {
10079         case 0:         /* test byte imm */
10080             DECODE_PRINTF("TEST\t");
10081             destreg = DECODE_RM_BYTE_REGISTER(rl);
10082             DECODE_PRINTF(",");
10083             srcval = fetch_byte_imm();
10084             DECODE_PRINTF2("%02x\n", srcval);
10085             TRACE_AND_STEP();
10086             test_byte(*destreg, srcval);
10087             break;
10088         case 1:
10089             DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n");
10090             HALT_SYS();
10091             break;
10092         case 2:
10093             DECODE_PRINTF("NOT\t");
10094             destreg = DECODE_RM_BYTE_REGISTER(rl);
10095             DECODE_PRINTF("\n");
10096             TRACE_AND_STEP();
10097             *destreg = not_byte(*destreg);
10098             break;
10099         case 3:
10100             DECODE_PRINTF("NEG\t");
10101             destreg = DECODE_RM_BYTE_REGISTER(rl);
10102             DECODE_PRINTF("\n");
10103             TRACE_AND_STEP();
10104             *destreg = neg_byte(*destreg);
10105             break;
10106         case 4:
10107             DECODE_PRINTF("MUL\t");
10108             destreg = DECODE_RM_BYTE_REGISTER(rl);
10109             DECODE_PRINTF("\n");
10110             TRACE_AND_STEP();
10111             mul_byte(*destreg);      /*!!!  */
10112             break;
10113         case 5:
10114             DECODE_PRINTF("IMUL\t");
10115             destreg = DECODE_RM_BYTE_REGISTER(rl);
10116             DECODE_PRINTF("\n");
10117             TRACE_AND_STEP();
10118             imul_byte(*destreg);
10119             break;
10120         case 6:
10121             DECODE_PRINTF("DIV\t");
10122             destreg = DECODE_RM_BYTE_REGISTER(rl);
10123             DECODE_PRINTF("\n");
10124             TRACE_AND_STEP();
10125             div_byte(*destreg);
10126             break;
10127         case 7:
10128             DECODE_PRINTF("IDIV\t");
10129             destreg = DECODE_RM_BYTE_REGISTER(rl);
10130             DECODE_PRINTF("\n");
10131             TRACE_AND_STEP();
10132             idiv_byte(*destreg);
10133             break;
10134         }
10135         break;                  /* end mod==11 */
10136     }
10137     DECODE_CLEAR_SEGOVR();
10138     END_OF_INSTR();
10139 }
10140
10141 /****************************************************************************
10142 REMARKS:
10143 Handles opcode 0xf7
10144 ****************************************************************************/
10145 void x86emuOp_opcF7_word_RM(u8 X86EMU_UNUSED(op1))
10146 {
10147     int mod, rl, rh;
10148     uint destoffset;
10149
10150     /* long, drawn out code follows.  Double switch for a total
10151        of 32 cases.  */
10152     START_OF_INSTR();
10153     FETCH_DECODE_MODRM(mod, rh, rl);
10154     switch (mod) {
10155     case 0:                     /* mod=00 */
10156         switch (rh) {
10157         case 0:         /* test word imm */
10158             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10159                 u32 destval,srcval;
10160
10161                 DECODE_PRINTF("TEST\tDWORD PTR ");
10162                 destoffset = decode_rm00_address(rl);
10163                 DECODE_PRINTF(",");
10164                 srcval = fetch_long_imm();
10165                 DECODE_PRINTF2("%x\n", srcval);
10166                 destval = fetch_data_long(destoffset);
10167                 TRACE_AND_STEP();
10168                 test_long(destval, srcval);
10169             } else {
10170                 u16 destval,srcval;
10171
10172                 DECODE_PRINTF("TEST\tWORD PTR ");
10173                 destoffset = decode_rm00_address(rl);
10174                 DECODE_PRINTF(",");
10175                 srcval = fetch_word_imm();
10176                 DECODE_PRINTF2("%x\n", srcval);
10177                 destval = fetch_data_word(destoffset);
10178                 TRACE_AND_STEP();
10179                 test_word(destval, srcval);
10180             }
10181             break;
10182         case 1:
10183             DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F7\n");
10184             HALT_SYS();
10185             break;
10186         case 2:
10187             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10188                 u32 destval;
10189
10190                 DECODE_PRINTF("NOT\tDWORD PTR ");
10191                 destoffset = decode_rm00_address(rl);
10192                 DECODE_PRINTF("\n");
10193                 destval = fetch_data_long(destoffset);
10194                 TRACE_AND_STEP();
10195                 destval = not_long(destval);
10196                 store_data_long(destoffset, destval);
10197             } else {
10198                 u16 destval;
10199
10200                 DECODE_PRINTF("NOT\tWORD PTR ");
10201                 destoffset = decode_rm00_address(rl);
10202                 DECODE_PRINTF("\n");
10203                 destval = fetch_data_word(destoffset);
10204                 TRACE_AND_STEP();
10205                 destval = not_word(destval);
10206                 store_data_word(destoffset, destval);
10207             }
10208             break;
10209         case 3:
10210             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10211                 u32 destval;
10212
10213                 DECODE_PRINTF("NEG\tDWORD PTR ");
10214                 destoffset = decode_rm00_address(rl);
10215                 DECODE_PRINTF("\n");
10216                 destval = fetch_data_long(destoffset);
10217                 TRACE_AND_STEP();
10218                 destval = neg_long(destval);
10219                 store_data_long(destoffset, destval);
10220             } else {
10221                 u16 destval;
10222
10223                 DECODE_PRINTF("NEG\tWORD PTR ");
10224                 destoffset = decode_rm00_address(rl);
10225                 DECODE_PRINTF("\n");
10226                 destval = fetch_data_word(destoffset);
10227                 TRACE_AND_STEP();
10228                 destval = neg_word(destval);
10229                 store_data_word(destoffset, destval);
10230             }
10231             break;
10232         case 4:
10233             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10234                 u32 destval;
10235
10236                 DECODE_PRINTF("MUL\tDWORD PTR ");
10237                 destoffset = decode_rm00_address(rl);
10238                 DECODE_PRINTF("\n");
10239                 destval = fetch_data_long(destoffset);
10240                 TRACE_AND_STEP();
10241                 mul_long(destval);
10242             } else {
10243                 u16 destval;
10244
10245                 DECODE_PRINTF("MUL\tWORD PTR ");
10246                 destoffset = decode_rm00_address(rl);
10247                 DECODE_PRINTF("\n");
10248                 destval = fetch_data_word(destoffset);
10249                 TRACE_AND_STEP();
10250                 mul_word(destval);
10251             }
10252             break;
10253         case 5:
10254             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10255                 u32 destval;
10256
10257                 DECODE_PRINTF("IMUL\tDWORD PTR ");
10258                 destoffset = decode_rm00_address(rl);
10259                 DECODE_PRINTF("\n");
10260                 destval = fetch_data_long(destoffset);
10261                 TRACE_AND_STEP();
10262                 imul_long(destval);
10263             } else {
10264                 u16 destval;
10265
10266                 DECODE_PRINTF("IMUL\tWORD PTR ");
10267                 destoffset = decode_rm00_address(rl);
10268                 DECODE_PRINTF("\n");
10269                 destval = fetch_data_word(destoffset);
10270                 TRACE_AND_STEP();
10271                 imul_word(destval);
10272             }
10273             break;
10274         case 6:
10275             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10276                 u32 destval;
10277
10278                 DECODE_PRINTF("DIV\tDWORD PTR ");
10279                 destoffset = decode_rm00_address(rl);
10280                 DECODE_PRINTF("\n");
10281                 destval = fetch_data_long(destoffset);
10282                 TRACE_AND_STEP();
10283                 div_long(destval);
10284             } else {
10285                 u16 destval;
10286
10287                 DECODE_PRINTF("DIV\tWORD PTR ");
10288                 destoffset = decode_rm00_address(rl);
10289                 DECODE_PRINTF("\n");
10290                 destval = fetch_data_word(destoffset);
10291                 TRACE_AND_STEP();
10292                 div_word(destval);
10293             }
10294             break;
10295         case 7:
10296             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10297                 u32 destval;
10298
10299                 DECODE_PRINTF("IDIV\tDWORD PTR ");
10300                 destoffset = decode_rm00_address(rl);
10301                 DECODE_PRINTF("\n");
10302                 destval = fetch_data_long(destoffset);
10303                 TRACE_AND_STEP();
10304                 idiv_long(destval);
10305             } else {
10306                 u16 destval;
10307
10308                 DECODE_PRINTF("IDIV\tWORD PTR ");
10309                 destoffset = decode_rm00_address(rl);
10310                 DECODE_PRINTF("\n");
10311                 destval = fetch_data_word(destoffset);
10312                 TRACE_AND_STEP();
10313                 idiv_word(destval);
10314             }
10315             break;
10316         }
10317         break;                  /* end mod==00 */
10318     case 1:                     /* mod=01 */
10319         switch (rh) {
10320         case 0:         /* test word imm */
10321             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10322                 u32 destval,srcval;
10323
10324                 DECODE_PRINTF("TEST\tDWORD PTR ");
10325                 destoffset = decode_rm01_address(rl);
10326                 DECODE_PRINTF(",");
10327                 srcval = fetch_long_imm();
10328                 DECODE_PRINTF2("%x\n", srcval);
10329                 destval = fetch_data_long(destoffset);
10330                 TRACE_AND_STEP();
10331                 test_long(destval, srcval);
10332             } else {
10333                 u16 destval,srcval;
10334
10335                 DECODE_PRINTF("TEST\tWORD PTR ");
10336                 destoffset = decode_rm01_address(rl);
10337                 DECODE_PRINTF(",");
10338                 srcval = fetch_word_imm();
10339                 DECODE_PRINTF2("%x\n", srcval);
10340                 destval = fetch_data_word(destoffset);
10341                 TRACE_AND_STEP();
10342                 test_word(destval, srcval);
10343             }
10344             break;
10345         case 1:
10346             DECODE_PRINTF("ILLEGAL OP MOD=01 RH=01 OP=F6\n");
10347             HALT_SYS();
10348             break;
10349         case 2:
10350             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10351                 u32 destval;
10352
10353                 DECODE_PRINTF("NOT\tDWORD PTR ");
10354                 destoffset = decode_rm01_address(rl);
10355                 DECODE_PRINTF("\n");
10356                 destval = fetch_data_long(destoffset);
10357                 TRACE_AND_STEP();
10358                 destval = not_long(destval);
10359                 store_data_long(destoffset, destval);
10360             } else {
10361                 u16 destval;
10362
10363                 DECODE_PRINTF("NOT\tWORD PTR ");
10364                 destoffset = decode_rm01_address(rl);
10365                 DECODE_PRINTF("\n");
10366                 destval = fetch_data_word(destoffset);
10367                 TRACE_AND_STEP();
10368                 destval = not_word(destval);
10369                 store_data_word(destoffset, destval);
10370             }
10371             break;
10372         case 3:
10373             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10374                 u32 destval;
10375
10376                 DECODE_PRINTF("NEG\tDWORD PTR ");
10377                 destoffset = decode_rm01_address(rl);
10378                 DECODE_PRINTF("\n");
10379                 destval = fetch_data_long(destoffset);
10380                 TRACE_AND_STEP();
10381                 destval = neg_long(destval);
10382                 store_data_long(destoffset, destval);
10383             } else {
10384                 u16 destval;
10385
10386                 DECODE_PRINTF("NEG\tWORD PTR ");
10387                 destoffset = decode_rm01_address(rl);
10388                 DECODE_PRINTF("\n");
10389                 destval = fetch_data_word(destoffset);
10390                 TRACE_AND_STEP();
10391                 destval = neg_word(destval);
10392                 store_data_word(destoffset, destval);
10393             }
10394             break;
10395         case 4:
10396             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10397                 u32 destval;
10398
10399                 DECODE_PRINTF("MUL\tDWORD PTR ");
10400                 destoffset = decode_rm01_address(rl);
10401                 DECODE_PRINTF("\n");
10402                 destval = fetch_data_long(destoffset);
10403                 TRACE_AND_STEP();
10404                 mul_long(destval);
10405             } else {
10406                 u16 destval;
10407
10408                 DECODE_PRINTF("MUL\tWORD PTR ");
10409                 destoffset = decode_rm01_address(rl);
10410                 DECODE_PRINTF("\n");
10411                 destval = fetch_data_word(destoffset);
10412                 TRACE_AND_STEP();
10413                 mul_word(destval);
10414             }
10415             break;
10416         case 5:
10417             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10418                 u32 destval;
10419
10420                 DECODE_PRINTF("IMUL\tDWORD PTR ");
10421                 destoffset = decode_rm01_address(rl);
10422                 DECODE_PRINTF("\n");
10423                 destval = fetch_data_long(destoffset);
10424                 TRACE_AND_STEP();
10425                 imul_long(destval);
10426             } else {
10427                 u16 destval;
10428
10429                 DECODE_PRINTF("IMUL\tWORD PTR ");
10430                 destoffset = decode_rm01_address(rl);
10431                 DECODE_PRINTF("\n");
10432                 destval = fetch_data_word(destoffset);
10433                 TRACE_AND_STEP();
10434                 imul_word(destval);
10435             }
10436             break;
10437         case 6:
10438             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10439                 u32 destval;
10440
10441                 DECODE_PRINTF("DIV\tDWORD PTR ");
10442                 destoffset = decode_rm01_address(rl);
10443                 DECODE_PRINTF("\n");
10444                 destval = fetch_data_long(destoffset);
10445                 TRACE_AND_STEP();
10446                 div_long(destval);
10447             } else {
10448                 u16 destval;
10449
10450                 DECODE_PRINTF("DIV\tWORD PTR ");
10451                 destoffset = decode_rm01_address(rl);
10452                 DECODE_PRINTF("\n");
10453                 destval = fetch_data_word(destoffset);
10454                 TRACE_AND_STEP();
10455                 div_word(destval);
10456             }
10457             break;
10458         case 7:
10459             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10460                 u32 destval;
10461
10462                 DECODE_PRINTF("IDIV\tDWORD PTR ");
10463                 destoffset = decode_rm01_address(rl);
10464                 DECODE_PRINTF("\n");
10465                 destval = fetch_data_long(destoffset);
10466                 TRACE_AND_STEP();
10467                 idiv_long(destval);
10468             } else {
10469                 u16 destval;
10470
10471                 DECODE_PRINTF("IDIV\tWORD PTR ");
10472                 destoffset = decode_rm01_address(rl);
10473                 DECODE_PRINTF("\n");
10474                 destval = fetch_data_word(destoffset);
10475                 TRACE_AND_STEP();
10476                 idiv_word(destval);
10477             }
10478             break;
10479         }
10480         break;                  /* end mod==01 */
10481     case 2:                     /* mod=10 */
10482         switch (rh) {
10483         case 0:         /* test word imm */
10484             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10485                 u32 destval,srcval;
10486
10487                 DECODE_PRINTF("TEST\tDWORD PTR ");
10488                 destoffset = decode_rm10_address(rl);
10489                 DECODE_PRINTF(",");
10490                 srcval = fetch_long_imm();
10491                 DECODE_PRINTF2("%x\n", srcval);
10492                 destval = fetch_data_long(destoffset);
10493                 TRACE_AND_STEP();
10494                 test_long(destval, srcval);
10495             } else {
10496                 u16 destval,srcval;
10497
10498                 DECODE_PRINTF("TEST\tWORD PTR ");
10499                 destoffset = decode_rm10_address(rl);
10500                 DECODE_PRINTF(",");
10501                 srcval = fetch_word_imm();
10502                 DECODE_PRINTF2("%x\n", srcval);
10503                 destval = fetch_data_word(destoffset);
10504                 TRACE_AND_STEP();
10505                 test_word(destval, srcval);
10506             }
10507             break;
10508         case 1:
10509             DECODE_PRINTF("ILLEGAL OP MOD=10 RH=01 OP=F6\n");
10510             HALT_SYS();
10511             break;
10512         case 2:
10513             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10514                 u32 destval;
10515
10516                 DECODE_PRINTF("NOT\tDWORD PTR ");
10517                 destoffset = decode_rm10_address(rl);
10518                 DECODE_PRINTF("\n");
10519                 destval = fetch_data_long(destoffset);
10520                 TRACE_AND_STEP();
10521                 destval = not_long(destval);
10522                 store_data_long(destoffset, destval);
10523             } else {
10524                 u16 destval;
10525
10526                 DECODE_PRINTF("NOT\tWORD PTR ");
10527                 destoffset = decode_rm10_address(rl);
10528                 DECODE_PRINTF("\n");
10529                 destval = fetch_data_word(destoffset);
10530                 TRACE_AND_STEP();
10531                 destval = not_word(destval);
10532                 store_data_word(destoffset, destval);
10533             }
10534             break;
10535         case 3:
10536             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10537                 u32 destval;
10538
10539                 DECODE_PRINTF("NEG\tDWORD PTR ");
10540                 destoffset = decode_rm10_address(rl);
10541                 DECODE_PRINTF("\n");
10542                 destval = fetch_data_long(destoffset);
10543                 TRACE_AND_STEP();
10544                 destval = neg_long(destval);
10545                 store_data_long(destoffset, destval);
10546             } else {
10547                 u16 destval;
10548
10549                 DECODE_PRINTF("NEG\tWORD PTR ");
10550                 destoffset = decode_rm10_address(rl);
10551                 DECODE_PRINTF("\n");
10552                 destval = fetch_data_word(destoffset);
10553                 TRACE_AND_STEP();
10554                 destval = neg_word(destval);
10555                 store_data_word(destoffset, destval);
10556             }
10557             break;
10558         case 4:
10559             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10560                 u32 destval;
10561
10562                 DECODE_PRINTF("MUL\tDWORD PTR ");
10563                 destoffset = decode_rm10_address(rl);
10564                 DECODE_PRINTF("\n");
10565                 destval = fetch_data_long(destoffset);
10566                 TRACE_AND_STEP();
10567                 mul_long(destval);
10568             } else {
10569                 u16 destval;
10570
10571                 DECODE_PRINTF("MUL\tWORD PTR ");
10572                 destoffset = decode_rm10_address(rl);
10573                 DECODE_PRINTF("\n");
10574                 destval = fetch_data_word(destoffset);
10575                 TRACE_AND_STEP();
10576                 mul_word(destval);
10577             }
10578             break;
10579         case 5:
10580             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10581                 u32 destval;
10582
10583                 DECODE_PRINTF("IMUL\tDWORD PTR ");
10584                 destoffset = decode_rm10_address(rl);
10585                 DECODE_PRINTF("\n");
10586                 destval = fetch_data_long(destoffset);
10587                 TRACE_AND_STEP();
10588                 imul_long(destval);
10589             } else {
10590                 u16 destval;
10591
10592                 DECODE_PRINTF("IMUL\tWORD PTR ");
10593                 destoffset = decode_rm10_address(rl);
10594                 DECODE_PRINTF("\n");
10595                 destval = fetch_data_word(destoffset);
10596                 TRACE_AND_STEP();
10597                 imul_word(destval);
10598             }
10599             break;
10600         case 6:
10601             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10602                 u32 destval;
10603
10604                 DECODE_PRINTF("DIV\tDWORD PTR ");
10605                 destoffset = decode_rm10_address(rl);
10606                 DECODE_PRINTF("\n");
10607                 destval = fetch_data_long(destoffset);
10608                 TRACE_AND_STEP();
10609                 div_long(destval);
10610             } else {
10611                 u16 destval;
10612
10613                 DECODE_PRINTF("DIV\tWORD PTR ");
10614                 destoffset = decode_rm10_address(rl);
10615                 DECODE_PRINTF("\n");
10616                 destval = fetch_data_word(destoffset);
10617                 TRACE_AND_STEP();
10618                 div_word(destval);
10619             }
10620             break;
10621         case 7:
10622             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10623                 u32 destval;
10624
10625                 DECODE_PRINTF("IDIV\tDWORD PTR ");
10626                 destoffset = decode_rm10_address(rl);
10627                 DECODE_PRINTF("\n");
10628                 destval = fetch_data_long(destoffset);
10629                 TRACE_AND_STEP();
10630                 idiv_long(destval);
10631             } else {
10632                 u16 destval;
10633
10634                 DECODE_PRINTF("IDIV\tWORD PTR ");
10635                 destoffset = decode_rm10_address(rl);
10636                 DECODE_PRINTF("\n");
10637                 destval = fetch_data_word(destoffset);
10638                 TRACE_AND_STEP();
10639                 idiv_word(destval);
10640             }
10641             break;
10642         }
10643         break;                  /* end mod==10 */
10644     case 3:                     /* mod=11 */
10645         switch (rh) {
10646         case 0:         /* test word imm */
10647             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10648                 u32 *destreg;
10649                 u32 srcval;
10650
10651                 DECODE_PRINTF("TEST\t");
10652                 destreg = DECODE_RM_LONG_REGISTER(rl);
10653                 DECODE_PRINTF(",");
10654                 srcval = fetch_long_imm();
10655                 DECODE_PRINTF2("%x\n", srcval);
10656                 TRACE_AND_STEP();
10657                 test_long(*destreg, srcval);
10658             } else {
10659                 u16 *destreg;
10660                 u16 srcval;
10661
10662                 DECODE_PRINTF("TEST\t");
10663                 destreg = DECODE_RM_WORD_REGISTER(rl);
10664                 DECODE_PRINTF(",");
10665                 srcval = fetch_word_imm();
10666                 DECODE_PRINTF2("%x\n", srcval);
10667                 TRACE_AND_STEP();
10668                 test_word(*destreg, srcval);
10669             }
10670             break;
10671         case 1:
10672             DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n");
10673             HALT_SYS();
10674             break;
10675         case 2:
10676             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10677                 u32 *destreg;
10678
10679                 DECODE_PRINTF("NOT\t");
10680                 destreg = DECODE_RM_LONG_REGISTER(rl);
10681                 DECODE_PRINTF("\n");
10682                 TRACE_AND_STEP();
10683                 *destreg = not_long(*destreg);
10684             } else {
10685                 u16 *destreg;
10686
10687                 DECODE_PRINTF("NOT\t");
10688                 destreg = DECODE_RM_WORD_REGISTER(rl);
10689                 DECODE_PRINTF("\n");
10690                 TRACE_AND_STEP();
10691                 *destreg = not_word(*destreg);
10692             }
10693             break;
10694         case 3:
10695             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10696                 u32 *destreg;
10697
10698                 DECODE_PRINTF("NEG\t");
10699                 destreg = DECODE_RM_LONG_REGISTER(rl);
10700                 DECODE_PRINTF("\n");
10701                 TRACE_AND_STEP();
10702                 *destreg = neg_long(*destreg);
10703             } else {
10704                 u16 *destreg;
10705
10706                 DECODE_PRINTF("NEG\t");
10707                 destreg = DECODE_RM_WORD_REGISTER(rl);
10708                 DECODE_PRINTF("\n");
10709                 TRACE_AND_STEP();
10710                 *destreg = neg_word(*destreg);
10711             }
10712             break;
10713         case 4:
10714             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10715                 u32 *destreg;
10716
10717                 DECODE_PRINTF("MUL\t");
10718                 destreg = DECODE_RM_LONG_REGISTER(rl);
10719                 DECODE_PRINTF("\n");
10720                 TRACE_AND_STEP();
10721                 mul_long(*destreg);      /*!!!  */
10722             } else {
10723                 u16 *destreg;
10724
10725                 DECODE_PRINTF("MUL\t");
10726                 destreg = DECODE_RM_WORD_REGISTER(rl);
10727                 DECODE_PRINTF("\n");
10728                 TRACE_AND_STEP();
10729                 mul_word(*destreg);      /*!!!  */
10730             }
10731             break;
10732         case 5:
10733             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10734                 u32 *destreg;
10735
10736                 DECODE_PRINTF("IMUL\t");
10737                 destreg = DECODE_RM_LONG_REGISTER(rl);
10738                 DECODE_PRINTF("\n");
10739                 TRACE_AND_STEP();
10740                 imul_long(*destreg);
10741             } else {
10742                 u16 *destreg;
10743
10744                 DECODE_PRINTF("IMUL\t");
10745                 destreg = DECODE_RM_WORD_REGISTER(rl);
10746                 DECODE_PRINTF("\n");
10747                 TRACE_AND_STEP();
10748                 imul_word(*destreg);
10749             }
10750             break;
10751         case 6:
10752             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10753                 u32 *destreg;
10754
10755                 DECODE_PRINTF("DIV\t");
10756                 destreg = DECODE_RM_LONG_REGISTER(rl);
10757                 DECODE_PRINTF("\n");
10758                 TRACE_AND_STEP();
10759                 div_long(*destreg);
10760             } else {
10761                 u16 *destreg;
10762
10763                 DECODE_PRINTF("DIV\t");
10764                 destreg = DECODE_RM_WORD_REGISTER(rl);
10765                 DECODE_PRINTF("\n");
10766                 TRACE_AND_STEP();
10767                 div_word(*destreg);
10768             }
10769             break;
10770         case 7:
10771             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10772                 u32 *destreg;
10773
10774                 DECODE_PRINTF("IDIV\t");
10775                 destreg = DECODE_RM_LONG_REGISTER(rl);
10776                 DECODE_PRINTF("\n");
10777                 TRACE_AND_STEP();
10778                 idiv_long(*destreg);
10779             } else {
10780                 u16 *destreg;
10781
10782                 DECODE_PRINTF("IDIV\t");
10783                 destreg = DECODE_RM_WORD_REGISTER(rl);
10784                 DECODE_PRINTF("\n");
10785                 TRACE_AND_STEP();
10786                 idiv_word(*destreg);
10787             }
10788             break;
10789         }
10790         break;                  /* end mod==11 */
10791     }
10792     DECODE_CLEAR_SEGOVR();
10793     END_OF_INSTR();
10794 }
10795
10796 /****************************************************************************
10797 REMARKS:
10798 Handles opcode 0xf8
10799 ****************************************************************************/
10800 void x86emuOp_clc(u8 X86EMU_UNUSED(op1))
10801 {
10802     /* clear the carry flag. */
10803     START_OF_INSTR();
10804     DECODE_PRINTF("CLC\n");
10805     TRACE_AND_STEP();
10806     CLEAR_FLAG(F_CF);
10807     DECODE_CLEAR_SEGOVR();
10808     END_OF_INSTR();
10809 }
10810
10811 /****************************************************************************
10812 REMARKS:
10813 Handles opcode 0xf9
10814 ****************************************************************************/
10815 void x86emuOp_stc(u8 X86EMU_UNUSED(op1))
10816 {
10817     /* set the carry flag. */
10818     START_OF_INSTR();
10819     DECODE_PRINTF("STC\n");
10820     TRACE_AND_STEP();
10821     SET_FLAG(F_CF);
10822     DECODE_CLEAR_SEGOVR();
10823     END_OF_INSTR();
10824 }
10825
10826 /****************************************************************************
10827 REMARKS:
10828 Handles opcode 0xfa
10829 ****************************************************************************/
10830 void x86emuOp_cli(u8 X86EMU_UNUSED(op1))
10831 {
10832     /* clear interrupts. */
10833     START_OF_INSTR();
10834     DECODE_PRINTF("CLI\n");
10835     TRACE_AND_STEP();
10836     CLEAR_FLAG(F_IF);
10837     DECODE_CLEAR_SEGOVR();
10838     END_OF_INSTR();
10839 }
10840
10841 /****************************************************************************
10842 REMARKS:
10843 Handles opcode 0xfb
10844 ****************************************************************************/
10845 void x86emuOp_sti(u8 X86EMU_UNUSED(op1))
10846 {
10847     /* enable  interrupts. */
10848     START_OF_INSTR();
10849     DECODE_PRINTF("STI\n");
10850     TRACE_AND_STEP();
10851     SET_FLAG(F_IF);
10852     DECODE_CLEAR_SEGOVR();
10853     END_OF_INSTR();
10854 }
10855
10856 /****************************************************************************
10857 REMARKS:
10858 Handles opcode 0xfc
10859 ****************************************************************************/
10860 void x86emuOp_cld(u8 X86EMU_UNUSED(op1))
10861 {
10862     /* clear interrupts. */
10863     START_OF_INSTR();
10864     DECODE_PRINTF("CLD\n");
10865     TRACE_AND_STEP();
10866     CLEAR_FLAG(F_DF);
10867     DECODE_CLEAR_SEGOVR();
10868     END_OF_INSTR();
10869 }
10870
10871 /****************************************************************************
10872 REMARKS:
10873 Handles opcode 0xfd
10874 ****************************************************************************/
10875 void x86emuOp_std(u8 X86EMU_UNUSED(op1))
10876 {
10877     /* clear interrupts. */
10878     START_OF_INSTR();
10879     DECODE_PRINTF("STD\n");
10880     TRACE_AND_STEP();
10881     SET_FLAG(F_DF);
10882     DECODE_CLEAR_SEGOVR();
10883     END_OF_INSTR();
10884 }
10885
10886 /****************************************************************************
10887 REMARKS:
10888 Handles opcode 0xfe
10889 ****************************************************************************/
10890 void x86emuOp_opcFE_byte_RM(u8 X86EMU_UNUSED(op1))
10891 {
10892     int mod, rh, rl;
10893     u8 destval;
10894     uint destoffset;
10895     u8 *destreg;
10896
10897     /* Yet another special case instruction. */
10898     START_OF_INSTR();
10899     FETCH_DECODE_MODRM(mod, rh, rl);
10900 #ifdef DEBUG
10901     if (DEBUG_DECODE()) {
10902         /* XXX DECODE_PRINTF may be changed to something more
10903            general, so that it is important to leave the strings
10904            in the same format, even though the result is that the 
10905            above test is done twice. */
10906
10907         switch (rh) {
10908         case 0:
10909             DECODE_PRINTF("INC\t");
10910             break;
10911         case 1:
10912             DECODE_PRINTF("DEC\t");
10913             break;
10914         case 2:
10915         case 3:
10916         case 4:
10917         case 5:
10918         case 6:
10919         case 7:
10920             DECODE_PRINTF2("ILLEGAL OP MAJOR OP 0xFE MINOR OP %x \n", mod);
10921             HALT_SYS();
10922             break;
10923         }
10924     }
10925 #endif
10926     switch (mod) {
10927     case 0:
10928         DECODE_PRINTF("BYTE PTR ");
10929         destoffset = decode_rm00_address(rl);
10930         DECODE_PRINTF("\n");
10931         switch (rh) {
10932         case 0:         /* inc word ptr ... */
10933             destval = fetch_data_byte(destoffset);
10934             TRACE_AND_STEP();
10935             destval = inc_byte(destval);
10936             store_data_byte(destoffset, destval);
10937             break;
10938         case 1:         /* dec word ptr ... */
10939             destval = fetch_data_byte(destoffset);
10940             TRACE_AND_STEP();
10941             destval = dec_byte(destval);
10942             store_data_byte(destoffset, destval);
10943             break;
10944         }
10945         break;
10946     case 1:
10947         DECODE_PRINTF("BYTE PTR ");
10948         destoffset = decode_rm01_address(rl);
10949         DECODE_PRINTF("\n");
10950         switch (rh) {
10951         case 0:
10952             destval = fetch_data_byte(destoffset);
10953             TRACE_AND_STEP();
10954             destval = inc_byte(destval);
10955             store_data_byte(destoffset, destval);
10956             break;
10957         case 1:
10958             destval = fetch_data_byte(destoffset);
10959             TRACE_AND_STEP();
10960             destval = dec_byte(destval);
10961             store_data_byte(destoffset, destval);
10962             break;
10963         }
10964         break;
10965     case 2:
10966         DECODE_PRINTF("BYTE PTR ");
10967         destoffset = decode_rm10_address(rl);
10968         DECODE_PRINTF("\n");
10969         switch (rh) {
10970         case 0:
10971             destval = fetch_data_byte(destoffset);
10972             TRACE_AND_STEP();
10973             destval = inc_byte(destval);
10974             store_data_byte(destoffset, destval);
10975             break;
10976         case 1:
10977             destval = fetch_data_byte(destoffset);
10978             TRACE_AND_STEP();
10979             destval = dec_byte(destval);
10980             store_data_byte(destoffset, destval);
10981             break;
10982         }
10983         break;
10984     case 3:
10985         destreg = DECODE_RM_BYTE_REGISTER(rl);
10986         DECODE_PRINTF("\n");
10987         switch (rh) {
10988         case 0:
10989             TRACE_AND_STEP();
10990             *destreg = inc_byte(*destreg);
10991             break;
10992         case 1:
10993             TRACE_AND_STEP();
10994             *destreg = dec_byte(*destreg);
10995             break;
10996         }
10997         break;
10998     }
10999     DECODE_CLEAR_SEGOVR();
11000     END_OF_INSTR();
11001 }
11002
11003 /****************************************************************************
11004 REMARKS:
11005 Handles opcode 0xff
11006 ****************************************************************************/
11007 void x86emuOp_opcFF_word_RM(u8 X86EMU_UNUSED(op1))
11008 {
11009     int mod, rh, rl;
11010     uint destoffset = 0;
11011         u16 *destreg;
11012         u16 destval,destval2;
11013
11014     /* Yet another special case instruction. */
11015     START_OF_INSTR();
11016     FETCH_DECODE_MODRM(mod, rh, rl);
11017 #ifdef DEBUG
11018     if (DEBUG_DECODE()) {
11019         /* XXX DECODE_PRINTF may be changed to something more
11020            general, so that it is important to leave the strings
11021            in the same format, even though the result is that the
11022            above test is done twice. */
11023
11024         switch (rh) {
11025         case 0:
11026             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11027                 DECODE_PRINTF("INC\tDWORD PTR ");
11028             } else {
11029                 DECODE_PRINTF("INC\tWORD PTR ");
11030             }
11031             break;
11032         case 1:
11033             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11034                 DECODE_PRINTF("DEC\tDWORD PTR ");
11035             } else {
11036                 DECODE_PRINTF("DEC\tWORD PTR ");
11037             }
11038             break;
11039         case 2:
11040             DECODE_PRINTF("CALL\t ");
11041             break;
11042         case 3:
11043             DECODE_PRINTF("CALL\tFAR ");
11044             break;
11045         case 4:
11046             DECODE_PRINTF("JMP\t");
11047             break;
11048         case 5:
11049             DECODE_PRINTF("JMP\tFAR ");
11050             break;
11051         case 6:
11052             DECODE_PRINTF("PUSH\t");
11053             break;
11054         case 7:
11055             DECODE_PRINTF("ILLEGAL DECODING OF OPCODE FF\t");
11056             HALT_SYS();
11057             break;
11058         }
11059     }
11060 #endif
11061     switch (mod) {
11062     case 0:
11063         destoffset = decode_rm00_address(rl);
11064         DECODE_PRINTF("\n");
11065         switch (rh) {
11066         case 0:         /* inc word ptr ... */
11067             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11068                 u32 destval;
11069
11070                 destval = fetch_data_long(destoffset);
11071                 TRACE_AND_STEP();
11072                 destval = inc_long(destval);
11073                 store_data_long(destoffset, destval);
11074             } else {
11075                 u16 destval;
11076
11077                 destval = fetch_data_word(destoffset);
11078                 TRACE_AND_STEP();
11079                 destval = inc_word(destval);
11080                 store_data_word(destoffset, destval);
11081             }
11082             break;
11083         case 1:         /* dec word ptr ... */
11084             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11085                 u32 destval;
11086
11087                 destval = fetch_data_long(destoffset);
11088                 TRACE_AND_STEP();
11089                 destval = dec_long(destval);
11090                 store_data_long(destoffset, destval);
11091             } else {
11092                 u16 destval;
11093
11094                 destval = fetch_data_word(destoffset);
11095                 TRACE_AND_STEP();
11096                 destval = dec_word(destval);
11097                 store_data_word(destoffset, destval);
11098             }
11099             break;
11100         case 2:         /* call word ptr ... */
11101             destval = fetch_data_word(destoffset);
11102             TRACE_AND_STEP();
11103             push_word(M.x86.R_IP);
11104             M.x86.R_IP = destval;
11105             break;
11106         case 3:         /* call far ptr ... */
11107             destval = fetch_data_word(destoffset);
11108             destval2 = fetch_data_word(destoffset + 2);
11109             TRACE_AND_STEP();
11110             push_word(M.x86.R_CS);
11111             M.x86.R_CS = destval2;
11112             push_word(M.x86.R_IP);
11113             M.x86.R_IP = destval;
11114             break;
11115         case 4:         /* jmp word ptr ... */
11116             destval = fetch_data_word(destoffset);
11117             TRACE_AND_STEP();
11118             M.x86.R_IP = destval;
11119             break;
11120         case 5:         /* jmp far ptr ... */
11121             destval = fetch_data_word(destoffset);
11122             destval2 = fetch_data_word(destoffset + 2);
11123             TRACE_AND_STEP();
11124             M.x86.R_IP = destval;
11125             M.x86.R_CS = destval2;
11126             break;
11127         case 6:         /*  push word ptr ... */
11128             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11129                 u32 destval;
11130
11131                 destval = fetch_data_long(destoffset);
11132                 TRACE_AND_STEP();
11133                 push_long(destval);
11134             } else {
11135                 u16 destval;
11136
11137                 destval = fetch_data_word(destoffset);
11138                 TRACE_AND_STEP();
11139                 push_word(destval);
11140             }
11141             break;
11142         }
11143         break;
11144     case 1:
11145         destoffset = decode_rm01_address(rl);
11146         DECODE_PRINTF("\n");
11147         switch (rh) {
11148         case 0:
11149             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11150                 u32 destval;
11151
11152                 destval = fetch_data_long(destoffset);
11153                 TRACE_AND_STEP();
11154                 destval = inc_long(destval);
11155                 store_data_long(destoffset, destval);
11156             } else {
11157                 u16 destval;
11158
11159                 destval = fetch_data_word(destoffset);
11160                 TRACE_AND_STEP();
11161                 destval = inc_word(destval);
11162                 store_data_word(destoffset, destval);
11163             }
11164             break;
11165         case 1:
11166             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11167                 u32 destval;
11168
11169                 destval = fetch_data_long(destoffset);
11170                 TRACE_AND_STEP();
11171                 destval = dec_long(destval);
11172                 store_data_long(destoffset, destval);
11173             } else {
11174                 u16 destval;
11175
11176                 destval = fetch_data_word(destoffset);
11177                 TRACE_AND_STEP();
11178                 destval = dec_word(destval);
11179                 store_data_word(destoffset, destval);
11180             }
11181             break;
11182         case 2:         /* call word ptr ... */
11183             destval = fetch_data_word(destoffset);
11184             TRACE_AND_STEP();
11185             push_word(M.x86.R_IP);
11186             M.x86.R_IP = destval;
11187             break;
11188         case 3:         /* call far ptr ... */
11189             destval = fetch_data_word(destoffset);
11190             destval2 = fetch_data_word(destoffset + 2);
11191             TRACE_AND_STEP();
11192             push_word(M.x86.R_CS);
11193             M.x86.R_CS = destval2;
11194             push_word(M.x86.R_IP);
11195             M.x86.R_IP = destval;
11196             break;
11197         case 4:         /* jmp word ptr ... */
11198             destval = fetch_data_word(destoffset);
11199             TRACE_AND_STEP();
11200             M.x86.R_IP = destval;
11201             break;
11202         case 5:         /* jmp far ptr ... */
11203             destval = fetch_data_word(destoffset);
11204             destval2 = fetch_data_word(destoffset + 2);
11205             TRACE_AND_STEP();
11206             M.x86.R_IP = destval;
11207             M.x86.R_CS = destval2;
11208             break;
11209         case 6:         /*  push word ptr ... */
11210             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11211                 u32 destval;
11212
11213                 destval = fetch_data_long(destoffset);
11214                 TRACE_AND_STEP();
11215                 push_long(destval);
11216             } else {
11217                 u16 destval;
11218
11219                 destval = fetch_data_word(destoffset);
11220                 TRACE_AND_STEP();
11221                 push_word(destval);
11222             }
11223             break;
11224         }
11225         break;
11226     case 2:
11227         destoffset = decode_rm10_address(rl);
11228         DECODE_PRINTF("\n");
11229         switch (rh) {
11230         case 0:
11231             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11232                 u32 destval;
11233
11234                 destval = fetch_data_long(destoffset);
11235                 TRACE_AND_STEP();
11236                 destval = inc_long(destval);
11237                 store_data_long(destoffset, destval);
11238             } else {
11239                 u16 destval;
11240
11241                 destval = fetch_data_word(destoffset);
11242                 TRACE_AND_STEP();
11243                 destval = inc_word(destval);
11244                 store_data_word(destoffset, destval);
11245             }
11246             break;
11247         case 1:
11248             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11249                 u32 destval;
11250
11251                 destval = fetch_data_long(destoffset);
11252                 TRACE_AND_STEP();
11253                 destval = dec_long(destval);
11254                 store_data_long(destoffset, destval);
11255             } else {
11256                 u16 destval;
11257
11258                 destval = fetch_data_word(destoffset);
11259                 TRACE_AND_STEP();
11260                 destval = dec_word(destval);
11261                 store_data_word(destoffset, destval);
11262             }
11263             break;
11264         case 2:         /* call word ptr ... */
11265             destval = fetch_data_word(destoffset);
11266             TRACE_AND_STEP();
11267             push_word(M.x86.R_IP);
11268             M.x86.R_IP = destval;
11269             break;
11270         case 3:         /* call far ptr ... */
11271             destval = fetch_data_word(destoffset);
11272             destval2 = fetch_data_word(destoffset + 2);
11273             TRACE_AND_STEP();
11274             push_word(M.x86.R_CS);
11275             M.x86.R_CS = destval2;
11276             push_word(M.x86.R_IP);
11277             M.x86.R_IP = destval;
11278             break;
11279         case 4:         /* jmp word ptr ... */
11280             destval = fetch_data_word(destoffset);
11281             TRACE_AND_STEP();
11282             M.x86.R_IP = destval;
11283             break;
11284         case 5:         /* jmp far ptr ... */
11285             destval = fetch_data_word(destoffset);
11286             destval2 = fetch_data_word(destoffset + 2);
11287             TRACE_AND_STEP();
11288             M.x86.R_IP = destval;
11289             M.x86.R_CS = destval2;
11290             break;
11291         case 6:         /*  push word ptr ... */
11292             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11293                 u32 destval;
11294
11295                 destval = fetch_data_long(destoffset);
11296                 TRACE_AND_STEP();
11297                 push_long(destval);
11298             } else {
11299                 u16 destval;
11300
11301                 destval = fetch_data_word(destoffset);
11302                 TRACE_AND_STEP();
11303                 push_word(destval);
11304             }
11305             break;
11306         }
11307         break;
11308     case 3:
11309         switch (rh) {
11310         case 0:
11311             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11312                 u32 *destreg;
11313
11314                 destreg = DECODE_RM_LONG_REGISTER(rl);
11315                 DECODE_PRINTF("\n");
11316                 TRACE_AND_STEP();
11317                 *destreg = inc_long(*destreg);
11318             } else {
11319                 u16 *destreg;
11320
11321                 destreg = DECODE_RM_WORD_REGISTER(rl);
11322                 DECODE_PRINTF("\n");
11323                 TRACE_AND_STEP();
11324                 *destreg = inc_word(*destreg);
11325             }
11326             break;
11327         case 1:
11328             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11329                 u32 *destreg;
11330
11331                 destreg = DECODE_RM_LONG_REGISTER(rl);
11332                 DECODE_PRINTF("\n");
11333                 TRACE_AND_STEP();
11334                 *destreg = dec_long(*destreg);
11335             } else {
11336                 u16 *destreg;
11337
11338                 destreg = DECODE_RM_WORD_REGISTER(rl);
11339                 DECODE_PRINTF("\n");
11340                 TRACE_AND_STEP();
11341                 *destreg = dec_word(*destreg);
11342             }
11343             break;
11344         case 2:         /* call word ptr ... */
11345             destreg = DECODE_RM_WORD_REGISTER(rl);
11346             DECODE_PRINTF("\n");
11347             TRACE_AND_STEP();
11348             push_word(M.x86.R_IP);
11349             M.x86.R_IP = *destreg;
11350             break;
11351         case 3:         /* jmp far ptr ... */
11352             DECODE_PRINTF("OPERATION UNDEFINED 0XFF \n");
11353             TRACE_AND_STEP();
11354             HALT_SYS();
11355             break;
11356
11357         case 4:         /* jmp  ... */
11358             destreg = DECODE_RM_WORD_REGISTER(rl);
11359             DECODE_PRINTF("\n");
11360             TRACE_AND_STEP();
11361             M.x86.R_IP = (u16) (*destreg);
11362             break;
11363         case 5:         /* jmp far ptr ... */
11364             DECODE_PRINTF("OPERATION UNDEFINED 0XFF \n");
11365             TRACE_AND_STEP();
11366             HALT_SYS();
11367             break;
11368         case 6:
11369             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11370                 u32 *destreg;
11371
11372                 destreg = DECODE_RM_LONG_REGISTER(rl);
11373                 DECODE_PRINTF("\n");
11374                 TRACE_AND_STEP();
11375                 push_long(*destreg);
11376             } else {
11377                 u16 *destreg;
11378
11379                 destreg = DECODE_RM_WORD_REGISTER(rl);
11380                 DECODE_PRINTF("\n");
11381                 TRACE_AND_STEP();
11382                 push_word(*destreg);
11383             }
11384             break;
11385         }
11386         break;
11387     }
11388     DECODE_CLEAR_SEGOVR();
11389     END_OF_INSTR();
11390 }
11391
11392 /***************************************************************************
11393  * Single byte operation code table:
11394  **************************************************************************/
11395 void (*x86emu_optab[256])(u8) =
11396 {
11397 /*  0x00 */ x86emuOp_add_byte_RM_R,
11398 /*  0x01 */ x86emuOp_add_word_RM_R,
11399 /*  0x02 */ x86emuOp_add_byte_R_RM,
11400 /*  0x03 */ x86emuOp_add_word_R_RM,
11401 /*  0x04 */ x86emuOp_add_byte_AL_IMM,
11402 /*  0x05 */ x86emuOp_add_word_AX_IMM,
11403 /*  0x06 */ x86emuOp_push_ES,
11404 /*  0x07 */ x86emuOp_pop_ES,
11405
11406 /*  0x08 */ x86emuOp_or_byte_RM_R,
11407 /*  0x09 */ x86emuOp_or_word_RM_R,
11408 /*  0x0a */ x86emuOp_or_byte_R_RM,
11409 /*  0x0b */ x86emuOp_or_word_R_RM,
11410 /*  0x0c */ x86emuOp_or_byte_AL_IMM,
11411 /*  0x0d */ x86emuOp_or_word_AX_IMM,
11412 /*  0x0e */ x86emuOp_push_CS,
11413 /*  0x0f */ x86emuOp_two_byte,
11414
11415 /*  0x10 */ x86emuOp_adc_byte_RM_R,
11416 /*  0x11 */ x86emuOp_adc_word_RM_R,
11417 /*  0x12 */ x86emuOp_adc_byte_R_RM,
11418 /*  0x13 */ x86emuOp_adc_word_R_RM,
11419 /*  0x14 */ x86emuOp_adc_byte_AL_IMM,
11420 /*  0x15 */ x86emuOp_adc_word_AX_IMM,
11421 /*  0x16 */ x86emuOp_push_SS,
11422 /*  0x17 */ x86emuOp_pop_SS,
11423
11424 /*  0x18 */ x86emuOp_sbb_byte_RM_R,
11425 /*  0x19 */ x86emuOp_sbb_word_RM_R,
11426 /*  0x1a */ x86emuOp_sbb_byte_R_RM,
11427 /*  0x1b */ x86emuOp_sbb_word_R_RM,
11428 /*  0x1c */ x86emuOp_sbb_byte_AL_IMM,
11429 /*  0x1d */ x86emuOp_sbb_word_AX_IMM,
11430 /*  0x1e */ x86emuOp_push_DS,
11431 /*  0x1f */ x86emuOp_pop_DS,
11432
11433 /*  0x20 */ x86emuOp_and_byte_RM_R,
11434 /*  0x21 */ x86emuOp_and_word_RM_R,
11435 /*  0x22 */ x86emuOp_and_byte_R_RM,
11436 /*  0x23 */ x86emuOp_and_word_R_RM,
11437 /*  0x24 */ x86emuOp_and_byte_AL_IMM,
11438 /*  0x25 */ x86emuOp_and_word_AX_IMM,
11439 /*  0x26 */ x86emuOp_segovr_ES,
11440 /*  0x27 */ x86emuOp_daa,
11441
11442 /*  0x28 */ x86emuOp_sub_byte_RM_R,
11443 /*  0x29 */ x86emuOp_sub_word_RM_R,
11444 /*  0x2a */ x86emuOp_sub_byte_R_RM,
11445 /*  0x2b */ x86emuOp_sub_word_R_RM,
11446 /*  0x2c */ x86emuOp_sub_byte_AL_IMM,
11447 /*  0x2d */ x86emuOp_sub_word_AX_IMM,
11448 /*  0x2e */ x86emuOp_segovr_CS,
11449 /*  0x2f */ x86emuOp_das,
11450
11451 /*  0x30 */ x86emuOp_xor_byte_RM_R,
11452 /*  0x31 */ x86emuOp_xor_word_RM_R,
11453 /*  0x32 */ x86emuOp_xor_byte_R_RM,
11454 /*  0x33 */ x86emuOp_xor_word_R_RM,
11455 /*  0x34 */ x86emuOp_xor_byte_AL_IMM,
11456 /*  0x35 */ x86emuOp_xor_word_AX_IMM,
11457 /*  0x36 */ x86emuOp_segovr_SS,
11458 /*  0x37 */ x86emuOp_aaa,
11459
11460 /*  0x38 */ x86emuOp_cmp_byte_RM_R,
11461 /*  0x39 */ x86emuOp_cmp_word_RM_R,
11462 /*  0x3a */ x86emuOp_cmp_byte_R_RM,
11463 /*  0x3b */ x86emuOp_cmp_word_R_RM,
11464 /*  0x3c */ x86emuOp_cmp_byte_AL_IMM,
11465 /*  0x3d */ x86emuOp_cmp_word_AX_IMM,
11466 /*  0x3e */ x86emuOp_segovr_DS,
11467 /*  0x3f */ x86emuOp_aas,
11468
11469 /*  0x40 */ x86emuOp_inc_AX,
11470 /*  0x41 */ x86emuOp_inc_CX,
11471 /*  0x42 */ x86emuOp_inc_DX,
11472 /*  0x43 */ x86emuOp_inc_BX,
11473 /*  0x44 */ x86emuOp_inc_SP,
11474 /*  0x45 */ x86emuOp_inc_BP,
11475 /*  0x46 */ x86emuOp_inc_SI,
11476 /*  0x47 */ x86emuOp_inc_DI,
11477
11478 /*  0x48 */ x86emuOp_dec_AX,
11479 /*  0x49 */ x86emuOp_dec_CX,
11480 /*  0x4a */ x86emuOp_dec_DX,
11481 /*  0x4b */ x86emuOp_dec_BX,
11482 /*  0x4c */ x86emuOp_dec_SP,
11483 /*  0x4d */ x86emuOp_dec_BP,
11484 /*  0x4e */ x86emuOp_dec_SI,
11485 /*  0x4f */ x86emuOp_dec_DI,
11486
11487 /*  0x50 */ x86emuOp_push_AX,
11488 /*  0x51 */ x86emuOp_push_CX,
11489 /*  0x52 */ x86emuOp_push_DX,
11490 /*  0x53 */ x86emuOp_push_BX,
11491 /*  0x54 */ x86emuOp_push_SP,
11492 /*  0x55 */ x86emuOp_push_BP,
11493 /*  0x56 */ x86emuOp_push_SI,
11494 /*  0x57 */ x86emuOp_push_DI,
11495
11496 /*  0x58 */ x86emuOp_pop_AX,
11497 /*  0x59 */ x86emuOp_pop_CX,
11498 /*  0x5a */ x86emuOp_pop_DX,
11499 /*  0x5b */ x86emuOp_pop_BX,
11500 /*  0x5c */ x86emuOp_pop_SP,
11501 /*  0x5d */ x86emuOp_pop_BP,
11502 /*  0x5e */ x86emuOp_pop_SI,
11503 /*  0x5f */ x86emuOp_pop_DI,
11504
11505 /*  0x60 */ x86emuOp_push_all,
11506 /*  0x61 */ x86emuOp_pop_all,
11507 /*  0x62 */ x86emuOp_illegal_op,   /* bound */
11508 /*  0x63 */ x86emuOp_illegal_op,   /* arpl */
11509 /*  0x64 */ x86emuOp_segovr_FS,
11510 /*  0x65 */ x86emuOp_segovr_GS,
11511 /*  0x66 */ x86emuOp_prefix_data,
11512 /*  0x67 */ x86emuOp_prefix_addr,
11513
11514 /*  0x68 */ x86emuOp_push_word_IMM,
11515 /*  0x69 */ x86emuOp_imul_word_IMM,
11516 /*  0x6a */ x86emuOp_push_byte_IMM,
11517 /*  0x6b */ x86emuOp_imul_byte_IMM,
11518 /*  0x6c */ x86emuOp_ins_byte,
11519 /*  0x6d */ x86emuOp_ins_word,
11520 /*  0x6e */ x86emuOp_outs_byte,
11521 /*  0x6f */ x86emuOp_outs_word,
11522
11523 /*  0x70 */ x86emuOp_jump_near_O,
11524 /*  0x71 */ x86emuOp_jump_near_NO,
11525 /*  0x72 */ x86emuOp_jump_near_B,
11526 /*  0x73 */ x86emuOp_jump_near_NB,
11527 /*  0x74 */ x86emuOp_jump_near_Z,
11528 /*  0x75 */ x86emuOp_jump_near_NZ,
11529 /*  0x76 */ x86emuOp_jump_near_BE,
11530 /*  0x77 */ x86emuOp_jump_near_NBE,
11531
11532 /*  0x78 */ x86emuOp_jump_near_S,
11533 /*  0x79 */ x86emuOp_jump_near_NS,
11534 /*  0x7a */ x86emuOp_jump_near_P,
11535 /*  0x7b */ x86emuOp_jump_near_NP,
11536 /*  0x7c */ x86emuOp_jump_near_L,
11537 /*  0x7d */ x86emuOp_jump_near_NL,
11538 /*  0x7e */ x86emuOp_jump_near_LE,
11539 /*  0x7f */ x86emuOp_jump_near_NLE,
11540
11541 /*  0x80 */ x86emuOp_opc80_byte_RM_IMM,
11542 /*  0x81 */ x86emuOp_opc81_word_RM_IMM,
11543 /*  0x82 */ x86emuOp_opc82_byte_RM_IMM,
11544 /*  0x83 */ x86emuOp_opc83_word_RM_IMM,
11545 /*  0x84 */ x86emuOp_test_byte_RM_R,
11546 /*  0x85 */ x86emuOp_test_word_RM_R,
11547 /*  0x86 */ x86emuOp_xchg_byte_RM_R,
11548 /*  0x87 */ x86emuOp_xchg_word_RM_R,
11549
11550 /*  0x88 */ x86emuOp_mov_byte_RM_R,
11551 /*  0x89 */ x86emuOp_mov_word_RM_R,
11552 /*  0x8a */ x86emuOp_mov_byte_R_RM,
11553 /*  0x8b */ x86emuOp_mov_word_R_RM,
11554 /*  0x8c */ x86emuOp_mov_word_RM_SR,
11555 /*  0x8d */ x86emuOp_lea_word_R_M,
11556 /*  0x8e */ x86emuOp_mov_word_SR_RM,
11557 /*  0x8f */ x86emuOp_pop_RM,
11558
11559 /*  0x90 */ x86emuOp_nop,
11560 /*  0x91 */ x86emuOp_xchg_word_AX_CX,
11561 /*  0x92 */ x86emuOp_xchg_word_AX_DX,
11562 /*  0x93 */ x86emuOp_xchg_word_AX_BX,
11563 /*  0x94 */ x86emuOp_xchg_word_AX_SP,
11564 /*  0x95 */ x86emuOp_xchg_word_AX_BP,
11565 /*  0x96 */ x86emuOp_xchg_word_AX_SI,
11566 /*  0x97 */ x86emuOp_xchg_word_AX_DI,
11567
11568 /*  0x98 */ x86emuOp_cbw,
11569 /*  0x99 */ x86emuOp_cwd,
11570 /*  0x9a */ x86emuOp_call_far_IMM,
11571 /*  0x9b */ x86emuOp_wait,
11572 /*  0x9c */ x86emuOp_pushf_word,
11573 /*  0x9d */ x86emuOp_popf_word,
11574 /*  0x9e */ x86emuOp_sahf,
11575 /*  0x9f */ x86emuOp_lahf,
11576
11577 /*  0xa0 */ x86emuOp_mov_AL_M_IMM,
11578 /*  0xa1 */ x86emuOp_mov_AX_M_IMM,
11579 /*  0xa2 */ x86emuOp_mov_M_AL_IMM,
11580 /*  0xa3 */ x86emuOp_mov_M_AX_IMM,
11581 /*  0xa4 */ x86emuOp_movs_byte,
11582 /*  0xa5 */ x86emuOp_movs_word,
11583 /*  0xa6 */ x86emuOp_cmps_byte,
11584 /*  0xa7 */ x86emuOp_cmps_word,
11585 /*  0xa8 */ x86emuOp_test_AL_IMM,
11586 /*  0xa9 */ x86emuOp_test_AX_IMM,
11587 /*  0xaa */ x86emuOp_stos_byte,
11588 /*  0xab */ x86emuOp_stos_word,
11589 /*  0xac */ x86emuOp_lods_byte,
11590 /*  0xad */ x86emuOp_lods_word,
11591 /*  0xac */ x86emuOp_scas_byte,
11592 /*  0xad */ x86emuOp_scas_word,
11593
11594
11595 /*  0xb0 */ x86emuOp_mov_byte_AL_IMM,
11596 /*  0xb1 */ x86emuOp_mov_byte_CL_IMM,
11597 /*  0xb2 */ x86emuOp_mov_byte_DL_IMM,
11598 /*  0xb3 */ x86emuOp_mov_byte_BL_IMM,
11599 /*  0xb4 */ x86emuOp_mov_byte_AH_IMM,
11600 /*  0xb5 */ x86emuOp_mov_byte_CH_IMM,
11601 /*  0xb6 */ x86emuOp_mov_byte_DH_IMM,
11602 /*  0xb7 */ x86emuOp_mov_byte_BH_IMM,
11603
11604 /*  0xb8 */ x86emuOp_mov_word_AX_IMM,
11605 /*  0xb9 */ x86emuOp_mov_word_CX_IMM,
11606 /*  0xba */ x86emuOp_mov_word_DX_IMM,
11607 /*  0xbb */ x86emuOp_mov_word_BX_IMM,
11608 /*  0xbc */ x86emuOp_mov_word_SP_IMM,
11609 /*  0xbd */ x86emuOp_mov_word_BP_IMM,
11610 /*  0xbe */ x86emuOp_mov_word_SI_IMM,
11611 /*  0xbf */ x86emuOp_mov_word_DI_IMM,
11612
11613 /*  0xc0 */ x86emuOp_opcC0_byte_RM_MEM,
11614 /*  0xc1 */ x86emuOp_opcC1_word_RM_MEM,
11615 /*  0xc2 */ x86emuOp_ret_near_IMM,
11616 /*  0xc3 */ x86emuOp_ret_near,
11617 /*  0xc4 */ x86emuOp_les_R_IMM,
11618 /*  0xc5 */ x86emuOp_lds_R_IMM,
11619 /*  0xc6 */ x86emuOp_mov_byte_RM_IMM,
11620 /*  0xc7 */ x86emuOp_mov_word_RM_IMM,
11621 /*  0xc8 */ x86emuOp_enter,
11622 /*  0xc9 */ x86emuOp_leave,
11623 /*  0xca */ x86emuOp_ret_far_IMM,
11624 /*  0xcb */ x86emuOp_ret_far,
11625 /*  0xcc */ x86emuOp_int3,
11626 /*  0xcd */ x86emuOp_int_IMM,
11627 /*  0xce */ x86emuOp_into,
11628 /*  0xcf */ x86emuOp_iret,
11629
11630 /*  0xd0 */ x86emuOp_opcD0_byte_RM_1,
11631 /*  0xd1 */ x86emuOp_opcD1_word_RM_1,
11632 /*  0xd2 */ x86emuOp_opcD2_byte_RM_CL,
11633 /*  0xd3 */ x86emuOp_opcD3_word_RM_CL,
11634 /*  0xd4 */ x86emuOp_aam,
11635 /*  0xd5 */ x86emuOp_aad,
11636 /*  0xd6 */ x86emuOp_illegal_op,   /* Undocumented SETALC instruction */
11637 /*  0xd7 */ x86emuOp_xlat,
11638 /*  0xd8 */ x86emuOp_esc_coprocess_d8,
11639 /*  0xd9 */ x86emuOp_esc_coprocess_d9,
11640 /*  0xda */ x86emuOp_esc_coprocess_da,
11641 /*  0xdb */ x86emuOp_esc_coprocess_db,
11642 /*  0xdc */ x86emuOp_esc_coprocess_dc,
11643 /*  0xdd */ x86emuOp_esc_coprocess_dd,
11644 /*  0xde */ x86emuOp_esc_coprocess_de,
11645 /*  0xdf */ x86emuOp_esc_coprocess_df,
11646
11647 /*  0xe0 */ x86emuOp_loopne,
11648 /*  0xe1 */ x86emuOp_loope,
11649 /*  0xe2 */ x86emuOp_loop,
11650 /*  0xe3 */ x86emuOp_jcxz,
11651 /*  0xe4 */ x86emuOp_in_byte_AL_IMM,
11652 /*  0xe5 */ x86emuOp_in_word_AX_IMM,
11653 /*  0xe6 */ x86emuOp_out_byte_IMM_AL,
11654 /*  0xe7 */ x86emuOp_out_word_IMM_AX,
11655
11656 /*  0xe8 */ x86emuOp_call_near_IMM,
11657 /*  0xe9 */ x86emuOp_jump_near_IMM,
11658 /*  0xea */ x86emuOp_jump_far_IMM,
11659 /*  0xeb */ x86emuOp_jump_byte_IMM,
11660 /*  0xec */ x86emuOp_in_byte_AL_DX,
11661 /*  0xed */ x86emuOp_in_word_AX_DX,
11662 /*  0xee */ x86emuOp_out_byte_DX_AL,
11663 /*  0xef */ x86emuOp_out_word_DX_AX,
11664
11665 /*  0xf0 */ x86emuOp_lock,
11666 /*  0xf1 */ x86emuOp_illegal_op,
11667 /*  0xf2 */ x86emuOp_repne,
11668 /*  0xf3 */ x86emuOp_repe,
11669 /*  0xf4 */ x86emuOp_halt,
11670 /*  0xf5 */ x86emuOp_cmc,
11671 /*  0xf6 */ x86emuOp_opcF6_byte_RM,
11672 /*  0xf7 */ x86emuOp_opcF7_word_RM,
11673
11674 /*  0xf8 */ x86emuOp_clc,
11675 /*  0xf9 */ x86emuOp_stc,
11676 /*  0xfa */ x86emuOp_cli,
11677 /*  0xfb */ x86emuOp_sti,
11678 /*  0xfc */ x86emuOp_cld,
11679 /*  0xfd */ x86emuOp_std,
11680 /*  0xfe */ x86emuOp_opcFE_byte_RM,
11681 /*  0xff */ x86emuOp_opcFF_word_RM,
11682 };
11683
11684 void tables_relocate(unsigned int offset)
11685 {
11686     int i;
11687     for (i=0; i<8; i++)
11688     {
11689         opc80_byte_operation[i] -= offset;
11690         opc81_word_operation[i] -= offset;
11691         opc81_long_operation[i] -= offset;
11692
11693         opc82_byte_operation[i] -= offset;
11694         opc83_word_operation[i] -= offset;
11695         opc83_long_operation[i] -= offset;
11696
11697         opcD0_byte_operation[i] -= offset;
11698         opcD1_word_operation[i] -= offset;
11699         opcD1_long_operation[i] -= offset;
11700     }
11701 }