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 static void
x86emuOp_illegal_op(u8 op1)85 x86emuOp_illegal_op(u8 op1)
86 {
87     START_OF_INSTR();
88     if (M.x86.R_SP != 0) {
89         DECODE_PRINTF("ILLEGAL X86 OPCODE\n");
90         TRACE_REGS();
91         DB(printk("%04x:%04x: %02X ILLEGAL X86 OPCODE!\n",
92                   M.x86.R_CS, M.x86.R_IP - 1, op1));
93         HALT_SYS();
94     }
95     else {
96         /* If we get here, it means the stack pointer is back to zero
97          * so we are just returning from an emulator service call
98          * so therte is no need to display an error message. We trap
99          * the emulator with an 0xF1 opcode to finish the service
100          * call.
101          */
102         X86EMU_halt_sys();
103     }
104     END_OF_INSTR();
105 }
106 
107 /****************************************************************************
108 REMARKS:
109 Handles opcode 0x00
110 ****************************************************************************/
111 static void
x86emuOp_add_byte_RM_R(u8 X86EMU_UNUSED (op1))112 x86emuOp_add_byte_RM_R(u8 X86EMU_UNUSED(op1))
113 {
114     int mod, rl, rh;
115     uint destoffset;
116     u8 *destreg, *srcreg;
117     u8 destval;
118 
119     START_OF_INSTR();
120     DECODE_PRINTF("ADD\t");
121     FETCH_DECODE_MODRM(mod, rh, rl);
122     switch (mod) {
123     case 0:
124         destoffset = decode_rm00_address(rl);
125         DECODE_PRINTF(",");
126         destval = fetch_data_byte(destoffset);
127         srcreg = DECODE_RM_BYTE_REGISTER(rh);
128         DECODE_PRINTF("\n");
129         TRACE_AND_STEP();
130         destval = add_byte(destval, *srcreg);
131         store_data_byte(destoffset, destval);
132         break;
133     case 1:
134         destoffset = decode_rm01_address(rl);
135         DECODE_PRINTF(",");
136         destval = fetch_data_byte(destoffset);
137         srcreg = DECODE_RM_BYTE_REGISTER(rh);
138         DECODE_PRINTF("\n");
139         TRACE_AND_STEP();
140         destval = add_byte(destval, *srcreg);
141         store_data_byte(destoffset, destval);
142         break;
143     case 2:
144         destoffset = decode_rm10_address(rl);
145         DECODE_PRINTF(",");
146         destval = fetch_data_byte(destoffset);
147         srcreg = DECODE_RM_BYTE_REGISTER(rh);
148         DECODE_PRINTF("\n");
149         TRACE_AND_STEP();
150         destval = add_byte(destval, *srcreg);
151         store_data_byte(destoffset, destval);
152         break;
153     case 3:                    /* register to register */
154         destreg = DECODE_RM_BYTE_REGISTER(rl);
155         DECODE_PRINTF(",");
156         srcreg = DECODE_RM_BYTE_REGISTER(rh);
157         DECODE_PRINTF("\n");
158         TRACE_AND_STEP();
159         *destreg = add_byte(*destreg, *srcreg);
160         break;
161     }
162     DECODE_CLEAR_SEGOVR();
163     END_OF_INSTR();
164 }
165 
166 /****************************************************************************
167 REMARKS:
168 Handles opcode 0x01
169 ****************************************************************************/
170 static void
x86emuOp_add_word_RM_R(u8 X86EMU_UNUSED (op1))171 x86emuOp_add_word_RM_R(u8 X86EMU_UNUSED(op1))
172 {
173     int mod, rl, rh;
174     uint destoffset;
175 
176     START_OF_INSTR();
177     DECODE_PRINTF("ADD\t");
178     FETCH_DECODE_MODRM(mod, rh, rl);
179     switch (mod) {
180     case 0:
181         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
182             u32 destval;
183             u32 *srcreg;
184 
185             destoffset = decode_rm00_address(rl);
186             DECODE_PRINTF(",");
187             destval = fetch_data_long(destoffset);
188             srcreg = DECODE_RM_LONG_REGISTER(rh);
189             DECODE_PRINTF("\n");
190             TRACE_AND_STEP();
191             destval = add_long(destval, *srcreg);
192             store_data_long(destoffset, destval);
193         }
194         else {
195             u16 destval;
196             u16 *srcreg;
197 
198             destoffset = decode_rm00_address(rl);
199             DECODE_PRINTF(",");
200             destval = fetch_data_word(destoffset);
201             srcreg = DECODE_RM_WORD_REGISTER(rh);
202             DECODE_PRINTF("\n");
203             TRACE_AND_STEP();
204             destval = add_word(destval, *srcreg);
205             store_data_word(destoffset, destval);
206         }
207         break;
208     case 1:
209         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
210             u32 destval;
211             u32 *srcreg;
212 
213             destoffset = decode_rm01_address(rl);
214             DECODE_PRINTF(",");
215             destval = fetch_data_long(destoffset);
216             srcreg = DECODE_RM_LONG_REGISTER(rh);
217             DECODE_PRINTF("\n");
218             TRACE_AND_STEP();
219             destval = add_long(destval, *srcreg);
220             store_data_long(destoffset, destval);
221         }
222         else {
223             u16 destval;
224             u16 *srcreg;
225 
226             destoffset = decode_rm01_address(rl);
227             DECODE_PRINTF(",");
228             destval = fetch_data_word(destoffset);
229             srcreg = DECODE_RM_WORD_REGISTER(rh);
230             DECODE_PRINTF("\n");
231             TRACE_AND_STEP();
232             destval = add_word(destval, *srcreg);
233             store_data_word(destoffset, destval);
234         }
235         break;
236     case 2:
237         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
238             u32 destval;
239             u32 *srcreg;
240 
241             destoffset = decode_rm10_address(rl);
242             DECODE_PRINTF(",");
243             destval = fetch_data_long(destoffset);
244             srcreg = DECODE_RM_LONG_REGISTER(rh);
245             DECODE_PRINTF("\n");
246             TRACE_AND_STEP();
247             destval = add_long(destval, *srcreg);
248             store_data_long(destoffset, destval);
249         }
250         else {
251             u16 destval;
252             u16 *srcreg;
253 
254             destoffset = decode_rm10_address(rl);
255             DECODE_PRINTF(",");
256             destval = fetch_data_word(destoffset);
257             srcreg = DECODE_RM_WORD_REGISTER(rh);
258             DECODE_PRINTF("\n");
259             TRACE_AND_STEP();
260             destval = add_word(destval, *srcreg);
261             store_data_word(destoffset, destval);
262         }
263         break;
264     case 3:                    /* register to register */
265         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
266             u32 *destreg, *srcreg;
267 
268             destreg = DECODE_RM_LONG_REGISTER(rl);
269             DECODE_PRINTF(",");
270             srcreg = DECODE_RM_LONG_REGISTER(rh);
271             DECODE_PRINTF("\n");
272             TRACE_AND_STEP();
273             *destreg = add_long(*destreg, *srcreg);
274         }
275         else {
276             u16 *destreg, *srcreg;
277 
278             destreg = DECODE_RM_WORD_REGISTER(rl);
279             DECODE_PRINTF(",");
280             srcreg = DECODE_RM_WORD_REGISTER(rh);
281             DECODE_PRINTF("\n");
282             TRACE_AND_STEP();
283             *destreg = add_word(*destreg, *srcreg);
284         }
285         break;
286     }
287     DECODE_CLEAR_SEGOVR();
288     END_OF_INSTR();
289 }
290 
291 /****************************************************************************
292 REMARKS:
293 Handles opcode 0x02
294 ****************************************************************************/
295 static void
x86emuOp_add_byte_R_RM(u8 X86EMU_UNUSED (op1))296 x86emuOp_add_byte_R_RM(u8 X86EMU_UNUSED(op1))
297 {
298     int mod, rl, rh;
299     u8 *destreg, *srcreg;
300     uint srcoffset;
301     u8 srcval;
302 
303     START_OF_INSTR();
304     DECODE_PRINTF("ADD\t");
305     FETCH_DECODE_MODRM(mod, rh, rl);
306     switch (mod) {
307     case 0:
308         destreg = DECODE_RM_BYTE_REGISTER(rh);
309         DECODE_PRINTF(",");
310         srcoffset = decode_rm00_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 1:
317         destreg = DECODE_RM_BYTE_REGISTER(rh);
318         DECODE_PRINTF(",");
319         srcoffset = decode_rm01_address(rl);
320         srcval = fetch_data_byte(srcoffset);
321         DECODE_PRINTF("\n");
322         TRACE_AND_STEP();
323         *destreg = add_byte(*destreg, srcval);
324         break;
325     case 2:
326         destreg = DECODE_RM_BYTE_REGISTER(rh);
327         DECODE_PRINTF(",");
328         srcoffset = decode_rm10_address(rl);
329         srcval = fetch_data_byte(srcoffset);
330         DECODE_PRINTF("\n");
331         TRACE_AND_STEP();
332         *destreg = add_byte(*destreg, srcval);
333         break;
334     case 3:                    /* register to register */
335         destreg = DECODE_RM_BYTE_REGISTER(rh);
336         DECODE_PRINTF(",");
337         srcreg = DECODE_RM_BYTE_REGISTER(rl);
338         DECODE_PRINTF("\n");
339         TRACE_AND_STEP();
340         *destreg = add_byte(*destreg, *srcreg);
341         break;
342     }
343     DECODE_CLEAR_SEGOVR();
344     END_OF_INSTR();
345 }
346 
347 /****************************************************************************
348 REMARKS:
349 Handles opcode 0x03
350 ****************************************************************************/
351 static void
x86emuOp_add_word_R_RM(u8 X86EMU_UNUSED (op1))352 x86emuOp_add_word_R_RM(u8 X86EMU_UNUSED(op1))
353 {
354     int mod, rl, rh;
355     uint srcoffset;
356 
357     START_OF_INSTR();
358     DECODE_PRINTF("ADD\t");
359     FETCH_DECODE_MODRM(mod, rh, rl);
360     switch (mod) {
361     case 0:
362         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
363             u32 *destreg;
364             u32 srcval;
365 
366             destreg = DECODE_RM_LONG_REGISTER(rh);
367             DECODE_PRINTF(",");
368             srcoffset = decode_rm00_address(rl);
369             srcval = fetch_data_long(srcoffset);
370             DECODE_PRINTF("\n");
371             TRACE_AND_STEP();
372             *destreg = add_long(*destreg, srcval);
373         }
374         else {
375             u16 *destreg;
376             u16 srcval;
377 
378             destreg = DECODE_RM_WORD_REGISTER(rh);
379             DECODE_PRINTF(",");
380             srcoffset = decode_rm00_address(rl);
381             srcval = fetch_data_word(srcoffset);
382             DECODE_PRINTF("\n");
383             TRACE_AND_STEP();
384             *destreg = add_word(*destreg, srcval);
385         }
386         break;
387     case 1:
388         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
389             u32 *destreg;
390             u32 srcval;
391 
392             destreg = DECODE_RM_LONG_REGISTER(rh);
393             DECODE_PRINTF(",");
394             srcoffset = decode_rm01_address(rl);
395             srcval = fetch_data_long(srcoffset);
396             DECODE_PRINTF("\n");
397             TRACE_AND_STEP();
398             *destreg = add_long(*destreg, srcval);
399         }
400         else {
401             u16 *destreg;
402             u16 srcval;
403 
404             destreg = DECODE_RM_WORD_REGISTER(rh);
405             DECODE_PRINTF(",");
406             srcoffset = decode_rm01_address(rl);
407             srcval = fetch_data_word(srcoffset);
408             DECODE_PRINTF("\n");
409             TRACE_AND_STEP();
410             *destreg = add_word(*destreg, srcval);
411         }
412         break;
413     case 2:
414         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
415             u32 *destreg;
416             u32 srcval;
417 
418             destreg = DECODE_RM_LONG_REGISTER(rh);
419             DECODE_PRINTF(",");
420             srcoffset = decode_rm10_address(rl);
421             srcval = fetch_data_long(srcoffset);
422             DECODE_PRINTF("\n");
423             TRACE_AND_STEP();
424             *destreg = add_long(*destreg, srcval);
425         }
426         else {
427             u16 *destreg;
428             u16 srcval;
429 
430             destreg = DECODE_RM_WORD_REGISTER(rh);
431             DECODE_PRINTF(",");
432             srcoffset = decode_rm10_address(rl);
433             srcval = fetch_data_word(srcoffset);
434             DECODE_PRINTF("\n");
435             TRACE_AND_STEP();
436             *destreg = add_word(*destreg, srcval);
437         }
438         break;
439     case 3:                    /* register to register */
440         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
441             u32 *destreg, *srcreg;
442 
443             destreg = DECODE_RM_LONG_REGISTER(rh);
444             DECODE_PRINTF(",");
445             srcreg = DECODE_RM_LONG_REGISTER(rl);
446             DECODE_PRINTF("\n");
447             TRACE_AND_STEP();
448             *destreg = add_long(*destreg, *srcreg);
449         }
450         else {
451             u16 *destreg, *srcreg;
452 
453             destreg = DECODE_RM_WORD_REGISTER(rh);
454             DECODE_PRINTF(",");
455             srcreg = DECODE_RM_WORD_REGISTER(rl);
456             DECODE_PRINTF("\n");
457             TRACE_AND_STEP();
458             *destreg = add_word(*destreg, *srcreg);
459         }
460         break;
461     }
462     DECODE_CLEAR_SEGOVR();
463     END_OF_INSTR();
464 }
465 
466 /****************************************************************************
467 REMARKS:
468 Handles opcode 0x04
469 ****************************************************************************/
470 static void
x86emuOp_add_byte_AL_IMM(u8 X86EMU_UNUSED (op1))471 x86emuOp_add_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
472 {
473     u8 srcval;
474 
475     START_OF_INSTR();
476     DECODE_PRINTF("ADD\tAL,");
477     srcval = fetch_byte_imm();
478     DECODE_PRINTF2("%x\n", srcval);
479     TRACE_AND_STEP();
480     M.x86.R_AL = add_byte(M.x86.R_AL, srcval);
481     DECODE_CLEAR_SEGOVR();
482     END_OF_INSTR();
483 }
484 
485 /****************************************************************************
486 REMARKS:
487 Handles opcode 0x05
488 ****************************************************************************/
489 static void
x86emuOp_add_word_AX_IMM(u8 X86EMU_UNUSED (op1))490 x86emuOp_add_word_AX_IMM(u8 X86EMU_UNUSED(op1))
491 {
492     u32 srcval;
493 
494     START_OF_INSTR();
495     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
496         DECODE_PRINTF("ADD\tEAX,");
497         srcval = fetch_long_imm();
498     }
499     else {
500         DECODE_PRINTF("ADD\tAX,");
501         srcval = fetch_word_imm();
502     }
503     DECODE_PRINTF2("%x\n", srcval);
504     TRACE_AND_STEP();
505     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
506         M.x86.R_EAX = add_long(M.x86.R_EAX, srcval);
507     }
508     else {
509         M.x86.R_AX = add_word(M.x86.R_AX, (u16) srcval);
510     }
511     DECODE_CLEAR_SEGOVR();
512     END_OF_INSTR();
513 }
514 
515 /****************************************************************************
516 REMARKS:
517 Handles opcode 0x06
518 ****************************************************************************/
519 static void
x86emuOp_push_ES(u8 X86EMU_UNUSED (op1))520 x86emuOp_push_ES(u8 X86EMU_UNUSED(op1))
521 {
522     START_OF_INSTR();
523     DECODE_PRINTF("PUSH\tES\n");
524     TRACE_AND_STEP();
525     push_word(M.x86.R_ES);
526     DECODE_CLEAR_SEGOVR();
527     END_OF_INSTR();
528 }
529 
530 /****************************************************************************
531 REMARKS:
532 Handles opcode 0x07
533 ****************************************************************************/
534 static void
x86emuOp_pop_ES(u8 X86EMU_UNUSED (op1))535 x86emuOp_pop_ES(u8 X86EMU_UNUSED(op1))
536 {
537     START_OF_INSTR();
538     DECODE_PRINTF("POP\tES\n");
539     TRACE_AND_STEP();
540     M.x86.R_ES = pop_word();
541     DECODE_CLEAR_SEGOVR();
542     END_OF_INSTR();
543 }
544 
545 /****************************************************************************
546 REMARKS:
547 Handles opcode 0x08
548 ****************************************************************************/
549 static void
x86emuOp_or_byte_RM_R(u8 X86EMU_UNUSED (op1))550 x86emuOp_or_byte_RM_R(u8 X86EMU_UNUSED(op1))
551 {
552     int mod, rl, rh;
553     u8 *destreg, *srcreg;
554     uint destoffset;
555     u8 destval;
556 
557     START_OF_INSTR();
558     DECODE_PRINTF("OR\t");
559     FETCH_DECODE_MODRM(mod, rh, rl);
560     switch (mod) {
561     case 0:
562         destoffset = decode_rm00_address(rl);
563         DECODE_PRINTF(",");
564         destval = fetch_data_byte(destoffset);
565         srcreg = DECODE_RM_BYTE_REGISTER(rh);
566         DECODE_PRINTF("\n");
567         TRACE_AND_STEP();
568         destval = or_byte(destval, *srcreg);
569         store_data_byte(destoffset, destval);
570         break;
571     case 1:
572         destoffset = decode_rm01_address(rl);
573         DECODE_PRINTF(",");
574         destval = fetch_data_byte(destoffset);
575         srcreg = DECODE_RM_BYTE_REGISTER(rh);
576         DECODE_PRINTF("\n");
577         TRACE_AND_STEP();
578         destval = or_byte(destval, *srcreg);
579         store_data_byte(destoffset, destval);
580         break;
581     case 2:
582         destoffset = decode_rm10_address(rl);
583         DECODE_PRINTF(",");
584         destval = fetch_data_byte(destoffset);
585         srcreg = DECODE_RM_BYTE_REGISTER(rh);
586         DECODE_PRINTF("\n");
587         TRACE_AND_STEP();
588         destval = or_byte(destval, *srcreg);
589         store_data_byte(destoffset, destval);
590         break;
591     case 3:                    /* register to register */
592         destreg = DECODE_RM_BYTE_REGISTER(rl);
593         DECODE_PRINTF(",");
594         srcreg = DECODE_RM_BYTE_REGISTER(rh);
595         DECODE_PRINTF("\n");
596         TRACE_AND_STEP();
597         *destreg = or_byte(*destreg, *srcreg);
598         break;
599     }
600     DECODE_CLEAR_SEGOVR();
601     END_OF_INSTR();
602 }
603 
604 /****************************************************************************
605 REMARKS:
606 Handles opcode 0x09
607 ****************************************************************************/
608 static void
x86emuOp_or_word_RM_R(u8 X86EMU_UNUSED (op1))609 x86emuOp_or_word_RM_R(u8 X86EMU_UNUSED(op1))
610 {
611     int mod, rl, rh;
612     uint destoffset;
613 
614     START_OF_INSTR();
615     DECODE_PRINTF("OR\t");
616     FETCH_DECODE_MODRM(mod, rh, rl);
617     switch (mod) {
618     case 0:
619         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
620             u32 destval;
621             u32 *srcreg;
622 
623             destoffset = decode_rm00_address(rl);
624             DECODE_PRINTF(",");
625             destval = fetch_data_long(destoffset);
626             srcreg = DECODE_RM_LONG_REGISTER(rh);
627             DECODE_PRINTF("\n");
628             TRACE_AND_STEP();
629             destval = or_long(destval, *srcreg);
630             store_data_long(destoffset, destval);
631         }
632         else {
633             u16 destval;
634             u16 *srcreg;
635 
636             destoffset = decode_rm00_address(rl);
637             DECODE_PRINTF(",");
638             destval = fetch_data_word(destoffset);
639             srcreg = DECODE_RM_WORD_REGISTER(rh);
640             DECODE_PRINTF("\n");
641             TRACE_AND_STEP();
642             destval = or_word(destval, *srcreg);
643             store_data_word(destoffset, destval);
644         }
645         break;
646     case 1:
647         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
648             u32 destval;
649             u32 *srcreg;
650 
651             destoffset = decode_rm01_address(rl);
652             DECODE_PRINTF(",");
653             destval = fetch_data_long(destoffset);
654             srcreg = DECODE_RM_LONG_REGISTER(rh);
655             DECODE_PRINTF("\n");
656             TRACE_AND_STEP();
657             destval = or_long(destval, *srcreg);
658             store_data_long(destoffset, destval);
659         }
660         else {
661             u16 destval;
662             u16 *srcreg;
663 
664             destoffset = decode_rm01_address(rl);
665             DECODE_PRINTF(",");
666             destval = fetch_data_word(destoffset);
667             srcreg = DECODE_RM_WORD_REGISTER(rh);
668             DECODE_PRINTF("\n");
669             TRACE_AND_STEP();
670             destval = or_word(destval, *srcreg);
671             store_data_word(destoffset, destval);
672         }
673         break;
674     case 2:
675         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
676             u32 destval;
677             u32 *srcreg;
678 
679             destoffset = decode_rm10_address(rl);
680             DECODE_PRINTF(",");
681             destval = fetch_data_long(destoffset);
682             srcreg = DECODE_RM_LONG_REGISTER(rh);
683             DECODE_PRINTF("\n");
684             TRACE_AND_STEP();
685             destval = or_long(destval, *srcreg);
686             store_data_long(destoffset, destval);
687         }
688         else {
689             u16 destval;
690             u16 *srcreg;
691 
692             destoffset = decode_rm10_address(rl);
693             DECODE_PRINTF(",");
694             destval = fetch_data_word(destoffset);
695             srcreg = DECODE_RM_WORD_REGISTER(rh);
696             DECODE_PRINTF("\n");
697             TRACE_AND_STEP();
698             destval = or_word(destval, *srcreg);
699             store_data_word(destoffset, destval);
700         }
701         break;
702     case 3:                    /* register to register */
703         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
704             u32 *destreg, *srcreg;
705 
706             destreg = DECODE_RM_LONG_REGISTER(rl);
707             DECODE_PRINTF(",");
708             srcreg = DECODE_RM_LONG_REGISTER(rh);
709             DECODE_PRINTF("\n");
710             TRACE_AND_STEP();
711             *destreg = or_long(*destreg, *srcreg);
712         }
713         else {
714             u16 *destreg, *srcreg;
715 
716             destreg = DECODE_RM_WORD_REGISTER(rl);
717             DECODE_PRINTF(",");
718             srcreg = DECODE_RM_WORD_REGISTER(rh);
719             DECODE_PRINTF("\n");
720             TRACE_AND_STEP();
721             *destreg = or_word(*destreg, *srcreg);
722         }
723         break;
724     }
725     DECODE_CLEAR_SEGOVR();
726     END_OF_INSTR();
727 }
728 
729 /****************************************************************************
730 REMARKS:
731 Handles opcode 0x0a
732 ****************************************************************************/
733 static void
x86emuOp_or_byte_R_RM(u8 X86EMU_UNUSED (op1))734 x86emuOp_or_byte_R_RM(u8 X86EMU_UNUSED(op1))
735 {
736     int mod, rl, rh;
737     u8 *destreg, *srcreg;
738     uint srcoffset;
739     u8 srcval;
740 
741     START_OF_INSTR();
742     DECODE_PRINTF("OR\t");
743     FETCH_DECODE_MODRM(mod, rh, rl);
744     switch (mod) {
745     case 0:
746         destreg = DECODE_RM_BYTE_REGISTER(rh);
747         DECODE_PRINTF(",");
748         srcoffset = decode_rm00_address(rl);
749         srcval = fetch_data_byte(srcoffset);
750         DECODE_PRINTF("\n");
751         TRACE_AND_STEP();
752         *destreg = or_byte(*destreg, srcval);
753         break;
754     case 1:
755         destreg = DECODE_RM_BYTE_REGISTER(rh);
756         DECODE_PRINTF(",");
757         srcoffset = decode_rm01_address(rl);
758         srcval = fetch_data_byte(srcoffset);
759         DECODE_PRINTF("\n");
760         TRACE_AND_STEP();
761         *destreg = or_byte(*destreg, srcval);
762         break;
763     case 2:
764         destreg = DECODE_RM_BYTE_REGISTER(rh);
765         DECODE_PRINTF(",");
766         srcoffset = decode_rm10_address(rl);
767         srcval = fetch_data_byte(srcoffset);
768         DECODE_PRINTF("\n");
769         TRACE_AND_STEP();
770         *destreg = or_byte(*destreg, srcval);
771         break;
772     case 3:                    /* register to register */
773         destreg = DECODE_RM_BYTE_REGISTER(rh);
774         DECODE_PRINTF(",");
775         srcreg = DECODE_RM_BYTE_REGISTER(rl);
776         DECODE_PRINTF("\n");
777         TRACE_AND_STEP();
778         *destreg = or_byte(*destreg, *srcreg);
779         break;
780     }
781     DECODE_CLEAR_SEGOVR();
782     END_OF_INSTR();
783 }
784 
785 /****************************************************************************
786 REMARKS:
787 Handles opcode 0x0b
788 ****************************************************************************/
789 static void
x86emuOp_or_word_R_RM(u8 X86EMU_UNUSED (op1))790 x86emuOp_or_word_R_RM(u8 X86EMU_UNUSED(op1))
791 {
792     int mod, rl, rh;
793     uint srcoffset;
794 
795     START_OF_INSTR();
796     DECODE_PRINTF("OR\t");
797     FETCH_DECODE_MODRM(mod, rh, rl);
798     switch (mod) {
799     case 0:
800         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
801             u32 *destreg;
802             u32 srcval;
803 
804             destreg = DECODE_RM_LONG_REGISTER(rh);
805             DECODE_PRINTF(",");
806             srcoffset = decode_rm00_address(rl);
807             srcval = fetch_data_long(srcoffset);
808             DECODE_PRINTF("\n");
809             TRACE_AND_STEP();
810             *destreg = or_long(*destreg, srcval);
811         }
812         else {
813             u16 *destreg;
814             u16 srcval;
815 
816             destreg = DECODE_RM_WORD_REGISTER(rh);
817             DECODE_PRINTF(",");
818             srcoffset = decode_rm00_address(rl);
819             srcval = fetch_data_word(srcoffset);
820             DECODE_PRINTF("\n");
821             TRACE_AND_STEP();
822             *destreg = or_word(*destreg, srcval);
823         }
824         break;
825     case 1:
826         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
827             u32 *destreg;
828             u32 srcval;
829 
830             destreg = DECODE_RM_LONG_REGISTER(rh);
831             DECODE_PRINTF(",");
832             srcoffset = decode_rm01_address(rl);
833             srcval = fetch_data_long(srcoffset);
834             DECODE_PRINTF("\n");
835             TRACE_AND_STEP();
836             *destreg = or_long(*destreg, srcval);
837         }
838         else {
839             u16 *destreg;
840             u16 srcval;
841 
842             destreg = DECODE_RM_WORD_REGISTER(rh);
843             DECODE_PRINTF(",");
844             srcoffset = decode_rm01_address(rl);
845             srcval = fetch_data_word(srcoffset);
846             DECODE_PRINTF("\n");
847             TRACE_AND_STEP();
848             *destreg = or_word(*destreg, srcval);
849         }
850         break;
851     case 2:
852         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
853             u32 *destreg;
854             u32 srcval;
855 
856             destreg = DECODE_RM_LONG_REGISTER(rh);
857             DECODE_PRINTF(",");
858             srcoffset = decode_rm10_address(rl);
859             srcval = fetch_data_long(srcoffset);
860             DECODE_PRINTF("\n");
861             TRACE_AND_STEP();
862             *destreg = or_long(*destreg, srcval);
863         }
864         else {
865             u16 *destreg;
866             u16 srcval;
867 
868             destreg = DECODE_RM_WORD_REGISTER(rh);
869             DECODE_PRINTF(",");
870             srcoffset = decode_rm10_address(rl);
871             srcval = fetch_data_word(srcoffset);
872             DECODE_PRINTF("\n");
873             TRACE_AND_STEP();
874             *destreg = or_word(*destreg, srcval);
875         }
876         break;
877     case 3:                    /* register to register */
878         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
879             u32 *destreg, *srcreg;
880 
881             destreg = DECODE_RM_LONG_REGISTER(rh);
882             DECODE_PRINTF(",");
883             srcreg = DECODE_RM_LONG_REGISTER(rl);
884             DECODE_PRINTF("\n");
885             TRACE_AND_STEP();
886             *destreg = or_long(*destreg, *srcreg);
887         }
888         else {
889             u16 *destreg, *srcreg;
890 
891             destreg = DECODE_RM_WORD_REGISTER(rh);
892             DECODE_PRINTF(",");
893             srcreg = DECODE_RM_WORD_REGISTER(rl);
894             DECODE_PRINTF("\n");
895             TRACE_AND_STEP();
896             *destreg = or_word(*destreg, *srcreg);
897         }
898         break;
899     }
900     DECODE_CLEAR_SEGOVR();
901     END_OF_INSTR();
902 }
903 
904 /****************************************************************************
905 REMARKS:
906 Handles opcode 0x0c
907 ****************************************************************************/
908 static void
x86emuOp_or_byte_AL_IMM(u8 X86EMU_UNUSED (op1))909 x86emuOp_or_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
910 {
911     u8 srcval;
912 
913     START_OF_INSTR();
914     DECODE_PRINTF("OR\tAL,");
915     srcval = fetch_byte_imm();
916     DECODE_PRINTF2("%x\n", srcval);
917     TRACE_AND_STEP();
918     M.x86.R_AL = or_byte(M.x86.R_AL, srcval);
919     DECODE_CLEAR_SEGOVR();
920     END_OF_INSTR();
921 }
922 
923 /****************************************************************************
924 REMARKS:
925 Handles opcode 0x0d
926 ****************************************************************************/
927 static void
x86emuOp_or_word_AX_IMM(u8 X86EMU_UNUSED (op1))928 x86emuOp_or_word_AX_IMM(u8 X86EMU_UNUSED(op1))
929 {
930     u32 srcval;
931 
932     START_OF_INSTR();
933     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
934         DECODE_PRINTF("OR\tEAX,");
935         srcval = fetch_long_imm();
936     }
937     else {
938         DECODE_PRINTF("OR\tAX,");
939         srcval = fetch_word_imm();
940     }
941     DECODE_PRINTF2("%x\n", srcval);
942     TRACE_AND_STEP();
943     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
944         M.x86.R_EAX = or_long(M.x86.R_EAX, srcval);
945     }
946     else {
947         M.x86.R_AX = or_word(M.x86.R_AX, (u16) srcval);
948     }
949     DECODE_CLEAR_SEGOVR();
950     END_OF_INSTR();
951 }
952 
953 /****************************************************************************
954 REMARKS:
955 Handles opcode 0x0e
956 ****************************************************************************/
957 static void
x86emuOp_push_CS(u8 X86EMU_UNUSED (op1))958 x86emuOp_push_CS(u8 X86EMU_UNUSED(op1))
959 {
960     START_OF_INSTR();
961     DECODE_PRINTF("PUSH\tCS\n");
962     TRACE_AND_STEP();
963     push_word(M.x86.R_CS);
964     DECODE_CLEAR_SEGOVR();
965     END_OF_INSTR();
966 }
967 
968 /****************************************************************************
969 REMARKS:
970 Handles opcode 0x0f. Escape for two-byte opcode (286 or better)
971 ****************************************************************************/
972 static void
x86emuOp_two_byte(u8 X86EMU_UNUSED (op1))973 x86emuOp_two_byte(u8 X86EMU_UNUSED(op1))
974 {
975     u8 op2 = (*sys_rdb) (((u32) M.x86.R_CS << 4) + (M.x86.R_IP++));
976 
977     INC_DECODED_INST_LEN(1);
978     (*x86emu_optab2[op2]) (op2);
979 }
980 
981 /****************************************************************************
982 REMARKS:
983 Handles opcode 0x10
984 ****************************************************************************/
985 static void
x86emuOp_adc_byte_RM_R(u8 X86EMU_UNUSED (op1))986 x86emuOp_adc_byte_RM_R(u8 X86EMU_UNUSED(op1))
987 {
988     int mod, rl, rh;
989     u8 *destreg, *srcreg;
990     uint destoffset;
991     u8 destval;
992 
993     START_OF_INSTR();
994     DECODE_PRINTF("ADC\t");
995     FETCH_DECODE_MODRM(mod, rh, rl);
996     switch (mod) {
997     case 0:
998         destoffset = decode_rm00_address(rl);
999         DECODE_PRINTF(",");
1000         destval = fetch_data_byte(destoffset);
1001         srcreg = DECODE_RM_BYTE_REGISTER(rh);
1002         DECODE_PRINTF("\n");
1003         TRACE_AND_STEP();
1004         destval = adc_byte(destval, *srcreg);
1005         store_data_byte(destoffset, destval);
1006         break;
1007     case 1:
1008         destoffset = decode_rm01_address(rl);
1009         DECODE_PRINTF(",");
1010         destval = fetch_data_byte(destoffset);
1011         srcreg = DECODE_RM_BYTE_REGISTER(rh);
1012         DECODE_PRINTF("\n");
1013         TRACE_AND_STEP();
1014         destval = adc_byte(destval, *srcreg);
1015         store_data_byte(destoffset, destval);
1016         break;
1017     case 2:
1018         destoffset = decode_rm10_address(rl);
1019         DECODE_PRINTF(",");
1020         destval = fetch_data_byte(destoffset);
1021         srcreg = DECODE_RM_BYTE_REGISTER(rh);
1022         DECODE_PRINTF("\n");
1023         TRACE_AND_STEP();
1024         destval = adc_byte(destval, *srcreg);
1025         store_data_byte(destoffset, destval);
1026         break;
1027     case 3:                    /* register to register */
1028         destreg = DECODE_RM_BYTE_REGISTER(rl);
1029         DECODE_PRINTF(",");
1030         srcreg = DECODE_RM_BYTE_REGISTER(rh);
1031         DECODE_PRINTF("\n");
1032         TRACE_AND_STEP();
1033         *destreg = adc_byte(*destreg, *srcreg);
1034         break;
1035     }
1036     DECODE_CLEAR_SEGOVR();
1037     END_OF_INSTR();
1038 }
1039 
1040 /****************************************************************************
1041 REMARKS:
1042 Handles opcode 0x11
1043 ****************************************************************************/
1044 static void
x86emuOp_adc_word_RM_R(u8 X86EMU_UNUSED (op1))1045 x86emuOp_adc_word_RM_R(u8 X86EMU_UNUSED(op1))
1046 {
1047     int mod, rl, rh;
1048     uint destoffset;
1049 
1050     START_OF_INSTR();
1051     DECODE_PRINTF("ADC\t");
1052     FETCH_DECODE_MODRM(mod, rh, rl);
1053     switch (mod) {
1054     case 0:
1055         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1056             u32 destval;
1057             u32 *srcreg;
1058 
1059             destoffset = decode_rm00_address(rl);
1060             DECODE_PRINTF(",");
1061             destval = fetch_data_long(destoffset);
1062             srcreg = DECODE_RM_LONG_REGISTER(rh);
1063             DECODE_PRINTF("\n");
1064             TRACE_AND_STEP();
1065             destval = adc_long(destval, *srcreg);
1066             store_data_long(destoffset, destval);
1067         }
1068         else {
1069             u16 destval;
1070             u16 *srcreg;
1071 
1072             destoffset = decode_rm00_address(rl);
1073             DECODE_PRINTF(",");
1074             destval = fetch_data_word(destoffset);
1075             srcreg = DECODE_RM_WORD_REGISTER(rh);
1076             DECODE_PRINTF("\n");
1077             TRACE_AND_STEP();
1078             destval = adc_word(destval, *srcreg);
1079             store_data_word(destoffset, destval);
1080         }
1081         break;
1082     case 1:
1083         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1084             u32 destval;
1085             u32 *srcreg;
1086 
1087             destoffset = decode_rm01_address(rl);
1088             DECODE_PRINTF(",");
1089             destval = fetch_data_long(destoffset);
1090             srcreg = DECODE_RM_LONG_REGISTER(rh);
1091             DECODE_PRINTF("\n");
1092             TRACE_AND_STEP();
1093             destval = adc_long(destval, *srcreg);
1094             store_data_long(destoffset, destval);
1095         }
1096         else {
1097             u16 destval;
1098             u16 *srcreg;
1099 
1100             destoffset = decode_rm01_address(rl);
1101             DECODE_PRINTF(",");
1102             destval = fetch_data_word(destoffset);
1103             srcreg = DECODE_RM_WORD_REGISTER(rh);
1104             DECODE_PRINTF("\n");
1105             TRACE_AND_STEP();
1106             destval = adc_word(destval, *srcreg);
1107             store_data_word(destoffset, destval);
1108         }
1109         break;
1110     case 2:
1111         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1112             u32 destval;
1113             u32 *srcreg;
1114 
1115             destoffset = decode_rm10_address(rl);
1116             DECODE_PRINTF(",");
1117             destval = fetch_data_long(destoffset);
1118             srcreg = DECODE_RM_LONG_REGISTER(rh);
1119             DECODE_PRINTF("\n");
1120             TRACE_AND_STEP();
1121             destval = adc_long(destval, *srcreg);
1122             store_data_long(destoffset, destval);
1123         }
1124         else {
1125             u16 destval;
1126             u16 *srcreg;
1127 
1128             destoffset = decode_rm10_address(rl);
1129             DECODE_PRINTF(",");
1130             destval = fetch_data_word(destoffset);
1131             srcreg = DECODE_RM_WORD_REGISTER(rh);
1132             DECODE_PRINTF("\n");
1133             TRACE_AND_STEP();
1134             destval = adc_word(destval, *srcreg);
1135             store_data_word(destoffset, destval);
1136         }
1137         break;
1138     case 3:                    /* register to register */
1139         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1140             u32 *destreg, *srcreg;
1141 
1142             destreg = DECODE_RM_LONG_REGISTER(rl);
1143             DECODE_PRINTF(",");
1144             srcreg = DECODE_RM_LONG_REGISTER(rh);
1145             DECODE_PRINTF("\n");
1146             TRACE_AND_STEP();
1147             *destreg = adc_long(*destreg, *srcreg);
1148         }
1149         else {
1150             u16 *destreg, *srcreg;
1151 
1152             destreg = DECODE_RM_WORD_REGISTER(rl);
1153             DECODE_PRINTF(",");
1154             srcreg = DECODE_RM_WORD_REGISTER(rh);
1155             DECODE_PRINTF("\n");
1156             TRACE_AND_STEP();
1157             *destreg = adc_word(*destreg, *srcreg);
1158         }
1159         break;
1160     }
1161     DECODE_CLEAR_SEGOVR();
1162     END_OF_INSTR();
1163 }
1164 
1165 /****************************************************************************
1166 REMARKS:
1167 Handles opcode 0x12
1168 ****************************************************************************/
1169 static void
x86emuOp_adc_byte_R_RM(u8 X86EMU_UNUSED (op1))1170 x86emuOp_adc_byte_R_RM(u8 X86EMU_UNUSED(op1))
1171 {
1172     int mod, rl, rh;
1173     u8 *destreg, *srcreg;
1174     uint srcoffset;
1175     u8 srcval;
1176 
1177     START_OF_INSTR();
1178     DECODE_PRINTF("ADC\t");
1179     FETCH_DECODE_MODRM(mod, rh, rl);
1180     switch (mod) {
1181     case 0:
1182         destreg = DECODE_RM_BYTE_REGISTER(rh);
1183         DECODE_PRINTF(",");
1184         srcoffset = decode_rm00_address(rl);
1185         srcval = fetch_data_byte(srcoffset);
1186         DECODE_PRINTF("\n");
1187         TRACE_AND_STEP();
1188         *destreg = adc_byte(*destreg, srcval);
1189         break;
1190     case 1:
1191         destreg = DECODE_RM_BYTE_REGISTER(rh);
1192         DECODE_PRINTF(",");
1193         srcoffset = decode_rm01_address(rl);
1194         srcval = fetch_data_byte(srcoffset);
1195         DECODE_PRINTF("\n");
1196         TRACE_AND_STEP();
1197         *destreg = adc_byte(*destreg, srcval);
1198         break;
1199     case 2:
1200         destreg = DECODE_RM_BYTE_REGISTER(rh);
1201         DECODE_PRINTF(",");
1202         srcoffset = decode_rm10_address(rl);
1203         srcval = fetch_data_byte(srcoffset);
1204         DECODE_PRINTF("\n");
1205         TRACE_AND_STEP();
1206         *destreg = adc_byte(*destreg, srcval);
1207         break;
1208     case 3:                    /* register to register */
1209         destreg = DECODE_RM_BYTE_REGISTER(rh);
1210         DECODE_PRINTF(",");
1211         srcreg = DECODE_RM_BYTE_REGISTER(rl);
1212         DECODE_PRINTF("\n");
1213         TRACE_AND_STEP();
1214         *destreg = adc_byte(*destreg, *srcreg);
1215         break;
1216     }
1217     DECODE_CLEAR_SEGOVR();
1218     END_OF_INSTR();
1219 }
1220 
1221 /****************************************************************************
1222 REMARKS:
1223 Handles opcode 0x13
1224 ****************************************************************************/
1225 static void
x86emuOp_adc_word_R_RM(u8 X86EMU_UNUSED (op1))1226 x86emuOp_adc_word_R_RM(u8 X86EMU_UNUSED(op1))
1227 {
1228     int mod, rl, rh;
1229     uint srcoffset;
1230 
1231     START_OF_INSTR();
1232     DECODE_PRINTF("ADC\t");
1233     FETCH_DECODE_MODRM(mod, rh, rl);
1234     switch (mod) {
1235     case 0:
1236         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1237             u32 *destreg;
1238             u32 srcval;
1239 
1240             destreg = DECODE_RM_LONG_REGISTER(rh);
1241             DECODE_PRINTF(",");
1242             srcoffset = decode_rm00_address(rl);
1243             srcval = fetch_data_long(srcoffset);
1244             DECODE_PRINTF("\n");
1245             TRACE_AND_STEP();
1246             *destreg = adc_long(*destreg, srcval);
1247         }
1248         else {
1249             u16 *destreg;
1250             u16 srcval;
1251 
1252             destreg = DECODE_RM_WORD_REGISTER(rh);
1253             DECODE_PRINTF(",");
1254             srcoffset = decode_rm00_address(rl);
1255             srcval = fetch_data_word(srcoffset);
1256             DECODE_PRINTF("\n");
1257             TRACE_AND_STEP();
1258             *destreg = adc_word(*destreg, srcval);
1259         }
1260         break;
1261     case 1:
1262         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1263             u32 *destreg;
1264             u32 srcval;
1265 
1266             destreg = DECODE_RM_LONG_REGISTER(rh);
1267             DECODE_PRINTF(",");
1268             srcoffset = decode_rm01_address(rl);
1269             srcval = fetch_data_long(srcoffset);
1270             DECODE_PRINTF("\n");
1271             TRACE_AND_STEP();
1272             *destreg = adc_long(*destreg, srcval);
1273         }
1274         else {
1275             u16 *destreg;
1276             u16 srcval;
1277 
1278             destreg = DECODE_RM_WORD_REGISTER(rh);
1279             DECODE_PRINTF(",");
1280             srcoffset = decode_rm01_address(rl);
1281             srcval = fetch_data_word(srcoffset);
1282             DECODE_PRINTF("\n");
1283             TRACE_AND_STEP();
1284             *destreg = adc_word(*destreg, srcval);
1285         }
1286         break;
1287     case 2:
1288         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1289             u32 *destreg;
1290             u32 srcval;
1291 
1292             destreg = DECODE_RM_LONG_REGISTER(rh);
1293             DECODE_PRINTF(",");
1294             srcoffset = decode_rm10_address(rl);
1295             srcval = fetch_data_long(srcoffset);
1296             DECODE_PRINTF("\n");
1297             TRACE_AND_STEP();
1298             *destreg = adc_long(*destreg, srcval);
1299         }
1300         else {
1301             u16 *destreg;
1302             u16 srcval;
1303 
1304             destreg = DECODE_RM_WORD_REGISTER(rh);
1305             DECODE_PRINTF(",");
1306             srcoffset = decode_rm10_address(rl);
1307             srcval = fetch_data_word(srcoffset);
1308             DECODE_PRINTF("\n");
1309             TRACE_AND_STEP();
1310             *destreg = adc_word(*destreg, srcval);
1311         }
1312         break;
1313     case 3:                    /* register to register */
1314         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1315             u32 *destreg, *srcreg;
1316 
1317             destreg = DECODE_RM_LONG_REGISTER(rh);
1318             DECODE_PRINTF(",");
1319             srcreg = DECODE_RM_LONG_REGISTER(rl);
1320             DECODE_PRINTF("\n");
1321             TRACE_AND_STEP();
1322             *destreg = adc_long(*destreg, *srcreg);
1323         }
1324         else {
1325             u16 *destreg, *srcreg;
1326 
1327             destreg = DECODE_RM_WORD_REGISTER(rh);
1328             DECODE_PRINTF(",");
1329             srcreg = DECODE_RM_WORD_REGISTER(rl);
1330             DECODE_PRINTF("\n");
1331             TRACE_AND_STEP();
1332             *destreg = adc_word(*destreg, *srcreg);
1333         }
1334         break;
1335     }
1336     DECODE_CLEAR_SEGOVR();
1337     END_OF_INSTR();
1338 }
1339 
1340 /****************************************************************************
1341 REMARKS:
1342 Handles opcode 0x14
1343 ****************************************************************************/
1344 static void
x86emuOp_adc_byte_AL_IMM(u8 X86EMU_UNUSED (op1))1345 x86emuOp_adc_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
1346 {
1347     u8 srcval;
1348 
1349     START_OF_INSTR();
1350     DECODE_PRINTF("ADC\tAL,");
1351     srcval = fetch_byte_imm();
1352     DECODE_PRINTF2("%x\n", srcval);
1353     TRACE_AND_STEP();
1354     M.x86.R_AL = adc_byte(M.x86.R_AL, srcval);
1355     DECODE_CLEAR_SEGOVR();
1356     END_OF_INSTR();
1357 }
1358 
1359 /****************************************************************************
1360 REMARKS:
1361 Handles opcode 0x15
1362 ****************************************************************************/
1363 static void
x86emuOp_adc_word_AX_IMM(u8 X86EMU_UNUSED (op1))1364 x86emuOp_adc_word_AX_IMM(u8 X86EMU_UNUSED(op1))
1365 {
1366     u32 srcval;
1367 
1368     START_OF_INSTR();
1369     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1370         DECODE_PRINTF("ADC\tEAX,");
1371         srcval = fetch_long_imm();
1372     }
1373     else {
1374         DECODE_PRINTF("ADC\tAX,");
1375         srcval = fetch_word_imm();
1376     }
1377     DECODE_PRINTF2("%x\n", srcval);
1378     TRACE_AND_STEP();
1379     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1380         M.x86.R_EAX = adc_long(M.x86.R_EAX, srcval);
1381     }
1382     else {
1383         M.x86.R_AX = adc_word(M.x86.R_AX, (u16) srcval);
1384     }
1385     DECODE_CLEAR_SEGOVR();
1386     END_OF_INSTR();
1387 }
1388 
1389 /****************************************************************************
1390 REMARKS:
1391 Handles opcode 0x16
1392 ****************************************************************************/
1393 static void
x86emuOp_push_SS(u8 X86EMU_UNUSED (op1))1394 x86emuOp_push_SS(u8 X86EMU_UNUSED(op1))
1395 {
1396     START_OF_INSTR();
1397     DECODE_PRINTF("PUSH\tSS\n");
1398     TRACE_AND_STEP();
1399     push_word(M.x86.R_SS);
1400     DECODE_CLEAR_SEGOVR();
1401     END_OF_INSTR();
1402 }
1403 
1404 /****************************************************************************
1405 REMARKS:
1406 Handles opcode 0x17
1407 ****************************************************************************/
1408 static void
x86emuOp_pop_SS(u8 X86EMU_UNUSED (op1))1409 x86emuOp_pop_SS(u8 X86EMU_UNUSED(op1))
1410 {
1411     START_OF_INSTR();
1412     DECODE_PRINTF("POP\tSS\n");
1413     TRACE_AND_STEP();
1414     M.x86.R_SS = pop_word();
1415     DECODE_CLEAR_SEGOVR();
1416     END_OF_INSTR();
1417 }
1418 
1419 /****************************************************************************
1420 REMARKS:
1421 Handles opcode 0x18
1422 ****************************************************************************/
1423 static void
x86emuOp_sbb_byte_RM_R(u8 X86EMU_UNUSED (op1))1424 x86emuOp_sbb_byte_RM_R(u8 X86EMU_UNUSED(op1))
1425 {
1426     int mod, rl, rh;
1427     u8 *destreg, *srcreg;
1428     uint destoffset;
1429     u8 destval;
1430 
1431     START_OF_INSTR();
1432     DECODE_PRINTF("SBB\t");
1433     FETCH_DECODE_MODRM(mod, rh, rl);
1434     switch (mod) {
1435     case 0:
1436         destoffset = decode_rm00_address(rl);
1437         DECODE_PRINTF(",");
1438         destval = fetch_data_byte(destoffset);
1439         srcreg = DECODE_RM_BYTE_REGISTER(rh);
1440         DECODE_PRINTF("\n");
1441         TRACE_AND_STEP();
1442         destval = sbb_byte(destval, *srcreg);
1443         store_data_byte(destoffset, destval);
1444         break;
1445     case 1:
1446         destoffset = decode_rm01_address(rl);
1447         DECODE_PRINTF(",");
1448         destval = fetch_data_byte(destoffset);
1449         srcreg = DECODE_RM_BYTE_REGISTER(rh);
1450         DECODE_PRINTF("\n");
1451         TRACE_AND_STEP();
1452         destval = sbb_byte(destval, *srcreg);
1453         store_data_byte(destoffset, destval);
1454         break;
1455     case 2:
1456         destoffset = decode_rm10_address(rl);
1457         DECODE_PRINTF(",");
1458         destval = fetch_data_byte(destoffset);
1459         srcreg = DECODE_RM_BYTE_REGISTER(rh);
1460         DECODE_PRINTF("\n");
1461         TRACE_AND_STEP();
1462         destval = sbb_byte(destval, *srcreg);
1463         store_data_byte(destoffset, destval);
1464         break;
1465     case 3:                    /* register to register */
1466         destreg = DECODE_RM_BYTE_REGISTER(rl);
1467         DECODE_PRINTF(",");
1468         srcreg = DECODE_RM_BYTE_REGISTER(rh);
1469         DECODE_PRINTF("\n");
1470         TRACE_AND_STEP();
1471         *destreg = sbb_byte(*destreg, *srcreg);
1472         break;
1473     }
1474     DECODE_CLEAR_SEGOVR();
1475     END_OF_INSTR();
1476 }
1477 
1478 /****************************************************************************
1479 REMARKS:
1480 Handles opcode 0x19
1481 ****************************************************************************/
1482 static void
x86emuOp_sbb_word_RM_R(u8 X86EMU_UNUSED (op1))1483 x86emuOp_sbb_word_RM_R(u8 X86EMU_UNUSED(op1))
1484 {
1485     int mod, rl, rh;
1486     uint destoffset;
1487 
1488     START_OF_INSTR();
1489     DECODE_PRINTF("SBB\t");
1490     FETCH_DECODE_MODRM(mod, rh, rl);
1491     switch (mod) {
1492     case 0:
1493         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1494             u32 destval;
1495             u32 *srcreg;
1496 
1497             destoffset = decode_rm00_address(rl);
1498             DECODE_PRINTF(",");
1499             destval = fetch_data_long(destoffset);
1500             srcreg = DECODE_RM_LONG_REGISTER(rh);
1501             DECODE_PRINTF("\n");
1502             TRACE_AND_STEP();
1503             destval = sbb_long(destval, *srcreg);
1504             store_data_long(destoffset, destval);
1505         }
1506         else {
1507             u16 destval;
1508             u16 *srcreg;
1509 
1510             destoffset = decode_rm00_address(rl);
1511             DECODE_PRINTF(",");
1512             destval = fetch_data_word(destoffset);
1513             srcreg = DECODE_RM_WORD_REGISTER(rh);
1514             DECODE_PRINTF("\n");
1515             TRACE_AND_STEP();
1516             destval = sbb_word(destval, *srcreg);
1517             store_data_word(destoffset, destval);
1518         }
1519         break;
1520     case 1:
1521         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1522             u32 destval;
1523             u32 *srcreg;
1524 
1525             destoffset = decode_rm01_address(rl);
1526             DECODE_PRINTF(",");
1527             destval = fetch_data_long(destoffset);
1528             srcreg = DECODE_RM_LONG_REGISTER(rh);
1529             DECODE_PRINTF("\n");
1530             TRACE_AND_STEP();
1531             destval = sbb_long(destval, *srcreg);
1532             store_data_long(destoffset, destval);
1533         }
1534         else {
1535             u16 destval;
1536             u16 *srcreg;
1537 
1538             destoffset = decode_rm01_address(rl);
1539             DECODE_PRINTF(",");
1540             destval = fetch_data_word(destoffset);
1541             srcreg = DECODE_RM_WORD_REGISTER(rh);
1542             DECODE_PRINTF("\n");
1543             TRACE_AND_STEP();
1544             destval = sbb_word(destval, *srcreg);
1545             store_data_word(destoffset, destval);
1546         }
1547         break;
1548     case 2:
1549         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1550             u32 destval;
1551             u32 *srcreg;
1552 
1553             destoffset = decode_rm10_address(rl);
1554             DECODE_PRINTF(",");
1555             destval = fetch_data_long(destoffset);
1556             srcreg = DECODE_RM_LONG_REGISTER(rh);
1557             DECODE_PRINTF("\n");
1558             TRACE_AND_STEP();
1559             destval = sbb_long(destval, *srcreg);
1560             store_data_long(destoffset, destval);
1561         }
1562         else {
1563             u16 destval;
1564             u16 *srcreg;
1565 
1566             destoffset = decode_rm10_address(rl);
1567             DECODE_PRINTF(",");
1568             destval = fetch_data_word(destoffset);
1569             srcreg = DECODE_RM_WORD_REGISTER(rh);
1570             DECODE_PRINTF("\n");
1571             TRACE_AND_STEP();
1572             destval = sbb_word(destval, *srcreg);
1573             store_data_word(destoffset, destval);
1574         }
1575         break;
1576     case 3:                    /* register to register */
1577         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1578             u32 *destreg, *srcreg;
1579 
1580             destreg = DECODE_RM_LONG_REGISTER(rl);
1581             DECODE_PRINTF(",");
1582             srcreg = DECODE_RM_LONG_REGISTER(rh);
1583             DECODE_PRINTF("\n");
1584             TRACE_AND_STEP();
1585             *destreg = sbb_long(*destreg, *srcreg);
1586         }
1587         else {
1588             u16 *destreg, *srcreg;
1589 
1590             destreg = DECODE_RM_WORD_REGISTER(rl);
1591             DECODE_PRINTF(",");
1592             srcreg = DECODE_RM_WORD_REGISTER(rh);
1593             DECODE_PRINTF("\n");
1594             TRACE_AND_STEP();
1595             *destreg = sbb_word(*destreg, *srcreg);
1596         }
1597         break;
1598     }
1599     DECODE_CLEAR_SEGOVR();
1600     END_OF_INSTR();
1601 }
1602 
1603 /****************************************************************************
1604 REMARKS:
1605 Handles opcode 0x1a
1606 ****************************************************************************/
1607 static void
x86emuOp_sbb_byte_R_RM(u8 X86EMU_UNUSED (op1))1608 x86emuOp_sbb_byte_R_RM(u8 X86EMU_UNUSED(op1))
1609 {
1610     int mod, rl, rh;
1611     u8 *destreg, *srcreg;
1612     uint srcoffset;
1613     u8 srcval;
1614 
1615     START_OF_INSTR();
1616     DECODE_PRINTF("SBB\t");
1617     FETCH_DECODE_MODRM(mod, rh, rl);
1618     switch (mod) {
1619     case 0:
1620         destreg = DECODE_RM_BYTE_REGISTER(rh);
1621         DECODE_PRINTF(",");
1622         srcoffset = decode_rm00_address(rl);
1623         srcval = fetch_data_byte(srcoffset);
1624         DECODE_PRINTF("\n");
1625         TRACE_AND_STEP();
1626         *destreg = sbb_byte(*destreg, srcval);
1627         break;
1628     case 1:
1629         destreg = DECODE_RM_BYTE_REGISTER(rh);
1630         DECODE_PRINTF(",");
1631         srcoffset = decode_rm01_address(rl);
1632         srcval = fetch_data_byte(srcoffset);
1633         DECODE_PRINTF("\n");
1634         TRACE_AND_STEP();
1635         *destreg = sbb_byte(*destreg, srcval);
1636         break;
1637     case 2:
1638         destreg = DECODE_RM_BYTE_REGISTER(rh);
1639         DECODE_PRINTF(",");
1640         srcoffset = decode_rm10_address(rl);
1641         srcval = fetch_data_byte(srcoffset);
1642         DECODE_PRINTF("\n");
1643         TRACE_AND_STEP();
1644         *destreg = sbb_byte(*destreg, srcval);
1645         break;
1646     case 3:                    /* register to register */
1647         destreg = DECODE_RM_BYTE_REGISTER(rh);
1648         DECODE_PRINTF(",");
1649         srcreg = DECODE_RM_BYTE_REGISTER(rl);
1650         DECODE_PRINTF("\n");
1651         TRACE_AND_STEP();
1652         *destreg = sbb_byte(*destreg, *srcreg);
1653         break;
1654     }
1655     DECODE_CLEAR_SEGOVR();
1656     END_OF_INSTR();
1657 }
1658 
1659 /****************************************************************************
1660 REMARKS:
1661 Handles opcode 0x1b
1662 ****************************************************************************/
1663 static void
x86emuOp_sbb_word_R_RM(u8 X86EMU_UNUSED (op1))1664 x86emuOp_sbb_word_R_RM(u8 X86EMU_UNUSED(op1))
1665 {
1666     int mod, rl, rh;
1667     uint srcoffset;
1668 
1669     START_OF_INSTR();
1670     DECODE_PRINTF("SBB\t");
1671     FETCH_DECODE_MODRM(mod, rh, rl);
1672     switch (mod) {
1673     case 0:
1674         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1675             u32 *destreg;
1676             u32 srcval;
1677 
1678             destreg = DECODE_RM_LONG_REGISTER(rh);
1679             DECODE_PRINTF(",");
1680             srcoffset = decode_rm00_address(rl);
1681             srcval = fetch_data_long(srcoffset);
1682             DECODE_PRINTF("\n");
1683             TRACE_AND_STEP();
1684             *destreg = sbb_long(*destreg, srcval);
1685         }
1686         else {
1687             u16 *destreg;
1688             u16 srcval;
1689 
1690             destreg = DECODE_RM_WORD_REGISTER(rh);
1691             DECODE_PRINTF(",");
1692             srcoffset = decode_rm00_address(rl);
1693             srcval = fetch_data_word(srcoffset);
1694             DECODE_PRINTF("\n");
1695             TRACE_AND_STEP();
1696             *destreg = sbb_word(*destreg, srcval);
1697         }
1698         break;
1699     case 1:
1700         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1701             u32 *destreg;
1702             u32 srcval;
1703 
1704             destreg = DECODE_RM_LONG_REGISTER(rh);
1705             DECODE_PRINTF(",");
1706             srcoffset = decode_rm01_address(rl);
1707             srcval = fetch_data_long(srcoffset);
1708             DECODE_PRINTF("\n");
1709             TRACE_AND_STEP();
1710             *destreg = sbb_long(*destreg, srcval);
1711         }
1712         else {
1713             u16 *destreg;
1714             u16 srcval;
1715 
1716             destreg = DECODE_RM_WORD_REGISTER(rh);
1717             DECODE_PRINTF(",");
1718             srcoffset = decode_rm01_address(rl);
1719             srcval = fetch_data_word(srcoffset);
1720             DECODE_PRINTF("\n");
1721             TRACE_AND_STEP();
1722             *destreg = sbb_word(*destreg, srcval);
1723         }
1724         break;
1725     case 2:
1726         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1727             u32 *destreg;
1728             u32 srcval;
1729 
1730             destreg = DECODE_RM_LONG_REGISTER(rh);
1731             DECODE_PRINTF(",");
1732             srcoffset = decode_rm10_address(rl);
1733             srcval = fetch_data_long(srcoffset);
1734             DECODE_PRINTF("\n");
1735             TRACE_AND_STEP();
1736             *destreg = sbb_long(*destreg, srcval);
1737         }
1738         else {
1739             u16 *destreg;
1740             u16 srcval;
1741 
1742             destreg = DECODE_RM_WORD_REGISTER(rh);
1743             DECODE_PRINTF(",");
1744             srcoffset = decode_rm10_address(rl);
1745             srcval = fetch_data_word(srcoffset);
1746             DECODE_PRINTF("\n");
1747             TRACE_AND_STEP();
1748             *destreg = sbb_word(*destreg, srcval);
1749         }
1750         break;
1751     case 3:                    /* register to register */
1752         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1753             u32 *destreg, *srcreg;
1754 
1755             destreg = DECODE_RM_LONG_REGISTER(rh);
1756             DECODE_PRINTF(",");
1757             srcreg = DECODE_RM_LONG_REGISTER(rl);
1758             DECODE_PRINTF("\n");
1759             TRACE_AND_STEP();
1760             *destreg = sbb_long(*destreg, *srcreg);
1761         }
1762         else {
1763             u16 *destreg, *srcreg;
1764 
1765             destreg = DECODE_RM_WORD_REGISTER(rh);
1766             DECODE_PRINTF(",");
1767             srcreg = DECODE_RM_WORD_REGISTER(rl);
1768             DECODE_PRINTF("\n");
1769             TRACE_AND_STEP();
1770             *destreg = sbb_word(*destreg, *srcreg);
1771         }
1772         break;
1773     }
1774     DECODE_CLEAR_SEGOVR();
1775     END_OF_INSTR();
1776 }
1777 
1778 /****************************************************************************
1779 REMARKS:
1780 Handles opcode 0x1c
1781 ****************************************************************************/
1782 static void
x86emuOp_sbb_byte_AL_IMM(u8 X86EMU_UNUSED (op1))1783 x86emuOp_sbb_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
1784 {
1785     u8 srcval;
1786 
1787     START_OF_INSTR();
1788     DECODE_PRINTF("SBB\tAL,");
1789     srcval = fetch_byte_imm();
1790     DECODE_PRINTF2("%x\n", srcval);
1791     TRACE_AND_STEP();
1792     M.x86.R_AL = sbb_byte(M.x86.R_AL, srcval);
1793     DECODE_CLEAR_SEGOVR();
1794     END_OF_INSTR();
1795 }
1796 
1797 /****************************************************************************
1798 REMARKS:
1799 Handles opcode 0x1d
1800 ****************************************************************************/
1801 static void
x86emuOp_sbb_word_AX_IMM(u8 X86EMU_UNUSED (op1))1802 x86emuOp_sbb_word_AX_IMM(u8 X86EMU_UNUSED(op1))
1803 {
1804     u32 srcval;
1805 
1806     START_OF_INSTR();
1807     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1808         DECODE_PRINTF("SBB\tEAX,");
1809         srcval = fetch_long_imm();
1810     }
1811     else {
1812         DECODE_PRINTF("SBB\tAX,");
1813         srcval = fetch_word_imm();
1814     }
1815     DECODE_PRINTF2("%x\n", srcval);
1816     TRACE_AND_STEP();
1817     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1818         M.x86.R_EAX = sbb_long(M.x86.R_EAX, srcval);
1819     }
1820     else {
1821         M.x86.R_AX = sbb_word(M.x86.R_AX, (u16) srcval);
1822     }
1823     DECODE_CLEAR_SEGOVR();
1824     END_OF_INSTR();
1825 }
1826 
1827 /****************************************************************************
1828 REMARKS:
1829 Handles opcode 0x1e
1830 ****************************************************************************/
1831 static void
x86emuOp_push_DS(u8 X86EMU_UNUSED (op1))1832 x86emuOp_push_DS(u8 X86EMU_UNUSED(op1))
1833 {
1834     START_OF_INSTR();
1835     DECODE_PRINTF("PUSH\tDS\n");
1836     TRACE_AND_STEP();
1837     push_word(M.x86.R_DS);
1838     DECODE_CLEAR_SEGOVR();
1839     END_OF_INSTR();
1840 }
1841 
1842 /****************************************************************************
1843 REMARKS:
1844 Handles opcode 0x1f
1845 ****************************************************************************/
1846 static void
x86emuOp_pop_DS(u8 X86EMU_UNUSED (op1))1847 x86emuOp_pop_DS(u8 X86EMU_UNUSED(op1))
1848 {
1849     START_OF_INSTR();
1850     DECODE_PRINTF("POP\tDS\n");
1851     TRACE_AND_STEP();
1852     M.x86.R_DS = pop_word();
1853     DECODE_CLEAR_SEGOVR();
1854     END_OF_INSTR();
1855 }
1856 
1857 /****************************************************************************
1858 REMARKS:
1859 Handles opcode 0x20
1860 ****************************************************************************/
1861 static void
x86emuOp_and_byte_RM_R(u8 X86EMU_UNUSED (op1))1862 x86emuOp_and_byte_RM_R(u8 X86EMU_UNUSED(op1))
1863 {
1864     int mod, rl, rh;
1865     u8 *destreg, *srcreg;
1866     uint destoffset;
1867     u8 destval;
1868 
1869     START_OF_INSTR();
1870     DECODE_PRINTF("AND\t");
1871     FETCH_DECODE_MODRM(mod, rh, rl);
1872 
1873     switch (mod) {
1874     case 0:
1875         destoffset = decode_rm00_address(rl);
1876         DECODE_PRINTF(",");
1877         destval = fetch_data_byte(destoffset);
1878         srcreg = DECODE_RM_BYTE_REGISTER(rh);
1879         DECODE_PRINTF("\n");
1880         TRACE_AND_STEP();
1881         destval = and_byte(destval, *srcreg);
1882         store_data_byte(destoffset, destval);
1883         break;
1884 
1885     case 1:
1886         destoffset = decode_rm01_address(rl);
1887         DECODE_PRINTF(",");
1888         destval = fetch_data_byte(destoffset);
1889         srcreg = DECODE_RM_BYTE_REGISTER(rh);
1890         DECODE_PRINTF("\n");
1891         TRACE_AND_STEP();
1892         destval = and_byte(destval, *srcreg);
1893         store_data_byte(destoffset, destval);
1894         break;
1895 
1896     case 2:
1897         destoffset = decode_rm10_address(rl);
1898         DECODE_PRINTF(",");
1899         destval = fetch_data_byte(destoffset);
1900         srcreg = DECODE_RM_BYTE_REGISTER(rh);
1901         DECODE_PRINTF("\n");
1902         TRACE_AND_STEP();
1903         destval = and_byte(destval, *srcreg);
1904         store_data_byte(destoffset, destval);
1905         break;
1906 
1907     case 3:                    /* register to register */
1908         destreg = DECODE_RM_BYTE_REGISTER(rl);
1909         DECODE_PRINTF(",");
1910         srcreg = DECODE_RM_BYTE_REGISTER(rh);
1911         DECODE_PRINTF("\n");
1912         TRACE_AND_STEP();
1913         *destreg = and_byte(*destreg, *srcreg);
1914         break;
1915     }
1916     DECODE_CLEAR_SEGOVR();
1917     END_OF_INSTR();
1918 }
1919 
1920 /****************************************************************************
1921 REMARKS:
1922 Handles opcode 0x21
1923 ****************************************************************************/
1924 static void
x86emuOp_and_word_RM_R(u8 X86EMU_UNUSED (op1))1925 x86emuOp_and_word_RM_R(u8 X86EMU_UNUSED(op1))
1926 {
1927     int mod, rl, rh;
1928     uint destoffset;
1929 
1930     START_OF_INSTR();
1931     DECODE_PRINTF("AND\t");
1932     FETCH_DECODE_MODRM(mod, rh, rl);
1933     switch (mod) {
1934     case 0:
1935         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1936             u32 destval;
1937             u32 *srcreg;
1938 
1939             destoffset = decode_rm00_address(rl);
1940             DECODE_PRINTF(",");
1941             destval = fetch_data_long(destoffset);
1942             srcreg = DECODE_RM_LONG_REGISTER(rh);
1943             DECODE_PRINTF("\n");
1944             TRACE_AND_STEP();
1945             destval = and_long(destval, *srcreg);
1946             store_data_long(destoffset, destval);
1947         }
1948         else {
1949             u16 destval;
1950             u16 *srcreg;
1951 
1952             destoffset = decode_rm00_address(rl);
1953             DECODE_PRINTF(",");
1954             destval = fetch_data_word(destoffset);
1955             srcreg = DECODE_RM_WORD_REGISTER(rh);
1956             DECODE_PRINTF("\n");
1957             TRACE_AND_STEP();
1958             destval = and_word(destval, *srcreg);
1959             store_data_word(destoffset, destval);
1960         }
1961         break;
1962     case 1:
1963         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1964             u32 destval;
1965             u32 *srcreg;
1966 
1967             destoffset = decode_rm01_address(rl);
1968             DECODE_PRINTF(",");
1969             destval = fetch_data_long(destoffset);
1970             srcreg = DECODE_RM_LONG_REGISTER(rh);
1971             DECODE_PRINTF("\n");
1972             TRACE_AND_STEP();
1973             destval = and_long(destval, *srcreg);
1974             store_data_long(destoffset, destval);
1975         }
1976         else {
1977             u16 destval;
1978             u16 *srcreg;
1979 
1980             destoffset = decode_rm01_address(rl);
1981             DECODE_PRINTF(",");
1982             destval = fetch_data_word(destoffset);
1983             srcreg = DECODE_RM_WORD_REGISTER(rh);
1984             DECODE_PRINTF("\n");
1985             TRACE_AND_STEP();
1986             destval = and_word(destval, *srcreg);
1987             store_data_word(destoffset, destval);
1988         }
1989         break;
1990     case 2:
1991         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1992             u32 destval;
1993             u32 *srcreg;
1994 
1995             destoffset = decode_rm10_address(rl);
1996             DECODE_PRINTF(",");
1997             destval = fetch_data_long(destoffset);
1998             srcreg = DECODE_RM_LONG_REGISTER(rh);
1999             DECODE_PRINTF("\n");
2000             TRACE_AND_STEP();
2001             destval = and_long(destval, *srcreg);
2002             store_data_long(destoffset, destval);
2003         }
2004         else {
2005             u16 destval;
2006             u16 *srcreg;
2007 
2008             destoffset = decode_rm10_address(rl);
2009             DECODE_PRINTF(",");
2010             destval = fetch_data_word(destoffset);
2011             srcreg = DECODE_RM_WORD_REGISTER(rh);
2012             DECODE_PRINTF("\n");
2013             TRACE_AND_STEP();
2014             destval = and_word(destval, *srcreg);
2015             store_data_word(destoffset, destval);
2016         }
2017         break;
2018     case 3:                    /* register to register */
2019         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2020             u32 *destreg, *srcreg;
2021 
2022             destreg = DECODE_RM_LONG_REGISTER(rl);
2023             DECODE_PRINTF(",");
2024             srcreg = DECODE_RM_LONG_REGISTER(rh);
2025             DECODE_PRINTF("\n");
2026             TRACE_AND_STEP();
2027             *destreg = and_long(*destreg, *srcreg);
2028         }
2029         else {
2030             u16 *destreg, *srcreg;
2031 
2032             destreg = DECODE_RM_WORD_REGISTER(rl);
2033             DECODE_PRINTF(",");
2034             srcreg = DECODE_RM_WORD_REGISTER(rh);
2035             DECODE_PRINTF("\n");
2036             TRACE_AND_STEP();
2037             *destreg = and_word(*destreg, *srcreg);
2038         }
2039         break;
2040     }
2041     DECODE_CLEAR_SEGOVR();
2042     END_OF_INSTR();
2043 }
2044 
2045 /****************************************************************************
2046 REMARKS:
2047 Handles opcode 0x22
2048 ****************************************************************************/
2049 static void
x86emuOp_and_byte_R_RM(u8 X86EMU_UNUSED (op1))2050 x86emuOp_and_byte_R_RM(u8 X86EMU_UNUSED(op1))
2051 {
2052     int mod, rl, rh;
2053     u8 *destreg, *srcreg;
2054     uint srcoffset;
2055     u8 srcval;
2056 
2057     START_OF_INSTR();
2058     DECODE_PRINTF("AND\t");
2059     FETCH_DECODE_MODRM(mod, rh, rl);
2060     switch (mod) {
2061     case 0:
2062         destreg = DECODE_RM_BYTE_REGISTER(rh);
2063         DECODE_PRINTF(",");
2064         srcoffset = decode_rm00_address(rl);
2065         srcval = fetch_data_byte(srcoffset);
2066         DECODE_PRINTF("\n");
2067         TRACE_AND_STEP();
2068         *destreg = and_byte(*destreg, srcval);
2069         break;
2070     case 1:
2071         destreg = DECODE_RM_BYTE_REGISTER(rh);
2072         DECODE_PRINTF(",");
2073         srcoffset = decode_rm01_address(rl);
2074         srcval = fetch_data_byte(srcoffset);
2075         DECODE_PRINTF("\n");
2076         TRACE_AND_STEP();
2077         *destreg = and_byte(*destreg, srcval);
2078         break;
2079     case 2:
2080         destreg = DECODE_RM_BYTE_REGISTER(rh);
2081         DECODE_PRINTF(",");
2082         srcoffset = decode_rm10_address(rl);
2083         srcval = fetch_data_byte(srcoffset);
2084         DECODE_PRINTF("\n");
2085         TRACE_AND_STEP();
2086         *destreg = and_byte(*destreg, srcval);
2087         break;
2088     case 3:                    /* register to register */
2089         destreg = DECODE_RM_BYTE_REGISTER(rh);
2090         DECODE_PRINTF(",");
2091         srcreg = DECODE_RM_BYTE_REGISTER(rl);
2092         DECODE_PRINTF("\n");
2093         TRACE_AND_STEP();
2094         *destreg = and_byte(*destreg, *srcreg);
2095         break;
2096     }
2097     DECODE_CLEAR_SEGOVR();
2098     END_OF_INSTR();
2099 }
2100 
2101 /****************************************************************************
2102 REMARKS:
2103 Handles opcode 0x23
2104 ****************************************************************************/
2105 static void
x86emuOp_and_word_R_RM(u8 X86EMU_UNUSED (op1))2106 x86emuOp_and_word_R_RM(u8 X86EMU_UNUSED(op1))
2107 {
2108     int mod, rl, rh;
2109     uint srcoffset;
2110 
2111     START_OF_INSTR();
2112     DECODE_PRINTF("AND\t");
2113     FETCH_DECODE_MODRM(mod, rh, rl);
2114     switch (mod) {
2115     case 0:
2116         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2117             u32 *destreg;
2118             u32 srcval;
2119 
2120             destreg = DECODE_RM_LONG_REGISTER(rh);
2121             DECODE_PRINTF(",");
2122             srcoffset = decode_rm00_address(rl);
2123             srcval = fetch_data_long(srcoffset);
2124             DECODE_PRINTF("\n");
2125             TRACE_AND_STEP();
2126             *destreg = and_long(*destreg, srcval);
2127         }
2128         else {
2129             u16 *destreg;
2130             u16 srcval;
2131 
2132             destreg = DECODE_RM_WORD_REGISTER(rh);
2133             DECODE_PRINTF(",");
2134             srcoffset = decode_rm00_address(rl);
2135             srcval = fetch_data_word(srcoffset);
2136             DECODE_PRINTF("\n");
2137             TRACE_AND_STEP();
2138             *destreg = and_word(*destreg, srcval);
2139         }
2140         break;
2141     case 1:
2142         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2143             u32 *destreg;
2144             u32 srcval;
2145 
2146             destreg = DECODE_RM_LONG_REGISTER(rh);
2147             DECODE_PRINTF(",");
2148             srcoffset = decode_rm01_address(rl);
2149             srcval = fetch_data_long(srcoffset);
2150             DECODE_PRINTF("\n");
2151             TRACE_AND_STEP();
2152             *destreg = and_long(*destreg, srcval);
2153             break;
2154         }
2155         else {
2156             u16 *destreg;
2157             u16 srcval;
2158 
2159             destreg = DECODE_RM_WORD_REGISTER(rh);
2160             DECODE_PRINTF(",");
2161             srcoffset = decode_rm01_address(rl);
2162             srcval = fetch_data_word(srcoffset);
2163             DECODE_PRINTF("\n");
2164             TRACE_AND_STEP();
2165             *destreg = and_word(*destreg, srcval);
2166             break;
2167         }
2168     case 2:
2169         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2170             u32 *destreg;
2171             u32 srcval;
2172 
2173             destreg = DECODE_RM_LONG_REGISTER(rh);
2174             DECODE_PRINTF(",");
2175             srcoffset = decode_rm10_address(rl);
2176             srcval = fetch_data_long(srcoffset);
2177             DECODE_PRINTF("\n");
2178             TRACE_AND_STEP();
2179             *destreg = and_long(*destreg, srcval);
2180         }
2181         else {
2182             u16 *destreg;
2183             u16 srcval;
2184 
2185             destreg = DECODE_RM_WORD_REGISTER(rh);
2186             DECODE_PRINTF(",");
2187             srcoffset = decode_rm10_address(rl);
2188             srcval = fetch_data_word(srcoffset);
2189             DECODE_PRINTF("\n");
2190             TRACE_AND_STEP();
2191             *destreg = and_word(*destreg, srcval);
2192         }
2193         break;
2194     case 3:                    /* register to register */
2195         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2196             u32 *destreg, *srcreg;
2197 
2198             destreg = DECODE_RM_LONG_REGISTER(rh);
2199             DECODE_PRINTF(",");
2200             srcreg = DECODE_RM_LONG_REGISTER(rl);
2201             DECODE_PRINTF("\n");
2202             TRACE_AND_STEP();
2203             *destreg = and_long(*destreg, *srcreg);
2204         }
2205         else {
2206             u16 *destreg, *srcreg;
2207 
2208             destreg = DECODE_RM_WORD_REGISTER(rh);
2209             DECODE_PRINTF(",");
2210             srcreg = DECODE_RM_WORD_REGISTER(rl);
2211             DECODE_PRINTF("\n");
2212             TRACE_AND_STEP();
2213             *destreg = and_word(*destreg, *srcreg);
2214         }
2215         break;
2216     }
2217     DECODE_CLEAR_SEGOVR();
2218     END_OF_INSTR();
2219 }
2220 
2221 /****************************************************************************
2222 REMARKS:
2223 Handles opcode 0x24
2224 ****************************************************************************/
2225 static void
x86emuOp_and_byte_AL_IMM(u8 X86EMU_UNUSED (op1))2226 x86emuOp_and_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
2227 {
2228     u8 srcval;
2229 
2230     START_OF_INSTR();
2231     DECODE_PRINTF("AND\tAL,");
2232     srcval = fetch_byte_imm();
2233     DECODE_PRINTF2("%x\n", srcval);
2234     TRACE_AND_STEP();
2235     M.x86.R_AL = and_byte(M.x86.R_AL, srcval);
2236     DECODE_CLEAR_SEGOVR();
2237     END_OF_INSTR();
2238 }
2239 
2240 /****************************************************************************
2241 REMARKS:
2242 Handles opcode 0x25
2243 ****************************************************************************/
2244 static void
x86emuOp_and_word_AX_IMM(u8 X86EMU_UNUSED (op1))2245 x86emuOp_and_word_AX_IMM(u8 X86EMU_UNUSED(op1))
2246 {
2247     u32 srcval;
2248 
2249     START_OF_INSTR();
2250     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2251         DECODE_PRINTF("AND\tEAX,");
2252         srcval = fetch_long_imm();
2253     }
2254     else {
2255         DECODE_PRINTF("AND\tAX,");
2256         srcval = fetch_word_imm();
2257     }
2258     DECODE_PRINTF2("%x\n", srcval);
2259     TRACE_AND_STEP();
2260     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2261         M.x86.R_EAX = and_long(M.x86.R_EAX, srcval);
2262     }
2263     else {
2264         M.x86.R_AX = and_word(M.x86.R_AX, (u16) srcval);
2265     }
2266     DECODE_CLEAR_SEGOVR();
2267     END_OF_INSTR();
2268 }
2269 
2270 /****************************************************************************
2271 REMARKS:
2272 Handles opcode 0x26
2273 ****************************************************************************/
2274 static void
x86emuOp_segovr_ES(u8 X86EMU_UNUSED (op1))2275 x86emuOp_segovr_ES(u8 X86EMU_UNUSED(op1))
2276 {
2277     START_OF_INSTR();
2278     DECODE_PRINTF("ES:\n");
2279     TRACE_AND_STEP();
2280     M.x86.mode |= SYSMODE_SEGOVR_ES;
2281     /*
2282      * note the lack of DECODE_CLEAR_SEGOVR(r) since, here is one of 4
2283      * opcode subroutines we do not want to do this.
2284      */
2285     END_OF_INSTR();
2286 }
2287 
2288 /****************************************************************************
2289 REMARKS:
2290 Handles opcode 0x27
2291 ****************************************************************************/
2292 static void
x86emuOp_daa(u8 X86EMU_UNUSED (op1))2293 x86emuOp_daa(u8 X86EMU_UNUSED(op1))
2294 {
2295     START_OF_INSTR();
2296     DECODE_PRINTF("DAA\n");
2297     TRACE_AND_STEP();
2298     M.x86.R_AL = daa_byte(M.x86.R_AL);
2299     DECODE_CLEAR_SEGOVR();
2300     END_OF_INSTR();
2301 }
2302 
2303 /****************************************************************************
2304 REMARKS:
2305 Handles opcode 0x28
2306 ****************************************************************************/
2307 static void
x86emuOp_sub_byte_RM_R(u8 X86EMU_UNUSED (op1))2308 x86emuOp_sub_byte_RM_R(u8 X86EMU_UNUSED(op1))
2309 {
2310     int mod, rl, rh;
2311     u8 *destreg, *srcreg;
2312     uint destoffset;
2313     u8 destval;
2314 
2315     START_OF_INSTR();
2316     DECODE_PRINTF("SUB\t");
2317     FETCH_DECODE_MODRM(mod, rh, rl);
2318     switch (mod) {
2319     case 0:
2320         destoffset = decode_rm00_address(rl);
2321         DECODE_PRINTF(",");
2322         destval = fetch_data_byte(destoffset);
2323         srcreg = DECODE_RM_BYTE_REGISTER(rh);
2324         DECODE_PRINTF("\n");
2325         TRACE_AND_STEP();
2326         destval = sub_byte(destval, *srcreg);
2327         store_data_byte(destoffset, destval);
2328         break;
2329     case 1:
2330         destoffset = decode_rm01_address(rl);
2331         DECODE_PRINTF(",");
2332         destval = fetch_data_byte(destoffset);
2333         srcreg = DECODE_RM_BYTE_REGISTER(rh);
2334         DECODE_PRINTF("\n");
2335         TRACE_AND_STEP();
2336         destval = sub_byte(destval, *srcreg);
2337         store_data_byte(destoffset, destval);
2338         break;
2339     case 2:
2340         destoffset = decode_rm10_address(rl);
2341         DECODE_PRINTF(",");
2342         destval = fetch_data_byte(destoffset);
2343         srcreg = DECODE_RM_BYTE_REGISTER(rh);
2344         DECODE_PRINTF("\n");
2345         TRACE_AND_STEP();
2346         destval = sub_byte(destval, *srcreg);
2347         store_data_byte(destoffset, destval);
2348         break;
2349     case 3:                    /* register to register */
2350         destreg = DECODE_RM_BYTE_REGISTER(rl);
2351         DECODE_PRINTF(",");
2352         srcreg = DECODE_RM_BYTE_REGISTER(rh);
2353         DECODE_PRINTF("\n");
2354         TRACE_AND_STEP();
2355         *destreg = sub_byte(*destreg, *srcreg);
2356         break;
2357     }
2358     DECODE_CLEAR_SEGOVR();
2359     END_OF_INSTR();
2360 }
2361 
2362 /****************************************************************************
2363 REMARKS:
2364 Handles opcode 0x29
2365 ****************************************************************************/
2366 static void
x86emuOp_sub_word_RM_R(u8 X86EMU_UNUSED (op1))2367 x86emuOp_sub_word_RM_R(u8 X86EMU_UNUSED(op1))
2368 {
2369     int mod, rl, rh;
2370     uint destoffset;
2371 
2372     START_OF_INSTR();
2373     DECODE_PRINTF("SUB\t");
2374     FETCH_DECODE_MODRM(mod, rh, rl);
2375     switch (mod) {
2376     case 0:
2377         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2378             u32 destval;
2379             u32 *srcreg;
2380 
2381             destoffset = decode_rm00_address(rl);
2382             DECODE_PRINTF(",");
2383             destval = fetch_data_long(destoffset);
2384             srcreg = DECODE_RM_LONG_REGISTER(rh);
2385             DECODE_PRINTF("\n");
2386             TRACE_AND_STEP();
2387             destval = sub_long(destval, *srcreg);
2388             store_data_long(destoffset, destval);
2389         }
2390         else {
2391             u16 destval;
2392             u16 *srcreg;
2393 
2394             destoffset = decode_rm00_address(rl);
2395             DECODE_PRINTF(",");
2396             destval = fetch_data_word(destoffset);
2397             srcreg = DECODE_RM_WORD_REGISTER(rh);
2398             DECODE_PRINTF("\n");
2399             TRACE_AND_STEP();
2400             destval = sub_word(destval, *srcreg);
2401             store_data_word(destoffset, destval);
2402         }
2403         break;
2404     case 1:
2405         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2406             u32 destval;
2407             u32 *srcreg;
2408 
2409             destoffset = decode_rm01_address(rl);
2410             DECODE_PRINTF(",");
2411             destval = fetch_data_long(destoffset);
2412             srcreg = DECODE_RM_LONG_REGISTER(rh);
2413             DECODE_PRINTF("\n");
2414             TRACE_AND_STEP();
2415             destval = sub_long(destval, *srcreg);
2416             store_data_long(destoffset, destval);
2417         }
2418         else {
2419             u16 destval;
2420             u16 *srcreg;
2421 
2422             destoffset = decode_rm01_address(rl);
2423             DECODE_PRINTF(",");
2424             destval = fetch_data_word(destoffset);
2425             srcreg = DECODE_RM_WORD_REGISTER(rh);
2426             DECODE_PRINTF("\n");
2427             TRACE_AND_STEP();
2428             destval = sub_word(destval, *srcreg);
2429             store_data_word(destoffset, destval);
2430         }
2431         break;
2432     case 2:
2433         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2434             u32 destval;
2435             u32 *srcreg;
2436 
2437             destoffset = decode_rm10_address(rl);
2438             DECODE_PRINTF(",");
2439             destval = fetch_data_long(destoffset);
2440             srcreg = DECODE_RM_LONG_REGISTER(rh);
2441             DECODE_PRINTF("\n");
2442             TRACE_AND_STEP();
2443             destval = sub_long(destval, *srcreg);
2444             store_data_long(destoffset, destval);
2445         }
2446         else {
2447             u16 destval;
2448             u16 *srcreg;
2449 
2450             destoffset = decode_rm10_address(rl);
2451             DECODE_PRINTF(",");
2452             destval = fetch_data_word(destoffset);
2453             srcreg = DECODE_RM_WORD_REGISTER(rh);
2454             DECODE_PRINTF("\n");
2455             TRACE_AND_STEP();
2456             destval = sub_word(destval, *srcreg);
2457             store_data_word(destoffset, destval);
2458         }
2459         break;
2460     case 3:                    /* register to register */
2461         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2462             u32 *destreg, *srcreg;
2463 
2464             destreg = DECODE_RM_LONG_REGISTER(rl);
2465             DECODE_PRINTF(",");
2466             srcreg = DECODE_RM_LONG_REGISTER(rh);
2467             DECODE_PRINTF("\n");
2468             TRACE_AND_STEP();
2469             *destreg = sub_long(*destreg, *srcreg);
2470         }
2471         else {
2472             u16 *destreg, *srcreg;
2473 
2474             destreg = DECODE_RM_WORD_REGISTER(rl);
2475             DECODE_PRINTF(",");
2476             srcreg = DECODE_RM_WORD_REGISTER(rh);
2477             DECODE_PRINTF("\n");
2478             TRACE_AND_STEP();
2479             *destreg = sub_word(*destreg, *srcreg);
2480         }
2481         break;
2482     }
2483     DECODE_CLEAR_SEGOVR();
2484     END_OF_INSTR();
2485 }
2486 
2487 /****************************************************************************
2488 REMARKS:
2489 Handles opcode 0x2a
2490 ****************************************************************************/
2491 static void
x86emuOp_sub_byte_R_RM(u8 X86EMU_UNUSED (op1))2492 x86emuOp_sub_byte_R_RM(u8 X86EMU_UNUSED(op1))
2493 {
2494     int mod, rl, rh;
2495     u8 *destreg, *srcreg;
2496     uint srcoffset;
2497     u8 srcval;
2498 
2499     START_OF_INSTR();
2500     DECODE_PRINTF("SUB\t");
2501     FETCH_DECODE_MODRM(mod, rh, rl);
2502     switch (mod) {
2503     case 0:
2504         destreg = DECODE_RM_BYTE_REGISTER(rh);
2505         DECODE_PRINTF(",");
2506         srcoffset = decode_rm00_address(rl);
2507         srcval = fetch_data_byte(srcoffset);
2508         DECODE_PRINTF("\n");
2509         TRACE_AND_STEP();
2510         *destreg = sub_byte(*destreg, srcval);
2511         break;
2512     case 1:
2513         destreg = DECODE_RM_BYTE_REGISTER(rh);
2514         DECODE_PRINTF(",");
2515         srcoffset = decode_rm01_address(rl);
2516         srcval = fetch_data_byte(srcoffset);
2517         DECODE_PRINTF("\n");
2518         TRACE_AND_STEP();
2519         *destreg = sub_byte(*destreg, srcval);
2520         break;
2521     case 2:
2522         destreg = DECODE_RM_BYTE_REGISTER(rh);
2523         DECODE_PRINTF(",");
2524         srcoffset = decode_rm10_address(rl);
2525         srcval = fetch_data_byte(srcoffset);
2526         DECODE_PRINTF("\n");
2527         TRACE_AND_STEP();
2528         *destreg = sub_byte(*destreg, srcval);
2529         break;
2530     case 3:                    /* register to register */
2531         destreg = DECODE_RM_BYTE_REGISTER(rh);
2532         DECODE_PRINTF(",");
2533         srcreg = DECODE_RM_BYTE_REGISTER(rl);
2534         DECODE_PRINTF("\n");
2535         TRACE_AND_STEP();
2536         *destreg = sub_byte(*destreg, *srcreg);
2537         break;
2538     }
2539     DECODE_CLEAR_SEGOVR();
2540     END_OF_INSTR();
2541 }
2542 
2543 /****************************************************************************
2544 REMARKS:
2545 Handles opcode 0x2b
2546 ****************************************************************************/
2547 static void
x86emuOp_sub_word_R_RM(u8 X86EMU_UNUSED (op1))2548 x86emuOp_sub_word_R_RM(u8 X86EMU_UNUSED(op1))
2549 {
2550     int mod, rl, rh;
2551     uint srcoffset;
2552 
2553     START_OF_INSTR();
2554     DECODE_PRINTF("SUB\t");
2555     FETCH_DECODE_MODRM(mod, rh, rl);
2556     switch (mod) {
2557     case 0:
2558         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2559             u32 *destreg;
2560             u32 srcval;
2561 
2562             destreg = DECODE_RM_LONG_REGISTER(rh);
2563             DECODE_PRINTF(",");
2564             srcoffset = decode_rm00_address(rl);
2565             srcval = fetch_data_long(srcoffset);
2566             DECODE_PRINTF("\n");
2567             TRACE_AND_STEP();
2568             *destreg = sub_long(*destreg, srcval);
2569         }
2570         else {
2571             u16 *destreg;
2572             u16 srcval;
2573 
2574             destreg = DECODE_RM_WORD_REGISTER(rh);
2575             DECODE_PRINTF(",");
2576             srcoffset = decode_rm00_address(rl);
2577             srcval = fetch_data_word(srcoffset);
2578             DECODE_PRINTF("\n");
2579             TRACE_AND_STEP();
2580             *destreg = sub_word(*destreg, srcval);
2581         }
2582         break;
2583     case 1:
2584         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2585             u32 *destreg;
2586             u32 srcval;
2587 
2588             destreg = DECODE_RM_LONG_REGISTER(rh);
2589             DECODE_PRINTF(",");
2590             srcoffset = decode_rm01_address(rl);
2591             srcval = fetch_data_long(srcoffset);
2592             DECODE_PRINTF("\n");
2593             TRACE_AND_STEP();
2594             *destreg = sub_long(*destreg, srcval);
2595         }
2596         else {
2597             u16 *destreg;
2598             u16 srcval;
2599 
2600             destreg = DECODE_RM_WORD_REGISTER(rh);
2601             DECODE_PRINTF(",");
2602             srcoffset = decode_rm01_address(rl);
2603             srcval = fetch_data_word(srcoffset);
2604             DECODE_PRINTF("\n");
2605             TRACE_AND_STEP();
2606             *destreg = sub_word(*destreg, srcval);
2607         }
2608         break;
2609     case 2:
2610         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2611             u32 *destreg;
2612             u32 srcval;
2613 
2614             destreg = DECODE_RM_LONG_REGISTER(rh);
2615             DECODE_PRINTF(",");
2616             srcoffset = decode_rm10_address(rl);
2617             srcval = fetch_data_long(srcoffset);
2618             DECODE_PRINTF("\n");
2619             TRACE_AND_STEP();
2620             *destreg = sub_long(*destreg, srcval);
2621         }
2622         else {
2623             u16 *destreg;
2624             u16 srcval;
2625 
2626             destreg = DECODE_RM_WORD_REGISTER(rh);
2627             DECODE_PRINTF(",");
2628             srcoffset = decode_rm10_address(rl);
2629             srcval = fetch_data_word(srcoffset);
2630             DECODE_PRINTF("\n");
2631             TRACE_AND_STEP();
2632             *destreg = sub_word(*destreg, srcval);
2633         }
2634         break;
2635     case 3:                    /* register to register */
2636         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2637             u32 *destreg, *srcreg;
2638 
2639             destreg = DECODE_RM_LONG_REGISTER(rh);
2640             DECODE_PRINTF(",");
2641             srcreg = DECODE_RM_LONG_REGISTER(rl);
2642             DECODE_PRINTF("\n");
2643             TRACE_AND_STEP();
2644             *destreg = sub_long(*destreg, *srcreg);
2645         }
2646         else {
2647             u16 *destreg, *srcreg;
2648 
2649             destreg = DECODE_RM_WORD_REGISTER(rh);
2650             DECODE_PRINTF(",");
2651             srcreg = DECODE_RM_WORD_REGISTER(rl);
2652             DECODE_PRINTF("\n");
2653             TRACE_AND_STEP();
2654             *destreg = sub_word(*destreg, *srcreg);
2655         }
2656         break;
2657     }
2658     DECODE_CLEAR_SEGOVR();
2659     END_OF_INSTR();
2660 }
2661 
2662 /****************************************************************************
2663 REMARKS:
2664 Handles opcode 0x2c
2665 ****************************************************************************/
2666 static void
x86emuOp_sub_byte_AL_IMM(u8 X86EMU_UNUSED (op1))2667 x86emuOp_sub_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
2668 {
2669     u8 srcval;
2670 
2671     START_OF_INSTR();
2672     DECODE_PRINTF("SUB\tAL,");
2673     srcval = fetch_byte_imm();
2674     DECODE_PRINTF2("%x\n", srcval);
2675     TRACE_AND_STEP();
2676     M.x86.R_AL = sub_byte(M.x86.R_AL, srcval);
2677     DECODE_CLEAR_SEGOVR();
2678     END_OF_INSTR();
2679 }
2680 
2681 /****************************************************************************
2682 REMARKS:
2683 Handles opcode 0x2d
2684 ****************************************************************************/
2685 static void
x86emuOp_sub_word_AX_IMM(u8 X86EMU_UNUSED (op1))2686 x86emuOp_sub_word_AX_IMM(u8 X86EMU_UNUSED(op1))
2687 {
2688     u32 srcval;
2689 
2690     START_OF_INSTR();
2691     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2692         DECODE_PRINTF("SUB\tEAX,");
2693         srcval = fetch_long_imm();
2694     }
2695     else {
2696         DECODE_PRINTF("SUB\tAX,");
2697         srcval = fetch_word_imm();
2698     }
2699     DECODE_PRINTF2("%x\n", srcval);
2700     TRACE_AND_STEP();
2701     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2702         M.x86.R_EAX = sub_long(M.x86.R_EAX, srcval);
2703     }
2704     else {
2705         M.x86.R_AX = sub_word(M.x86.R_AX, (u16) srcval);
2706     }
2707     DECODE_CLEAR_SEGOVR();
2708     END_OF_INSTR();
2709 }
2710 
2711 /****************************************************************************
2712 REMARKS:
2713 Handles opcode 0x2e
2714 ****************************************************************************/
2715 static void
x86emuOp_segovr_CS(u8 X86EMU_UNUSED (op1))2716 x86emuOp_segovr_CS(u8 X86EMU_UNUSED(op1))
2717 {
2718     START_OF_INSTR();
2719     DECODE_PRINTF("CS:\n");
2720     TRACE_AND_STEP();
2721     M.x86.mode |= SYSMODE_SEGOVR_CS;
2722     /* note no DECODE_CLEAR_SEGOVR here. */
2723     END_OF_INSTR();
2724 }
2725 
2726 /****************************************************************************
2727 REMARKS:
2728 Handles opcode 0x2f
2729 ****************************************************************************/
2730 static void
x86emuOp_das(u8 X86EMU_UNUSED (op1))2731 x86emuOp_das(u8 X86EMU_UNUSED(op1))
2732 {
2733     START_OF_INSTR();
2734     DECODE_PRINTF("DAS\n");
2735     TRACE_AND_STEP();
2736     M.x86.R_AL = das_byte(M.x86.R_AL);
2737     DECODE_CLEAR_SEGOVR();
2738     END_OF_INSTR();
2739 }
2740 
2741 /****************************************************************************
2742 REMARKS:
2743 Handles opcode 0x30
2744 ****************************************************************************/
2745 static void
x86emuOp_xor_byte_RM_R(u8 X86EMU_UNUSED (op1))2746 x86emuOp_xor_byte_RM_R(u8 X86EMU_UNUSED(op1))
2747 {
2748     int mod, rl, rh;
2749     u8 *destreg, *srcreg;
2750     uint destoffset;
2751     u8 destval;
2752 
2753     START_OF_INSTR();
2754     DECODE_PRINTF("XOR\t");
2755     FETCH_DECODE_MODRM(mod, rh, rl);
2756     switch (mod) {
2757     case 0:
2758         destoffset = decode_rm00_address(rl);
2759         DECODE_PRINTF(",");
2760         destval = fetch_data_byte(destoffset);
2761         srcreg = DECODE_RM_BYTE_REGISTER(rh);
2762         DECODE_PRINTF("\n");
2763         TRACE_AND_STEP();
2764         destval = xor_byte(destval, *srcreg);
2765         store_data_byte(destoffset, destval);
2766         break;
2767     case 1:
2768         destoffset = decode_rm01_address(rl);
2769         DECODE_PRINTF(",");
2770         destval = fetch_data_byte(destoffset);
2771         srcreg = DECODE_RM_BYTE_REGISTER(rh);
2772         DECODE_PRINTF("\n");
2773         TRACE_AND_STEP();
2774         destval = xor_byte(destval, *srcreg);
2775         store_data_byte(destoffset, destval);
2776         break;
2777     case 2:
2778         destoffset = decode_rm10_address(rl);
2779         DECODE_PRINTF(",");
2780         destval = fetch_data_byte(destoffset);
2781         srcreg = DECODE_RM_BYTE_REGISTER(rh);
2782         DECODE_PRINTF("\n");
2783         TRACE_AND_STEP();
2784         destval = xor_byte(destval, *srcreg);
2785         store_data_byte(destoffset, destval);
2786         break;
2787     case 3:                    /* register to register */
2788         destreg = DECODE_RM_BYTE_REGISTER(rl);
2789         DECODE_PRINTF(",");
2790         srcreg = DECODE_RM_BYTE_REGISTER(rh);
2791         DECODE_PRINTF("\n");
2792         TRACE_AND_STEP();
2793         *destreg = xor_byte(*destreg, *srcreg);
2794         break;
2795     }
2796     DECODE_CLEAR_SEGOVR();
2797     END_OF_INSTR();
2798 }
2799 
2800 /****************************************************************************
2801 REMARKS:
2802 Handles opcode 0x31
2803 ****************************************************************************/
2804 static void
x86emuOp_xor_word_RM_R(u8 X86EMU_UNUSED (op1))2805 x86emuOp_xor_word_RM_R(u8 X86EMU_UNUSED(op1))
2806 {
2807     int mod, rl, rh;
2808     uint destoffset;
2809 
2810     START_OF_INSTR();
2811     DECODE_PRINTF("XOR\t");
2812     FETCH_DECODE_MODRM(mod, rh, rl);
2813     switch (mod) {
2814     case 0:
2815         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2816             u32 destval;
2817             u32 *srcreg;
2818 
2819             destoffset = decode_rm00_address(rl);
2820             DECODE_PRINTF(",");
2821             destval = fetch_data_long(destoffset);
2822             srcreg = DECODE_RM_LONG_REGISTER(rh);
2823             DECODE_PRINTF("\n");
2824             TRACE_AND_STEP();
2825             destval = xor_long(destval, *srcreg);
2826             store_data_long(destoffset, destval);
2827         }
2828         else {
2829             u16 destval;
2830             u16 *srcreg;
2831 
2832             destoffset = decode_rm00_address(rl);
2833             DECODE_PRINTF(",");
2834             destval = fetch_data_word(destoffset);
2835             srcreg = DECODE_RM_WORD_REGISTER(rh);
2836             DECODE_PRINTF("\n");
2837             TRACE_AND_STEP();
2838             destval = xor_word(destval, *srcreg);
2839             store_data_word(destoffset, destval);
2840         }
2841         break;
2842     case 1:
2843         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2844             u32 destval;
2845             u32 *srcreg;
2846 
2847             destoffset = decode_rm01_address(rl);
2848             DECODE_PRINTF(",");
2849             destval = fetch_data_long(destoffset);
2850             srcreg = DECODE_RM_LONG_REGISTER(rh);
2851             DECODE_PRINTF("\n");
2852             TRACE_AND_STEP();
2853             destval = xor_long(destval, *srcreg);
2854             store_data_long(destoffset, destval);
2855         }
2856         else {
2857             u16 destval;
2858             u16 *srcreg;
2859 
2860             destoffset = decode_rm01_address(rl);
2861             DECODE_PRINTF(",");
2862             destval = fetch_data_word(destoffset);
2863             srcreg = DECODE_RM_WORD_REGISTER(rh);
2864             DECODE_PRINTF("\n");
2865             TRACE_AND_STEP();
2866             destval = xor_word(destval, *srcreg);
2867             store_data_word(destoffset, destval);
2868         }
2869         break;
2870     case 2:
2871         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2872             u32 destval;
2873             u32 *srcreg;
2874 
2875             destoffset = decode_rm10_address(rl);
2876             DECODE_PRINTF(",");
2877             destval = fetch_data_long(destoffset);
2878             srcreg = DECODE_RM_LONG_REGISTER(rh);
2879             DECODE_PRINTF("\n");
2880             TRACE_AND_STEP();
2881             destval = xor_long(destval, *srcreg);
2882             store_data_long(destoffset, destval);
2883         }
2884         else {
2885             u16 destval;
2886             u16 *srcreg;
2887 
2888             destoffset = decode_rm10_address(rl);
2889             DECODE_PRINTF(",");
2890             destval = fetch_data_word(destoffset);
2891             srcreg = DECODE_RM_WORD_REGISTER(rh);
2892             DECODE_PRINTF("\n");
2893             TRACE_AND_STEP();
2894             destval = xor_word(destval, *srcreg);
2895             store_data_word(destoffset, destval);
2896         }
2897         break;
2898     case 3:                    /* register to register */
2899         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2900             u32 *destreg, *srcreg;
2901 
2902             destreg = DECODE_RM_LONG_REGISTER(rl);
2903             DECODE_PRINTF(",");
2904             srcreg = DECODE_RM_LONG_REGISTER(rh);
2905             DECODE_PRINTF("\n");
2906             TRACE_AND_STEP();
2907             *destreg = xor_long(*destreg, *srcreg);
2908         }
2909         else {
2910             u16 *destreg, *srcreg;
2911 
2912             destreg = DECODE_RM_WORD_REGISTER(rl);
2913             DECODE_PRINTF(",");
2914             srcreg = DECODE_RM_WORD_REGISTER(rh);
2915             DECODE_PRINTF("\n");
2916             TRACE_AND_STEP();
2917             *destreg = xor_word(*destreg, *srcreg);
2918         }
2919         break;
2920     }
2921     DECODE_CLEAR_SEGOVR();
2922     END_OF_INSTR();
2923 }
2924 
2925 /****************************************************************************
2926 REMARKS:
2927 Handles opcode 0x32
2928 ****************************************************************************/
2929 static void
x86emuOp_xor_byte_R_RM(u8 X86EMU_UNUSED (op1))2930 x86emuOp_xor_byte_R_RM(u8 X86EMU_UNUSED(op1))
2931 {
2932     int mod, rl, rh;
2933     u8 *destreg, *srcreg;
2934     uint srcoffset;
2935     u8 srcval;
2936 
2937     START_OF_INSTR();
2938     DECODE_PRINTF("XOR\t");
2939     FETCH_DECODE_MODRM(mod, rh, rl);
2940     switch (mod) {
2941     case 0:
2942         destreg = DECODE_RM_BYTE_REGISTER(rh);
2943         DECODE_PRINTF(",");
2944         srcoffset = decode_rm00_address(rl);
2945         srcval = fetch_data_byte(srcoffset);
2946         DECODE_PRINTF("\n");
2947         TRACE_AND_STEP();
2948         *destreg = xor_byte(*destreg, srcval);
2949         break;
2950     case 1:
2951         destreg = DECODE_RM_BYTE_REGISTER(rh);
2952         DECODE_PRINTF(",");
2953         srcoffset = decode_rm01_address(rl);
2954         srcval = fetch_data_byte(srcoffset);
2955         DECODE_PRINTF("\n");
2956         TRACE_AND_STEP();
2957         *destreg = xor_byte(*destreg, srcval);
2958         break;
2959     case 2:
2960         destreg = DECODE_RM_BYTE_REGISTER(rh);
2961         DECODE_PRINTF(",");
2962         srcoffset = decode_rm10_address(rl);
2963         srcval = fetch_data_byte(srcoffset);
2964         DECODE_PRINTF("\n");
2965         TRACE_AND_STEP();
2966         *destreg = xor_byte(*destreg, srcval);
2967         break;
2968     case 3:                    /* register to register */
2969         destreg = DECODE_RM_BYTE_REGISTER(rh);
2970         DECODE_PRINTF(",");
2971         srcreg = DECODE_RM_BYTE_REGISTER(rl);
2972         DECODE_PRINTF("\n");
2973         TRACE_AND_STEP();
2974         *destreg = xor_byte(*destreg, *srcreg);
2975         break;
2976     }
2977     DECODE_CLEAR_SEGOVR();
2978     END_OF_INSTR();
2979 }
2980 
2981 /****************************************************************************
2982 REMARKS:
2983 Handles opcode 0x33
2984 ****************************************************************************/
2985 static void
x86emuOp_xor_word_R_RM(u8 X86EMU_UNUSED (op1))2986 x86emuOp_xor_word_R_RM(u8 X86EMU_UNUSED(op1))
2987 {
2988     int mod, rl, rh;
2989     uint srcoffset;
2990 
2991     START_OF_INSTR();
2992     DECODE_PRINTF("XOR\t");
2993     FETCH_DECODE_MODRM(mod, rh, rl);
2994     switch (mod) {
2995     case 0:
2996         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2997             u32 *destreg;
2998             u32 srcval;
2999 
3000             destreg = DECODE_RM_LONG_REGISTER(rh);
3001             DECODE_PRINTF(",");
3002             srcoffset = decode_rm00_address(rl);
3003             srcval = fetch_data_long(srcoffset);
3004             DECODE_PRINTF("\n");
3005             TRACE_AND_STEP();
3006             *destreg = xor_long(*destreg, srcval);
3007         }
3008         else {
3009             u16 *destreg;
3010             u16 srcval;
3011 
3012             destreg = DECODE_RM_WORD_REGISTER(rh);
3013             DECODE_PRINTF(",");
3014             srcoffset = decode_rm00_address(rl);
3015             srcval = fetch_data_word(srcoffset);
3016             DECODE_PRINTF("\n");
3017             TRACE_AND_STEP();
3018             *destreg = xor_word(*destreg, srcval);
3019         }
3020         break;
3021     case 1:
3022         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3023             u32 *destreg;
3024             u32 srcval;
3025 
3026             destreg = DECODE_RM_LONG_REGISTER(rh);
3027             DECODE_PRINTF(",");
3028             srcoffset = decode_rm01_address(rl);
3029             srcval = fetch_data_long(srcoffset);
3030             DECODE_PRINTF("\n");
3031             TRACE_AND_STEP();
3032             *destreg = xor_long(*destreg, srcval);
3033         }
3034         else {
3035             u16 *destreg;
3036             u16 srcval;
3037 
3038             destreg = DECODE_RM_WORD_REGISTER(rh);
3039             DECODE_PRINTF(",");
3040             srcoffset = decode_rm01_address(rl);
3041             srcval = fetch_data_word(srcoffset);
3042             DECODE_PRINTF("\n");
3043             TRACE_AND_STEP();
3044             *destreg = xor_word(*destreg, srcval);
3045         }
3046         break;
3047     case 2:
3048         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3049             u32 *destreg;
3050             u32 srcval;
3051 
3052             destreg = DECODE_RM_LONG_REGISTER(rh);
3053             DECODE_PRINTF(",");
3054             srcoffset = decode_rm10_address(rl);
3055             srcval = fetch_data_long(srcoffset);
3056             DECODE_PRINTF("\n");
3057             TRACE_AND_STEP();
3058             *destreg = xor_long(*destreg, srcval);
3059         }
3060         else {
3061             u16 *destreg;
3062             u16 srcval;
3063 
3064             destreg = DECODE_RM_WORD_REGISTER(rh);
3065             DECODE_PRINTF(",");
3066             srcoffset = decode_rm10_address(rl);
3067             srcval = fetch_data_word(srcoffset);
3068             DECODE_PRINTF("\n");
3069             TRACE_AND_STEP();
3070             *destreg = xor_word(*destreg, srcval);
3071         }
3072         break;
3073     case 3:                    /* register to register */
3074         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3075             u32 *destreg, *srcreg;
3076 
3077             destreg = DECODE_RM_LONG_REGISTER(rh);
3078             DECODE_PRINTF(",");
3079             srcreg = DECODE_RM_LONG_REGISTER(rl);
3080             DECODE_PRINTF("\n");
3081             TRACE_AND_STEP();
3082             *destreg = xor_long(*destreg, *srcreg);
3083         }
3084         else {
3085             u16 *destreg, *srcreg;
3086 
3087             destreg = DECODE_RM_WORD_REGISTER(rh);
3088             DECODE_PRINTF(",");
3089             srcreg = DECODE_RM_WORD_REGISTER(rl);
3090             DECODE_PRINTF("\n");
3091             TRACE_AND_STEP();
3092             *destreg = xor_word(*destreg, *srcreg);
3093         }
3094         break;
3095     }
3096     DECODE_CLEAR_SEGOVR();
3097     END_OF_INSTR();
3098 }
3099 
3100 /****************************************************************************
3101 REMARKS:
3102 Handles opcode 0x34
3103 ****************************************************************************/
3104 static void
x86emuOp_xor_byte_AL_IMM(u8 X86EMU_UNUSED (op1))3105 x86emuOp_xor_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
3106 {
3107     u8 srcval;
3108 
3109     START_OF_INSTR();
3110     DECODE_PRINTF("XOR\tAL,");
3111     srcval = fetch_byte_imm();
3112     DECODE_PRINTF2("%x\n", srcval);
3113     TRACE_AND_STEP();
3114     M.x86.R_AL = xor_byte(M.x86.R_AL, srcval);
3115     DECODE_CLEAR_SEGOVR();
3116     END_OF_INSTR();
3117 }
3118 
3119 /****************************************************************************
3120 REMARKS:
3121 Handles opcode 0x35
3122 ****************************************************************************/
3123 static void
x86emuOp_xor_word_AX_IMM(u8 X86EMU_UNUSED (op1))3124 x86emuOp_xor_word_AX_IMM(u8 X86EMU_UNUSED(op1))
3125 {
3126     u32 srcval;
3127 
3128     START_OF_INSTR();
3129     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3130         DECODE_PRINTF("XOR\tEAX,");
3131         srcval = fetch_long_imm();
3132     }
3133     else {
3134         DECODE_PRINTF("XOR\tAX,");
3135         srcval = fetch_word_imm();
3136     }
3137     DECODE_PRINTF2("%x\n", srcval);
3138     TRACE_AND_STEP();
3139     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3140         M.x86.R_EAX = xor_long(M.x86.R_EAX, srcval);
3141     }
3142     else {
3143         M.x86.R_AX = xor_word(M.x86.R_AX, (u16) srcval);
3144     }
3145     DECODE_CLEAR_SEGOVR();
3146     END_OF_INSTR();
3147 }
3148 
3149 /****************************************************************************
3150 REMARKS:
3151 Handles opcode 0x36
3152 ****************************************************************************/
3153 static void
x86emuOp_segovr_SS(u8 X86EMU_UNUSED (op1))3154 x86emuOp_segovr_SS(u8 X86EMU_UNUSED(op1))
3155 {
3156     START_OF_INSTR();
3157     DECODE_PRINTF("SS:\n");
3158     TRACE_AND_STEP();
3159     M.x86.mode |= SYSMODE_SEGOVR_SS;
3160     /* no DECODE_CLEAR_SEGOVR ! */
3161     END_OF_INSTR();
3162 }
3163 
3164 /****************************************************************************
3165 REMARKS:
3166 Handles opcode 0x37
3167 ****************************************************************************/
3168 static void
x86emuOp_aaa(u8 X86EMU_UNUSED (op1))3169 x86emuOp_aaa(u8 X86EMU_UNUSED(op1))
3170 {
3171     START_OF_INSTR();
3172     DECODE_PRINTF("AAA\n");
3173     TRACE_AND_STEP();
3174     M.x86.R_AX = aaa_word(M.x86.R_AX);
3175     DECODE_CLEAR_SEGOVR();
3176     END_OF_INSTR();
3177 }
3178 
3179 /****************************************************************************
3180 REMARKS:
3181 Handles opcode 0x38
3182 ****************************************************************************/
3183 static void
x86emuOp_cmp_byte_RM_R(u8 X86EMU_UNUSED (op1))3184 x86emuOp_cmp_byte_RM_R(u8 X86EMU_UNUSED(op1))
3185 {
3186     int mod, rl, rh;
3187     uint destoffset;
3188     u8 *destreg, *srcreg;
3189     u8 destval;
3190 
3191     START_OF_INSTR();
3192     DECODE_PRINTF("CMP\t");
3193     FETCH_DECODE_MODRM(mod, rh, rl);
3194     switch (mod) {
3195     case 0:
3196         destoffset = decode_rm00_address(rl);
3197         DECODE_PRINTF(",");
3198         destval = fetch_data_byte(destoffset);
3199         srcreg = DECODE_RM_BYTE_REGISTER(rh);
3200         DECODE_PRINTF("\n");
3201         TRACE_AND_STEP();
3202         cmp_byte(destval, *srcreg);
3203         break;
3204     case 1:
3205         destoffset = decode_rm01_address(rl);
3206         DECODE_PRINTF(",");
3207         destval = fetch_data_byte(destoffset);
3208         srcreg = DECODE_RM_BYTE_REGISTER(rh);
3209         DECODE_PRINTF("\n");
3210         TRACE_AND_STEP();
3211         cmp_byte(destval, *srcreg);
3212         break;
3213     case 2:
3214         destoffset = decode_rm10_address(rl);
3215         DECODE_PRINTF(",");
3216         destval = fetch_data_byte(destoffset);
3217         srcreg = DECODE_RM_BYTE_REGISTER(rh);
3218         DECODE_PRINTF("\n");
3219         TRACE_AND_STEP();
3220         cmp_byte(destval, *srcreg);
3221         break;
3222     case 3:                    /* register to register */
3223         destreg = DECODE_RM_BYTE_REGISTER(rl);
3224         DECODE_PRINTF(",");
3225         srcreg = DECODE_RM_BYTE_REGISTER(rh);
3226         DECODE_PRINTF("\n");
3227         TRACE_AND_STEP();
3228         cmp_byte(*destreg, *srcreg);
3229         break;
3230     }
3231     DECODE_CLEAR_SEGOVR();
3232     END_OF_INSTR();
3233 }
3234 
3235 /****************************************************************************
3236 REMARKS:
3237 Handles opcode 0x39
3238 ****************************************************************************/
3239 static void
x86emuOp_cmp_word_RM_R(u8 X86EMU_UNUSED (op1))3240 x86emuOp_cmp_word_RM_R(u8 X86EMU_UNUSED(op1))
3241 {
3242     int mod, rl, rh;
3243     uint destoffset;
3244 
3245     START_OF_INSTR();
3246     DECODE_PRINTF("CMP\t");
3247     FETCH_DECODE_MODRM(mod, rh, rl);
3248     switch (mod) {
3249     case 0:
3250         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3251             u32 destval;
3252             u32 *srcreg;
3253 
3254             destoffset = decode_rm00_address(rl);
3255             DECODE_PRINTF(",");
3256             destval = fetch_data_long(destoffset);
3257             srcreg = DECODE_RM_LONG_REGISTER(rh);
3258             DECODE_PRINTF("\n");
3259             TRACE_AND_STEP();
3260             cmp_long(destval, *srcreg);
3261         }
3262         else {
3263             u16 destval;
3264             u16 *srcreg;
3265 
3266             destoffset = decode_rm00_address(rl);
3267             DECODE_PRINTF(",");
3268             destval = fetch_data_word(destoffset);
3269             srcreg = DECODE_RM_WORD_REGISTER(rh);
3270             DECODE_PRINTF("\n");
3271             TRACE_AND_STEP();
3272             cmp_word(destval, *srcreg);
3273         }
3274         break;
3275     case 1:
3276         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3277             u32 destval;
3278             u32 *srcreg;
3279 
3280             destoffset = decode_rm01_address(rl);
3281             DECODE_PRINTF(",");
3282             destval = fetch_data_long(destoffset);
3283             srcreg = DECODE_RM_LONG_REGISTER(rh);
3284             DECODE_PRINTF("\n");
3285             TRACE_AND_STEP();
3286             cmp_long(destval, *srcreg);
3287         }
3288         else {
3289             u16 destval;
3290             u16 *srcreg;
3291 
3292             destoffset = decode_rm01_address(rl);
3293             DECODE_PRINTF(",");
3294             destval = fetch_data_word(destoffset);
3295             srcreg = DECODE_RM_WORD_REGISTER(rh);
3296             DECODE_PRINTF("\n");
3297             TRACE_AND_STEP();
3298             cmp_word(destval, *srcreg);
3299         }
3300         break;
3301     case 2:
3302         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3303             u32 destval;
3304             u32 *srcreg;
3305 
3306             destoffset = decode_rm10_address(rl);
3307             DECODE_PRINTF(",");
3308             destval = fetch_data_long(destoffset);
3309             srcreg = DECODE_RM_LONG_REGISTER(rh);
3310             DECODE_PRINTF("\n");
3311             TRACE_AND_STEP();
3312             cmp_long(destval, *srcreg);
3313         }
3314         else {
3315             u16 destval;
3316             u16 *srcreg;
3317 
3318             destoffset = decode_rm10_address(rl);
3319             DECODE_PRINTF(",");
3320             destval = fetch_data_word(destoffset);
3321             srcreg = DECODE_RM_WORD_REGISTER(rh);
3322             DECODE_PRINTF("\n");
3323             TRACE_AND_STEP();
3324             cmp_word(destval, *srcreg);
3325         }
3326         break;
3327     case 3:                    /* register to register */
3328         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3329             u32 *destreg, *srcreg;
3330 
3331             destreg = DECODE_RM_LONG_REGISTER(rl);
3332             DECODE_PRINTF(",");
3333             srcreg = DECODE_RM_LONG_REGISTER(rh);
3334             DECODE_PRINTF("\n");
3335             TRACE_AND_STEP();
3336             cmp_long(*destreg, *srcreg);
3337         }
3338         else {
3339             u16 *destreg, *srcreg;
3340 
3341             destreg = DECODE_RM_WORD_REGISTER(rl);
3342             DECODE_PRINTF(",");
3343             srcreg = DECODE_RM_WORD_REGISTER(rh);
3344             DECODE_PRINTF("\n");
3345             TRACE_AND_STEP();
3346             cmp_word(*destreg, *srcreg);
3347         }
3348         break;
3349     }
3350     DECODE_CLEAR_SEGOVR();
3351     END_OF_INSTR();
3352 }
3353 
3354 /****************************************************************************
3355 REMARKS:
3356 Handles opcode 0x3a
3357 ****************************************************************************/
3358 static void
x86emuOp_cmp_byte_R_RM(u8 X86EMU_UNUSED (op1))3359 x86emuOp_cmp_byte_R_RM(u8 X86EMU_UNUSED(op1))
3360 {
3361     int mod, rl, rh;
3362     u8 *destreg, *srcreg;
3363     uint srcoffset;
3364     u8 srcval;
3365 
3366     START_OF_INSTR();
3367     DECODE_PRINTF("CMP\t");
3368     FETCH_DECODE_MODRM(mod, rh, rl);
3369     switch (mod) {
3370     case 0:
3371         destreg = DECODE_RM_BYTE_REGISTER(rh);
3372         DECODE_PRINTF(",");
3373         srcoffset = decode_rm00_address(rl);
3374         srcval = fetch_data_byte(srcoffset);
3375         DECODE_PRINTF("\n");
3376         TRACE_AND_STEP();
3377         cmp_byte(*destreg, srcval);
3378         break;
3379     case 1:
3380         destreg = DECODE_RM_BYTE_REGISTER(rh);
3381         DECODE_PRINTF(",");
3382         srcoffset = decode_rm01_address(rl);
3383         srcval = fetch_data_byte(srcoffset);
3384         DECODE_PRINTF("\n");
3385         TRACE_AND_STEP();
3386         cmp_byte(*destreg, srcval);
3387         break;
3388     case 2:
3389         destreg = DECODE_RM_BYTE_REGISTER(rh);
3390         DECODE_PRINTF(",");
3391         srcoffset = decode_rm10_address(rl);
3392         srcval = fetch_data_byte(srcoffset);
3393         DECODE_PRINTF("\n");
3394         TRACE_AND_STEP();
3395         cmp_byte(*destreg, srcval);
3396         break;
3397     case 3:                    /* register to register */
3398         destreg = DECODE_RM_BYTE_REGISTER(rh);
3399         DECODE_PRINTF(",");
3400         srcreg = DECODE_RM_BYTE_REGISTER(rl);
3401         DECODE_PRINTF("\n");
3402         TRACE_AND_STEP();
3403         cmp_byte(*destreg, *srcreg);
3404         break;
3405     }
3406     DECODE_CLEAR_SEGOVR();
3407     END_OF_INSTR();
3408 }
3409 
3410 /****************************************************************************
3411 REMARKS:
3412 Handles opcode 0x3b
3413 ****************************************************************************/
3414 static void
x86emuOp_cmp_word_R_RM(u8 X86EMU_UNUSED (op1))3415 x86emuOp_cmp_word_R_RM(u8 X86EMU_UNUSED(op1))
3416 {
3417     int mod, rl, rh;
3418     uint srcoffset;
3419 
3420     START_OF_INSTR();
3421     DECODE_PRINTF("CMP\t");
3422     FETCH_DECODE_MODRM(mod, rh, rl);
3423     switch (mod) {
3424     case 0:
3425         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3426             u32 *destreg;
3427             u32 srcval;
3428 
3429             destreg = DECODE_RM_LONG_REGISTER(rh);
3430             DECODE_PRINTF(",");
3431             srcoffset = decode_rm00_address(rl);
3432             srcval = fetch_data_long(srcoffset);
3433             DECODE_PRINTF("\n");
3434             TRACE_AND_STEP();
3435             cmp_long(*destreg, srcval);
3436         }
3437         else {
3438             u16 *destreg;
3439             u16 srcval;
3440 
3441             destreg = DECODE_RM_WORD_REGISTER(rh);
3442             DECODE_PRINTF(",");
3443             srcoffset = decode_rm00_address(rl);
3444             srcval = fetch_data_word(srcoffset);
3445             DECODE_PRINTF("\n");
3446             TRACE_AND_STEP();
3447             cmp_word(*destreg, srcval);
3448         }
3449         break;
3450     case 1:
3451         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3452             u32 *destreg;
3453             u32 srcval;
3454 
3455             destreg = DECODE_RM_LONG_REGISTER(rh);
3456             DECODE_PRINTF(",");
3457             srcoffset = decode_rm01_address(rl);
3458             srcval = fetch_data_long(srcoffset);
3459             DECODE_PRINTF("\n");
3460             TRACE_AND_STEP();
3461             cmp_long(*destreg, srcval);
3462         }
3463         else {
3464             u16 *destreg;
3465             u16 srcval;
3466 
3467             destreg = DECODE_RM_WORD_REGISTER(rh);
3468             DECODE_PRINTF(",");
3469             srcoffset = decode_rm01_address(rl);
3470             srcval = fetch_data_word(srcoffset);
3471             DECODE_PRINTF("\n");
3472             TRACE_AND_STEP();
3473             cmp_word(*destreg, srcval);
3474         }
3475         break;
3476     case 2:
3477         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3478             u32 *destreg;
3479             u32 srcval;
3480 
3481             destreg = DECODE_RM_LONG_REGISTER(rh);
3482             DECODE_PRINTF(",");
3483             srcoffset = decode_rm10_address(rl);
3484             srcval = fetch_data_long(srcoffset);
3485             DECODE_PRINTF("\n");
3486             TRACE_AND_STEP();
3487             cmp_long(*destreg, srcval);
3488         }
3489         else {
3490             u16 *destreg;
3491             u16 srcval;
3492 
3493             destreg = DECODE_RM_WORD_REGISTER(rh);
3494             DECODE_PRINTF(",");
3495             srcoffset = decode_rm10_address(rl);
3496             srcval = fetch_data_word(srcoffset);
3497             DECODE_PRINTF("\n");
3498             TRACE_AND_STEP();
3499             cmp_word(*destreg, srcval);
3500         }
3501         break;
3502     case 3:                    /* register to register */
3503         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3504             u32 *destreg, *srcreg;
3505 
3506             destreg = DECODE_RM_LONG_REGISTER(rh);
3507             DECODE_PRINTF(",");
3508             srcreg = DECODE_RM_LONG_REGISTER(rl);
3509             DECODE_PRINTF("\n");
3510             TRACE_AND_STEP();
3511             cmp_long(*destreg, *srcreg);
3512         }
3513         else {
3514             u16 *destreg, *srcreg;
3515 
3516             destreg = DECODE_RM_WORD_REGISTER(rh);
3517             DECODE_PRINTF(",");
3518             srcreg = DECODE_RM_WORD_REGISTER(rl);
3519             DECODE_PRINTF("\n");
3520             TRACE_AND_STEP();
3521             cmp_word(*destreg, *srcreg);
3522         }
3523         break;
3524     }
3525     DECODE_CLEAR_SEGOVR();
3526     END_OF_INSTR();
3527 }
3528 
3529 /****************************************************************************
3530 REMARKS:
3531 Handles opcode 0x3c
3532 ****************************************************************************/
3533 static void
x86emuOp_cmp_byte_AL_IMM(u8 X86EMU_UNUSED (op1))3534 x86emuOp_cmp_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
3535 {
3536     u8 srcval;
3537 
3538     START_OF_INSTR();
3539     DECODE_PRINTF("CMP\tAL,");
3540     srcval = fetch_byte_imm();
3541     DECODE_PRINTF2("%x\n", srcval);
3542     TRACE_AND_STEP();
3543     cmp_byte(M.x86.R_AL, srcval);
3544     DECODE_CLEAR_SEGOVR();
3545     END_OF_INSTR();
3546 }
3547 
3548 /****************************************************************************
3549 REMARKS:
3550 Handles opcode 0x3d
3551 ****************************************************************************/
3552 static void
x86emuOp_cmp_word_AX_IMM(u8 X86EMU_UNUSED (op1))3553 x86emuOp_cmp_word_AX_IMM(u8 X86EMU_UNUSED(op1))
3554 {
3555     u32 srcval;
3556 
3557     START_OF_INSTR();
3558     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3559         DECODE_PRINTF("CMP\tEAX,");
3560         srcval = fetch_long_imm();
3561     }
3562     else {
3563         DECODE_PRINTF("CMP\tAX,");
3564         srcval = fetch_word_imm();
3565     }
3566     DECODE_PRINTF2("%x\n", srcval);
3567     TRACE_AND_STEP();
3568     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3569         cmp_long(M.x86.R_EAX, srcval);
3570     }
3571     else {
3572         cmp_word(M.x86.R_AX, (u16) srcval);
3573     }
3574     DECODE_CLEAR_SEGOVR();
3575     END_OF_INSTR();
3576 }
3577 
3578 /****************************************************************************
3579 REMARKS:
3580 Handles opcode 0x3e
3581 ****************************************************************************/
3582 static void
x86emuOp_segovr_DS(u8 X86EMU_UNUSED (op1))3583 x86emuOp_segovr_DS(u8 X86EMU_UNUSED(op1))
3584 {
3585     START_OF_INSTR();
3586     DECODE_PRINTF("DS:\n");
3587     TRACE_AND_STEP();
3588     M.x86.mode |= SYSMODE_SEGOVR_DS;
3589     /* NO DECODE_CLEAR_SEGOVR! */
3590     END_OF_INSTR();
3591 }
3592 
3593 /****************************************************************************
3594 REMARKS:
3595 Handles opcode 0x3f
3596 ****************************************************************************/
3597 static void
x86emuOp_aas(u8 X86EMU_UNUSED (op1))3598 x86emuOp_aas(u8 X86EMU_UNUSED(op1))
3599 {
3600     START_OF_INSTR();
3601     DECODE_PRINTF("AAS\n");
3602     TRACE_AND_STEP();
3603     M.x86.R_AX = aas_word(M.x86.R_AX);
3604     DECODE_CLEAR_SEGOVR();
3605     END_OF_INSTR();
3606 }
3607 
3608 /****************************************************************************
3609 REMARKS:
3610 Handles opcode 0x40
3611 ****************************************************************************/
3612 static void
x86emuOp_inc_AX(u8 X86EMU_UNUSED (op1))3613 x86emuOp_inc_AX(u8 X86EMU_UNUSED(op1))
3614 {
3615     START_OF_INSTR();
3616     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3617         DECODE_PRINTF("INC\tEAX\n");
3618     }
3619     else {
3620         DECODE_PRINTF("INC\tAX\n");
3621     }
3622     TRACE_AND_STEP();
3623     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3624         M.x86.R_EAX = inc_long(M.x86.R_EAX);
3625     }
3626     else {
3627         M.x86.R_AX = inc_word(M.x86.R_AX);
3628     }
3629     DECODE_CLEAR_SEGOVR();
3630     END_OF_INSTR();
3631 }
3632 
3633 /****************************************************************************
3634 REMARKS:
3635 Handles opcode 0x41
3636 ****************************************************************************/
3637 static void
x86emuOp_inc_CX(u8 X86EMU_UNUSED (op1))3638 x86emuOp_inc_CX(u8 X86EMU_UNUSED(op1))
3639 {
3640     START_OF_INSTR();
3641     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3642         DECODE_PRINTF("INC\tECX\n");
3643     }
3644     else {
3645         DECODE_PRINTF("INC\tCX\n");
3646     }
3647     TRACE_AND_STEP();
3648     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3649         M.x86.R_ECX = inc_long(M.x86.R_ECX);
3650     }
3651     else {
3652         M.x86.R_CX = inc_word(M.x86.R_CX);
3653     }
3654     DECODE_CLEAR_SEGOVR();
3655     END_OF_INSTR();
3656 }
3657 
3658 /****************************************************************************
3659 REMARKS:
3660 Handles opcode 0x42
3661 ****************************************************************************/
3662 static void
x86emuOp_inc_DX(u8 X86EMU_UNUSED (op1))3663 x86emuOp_inc_DX(u8 X86EMU_UNUSED(op1))
3664 {
3665     START_OF_INSTR();
3666     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3667         DECODE_PRINTF("INC\tEDX\n");
3668     }
3669     else {
3670         DECODE_PRINTF("INC\tDX\n");
3671     }
3672     TRACE_AND_STEP();
3673     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3674         M.x86.R_EDX = inc_long(M.x86.R_EDX);
3675     }
3676     else {
3677         M.x86.R_DX = inc_word(M.x86.R_DX);
3678     }
3679     DECODE_CLEAR_SEGOVR();
3680     END_OF_INSTR();
3681 }
3682 
3683 /****************************************************************************
3684 REMARKS:
3685 Handles opcode 0x43
3686 ****************************************************************************/
3687 static void
x86emuOp_inc_BX(u8 X86EMU_UNUSED (op1))3688 x86emuOp_inc_BX(u8 X86EMU_UNUSED(op1))
3689 {
3690     START_OF_INSTR();
3691     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3692         DECODE_PRINTF("INC\tEBX\n");
3693     }
3694     else {
3695         DECODE_PRINTF("INC\tBX\n");
3696     }
3697     TRACE_AND_STEP();
3698     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3699         M.x86.R_EBX = inc_long(M.x86.R_EBX);
3700     }
3701     else {
3702         M.x86.R_BX = inc_word(M.x86.R_BX);
3703     }
3704     DECODE_CLEAR_SEGOVR();
3705     END_OF_INSTR();
3706 }
3707 
3708 /****************************************************************************
3709 REMARKS:
3710 Handles opcode 0x44
3711 ****************************************************************************/
3712 static void
x86emuOp_inc_SP(u8 X86EMU_UNUSED (op1))3713 x86emuOp_inc_SP(u8 X86EMU_UNUSED(op1))
3714 {
3715     START_OF_INSTR();
3716     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3717         DECODE_PRINTF("INC\tESP\n");
3718     }
3719     else {
3720         DECODE_PRINTF("INC\tSP\n");
3721     }
3722     TRACE_AND_STEP();
3723     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3724         M.x86.R_ESP = inc_long(M.x86.R_ESP);
3725     }
3726     else {
3727         M.x86.R_SP = inc_word(M.x86.R_SP);
3728     }
3729     DECODE_CLEAR_SEGOVR();
3730     END_OF_INSTR();
3731 }
3732 
3733 /****************************************************************************
3734 REMARKS:
3735 Handles opcode 0x45
3736 ****************************************************************************/
3737 static void
x86emuOp_inc_BP(u8 X86EMU_UNUSED (op1))3738 x86emuOp_inc_BP(u8 X86EMU_UNUSED(op1))
3739 {
3740     START_OF_INSTR();
3741     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3742         DECODE_PRINTF("INC\tEBP\n");
3743     }
3744     else {
3745         DECODE_PRINTF("INC\tBP\n");
3746     }
3747     TRACE_AND_STEP();
3748     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3749         M.x86.R_EBP = inc_long(M.x86.R_EBP);
3750     }
3751     else {
3752         M.x86.R_BP = inc_word(M.x86.R_BP);
3753     }
3754     DECODE_CLEAR_SEGOVR();
3755     END_OF_INSTR();
3756 }
3757 
3758 /****************************************************************************
3759 REMARKS:
3760 Handles opcode 0x46
3761 ****************************************************************************/
3762 static void
x86emuOp_inc_SI(u8 X86EMU_UNUSED (op1))3763 x86emuOp_inc_SI(u8 X86EMU_UNUSED(op1))
3764 {
3765     START_OF_INSTR();
3766     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3767         DECODE_PRINTF("INC\tESI\n");
3768     }
3769     else {
3770         DECODE_PRINTF("INC\tSI\n");
3771     }
3772     TRACE_AND_STEP();
3773     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3774         M.x86.R_ESI = inc_long(M.x86.R_ESI);
3775     }
3776     else {
3777         M.x86.R_SI = inc_word(M.x86.R_SI);
3778     }
3779     DECODE_CLEAR_SEGOVR();
3780     END_OF_INSTR();
3781 }
3782 
3783 /****************************************************************************
3784 REMARKS:
3785 Handles opcode 0x47
3786 ****************************************************************************/
3787 static void
x86emuOp_inc_DI(u8 X86EMU_UNUSED (op1))3788 x86emuOp_inc_DI(u8 X86EMU_UNUSED(op1))
3789 {
3790     START_OF_INSTR();
3791     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3792         DECODE_PRINTF("INC\tEDI\n");
3793     }
3794     else {
3795         DECODE_PRINTF("INC\tDI\n");
3796     }
3797     TRACE_AND_STEP();
3798     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3799         M.x86.R_EDI = inc_long(M.x86.R_EDI);
3800     }
3801     else {
3802         M.x86.R_DI = inc_word(M.x86.R_DI);
3803     }
3804     DECODE_CLEAR_SEGOVR();
3805     END_OF_INSTR();
3806 }
3807 
3808 /****************************************************************************
3809 REMARKS:
3810 Handles opcode 0x48
3811 ****************************************************************************/
3812 static void
x86emuOp_dec_AX(u8 X86EMU_UNUSED (op1))3813 x86emuOp_dec_AX(u8 X86EMU_UNUSED(op1))
3814 {
3815     START_OF_INSTR();
3816     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3817         DECODE_PRINTF("DEC\tEAX\n");
3818     }
3819     else {
3820         DECODE_PRINTF("DEC\tAX\n");
3821     }
3822     TRACE_AND_STEP();
3823     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3824         M.x86.R_EAX = dec_long(M.x86.R_EAX);
3825     }
3826     else {
3827         M.x86.R_AX = dec_word(M.x86.R_AX);
3828     }
3829     DECODE_CLEAR_SEGOVR();
3830     END_OF_INSTR();
3831 }
3832 
3833 /****************************************************************************
3834 REMARKS:
3835 Handles opcode 0x49
3836 ****************************************************************************/
3837 static void
x86emuOp_dec_CX(u8 X86EMU_UNUSED (op1))3838 x86emuOp_dec_CX(u8 X86EMU_UNUSED(op1))
3839 {
3840     START_OF_INSTR();
3841     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3842         DECODE_PRINTF("DEC\tECX\n");
3843     }
3844     else {
3845         DECODE_PRINTF("DEC\tCX\n");
3846     }
3847     TRACE_AND_STEP();
3848     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3849         M.x86.R_ECX = dec_long(M.x86.R_ECX);
3850     }
3851     else {
3852         M.x86.R_CX = dec_word(M.x86.R_CX);
3853     }
3854     DECODE_CLEAR_SEGOVR();
3855     END_OF_INSTR();
3856 }
3857 
3858 /****************************************************************************
3859 REMARKS:
3860 Handles opcode 0x4a
3861 ****************************************************************************/
3862 static void
x86emuOp_dec_DX(u8 X86EMU_UNUSED (op1))3863 x86emuOp_dec_DX(u8 X86EMU_UNUSED(op1))
3864 {
3865     START_OF_INSTR();
3866     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3867         DECODE_PRINTF("DEC\tEDX\n");
3868     }
3869     else {
3870         DECODE_PRINTF("DEC\tDX\n");
3871     }
3872     TRACE_AND_STEP();
3873     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3874         M.x86.R_EDX = dec_long(M.x86.R_EDX);
3875     }
3876     else {
3877         M.x86.R_DX = dec_word(M.x86.R_DX);
3878     }
3879     DECODE_CLEAR_SEGOVR();
3880     END_OF_INSTR();
3881 }
3882 
3883 /****************************************************************************
3884 REMARKS:
3885 Handles opcode 0x4b
3886 ****************************************************************************/
3887 static void
x86emuOp_dec_BX(u8 X86EMU_UNUSED (op1))3888 x86emuOp_dec_BX(u8 X86EMU_UNUSED(op1))
3889 {
3890     START_OF_INSTR();
3891     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3892         DECODE_PRINTF("DEC\tEBX\n");
3893     }
3894     else {
3895         DECODE_PRINTF("DEC\tBX\n");
3896     }
3897     TRACE_AND_STEP();
3898     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3899         M.x86.R_EBX = dec_long(M.x86.R_EBX);
3900     }
3901     else {
3902         M.x86.R_BX = dec_word(M.x86.R_BX);
3903     }
3904     DECODE_CLEAR_SEGOVR();
3905     END_OF_INSTR();
3906 }
3907 
3908 /****************************************************************************
3909 REMARKS:
3910 Handles opcode 0x4c
3911 ****************************************************************************/
3912 static void
x86emuOp_dec_SP(u8 X86EMU_UNUSED (op1))3913 x86emuOp_dec_SP(u8 X86EMU_UNUSED(op1))
3914 {
3915     START_OF_INSTR();
3916     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3917         DECODE_PRINTF("DEC\tESP\n");
3918     }
3919     else {
3920         DECODE_PRINTF("DEC\tSP\n");
3921     }
3922     TRACE_AND_STEP();
3923     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3924         M.x86.R_ESP = dec_long(M.x86.R_ESP);
3925     }
3926     else {
3927         M.x86.R_SP = dec_word(M.x86.R_SP);
3928     }
3929     DECODE_CLEAR_SEGOVR();
3930     END_OF_INSTR();
3931 }
3932 
3933 /****************************************************************************
3934 REMARKS:
3935 Handles opcode 0x4d
3936 ****************************************************************************/
3937 static void
x86emuOp_dec_BP(u8 X86EMU_UNUSED (op1))3938 x86emuOp_dec_BP(u8 X86EMU_UNUSED(op1))
3939 {
3940     START_OF_INSTR();
3941     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3942         DECODE_PRINTF("DEC\tEBP\n");
3943     }
3944     else {
3945         DECODE_PRINTF("DEC\tBP\n");
3946     }
3947     TRACE_AND_STEP();
3948     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3949         M.x86.R_EBP = dec_long(M.x86.R_EBP);
3950     }
3951     else {
3952         M.x86.R_BP = dec_word(M.x86.R_BP);
3953     }
3954     DECODE_CLEAR_SEGOVR();
3955     END_OF_INSTR();
3956 }
3957 
3958 /****************************************************************************
3959 REMARKS:
3960 Handles opcode 0x4e
3961 ****************************************************************************/
3962 static void
x86emuOp_dec_SI(u8 X86EMU_UNUSED (op1))3963 x86emuOp_dec_SI(u8 X86EMU_UNUSED(op1))
3964 {
3965     START_OF_INSTR();
3966     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3967         DECODE_PRINTF("DEC\tESI\n");
3968     }
3969     else {
3970         DECODE_PRINTF("DEC\tSI\n");
3971     }
3972     TRACE_AND_STEP();
3973     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3974         M.x86.R_ESI = dec_long(M.x86.R_ESI);
3975     }
3976     else {
3977         M.x86.R_SI = dec_word(M.x86.R_SI);
3978     }
3979     DECODE_CLEAR_SEGOVR();
3980     END_OF_INSTR();
3981 }
3982 
3983 /****************************************************************************
3984 REMARKS:
3985 Handles opcode 0x4f
3986 ****************************************************************************/
3987 static void
x86emuOp_dec_DI(u8 X86EMU_UNUSED (op1))3988 x86emuOp_dec_DI(u8 X86EMU_UNUSED(op1))
3989 {
3990     START_OF_INSTR();
3991     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3992         DECODE_PRINTF("DEC\tEDI\n");
3993     }
3994     else {
3995         DECODE_PRINTF("DEC\tDI\n");
3996     }
3997     TRACE_AND_STEP();
3998     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3999         M.x86.R_EDI = dec_long(M.x86.R_EDI);
4000     }
4001     else {
4002         M.x86.R_DI = dec_word(M.x86.R_DI);
4003     }
4004     DECODE_CLEAR_SEGOVR();
4005     END_OF_INSTR();
4006 }
4007 
4008 /****************************************************************************
4009 REMARKS:
4010 Handles opcode 0x50
4011 ****************************************************************************/
4012 static void
x86emuOp_push_AX(u8 X86EMU_UNUSED (op1))4013 x86emuOp_push_AX(u8 X86EMU_UNUSED(op1))
4014 {
4015     START_OF_INSTR();
4016     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4017         DECODE_PRINTF("PUSH\tEAX\n");
4018     }
4019     else {
4020         DECODE_PRINTF("PUSH\tAX\n");
4021     }
4022     TRACE_AND_STEP();
4023     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4024         push_long(M.x86.R_EAX);
4025     }
4026     else {
4027         push_word(M.x86.R_AX);
4028     }
4029     DECODE_CLEAR_SEGOVR();
4030     END_OF_INSTR();
4031 }
4032 
4033 /****************************************************************************
4034 REMARKS:
4035 Handles opcode 0x51
4036 ****************************************************************************/
4037 static void
x86emuOp_push_CX(u8 X86EMU_UNUSED (op1))4038 x86emuOp_push_CX(u8 X86EMU_UNUSED(op1))
4039 {
4040     START_OF_INSTR();
4041     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4042         DECODE_PRINTF("PUSH\tECX\n");
4043     }
4044     else {
4045         DECODE_PRINTF("PUSH\tCX\n");
4046     }
4047     TRACE_AND_STEP();
4048     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4049         push_long(M.x86.R_ECX);
4050     }
4051     else {
4052         push_word(M.x86.R_CX);
4053     }
4054     DECODE_CLEAR_SEGOVR();
4055     END_OF_INSTR();
4056 }
4057 
4058 /****************************************************************************
4059 REMARKS:
4060 Handles opcode 0x52
4061 ****************************************************************************/
4062 static void
x86emuOp_push_DX(u8 X86EMU_UNUSED (op1))4063 x86emuOp_push_DX(u8 X86EMU_UNUSED(op1))
4064 {
4065     START_OF_INSTR();
4066     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4067         DECODE_PRINTF("PUSH\tEDX\n");
4068     }
4069     else {
4070         DECODE_PRINTF("PUSH\tDX\n");
4071     }
4072     TRACE_AND_STEP();
4073     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4074         push_long(M.x86.R_EDX);
4075     }
4076     else {
4077         push_word(M.x86.R_DX);
4078     }
4079     DECODE_CLEAR_SEGOVR();
4080     END_OF_INSTR();
4081 }
4082 
4083 /****************************************************************************
4084 REMARKS:
4085 Handles opcode 0x53
4086 ****************************************************************************/
4087 static void
x86emuOp_push_BX(u8 X86EMU_UNUSED (op1))4088 x86emuOp_push_BX(u8 X86EMU_UNUSED(op1))
4089 {
4090     START_OF_INSTR();
4091     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4092         DECODE_PRINTF("PUSH\tEBX\n");
4093     }
4094     else {
4095         DECODE_PRINTF("PUSH\tBX\n");
4096     }
4097     TRACE_AND_STEP();
4098     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4099         push_long(M.x86.R_EBX);
4100     }
4101     else {
4102         push_word(M.x86.R_BX);
4103     }
4104     DECODE_CLEAR_SEGOVR();
4105     END_OF_INSTR();
4106 }
4107 
4108 /****************************************************************************
4109 REMARKS:
4110 Handles opcode 0x54
4111 ****************************************************************************/
4112 static void
x86emuOp_push_SP(u8 X86EMU_UNUSED (op1))4113 x86emuOp_push_SP(u8 X86EMU_UNUSED(op1))
4114 {
4115     START_OF_INSTR();
4116     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4117         DECODE_PRINTF("PUSH\tESP\n");
4118     }
4119     else {
4120         DECODE_PRINTF("PUSH\tSP\n");
4121     }
4122     TRACE_AND_STEP();
4123     /* Always push (E)SP, since we are emulating an i386 and above
4124      * processor. This is necessary as some BIOS'es use this to check
4125      * what type of processor is in the system.
4126      */
4127     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4128         push_long(M.x86.R_ESP);
4129     }
4130     else {
4131         push_word((u16) (M.x86.R_SP));
4132     }
4133     DECODE_CLEAR_SEGOVR();
4134     END_OF_INSTR();
4135 }
4136 
4137 /****************************************************************************
4138 REMARKS:
4139 Handles opcode 0x55
4140 ****************************************************************************/
4141 static void
x86emuOp_push_BP(u8 X86EMU_UNUSED (op1))4142 x86emuOp_push_BP(u8 X86EMU_UNUSED(op1))
4143 {
4144     START_OF_INSTR();
4145     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4146         DECODE_PRINTF("PUSH\tEBP\n");
4147     }
4148     else {
4149         DECODE_PRINTF("PUSH\tBP\n");
4150     }
4151     TRACE_AND_STEP();
4152     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4153         push_long(M.x86.R_EBP);
4154     }
4155     else {
4156         push_word(M.x86.R_BP);
4157     }
4158     DECODE_CLEAR_SEGOVR();
4159     END_OF_INSTR();
4160 }
4161 
4162 /****************************************************************************
4163 REMARKS:
4164 Handles opcode 0x56
4165 ****************************************************************************/
4166 static void
x86emuOp_push_SI(u8 X86EMU_UNUSED (op1))4167 x86emuOp_push_SI(u8 X86EMU_UNUSED(op1))
4168 {
4169     START_OF_INSTR();
4170     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4171         DECODE_PRINTF("PUSH\tESI\n");
4172     }
4173     else {
4174         DECODE_PRINTF("PUSH\tSI\n");
4175     }
4176     TRACE_AND_STEP();
4177     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4178         push_long(M.x86.R_ESI);
4179     }
4180     else {
4181         push_word(M.x86.R_SI);
4182     }
4183     DECODE_CLEAR_SEGOVR();
4184     END_OF_INSTR();
4185 }
4186 
4187 /****************************************************************************
4188 REMARKS:
4189 Handles opcode 0x57
4190 ****************************************************************************/
4191 static void
x86emuOp_push_DI(u8 X86EMU_UNUSED (op1))4192 x86emuOp_push_DI(u8 X86EMU_UNUSED(op1))
4193 {
4194     START_OF_INSTR();
4195     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4196         DECODE_PRINTF("PUSH\tEDI\n");
4197     }
4198     else {
4199         DECODE_PRINTF("PUSH\tDI\n");
4200     }
4201     TRACE_AND_STEP();
4202     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4203         push_long(M.x86.R_EDI);
4204     }
4205     else {
4206         push_word(M.x86.R_DI);
4207     }
4208     DECODE_CLEAR_SEGOVR();
4209     END_OF_INSTR();
4210 }
4211 
4212 /****************************************************************************
4213 REMARKS:
4214 Handles opcode 0x58
4215 ****************************************************************************/
4216 static void
x86emuOp_pop_AX(u8 X86EMU_UNUSED (op1))4217 x86emuOp_pop_AX(u8 X86EMU_UNUSED(op1))
4218 {
4219     START_OF_INSTR();
4220     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4221         DECODE_PRINTF("POP\tEAX\n");
4222     }
4223     else {
4224         DECODE_PRINTF("POP\tAX\n");
4225     }
4226     TRACE_AND_STEP();
4227     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4228         M.x86.R_EAX = pop_long();
4229     }
4230     else {
4231         M.x86.R_AX = pop_word();
4232     }
4233     DECODE_CLEAR_SEGOVR();
4234     END_OF_INSTR();
4235 }
4236 
4237 /****************************************************************************
4238 REMARKS:
4239 Handles opcode 0x59
4240 ****************************************************************************/
4241 static void
x86emuOp_pop_CX(u8 X86EMU_UNUSED (op1))4242 x86emuOp_pop_CX(u8 X86EMU_UNUSED(op1))
4243 {
4244     START_OF_INSTR();
4245     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4246         DECODE_PRINTF("POP\tECX\n");
4247     }
4248     else {
4249         DECODE_PRINTF("POP\tCX\n");
4250     }
4251     TRACE_AND_STEP();
4252     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4253         M.x86.R_ECX = pop_long();
4254     }
4255     else {
4256         M.x86.R_CX = pop_word();
4257     }
4258     DECODE_CLEAR_SEGOVR();
4259     END_OF_INSTR();
4260 }
4261 
4262 /****************************************************************************
4263 REMARKS:
4264 Handles opcode 0x5a
4265 ****************************************************************************/
4266 static void
x86emuOp_pop_DX(u8 X86EMU_UNUSED (op1))4267 x86emuOp_pop_DX(u8 X86EMU_UNUSED(op1))
4268 {
4269     START_OF_INSTR();
4270     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4271         DECODE_PRINTF("POP\tEDX\n");
4272     }
4273     else {
4274         DECODE_PRINTF("POP\tDX\n");
4275     }
4276     TRACE_AND_STEP();
4277     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4278         M.x86.R_EDX = pop_long();
4279     }
4280     else {
4281         M.x86.R_DX = pop_word();
4282     }
4283     DECODE_CLEAR_SEGOVR();
4284     END_OF_INSTR();
4285 }
4286 
4287 /****************************************************************************
4288 REMARKS:
4289 Handles opcode 0x5b
4290 ****************************************************************************/
4291 static void
x86emuOp_pop_BX(u8 X86EMU_UNUSED (op1))4292 x86emuOp_pop_BX(u8 X86EMU_UNUSED(op1))
4293 {
4294     START_OF_INSTR();
4295     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4296         DECODE_PRINTF("POP\tEBX\n");
4297     }
4298     else {
4299         DECODE_PRINTF("POP\tBX\n");
4300     }
4301     TRACE_AND_STEP();
4302     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4303         M.x86.R_EBX = pop_long();
4304     }
4305     else {
4306         M.x86.R_BX = pop_word();
4307     }
4308     DECODE_CLEAR_SEGOVR();
4309     END_OF_INSTR();
4310 }
4311 
4312 /****************************************************************************
4313 REMARKS:
4314 Handles opcode 0x5c
4315 ****************************************************************************/
4316 static void
x86emuOp_pop_SP(u8 X86EMU_UNUSED (op1))4317 x86emuOp_pop_SP(u8 X86EMU_UNUSED(op1))
4318 {
4319     START_OF_INSTR();
4320     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4321         DECODE_PRINTF("POP\tESP\n");
4322     }
4323     else {
4324         DECODE_PRINTF("POP\tSP\n");
4325     }
4326     TRACE_AND_STEP();
4327     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4328         M.x86.R_ESP = pop_long();
4329     }
4330     else {
4331         M.x86.R_SP = pop_word();
4332     }
4333     DECODE_CLEAR_SEGOVR();
4334     END_OF_INSTR();
4335 }
4336 
4337 /****************************************************************************
4338 REMARKS:
4339 Handles opcode 0x5d
4340 ****************************************************************************/
4341 static void
x86emuOp_pop_BP(u8 X86EMU_UNUSED (op1))4342 x86emuOp_pop_BP(u8 X86EMU_UNUSED(op1))
4343 {
4344     START_OF_INSTR();
4345     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4346         DECODE_PRINTF("POP\tEBP\n");
4347     }
4348     else {
4349         DECODE_PRINTF("POP\tBP\n");
4350     }
4351     TRACE_AND_STEP();
4352     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4353         M.x86.R_EBP = pop_long();
4354     }
4355     else {
4356         M.x86.R_BP = pop_word();
4357     }
4358     DECODE_CLEAR_SEGOVR();
4359     END_OF_INSTR();
4360 }
4361 
4362 /****************************************************************************
4363 REMARKS:
4364 Handles opcode 0x5e
4365 ****************************************************************************/
4366 static void
x86emuOp_pop_SI(u8 X86EMU_UNUSED (op1))4367 x86emuOp_pop_SI(u8 X86EMU_UNUSED(op1))
4368 {
4369     START_OF_INSTR();
4370     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4371         DECODE_PRINTF("POP\tESI\n");
4372     }
4373     else {
4374         DECODE_PRINTF("POP\tSI\n");
4375     }
4376     TRACE_AND_STEP();
4377     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4378         M.x86.R_ESI = pop_long();
4379     }
4380     else {
4381         M.x86.R_SI = pop_word();
4382     }
4383     DECODE_CLEAR_SEGOVR();
4384     END_OF_INSTR();
4385 }
4386 
4387 /****************************************************************************
4388 REMARKS:
4389 Handles opcode 0x5f
4390 ****************************************************************************/
4391 static void
x86emuOp_pop_DI(u8 X86EMU_UNUSED (op1))4392 x86emuOp_pop_DI(u8 X86EMU_UNUSED(op1))
4393 {
4394     START_OF_INSTR();
4395     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4396         DECODE_PRINTF("POP\tEDI\n");
4397     }
4398     else {
4399         DECODE_PRINTF("POP\tDI\n");
4400     }
4401     TRACE_AND_STEP();
4402     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4403         M.x86.R_EDI = pop_long();
4404     }
4405     else {
4406         M.x86.R_DI = pop_word();
4407     }
4408     DECODE_CLEAR_SEGOVR();
4409     END_OF_INSTR();
4410 }
4411 
4412 /****************************************************************************
4413 REMARKS:
4414 Handles opcode 0x60
4415 ****************************************************************************/
4416 static void
x86emuOp_push_all(u8 X86EMU_UNUSED (op1))4417 x86emuOp_push_all(u8 X86EMU_UNUSED(op1))
4418 {
4419     START_OF_INSTR();
4420     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4421         DECODE_PRINTF("PUSHAD\n");
4422     }
4423     else {
4424         DECODE_PRINTF("PUSHA\n");
4425     }
4426     TRACE_AND_STEP();
4427     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4428         u32 old_sp = M.x86.R_ESP;
4429 
4430         push_long(M.x86.R_EAX);
4431         push_long(M.x86.R_ECX);
4432         push_long(M.x86.R_EDX);
4433         push_long(M.x86.R_EBX);
4434         push_long(old_sp);
4435         push_long(M.x86.R_EBP);
4436         push_long(M.x86.R_ESI);
4437         push_long(M.x86.R_EDI);
4438     }
4439     else {
4440         u16 old_sp = M.x86.R_SP;
4441 
4442         push_word(M.x86.R_AX);
4443         push_word(M.x86.R_CX);
4444         push_word(M.x86.R_DX);
4445         push_word(M.x86.R_BX);
4446         push_word(old_sp);
4447         push_word(M.x86.R_BP);
4448         push_word(M.x86.R_SI);
4449         push_word(M.x86.R_DI);
4450     }
4451     DECODE_CLEAR_SEGOVR();
4452     END_OF_INSTR();
4453 }
4454 
4455 /****************************************************************************
4456 REMARKS:
4457 Handles opcode 0x61
4458 ****************************************************************************/
4459 static void
x86emuOp_pop_all(u8 X86EMU_UNUSED (op1))4460 x86emuOp_pop_all(u8 X86EMU_UNUSED(op1))
4461 {
4462     START_OF_INSTR();
4463     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4464         DECODE_PRINTF("POPAD\n");
4465     }
4466     else {
4467         DECODE_PRINTF("POPA\n");
4468     }
4469     TRACE_AND_STEP();
4470     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4471         M.x86.R_EDI = pop_long();
4472         M.x86.R_ESI = pop_long();
4473         M.x86.R_EBP = pop_long();
4474         M.x86.R_ESP += 4;       /* skip ESP */
4475         M.x86.R_EBX = pop_long();
4476         M.x86.R_EDX = pop_long();
4477         M.x86.R_ECX = pop_long();
4478         M.x86.R_EAX = pop_long();
4479     }
4480     else {
4481         M.x86.R_DI = pop_word();
4482         M.x86.R_SI = pop_word();
4483         M.x86.R_BP = pop_word();
4484         M.x86.R_SP += 2;        /* skip SP */
4485         M.x86.R_BX = pop_word();
4486         M.x86.R_DX = pop_word();
4487         M.x86.R_CX = pop_word();
4488         M.x86.R_AX = pop_word();
4489     }
4490     DECODE_CLEAR_SEGOVR();
4491     END_OF_INSTR();
4492 }
4493 
4494 /*opcode 0x62   ILLEGAL OP, calls x86emuOp_illegal_op() */
4495 /*opcode 0x63   ILLEGAL OP, calls x86emuOp_illegal_op() */
4496 
4497 /****************************************************************************
4498 REMARKS:
4499 Handles opcode 0x64
4500 ****************************************************************************/
4501 static void
x86emuOp_segovr_FS(u8 X86EMU_UNUSED (op1))4502 x86emuOp_segovr_FS(u8 X86EMU_UNUSED(op1))
4503 {
4504     START_OF_INSTR();
4505     DECODE_PRINTF("FS:\n");
4506     TRACE_AND_STEP();
4507     M.x86.mode |= SYSMODE_SEGOVR_FS;
4508     /*
4509      * note the lack of DECODE_CLEAR_SEGOVR(r) since, here is one of 4
4510      * opcode subroutines we do not want to do this.
4511      */
4512     END_OF_INSTR();
4513 }
4514 
4515 /****************************************************************************
4516 REMARKS:
4517 Handles opcode 0x65
4518 ****************************************************************************/
4519 static void
x86emuOp_segovr_GS(u8 X86EMU_UNUSED (op1))4520 x86emuOp_segovr_GS(u8 X86EMU_UNUSED(op1))
4521 {
4522     START_OF_INSTR();
4523     DECODE_PRINTF("GS:\n");
4524     TRACE_AND_STEP();
4525     M.x86.mode |= SYSMODE_SEGOVR_GS;
4526     /*
4527      * note the lack of DECODE_CLEAR_SEGOVR(r) since, here is one of 4
4528      * opcode subroutines we do not want to do this.
4529      */
4530     END_OF_INSTR();
4531 }
4532 
4533 /****************************************************************************
4534 REMARKS:
4535 Handles opcode 0x66 - prefix for 32-bit register
4536 ****************************************************************************/
4537 static void
x86emuOp_prefix_data(u8 X86EMU_UNUSED (op1))4538 x86emuOp_prefix_data(u8 X86EMU_UNUSED(op1))
4539 {
4540     START_OF_INSTR();
4541     DECODE_PRINTF("DATA:\n");
4542     TRACE_AND_STEP();
4543     M.x86.mode |= SYSMODE_PREFIX_DATA;
4544     /* note no DECODE_CLEAR_SEGOVR here. */
4545     END_OF_INSTR();
4546 }
4547 
4548 /****************************************************************************
4549 REMARKS:
4550 Handles opcode 0x67 - prefix for 32-bit address
4551 ****************************************************************************/
4552 static void
x86emuOp_prefix_addr(u8 X86EMU_UNUSED (op1))4553 x86emuOp_prefix_addr(u8 X86EMU_UNUSED(op1))
4554 {
4555     START_OF_INSTR();
4556     DECODE_PRINTF("ADDR:\n");
4557     TRACE_AND_STEP();
4558     M.x86.mode |= SYSMODE_PREFIX_ADDR;
4559     /* note no DECODE_CLEAR_SEGOVR here. */
4560     END_OF_INSTR();
4561 }
4562 
4563 /****************************************************************************
4564 REMARKS:
4565 Handles opcode 0x68
4566 ****************************************************************************/
4567 static void
x86emuOp_push_word_IMM(u8 X86EMU_UNUSED (op1))4568 x86emuOp_push_word_IMM(u8 X86EMU_UNUSED(op1))
4569 {
4570     u32 imm;
4571 
4572     START_OF_INSTR();
4573     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4574         imm = fetch_long_imm();
4575     }
4576     else {
4577         imm = fetch_word_imm();
4578     }
4579     DECODE_PRINTF2("PUSH\t%x\n", imm);
4580     TRACE_AND_STEP();
4581     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4582         push_long(imm);
4583     }
4584     else {
4585         push_word((u16) imm);
4586     }
4587     DECODE_CLEAR_SEGOVR();
4588     END_OF_INSTR();
4589 }
4590 
4591 /****************************************************************************
4592 REMARKS:
4593 Handles opcode 0x69
4594 ****************************************************************************/
4595 static void
x86emuOp_imul_word_IMM(u8 X86EMU_UNUSED (op1))4596 x86emuOp_imul_word_IMM(u8 X86EMU_UNUSED(op1))
4597 {
4598     int mod, rl, rh;
4599     uint srcoffset;
4600 
4601     START_OF_INSTR();
4602     DECODE_PRINTF("IMUL\t");
4603     FETCH_DECODE_MODRM(mod, rh, rl);
4604     switch (mod) {
4605     case 0:
4606         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4607             u32 *destreg;
4608             u32 srcval;
4609             u32 res_lo, res_hi;
4610             s32 imm;
4611 
4612             destreg = DECODE_RM_LONG_REGISTER(rh);
4613             DECODE_PRINTF(",");
4614             srcoffset = decode_rm00_address(rl);
4615             srcval = fetch_data_long(srcoffset);
4616             imm = fetch_long_imm();
4617             DECODE_PRINTF2(",%d\n", (s32) imm);
4618             TRACE_AND_STEP();
4619             imul_long_direct(&res_lo, &res_hi, (s32) srcval, (s32) imm);
4620             if (res_hi != 0) {
4621                 SET_FLAG(F_CF);
4622                 SET_FLAG(F_OF);
4623             }
4624             else {
4625                 CLEAR_FLAG(F_CF);
4626                 CLEAR_FLAG(F_OF);
4627             }
4628             *destreg = (u32) res_lo;
4629         }
4630         else {
4631             u16 *destreg;
4632             u16 srcval;
4633             u32 res;
4634             s16 imm;
4635 
4636             destreg = DECODE_RM_WORD_REGISTER(rh);
4637             DECODE_PRINTF(",");
4638             srcoffset = decode_rm00_address(rl);
4639             srcval = fetch_data_word(srcoffset);
4640             imm = fetch_word_imm();
4641             DECODE_PRINTF2(",%d\n", (s32) imm);
4642             TRACE_AND_STEP();
4643             res = (s16) srcval *(s16) imm;
4644 
4645             if (res > 0xFFFF) {
4646                 SET_FLAG(F_CF);
4647                 SET_FLAG(F_OF);
4648             }
4649             else {
4650                 CLEAR_FLAG(F_CF);
4651                 CLEAR_FLAG(F_OF);
4652             }
4653             *destreg = (u16) res;
4654         }
4655         break;
4656     case 1:
4657         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4658             u32 *destreg;
4659             u32 srcval;
4660             u32 res_lo, res_hi;
4661             s32 imm;
4662 
4663             destreg = DECODE_RM_LONG_REGISTER(rh);
4664             DECODE_PRINTF(",");
4665             srcoffset = decode_rm01_address(rl);
4666             srcval = fetch_data_long(srcoffset);
4667             imm = fetch_long_imm();
4668             DECODE_PRINTF2(",%d\n", (s32) imm);
4669             TRACE_AND_STEP();
4670             imul_long_direct(&res_lo, &res_hi, (s32) srcval, (s32) imm);
4671             if (res_hi != 0) {
4672                 SET_FLAG(F_CF);
4673                 SET_FLAG(F_OF);
4674             }
4675             else {
4676                 CLEAR_FLAG(F_CF);
4677                 CLEAR_FLAG(F_OF);
4678             }
4679             *destreg = (u32) res_lo;
4680         }
4681         else {
4682             u16 *destreg;
4683             u16 srcval;
4684             u32 res;
4685             s16 imm;
4686 
4687             destreg = DECODE_RM_WORD_REGISTER(rh);
4688             DECODE_PRINTF(",");
4689             srcoffset = decode_rm01_address(rl);
4690             srcval = fetch_data_word(srcoffset);
4691             imm = fetch_word_imm();
4692             DECODE_PRINTF2(",%d\n", (s32) imm);
4693             TRACE_AND_STEP();
4694             res = (s16) srcval *(s16) imm;
4695 
4696             if (res > 0xFFFF) {
4697                 SET_FLAG(F_CF);
4698                 SET_FLAG(F_OF);
4699             }
4700             else {
4701                 CLEAR_FLAG(F_CF);
4702                 CLEAR_FLAG(F_OF);
4703             }
4704             *destreg = (u16) res;
4705         }
4706         break;
4707     case 2:
4708         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4709             u32 *destreg;
4710             u32 srcval;
4711             u32 res_lo, res_hi;
4712             s32 imm;
4713 
4714             destreg = DECODE_RM_LONG_REGISTER(rh);
4715             DECODE_PRINTF(",");
4716             srcoffset = decode_rm10_address(rl);
4717             srcval = fetch_data_long(srcoffset);
4718             imm = fetch_long_imm();
4719             DECODE_PRINTF2(",%d\n", (s32) imm);
4720             TRACE_AND_STEP();
4721             imul_long_direct(&res_lo, &res_hi, (s32) srcval, (s32) imm);
4722             if (res_hi != 0) {
4723                 SET_FLAG(F_CF);
4724                 SET_FLAG(F_OF);
4725             }
4726             else {
4727                 CLEAR_FLAG(F_CF);
4728                 CLEAR_FLAG(F_OF);
4729             }
4730             *destreg = (u32) res_lo;
4731         }
4732         else {
4733             u16 *destreg;
4734             u16 srcval;
4735             u32 res;
4736             s16 imm;
4737 
4738             destreg = DECODE_RM_WORD_REGISTER(rh);
4739             DECODE_PRINTF(",");
4740             srcoffset = decode_rm10_address(rl);
4741             srcval = fetch_data_word(srcoffset);
4742             imm = fetch_word_imm();
4743             DECODE_PRINTF2(",%d\n", (s32) imm);
4744             TRACE_AND_STEP();
4745             res = (s16) srcval *(s16) imm;
4746 
4747             if (res > 0xFFFF) {
4748                 SET_FLAG(F_CF);
4749                 SET_FLAG(F_OF);
4750             }
4751             else {
4752                 CLEAR_FLAG(F_CF);
4753                 CLEAR_FLAG(F_OF);
4754             }
4755             *destreg = (u16) res;
4756         }
4757         break;
4758     case 3:                    /* register to register */
4759         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4760             u32 *destreg, *srcreg;
4761             u32 res_lo, res_hi;
4762             s32 imm;
4763 
4764             destreg = DECODE_RM_LONG_REGISTER(rh);
4765             DECODE_PRINTF(",");
4766             srcreg = DECODE_RM_LONG_REGISTER(rl);
4767             imm = fetch_long_imm();
4768             DECODE_PRINTF2(",%d\n", (s32) imm);
4769             TRACE_AND_STEP();
4770             imul_long_direct(&res_lo, &res_hi, (s32) * srcreg, (s32) imm);
4771             if (res_hi != 0) {
4772                 SET_FLAG(F_CF);
4773                 SET_FLAG(F_OF);
4774             }
4775             else {
4776                 CLEAR_FLAG(F_CF);
4777                 CLEAR_FLAG(F_OF);
4778             }
4779             *destreg = (u32) res_lo;
4780         }
4781         else {
4782             u16 *destreg, *srcreg;
4783             u32 res;
4784             s16 imm;
4785 
4786             destreg = DECODE_RM_WORD_REGISTER(rh);
4787             DECODE_PRINTF(",");
4788             srcreg = DECODE_RM_WORD_REGISTER(rl);
4789             imm = fetch_word_imm();
4790             DECODE_PRINTF2(",%d\n", (s32) imm);
4791             res = (s16) * srcreg * (s16) imm;
4792             if (res > 0xFFFF) {
4793                 SET_FLAG(F_CF);
4794                 SET_FLAG(F_OF);
4795             }
4796             else {
4797                 CLEAR_FLAG(F_CF);
4798                 CLEAR_FLAG(F_OF);
4799             }
4800             *destreg = (u16) res;
4801         }
4802         break;
4803     }
4804     DECODE_CLEAR_SEGOVR();
4805     END_OF_INSTR();
4806 }
4807 
4808 /****************************************************************************
4809 REMARKS:
4810 Handles opcode 0x6a
4811 ****************************************************************************/
4812 static void
x86emuOp_push_byte_IMM(u8 X86EMU_UNUSED (op1))4813 x86emuOp_push_byte_IMM(u8 X86EMU_UNUSED(op1))
4814 {
4815     s16 imm;
4816 
4817     START_OF_INSTR();
4818     imm = (s8) fetch_byte_imm();
4819     DECODE_PRINTF2("PUSH\t%d\n", imm);
4820     TRACE_AND_STEP();
4821     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4822         push_long((s32) imm);
4823     }
4824     else {
4825         push_word(imm);
4826     }
4827     DECODE_CLEAR_SEGOVR();
4828     END_OF_INSTR();
4829 }
4830 
4831 /****************************************************************************
4832 REMARKS:
4833 Handles opcode 0x6b
4834 ****************************************************************************/
4835 static void
x86emuOp_imul_byte_IMM(u8 X86EMU_UNUSED (op1))4836 x86emuOp_imul_byte_IMM(u8 X86EMU_UNUSED(op1))
4837 {
4838     int mod, rl, rh;
4839     uint srcoffset;
4840     s8 imm;
4841 
4842     START_OF_INSTR();
4843     DECODE_PRINTF("IMUL\t");
4844     FETCH_DECODE_MODRM(mod, rh, rl);
4845     switch (mod) {
4846     case 0:
4847         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4848             u32 *destreg;
4849             u32 srcval;
4850             u32 res_lo, res_hi;
4851 
4852             destreg = DECODE_RM_LONG_REGISTER(rh);
4853             DECODE_PRINTF(",");
4854             srcoffset = decode_rm00_address(rl);
4855             srcval = fetch_data_long(srcoffset);
4856             imm = fetch_byte_imm();
4857             DECODE_PRINTF2(",%d\n", (s32) imm);
4858             TRACE_AND_STEP();
4859             imul_long_direct(&res_lo, &res_hi, (s32) srcval, (s32) imm);
4860             if (res_hi != 0) {
4861                 SET_FLAG(F_CF);
4862                 SET_FLAG(F_OF);
4863             }
4864             else {
4865                 CLEAR_FLAG(F_CF);
4866                 CLEAR_FLAG(F_OF);
4867             }
4868             *destreg = (u32) res_lo;
4869         }
4870         else {
4871             u16 *destreg;
4872             u16 srcval;
4873             u32 res;
4874 
4875             destreg = DECODE_RM_WORD_REGISTER(rh);
4876             DECODE_PRINTF(",");
4877             srcoffset = decode_rm00_address(rl);
4878             srcval = fetch_data_word(srcoffset);
4879             imm = fetch_byte_imm();
4880             DECODE_PRINTF2(",%d\n", (s32) imm);
4881             TRACE_AND_STEP();
4882             res = (s16) srcval *(s16) imm;
4883 
4884             if (res > 0xFFFF) {
4885                 SET_FLAG(F_CF);
4886                 SET_FLAG(F_OF);
4887             }
4888             else {
4889                 CLEAR_FLAG(F_CF);
4890                 CLEAR_FLAG(F_OF);
4891             }
4892             *destreg = (u16) res;
4893         }
4894         break;
4895     case 1:
4896         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4897             u32 *destreg;
4898             u32 srcval;
4899             u32 res_lo, res_hi;
4900 
4901             destreg = DECODE_RM_LONG_REGISTER(rh);
4902             DECODE_PRINTF(",");
4903             srcoffset = decode_rm01_address(rl);
4904             srcval = fetch_data_long(srcoffset);
4905             imm = fetch_byte_imm();
4906             DECODE_PRINTF2(",%d\n", (s32) imm);
4907             TRACE_AND_STEP();
4908             imul_long_direct(&res_lo, &res_hi, (s32) srcval, (s32) imm);
4909             if (res_hi != 0) {
4910                 SET_FLAG(F_CF);
4911                 SET_FLAG(F_OF);
4912             }
4913             else {
4914                 CLEAR_FLAG(F_CF);
4915                 CLEAR_FLAG(F_OF);
4916             }
4917             *destreg = (u32) res_lo;
4918         }
4919         else {
4920             u16 *destreg;
4921             u16 srcval;
4922             u32 res;
4923 
4924             destreg = DECODE_RM_WORD_REGISTER(rh);
4925             DECODE_PRINTF(",");
4926             srcoffset = decode_rm01_address(rl);
4927             srcval = fetch_data_word(srcoffset);
4928             imm = fetch_byte_imm();
4929             DECODE_PRINTF2(",%d\n", (s32) imm);
4930             TRACE_AND_STEP();
4931             res = (s16) srcval *(s16) imm;
4932 
4933             if (res > 0xFFFF) {
4934                 SET_FLAG(F_CF);
4935                 SET_FLAG(F_OF);
4936             }
4937             else {
4938                 CLEAR_FLAG(F_CF);
4939                 CLEAR_FLAG(F_OF);
4940             }
4941             *destreg = (u16) res;
4942         }
4943         break;
4944     case 2:
4945         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4946             u32 *destreg;
4947             u32 srcval;
4948             u32 res_lo, res_hi;
4949 
4950             destreg = DECODE_RM_LONG_REGISTER(rh);
4951             DECODE_PRINTF(",");
4952             srcoffset = decode_rm10_address(rl);
4953             srcval = fetch_data_long(srcoffset);
4954             imm = fetch_byte_imm();
4955             DECODE_PRINTF2(",%d\n", (s32) imm);
4956             TRACE_AND_STEP();
4957             imul_long_direct(&res_lo, &res_hi, (s32) srcval, (s32) imm);
4958             if (res_hi != 0) {
4959                 SET_FLAG(F_CF);
4960                 SET_FLAG(F_OF);
4961             }
4962             else {
4963                 CLEAR_FLAG(F_CF);
4964                 CLEAR_FLAG(F_OF);
4965             }
4966             *destreg = (u32) res_lo;
4967         }
4968         else {
4969             u16 *destreg;
4970             u16 srcval;
4971             u32 res;
4972 
4973             destreg = DECODE_RM_WORD_REGISTER(rh);
4974             DECODE_PRINTF(",");
4975             srcoffset = decode_rm10_address(rl);
4976             srcval = fetch_data_word(srcoffset);
4977             imm = fetch_byte_imm();
4978             DECODE_PRINTF2(",%d\n", (s32) imm);
4979             TRACE_AND_STEP();
4980             res = (s16) srcval *(s16) imm;
4981 
4982             if (res > 0xFFFF) {
4983                 SET_FLAG(F_CF);
4984                 SET_FLAG(F_OF);
4985             }
4986             else {
4987                 CLEAR_FLAG(F_CF);
4988                 CLEAR_FLAG(F_OF);
4989             }
4990             *destreg = (u16) res;
4991         }
4992         break;
4993     case 3:                    /* register to register */
4994         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4995             u32 *destreg, *srcreg;
4996             u32 res_lo, res_hi;
4997 
4998             destreg = DECODE_RM_LONG_REGISTER(rh);
4999             DECODE_PRINTF(",");
5000             srcreg = DECODE_RM_LONG_REGISTER(rl);
5001             imm = fetch_byte_imm();
5002             DECODE_PRINTF2(",%d\n", (s32) imm);
5003             TRACE_AND_STEP();
5004             imul_long_direct(&res_lo, &res_hi, (s32) * srcreg, (s32) imm);
5005             if (res_hi != 0) {
5006                 SET_FLAG(F_CF);
5007                 SET_FLAG(F_OF);
5008             }
5009             else {
5010                 CLEAR_FLAG(F_CF);
5011                 CLEAR_FLAG(F_OF);
5012             }
5013             *destreg = (u32) res_lo;
5014         }
5015         else {
5016             u16 *destreg, *srcreg;
5017             u32 res;
5018 
5019             destreg = DECODE_RM_WORD_REGISTER(rh);
5020             DECODE_PRINTF(",");
5021             srcreg = DECODE_RM_WORD_REGISTER(rl);
5022             imm = fetch_byte_imm();
5023             DECODE_PRINTF2(",%d\n", (s32) imm);
5024             res = (s16) * srcreg * (s16) imm;
5025             if (res > 0xFFFF) {
5026                 SET_FLAG(F_CF);
5027                 SET_FLAG(F_OF);
5028             }
5029             else {
5030                 CLEAR_FLAG(F_CF);
5031                 CLEAR_FLAG(F_OF);
5032             }
5033             *destreg = (u16) res;
5034         }
5035         break;
5036     }
5037     DECODE_CLEAR_SEGOVR();
5038     END_OF_INSTR();
5039 }
5040 
5041 /****************************************************************************
5042 REMARKS:
5043 Handles opcode 0x6c
5044 ****************************************************************************/
5045 static void
x86emuOp_ins_byte(u8 X86EMU_UNUSED (op1))5046 x86emuOp_ins_byte(u8 X86EMU_UNUSED(op1))
5047 {
5048     START_OF_INSTR();
5049     DECODE_PRINTF("INSB\n");
5050     ins(1);
5051     TRACE_AND_STEP();
5052     DECODE_CLEAR_SEGOVR();
5053     END_OF_INSTR();
5054 }
5055 
5056 /****************************************************************************
5057 REMARKS:
5058 Handles opcode 0x6d
5059 ****************************************************************************/
5060 static void
x86emuOp_ins_word(u8 X86EMU_UNUSED (op1))5061 x86emuOp_ins_word(u8 X86EMU_UNUSED(op1))
5062 {
5063     START_OF_INSTR();
5064     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5065         DECODE_PRINTF("INSD\n");
5066         ins(4);
5067     }
5068     else {
5069         DECODE_PRINTF("INSW\n");
5070         ins(2);
5071     }
5072     TRACE_AND_STEP();
5073     DECODE_CLEAR_SEGOVR();
5074     END_OF_INSTR();
5075 }
5076 
5077 /****************************************************************************
5078 REMARKS:
5079 Handles opcode 0x6e
5080 ****************************************************************************/
5081 static void
x86emuOp_outs_byte(u8 X86EMU_UNUSED (op1))5082 x86emuOp_outs_byte(u8 X86EMU_UNUSED(op1))
5083 {
5084     START_OF_INSTR();
5085     DECODE_PRINTF("OUTSB\n");
5086     outs(1);
5087     TRACE_AND_STEP();
5088     DECODE_CLEAR_SEGOVR();
5089     END_OF_INSTR();
5090 }
5091 
5092 /****************************************************************************
5093 REMARKS:
5094 Handles opcode 0x6f
5095 ****************************************************************************/
5096 static void
x86emuOp_outs_word(u8 X86EMU_UNUSED (op1))5097 x86emuOp_outs_word(u8 X86EMU_UNUSED(op1))
5098 {
5099     START_OF_INSTR();
5100     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5101         DECODE_PRINTF("OUTSD\n");
5102         outs(4);
5103     }
5104     else {
5105         DECODE_PRINTF("OUTSW\n");
5106         outs(2);
5107     }
5108     TRACE_AND_STEP();
5109     DECODE_CLEAR_SEGOVR();
5110     END_OF_INSTR();
5111 }
5112 
5113 /****************************************************************************
5114 REMARKS:
5115 Handles opcode 0x70
5116 ****************************************************************************/
5117 static void
x86emuOp_jump_near_O(u8 X86EMU_UNUSED (op1))5118 x86emuOp_jump_near_O(u8 X86EMU_UNUSED(op1))
5119 {
5120     s8 offset;
5121     u16 target;
5122 
5123     /* jump to byte offset if overflow flag is set */
5124     START_OF_INSTR();
5125     DECODE_PRINTF("JO\t");
5126     offset = (s8) fetch_byte_imm();
5127     target = (u16) (M.x86.R_IP + (s16) offset);
5128     DECODE_PRINTF2("%x\n", target);
5129     TRACE_AND_STEP();
5130     if (ACCESS_FLAG(F_OF))
5131         M.x86.R_IP = target;
5132     DECODE_CLEAR_SEGOVR();
5133     END_OF_INSTR();
5134 }
5135 
5136 /****************************************************************************
5137 REMARKS:
5138 Handles opcode 0x71
5139 ****************************************************************************/
5140 static void
x86emuOp_jump_near_NO(u8 X86EMU_UNUSED (op1))5141 x86emuOp_jump_near_NO(u8 X86EMU_UNUSED(op1))
5142 {
5143     s8 offset;
5144     u16 target;
5145 
5146     /* jump to byte offset if overflow is not set */
5147     START_OF_INSTR();
5148     DECODE_PRINTF("JNO\t");
5149     offset = (s8) fetch_byte_imm();
5150     target = (u16) (M.x86.R_IP + (s16) offset);
5151     DECODE_PRINTF2("%x\n", target);
5152     TRACE_AND_STEP();
5153     if (!ACCESS_FLAG(F_OF))
5154         M.x86.R_IP = target;
5155     DECODE_CLEAR_SEGOVR();
5156     END_OF_INSTR();
5157 }
5158 
5159 /****************************************************************************
5160 REMARKS:
5161 Handles opcode 0x72
5162 ****************************************************************************/
5163 static void
x86emuOp_jump_near_B(u8 X86EMU_UNUSED (op1))5164 x86emuOp_jump_near_B(u8 X86EMU_UNUSED(op1))
5165 {
5166     s8 offset;
5167     u16 target;
5168 
5169     /* jump to byte offset if carry flag is set. */
5170     START_OF_INSTR();
5171     DECODE_PRINTF("JB\t");
5172     offset = (s8) fetch_byte_imm();
5173     target = (u16) (M.x86.R_IP + (s16) offset);
5174     DECODE_PRINTF2("%x\n", target);
5175     TRACE_AND_STEP();
5176     if (ACCESS_FLAG(F_CF))
5177         M.x86.R_IP = target;
5178     DECODE_CLEAR_SEGOVR();
5179     END_OF_INSTR();
5180 }
5181 
5182 /****************************************************************************
5183 REMARKS:
5184 Handles opcode 0x73
5185 ****************************************************************************/
5186 static void
x86emuOp_jump_near_NB(u8 X86EMU_UNUSED (op1))5187 x86emuOp_jump_near_NB(u8 X86EMU_UNUSED(op1))
5188 {
5189     s8 offset;
5190     u16 target;
5191 
5192     /* jump to byte offset if carry flag is clear. */
5193     START_OF_INSTR();
5194     DECODE_PRINTF("JNB\t");
5195     offset = (s8) fetch_byte_imm();
5196     target = (u16) (M.x86.R_IP + (s16) offset);
5197     DECODE_PRINTF2("%x\n", target);
5198     TRACE_AND_STEP();
5199     if (!ACCESS_FLAG(F_CF))
5200         M.x86.R_IP = target;
5201     DECODE_CLEAR_SEGOVR();
5202     END_OF_INSTR();
5203 }
5204 
5205 /****************************************************************************
5206 REMARKS:
5207 Handles opcode 0x74
5208 ****************************************************************************/
5209 static void
x86emuOp_jump_near_Z(u8 X86EMU_UNUSED (op1))5210 x86emuOp_jump_near_Z(u8 X86EMU_UNUSED(op1))
5211 {
5212     s8 offset;
5213     u16 target;
5214 
5215     /* jump to byte offset if zero flag is set. */
5216     START_OF_INSTR();
5217     DECODE_PRINTF("JZ\t");
5218     offset = (s8) fetch_byte_imm();
5219     target = (u16) (M.x86.R_IP + (s16) offset);
5220     DECODE_PRINTF2("%x\n", target);
5221     TRACE_AND_STEP();
5222     if (ACCESS_FLAG(F_ZF))
5223         M.x86.R_IP = target;
5224     DECODE_CLEAR_SEGOVR();
5225     END_OF_INSTR();
5226 }
5227 
5228 /****************************************************************************
5229 REMARKS:
5230 Handles opcode 0x75
5231 ****************************************************************************/
5232 static void
x86emuOp_jump_near_NZ(u8 X86EMU_UNUSED (op1))5233 x86emuOp_jump_near_NZ(u8 X86EMU_UNUSED(op1))
5234 {
5235     s8 offset;
5236     u16 target;
5237 
5238     /* jump to byte offset if zero flag is clear. */
5239     START_OF_INSTR();
5240     DECODE_PRINTF("JNZ\t");
5241     offset = (s8) fetch_byte_imm();
5242     target = (u16) (M.x86.R_IP + (s16) offset);
5243     DECODE_PRINTF2("%x\n", target);
5244     TRACE_AND_STEP();
5245     if (!ACCESS_FLAG(F_ZF))
5246         M.x86.R_IP = target;
5247     DECODE_CLEAR_SEGOVR();
5248     END_OF_INSTR();
5249 }
5250 
5251 /****************************************************************************
5252 REMARKS:
5253 Handles opcode 0x76
5254 ****************************************************************************/
5255 static void
x86emuOp_jump_near_BE(u8 X86EMU_UNUSED (op1))5256 x86emuOp_jump_near_BE(u8 X86EMU_UNUSED(op1))
5257 {
5258     s8 offset;
5259     u16 target;
5260 
5261     /* jump to byte offset if carry flag is set or if the zero
5262        flag is set. */
5263     START_OF_INSTR();
5264     DECODE_PRINTF("JBE\t");
5265     offset = (s8) fetch_byte_imm();
5266     target = (u16) (M.x86.R_IP + (s16) offset);
5267     DECODE_PRINTF2("%x\n", target);
5268     TRACE_AND_STEP();
5269     if (ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF))
5270         M.x86.R_IP = target;
5271     DECODE_CLEAR_SEGOVR();
5272     END_OF_INSTR();
5273 }
5274 
5275 /****************************************************************************
5276 REMARKS:
5277 Handles opcode 0x77
5278 ****************************************************************************/
5279 static void
x86emuOp_jump_near_NBE(u8 X86EMU_UNUSED (op1))5280 x86emuOp_jump_near_NBE(u8 X86EMU_UNUSED(op1))
5281 {
5282     s8 offset;
5283     u16 target;
5284 
5285     /* jump to byte offset if carry flag is clear and if the zero
5286        flag is clear */
5287     START_OF_INSTR();
5288     DECODE_PRINTF("JNBE\t");
5289     offset = (s8) fetch_byte_imm();
5290     target = (u16) (M.x86.R_IP + (s16) offset);
5291     DECODE_PRINTF2("%x\n", target);
5292     TRACE_AND_STEP();
5293     if (!(ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF)))
5294         M.x86.R_IP = target;
5295     DECODE_CLEAR_SEGOVR();
5296     END_OF_INSTR();
5297 }
5298 
5299 /****************************************************************************
5300 REMARKS:
5301 Handles opcode 0x78
5302 ****************************************************************************/
5303 static void
x86emuOp_jump_near_S(u8 X86EMU_UNUSED (op1))5304 x86emuOp_jump_near_S(u8 X86EMU_UNUSED(op1))
5305 {
5306     s8 offset;
5307     u16 target;
5308 
5309     /* jump to byte offset if sign flag is set */
5310     START_OF_INSTR();
5311     DECODE_PRINTF("JS\t");
5312     offset = (s8) fetch_byte_imm();
5313     target = (u16) (M.x86.R_IP + (s16) offset);
5314     DECODE_PRINTF2("%x\n", target);
5315     TRACE_AND_STEP();
5316     if (ACCESS_FLAG(F_SF))
5317         M.x86.R_IP = target;
5318     DECODE_CLEAR_SEGOVR();
5319     END_OF_INSTR();
5320 }
5321 
5322 /****************************************************************************
5323 REMARKS:
5324 Handles opcode 0x79
5325 ****************************************************************************/
5326 static void
x86emuOp_jump_near_NS(u8 X86EMU_UNUSED (op1))5327 x86emuOp_jump_near_NS(u8 X86EMU_UNUSED(op1))
5328 {
5329     s8 offset;
5330     u16 target;
5331 
5332     /* jump to byte offset if sign flag is clear */
5333     START_OF_INSTR();
5334     DECODE_PRINTF("JNS\t");
5335     offset = (s8) fetch_byte_imm();
5336     target = (u16) (M.x86.R_IP + (s16) offset);
5337     DECODE_PRINTF2("%x\n", target);
5338     TRACE_AND_STEP();
5339     if (!ACCESS_FLAG(F_SF))
5340         M.x86.R_IP = target;
5341     DECODE_CLEAR_SEGOVR();
5342     END_OF_INSTR();
5343 }
5344 
5345 /****************************************************************************
5346 REMARKS:
5347 Handles opcode 0x7a
5348 ****************************************************************************/
5349 static void
x86emuOp_jump_near_P(u8 X86EMU_UNUSED (op1))5350 x86emuOp_jump_near_P(u8 X86EMU_UNUSED(op1))
5351 {
5352     s8 offset;
5353     u16 target;
5354 
5355     /* jump to byte offset if parity flag is set (even parity) */
5356     START_OF_INSTR();
5357     DECODE_PRINTF("JP\t");
5358     offset = (s8) fetch_byte_imm();
5359     target = (u16) (M.x86.R_IP + (s16) offset);
5360     DECODE_PRINTF2("%x\n", target);
5361     TRACE_AND_STEP();
5362     if (ACCESS_FLAG(F_PF))
5363         M.x86.R_IP = target;
5364     DECODE_CLEAR_SEGOVR();
5365     END_OF_INSTR();
5366 }
5367 
5368 /****************************************************************************
5369 REMARKS:
5370 Handles opcode 0x7b
5371 ****************************************************************************/
5372 static void
x86emuOp_jump_near_NP(u8 X86EMU_UNUSED (op1))5373 x86emuOp_jump_near_NP(u8 X86EMU_UNUSED(op1))
5374 {
5375     s8 offset;
5376     u16 target;
5377 
5378     /* jump to byte offset if parity flag is clear (odd parity) */
5379     START_OF_INSTR();
5380     DECODE_PRINTF("JNP\t");
5381     offset = (s8) fetch_byte_imm();
5382     target = (u16) (M.x86.R_IP + (s16) offset);
5383     DECODE_PRINTF2("%x\n", target);
5384     TRACE_AND_STEP();
5385     if (!ACCESS_FLAG(F_PF))
5386         M.x86.R_IP = target;
5387     DECODE_CLEAR_SEGOVR();
5388     END_OF_INSTR();
5389 }
5390 
5391 /****************************************************************************
5392 REMARKS:
5393 Handles opcode 0x7c
5394 ****************************************************************************/
5395 static void
x86emuOp_jump_near_L(u8 X86EMU_UNUSED (op1))5396 x86emuOp_jump_near_L(u8 X86EMU_UNUSED(op1))
5397 {
5398     s8 offset;
5399     u16 target;
5400     int sf, of;
5401 
5402     /* jump to byte offset if sign flag not equal to overflow flag. */
5403     START_OF_INSTR();
5404     DECODE_PRINTF("JL\t");
5405     offset = (s8) fetch_byte_imm();
5406     target = (u16) (M.x86.R_IP + (s16) offset);
5407     DECODE_PRINTF2("%x\n", target);
5408     TRACE_AND_STEP();
5409     sf = ACCESS_FLAG(F_SF) != 0;
5410     of = ACCESS_FLAG(F_OF) != 0;
5411     if (sf ^ of)
5412         M.x86.R_IP = target;
5413     DECODE_CLEAR_SEGOVR();
5414     END_OF_INSTR();
5415 }
5416 
5417 /****************************************************************************
5418 REMARKS:
5419 Handles opcode 0x7d
5420 ****************************************************************************/
5421 static void
x86emuOp_jump_near_NL(u8 X86EMU_UNUSED (op1))5422 x86emuOp_jump_near_NL(u8 X86EMU_UNUSED(op1))
5423 {
5424     s8 offset;
5425     u16 target;
5426     int sf, of;
5427 
5428     /* jump to byte offset if sign flag not equal to overflow flag. */
5429     START_OF_INSTR();
5430     DECODE_PRINTF("JNL\t");
5431     offset = (s8) fetch_byte_imm();
5432     target = (u16) (M.x86.R_IP + (s16) offset);
5433     DECODE_PRINTF2("%x\n", target);
5434     TRACE_AND_STEP();
5435     sf = ACCESS_FLAG(F_SF) != 0;
5436     of = ACCESS_FLAG(F_OF) != 0;
5437     /* note: inverse of above, but using == instead of xor. */
5438     if (sf == of)
5439         M.x86.R_IP = target;
5440     DECODE_CLEAR_SEGOVR();
5441     END_OF_INSTR();
5442 }
5443 
5444 /****************************************************************************
5445 REMARKS:
5446 Handles opcode 0x7e
5447 ****************************************************************************/
5448 static void
x86emuOp_jump_near_LE(u8 X86EMU_UNUSED (op1))5449 x86emuOp_jump_near_LE(u8 X86EMU_UNUSED(op1))
5450 {
5451     s8 offset;
5452     u16 target;
5453     int sf, of;
5454 
5455     /* jump to byte offset if sign flag not equal to overflow flag
5456        or the zero flag is set */
5457     START_OF_INSTR();
5458     DECODE_PRINTF("JLE\t");
5459     offset = (s8) fetch_byte_imm();
5460     target = (u16) (M.x86.R_IP + (s16) offset);
5461     DECODE_PRINTF2("%x\n", target);
5462     TRACE_AND_STEP();
5463     sf = ACCESS_FLAG(F_SF) != 0;
5464     of = ACCESS_FLAG(F_OF) != 0;
5465     if ((sf ^ of) || ACCESS_FLAG(F_ZF))
5466         M.x86.R_IP = target;
5467     DECODE_CLEAR_SEGOVR();
5468     END_OF_INSTR();
5469 }
5470 
5471 /****************************************************************************
5472 REMARKS:
5473 Handles opcode 0x7f
5474 ****************************************************************************/
5475 static void
x86emuOp_jump_near_NLE(u8 X86EMU_UNUSED (op1))5476 x86emuOp_jump_near_NLE(u8 X86EMU_UNUSED(op1))
5477 {
5478     s8 offset;
5479     u16 target;
5480     int sf, of;
5481 
5482     /* jump to byte offset if sign flag equal to overflow flag.
5483        and the zero flag is clear */
5484     START_OF_INSTR();
5485     DECODE_PRINTF("JNLE\t");
5486     offset = (s8) fetch_byte_imm();
5487     target = (u16) (M.x86.R_IP + (s16) offset);
5488     DECODE_PRINTF2("%x\n", target);
5489     TRACE_AND_STEP();
5490     sf = ACCESS_FLAG(F_SF) != 0;
5491     of = ACCESS_FLAG(F_OF) != 0;
5492     if ((sf == of) && !ACCESS_FLAG(F_ZF))
5493         M.x86.R_IP = target;
5494     DECODE_CLEAR_SEGOVR();
5495     END_OF_INSTR();
5496 }
5497 
5498 static u8(*opc80_byte_operation[]) (u8 d, u8 s) = {
5499     add_byte,                   /* 00 */
5500         or_byte,                /* 01 */
5501         adc_byte,               /* 02 */
5502         sbb_byte,               /* 03 */
5503         and_byte,               /* 04 */
5504         sub_byte,               /* 05 */
5505         xor_byte,               /* 06 */
5506         cmp_byte,               /* 07 */
5507 };
5508 
5509 /****************************************************************************
5510 REMARKS:
5511 Handles opcode 0x80
5512 ****************************************************************************/
5513 static void
x86emuOp_opc80_byte_RM_IMM(u8 X86EMU_UNUSED (op1))5514 x86emuOp_opc80_byte_RM_IMM(u8 X86EMU_UNUSED(op1))
5515 {
5516     int mod, rl, rh;
5517     u8 *destreg;
5518     uint destoffset;
5519     u8 imm;
5520     u8 destval;
5521 
5522     /*
5523      * Weirdo special case instruction format.  Part of the opcode
5524      * held below in "RH".  Doubly nested case would result, except
5525      * that the decoded instruction
5526      */
5527     START_OF_INSTR();
5528     FETCH_DECODE_MODRM(mod, rh, rl);
5529 #ifdef DEBUG
5530     if (DEBUG_DECODE()) {
5531         /* XXX DECODE_PRINTF may be changed to something more
5532            general, so that it is important to leave the strings
5533            in the same format, even though the result is that the
5534            above test is done twice. */
5535 
5536         switch (rh) {
5537         case 0:
5538             DECODE_PRINTF("ADD\t");
5539             break;
5540         case 1:
5541             DECODE_PRINTF("OR\t");
5542             break;
5543         case 2:
5544             DECODE_PRINTF("ADC\t");
5545             break;
5546         case 3:
5547             DECODE_PRINTF("SBB\t");
5548             break;
5549         case 4:
5550             DECODE_PRINTF("AND\t");
5551             break;
5552         case 5:
5553             DECODE_PRINTF("SUB\t");
5554             break;
5555         case 6:
5556             DECODE_PRINTF("XOR\t");
5557             break;
5558         case 7:
5559             DECODE_PRINTF("CMP\t");
5560             break;
5561         }
5562     }
5563 #endif
5564     /* know operation, decode the mod byte to find the addressing
5565        mode. */
5566     switch (mod) {
5567     case 0:
5568         DECODE_PRINTF("BYTE PTR ");
5569         destoffset = decode_rm00_address(rl);
5570         DECODE_PRINTF(",");
5571         destval = fetch_data_byte(destoffset);
5572         imm = fetch_byte_imm();
5573         DECODE_PRINTF2("%x\n", imm);
5574         TRACE_AND_STEP();
5575         destval = (*opc80_byte_operation[rh]) (destval, imm);
5576         if (rh != 7)
5577             store_data_byte(destoffset, destval);
5578         break;
5579     case 1:
5580         DECODE_PRINTF("BYTE PTR ");
5581         destoffset = decode_rm01_address(rl);
5582         DECODE_PRINTF(",");
5583         destval = fetch_data_byte(destoffset);
5584         imm = fetch_byte_imm();
5585         DECODE_PRINTF2("%x\n", imm);
5586         TRACE_AND_STEP();
5587         destval = (*opc80_byte_operation[rh]) (destval, imm);
5588         if (rh != 7)
5589             store_data_byte(destoffset, destval);
5590         break;
5591     case 2:
5592         DECODE_PRINTF("BYTE PTR ");
5593         destoffset = decode_rm10_address(rl);
5594         DECODE_PRINTF(",");
5595         destval = fetch_data_byte(destoffset);
5596         imm = fetch_byte_imm();
5597         DECODE_PRINTF2("%x\n", imm);
5598         TRACE_AND_STEP();
5599         destval = (*opc80_byte_operation[rh]) (destval, imm);
5600         if (rh != 7)
5601             store_data_byte(destoffset, destval);
5602         break;
5603     case 3:                    /* register to register */
5604         destreg = DECODE_RM_BYTE_REGISTER(rl);
5605         DECODE_PRINTF(",");
5606         imm = fetch_byte_imm();
5607         DECODE_PRINTF2("%x\n", imm);
5608         TRACE_AND_STEP();
5609         destval = (*opc80_byte_operation[rh]) (*destreg, imm);
5610         if (rh != 7)
5611             *destreg = destval;
5612         break;
5613     }
5614     DECODE_CLEAR_SEGOVR();
5615     END_OF_INSTR();
5616 }
5617 
5618 static u16(*opc81_word_operation[]) (u16 d, u16 s) = {
5619     add_word,                   /*00 */
5620         or_word,                /*01 */
5621         adc_word,               /*02 */
5622         sbb_word,               /*03 */
5623         and_word,               /*04 */
5624         sub_word,               /*05 */
5625         xor_word,               /*06 */
5626         cmp_word,               /*07 */
5627 };
5628 
5629 static u32(*opc81_long_operation[]) (u32 d, u32 s) = {
5630     add_long,                   /*00 */
5631         or_long,                /*01 */
5632         adc_long,               /*02 */
5633         sbb_long,               /*03 */
5634         and_long,               /*04 */
5635         sub_long,               /*05 */
5636         xor_long,               /*06 */
5637         cmp_long,               /*07 */
5638 };
5639 
5640 /****************************************************************************
5641 REMARKS:
5642 Handles opcode 0x81
5643 ****************************************************************************/
5644 static void
x86emuOp_opc81_word_RM_IMM(u8 X86EMU_UNUSED (op1))5645 x86emuOp_opc81_word_RM_IMM(u8 X86EMU_UNUSED(op1))
5646 {
5647     int mod, rl, rh;
5648     uint destoffset;
5649 
5650     /*
5651      * Weirdo special case instruction format.  Part of the opcode
5652      * held below in "RH".  Doubly nested case would result, except
5653      * that the decoded instruction
5654      */
5655     START_OF_INSTR();
5656     FETCH_DECODE_MODRM(mod, rh, rl);
5657 #ifdef DEBUG
5658     if (DEBUG_DECODE()) {
5659         /* XXX DECODE_PRINTF may be changed to something more
5660            general, so that it is important to leave the strings
5661            in the same format, even though the result is that the
5662            above test is done twice. */
5663 
5664         switch (rh) {
5665         case 0:
5666             DECODE_PRINTF("ADD\t");
5667             break;
5668         case 1:
5669             DECODE_PRINTF("OR\t");
5670             break;
5671         case 2:
5672             DECODE_PRINTF("ADC\t");
5673             break;
5674         case 3:
5675             DECODE_PRINTF("SBB\t");
5676             break;
5677         case 4:
5678             DECODE_PRINTF("AND\t");
5679             break;
5680         case 5:
5681             DECODE_PRINTF("SUB\t");
5682             break;
5683         case 6:
5684             DECODE_PRINTF("XOR\t");
5685             break;
5686         case 7:
5687             DECODE_PRINTF("CMP\t");
5688             break;
5689         }
5690     }
5691 #endif
5692     /*
5693      * Know operation, decode the mod byte to find the addressing
5694      * mode.
5695      */
5696     switch (mod) {
5697     case 0:
5698         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5699             u32 destval, imm;
5700 
5701             DECODE_PRINTF("DWORD PTR ");
5702             destoffset = decode_rm00_address(rl);
5703             DECODE_PRINTF(",");
5704             destval = fetch_data_long(destoffset);
5705             imm = fetch_long_imm();
5706             DECODE_PRINTF2("%x\n", imm);
5707             TRACE_AND_STEP();
5708             destval = (*opc81_long_operation[rh]) (destval, imm);
5709             if (rh != 7)
5710                 store_data_long(destoffset, destval);
5711         }
5712         else {
5713             u16 destval, imm;
5714 
5715             DECODE_PRINTF("WORD PTR ");
5716             destoffset = decode_rm00_address(rl);
5717             DECODE_PRINTF(",");
5718             destval = fetch_data_word(destoffset);
5719             imm = fetch_word_imm();
5720             DECODE_PRINTF2("%x\n", imm);
5721             TRACE_AND_STEP();
5722             destval = (*opc81_word_operation[rh]) (destval, imm);
5723             if (rh != 7)
5724                 store_data_word(destoffset, destval);
5725         }
5726         break;
5727     case 1:
5728         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5729             u32 destval, imm;
5730 
5731             DECODE_PRINTF("DWORD PTR ");
5732             destoffset = decode_rm01_address(rl);
5733             DECODE_PRINTF(",");
5734             destval = fetch_data_long(destoffset);
5735             imm = fetch_long_imm();
5736             DECODE_PRINTF2("%x\n", imm);
5737             TRACE_AND_STEP();
5738             destval = (*opc81_long_operation[rh]) (destval, imm);
5739             if (rh != 7)
5740                 store_data_long(destoffset, destval);
5741         }
5742         else {
5743             u16 destval, imm;
5744 
5745             DECODE_PRINTF("WORD PTR ");
5746             destoffset = decode_rm01_address(rl);
5747             DECODE_PRINTF(",");
5748             destval = fetch_data_word(destoffset);
5749             imm = fetch_word_imm();
5750             DECODE_PRINTF2("%x\n", imm);
5751             TRACE_AND_STEP();
5752             destval = (*opc81_word_operation[rh]) (destval, imm);
5753             if (rh != 7)
5754                 store_data_word(destoffset, destval);
5755         }
5756         break;
5757     case 2:
5758         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5759             u32 destval, imm;
5760 
5761             DECODE_PRINTF("DWORD PTR ");
5762             destoffset = decode_rm10_address(rl);
5763             DECODE_PRINTF(",");
5764             destval = fetch_data_long(destoffset);
5765             imm = fetch_long_imm();
5766             DECODE_PRINTF2("%x\n", imm);
5767             TRACE_AND_STEP();
5768             destval = (*opc81_long_operation[rh]) (destval, imm);
5769             if (rh != 7)
5770                 store_data_long(destoffset, destval);
5771         }
5772         else {
5773             u16 destval, imm;
5774 
5775             DECODE_PRINTF("WORD PTR ");
5776             destoffset = decode_rm10_address(rl);
5777             DECODE_PRINTF(",");
5778             destval = fetch_data_word(destoffset);
5779             imm = fetch_word_imm();
5780             DECODE_PRINTF2("%x\n", imm);
5781             TRACE_AND_STEP();
5782             destval = (*opc81_word_operation[rh]) (destval, imm);
5783             if (rh != 7)
5784                 store_data_word(destoffset, destval);
5785         }
5786         break;
5787     case 3:                    /* register to register */
5788         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5789             u32 *destreg;
5790             u32 destval, imm;
5791 
5792             destreg = DECODE_RM_LONG_REGISTER(rl);
5793             DECODE_PRINTF(",");
5794             imm = fetch_long_imm();
5795             DECODE_PRINTF2("%x\n", imm);
5796             TRACE_AND_STEP();
5797             destval = (*opc81_long_operation[rh]) (*destreg, imm);
5798             if (rh != 7)
5799                 *destreg = destval;
5800         }
5801         else {
5802             u16 *destreg;
5803             u16 destval, imm;
5804 
5805             destreg = DECODE_RM_WORD_REGISTER(rl);
5806             DECODE_PRINTF(",");
5807             imm = fetch_word_imm();
5808             DECODE_PRINTF2("%x\n", imm);
5809             TRACE_AND_STEP();
5810             destval = (*opc81_word_operation[rh]) (*destreg, imm);
5811             if (rh != 7)
5812                 *destreg = destval;
5813         }
5814         break;
5815     }
5816     DECODE_CLEAR_SEGOVR();
5817     END_OF_INSTR();
5818 }
5819 
5820 static u8(*opc82_byte_operation[]) (u8 s, u8 d) = {
5821     add_byte,                   /*00 */
5822         or_byte,                /*01 *//*YYY UNUSED ???? */
5823         adc_byte,               /*02 */
5824         sbb_byte,               /*03 */
5825         and_byte,               /*04 *//*YYY UNUSED ???? */
5826         sub_byte,               /*05 */
5827         xor_byte,               /*06 *//*YYY UNUSED ???? */
5828         cmp_byte,               /*07 */
5829 };
5830 
5831 /****************************************************************************
5832 REMARKS:
5833 Handles opcode 0x82
5834 ****************************************************************************/
5835 static void
x86emuOp_opc82_byte_RM_IMM(u8 X86EMU_UNUSED (op1))5836 x86emuOp_opc82_byte_RM_IMM(u8 X86EMU_UNUSED(op1))
5837 {
5838     int mod, rl, rh;
5839     u8 *destreg;
5840     uint destoffset;
5841     u8 imm;
5842     u8 destval;
5843 
5844     /*
5845      * Weirdo special case instruction format.  Part of the opcode
5846      * held below in "RH".  Doubly nested case would result, except
5847      * that the decoded instruction Similar to opcode 81, except that
5848      * the immediate byte is sign extended to a word length.
5849      */
5850     START_OF_INSTR();
5851     FETCH_DECODE_MODRM(mod, rh, rl);
5852 #ifdef DEBUG
5853     if (DEBUG_DECODE()) {
5854         /* XXX DECODE_PRINTF may be changed to something more
5855            general, so that it is important to leave the strings
5856            in the same format, even though the result is that the
5857            above test is done twice. */
5858         switch (rh) {
5859         case 0:
5860             DECODE_PRINTF("ADD\t");
5861             break;
5862         case 1:
5863             DECODE_PRINTF("OR\t");
5864             break;
5865         case 2:
5866             DECODE_PRINTF("ADC\t");
5867             break;
5868         case 3:
5869             DECODE_PRINTF("SBB\t");
5870             break;
5871         case 4:
5872             DECODE_PRINTF("AND\t");
5873             break;
5874         case 5:
5875             DECODE_PRINTF("SUB\t");
5876             break;
5877         case 6:
5878             DECODE_PRINTF("XOR\t");
5879             break;
5880         case 7:
5881             DECODE_PRINTF("CMP\t");
5882             break;
5883         }
5884     }
5885 #endif
5886     /* know operation, decode the mod byte to find the addressing
5887        mode. */
5888     switch (mod) {
5889     case 0:
5890         DECODE_PRINTF("BYTE PTR ");
5891         destoffset = decode_rm00_address(rl);
5892         destval = fetch_data_byte(destoffset);
5893         imm = fetch_byte_imm();
5894         DECODE_PRINTF2(",%x\n", imm);
5895         TRACE_AND_STEP();
5896         destval = (*opc82_byte_operation[rh]) (destval, imm);
5897         if (rh != 7)
5898             store_data_byte(destoffset, destval);
5899         break;
5900     case 1:
5901         DECODE_PRINTF("BYTE PTR ");
5902         destoffset = decode_rm01_address(rl);
5903         destval = fetch_data_byte(destoffset);
5904         imm = fetch_byte_imm();
5905         DECODE_PRINTF2(",%x\n", imm);
5906         TRACE_AND_STEP();
5907         destval = (*opc82_byte_operation[rh]) (destval, imm);
5908         if (rh != 7)
5909             store_data_byte(destoffset, destval);
5910         break;
5911     case 2:
5912         DECODE_PRINTF("BYTE PTR ");
5913         destoffset = decode_rm10_address(rl);
5914         destval = fetch_data_byte(destoffset);
5915         imm = fetch_byte_imm();
5916         DECODE_PRINTF2(",%x\n", imm);
5917         TRACE_AND_STEP();
5918         destval = (*opc82_byte_operation[rh]) (destval, imm);
5919         if (rh != 7)
5920             store_data_byte(destoffset, destval);
5921         break;
5922     case 3:                    /* register to register */
5923         destreg = DECODE_RM_BYTE_REGISTER(rl);
5924         imm = fetch_byte_imm();
5925         DECODE_PRINTF2(",%x\n", imm);
5926         TRACE_AND_STEP();
5927         destval = (*opc82_byte_operation[rh]) (*destreg, imm);
5928         if (rh != 7)
5929             *destreg = destval;
5930         break;
5931     }
5932     DECODE_CLEAR_SEGOVR();
5933     END_OF_INSTR();
5934 }
5935 
5936 static u16(*opc83_word_operation[]) (u16 s, u16 d) = {
5937     add_word,                   /*00 */
5938         or_word,                /*01 *//*YYY UNUSED ???? */
5939         adc_word,               /*02 */
5940         sbb_word,               /*03 */
5941         and_word,               /*04 *//*YYY UNUSED ???? */
5942         sub_word,               /*05 */
5943         xor_word,               /*06 *//*YYY UNUSED ???? */
5944         cmp_word,               /*07 */
5945 };
5946 
5947 static u32(*opc83_long_operation[]) (u32 s, u32 d) = {
5948     add_long,                   /*00 */
5949         or_long,                /*01 *//*YYY UNUSED ???? */
5950         adc_long,               /*02 */
5951         sbb_long,               /*03 */
5952         and_long,               /*04 *//*YYY UNUSED ???? */
5953         sub_long,               /*05 */
5954         xor_long,               /*06 *//*YYY UNUSED ???? */
5955         cmp_long,               /*07 */
5956 };
5957 
5958 /****************************************************************************
5959 REMARKS:
5960 Handles opcode 0x83
5961 ****************************************************************************/
5962 static void
x86emuOp_opc83_word_RM_IMM(u8 X86EMU_UNUSED (op1))5963 x86emuOp_opc83_word_RM_IMM(u8 X86EMU_UNUSED(op1))
5964 {
5965     int mod, rl, rh;
5966     uint destoffset;
5967 
5968     /*
5969      * Weirdo special case instruction format.  Part of the opcode
5970      * held below in "RH".  Doubly nested case would result, except
5971      * that the decoded instruction Similar to opcode 81, except that
5972      * the immediate byte is sign extended to a word length.
5973      */
5974     START_OF_INSTR();
5975     FETCH_DECODE_MODRM(mod, rh, rl);
5976 #ifdef DEBUG
5977     if (DEBUG_DECODE()) {
5978         /* XXX DECODE_PRINTF may be changed to something more
5979            general, so that it is important to leave the strings
5980            in the same format, even though the result is that the
5981            above test is done twice. */
5982         switch (rh) {
5983         case 0:
5984             DECODE_PRINTF("ADD\t");
5985             break;
5986         case 1:
5987             DECODE_PRINTF("OR\t");
5988             break;
5989         case 2:
5990             DECODE_PRINTF("ADC\t");
5991             break;
5992         case 3:
5993             DECODE_PRINTF("SBB\t");
5994             break;
5995         case 4:
5996             DECODE_PRINTF("AND\t");
5997             break;
5998         case 5:
5999             DECODE_PRINTF("SUB\t");
6000             break;
6001         case 6:
6002             DECODE_PRINTF("XOR\t");
6003             break;
6004         case 7:
6005             DECODE_PRINTF("CMP\t");
6006             break;
6007         }
6008     }
6009 #endif
6010     /* know operation, decode the mod byte to find the addressing
6011        mode. */
6012     switch (mod) {
6013     case 0:
6014         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6015             u32 destval, imm;
6016 
6017             DECODE_PRINTF("DWORD PTR ");
6018             destoffset = decode_rm00_address(rl);
6019             destval = fetch_data_long(destoffset);
6020             imm = (s8) fetch_byte_imm();
6021             DECODE_PRINTF2(",%x\n", imm);
6022             TRACE_AND_STEP();
6023             destval = (*opc83_long_operation[rh]) (destval, imm);
6024             if (rh != 7)
6025                 store_data_long(destoffset, destval);
6026         }
6027         else {
6028             u16 destval, imm;
6029 
6030             DECODE_PRINTF("WORD PTR ");
6031             destoffset = decode_rm00_address(rl);
6032             destval = fetch_data_word(destoffset);
6033             imm = (s8) fetch_byte_imm();
6034             DECODE_PRINTF2(",%x\n", imm);
6035             TRACE_AND_STEP();
6036             destval = (*opc83_word_operation[rh]) (destval, imm);
6037             if (rh != 7)
6038                 store_data_word(destoffset, destval);
6039         }
6040         break;
6041     case 1:
6042         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6043             u32 destval, imm;
6044 
6045             DECODE_PRINTF("DWORD PTR ");
6046             destoffset = decode_rm01_address(rl);
6047             destval = fetch_data_long(destoffset);
6048             imm = (s8) fetch_byte_imm();
6049             DECODE_PRINTF2(",%x\n", imm);
6050             TRACE_AND_STEP();
6051             destval = (*opc83_long_operation[rh]) (destval, imm);
6052             if (rh != 7)
6053                 store_data_long(destoffset, destval);
6054         }
6055         else {
6056             u16 destval, imm;
6057 
6058             DECODE_PRINTF("WORD PTR ");
6059             destoffset = decode_rm01_address(rl);
6060             destval = fetch_data_word(destoffset);
6061             imm = (s8) fetch_byte_imm();
6062             DECODE_PRINTF2(",%x\n", imm);
6063             TRACE_AND_STEP();
6064             destval = (*opc83_word_operation[rh]) (destval, imm);
6065             if (rh != 7)
6066                 store_data_word(destoffset, destval);
6067         }
6068         break;
6069     case 2:
6070         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6071             u32 destval, imm;
6072 
6073             DECODE_PRINTF("DWORD PTR ");
6074             destoffset = decode_rm10_address(rl);
6075             destval = fetch_data_long(destoffset);
6076             imm = (s8) fetch_byte_imm();
6077             DECODE_PRINTF2(",%x\n", imm);
6078             TRACE_AND_STEP();
6079             destval = (*opc83_long_operation[rh]) (destval, imm);
6080             if (rh != 7)
6081                 store_data_long(destoffset, destval);
6082         }
6083         else {
6084             u16 destval, imm;
6085 
6086             DECODE_PRINTF("WORD PTR ");
6087             destoffset = decode_rm10_address(rl);
6088             destval = fetch_data_word(destoffset);
6089             imm = (s8) fetch_byte_imm();
6090             DECODE_PRINTF2(",%x\n", imm);
6091             TRACE_AND_STEP();
6092             destval = (*opc83_word_operation[rh]) (destval, imm);
6093             if (rh != 7)
6094                 store_data_word(destoffset, destval);
6095         }
6096         break;
6097     case 3:                    /* register to register */
6098         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6099             u32 *destreg;
6100             u32 destval, imm;
6101 
6102             destreg = DECODE_RM_LONG_REGISTER(rl);
6103             imm = (s8) fetch_byte_imm();
6104             DECODE_PRINTF2(",%x\n", imm);
6105             TRACE_AND_STEP();
6106             destval = (*opc83_long_operation[rh]) (*destreg, imm);
6107             if (rh != 7)
6108                 *destreg = destval;
6109         }
6110         else {
6111             u16 *destreg;
6112             u16 destval, imm;
6113 
6114             destreg = DECODE_RM_WORD_REGISTER(rl);
6115             imm = (s8) fetch_byte_imm();
6116             DECODE_PRINTF2(",%x\n", imm);
6117             TRACE_AND_STEP();
6118             destval = (*opc83_word_operation[rh]) (*destreg, imm);
6119             if (rh != 7)
6120                 *destreg = destval;
6121         }
6122         break;
6123     }
6124     DECODE_CLEAR_SEGOVR();
6125     END_OF_INSTR();
6126 }
6127 
6128 /****************************************************************************
6129 REMARKS:
6130 Handles opcode 0x84
6131 ****************************************************************************/
6132 static void
x86emuOp_test_byte_RM_R(u8 X86EMU_UNUSED (op1))6133 x86emuOp_test_byte_RM_R(u8 X86EMU_UNUSED(op1))
6134 {
6135     int mod, rl, rh;
6136     u8 *destreg, *srcreg;
6137     uint destoffset;
6138     u8 destval;
6139 
6140     START_OF_INSTR();
6141     DECODE_PRINTF("TEST\t");
6142     FETCH_DECODE_MODRM(mod, rh, rl);
6143     switch (mod) {
6144     case 0:
6145         destoffset = decode_rm00_address(rl);
6146         DECODE_PRINTF(",");
6147         destval = fetch_data_byte(destoffset);
6148         srcreg = DECODE_RM_BYTE_REGISTER(rh);
6149         DECODE_PRINTF("\n");
6150         TRACE_AND_STEP();
6151         test_byte(destval, *srcreg);
6152         break;
6153     case 1:
6154         destoffset = decode_rm01_address(rl);
6155         DECODE_PRINTF(",");
6156         destval = fetch_data_byte(destoffset);
6157         srcreg = DECODE_RM_BYTE_REGISTER(rh);
6158         DECODE_PRINTF("\n");
6159         TRACE_AND_STEP();
6160         test_byte(destval, *srcreg);
6161         break;
6162     case 2:
6163         destoffset = decode_rm10_address(rl);
6164         DECODE_PRINTF(",");
6165         destval = fetch_data_byte(destoffset);
6166         srcreg = DECODE_RM_BYTE_REGISTER(rh);
6167         DECODE_PRINTF("\n");
6168         TRACE_AND_STEP();
6169         test_byte(destval, *srcreg);
6170         break;
6171     case 3:                    /* register to register */
6172         destreg = DECODE_RM_BYTE_REGISTER(rl);
6173         DECODE_PRINTF(",");
6174         srcreg = DECODE_RM_BYTE_REGISTER(rh);
6175         DECODE_PRINTF("\n");
6176         TRACE_AND_STEP();
6177         test_byte(*destreg, *srcreg);
6178         break;
6179     }
6180     DECODE_CLEAR_SEGOVR();
6181     END_OF_INSTR();
6182 }
6183 
6184 /****************************************************************************
6185 REMARKS:
6186 Handles opcode 0x85
6187 ****************************************************************************/
6188 static void
x86emuOp_test_word_RM_R(u8 X86EMU_UNUSED (op1))6189 x86emuOp_test_word_RM_R(u8 X86EMU_UNUSED(op1))
6190 {
6191     int mod, rl, rh;
6192     uint destoffset;
6193 
6194     START_OF_INSTR();
6195     DECODE_PRINTF("TEST\t");
6196     FETCH_DECODE_MODRM(mod, rh, rl);
6197     switch (mod) {
6198     case 0:
6199         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6200             u32 destval;
6201             u32 *srcreg;
6202 
6203             destoffset = decode_rm00_address(rl);
6204             DECODE_PRINTF(",");
6205             destval = fetch_data_long(destoffset);
6206             srcreg = DECODE_RM_LONG_REGISTER(rh);
6207             DECODE_PRINTF("\n");
6208             TRACE_AND_STEP();
6209             test_long(destval, *srcreg);
6210         }
6211         else {
6212             u16 destval;
6213             u16 *srcreg;
6214 
6215             destoffset = decode_rm00_address(rl);
6216             DECODE_PRINTF(",");
6217             destval = fetch_data_word(destoffset);
6218             srcreg = DECODE_RM_WORD_REGISTER(rh);
6219             DECODE_PRINTF("\n");
6220             TRACE_AND_STEP();
6221             test_word(destval, *srcreg);
6222         }
6223         break;
6224     case 1:
6225         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6226             u32 destval;
6227             u32 *srcreg;
6228 
6229             destoffset = decode_rm01_address(rl);
6230             DECODE_PRINTF(",");
6231             destval = fetch_data_long(destoffset);
6232             srcreg = DECODE_RM_LONG_REGISTER(rh);
6233             DECODE_PRINTF("\n");
6234             TRACE_AND_STEP();
6235             test_long(destval, *srcreg);
6236         }
6237         else {
6238             u16 destval;
6239             u16 *srcreg;
6240 
6241             destoffset = decode_rm01_address(rl);
6242             DECODE_PRINTF(",");
6243             destval = fetch_data_word(destoffset);
6244             srcreg = DECODE_RM_WORD_REGISTER(rh);
6245             DECODE_PRINTF("\n");
6246             TRACE_AND_STEP();
6247             test_word(destval, *srcreg);
6248         }
6249         break;
6250     case 2:
6251         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6252             u32 destval;
6253             u32 *srcreg;
6254 
6255             destoffset = decode_rm10_address(rl);
6256             DECODE_PRINTF(",");
6257             destval = fetch_data_long(destoffset);
6258             srcreg = DECODE_RM_LONG_REGISTER(rh);
6259             DECODE_PRINTF("\n");
6260             TRACE_AND_STEP();
6261             test_long(destval, *srcreg);
6262         }
6263         else {
6264             u16 destval;
6265             u16 *srcreg;
6266 
6267             destoffset = decode_rm10_address(rl);
6268             DECODE_PRINTF(",");
6269             destval = fetch_data_word(destoffset);
6270             srcreg = DECODE_RM_WORD_REGISTER(rh);
6271             DECODE_PRINTF("\n");
6272             TRACE_AND_STEP();
6273             test_word(destval, *srcreg);
6274         }
6275         break;
6276     case 3:                    /* register to register */
6277         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6278             u32 *destreg, *srcreg;
6279 
6280             destreg = DECODE_RM_LONG_REGISTER(rl);
6281             DECODE_PRINTF(",");
6282             srcreg = DECODE_RM_LONG_REGISTER(rh);
6283             DECODE_PRINTF("\n");
6284             TRACE_AND_STEP();
6285             test_long(*destreg, *srcreg);
6286         }
6287         else {
6288             u16 *destreg, *srcreg;
6289 
6290             destreg = DECODE_RM_WORD_REGISTER(rl);
6291             DECODE_PRINTF(",");
6292             srcreg = DECODE_RM_WORD_REGISTER(rh);
6293             DECODE_PRINTF("\n");
6294             TRACE_AND_STEP();
6295             test_word(*destreg, *srcreg);
6296         }
6297         break;
6298     }
6299     DECODE_CLEAR_SEGOVR();
6300     END_OF_INSTR();
6301 }
6302 
6303 /****************************************************************************
6304 REMARKS:
6305 Handles opcode 0x86
6306 ****************************************************************************/
6307 static void
x86emuOp_xchg_byte_RM_R(u8 X86EMU_UNUSED (op1))6308 x86emuOp_xchg_byte_RM_R(u8 X86EMU_UNUSED(op1))
6309 {
6310     int mod, rl, rh;
6311     u8 *destreg, *srcreg;
6312     uint destoffset;
6313     u8 destval;
6314     u8 tmp;
6315 
6316     START_OF_INSTR();
6317     DECODE_PRINTF("XCHG\t");
6318     FETCH_DECODE_MODRM(mod, rh, rl);
6319     switch (mod) {
6320     case 0:
6321         destoffset = decode_rm00_address(rl);
6322         DECODE_PRINTF(",");
6323         destval = fetch_data_byte(destoffset);
6324         srcreg = DECODE_RM_BYTE_REGISTER(rh);
6325         DECODE_PRINTF("\n");
6326         TRACE_AND_STEP();
6327         tmp = *srcreg;
6328         *srcreg = destval;
6329         destval = tmp;
6330         store_data_byte(destoffset, destval);
6331         break;
6332     case 1:
6333         destoffset = decode_rm01_address(rl);
6334         DECODE_PRINTF(",");
6335         destval = fetch_data_byte(destoffset);
6336         srcreg = DECODE_RM_BYTE_REGISTER(rh);
6337         DECODE_PRINTF("\n");
6338         TRACE_AND_STEP();
6339         tmp = *srcreg;
6340         *srcreg = destval;
6341         destval = tmp;
6342         store_data_byte(destoffset, destval);
6343         break;
6344     case 2:
6345         destoffset = decode_rm10_address(rl);
6346         DECODE_PRINTF(",");
6347         destval = fetch_data_byte(destoffset);
6348         srcreg = DECODE_RM_BYTE_REGISTER(rh);
6349         DECODE_PRINTF("\n");
6350         TRACE_AND_STEP();
6351         tmp = *srcreg;
6352         *srcreg = destval;
6353         destval = tmp;
6354         store_data_byte(destoffset, destval);
6355         break;
6356     case 3:                    /* register to register */
6357         destreg = DECODE_RM_BYTE_REGISTER(rl);
6358         DECODE_PRINTF(",");
6359         srcreg = DECODE_RM_BYTE_REGISTER(rh);
6360         DECODE_PRINTF("\n");
6361         TRACE_AND_STEP();
6362         tmp = *srcreg;
6363         *srcreg = *destreg;
6364         *destreg = tmp;
6365         break;
6366     }
6367     DECODE_CLEAR_SEGOVR();
6368     END_OF_INSTR();
6369 }
6370 
6371 /****************************************************************************
6372 REMARKS:
6373 Handles opcode 0x87
6374 ****************************************************************************/
6375 static void
x86emuOp_xchg_word_RM_R(u8 X86EMU_UNUSED (op1))6376 x86emuOp_xchg_word_RM_R(u8 X86EMU_UNUSED(op1))
6377 {
6378     int mod, rl, rh;
6379     uint destoffset;
6380 
6381     START_OF_INSTR();
6382     DECODE_PRINTF("XCHG\t");
6383     FETCH_DECODE_MODRM(mod, rh, rl);
6384     switch (mod) {
6385     case 0:
6386         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6387             u32 *srcreg;
6388             u32 destval, tmp;
6389 
6390             destoffset = decode_rm00_address(rl);
6391             DECODE_PRINTF(",");
6392             destval = fetch_data_long(destoffset);
6393             srcreg = DECODE_RM_LONG_REGISTER(rh);
6394             DECODE_PRINTF("\n");
6395             TRACE_AND_STEP();
6396             tmp = *srcreg;
6397             *srcreg = destval;
6398             destval = tmp;
6399             store_data_long(destoffset, destval);
6400         }
6401         else {
6402             u16 *srcreg;
6403             u16 destval, tmp;
6404 
6405             destoffset = decode_rm00_address(rl);
6406             DECODE_PRINTF(",");
6407             destval = fetch_data_word(destoffset);
6408             srcreg = DECODE_RM_WORD_REGISTER(rh);
6409             DECODE_PRINTF("\n");
6410             TRACE_AND_STEP();
6411             tmp = *srcreg;
6412             *srcreg = destval;
6413             destval = tmp;
6414             store_data_word(destoffset, destval);
6415         }
6416         break;
6417     case 1:
6418         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6419             u32 *srcreg;
6420             u32 destval, tmp;
6421 
6422             destoffset = decode_rm01_address(rl);
6423             DECODE_PRINTF(",");
6424             destval = fetch_data_long(destoffset);
6425             srcreg = DECODE_RM_LONG_REGISTER(rh);
6426             DECODE_PRINTF("\n");
6427             TRACE_AND_STEP();
6428             tmp = *srcreg;
6429             *srcreg = destval;
6430             destval = tmp;
6431             store_data_long(destoffset, destval);
6432         }
6433         else {
6434             u16 *srcreg;
6435             u16 destval, tmp;
6436 
6437             destoffset = decode_rm01_address(rl);
6438             DECODE_PRINTF(",");
6439             destval = fetch_data_word(destoffset);
6440             srcreg = DECODE_RM_WORD_REGISTER(rh);
6441             DECODE_PRINTF("\n");
6442             TRACE_AND_STEP();
6443             tmp = *srcreg;
6444             *srcreg = destval;
6445             destval = tmp;
6446             store_data_word(destoffset, destval);
6447         }
6448         break;
6449     case 2:
6450         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6451             u32 *srcreg;
6452             u32 destval, tmp;
6453 
6454             destoffset = decode_rm10_address(rl);
6455             DECODE_PRINTF(",");
6456             destval = fetch_data_long(destoffset);
6457             srcreg = DECODE_RM_LONG_REGISTER(rh);
6458             DECODE_PRINTF("\n");
6459             TRACE_AND_STEP();
6460             tmp = *srcreg;
6461             *srcreg = destval;
6462             destval = tmp;
6463             store_data_long(destoffset, destval);
6464         }
6465         else {
6466             u16 *srcreg;
6467             u16 destval, tmp;
6468 
6469             destoffset = decode_rm10_address(rl);
6470             DECODE_PRINTF(",");
6471             destval = fetch_data_word(destoffset);
6472             srcreg = DECODE_RM_WORD_REGISTER(rh);
6473             DECODE_PRINTF("\n");
6474             TRACE_AND_STEP();
6475             tmp = *srcreg;
6476             *srcreg = destval;
6477             destval = tmp;
6478             store_data_word(destoffset, destval);
6479         }
6480         break;
6481     case 3:                    /* register to register */
6482         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6483             u32 *destreg, *srcreg;
6484             u32 tmp;
6485 
6486             destreg = DECODE_RM_LONG_REGISTER(rl);
6487             DECODE_PRINTF(",");
6488             srcreg = DECODE_RM_LONG_REGISTER(rh);
6489             DECODE_PRINTF("\n");
6490             TRACE_AND_STEP();
6491             tmp = *srcreg;
6492             *srcreg = *destreg;
6493             *destreg = tmp;
6494         }
6495         else {
6496             u16 *destreg, *srcreg;
6497             u16 tmp;
6498 
6499             destreg = DECODE_RM_WORD_REGISTER(rl);
6500             DECODE_PRINTF(",");
6501             srcreg = DECODE_RM_WORD_REGISTER(rh);
6502             DECODE_PRINTF("\n");
6503             TRACE_AND_STEP();
6504             tmp = *srcreg;
6505             *srcreg = *destreg;
6506             *destreg = tmp;
6507         }
6508         break;
6509     }
6510     DECODE_CLEAR_SEGOVR();
6511     END_OF_INSTR();
6512 }
6513 
6514 /****************************************************************************
6515 REMARKS:
6516 Handles opcode 0x88
6517 ****************************************************************************/
6518 static void
x86emuOp_mov_byte_RM_R(u8 X86EMU_UNUSED (op1))6519 x86emuOp_mov_byte_RM_R(u8 X86EMU_UNUSED(op1))
6520 {
6521     int mod, rl, rh;
6522     u8 *destreg, *srcreg;
6523     uint destoffset;
6524 
6525     START_OF_INSTR();
6526     DECODE_PRINTF("MOV\t");
6527     FETCH_DECODE_MODRM(mod, rh, rl);
6528     switch (mod) {
6529     case 0:
6530         destoffset = decode_rm00_address(rl);
6531         DECODE_PRINTF(",");
6532         srcreg = DECODE_RM_BYTE_REGISTER(rh);
6533         DECODE_PRINTF("\n");
6534         TRACE_AND_STEP();
6535         store_data_byte(destoffset, *srcreg);
6536         break;
6537     case 1:
6538         destoffset = decode_rm01_address(rl);
6539         DECODE_PRINTF(",");
6540         srcreg = DECODE_RM_BYTE_REGISTER(rh);
6541         DECODE_PRINTF("\n");
6542         TRACE_AND_STEP();
6543         store_data_byte(destoffset, *srcreg);
6544         break;
6545     case 2:
6546         destoffset = decode_rm10_address(rl);
6547         DECODE_PRINTF(",");
6548         srcreg = DECODE_RM_BYTE_REGISTER(rh);
6549         DECODE_PRINTF("\n");
6550         TRACE_AND_STEP();
6551         store_data_byte(destoffset, *srcreg);
6552         break;
6553     case 3:                    /* register to register */
6554         destreg = DECODE_RM_BYTE_REGISTER(rl);
6555         DECODE_PRINTF(",");
6556         srcreg = DECODE_RM_BYTE_REGISTER(rh);
6557         DECODE_PRINTF("\n");
6558         TRACE_AND_STEP();
6559         *destreg = *srcreg;
6560         break;
6561     }
6562     DECODE_CLEAR_SEGOVR();
6563     END_OF_INSTR();
6564 }
6565 
6566 /****************************************************************************
6567 REMARKS:
6568 Handles opcode 0x89
6569 ****************************************************************************/
6570 static void
x86emuOp_mov_word_RM_R(u8 X86EMU_UNUSED (op1))6571 x86emuOp_mov_word_RM_R(u8 X86EMU_UNUSED(op1))
6572 {
6573     int mod, rl, rh;
6574     u32 destoffset;
6575 
6576     START_OF_INSTR();
6577     DECODE_PRINTF("MOV\t");
6578     FETCH_DECODE_MODRM(mod, rh, rl);
6579     switch (mod) {
6580     case 0:
6581         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6582             u32 *srcreg;
6583 
6584             destoffset = decode_rm00_address(rl);
6585             DECODE_PRINTF(",");
6586             srcreg = DECODE_RM_LONG_REGISTER(rh);
6587             DECODE_PRINTF("\n");
6588             TRACE_AND_STEP();
6589             store_data_long(destoffset, *srcreg);
6590         }
6591         else {
6592             u16 *srcreg;
6593 
6594             destoffset = decode_rm00_address(rl);
6595             DECODE_PRINTF(",");
6596             srcreg = DECODE_RM_WORD_REGISTER(rh);
6597             DECODE_PRINTF("\n");
6598             TRACE_AND_STEP();
6599             store_data_word(destoffset, *srcreg);
6600         }
6601         break;
6602     case 1:
6603         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6604             u32 *srcreg;
6605 
6606             destoffset = decode_rm01_address(rl);
6607             DECODE_PRINTF(",");
6608             srcreg = DECODE_RM_LONG_REGISTER(rh);
6609             DECODE_PRINTF("\n");
6610             TRACE_AND_STEP();
6611             store_data_long(destoffset, *srcreg);
6612         }
6613         else {
6614             u16 *srcreg;
6615 
6616             destoffset = decode_rm01_address(rl);
6617             DECODE_PRINTF(",");
6618             srcreg = DECODE_RM_WORD_REGISTER(rh);
6619             DECODE_PRINTF("\n");
6620             TRACE_AND_STEP();
6621             store_data_word(destoffset, *srcreg);
6622         }
6623         break;
6624     case 2:
6625         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6626             u32 *srcreg;
6627 
6628             destoffset = decode_rm10_address(rl);
6629             DECODE_PRINTF(",");
6630             srcreg = DECODE_RM_LONG_REGISTER(rh);
6631             DECODE_PRINTF("\n");
6632             TRACE_AND_STEP();
6633             store_data_long(destoffset, *srcreg);
6634         }
6635         else {
6636             u16 *srcreg;
6637 
6638             destoffset = decode_rm10_address(rl);
6639             DECODE_PRINTF(",");
6640             srcreg = DECODE_RM_WORD_REGISTER(rh);
6641             DECODE_PRINTF("\n");
6642             TRACE_AND_STEP();
6643             store_data_word(destoffset, *srcreg);
6644         }
6645         break;
6646     case 3:                    /* register to register */
6647         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6648             u32 *destreg, *srcreg;
6649 
6650             destreg = DECODE_RM_LONG_REGISTER(rl);
6651             DECODE_PRINTF(",");
6652             srcreg = DECODE_RM_LONG_REGISTER(rh);
6653             DECODE_PRINTF("\n");
6654             TRACE_AND_STEP();
6655             *destreg = *srcreg;
6656         }
6657         else {
6658             u16 *destreg, *srcreg;
6659 
6660             destreg = DECODE_RM_WORD_REGISTER(rl);
6661             DECODE_PRINTF(",");
6662             srcreg = DECODE_RM_WORD_REGISTER(rh);
6663             DECODE_PRINTF("\n");
6664             TRACE_AND_STEP();
6665             *destreg = *srcreg;
6666         }
6667         break;
6668     }
6669     DECODE_CLEAR_SEGOVR();
6670     END_OF_INSTR();
6671 }
6672 
6673 /****************************************************************************
6674 REMARKS:
6675 Handles opcode 0x8a
6676 ****************************************************************************/
6677 static void
x86emuOp_mov_byte_R_RM(u8 X86EMU_UNUSED (op1))6678 x86emuOp_mov_byte_R_RM(u8 X86EMU_UNUSED(op1))
6679 {
6680     int mod, rl, rh;
6681     u8 *destreg, *srcreg;
6682     uint srcoffset;
6683     u8 srcval;
6684 
6685     START_OF_INSTR();
6686     DECODE_PRINTF("MOV\t");
6687     FETCH_DECODE_MODRM(mod, rh, rl);
6688     switch (mod) {
6689     case 0:
6690         destreg = DECODE_RM_BYTE_REGISTER(rh);
6691         DECODE_PRINTF(",");
6692         srcoffset = decode_rm00_address(rl);
6693         srcval = fetch_data_byte(srcoffset);
6694         DECODE_PRINTF("\n");
6695         TRACE_AND_STEP();
6696         *destreg = srcval;
6697         break;
6698     case 1:
6699         destreg = DECODE_RM_BYTE_REGISTER(rh);
6700         DECODE_PRINTF(",");
6701         srcoffset = decode_rm01_address(rl);
6702         srcval = fetch_data_byte(srcoffset);
6703         DECODE_PRINTF("\n");
6704         TRACE_AND_STEP();
6705         *destreg = srcval;
6706         break;
6707     case 2:
6708         destreg = DECODE_RM_BYTE_REGISTER(rh);
6709         DECODE_PRINTF(",");
6710         srcoffset = decode_rm10_address(rl);
6711         srcval = fetch_data_byte(srcoffset);
6712         DECODE_PRINTF("\n");
6713         TRACE_AND_STEP();
6714         *destreg = srcval;
6715         break;
6716     case 3:                    /* register to register */
6717         destreg = DECODE_RM_BYTE_REGISTER(rh);
6718         DECODE_PRINTF(",");
6719         srcreg = DECODE_RM_BYTE_REGISTER(rl);
6720         DECODE_PRINTF("\n");
6721         TRACE_AND_STEP();
6722         *destreg = *srcreg;
6723         break;
6724     }
6725     DECODE_CLEAR_SEGOVR();
6726     END_OF_INSTR();
6727 }
6728 
6729 /****************************************************************************
6730 REMARKS:
6731 Handles opcode 0x8b
6732 ****************************************************************************/
6733 static void
x86emuOp_mov_word_R_RM(u8 X86EMU_UNUSED (op1))6734 x86emuOp_mov_word_R_RM(u8 X86EMU_UNUSED(op1))
6735 {
6736     int mod, rl, rh;
6737     uint srcoffset;
6738 
6739     START_OF_INSTR();
6740     DECODE_PRINTF("MOV\t");
6741     FETCH_DECODE_MODRM(mod, rh, rl);
6742     switch (mod) {
6743     case 0:
6744         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6745             u32 *destreg;
6746             u32 srcval;
6747 
6748             destreg = DECODE_RM_LONG_REGISTER(rh);
6749             DECODE_PRINTF(",");
6750             srcoffset = decode_rm00_address(rl);
6751             srcval = fetch_data_long(srcoffset);
6752             DECODE_PRINTF("\n");
6753             TRACE_AND_STEP();
6754             *destreg = srcval;
6755         }
6756         else {
6757             u16 *destreg;
6758             u16 srcval;
6759 
6760             destreg = DECODE_RM_WORD_REGISTER(rh);
6761             DECODE_PRINTF(",");
6762             srcoffset = decode_rm00_address(rl);
6763             srcval = fetch_data_word(srcoffset);
6764             DECODE_PRINTF("\n");
6765             TRACE_AND_STEP();
6766             *destreg = srcval;
6767         }
6768         break;
6769     case 1:
6770         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6771             u32 *destreg;
6772             u32 srcval;
6773 
6774             destreg = DECODE_RM_LONG_REGISTER(rh);
6775             DECODE_PRINTF(",");
6776             srcoffset = decode_rm01_address(rl);
6777             srcval = fetch_data_long(srcoffset);
6778             DECODE_PRINTF("\n");
6779             TRACE_AND_STEP();
6780             *destreg = srcval;
6781         }
6782         else {
6783             u16 *destreg;
6784             u16 srcval;
6785 
6786             destreg = DECODE_RM_WORD_REGISTER(rh);
6787             DECODE_PRINTF(",");
6788             srcoffset = decode_rm01_address(rl);
6789             srcval = fetch_data_word(srcoffset);
6790             DECODE_PRINTF("\n");
6791             TRACE_AND_STEP();
6792             *destreg = srcval;
6793         }
6794         break;
6795     case 2:
6796         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6797             u32 *destreg;
6798             u32 srcval;
6799 
6800             destreg = DECODE_RM_LONG_REGISTER(rh);
6801             DECODE_PRINTF(",");
6802             srcoffset = decode_rm10_address(rl);
6803             srcval = fetch_data_long(srcoffset);
6804             DECODE_PRINTF("\n");
6805             TRACE_AND_STEP();
6806             *destreg = srcval;
6807         }
6808         else {
6809             u16 *destreg;
6810             u16 srcval;
6811 
6812             destreg = DECODE_RM_WORD_REGISTER(rh);
6813             DECODE_PRINTF(",");
6814             srcoffset = decode_rm10_address(rl);
6815             srcval = fetch_data_word(srcoffset);
6816             DECODE_PRINTF("\n");
6817             TRACE_AND_STEP();
6818             *destreg = srcval;
6819         }
6820         break;
6821     case 3:                    /* register to register */
6822         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6823             u32 *destreg, *srcreg;
6824 
6825             destreg = DECODE_RM_LONG_REGISTER(rh);
6826             DECODE_PRINTF(",");
6827             srcreg = DECODE_RM_LONG_REGISTER(rl);
6828             DECODE_PRINTF("\n");
6829             TRACE_AND_STEP();
6830             *destreg = *srcreg;
6831         }
6832         else {
6833             u16 *destreg, *srcreg;
6834 
6835             destreg = DECODE_RM_WORD_REGISTER(rh);
6836             DECODE_PRINTF(",");
6837             srcreg = DECODE_RM_WORD_REGISTER(rl);
6838             DECODE_PRINTF("\n");
6839             TRACE_AND_STEP();
6840             *destreg = *srcreg;
6841         }
6842         break;
6843     }
6844     DECODE_CLEAR_SEGOVR();
6845     END_OF_INSTR();
6846 }
6847 
6848 /****************************************************************************
6849 REMARKS:
6850 Handles opcode 0x8c
6851 ****************************************************************************/
6852 static void
x86emuOp_mov_word_RM_SR(u8 X86EMU_UNUSED (op1))6853 x86emuOp_mov_word_RM_SR(u8 X86EMU_UNUSED(op1))
6854 {
6855     int mod, rl, rh;
6856     u16 *destreg, *srcreg;
6857     uint destoffset;
6858     u16 destval;
6859 
6860     START_OF_INSTR();
6861     DECODE_PRINTF("MOV\t");
6862     FETCH_DECODE_MODRM(mod, rh, rl);
6863     switch (mod) {
6864     case 0:
6865         destoffset = decode_rm00_address(rl);
6866         DECODE_PRINTF(",");
6867         srcreg = decode_rm_seg_register(rh);
6868         DECODE_PRINTF("\n");
6869         TRACE_AND_STEP();
6870         destval = *srcreg;
6871         store_data_word(destoffset, destval);
6872         break;
6873     case 1:
6874         destoffset = decode_rm01_address(rl);
6875         DECODE_PRINTF(",");
6876         srcreg = decode_rm_seg_register(rh);
6877         DECODE_PRINTF("\n");
6878         TRACE_AND_STEP();
6879         destval = *srcreg;
6880         store_data_word(destoffset, destval);
6881         break;
6882     case 2:
6883         destoffset = decode_rm10_address(rl);
6884         DECODE_PRINTF(",");
6885         srcreg = decode_rm_seg_register(rh);
6886         DECODE_PRINTF("\n");
6887         TRACE_AND_STEP();
6888         destval = *srcreg;
6889         store_data_word(destoffset, destval);
6890         break;
6891     case 3:                    /* register to register */
6892         destreg = DECODE_RM_WORD_REGISTER(rl);
6893         DECODE_PRINTF(",");
6894         srcreg = decode_rm_seg_register(rh);
6895         DECODE_PRINTF("\n");
6896         TRACE_AND_STEP();
6897         *destreg = *srcreg;
6898         break;
6899     }
6900     DECODE_CLEAR_SEGOVR();
6901     END_OF_INSTR();
6902 }
6903 
6904 /****************************************************************************
6905 REMARKS:
6906 Handles opcode 0x8d
6907 ****************************************************************************/
6908 static void
x86emuOp_lea_word_R_M(u8 X86EMU_UNUSED (op1))6909 x86emuOp_lea_word_R_M(u8 X86EMU_UNUSED(op1))
6910 {
6911     int mod, rl, rh;
6912     uint destoffset;
6913 
6914     START_OF_INSTR();
6915     DECODE_PRINTF("LEA\t");
6916     FETCH_DECODE_MODRM(mod, rh, rl);
6917     switch (mod) {
6918     case 0:
6919         if (M.x86.mode & SYSMODE_PREFIX_ADDR) {
6920             u32 *srcreg = DECODE_RM_LONG_REGISTER(rh);
6921 
6922             DECODE_PRINTF(",");
6923             destoffset = decode_rm00_address(rl);
6924             DECODE_PRINTF("\n");
6925             TRACE_AND_STEP();
6926             *srcreg = (u32) destoffset;
6927         }
6928         else {
6929             u16 *srcreg = DECODE_RM_WORD_REGISTER(rh);
6930 
6931             DECODE_PRINTF(",");
6932             destoffset = decode_rm00_address(rl);
6933             DECODE_PRINTF("\n");
6934             TRACE_AND_STEP();
6935             *srcreg = (u16) destoffset;
6936         }
6937         break;
6938     case 1:
6939         if (M.x86.mode & SYSMODE_PREFIX_ADDR) {
6940             u32 *srcreg = DECODE_RM_LONG_REGISTER(rh);
6941 
6942             DECODE_PRINTF(",");
6943             destoffset = decode_rm01_address(rl);
6944             DECODE_PRINTF("\n");
6945             TRACE_AND_STEP();
6946             *srcreg = (u32) destoffset;
6947         }
6948         else {
6949             u16 *srcreg = DECODE_RM_WORD_REGISTER(rh);
6950 
6951             DECODE_PRINTF(",");
6952             destoffset = decode_rm01_address(rl);
6953             DECODE_PRINTF("\n");
6954             TRACE_AND_STEP();
6955             *srcreg = (u16) destoffset;
6956         }
6957         break;
6958     case 2:
6959         if (M.x86.mode & SYSMODE_PREFIX_ADDR) {
6960             u32 *srcreg = DECODE_RM_LONG_REGISTER(rh);
6961 
6962             DECODE_PRINTF(",");
6963             destoffset = decode_rm10_address(rl);
6964             DECODE_PRINTF("\n");
6965             TRACE_AND_STEP();
6966             *srcreg = (u32) destoffset;
6967         }
6968         else {
6969             u16 *srcreg = DECODE_RM_WORD_REGISTER(rh);
6970 
6971             DECODE_PRINTF(",");
6972             destoffset = decode_rm10_address(rl);
6973             DECODE_PRINTF("\n");
6974             TRACE_AND_STEP();
6975             *srcreg = (u16) destoffset;
6976         }
6977         break;
6978     case 3:                    /* register to register */
6979         /* undefined.  Do nothing. */
6980         break;
6981     }
6982     DECODE_CLEAR_SEGOVR();
6983     END_OF_INSTR();
6984 }
6985 
6986 /****************************************************************************
6987 REMARKS:
6988 Handles opcode 0x8e
6989 ****************************************************************************/
6990 static void
x86emuOp_mov_word_SR_RM(u8 X86EMU_UNUSED (op1))6991 x86emuOp_mov_word_SR_RM(u8 X86EMU_UNUSED(op1))
6992 {
6993     int mod, rl, rh;
6994     u16 *destreg, *srcreg;
6995     uint srcoffset;
6996     u16 srcval;
6997 
6998     START_OF_INSTR();
6999     DECODE_PRINTF("MOV\t");
7000     FETCH_DECODE_MODRM(mod, rh, rl);
7001     switch (mod) {
7002     case 0:
7003         destreg = decode_rm_seg_register(rh);
7004         DECODE_PRINTF(",");
7005         srcoffset = decode_rm00_address(rl);
7006         srcval = fetch_data_word(srcoffset);
7007         DECODE_PRINTF("\n");
7008         TRACE_AND_STEP();
7009         *destreg = srcval;
7010         break;
7011     case 1:
7012         destreg = decode_rm_seg_register(rh);
7013         DECODE_PRINTF(",");
7014         srcoffset = decode_rm01_address(rl);
7015         srcval = fetch_data_word(srcoffset);
7016         DECODE_PRINTF("\n");
7017         TRACE_AND_STEP();
7018         *destreg = srcval;
7019         break;
7020     case 2:
7021         destreg = decode_rm_seg_register(rh);
7022         DECODE_PRINTF(",");
7023         srcoffset = decode_rm10_address(rl);
7024         srcval = fetch_data_word(srcoffset);
7025         DECODE_PRINTF("\n");
7026         TRACE_AND_STEP();
7027         *destreg = srcval;
7028         break;
7029     case 3:                    /* register to register */
7030         destreg = decode_rm_seg_register(rh);
7031         DECODE_PRINTF(",");
7032         srcreg = DECODE_RM_WORD_REGISTER(rl);
7033         DECODE_PRINTF("\n");
7034         TRACE_AND_STEP();
7035         *destreg = *srcreg;
7036         break;
7037     }
7038     /*
7039      * Clean up, and reset all the R_xSP pointers to the correct
7040      * locations.  This is about 3x too much overhead (doing all the
7041      * segreg ptrs when only one is needed, but this instruction
7042      * *cannot* be that common, and this isn't too much work anyway.
7043      */
7044     DECODE_CLEAR_SEGOVR();
7045     END_OF_INSTR();
7046 }
7047 
7048 /****************************************************************************
7049 REMARKS:
7050 Handles opcode 0x8f
7051 ****************************************************************************/
7052 static void
x86emuOp_pop_RM(u8 X86EMU_UNUSED (op1))7053 x86emuOp_pop_RM(u8 X86EMU_UNUSED(op1))
7054 {
7055     int mod, rl, rh;
7056     uint destoffset;
7057 
7058     START_OF_INSTR();
7059     DECODE_PRINTF("POP\t");
7060     FETCH_DECODE_MODRM(mod, rh, rl);
7061     if (rh != 0) {
7062         DECODE_PRINTF("ILLEGAL DECODE OF OPCODE 8F\n");
7063         HALT_SYS();
7064     }
7065     switch (mod) {
7066     case 0:
7067         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7068             u32 destval;
7069 
7070             destoffset = decode_rm00_address(rl);
7071             DECODE_PRINTF("\n");
7072             TRACE_AND_STEP();
7073             destval = pop_long();
7074             store_data_long(destoffset, destval);
7075         }
7076         else {
7077             u16 destval;
7078 
7079             destoffset = decode_rm00_address(rl);
7080             DECODE_PRINTF("\n");
7081             TRACE_AND_STEP();
7082             destval = pop_word();
7083             store_data_word(destoffset, destval);
7084         }
7085         break;
7086     case 1:
7087         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7088             u32 destval;
7089 
7090             destoffset = decode_rm01_address(rl);
7091             DECODE_PRINTF("\n");
7092             TRACE_AND_STEP();
7093             destval = pop_long();
7094             store_data_long(destoffset, destval);
7095         }
7096         else {
7097             u16 destval;
7098 
7099             destoffset = decode_rm01_address(rl);
7100             DECODE_PRINTF("\n");
7101             TRACE_AND_STEP();
7102             destval = pop_word();
7103             store_data_word(destoffset, destval);
7104         }
7105         break;
7106     case 2:
7107         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7108             u32 destval;
7109 
7110             destoffset = decode_rm10_address(rl);
7111             DECODE_PRINTF("\n");
7112             TRACE_AND_STEP();
7113             destval = pop_long();
7114             store_data_long(destoffset, destval);
7115         }
7116         else {
7117             u16 destval;
7118 
7119             destoffset = decode_rm10_address(rl);
7120             DECODE_PRINTF("\n");
7121             TRACE_AND_STEP();
7122             destval = pop_word();
7123             store_data_word(destoffset, destval);
7124         }
7125         break;
7126     case 3:                    /* register to register */
7127         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7128             u32 *destreg;
7129 
7130             destreg = DECODE_RM_LONG_REGISTER(rl);
7131             DECODE_PRINTF("\n");
7132             TRACE_AND_STEP();
7133             *destreg = pop_long();
7134         }
7135         else {
7136             u16 *destreg;
7137 
7138             destreg = DECODE_RM_WORD_REGISTER(rl);
7139             DECODE_PRINTF("\n");
7140             TRACE_AND_STEP();
7141             *destreg = pop_word();
7142         }
7143         break;
7144     }
7145     DECODE_CLEAR_SEGOVR();
7146     END_OF_INSTR();
7147 }
7148 
7149 /****************************************************************************
7150 REMARKS:
7151 Handles opcode 0x90
7152 ****************************************************************************/
7153 static void
x86emuOp_nop(u8 X86EMU_UNUSED (op1))7154 x86emuOp_nop(u8 X86EMU_UNUSED(op1))
7155 {
7156     START_OF_INSTR();
7157     DECODE_PRINTF("NOP\n");
7158     TRACE_AND_STEP();
7159     DECODE_CLEAR_SEGOVR();
7160     END_OF_INSTR();
7161 }
7162 
7163 /****************************************************************************
7164 REMARKS:
7165 Handles opcode 0x91
7166 ****************************************************************************/
7167 static void
x86emuOp_xchg_word_AX_CX(u8 X86EMU_UNUSED (op1))7168 x86emuOp_xchg_word_AX_CX(u8 X86EMU_UNUSED(op1))
7169 {
7170     u32 tmp;
7171 
7172     START_OF_INSTR();
7173     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7174         DECODE_PRINTF("XCHG\tEAX,ECX\n");
7175     }
7176     else {
7177         DECODE_PRINTF("XCHG\tAX,CX\n");
7178     }
7179     TRACE_AND_STEP();
7180     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7181         tmp = M.x86.R_EAX;
7182         M.x86.R_EAX = M.x86.R_ECX;
7183         M.x86.R_ECX = tmp;
7184     }
7185     else {
7186         tmp = M.x86.R_AX;
7187         M.x86.R_AX = M.x86.R_CX;
7188         M.x86.R_CX = (u16) tmp;
7189     }
7190     DECODE_CLEAR_SEGOVR();
7191     END_OF_INSTR();
7192 }
7193 
7194 /****************************************************************************
7195 REMARKS:
7196 Handles opcode 0x92
7197 ****************************************************************************/
7198 static void
x86emuOp_xchg_word_AX_DX(u8 X86EMU_UNUSED (op1))7199 x86emuOp_xchg_word_AX_DX(u8 X86EMU_UNUSED(op1))
7200 {
7201     u32 tmp;
7202 
7203     START_OF_INSTR();
7204     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7205         DECODE_PRINTF("XCHG\tEAX,EDX\n");
7206     }
7207     else {
7208         DECODE_PRINTF("XCHG\tAX,DX\n");
7209     }
7210     TRACE_AND_STEP();
7211     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7212         tmp = M.x86.R_EAX;
7213         M.x86.R_EAX = M.x86.R_EDX;
7214         M.x86.R_EDX = tmp;
7215     }
7216     else {
7217         tmp = M.x86.R_AX;
7218         M.x86.R_AX = M.x86.R_DX;
7219         M.x86.R_DX = (u16) tmp;
7220     }
7221     DECODE_CLEAR_SEGOVR();
7222     END_OF_INSTR();
7223 }
7224 
7225 /****************************************************************************
7226 REMARKS:
7227 Handles opcode 0x93
7228 ****************************************************************************/
7229 static void
x86emuOp_xchg_word_AX_BX(u8 X86EMU_UNUSED (op1))7230 x86emuOp_xchg_word_AX_BX(u8 X86EMU_UNUSED(op1))
7231 {
7232     u32 tmp;
7233 
7234     START_OF_INSTR();
7235     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7236         DECODE_PRINTF("XCHG\tEAX,EBX\n");
7237     }
7238     else {
7239         DECODE_PRINTF("XCHG\tAX,BX\n");
7240     }
7241     TRACE_AND_STEP();
7242     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7243         tmp = M.x86.R_EAX;
7244         M.x86.R_EAX = M.x86.R_EBX;
7245         M.x86.R_EBX = tmp;
7246     }
7247     else {
7248         tmp = M.x86.R_AX;
7249         M.x86.R_AX = M.x86.R_BX;
7250         M.x86.R_BX = (u16) tmp;
7251     }
7252     DECODE_CLEAR_SEGOVR();
7253     END_OF_INSTR();
7254 }
7255 
7256 /****************************************************************************
7257 REMARKS:
7258 Handles opcode 0x94
7259 ****************************************************************************/
7260 static void
x86emuOp_xchg_word_AX_SP(u8 X86EMU_UNUSED (op1))7261 x86emuOp_xchg_word_AX_SP(u8 X86EMU_UNUSED(op1))
7262 {
7263     u32 tmp;
7264 
7265     START_OF_INSTR();
7266     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7267         DECODE_PRINTF("XCHG\tEAX,ESP\n");
7268     }
7269     else {
7270         DECODE_PRINTF("XCHG\tAX,SP\n");
7271     }
7272     TRACE_AND_STEP();
7273     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7274         tmp = M.x86.R_EAX;
7275         M.x86.R_EAX = M.x86.R_ESP;
7276         M.x86.R_ESP = tmp;
7277     }
7278     else {
7279         tmp = M.x86.R_AX;
7280         M.x86.R_AX = M.x86.R_SP;
7281         M.x86.R_SP = (u16) tmp;
7282     }
7283     DECODE_CLEAR_SEGOVR();
7284     END_OF_INSTR();
7285 }
7286 
7287 /****************************************************************************
7288 REMARKS:
7289 Handles opcode 0x95
7290 ****************************************************************************/
7291 static void
x86emuOp_xchg_word_AX_BP(u8 X86EMU_UNUSED (op1))7292 x86emuOp_xchg_word_AX_BP(u8 X86EMU_UNUSED(op1))
7293 {
7294     u32 tmp;
7295 
7296     START_OF_INSTR();
7297     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7298         DECODE_PRINTF("XCHG\tEAX,EBP\n");
7299     }
7300     else {
7301         DECODE_PRINTF("XCHG\tAX,BP\n");
7302     }
7303     TRACE_AND_STEP();
7304     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7305         tmp = M.x86.R_EAX;
7306         M.x86.R_EAX = M.x86.R_EBP;
7307         M.x86.R_EBP = tmp;
7308     }
7309     else {
7310         tmp = M.x86.R_AX;
7311         M.x86.R_AX = M.x86.R_BP;
7312         M.x86.R_BP = (u16) tmp;
7313     }
7314     DECODE_CLEAR_SEGOVR();
7315     END_OF_INSTR();
7316 }
7317 
7318 /****************************************************************************
7319 REMARKS:
7320 Handles opcode 0x96
7321 ****************************************************************************/
7322 static void
x86emuOp_xchg_word_AX_SI(u8 X86EMU_UNUSED (op1))7323 x86emuOp_xchg_word_AX_SI(u8 X86EMU_UNUSED(op1))
7324 {
7325     u32 tmp;
7326 
7327     START_OF_INSTR();
7328     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7329         DECODE_PRINTF("XCHG\tEAX,ESI\n");
7330     }
7331     else {
7332         DECODE_PRINTF("XCHG\tAX,SI\n");
7333     }
7334     TRACE_AND_STEP();
7335     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7336         tmp = M.x86.R_EAX;
7337         M.x86.R_EAX = M.x86.R_ESI;
7338         M.x86.R_ESI = tmp;
7339     }
7340     else {
7341         tmp = M.x86.R_AX;
7342         M.x86.R_AX = M.x86.R_SI;
7343         M.x86.R_SI = (u16) tmp;
7344     }
7345     DECODE_CLEAR_SEGOVR();
7346     END_OF_INSTR();
7347 }
7348 
7349 /****************************************************************************
7350 REMARKS:
7351 Handles opcode 0x97
7352 ****************************************************************************/
7353 static void
x86emuOp_xchg_word_AX_DI(u8 X86EMU_UNUSED (op1))7354 x86emuOp_xchg_word_AX_DI(u8 X86EMU_UNUSED(op1))
7355 {
7356     u32 tmp;
7357 
7358     START_OF_INSTR();
7359     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7360         DECODE_PRINTF("XCHG\tEAX,EDI\n");
7361     }
7362     else {
7363         DECODE_PRINTF("XCHG\tAX,DI\n");
7364     }
7365     TRACE_AND_STEP();
7366     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7367         tmp = M.x86.R_EAX;
7368         M.x86.R_EAX = M.x86.R_EDI;
7369         M.x86.R_EDI = tmp;
7370     }
7371     else {
7372         tmp = M.x86.R_AX;
7373         M.x86.R_AX = M.x86.R_DI;
7374         M.x86.R_DI = (u16) tmp;
7375     }
7376     DECODE_CLEAR_SEGOVR();
7377     END_OF_INSTR();
7378 }
7379 
7380 /****************************************************************************
7381 REMARKS:
7382 Handles opcode 0x98
7383 ****************************************************************************/
7384 static void
x86emuOp_cbw(u8 X86EMU_UNUSED (op1))7385 x86emuOp_cbw(u8 X86EMU_UNUSED(op1))
7386 {
7387     START_OF_INSTR();
7388     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7389         DECODE_PRINTF("CWDE\n");
7390     }
7391     else {
7392         DECODE_PRINTF("CBW\n");
7393     }
7394     TRACE_AND_STEP();
7395     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7396         if (M.x86.R_AX & 0x8000) {
7397             M.x86.R_EAX |= 0xffff0000;
7398         }
7399         else {
7400             M.x86.R_EAX &= 0x0000ffff;
7401         }
7402     }
7403     else {
7404         if (M.x86.R_AL & 0x80) {
7405             M.x86.R_AH = 0xff;
7406         }
7407         else {
7408             M.x86.R_AH = 0x0;
7409         }
7410     }
7411     DECODE_CLEAR_SEGOVR();
7412     END_OF_INSTR();
7413 }
7414 
7415 /****************************************************************************
7416 REMARKS:
7417 Handles opcode 0x99
7418 ****************************************************************************/
7419 static void
x86emuOp_cwd(u8 X86EMU_UNUSED (op1))7420 x86emuOp_cwd(u8 X86EMU_UNUSED(op1))
7421 {
7422     START_OF_INSTR();
7423     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7424         DECODE_PRINTF("CDQ\n");
7425     }
7426     else {
7427         DECODE_PRINTF("CWD\n");
7428     }
7429     DECODE_PRINTF("CWD\n");
7430     TRACE_AND_STEP();
7431     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7432         if (M.x86.R_EAX & 0x80000000) {
7433             M.x86.R_EDX = 0xffffffff;
7434         }
7435         else {
7436             M.x86.R_EDX = 0x0;
7437         }
7438     }
7439     else {
7440         if (M.x86.R_AX & 0x8000) {
7441             M.x86.R_DX = 0xffff;
7442         }
7443         else {
7444             M.x86.R_DX = 0x0;
7445         }
7446     }
7447     DECODE_CLEAR_SEGOVR();
7448     END_OF_INSTR();
7449 }
7450 
7451 /****************************************************************************
7452 REMARKS:
7453 Handles opcode 0x9a
7454 ****************************************************************************/
7455 static void
x86emuOp_call_far_IMM(u8 X86EMU_UNUSED (op1))7456 x86emuOp_call_far_IMM(u8 X86EMU_UNUSED(op1))
7457 {
7458     u32 farseg, faroff;
7459 
7460     START_OF_INSTR();
7461     DECODE_PRINTF("CALL\t");
7462     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7463         faroff = fetch_long_imm();
7464         farseg = fetch_word_imm();
7465     }
7466     else {
7467         faroff = fetch_word_imm();
7468         farseg = fetch_word_imm();
7469     }
7470     DECODE_PRINTF2("%04x:", farseg);
7471     DECODE_PRINTF2("%04x\n", faroff);
7472     CALL_TRACE(M.x86.saved_cs, M.x86.saved_ip, farseg, faroff, "FAR ");
7473 
7474     /* XXX
7475      *
7476      * Hooked interrupt vectors calling into our "BIOS" will cause
7477      * problems unless all intersegment stuff is checked for BIOS
7478      * access.  Check needed here.  For moment, let it alone.
7479      */
7480     TRACE_AND_STEP();
7481     push_word(M.x86.R_CS);
7482     M.x86.R_CS = farseg;
7483     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7484         push_long(M.x86.R_EIP);
7485     }
7486     else {
7487         push_word(M.x86.R_IP);
7488     }
7489     M.x86.R_EIP = faroff & 0xffff;
7490     DECODE_CLEAR_SEGOVR();
7491     END_OF_INSTR();
7492 }
7493 
7494 /****************************************************************************
7495 REMARKS:
7496 Handles opcode 0x9b
7497 ****************************************************************************/
7498 static void
x86emuOp_wait(u8 X86EMU_UNUSED (op1))7499 x86emuOp_wait(u8 X86EMU_UNUSED(op1))
7500 {
7501     START_OF_INSTR();
7502     DECODE_PRINTF("WAIT");
7503     TRACE_AND_STEP();
7504     /* NADA.  */
7505     DECODE_CLEAR_SEGOVR();
7506     END_OF_INSTR();
7507 }
7508 
7509 /****************************************************************************
7510 REMARKS:
7511 Handles opcode 0x9c
7512 ****************************************************************************/
7513 static void
x86emuOp_pushf_word(u8 X86EMU_UNUSED (op1))7514 x86emuOp_pushf_word(u8 X86EMU_UNUSED(op1))
7515 {
7516     u32 flags;
7517 
7518     START_OF_INSTR();
7519     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7520         DECODE_PRINTF("PUSHFD\n");
7521     }
7522     else {
7523         DECODE_PRINTF("PUSHF\n");
7524     }
7525     TRACE_AND_STEP();
7526 
7527     /* clear out *all* bits not representing flags, and turn on real bits */
7528     flags = (M.x86.R_EFLG & F_MSK) | F_ALWAYS_ON;
7529     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7530         push_long(flags);
7531     }
7532     else {
7533         push_word((u16) flags);
7534     }
7535     DECODE_CLEAR_SEGOVR();
7536     END_OF_INSTR();
7537 }
7538 
7539 /****************************************************************************
7540 REMARKS:
7541 Handles opcode 0x9d
7542 ****************************************************************************/
7543 static void
x86emuOp_popf_word(u8 X86EMU_UNUSED (op1))7544 x86emuOp_popf_word(u8 X86EMU_UNUSED(op1))
7545 {
7546     START_OF_INSTR();
7547     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7548         DECODE_PRINTF("POPFD\n");
7549     }
7550     else {
7551         DECODE_PRINTF("POPF\n");
7552     }
7553     TRACE_AND_STEP();
7554     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7555         M.x86.R_EFLG = pop_long();
7556     }
7557     else {
7558         M.x86.R_FLG = pop_word();
7559     }
7560     DECODE_CLEAR_SEGOVR();
7561     END_OF_INSTR();
7562 }
7563 
7564 /****************************************************************************
7565 REMARKS:
7566 Handles opcode 0x9e
7567 ****************************************************************************/
7568 static void
x86emuOp_sahf(u8 X86EMU_UNUSED (op1))7569 x86emuOp_sahf(u8 X86EMU_UNUSED(op1))
7570 {
7571     START_OF_INSTR();
7572     DECODE_PRINTF("SAHF\n");
7573     TRACE_AND_STEP();
7574     /* clear the lower bits of the flag register */
7575     M.x86.R_FLG &= 0xffffff00;
7576     /* or in the AH register into the flags register */
7577     M.x86.R_FLG |= M.x86.R_AH;
7578     DECODE_CLEAR_SEGOVR();
7579     END_OF_INSTR();
7580 }
7581 
7582 /****************************************************************************
7583 REMARKS:
7584 Handles opcode 0x9f
7585 ****************************************************************************/
7586 static void
x86emuOp_lahf(u8 X86EMU_UNUSED (op1))7587 x86emuOp_lahf(u8 X86EMU_UNUSED(op1))
7588 {
7589     START_OF_INSTR();
7590     DECODE_PRINTF("LAHF\n");
7591     TRACE_AND_STEP();
7592     M.x86.R_AH = (u8) (M.x86.R_FLG & 0xff);
7593     /*undocumented TC++ behavior??? Nope.  It's documented, but
7594        you have too look real hard to notice it. */
7595     M.x86.R_AH |= 0x2;
7596     DECODE_CLEAR_SEGOVR();
7597     END_OF_INSTR();
7598 }
7599 
7600 /****************************************************************************
7601 REMARKS:
7602 Handles opcode 0xa0
7603 ****************************************************************************/
7604 static void
x86emuOp_mov_AL_M_IMM(u8 X86EMU_UNUSED (op1))7605 x86emuOp_mov_AL_M_IMM(u8 X86EMU_UNUSED(op1))
7606 {
7607     u16 offset;
7608 
7609     START_OF_INSTR();
7610     DECODE_PRINTF("MOV\tAL,");
7611     offset = fetch_word_imm();
7612     DECODE_PRINTF2("[%04x]\n", offset);
7613     TRACE_AND_STEP();
7614     M.x86.R_AL = fetch_data_byte(offset);
7615     DECODE_CLEAR_SEGOVR();
7616     END_OF_INSTR();
7617 }
7618 
7619 /****************************************************************************
7620 REMARKS:
7621 Handles opcode 0xa1
7622 ****************************************************************************/
7623 static void
x86emuOp_mov_AX_M_IMM(u8 X86EMU_UNUSED (op1))7624 x86emuOp_mov_AX_M_IMM(u8 X86EMU_UNUSED(op1))
7625 {
7626     u16 offset;
7627 
7628     START_OF_INSTR();
7629     offset = fetch_word_imm();
7630     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7631         DECODE_PRINTF2("MOV\tEAX,[%04x]\n", offset);
7632     }
7633     else {
7634         DECODE_PRINTF2("MOV\tAX,[%04x]\n", offset);
7635     }
7636     TRACE_AND_STEP();
7637     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7638         M.x86.R_EAX = fetch_data_long(offset);
7639     }
7640     else {
7641         M.x86.R_AX = fetch_data_word(offset);
7642     }
7643     DECODE_CLEAR_SEGOVR();
7644     END_OF_INSTR();
7645 }
7646 
7647 /****************************************************************************
7648 REMARKS:
7649 Handles opcode 0xa2
7650 ****************************************************************************/
7651 static void
x86emuOp_mov_M_AL_IMM(u8 X86EMU_UNUSED (op1))7652 x86emuOp_mov_M_AL_IMM(u8 X86EMU_UNUSED(op1))
7653 {
7654     u16 offset;
7655 
7656     START_OF_INSTR();
7657     DECODE_PRINTF("MOV\t");
7658     offset = fetch_word_imm();
7659     DECODE_PRINTF2("[%04x],AL\n", offset);
7660     TRACE_AND_STEP();
7661     store_data_byte(offset, M.x86.R_AL);
7662     DECODE_CLEAR_SEGOVR();
7663     END_OF_INSTR();
7664 }
7665 
7666 /****************************************************************************
7667 REMARKS:
7668 Handles opcode 0xa3
7669 ****************************************************************************/
7670 static void
x86emuOp_mov_M_AX_IMM(u8 X86EMU_UNUSED (op1))7671 x86emuOp_mov_M_AX_IMM(u8 X86EMU_UNUSED(op1))
7672 {
7673     u16 offset;
7674 
7675     START_OF_INSTR();
7676     offset = fetch_word_imm();
7677     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7678         DECODE_PRINTF2("MOV\t[%04x],EAX\n", offset);
7679     }
7680     else {
7681         DECODE_PRINTF2("MOV\t[%04x],AX\n", offset);
7682     }
7683     TRACE_AND_STEP();
7684     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7685         store_data_long(offset, M.x86.R_EAX);
7686     }
7687     else {
7688         store_data_word(offset, M.x86.R_AX);
7689     }
7690     DECODE_CLEAR_SEGOVR();
7691     END_OF_INSTR();
7692 }
7693 
7694 /****************************************************************************
7695 REMARKS:
7696 Handles opcode 0xa4
7697 ****************************************************************************/
7698 static void
x86emuOp_movs_byte(u8 X86EMU_UNUSED (op1))7699 x86emuOp_movs_byte(u8 X86EMU_UNUSED(op1))
7700 {
7701     u8 val;
7702     u32 count;
7703     int inc;
7704 
7705     START_OF_INSTR();
7706     DECODE_PRINTF("MOVS\tBYTE\n");
7707     if (ACCESS_FLAG(F_DF))      /* down */
7708         inc = -1;
7709     else
7710         inc = 1;
7711     TRACE_AND_STEP();
7712     count = 1;
7713     if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
7714         /* dont care whether REPE or REPNE */
7715         /* move them until CX is ZERO. */
7716         count = M.x86.R_CX;
7717         M.x86.R_CX = 0;
7718         M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
7719     }
7720     while (count--) {
7721         val = fetch_data_byte(M.x86.R_SI);
7722         store_data_byte_abs(M.x86.R_ES, M.x86.R_DI, val);
7723         M.x86.R_SI += inc;
7724         M.x86.R_DI += inc;
7725     }
7726     DECODE_CLEAR_SEGOVR();
7727     END_OF_INSTR();
7728 }
7729 
7730 /****************************************************************************
7731 REMARKS:
7732 Handles opcode 0xa5
7733 ****************************************************************************/
7734 static void
x86emuOp_movs_word(u8 X86EMU_UNUSED (op1))7735 x86emuOp_movs_word(u8 X86EMU_UNUSED(op1))
7736 {
7737     u32 val;
7738     int inc;
7739     u32 count;
7740 
7741     START_OF_INSTR();
7742     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7743         DECODE_PRINTF("MOVS\tDWORD\n");
7744         if (ACCESS_FLAG(F_DF))  /* down */
7745             inc = -4;
7746         else
7747             inc = 4;
7748     }
7749     else {
7750         DECODE_PRINTF("MOVS\tWORD\n");
7751         if (ACCESS_FLAG(F_DF))  /* down */
7752             inc = -2;
7753         else
7754             inc = 2;
7755     }
7756     TRACE_AND_STEP();
7757     count = 1;
7758     if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
7759         /* dont care whether REPE or REPNE */
7760         /* move them until CX is ZERO. */
7761         count = M.x86.R_CX;
7762         M.x86.R_CX = 0;
7763         M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
7764     }
7765     while (count--) {
7766         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7767             val = fetch_data_long(M.x86.R_SI);
7768             store_data_long_abs(M.x86.R_ES, M.x86.R_DI, val);
7769         }
7770         else {
7771             val = fetch_data_word(M.x86.R_SI);
7772             store_data_word_abs(M.x86.R_ES, M.x86.R_DI, (u16) val);
7773         }
7774         M.x86.R_SI += inc;
7775         M.x86.R_DI += inc;
7776     }
7777     DECODE_CLEAR_SEGOVR();
7778     END_OF_INSTR();
7779 }
7780 
7781 /****************************************************************************
7782 REMARKS:
7783 Handles opcode 0xa6
7784 ****************************************************************************/
7785 static void
x86emuOp_cmps_byte(u8 X86EMU_UNUSED (op1))7786 x86emuOp_cmps_byte(u8 X86EMU_UNUSED(op1))
7787 {
7788     s8 val1, val2;
7789     int inc;
7790 
7791     START_OF_INSTR();
7792     DECODE_PRINTF("CMPS\tBYTE\n");
7793     TRACE_AND_STEP();
7794     if (ACCESS_FLAG(F_DF))      /* down */
7795         inc = -1;
7796     else
7797         inc = 1;
7798 
7799     if (M.x86.mode & SYSMODE_PREFIX_REPE) {
7800         /* REPE  */
7801         /* move them until CX is ZERO. */
7802         while (M.x86.R_CX != 0) {
7803             val1 = fetch_data_byte(M.x86.R_SI);
7804             val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
7805             cmp_byte(val1, val2);
7806             M.x86.R_CX -= 1;
7807             M.x86.R_SI += inc;
7808             M.x86.R_DI += inc;
7809             if (ACCESS_FLAG(F_ZF) == 0)
7810                 break;
7811         }
7812         M.x86.mode &= ~SYSMODE_PREFIX_REPE;
7813     }
7814     else if (M.x86.mode & SYSMODE_PREFIX_REPNE) {
7815         /* REPNE  */
7816         /* move them until CX is ZERO. */
7817         while (M.x86.R_CX != 0) {
7818             val1 = fetch_data_byte(M.x86.R_SI);
7819             val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
7820             cmp_byte(val1, val2);
7821             M.x86.R_CX -= 1;
7822             M.x86.R_SI += inc;
7823             M.x86.R_DI += inc;
7824             if (ACCESS_FLAG(F_ZF))
7825                 break;          /* zero flag set means equal */
7826         }
7827         M.x86.mode &= ~SYSMODE_PREFIX_REPNE;
7828     }
7829     else {
7830         val1 = fetch_data_byte(M.x86.R_SI);
7831         val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
7832         cmp_byte(val1, val2);
7833         M.x86.R_SI += inc;
7834         M.x86.R_DI += inc;
7835     }
7836     DECODE_CLEAR_SEGOVR();
7837     END_OF_INSTR();
7838 }
7839 
7840 /****************************************************************************
7841 REMARKS:
7842 Handles opcode 0xa7
7843 ****************************************************************************/
7844 static void
x86emuOp_cmps_word(u8 X86EMU_UNUSED (op1))7845 x86emuOp_cmps_word(u8 X86EMU_UNUSED(op1))
7846 {
7847     u32 val1, val2;
7848     int inc;
7849 
7850     START_OF_INSTR();
7851     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7852         DECODE_PRINTF("CMPS\tDWORD\n");
7853         if (ACCESS_FLAG(F_DF))  /* down */
7854             inc = -4;
7855         else
7856             inc = 4;
7857     }
7858     else {
7859         DECODE_PRINTF("CMPS\tWORD\n");
7860         if (ACCESS_FLAG(F_DF))  /* down */
7861             inc = -2;
7862         else
7863             inc = 2;
7864     }
7865     TRACE_AND_STEP();
7866     if (M.x86.mode & SYSMODE_PREFIX_REPE) {
7867         /* REPE  */
7868         /* move them until CX is ZERO. */
7869         while (M.x86.R_CX != 0) {
7870             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7871                 val1 = fetch_data_long(M.x86.R_SI);
7872                 val2 = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
7873                 cmp_long(val1, val2);
7874             }
7875             else {
7876                 val1 = fetch_data_word(M.x86.R_SI);
7877                 val2 = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
7878                 cmp_word((u16) val1, (u16) val2);
7879             }
7880             M.x86.R_CX -= 1;
7881             M.x86.R_SI += inc;
7882             M.x86.R_DI += inc;
7883             if (ACCESS_FLAG(F_ZF) == 0)
7884                 break;
7885         }
7886         M.x86.mode &= ~SYSMODE_PREFIX_REPE;
7887     }
7888     else if (M.x86.mode & SYSMODE_PREFIX_REPNE) {
7889         /* REPNE  */
7890         /* move them until CX is ZERO. */
7891         while (M.x86.R_CX != 0) {
7892             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7893                 val1 = fetch_data_long(M.x86.R_SI);
7894                 val2 = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
7895                 cmp_long(val1, val2);
7896             }
7897             else {
7898                 val1 = fetch_data_word(M.x86.R_SI);
7899                 val2 = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
7900                 cmp_word((u16) val1, (u16) val2);
7901             }
7902             M.x86.R_CX -= 1;
7903             M.x86.R_SI += inc;
7904             M.x86.R_DI += inc;
7905             if (ACCESS_FLAG(F_ZF))
7906                 break;          /* zero flag set means equal */
7907         }
7908         M.x86.mode &= ~SYSMODE_PREFIX_REPNE;
7909     }
7910     else {
7911         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7912             val1 = fetch_data_long(M.x86.R_SI);
7913             val2 = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
7914             cmp_long(val1, val2);
7915         }
7916         else {
7917             val1 = fetch_data_word(M.x86.R_SI);
7918             val2 = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
7919             cmp_word((u16) val1, (u16) val2);
7920         }
7921         M.x86.R_SI += inc;
7922         M.x86.R_DI += inc;
7923     }
7924     DECODE_CLEAR_SEGOVR();
7925     END_OF_INSTR();
7926 }
7927 
7928 /****************************************************************************
7929 REMARKS:
7930 Handles opcode 0xa8
7931 ****************************************************************************/
7932 static void
x86emuOp_test_AL_IMM(u8 X86EMU_UNUSED (op1))7933 x86emuOp_test_AL_IMM(u8 X86EMU_UNUSED(op1))
7934 {
7935     int imm;
7936 
7937     START_OF_INSTR();
7938     DECODE_PRINTF("TEST\tAL,");
7939     imm = fetch_byte_imm();
7940     DECODE_PRINTF2("%04x\n", imm);
7941     TRACE_AND_STEP();
7942     test_byte(M.x86.R_AL, (u8) imm);
7943     DECODE_CLEAR_SEGOVR();
7944     END_OF_INSTR();
7945 }
7946 
7947 /****************************************************************************
7948 REMARKS:
7949 Handles opcode 0xa9
7950 ****************************************************************************/
7951 static void
x86emuOp_test_AX_IMM(u8 X86EMU_UNUSED (op1))7952 x86emuOp_test_AX_IMM(u8 X86EMU_UNUSED(op1))
7953 {
7954     u32 srcval;
7955 
7956     START_OF_INSTR();
7957     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7958         DECODE_PRINTF("TEST\tEAX,");
7959         srcval = fetch_long_imm();
7960     }
7961     else {
7962         DECODE_PRINTF("TEST\tAX,");
7963         srcval = fetch_word_imm();
7964     }
7965     DECODE_PRINTF2("%x\n", srcval);
7966     TRACE_AND_STEP();
7967     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7968         test_long(M.x86.R_EAX, srcval);
7969     }
7970     else {
7971         test_word(M.x86.R_AX, (u16) srcval);
7972     }
7973     DECODE_CLEAR_SEGOVR();
7974     END_OF_INSTR();
7975 }
7976 
7977 /****************************************************************************
7978 REMARKS:
7979 Handles opcode 0xaa
7980 ****************************************************************************/
7981 static void
x86emuOp_stos_byte(u8 X86EMU_UNUSED (op1))7982 x86emuOp_stos_byte(u8 X86EMU_UNUSED(op1))
7983 {
7984     int inc;
7985 
7986     START_OF_INSTR();
7987     DECODE_PRINTF("STOS\tBYTE\n");
7988     if (ACCESS_FLAG(F_DF))      /* down */
7989         inc = -1;
7990     else
7991         inc = 1;
7992     TRACE_AND_STEP();
7993     if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
7994         /* dont care whether REPE or REPNE */
7995         /* move them until CX is ZERO. */
7996         while (M.x86.R_CX != 0) {
7997             store_data_byte_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_AL);
7998             M.x86.R_CX -= 1;
7999             M.x86.R_DI += inc;
8000         }
8001         M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
8002     }
8003     else {
8004         store_data_byte_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_AL);
8005         M.x86.R_DI += inc;
8006     }
8007     DECODE_CLEAR_SEGOVR();
8008     END_OF_INSTR();
8009 }
8010 
8011 /****************************************************************************
8012 REMARKS:
8013 Handles opcode 0xab
8014 ****************************************************************************/
8015 static void
x86emuOp_stos_word(u8 X86EMU_UNUSED (op1))8016 x86emuOp_stos_word(u8 X86EMU_UNUSED(op1))
8017 {
8018     int inc;
8019     u32 count;
8020 
8021     START_OF_INSTR();
8022     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8023         DECODE_PRINTF("STOS\tDWORD\n");
8024         if (ACCESS_FLAG(F_DF))  /* down */
8025             inc = -4;
8026         else
8027             inc = 4;
8028     }
8029     else {
8030         DECODE_PRINTF("STOS\tWORD\n");
8031         if (ACCESS_FLAG(F_DF))  /* down */
8032             inc = -2;
8033         else
8034             inc = 2;
8035     }
8036     TRACE_AND_STEP();
8037     count = 1;
8038     if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
8039         /* dont care whether REPE or REPNE */
8040         /* move them until CX is ZERO. */
8041         count = M.x86.R_CX;
8042         M.x86.R_CX = 0;
8043         M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
8044     }
8045     while (count--) {
8046         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8047             store_data_long_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_EAX);
8048         }
8049         else {
8050             store_data_word_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_AX);
8051         }
8052         M.x86.R_DI += inc;
8053     }
8054     DECODE_CLEAR_SEGOVR();
8055     END_OF_INSTR();
8056 }
8057 
8058 /****************************************************************************
8059 REMARKS:
8060 Handles opcode 0xac
8061 ****************************************************************************/
8062 static void
x86emuOp_lods_byte(u8 X86EMU_UNUSED (op1))8063 x86emuOp_lods_byte(u8 X86EMU_UNUSED(op1))
8064 {
8065     int inc;
8066 
8067     START_OF_INSTR();
8068     DECODE_PRINTF("LODS\tBYTE\n");
8069     TRACE_AND_STEP();
8070     if (ACCESS_FLAG(F_DF))      /* down */
8071         inc = -1;
8072     else
8073         inc = 1;
8074     if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
8075         /* dont care whether REPE or REPNE */
8076         /* move them until CX is ZERO. */
8077         while (M.x86.R_CX != 0) {
8078             M.x86.R_AL = fetch_data_byte(M.x86.R_SI);
8079             M.x86.R_CX -= 1;
8080             M.x86.R_SI += inc;
8081         }
8082         M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
8083     }
8084     else {
8085         M.x86.R_AL = fetch_data_byte(M.x86.R_SI);
8086         M.x86.R_SI += inc;
8087     }
8088     DECODE_CLEAR_SEGOVR();
8089     END_OF_INSTR();
8090 }
8091 
8092 /****************************************************************************
8093 REMARKS:
8094 Handles opcode 0xad
8095 ****************************************************************************/
8096 static void
x86emuOp_lods_word(u8 X86EMU_UNUSED (op1))8097 x86emuOp_lods_word(u8 X86EMU_UNUSED(op1))
8098 {
8099     int inc;
8100     u32 count;
8101 
8102     START_OF_INSTR();
8103     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8104         DECODE_PRINTF("LODS\tDWORD\n");
8105         if (ACCESS_FLAG(F_DF))  /* down */
8106             inc = -4;
8107         else
8108             inc = 4;
8109     }
8110     else {
8111         DECODE_PRINTF("LODS\tWORD\n");
8112         if (ACCESS_FLAG(F_DF))  /* down */
8113             inc = -2;
8114         else
8115             inc = 2;
8116     }
8117     TRACE_AND_STEP();
8118     count = 1;
8119     if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
8120         /* dont care whether REPE or REPNE */
8121         /* move them until CX is ZERO. */
8122         count = M.x86.R_CX;
8123         M.x86.R_CX = 0;
8124         M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
8125     }
8126     while (count--) {
8127         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8128             M.x86.R_EAX = fetch_data_long(M.x86.R_SI);
8129         }
8130         else {
8131             M.x86.R_AX = fetch_data_word(M.x86.R_SI);
8132         }
8133         M.x86.R_SI += inc;
8134     }
8135     DECODE_CLEAR_SEGOVR();
8136     END_OF_INSTR();
8137 }
8138 
8139 /****************************************************************************
8140 REMARKS:
8141 Handles opcode 0xae
8142 ****************************************************************************/
8143 static void
x86emuOp_scas_byte(u8 X86EMU_UNUSED (op1))8144 x86emuOp_scas_byte(u8 X86EMU_UNUSED(op1))
8145 {
8146     s8 val2;
8147     int inc;
8148 
8149     START_OF_INSTR();
8150     DECODE_PRINTF("SCAS\tBYTE\n");
8151     TRACE_AND_STEP();
8152     if (ACCESS_FLAG(F_DF))      /* down */
8153         inc = -1;
8154     else
8155         inc = 1;
8156     if (M.x86.mode & SYSMODE_PREFIX_REPE) {
8157         /* REPE  */
8158         /* move them until CX is ZERO. */
8159         while (M.x86.R_CX != 0) {
8160             val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
8161             cmp_byte(M.x86.R_AL, val2);
8162             M.x86.R_CX -= 1;
8163             M.x86.R_DI += inc;
8164             if (ACCESS_FLAG(F_ZF) == 0)
8165                 break;
8166         }
8167         M.x86.mode &= ~SYSMODE_PREFIX_REPE;
8168     }
8169     else if (M.x86.mode & SYSMODE_PREFIX_REPNE) {
8170         /* REPNE  */
8171         /* move them until CX is ZERO. */
8172         while (M.x86.R_CX != 0) {
8173             val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
8174             cmp_byte(M.x86.R_AL, val2);
8175             M.x86.R_CX -= 1;
8176             M.x86.R_DI += inc;
8177             if (ACCESS_FLAG(F_ZF))
8178                 break;          /* zero flag set means equal */
8179         }
8180         M.x86.mode &= ~SYSMODE_PREFIX_REPNE;
8181     }
8182     else {
8183         val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
8184         cmp_byte(M.x86.R_AL, val2);
8185         M.x86.R_DI += inc;
8186     }
8187     DECODE_CLEAR_SEGOVR();
8188     END_OF_INSTR();
8189 }
8190 
8191 /****************************************************************************
8192 REMARKS:
8193 Handles opcode 0xaf
8194 ****************************************************************************/
8195 static void
x86emuOp_scas_word(u8 X86EMU_UNUSED (op1))8196 x86emuOp_scas_word(u8 X86EMU_UNUSED(op1))
8197 {
8198     int inc;
8199     u32 val;
8200 
8201     START_OF_INSTR();
8202     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8203         DECODE_PRINTF("SCAS\tDWORD\n");
8204         if (ACCESS_FLAG(F_DF))  /* down */
8205             inc = -4;
8206         else
8207             inc = 4;
8208     }
8209     else {
8210         DECODE_PRINTF("SCAS\tWORD\n");
8211         if (ACCESS_FLAG(F_DF))  /* down */
8212             inc = -2;
8213         else
8214             inc = 2;
8215     }
8216     TRACE_AND_STEP();
8217     if (M.x86.mode & SYSMODE_PREFIX_REPE) {
8218         /* REPE  */
8219         /* move them until CX is ZERO. */
8220         while (M.x86.R_CX != 0) {
8221             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8222                 val = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
8223                 cmp_long(M.x86.R_EAX, val);
8224             }
8225             else {
8226                 val = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
8227                 cmp_word(M.x86.R_AX, (u16) val);
8228             }
8229             M.x86.R_CX -= 1;
8230             M.x86.R_DI += inc;
8231             if (ACCESS_FLAG(F_ZF) == 0)
8232                 break;
8233         }
8234         M.x86.mode &= ~SYSMODE_PREFIX_REPE;
8235     }
8236     else if (M.x86.mode & SYSMODE_PREFIX_REPNE) {
8237         /* REPNE  */
8238         /* move them until CX is ZERO. */
8239         while (M.x86.R_CX != 0) {
8240             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8241                 val = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
8242                 cmp_long(M.x86.R_EAX, val);
8243             }
8244             else {
8245                 val = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
8246                 cmp_word(M.x86.R_AX, (u16) val);
8247             }
8248             M.x86.R_CX -= 1;
8249             M.x86.R_DI += inc;
8250             if (ACCESS_FLAG(F_ZF))
8251                 break;          /* zero flag set means equal */
8252         }
8253         M.x86.mode &= ~SYSMODE_PREFIX_REPNE;
8254     }
8255     else {
8256         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8257             val = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
8258             cmp_long(M.x86.R_EAX, val);
8259         }
8260         else {
8261             val = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
8262             cmp_word(M.x86.R_AX, (u16) val);
8263         }
8264         M.x86.R_DI += inc;
8265     }
8266     DECODE_CLEAR_SEGOVR();
8267     END_OF_INSTR();
8268 }
8269 
8270 /****************************************************************************
8271 REMARKS:
8272 Handles opcode 0xb0
8273 ****************************************************************************/
8274 static void
x86emuOp_mov_byte_AL_IMM(u8 X86EMU_UNUSED (op1))8275 x86emuOp_mov_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
8276 {
8277     u8 imm;
8278 
8279     START_OF_INSTR();
8280     DECODE_PRINTF("MOV\tAL,");
8281     imm = fetch_byte_imm();
8282     DECODE_PRINTF2("%x\n", imm);
8283     TRACE_AND_STEP();
8284     M.x86.R_AL = imm;
8285     DECODE_CLEAR_SEGOVR();
8286     END_OF_INSTR();
8287 }
8288 
8289 /****************************************************************************
8290 REMARKS:
8291 Handles opcode 0xb1
8292 ****************************************************************************/
8293 static void
x86emuOp_mov_byte_CL_IMM(u8 X86EMU_UNUSED (op1))8294 x86emuOp_mov_byte_CL_IMM(u8 X86EMU_UNUSED(op1))
8295 {
8296     u8 imm;
8297 
8298     START_OF_INSTR();
8299     DECODE_PRINTF("MOV\tCL,");
8300     imm = fetch_byte_imm();
8301     DECODE_PRINTF2("%x\n", imm);
8302     TRACE_AND_STEP();
8303     M.x86.R_CL = imm;
8304     DECODE_CLEAR_SEGOVR();
8305     END_OF_INSTR();
8306 }
8307 
8308 /****************************************************************************
8309 REMARKS:
8310 Handles opcode 0xb2
8311 ****************************************************************************/
8312 static void
x86emuOp_mov_byte_DL_IMM(u8 X86EMU_UNUSED (op1))8313 x86emuOp_mov_byte_DL_IMM(u8 X86EMU_UNUSED(op1))
8314 {
8315     u8 imm;
8316 
8317     START_OF_INSTR();
8318     DECODE_PRINTF("MOV\tDL,");
8319     imm = fetch_byte_imm();
8320     DECODE_PRINTF2("%x\n", imm);
8321     TRACE_AND_STEP();
8322     M.x86.R_DL = imm;
8323     DECODE_CLEAR_SEGOVR();
8324     END_OF_INSTR();
8325 }
8326 
8327 /****************************************************************************
8328 REMARKS:
8329 Handles opcode 0xb3
8330 ****************************************************************************/
8331 static void
x86emuOp_mov_byte_BL_IMM(u8 X86EMU_UNUSED (op1))8332 x86emuOp_mov_byte_BL_IMM(u8 X86EMU_UNUSED(op1))
8333 {
8334     u8 imm;
8335 
8336     START_OF_INSTR();
8337     DECODE_PRINTF("MOV\tBL,");
8338     imm = fetch_byte_imm();
8339     DECODE_PRINTF2("%x\n", imm);
8340     TRACE_AND_STEP();
8341     M.x86.R_BL = imm;
8342     DECODE_CLEAR_SEGOVR();
8343     END_OF_INSTR();
8344 }
8345 
8346 /****************************************************************************
8347 REMARKS:
8348 Handles opcode 0xb4
8349 ****************************************************************************/
8350 static void
x86emuOp_mov_byte_AH_IMM(u8 X86EMU_UNUSED (op1))8351 x86emuOp_mov_byte_AH_IMM(u8 X86EMU_UNUSED(op1))
8352 {
8353     u8 imm;
8354 
8355     START_OF_INSTR();
8356     DECODE_PRINTF("MOV\tAH,");
8357     imm = fetch_byte_imm();
8358     DECODE_PRINTF2("%x\n", imm);
8359     TRACE_AND_STEP();
8360     M.x86.R_AH = imm;
8361     DECODE_CLEAR_SEGOVR();
8362     END_OF_INSTR();
8363 }
8364 
8365 /****************************************************************************
8366 REMARKS:
8367 Handles opcode 0xb5
8368 ****************************************************************************/
8369 static void
x86emuOp_mov_byte_CH_IMM(u8 X86EMU_UNUSED (op1))8370 x86emuOp_mov_byte_CH_IMM(u8 X86EMU_UNUSED(op1))
8371 {
8372     u8 imm;
8373 
8374     START_OF_INSTR();
8375     DECODE_PRINTF("MOV\tCH,");
8376     imm = fetch_byte_imm();
8377     DECODE_PRINTF2("%x\n", imm);
8378     TRACE_AND_STEP();
8379     M.x86.R_CH = imm;
8380     DECODE_CLEAR_SEGOVR();
8381     END_OF_INSTR();
8382 }
8383 
8384 /****************************************************************************
8385 REMARKS:
8386 Handles opcode 0xb6
8387 ****************************************************************************/
8388 static void
x86emuOp_mov_byte_DH_IMM(u8 X86EMU_UNUSED (op1))8389 x86emuOp_mov_byte_DH_IMM(u8 X86EMU_UNUSED(op1))
8390 {
8391     u8 imm;
8392 
8393     START_OF_INSTR();
8394     DECODE_PRINTF("MOV\tDH,");
8395     imm = fetch_byte_imm();
8396     DECODE_PRINTF2("%x\n", imm);
8397     TRACE_AND_STEP();
8398     M.x86.R_DH = imm;
8399     DECODE_CLEAR_SEGOVR();
8400     END_OF_INSTR();
8401 }
8402 
8403 /****************************************************************************
8404 REMARKS:
8405 Handles opcode 0xb7
8406 ****************************************************************************/
8407 static void
x86emuOp_mov_byte_BH_IMM(u8 X86EMU_UNUSED (op1))8408 x86emuOp_mov_byte_BH_IMM(u8 X86EMU_UNUSED(op1))
8409 {
8410     u8 imm;
8411 
8412     START_OF_INSTR();
8413     DECODE_PRINTF("MOV\tBH,");
8414     imm = fetch_byte_imm();
8415     DECODE_PRINTF2("%x\n", imm);
8416     TRACE_AND_STEP();
8417     M.x86.R_BH = imm;
8418     DECODE_CLEAR_SEGOVR();
8419     END_OF_INSTR();
8420 }
8421 
8422 /****************************************************************************
8423 REMARKS:
8424 Handles opcode 0xb8
8425 ****************************************************************************/
8426 static void
x86emuOp_mov_word_AX_IMM(u8 X86EMU_UNUSED (op1))8427 x86emuOp_mov_word_AX_IMM(u8 X86EMU_UNUSED(op1))
8428 {
8429     u32 srcval;
8430 
8431     START_OF_INSTR();
8432     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8433         DECODE_PRINTF("MOV\tEAX,");
8434         srcval = fetch_long_imm();
8435     }
8436     else {
8437         DECODE_PRINTF("MOV\tAX,");
8438         srcval = fetch_word_imm();
8439     }
8440     DECODE_PRINTF2("%x\n", srcval);
8441     TRACE_AND_STEP();
8442     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8443         M.x86.R_EAX = srcval;
8444     }
8445     else {
8446         M.x86.R_AX = (u16) srcval;
8447     }
8448     DECODE_CLEAR_SEGOVR();
8449     END_OF_INSTR();
8450 }
8451 
8452 /****************************************************************************
8453 REMARKS:
8454 Handles opcode 0xb9
8455 ****************************************************************************/
8456 static void
x86emuOp_mov_word_CX_IMM(u8 X86EMU_UNUSED (op1))8457 x86emuOp_mov_word_CX_IMM(u8 X86EMU_UNUSED(op1))
8458 {
8459     u32 srcval;
8460 
8461     START_OF_INSTR();
8462     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8463         DECODE_PRINTF("MOV\tECX,");
8464         srcval = fetch_long_imm();
8465     }
8466     else {
8467         DECODE_PRINTF("MOV\tCX,");
8468         srcval = fetch_word_imm();
8469     }
8470     DECODE_PRINTF2("%x\n", srcval);
8471     TRACE_AND_STEP();
8472     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8473         M.x86.R_ECX = srcval;
8474     }
8475     else {
8476         M.x86.R_CX = (u16) srcval;
8477     }
8478     DECODE_CLEAR_SEGOVR();
8479     END_OF_INSTR();
8480 }
8481 
8482 /****************************************************************************
8483 REMARKS:
8484 Handles opcode 0xba
8485 ****************************************************************************/
8486 static void
x86emuOp_mov_word_DX_IMM(u8 X86EMU_UNUSED (op1))8487 x86emuOp_mov_word_DX_IMM(u8 X86EMU_UNUSED(op1))
8488 {
8489     u32 srcval;
8490 
8491     START_OF_INSTR();
8492     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8493         DECODE_PRINTF("MOV\tEDX,");
8494         srcval = fetch_long_imm();
8495     }
8496     else {
8497         DECODE_PRINTF("MOV\tDX,");
8498         srcval = fetch_word_imm();
8499     }
8500     DECODE_PRINTF2("%x\n", srcval);
8501     TRACE_AND_STEP();
8502     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8503         M.x86.R_EDX = srcval;
8504     }
8505     else {
8506         M.x86.R_DX = (u16) srcval;
8507     }
8508     DECODE_CLEAR_SEGOVR();
8509     END_OF_INSTR();
8510 }
8511 
8512 /****************************************************************************
8513 REMARKS:
8514 Handles opcode 0xbb
8515 ****************************************************************************/
8516 static void
x86emuOp_mov_word_BX_IMM(u8 X86EMU_UNUSED (op1))8517 x86emuOp_mov_word_BX_IMM(u8 X86EMU_UNUSED(op1))
8518 {
8519     u32 srcval;
8520 
8521     START_OF_INSTR();
8522     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8523         DECODE_PRINTF("MOV\tEBX,");
8524         srcval = fetch_long_imm();
8525     }
8526     else {
8527         DECODE_PRINTF("MOV\tBX,");
8528         srcval = fetch_word_imm();
8529     }
8530     DECODE_PRINTF2("%x\n", srcval);
8531     TRACE_AND_STEP();
8532     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8533         M.x86.R_EBX = srcval;
8534     }
8535     else {
8536         M.x86.R_BX = (u16) srcval;
8537     }
8538     DECODE_CLEAR_SEGOVR();
8539     END_OF_INSTR();
8540 }
8541 
8542 /****************************************************************************
8543 REMARKS:
8544 Handles opcode 0xbc
8545 ****************************************************************************/
8546 static void
x86emuOp_mov_word_SP_IMM(u8 X86EMU_UNUSED (op1))8547 x86emuOp_mov_word_SP_IMM(u8 X86EMU_UNUSED(op1))
8548 {
8549     u32 srcval;
8550 
8551     START_OF_INSTR();
8552     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8553         DECODE_PRINTF("MOV\tESP,");
8554         srcval = fetch_long_imm();
8555     }
8556     else {
8557         DECODE_PRINTF("MOV\tSP,");
8558         srcval = fetch_word_imm();
8559     }
8560     DECODE_PRINTF2("%x\n", srcval);
8561     TRACE_AND_STEP();
8562     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8563         M.x86.R_ESP = srcval;
8564     }
8565     else {
8566         M.x86.R_SP = (u16) srcval;
8567     }
8568     DECODE_CLEAR_SEGOVR();
8569     END_OF_INSTR();
8570 }
8571 
8572 /****************************************************************************
8573 REMARKS:
8574 Handles opcode 0xbd
8575 ****************************************************************************/
8576 static void
x86emuOp_mov_word_BP_IMM(u8 X86EMU_UNUSED (op1))8577 x86emuOp_mov_word_BP_IMM(u8 X86EMU_UNUSED(op1))
8578 {
8579     u32 srcval;
8580 
8581     START_OF_INSTR();
8582     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8583         DECODE_PRINTF("MOV\tEBP,");
8584         srcval = fetch_long_imm();
8585     }
8586     else {
8587         DECODE_PRINTF("MOV\tBP,");
8588         srcval = fetch_word_imm();
8589     }
8590     DECODE_PRINTF2("%x\n", srcval);
8591     TRACE_AND_STEP();
8592     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8593         M.x86.R_EBP = srcval;
8594     }
8595     else {
8596         M.x86.R_BP = (u16) srcval;
8597     }
8598     DECODE_CLEAR_SEGOVR();
8599     END_OF_INSTR();
8600 }
8601 
8602 /****************************************************************************
8603 REMARKS:
8604 Handles opcode 0xbe
8605 ****************************************************************************/
8606 static void
x86emuOp_mov_word_SI_IMM(u8 X86EMU_UNUSED (op1))8607 x86emuOp_mov_word_SI_IMM(u8 X86EMU_UNUSED(op1))
8608 {
8609     u32 srcval;
8610 
8611     START_OF_INSTR();
8612     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8613         DECODE_PRINTF("MOV\tESI,");
8614         srcval = fetch_long_imm();
8615     }
8616     else {
8617         DECODE_PRINTF("MOV\tSI,");
8618         srcval = fetch_word_imm();
8619     }
8620     DECODE_PRINTF2("%x\n", srcval);
8621     TRACE_AND_STEP();
8622     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8623         M.x86.R_ESI = srcval;
8624     }
8625     else {
8626         M.x86.R_SI = (u16) srcval;
8627     }
8628     DECODE_CLEAR_SEGOVR();
8629     END_OF_INSTR();
8630 }
8631 
8632 /****************************************************************************
8633 REMARKS:
8634 Handles opcode 0xbf
8635 ****************************************************************************/
8636 static void
x86emuOp_mov_word_DI_IMM(u8 X86EMU_UNUSED (op1))8637 x86emuOp_mov_word_DI_IMM(u8 X86EMU_UNUSED(op1))
8638 {
8639     u32 srcval;
8640 
8641     START_OF_INSTR();
8642     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8643         DECODE_PRINTF("MOV\tEDI,");
8644         srcval = fetch_long_imm();
8645     }
8646     else {
8647         DECODE_PRINTF("MOV\tDI,");
8648         srcval = fetch_word_imm();
8649     }
8650     DECODE_PRINTF2("%x\n", srcval);
8651     TRACE_AND_STEP();
8652     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8653         M.x86.R_EDI = srcval;
8654     }
8655     else {
8656         M.x86.R_DI = (u16) srcval;
8657     }
8658     DECODE_CLEAR_SEGOVR();
8659     END_OF_INSTR();
8660 }
8661 
8662 /* used by opcodes c0, d0, and d2. */
8663 static u8(*opcD0_byte_operation[]) (u8 d, u8 s) = {
8664     rol_byte, ror_byte, rcl_byte, rcr_byte, shl_byte, shr_byte, shl_byte,       /* sal_byte === shl_byte  by definition */
8665 sar_byte,};
8666 
8667 /****************************************************************************
8668 REMARKS:
8669 Handles opcode 0xc0
8670 ****************************************************************************/
8671 static void
x86emuOp_opcC0_byte_RM_MEM(u8 X86EMU_UNUSED (op1))8672 x86emuOp_opcC0_byte_RM_MEM(u8 X86EMU_UNUSED(op1))
8673 {
8674     int mod, rl, rh;
8675     u8 *destreg;
8676     uint destoffset;
8677     u8 destval;
8678     u8 amt;
8679 
8680     /*
8681      * Yet another weirdo special case instruction format.  Part of
8682      * the opcode held below in "RH".  Doubly nested case would
8683      * result, except that the decoded instruction
8684      */
8685     START_OF_INSTR();
8686     FETCH_DECODE_MODRM(mod, rh, rl);
8687 #ifdef DEBUG
8688     if (DEBUG_DECODE()) {
8689         /* XXX DECODE_PRINTF may be changed to something more
8690            general, so that it is important to leave the strings
8691            in the same format, even though the result is that the
8692            above test is done twice. */
8693 
8694         switch (rh) {
8695         case 0:
8696             DECODE_PRINTF("ROL\t");
8697             break;
8698         case 1:
8699             DECODE_PRINTF("ROR\t");
8700             break;
8701         case 2:
8702             DECODE_PRINTF("RCL\t");
8703             break;
8704         case 3:
8705             DECODE_PRINTF("RCR\t");
8706             break;
8707         case 4:
8708             DECODE_PRINTF("SHL\t");
8709             break;
8710         case 5:
8711             DECODE_PRINTF("SHR\t");
8712             break;
8713         case 6:
8714             DECODE_PRINTF("SAL\t");
8715             break;
8716         case 7:
8717             DECODE_PRINTF("SAR\t");
8718             break;
8719         }
8720     }
8721 #endif
8722     /* know operation, decode the mod byte to find the addressing
8723        mode. */
8724     switch (mod) {
8725     case 0:
8726         DECODE_PRINTF("BYTE PTR ");
8727         destoffset = decode_rm00_address(rl);
8728         amt = fetch_byte_imm();
8729         DECODE_PRINTF2(",%x\n", amt);
8730         destval = fetch_data_byte(destoffset);
8731         TRACE_AND_STEP();
8732         destval = (*opcD0_byte_operation[rh]) (destval, amt);
8733         store_data_byte(destoffset, destval);
8734         break;
8735     case 1:
8736         DECODE_PRINTF("BYTE PTR ");
8737         destoffset = decode_rm01_address(rl);
8738         amt = fetch_byte_imm();
8739         DECODE_PRINTF2(",%x\n", amt);
8740         destval = fetch_data_byte(destoffset);
8741         TRACE_AND_STEP();
8742         destval = (*opcD0_byte_operation[rh]) (destval, amt);
8743         store_data_byte(destoffset, destval);
8744         break;
8745     case 2:
8746         DECODE_PRINTF("BYTE PTR ");
8747         destoffset = decode_rm10_address(rl);
8748         amt = fetch_byte_imm();
8749         DECODE_PRINTF2(",%x\n", amt);
8750         destval = fetch_data_byte(destoffset);
8751         TRACE_AND_STEP();
8752         destval = (*opcD0_byte_operation[rh]) (destval, amt);
8753         store_data_byte(destoffset, destval);
8754         break;
8755     case 3:                    /* register to register */
8756         destreg = DECODE_RM_BYTE_REGISTER(rl);
8757         amt = fetch_byte_imm();
8758         DECODE_PRINTF2(",%x\n", amt);
8759         TRACE_AND_STEP();
8760         destval = (*opcD0_byte_operation[rh]) (*destreg, amt);
8761         *destreg = destval;
8762         break;
8763     }
8764     DECODE_CLEAR_SEGOVR();
8765     END_OF_INSTR();
8766 }
8767 
8768 /* used by opcodes c1, d1, and d3. */
8769 static u16(*opcD1_word_operation[]) (u16 s, u8 d) = {
8770     rol_word, ror_word, rcl_word, rcr_word, shl_word, shr_word, shl_word,       /* sal_byte === shl_byte  by definition */
8771 sar_word,};
8772 
8773 /* used by opcodes c1, d1, and d3. */
8774 static u32(*opcD1_long_operation[]) (u32 s, u8 d) = {
8775     rol_long, ror_long, rcl_long, rcr_long, shl_long, shr_long, shl_long,       /* sal_byte === shl_byte  by definition */
8776 sar_long,};
8777 
8778 /****************************************************************************
8779 REMARKS:
8780 Handles opcode 0xc1
8781 ****************************************************************************/
8782 static void
x86emuOp_opcC1_word_RM_MEM(u8 X86EMU_UNUSED (op1))8783 x86emuOp_opcC1_word_RM_MEM(u8 X86EMU_UNUSED(op1))
8784 {
8785     int mod, rl, rh;
8786     uint destoffset;
8787     u8 amt;
8788 
8789     /*
8790      * Yet another weirdo special case instruction format.  Part of
8791      * the opcode held below in "RH".  Doubly nested case would
8792      * result, except that the decoded instruction
8793      */
8794     START_OF_INSTR();
8795     FETCH_DECODE_MODRM(mod, rh, rl);
8796 #ifdef DEBUG
8797     if (DEBUG_DECODE()) {
8798         /* XXX DECODE_PRINTF may be changed to something more
8799            general, so that it is important to leave the strings
8800            in the same format, even though the result is that the
8801            above test is done twice. */
8802 
8803         switch (rh) {
8804         case 0:
8805             DECODE_PRINTF("ROL\t");
8806             break;
8807         case 1:
8808             DECODE_PRINTF("ROR\t");
8809             break;
8810         case 2:
8811             DECODE_PRINTF("RCL\t");
8812             break;
8813         case 3:
8814             DECODE_PRINTF("RCR\t");
8815             break;
8816         case 4:
8817             DECODE_PRINTF("SHL\t");
8818             break;
8819         case 5:
8820             DECODE_PRINTF("SHR\t");
8821             break;
8822         case 6:
8823             DECODE_PRINTF("SAL\t");
8824             break;
8825         case 7:
8826             DECODE_PRINTF("SAR\t");
8827             break;
8828         }
8829     }
8830 #endif
8831     /* know operation, decode the mod byte to find the addressing
8832        mode. */
8833     switch (mod) {
8834     case 0:
8835         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8836             u32 destval;
8837 
8838             DECODE_PRINTF("DWORD PTR ");
8839             destoffset = decode_rm00_address(rl);
8840             amt = fetch_byte_imm();
8841             DECODE_PRINTF2(",%x\n", amt);
8842             destval = fetch_data_long(destoffset);
8843             TRACE_AND_STEP();
8844             destval = (*opcD1_long_operation[rh]) (destval, amt);
8845             store_data_long(destoffset, destval);
8846         }
8847         else {
8848             u16 destval;
8849 
8850             DECODE_PRINTF("WORD PTR ");
8851             destoffset = decode_rm00_address(rl);
8852             amt = fetch_byte_imm();
8853             DECODE_PRINTF2(",%x\n", amt);
8854             destval = fetch_data_word(destoffset);
8855             TRACE_AND_STEP();
8856             destval = (*opcD1_word_operation[rh]) (destval, amt);
8857             store_data_word(destoffset, destval);
8858         }
8859         break;
8860     case 1:
8861         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8862             u32 destval;
8863 
8864             DECODE_PRINTF("DWORD PTR ");
8865             destoffset = decode_rm01_address(rl);
8866             amt = fetch_byte_imm();
8867             DECODE_PRINTF2(",%x\n", amt);
8868             destval = fetch_data_long(destoffset);
8869             TRACE_AND_STEP();
8870             destval = (*opcD1_long_operation[rh]) (destval, amt);
8871             store_data_long(destoffset, destval);
8872         }
8873         else {
8874             u16 destval;
8875 
8876             DECODE_PRINTF("WORD PTR ");
8877             destoffset = decode_rm01_address(rl);
8878             amt = fetch_byte_imm();
8879             DECODE_PRINTF2(",%x\n", amt);
8880             destval = fetch_data_word(destoffset);
8881             TRACE_AND_STEP();
8882             destval = (*opcD1_word_operation[rh]) (destval, amt);
8883             store_data_word(destoffset, destval);
8884         }
8885         break;
8886     case 2:
8887         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8888             u32 destval;
8889 
8890             DECODE_PRINTF("DWORD PTR ");
8891             destoffset = decode_rm10_address(rl);
8892             amt = fetch_byte_imm();
8893             DECODE_PRINTF2(",%x\n", amt);
8894             destval = fetch_data_long(destoffset);
8895             TRACE_AND_STEP();
8896             destval = (*opcD1_long_operation[rh]) (destval, amt);
8897             store_data_long(destoffset, destval);
8898         }
8899         else {
8900             u16 destval;
8901 
8902             DECODE_PRINTF("WORD PTR ");
8903             destoffset = decode_rm10_address(rl);
8904             amt = fetch_byte_imm();
8905             DECODE_PRINTF2(",%x\n", amt);
8906             destval = fetch_data_word(destoffset);
8907             TRACE_AND_STEP();
8908             destval = (*opcD1_word_operation[rh]) (destval, amt);
8909             store_data_word(destoffset, destval);
8910         }
8911         break;
8912     case 3:                    /* register to register */
8913         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8914             u32 *destreg;
8915 
8916             destreg = DECODE_RM_LONG_REGISTER(rl);
8917             amt = fetch_byte_imm();
8918             DECODE_PRINTF2(",%x\n", amt);
8919             TRACE_AND_STEP();
8920             *destreg = (*opcD1_long_operation[rh]) (*destreg, amt);
8921         }
8922         else {
8923             u16 *destreg;
8924 
8925             destreg = DECODE_RM_WORD_REGISTER(rl);
8926             amt = fetch_byte_imm();
8927             DECODE_PRINTF2(",%x\n", amt);
8928             TRACE_AND_STEP();
8929             *destreg = (*opcD1_word_operation[rh]) (*destreg, amt);
8930         }
8931         break;
8932     }
8933     DECODE_CLEAR_SEGOVR();
8934     END_OF_INSTR();
8935 }
8936 
8937 /****************************************************************************
8938 REMARKS:
8939 Handles opcode 0xc2
8940 ****************************************************************************/
8941 static void
x86emuOp_ret_near_IMM(u8 X86EMU_UNUSED (op1))8942 x86emuOp_ret_near_IMM(u8 X86EMU_UNUSED(op1))
8943 {
8944     u16 imm;
8945 
8946     START_OF_INSTR();
8947     DECODE_PRINTF("RET\t");
8948     imm = fetch_word_imm();
8949     DECODE_PRINTF2("%x\n", imm);
8950     RETURN_TRACE("RET", M.x86.saved_cs, M.x86.saved_ip);
8951     TRACE_AND_STEP();
8952     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8953         M.x86.R_EIP = pop_long();
8954     } else {
8955         M.x86.R_IP = pop_word();
8956     }
8957     M.x86.R_SP += imm;
8958     DECODE_CLEAR_SEGOVR();
8959     END_OF_INSTR();
8960 }
8961 
8962 /****************************************************************************
8963 REMARKS:
8964 Handles opcode 0xc3
8965 ****************************************************************************/
8966 static void
x86emuOp_ret_near(u8 X86EMU_UNUSED (op1))8967 x86emuOp_ret_near(u8 X86EMU_UNUSED(op1))
8968 {
8969     START_OF_INSTR();
8970     DECODE_PRINTF("RET\n");
8971     RETURN_TRACE("RET", M.x86.saved_cs, M.x86.saved_ip);
8972     TRACE_AND_STEP();
8973     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8974         M.x86.R_EIP = pop_long();
8975     } else {
8976         M.x86.R_IP = pop_word();
8977     }
8978     DECODE_CLEAR_SEGOVR();
8979     END_OF_INSTR();
8980 }
8981 
8982 /****************************************************************************
8983 REMARKS:
8984 Handles opcode 0xc4
8985 ****************************************************************************/
8986 static void
x86emuOp_les_R_IMM(u8 X86EMU_UNUSED (op1))8987 x86emuOp_les_R_IMM(u8 X86EMU_UNUSED(op1))
8988 {
8989     int mod, rh, rl;
8990     u16 *dstreg;
8991     uint srcoffset;
8992 
8993     START_OF_INSTR();
8994     DECODE_PRINTF("LES\t");
8995     FETCH_DECODE_MODRM(mod, rh, rl);
8996     switch (mod) {
8997     case 0:
8998         dstreg = DECODE_RM_WORD_REGISTER(rh);
8999         DECODE_PRINTF(",");
9000         srcoffset = decode_rm00_address(rl);
9001         DECODE_PRINTF("\n");
9002         TRACE_AND_STEP();
9003         *dstreg = fetch_data_word(srcoffset);
9004         M.x86.R_ES = fetch_data_word(srcoffset + 2);
9005         break;
9006     case 1:
9007         dstreg = DECODE_RM_WORD_REGISTER(rh);
9008         DECODE_PRINTF(",");
9009         srcoffset = decode_rm01_address(rl);
9010         DECODE_PRINTF("\n");
9011         TRACE_AND_STEP();
9012         *dstreg = fetch_data_word(srcoffset);
9013         M.x86.R_ES = fetch_data_word(srcoffset + 2);
9014         break;
9015     case 2:
9016         dstreg = DECODE_RM_WORD_REGISTER(rh);
9017         DECODE_PRINTF(",");
9018         srcoffset = decode_rm10_address(rl);
9019         DECODE_PRINTF("\n");
9020         TRACE_AND_STEP();
9021         *dstreg = fetch_data_word(srcoffset);
9022         M.x86.R_ES = fetch_data_word(srcoffset + 2);
9023         break;
9024     case 3:                    /* register to register */
9025         /* UNDEFINED! */
9026         TRACE_AND_STEP();
9027     }
9028     DECODE_CLEAR_SEGOVR();
9029     END_OF_INSTR();
9030 }
9031 
9032 /****************************************************************************
9033 REMARKS:
9034 Handles opcode 0xc5
9035 ****************************************************************************/
9036 static void
x86emuOp_lds_R_IMM(u8 X86EMU_UNUSED (op1))9037 x86emuOp_lds_R_IMM(u8 X86EMU_UNUSED(op1))
9038 {
9039     int mod, rh, rl;
9040     u16 *dstreg;
9041     uint srcoffset;
9042 
9043     START_OF_INSTR();
9044     DECODE_PRINTF("LDS\t");
9045     FETCH_DECODE_MODRM(mod, rh, rl);
9046     switch (mod) {
9047     case 0:
9048         dstreg = DECODE_RM_WORD_REGISTER(rh);
9049         DECODE_PRINTF(",");
9050         srcoffset = decode_rm00_address(rl);
9051         DECODE_PRINTF("\n");
9052         TRACE_AND_STEP();
9053         *dstreg = fetch_data_word(srcoffset);
9054         M.x86.R_DS = fetch_data_word(srcoffset + 2);
9055         break;
9056     case 1:
9057         dstreg = DECODE_RM_WORD_REGISTER(rh);
9058         DECODE_PRINTF(",");
9059         srcoffset = decode_rm01_address(rl);
9060         DECODE_PRINTF("\n");
9061         TRACE_AND_STEP();
9062         *dstreg = fetch_data_word(srcoffset);
9063         M.x86.R_DS = fetch_data_word(srcoffset + 2);
9064         break;
9065     case 2:
9066         dstreg = DECODE_RM_WORD_REGISTER(rh);
9067         DECODE_PRINTF(",");
9068         srcoffset = decode_rm10_address(rl);
9069         DECODE_PRINTF("\n");
9070         TRACE_AND_STEP();
9071         *dstreg = fetch_data_word(srcoffset);
9072         M.x86.R_DS = fetch_data_word(srcoffset + 2);
9073         break;
9074     case 3:                    /* register to register */
9075         /* UNDEFINED! */
9076         TRACE_AND_STEP();
9077     }
9078     DECODE_CLEAR_SEGOVR();
9079     END_OF_INSTR();
9080 }
9081 
9082 /****************************************************************************
9083 REMARKS:
9084 Handles opcode 0xc6
9085 ****************************************************************************/
9086 static void
x86emuOp_mov_byte_RM_IMM(u8 X86EMU_UNUSED (op1))9087 x86emuOp_mov_byte_RM_IMM(u8 X86EMU_UNUSED(op1))
9088 {
9089     int mod, rl, rh;
9090     u8 *destreg;
9091     uint destoffset;
9092     u8 imm;
9093 
9094     START_OF_INSTR();
9095     DECODE_PRINTF("MOV\t");
9096     FETCH_DECODE_MODRM(mod, rh, rl);
9097     if (rh != 0) {
9098         DECODE_PRINTF("ILLEGAL DECODE OF OPCODE c6\n");
9099         HALT_SYS();
9100     }
9101     switch (mod) {
9102     case 0:
9103         DECODE_PRINTF("BYTE PTR ");
9104         destoffset = decode_rm00_address(rl);
9105         imm = fetch_byte_imm();
9106         DECODE_PRINTF2(",%2x\n", imm);
9107         TRACE_AND_STEP();
9108         store_data_byte(destoffset, imm);
9109         break;
9110     case 1:
9111         DECODE_PRINTF("BYTE PTR ");
9112         destoffset = decode_rm01_address(rl);
9113         imm = fetch_byte_imm();
9114         DECODE_PRINTF2(",%2x\n", imm);
9115         TRACE_AND_STEP();
9116         store_data_byte(destoffset, imm);
9117         break;
9118     case 2:
9119         DECODE_PRINTF("BYTE PTR ");
9120         destoffset = decode_rm10_address(rl);
9121         imm = fetch_byte_imm();
9122         DECODE_PRINTF2(",%2x\n", imm);
9123         TRACE_AND_STEP();
9124         store_data_byte(destoffset, imm);
9125         break;
9126     case 3:                    /* register to register */
9127         destreg = DECODE_RM_BYTE_REGISTER(rl);
9128         imm = fetch_byte_imm();
9129         DECODE_PRINTF2(",%2x\n", imm);
9130         TRACE_AND_STEP();
9131         *destreg = imm;
9132         break;
9133     }
9134     DECODE_CLEAR_SEGOVR();
9135     END_OF_INSTR();
9136 }
9137 
9138 /****************************************************************************
9139 REMARKS:
9140 Handles opcode 0xc7
9141 ****************************************************************************/
9142 static void
x86emuOp_mov_word_RM_IMM(u8 X86EMU_UNUSED (op1))9143 x86emuOp_mov_word_RM_IMM(u8 X86EMU_UNUSED(op1))
9144 {
9145     int mod, rl, rh;
9146     uint destoffset;
9147 
9148     START_OF_INSTR();
9149     DECODE_PRINTF("MOV\t");
9150     FETCH_DECODE_MODRM(mod, rh, rl);
9151     if (rh != 0) {
9152         DECODE_PRINTF("ILLEGAL DECODE OF OPCODE 8F\n");
9153         HALT_SYS();
9154     }
9155     switch (mod) {
9156     case 0:
9157         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9158             u32 imm;
9159 
9160             DECODE_PRINTF("DWORD PTR ");
9161             destoffset = decode_rm00_address(rl);
9162             imm = fetch_long_imm();
9163             DECODE_PRINTF2(",%x\n", imm);
9164             TRACE_AND_STEP();
9165             store_data_long(destoffset, imm);
9166         }
9167         else {
9168             u16 imm;
9169 
9170             DECODE_PRINTF("WORD PTR ");
9171             destoffset = decode_rm00_address(rl);
9172             imm = fetch_word_imm();
9173             DECODE_PRINTF2(",%x\n", imm);
9174             TRACE_AND_STEP();
9175             store_data_word(destoffset, imm);
9176         }
9177         break;
9178     case 1:
9179         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9180             u32 imm;
9181 
9182             DECODE_PRINTF("DWORD PTR ");
9183             destoffset = decode_rm01_address(rl);
9184             imm = fetch_long_imm();
9185             DECODE_PRINTF2(",%x\n", imm);
9186             TRACE_AND_STEP();
9187             store_data_long(destoffset, imm);
9188         }
9189         else {
9190             u16 imm;
9191 
9192             DECODE_PRINTF("WORD PTR ");
9193             destoffset = decode_rm01_address(rl);
9194             imm = fetch_word_imm();
9195             DECODE_PRINTF2(",%x\n", imm);
9196             TRACE_AND_STEP();
9197             store_data_word(destoffset, imm);
9198         }
9199         break;
9200     case 2:
9201         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9202             u32 imm;
9203 
9204             DECODE_PRINTF("DWORD PTR ");
9205             destoffset = decode_rm10_address(rl);
9206             imm = fetch_long_imm();
9207             DECODE_PRINTF2(",%x\n", imm);
9208             TRACE_AND_STEP();
9209             store_data_long(destoffset, imm);
9210         }
9211         else {
9212             u16 imm;
9213 
9214             DECODE_PRINTF("WORD PTR ");
9215             destoffset = decode_rm10_address(rl);
9216             imm = fetch_word_imm();
9217             DECODE_PRINTF2(",%x\n", imm);
9218             TRACE_AND_STEP();
9219             store_data_word(destoffset, imm);
9220         }
9221         break;
9222     case 3:                    /* register to register */
9223         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9224             u32 *destreg;
9225             u32 imm;
9226 
9227             destreg = DECODE_RM_LONG_REGISTER(rl);
9228             imm = fetch_long_imm();
9229             DECODE_PRINTF2(",%x\n", imm);
9230             TRACE_AND_STEP();
9231             *destreg = imm;
9232         }
9233         else {
9234             u16 *destreg;
9235             u16 imm;
9236 
9237             destreg = DECODE_RM_WORD_REGISTER(rl);
9238             imm = fetch_word_imm();
9239             DECODE_PRINTF2(",%x\n", imm);
9240             TRACE_AND_STEP();
9241             *destreg = imm;
9242         }
9243         break;
9244     }
9245     DECODE_CLEAR_SEGOVR();
9246     END_OF_INSTR();
9247 }
9248 
9249 /****************************************************************************
9250 REMARKS:
9251 Handles opcode 0xc8
9252 ****************************************************************************/
9253 static void
x86emuOp_enter(u8 X86EMU_UNUSED (op1))9254 x86emuOp_enter(u8 X86EMU_UNUSED(op1))
9255 {
9256     u16 local, frame_pointer;
9257     u8 nesting;
9258     int i;
9259 
9260     START_OF_INSTR();
9261     local = fetch_word_imm();
9262     nesting = fetch_byte_imm();
9263     DECODE_PRINTF2("ENTER %x\n", local);
9264     DECODE_PRINTF2(",%x\n", nesting);
9265     TRACE_AND_STEP();
9266     push_word(M.x86.R_BP);
9267     frame_pointer = M.x86.R_SP;
9268     if (nesting > 0) {
9269         for (i = 1; i < nesting; i++) {
9270             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9271                 M.x86.R_BP -= 4;
9272                 push_long(fetch_data_long_abs(M.x86.R_SS, M.x86.R_BP));
9273             } else {
9274                 M.x86.R_BP -= 2;
9275                 push_word(fetch_data_word_abs(M.x86.R_SS, M.x86.R_BP));
9276             }
9277         }
9278         push_word(frame_pointer);
9279     }
9280     M.x86.R_BP = frame_pointer;
9281     M.x86.R_SP = (u16) (M.x86.R_SP - local);
9282     DECODE_CLEAR_SEGOVR();
9283     END_OF_INSTR();
9284 }
9285 
9286 /****************************************************************************
9287 REMARKS:
9288 Handles opcode 0xc9
9289 ****************************************************************************/
9290 static void
x86emuOp_leave(u8 X86EMU_UNUSED (op1))9291 x86emuOp_leave(u8 X86EMU_UNUSED(op1))
9292 {
9293     START_OF_INSTR();
9294     DECODE_PRINTF("LEAVE\n");
9295     TRACE_AND_STEP();
9296     M.x86.R_SP = M.x86.R_BP;
9297     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9298         M.x86.R_EBP = pop_long();
9299     } else {
9300         M.x86.R_BP = pop_word();
9301     }
9302     DECODE_CLEAR_SEGOVR();
9303     END_OF_INSTR();
9304 }
9305 
9306 /****************************************************************************
9307 REMARKS:
9308 Handles opcode 0xca
9309 ****************************************************************************/
9310 static void
x86emuOp_ret_far_IMM(u8 X86EMU_UNUSED (op1))9311 x86emuOp_ret_far_IMM(u8 X86EMU_UNUSED(op1))
9312 {
9313     u16 imm;
9314 
9315     START_OF_INSTR();
9316     DECODE_PRINTF("RETF\t");
9317     imm = fetch_word_imm();
9318     DECODE_PRINTF2("%x\n", imm);
9319     RETURN_TRACE("RETF", M.x86.saved_cs, M.x86.saved_ip);
9320     TRACE_AND_STEP();
9321     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9322         M.x86.R_EIP = pop_long();
9323         M.x86.R_CS = pop_long() & 0xffff;
9324     } else {
9325         M.x86.R_IP = pop_word();
9326         M.x86.R_CS = pop_word();
9327     }
9328     M.x86.R_SP += imm;
9329     DECODE_CLEAR_SEGOVR();
9330     END_OF_INSTR();
9331 }
9332 
9333 /****************************************************************************
9334 REMARKS:
9335 Handles opcode 0xcb
9336 ****************************************************************************/
9337 static void
x86emuOp_ret_far(u8 X86EMU_UNUSED (op1))9338 x86emuOp_ret_far(u8 X86EMU_UNUSED(op1))
9339 {
9340     START_OF_INSTR();
9341     DECODE_PRINTF("RETF\n");
9342     RETURN_TRACE("RETF", M.x86.saved_cs, M.x86.saved_ip);
9343     TRACE_AND_STEP();
9344     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9345         M.x86.R_EIP = pop_long();
9346         M.x86.R_CS = pop_long() & 0xffff;
9347     } else {
9348         M.x86.R_IP = pop_word();
9349         M.x86.R_CS = pop_word();
9350     }
9351     DECODE_CLEAR_SEGOVR();
9352     END_OF_INSTR();
9353 }
9354 
9355 /****************************************************************************
9356 REMARKS:
9357 Handles opcode 0xcc
9358 ****************************************************************************/
9359 static void
x86emuOp_int3(u8 X86EMU_UNUSED (op1))9360 x86emuOp_int3(u8 X86EMU_UNUSED(op1))
9361 {
9362     START_OF_INSTR();
9363     DECODE_PRINTF("INT 3\n");
9364     TRACE_AND_STEP();
9365     if (_X86EMU_intrTab[3]) {
9366         (*_X86EMU_intrTab[3]) (3);
9367     }
9368     else {
9369         push_word((u16) M.x86.R_FLG);
9370         CLEAR_FLAG(F_IF);
9371         CLEAR_FLAG(F_TF);
9372         push_word(M.x86.R_CS);
9373         M.x86.R_CS = mem_access_word(3 * 4 + 2);
9374         push_word(M.x86.R_IP);
9375         M.x86.R_IP = mem_access_word(3 * 4);
9376     }
9377     DECODE_CLEAR_SEGOVR();
9378     END_OF_INSTR();
9379 }
9380 
9381 /****************************************************************************
9382 REMARKS:
9383 Handles opcode 0xcd
9384 ****************************************************************************/
9385 static void
x86emuOp_int_IMM(u8 X86EMU_UNUSED (op1))9386 x86emuOp_int_IMM(u8 X86EMU_UNUSED(op1))
9387 {
9388     u8 intnum;
9389 
9390     START_OF_INSTR();
9391     DECODE_PRINTF("INT\t");
9392     intnum = fetch_byte_imm();
9393     DECODE_PRINTF2("%x\n", intnum);
9394     TRACE_AND_STEP();
9395     if (_X86EMU_intrTab[intnum]) {
9396         (*_X86EMU_intrTab[intnum]) (intnum);
9397     }
9398     else {
9399         push_word((u16) M.x86.R_FLG);
9400         CLEAR_FLAG(F_IF);
9401         CLEAR_FLAG(F_TF);
9402         push_word(M.x86.R_CS);
9403         M.x86.R_CS = mem_access_word(intnum * 4 + 2);
9404         push_word(M.x86.R_IP);
9405         M.x86.R_IP = mem_access_word(intnum * 4);
9406     }
9407     DECODE_CLEAR_SEGOVR();
9408     END_OF_INSTR();
9409 }
9410 
9411 /****************************************************************************
9412 REMARKS:
9413 Handles opcode 0xce
9414 ****************************************************************************/
9415 static void
x86emuOp_into(u8 X86EMU_UNUSED (op1))9416 x86emuOp_into(u8 X86EMU_UNUSED(op1))
9417 {
9418     START_OF_INSTR();
9419     DECODE_PRINTF("INTO\n");
9420     TRACE_AND_STEP();
9421     if (ACCESS_FLAG(F_OF)) {
9422         if (_X86EMU_intrTab[4]) {
9423             (*_X86EMU_intrTab[4]) (4);
9424         }
9425         else {
9426             push_word((u16) M.x86.R_FLG);
9427             CLEAR_FLAG(F_IF);
9428             CLEAR_FLAG(F_TF);
9429             push_word(M.x86.R_CS);
9430             M.x86.R_CS = mem_access_word(4 * 4 + 2);
9431             push_word(M.x86.R_IP);
9432             M.x86.R_IP = mem_access_word(4 * 4);
9433         }
9434     }
9435     DECODE_CLEAR_SEGOVR();
9436     END_OF_INSTR();
9437 }
9438 
9439 /****************************************************************************
9440 REMARKS:
9441 Handles opcode 0xcf
9442 ****************************************************************************/
9443 static void
x86emuOp_iret(u8 X86EMU_UNUSED (op1))9444 x86emuOp_iret(u8 X86EMU_UNUSED(op1))
9445 {
9446     START_OF_INSTR();
9447     DECODE_PRINTF("IRET\n");
9448 
9449     TRACE_AND_STEP();
9450 
9451     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9452         M.x86.R_EIP = pop_long();
9453         M.x86.R_CS = pop_long() & 0xffff;
9454         M.x86.R_EFLG = (pop_long() & 0x257FD5) | (M.x86.R_EFLG & 0x1A0000);
9455     } else {
9456         M.x86.R_IP = pop_word();
9457         M.x86.R_CS = pop_word();
9458         M.x86.R_FLG = pop_word();
9459     }
9460     DECODE_CLEAR_SEGOVR();
9461     END_OF_INSTR();
9462 }
9463 
9464 /****************************************************************************
9465 REMARKS:
9466 Handles opcode 0xd0
9467 ****************************************************************************/
9468 static void
x86emuOp_opcD0_byte_RM_1(u8 X86EMU_UNUSED (op1))9469 x86emuOp_opcD0_byte_RM_1(u8 X86EMU_UNUSED(op1))
9470 {
9471     int mod, rl, rh;
9472     u8 *destreg;
9473     uint destoffset;
9474     u8 destval;
9475 
9476     /*
9477      * Yet another weirdo special case instruction format.  Part of
9478      * the opcode held below in "RH".  Doubly nested case would
9479      * result, except that the decoded instruction
9480      */
9481     START_OF_INSTR();
9482     FETCH_DECODE_MODRM(mod, rh, rl);
9483 #ifdef DEBUG
9484     if (DEBUG_DECODE()) {
9485         /* XXX DECODE_PRINTF may be changed to something more
9486            general, so that it is important to leave the strings
9487            in the same format, even though the result is that the
9488            above test is done twice. */
9489         switch (rh) {
9490         case 0:
9491             DECODE_PRINTF("ROL\t");
9492             break;
9493         case 1:
9494             DECODE_PRINTF("ROR\t");
9495             break;
9496         case 2:
9497             DECODE_PRINTF("RCL\t");
9498             break;
9499         case 3:
9500             DECODE_PRINTF("RCR\t");
9501             break;
9502         case 4:
9503             DECODE_PRINTF("SHL\t");
9504             break;
9505         case 5:
9506             DECODE_PRINTF("SHR\t");
9507             break;
9508         case 6:
9509             DECODE_PRINTF("SAL\t");
9510             break;
9511         case 7:
9512             DECODE_PRINTF("SAR\t");
9513             break;
9514         }
9515     }
9516 #endif
9517     /* know operation, decode the mod byte to find the addressing
9518        mode. */
9519     switch (mod) {
9520     case 0:
9521         DECODE_PRINTF("BYTE PTR ");
9522         destoffset = decode_rm00_address(rl);
9523         DECODE_PRINTF(",1\n");
9524         destval = fetch_data_byte(destoffset);
9525         TRACE_AND_STEP();
9526         destval = (*opcD0_byte_operation[rh]) (destval, 1);
9527         store_data_byte(destoffset, destval);
9528         break;
9529     case 1:
9530         DECODE_PRINTF("BYTE PTR ");
9531         destoffset = decode_rm01_address(rl);
9532         DECODE_PRINTF(",1\n");
9533         destval = fetch_data_byte(destoffset);
9534         TRACE_AND_STEP();
9535         destval = (*opcD0_byte_operation[rh]) (destval, 1);
9536         store_data_byte(destoffset, destval);
9537         break;
9538     case 2:
9539         DECODE_PRINTF("BYTE PTR ");
9540         destoffset = decode_rm10_address(rl);
9541         DECODE_PRINTF(",1\n");
9542         destval = fetch_data_byte(destoffset);
9543         TRACE_AND_STEP();
9544         destval = (*opcD0_byte_operation[rh]) (destval, 1);
9545         store_data_byte(destoffset, destval);
9546         break;
9547     case 3:                    /* register to register */
9548         destreg = DECODE_RM_BYTE_REGISTER(rl);
9549         DECODE_PRINTF(",1\n");
9550         TRACE_AND_STEP();
9551         destval = (*opcD0_byte_operation[rh]) (*destreg, 1);
9552         *destreg = destval;
9553         break;
9554     }
9555     DECODE_CLEAR_SEGOVR();
9556     END_OF_INSTR();
9557 }
9558 
9559 /****************************************************************************
9560 REMARKS:
9561 Handles opcode 0xd1
9562 ****************************************************************************/
9563 static void
x86emuOp_opcD1_word_RM_1(u8 X86EMU_UNUSED (op1))9564 x86emuOp_opcD1_word_RM_1(u8 X86EMU_UNUSED(op1))
9565 {
9566     int mod, rl, rh;
9567     uint destoffset;
9568 
9569     /*
9570      * Yet another weirdo special case instruction format.  Part of
9571      * the opcode held below in "RH".  Doubly nested case would
9572      * result, except that the decoded instruction
9573      */
9574     START_OF_INSTR();
9575     FETCH_DECODE_MODRM(mod, rh, rl);
9576 #ifdef DEBUG
9577     if (DEBUG_DECODE()) {
9578         /* XXX DECODE_PRINTF may be changed to something more
9579            general, so that it is important to leave the strings
9580            in the same format, even though the result is that the
9581            above test is done twice. */
9582         switch (rh) {
9583         case 0:
9584             DECODE_PRINTF("ROL\t");
9585             break;
9586         case 1:
9587             DECODE_PRINTF("ROR\t");
9588             break;
9589         case 2:
9590             DECODE_PRINTF("RCL\t");
9591             break;
9592         case 3:
9593             DECODE_PRINTF("RCR\t");
9594             break;
9595         case 4:
9596             DECODE_PRINTF("SHL\t");
9597             break;
9598         case 5:
9599             DECODE_PRINTF("SHR\t");
9600             break;
9601         case 6:
9602             DECODE_PRINTF("SAL\t");
9603             break;
9604         case 7:
9605             DECODE_PRINTF("SAR\t");
9606             break;
9607         }
9608     }
9609 #endif
9610     /* know operation, decode the mod byte to find the addressing
9611        mode. */
9612     switch (mod) {
9613     case 0:
9614         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9615             u32 destval;
9616 
9617             DECODE_PRINTF("DWORD PTR ");
9618             destoffset = decode_rm00_address(rl);
9619             DECODE_PRINTF(",1\n");
9620             destval = fetch_data_long(destoffset);
9621             TRACE_AND_STEP();
9622             destval = (*opcD1_long_operation[rh]) (destval, 1);
9623             store_data_long(destoffset, destval);
9624         }
9625         else {
9626             u16 destval;
9627 
9628             DECODE_PRINTF("WORD PTR ");
9629             destoffset = decode_rm00_address(rl);
9630             DECODE_PRINTF(",1\n");
9631             destval = fetch_data_word(destoffset);
9632             TRACE_AND_STEP();
9633             destval = (*opcD1_word_operation[rh]) (destval, 1);
9634             store_data_word(destoffset, destval);
9635         }
9636         break;
9637     case 1:
9638         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9639             u32 destval;
9640 
9641             DECODE_PRINTF("DWORD PTR ");
9642             destoffset = decode_rm01_address(rl);
9643             DECODE_PRINTF(",1\n");
9644             destval = fetch_data_long(destoffset);
9645             TRACE_AND_STEP();
9646             destval = (*opcD1_long_operation[rh]) (destval, 1);
9647             store_data_long(destoffset, destval);
9648         }
9649         else {
9650             u16 destval;
9651 
9652             DECODE_PRINTF("WORD PTR ");
9653             destoffset = decode_rm01_address(rl);
9654             DECODE_PRINTF(",1\n");
9655             destval = fetch_data_word(destoffset);
9656             TRACE_AND_STEP();
9657             destval = (*opcD1_word_operation[rh]) (destval, 1);
9658             store_data_word(destoffset, destval);
9659         }
9660         break;
9661     case 2:
9662         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9663             u32 destval;
9664 
9665             DECODE_PRINTF("DWORD PTR ");
9666             destoffset = decode_rm10_address(rl);
9667             DECODE_PRINTF(",1\n");
9668             destval = fetch_data_long(destoffset);
9669             TRACE_AND_STEP();
9670             destval = (*opcD1_long_operation[rh]) (destval, 1);
9671             store_data_long(destoffset, destval);
9672         }
9673         else {
9674             u16 destval;
9675 
9676             DECODE_PRINTF("BYTE PTR ");
9677             destoffset = decode_rm10_address(rl);
9678             DECODE_PRINTF(",1\n");
9679             destval = fetch_data_word(destoffset);
9680             TRACE_AND_STEP();
9681             destval = (*opcD1_word_operation[rh]) (destval, 1);
9682             store_data_word(destoffset, destval);
9683         }
9684         break;
9685     case 3:                    /* register to register */
9686         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9687             u32 destval;
9688             u32 *destreg;
9689 
9690             destreg = DECODE_RM_LONG_REGISTER(rl);
9691             DECODE_PRINTF(",1\n");
9692             TRACE_AND_STEP();
9693             destval = (*opcD1_long_operation[rh]) (*destreg, 1);
9694             *destreg = destval;
9695         }
9696         else {
9697             u16 destval;
9698             u16 *destreg;
9699 
9700             destreg = DECODE_RM_WORD_REGISTER(rl);
9701             DECODE_PRINTF(",1\n");
9702             TRACE_AND_STEP();
9703             destval = (*opcD1_word_operation[rh]) (*destreg, 1);
9704             *destreg = destval;
9705         }
9706         break;
9707     }
9708     DECODE_CLEAR_SEGOVR();
9709     END_OF_INSTR();
9710 }
9711 
9712 /****************************************************************************
9713 REMARKS:
9714 Handles opcode 0xd2
9715 ****************************************************************************/
9716 static void
x86emuOp_opcD2_byte_RM_CL(u8 X86EMU_UNUSED (op1))9717 x86emuOp_opcD2_byte_RM_CL(u8 X86EMU_UNUSED(op1))
9718 {
9719     int mod, rl, rh;
9720     u8 *destreg;
9721     uint destoffset;
9722     u8 destval;
9723     u8 amt;
9724 
9725     /*
9726      * Yet another weirdo special case instruction format.  Part of
9727      * the opcode held below in "RH".  Doubly nested case would
9728      * result, except that the decoded instruction
9729      */
9730     START_OF_INSTR();
9731     FETCH_DECODE_MODRM(mod, rh, rl);
9732 #ifdef DEBUG
9733     if (DEBUG_DECODE()) {
9734         /* XXX DECODE_PRINTF may be changed to something more
9735            general, so that it is important to leave the strings
9736            in the same format, even though the result is that the
9737            above test is done twice. */
9738         switch (rh) {
9739         case 0:
9740             DECODE_PRINTF("ROL\t");
9741             break;
9742         case 1:
9743             DECODE_PRINTF("ROR\t");
9744             break;
9745         case 2:
9746             DECODE_PRINTF("RCL\t");
9747             break;
9748         case 3:
9749             DECODE_PRINTF("RCR\t");
9750             break;
9751         case 4:
9752             DECODE_PRINTF("SHL\t");
9753             break;
9754         case 5:
9755             DECODE_PRINTF("SHR\t");
9756             break;
9757         case 6:
9758             DECODE_PRINTF("SAL\t");
9759             break;
9760         case 7:
9761             DECODE_PRINTF("SAR\t");
9762             break;
9763         }
9764     }
9765 #endif
9766     /* know operation, decode the mod byte to find the addressing
9767        mode. */
9768     amt = M.x86.R_CL;
9769     switch (mod) {
9770     case 0:
9771         DECODE_PRINTF("BYTE PTR ");
9772         destoffset = decode_rm00_address(rl);
9773         DECODE_PRINTF(",CL\n");
9774         destval = fetch_data_byte(destoffset);
9775         TRACE_AND_STEP();
9776         destval = (*opcD0_byte_operation[rh]) (destval, amt);
9777         store_data_byte(destoffset, destval);
9778         break;
9779     case 1:
9780         DECODE_PRINTF("BYTE PTR ");
9781         destoffset = decode_rm01_address(rl);
9782         DECODE_PRINTF(",CL\n");
9783         destval = fetch_data_byte(destoffset);
9784         TRACE_AND_STEP();
9785         destval = (*opcD0_byte_operation[rh]) (destval, amt);
9786         store_data_byte(destoffset, destval);
9787         break;
9788     case 2:
9789         DECODE_PRINTF("BYTE PTR ");
9790         destoffset = decode_rm10_address(rl);
9791         DECODE_PRINTF(",CL\n");
9792         destval = fetch_data_byte(destoffset);
9793         TRACE_AND_STEP();
9794         destval = (*opcD0_byte_operation[rh]) (destval, amt);
9795         store_data_byte(destoffset, destval);
9796         break;
9797     case 3:                    /* register to register */
9798         destreg = DECODE_RM_BYTE_REGISTER(rl);
9799         DECODE_PRINTF(",CL\n");
9800         TRACE_AND_STEP();
9801         destval = (*opcD0_byte_operation[rh]) (*destreg, amt);
9802         *destreg = destval;
9803         break;
9804     }
9805     DECODE_CLEAR_SEGOVR();
9806     END_OF_INSTR();
9807 }
9808 
9809 /****************************************************************************
9810 REMARKS:
9811 Handles opcode 0xd3
9812 ****************************************************************************/
9813 static void
x86emuOp_opcD3_word_RM_CL(u8 X86EMU_UNUSED (op1))9814 x86emuOp_opcD3_word_RM_CL(u8 X86EMU_UNUSED(op1))
9815 {
9816     int mod, rl, rh;
9817     uint destoffset;
9818     u8 amt;
9819 
9820     /*
9821      * Yet another weirdo special case instruction format.  Part of
9822      * the opcode held below in "RH".  Doubly nested case would
9823      * result, except that the decoded instruction
9824      */
9825     START_OF_INSTR();
9826     FETCH_DECODE_MODRM(mod, rh, rl);
9827 #ifdef DEBUG
9828     if (DEBUG_DECODE()) {
9829         /* XXX DECODE_PRINTF may be changed to something more
9830            general, so that it is important to leave the strings
9831            in the same format, even though the result is that the
9832            above test is done twice. */
9833         switch (rh) {
9834         case 0:
9835             DECODE_PRINTF("ROL\t");
9836             break;
9837         case 1:
9838             DECODE_PRINTF("ROR\t");
9839             break;
9840         case 2:
9841             DECODE_PRINTF("RCL\t");
9842             break;
9843         case 3:
9844             DECODE_PRINTF("RCR\t");
9845             break;
9846         case 4:
9847             DECODE_PRINTF("SHL\t");
9848             break;
9849         case 5:
9850             DECODE_PRINTF("SHR\t");
9851             break;
9852         case 6:
9853             DECODE_PRINTF("SAL\t");
9854             break;
9855         case 7:
9856             DECODE_PRINTF("SAR\t");
9857             break;
9858         }
9859     }
9860 #endif
9861     /* know operation, decode the mod byte to find the addressing
9862        mode. */
9863     amt = M.x86.R_CL;
9864     switch (mod) {
9865     case 0:
9866         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9867             u32 destval;
9868 
9869             DECODE_PRINTF("DWORD PTR ");
9870             destoffset = decode_rm00_address(rl);
9871             DECODE_PRINTF(",CL\n");
9872             destval = fetch_data_long(destoffset);
9873             TRACE_AND_STEP();
9874             destval = (*opcD1_long_operation[rh]) (destval, amt);
9875             store_data_long(destoffset, destval);
9876         }
9877         else {
9878             u16 destval;
9879 
9880             DECODE_PRINTF("WORD PTR ");
9881             destoffset = decode_rm00_address(rl);
9882             DECODE_PRINTF(",CL\n");
9883             destval = fetch_data_word(destoffset);
9884             TRACE_AND_STEP();
9885             destval = (*opcD1_word_operation[rh]) (destval, amt);
9886             store_data_word(destoffset, destval);
9887         }
9888         break;
9889     case 1:
9890         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9891             u32 destval;
9892 
9893             DECODE_PRINTF("DWORD PTR ");
9894             destoffset = decode_rm01_address(rl);
9895             DECODE_PRINTF(",CL\n");
9896             destval = fetch_data_long(destoffset);
9897             TRACE_AND_STEP();
9898             destval = (*opcD1_long_operation[rh]) (destval, amt);
9899             store_data_long(destoffset, destval);
9900         }
9901         else {
9902             u16 destval;
9903 
9904             DECODE_PRINTF("WORD PTR ");
9905             destoffset = decode_rm01_address(rl);
9906             DECODE_PRINTF(",CL\n");
9907             destval = fetch_data_word(destoffset);
9908             TRACE_AND_STEP();
9909             destval = (*opcD1_word_operation[rh]) (destval, amt);
9910             store_data_word(destoffset, destval);
9911         }
9912         break;
9913     case 2:
9914         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9915             u32 destval;
9916 
9917             DECODE_PRINTF("DWORD PTR ");
9918             destoffset = decode_rm10_address(rl);
9919             DECODE_PRINTF(",CL\n");
9920             destval = fetch_data_long(destoffset);
9921             TRACE_AND_STEP();
9922             destval = (*opcD1_long_operation[rh]) (destval, amt);
9923             store_data_long(destoffset, destval);
9924         }
9925         else {
9926             u16 destval;
9927 
9928             DECODE_PRINTF("WORD PTR ");
9929             destoffset = decode_rm10_address(rl);
9930             DECODE_PRINTF(",CL\n");
9931             destval = fetch_data_word(destoffset);
9932             TRACE_AND_STEP();
9933             destval = (*opcD1_word_operation[rh]) (destval, amt);
9934             store_data_word(destoffset, destval);
9935         }
9936         break;
9937     case 3:                    /* register to register */
9938         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9939             u32 *destreg;
9940 
9941             destreg = DECODE_RM_LONG_REGISTER(rl);
9942             DECODE_PRINTF(",CL\n");
9943             TRACE_AND_STEP();
9944             *destreg = (*opcD1_long_operation[rh]) (*destreg, amt);
9945         }
9946         else {
9947             u16 *destreg;
9948 
9949             destreg = DECODE_RM_WORD_REGISTER(rl);
9950             DECODE_PRINTF(",CL\n");
9951             TRACE_AND_STEP();
9952             *destreg = (*opcD1_word_operation[rh]) (*destreg, amt);
9953         }
9954         break;
9955     }
9956     DECODE_CLEAR_SEGOVR();
9957     END_OF_INSTR();
9958 }
9959 
9960 /****************************************************************************
9961 REMARKS:
9962 Handles opcode 0xd4
9963 ****************************************************************************/
9964 static void
x86emuOp_aam(u8 X86EMU_UNUSED (op1))9965 x86emuOp_aam(u8 X86EMU_UNUSED(op1))
9966 {
9967     u8 a;
9968 
9969     START_OF_INSTR();
9970     DECODE_PRINTF("AAM\n");
9971     a = fetch_byte_imm();       /* this is a stupid encoding. */
9972     if (a != 10) {
9973         /* fix: add base decoding
9974            aam_word(u8 val, int base a) */
9975         DECODE_PRINTF("ERROR DECODING AAM\n");
9976         TRACE_REGS();
9977         HALT_SYS();
9978     }
9979     TRACE_AND_STEP();
9980     /* note the type change here --- returning AL and AH in AX. */
9981     M.x86.R_AX = aam_word(M.x86.R_AL);
9982     DECODE_CLEAR_SEGOVR();
9983     END_OF_INSTR();
9984 }
9985 
9986 /****************************************************************************
9987 REMARKS:
9988 Handles opcode 0xd5
9989 ****************************************************************************/
9990 static void
x86emuOp_aad(u8 X86EMU_UNUSED (op1))9991 x86emuOp_aad(u8 X86EMU_UNUSED(op1))
9992 {
9993     u8 a;
9994 
9995     START_OF_INSTR();
9996     DECODE_PRINTF("AAD\n");
9997     a = fetch_byte_imm();
9998     if (a != 10) {
9999         /* fix: add base decoding
10000            aad_word(u16 val, int base a) */
10001         DECODE_PRINTF("ERROR DECODING AAM\n");
10002         TRACE_REGS();
10003         HALT_SYS();
10004     }
10005     TRACE_AND_STEP();
10006     M.x86.R_AX = aad_word(M.x86.R_AX);
10007     DECODE_CLEAR_SEGOVR();
10008     END_OF_INSTR();
10009 }
10010 
10011 /* opcode 0xd6 ILLEGAL OPCODE */
10012 
10013 /****************************************************************************
10014 REMARKS:
10015 Handles opcode 0xd7
10016 ****************************************************************************/
10017 static void
x86emuOp_xlat(u8 X86EMU_UNUSED (op1))10018 x86emuOp_xlat(u8 X86EMU_UNUSED(op1))
10019 {
10020     u16 addr;
10021 
10022     START_OF_INSTR();
10023     DECODE_PRINTF("XLAT\n");
10024     TRACE_AND_STEP();
10025     addr = (u16) (M.x86.R_BX + (u8) M.x86.R_AL);
10026     M.x86.R_AL = fetch_data_byte(addr);
10027     DECODE_CLEAR_SEGOVR();
10028     END_OF_INSTR();
10029 }
10030 
10031 /* instuctions  D8 .. DF are in i87_ops.c */
10032 
10033 /****************************************************************************
10034 REMARKS:
10035 Handles opcode 0xe0
10036 ****************************************************************************/
10037 static void
x86emuOp_loopne(u8 X86EMU_UNUSED (op1))10038 x86emuOp_loopne(u8 X86EMU_UNUSED(op1))
10039 {
10040     s16 ip;
10041 
10042     START_OF_INSTR();
10043     DECODE_PRINTF("LOOPNE\t");
10044     ip = (s8) fetch_byte_imm();
10045     ip += (s16) M.x86.R_IP;
10046     DECODE_PRINTF2("%04x\n", ip);
10047     TRACE_AND_STEP();
10048     M.x86.R_CX -= 1;
10049     if (M.x86.R_CX != 0 && !ACCESS_FLAG(F_ZF))  /* CX != 0 and !ZF */
10050         M.x86.R_IP = ip;
10051     DECODE_CLEAR_SEGOVR();
10052     END_OF_INSTR();
10053 }
10054 
10055 /****************************************************************************
10056 REMARKS:
10057 Handles opcode 0xe1
10058 ****************************************************************************/
10059 static void
x86emuOp_loope(u8 X86EMU_UNUSED (op1))10060 x86emuOp_loope(u8 X86EMU_UNUSED(op1))
10061 {
10062     s16 ip;
10063 
10064     START_OF_INSTR();
10065     DECODE_PRINTF("LOOPE\t");
10066     ip = (s8) fetch_byte_imm();
10067     ip += (s16) M.x86.R_IP;
10068     DECODE_PRINTF2("%04x\n", ip);
10069     TRACE_AND_STEP();
10070     M.x86.R_CX -= 1;
10071     if (M.x86.R_CX != 0 && ACCESS_FLAG(F_ZF))   /* CX != 0 and ZF */
10072         M.x86.R_IP = ip;
10073     DECODE_CLEAR_SEGOVR();
10074     END_OF_INSTR();
10075 }
10076 
10077 /****************************************************************************
10078 REMARKS:
10079 Handles opcode 0xe2
10080 ****************************************************************************/
10081 static void
x86emuOp_loop(u8 X86EMU_UNUSED (op1))10082 x86emuOp_loop(u8 X86EMU_UNUSED(op1))
10083 {
10084     s16 ip;
10085 
10086     START_OF_INSTR();
10087     DECODE_PRINTF("LOOP\t");
10088     ip = (s8) fetch_byte_imm();
10089     ip += (s16) M.x86.R_IP;
10090     DECODE_PRINTF2("%04x\n", ip);
10091     TRACE_AND_STEP();
10092     M.x86.R_CX -= 1;
10093     if (M.x86.R_CX != 0)
10094         M.x86.R_IP = ip;
10095     DECODE_CLEAR_SEGOVR();
10096     END_OF_INSTR();
10097 }
10098 
10099 /****************************************************************************
10100 REMARKS:
10101 Handles opcode 0xe3
10102 ****************************************************************************/
10103 static void
x86emuOp_jcxz(u8 X86EMU_UNUSED (op1))10104 x86emuOp_jcxz(u8 X86EMU_UNUSED(op1))
10105 {
10106     u16 target;
10107     s8 offset;
10108 
10109     /* jump to byte offset if overflow flag is set */
10110     START_OF_INSTR();
10111     DECODE_PRINTF("JCXZ\t");
10112     offset = (s8) fetch_byte_imm();
10113     target = (u16) (M.x86.R_IP + offset);
10114     DECODE_PRINTF2("%x\n", target);
10115     TRACE_AND_STEP();
10116     if (M.x86.R_CX == 0)
10117         M.x86.R_IP = target;
10118     DECODE_CLEAR_SEGOVR();
10119     END_OF_INSTR();
10120 }
10121 
10122 /****************************************************************************
10123 REMARKS:
10124 Handles opcode 0xe4
10125 ****************************************************************************/
10126 static void
x86emuOp_in_byte_AL_IMM(u8 X86EMU_UNUSED (op1))10127 x86emuOp_in_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
10128 {
10129     u8 port;
10130 
10131     START_OF_INSTR();
10132     DECODE_PRINTF("IN\t");
10133     port = (u8) fetch_byte_imm();
10134     DECODE_PRINTF2("%x,AL\n", port);
10135     TRACE_AND_STEP();
10136     M.x86.R_AL = (*sys_inb) (port);
10137     DECODE_CLEAR_SEGOVR();
10138     END_OF_INSTR();
10139 }
10140 
10141 /****************************************************************************
10142 REMARKS:
10143 Handles opcode 0xe5
10144 ****************************************************************************/
10145 static void
x86emuOp_in_word_AX_IMM(u8 X86EMU_UNUSED (op1))10146 x86emuOp_in_word_AX_IMM(u8 X86EMU_UNUSED(op1))
10147 {
10148     u8 port;
10149 
10150     START_OF_INSTR();
10151     DECODE_PRINTF("IN\t");
10152     port = (u8) fetch_byte_imm();
10153     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10154         DECODE_PRINTF2("EAX,%x\n", port);
10155     }
10156     else {
10157         DECODE_PRINTF2("AX,%x\n", port);
10158     }
10159     TRACE_AND_STEP();
10160     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10161         M.x86.R_EAX = (*sys_inl) (port);
10162     }
10163     else {
10164         M.x86.R_AX = (*sys_inw) (port);
10165     }
10166     DECODE_CLEAR_SEGOVR();
10167     END_OF_INSTR();
10168 }
10169 
10170 /****************************************************************************
10171 REMARKS:
10172 Handles opcode 0xe6
10173 ****************************************************************************/
10174 static void
x86emuOp_out_byte_IMM_AL(u8 X86EMU_UNUSED (op1))10175 x86emuOp_out_byte_IMM_AL(u8 X86EMU_UNUSED(op1))
10176 {
10177     u8 port;
10178 
10179     START_OF_INSTR();
10180     DECODE_PRINTF("OUT\t");
10181     port = (u8) fetch_byte_imm();
10182     DECODE_PRINTF2("%x,AL\n", port);
10183     TRACE_AND_STEP();
10184     (*sys_outb) (port, M.x86.R_AL);
10185     DECODE_CLEAR_SEGOVR();
10186     END_OF_INSTR();
10187 }
10188 
10189 /****************************************************************************
10190 REMARKS:
10191 Handles opcode 0xe7
10192 ****************************************************************************/
10193 static void
x86emuOp_out_word_IMM_AX(u8 X86EMU_UNUSED (op1))10194 x86emuOp_out_word_IMM_AX(u8 X86EMU_UNUSED(op1))
10195 {
10196     u8 port;
10197 
10198     START_OF_INSTR();
10199     DECODE_PRINTF("OUT\t");
10200     port = (u8) fetch_byte_imm();
10201     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10202         DECODE_PRINTF2("%x,EAX\n", port);
10203     }
10204     else {
10205         DECODE_PRINTF2("%x,AX\n", port);
10206     }
10207     TRACE_AND_STEP();
10208     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10209         (*sys_outl) (port, M.x86.R_EAX);
10210     }
10211     else {
10212         (*sys_outw) (port, M.x86.R_AX);
10213     }
10214     DECODE_CLEAR_SEGOVR();
10215     END_OF_INSTR();
10216 }
10217 
10218 /****************************************************************************
10219 REMARKS:
10220 Handles opcode 0xe8
10221 ****************************************************************************/
10222 static void
x86emuOp_call_near_IMM(u8 X86EMU_UNUSED (op1))10223 x86emuOp_call_near_IMM(u8 X86EMU_UNUSED(op1))
10224 {
10225     s16 ip16 = 0;
10226     s32 ip32 = 0;
10227 
10228     START_OF_INSTR();
10229     DECODE_PRINTF("CALL\t");
10230     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10231         ip32 = (s32) fetch_long_imm();
10232         ip32 += (s16) M.x86.R_IP;       /* CHECK SIGN */
10233         DECODE_PRINTF2("%04x\n", (u16) ip32);
10234         CALL_TRACE(M.x86.saved_cs, M.x86.saved_ip, M.x86.R_CS, ip32, "");
10235     }
10236     else {
10237         ip16 = (s16) fetch_word_imm();
10238         ip16 += (s16) M.x86.R_IP;       /* CHECK SIGN */
10239         DECODE_PRINTF2("%04x\n", (u16) ip16);
10240         CALL_TRACE(M.x86.saved_cs, M.x86.saved_ip, M.x86.R_CS, ip16, "");
10241     }
10242     TRACE_AND_STEP();
10243     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10244         push_long(M.x86.R_EIP);
10245         M.x86.R_EIP = ip32 & 0xffff;
10246     }
10247     else {
10248         push_word(M.x86.R_IP);
10249         M.x86.R_EIP = ip16;
10250     }
10251     DECODE_CLEAR_SEGOVR();
10252     END_OF_INSTR();
10253 }
10254 
10255 /****************************************************************************
10256 REMARKS:
10257 Handles opcode 0xe9
10258 ****************************************************************************/
10259 static void
x86emuOp_jump_near_IMM(u8 X86EMU_UNUSED (op1))10260 x86emuOp_jump_near_IMM(u8 X86EMU_UNUSED(op1))
10261 {
10262     u32 ip;
10263 
10264     START_OF_INSTR();
10265     DECODE_PRINTF("JMP\t");
10266     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10267         ip = (u32) fetch_long_imm();
10268         ip += (u32) M.x86.R_EIP;
10269         DECODE_PRINTF2("%08x\n", (u32) ip);
10270         TRACE_AND_STEP();
10271         M.x86.R_EIP = (u32) ip;
10272     }
10273     else {
10274         ip = (s16) fetch_word_imm();
10275         ip += (s16) M.x86.R_IP;
10276         DECODE_PRINTF2("%04x\n", (u16) ip);
10277         TRACE_AND_STEP();
10278         M.x86.R_IP = (u16) ip;
10279     }
10280     DECODE_CLEAR_SEGOVR();
10281     END_OF_INSTR();
10282 }
10283 
10284 /****************************************************************************
10285 REMARKS:
10286 Handles opcode 0xea
10287 ****************************************************************************/
10288 static void
x86emuOp_jump_far_IMM(u8 X86EMU_UNUSED (op1))10289 x86emuOp_jump_far_IMM(u8 X86EMU_UNUSED(op1))
10290 {
10291     u16 cs;
10292     u32 ip;
10293 
10294     START_OF_INSTR();
10295     DECODE_PRINTF("JMP\tFAR ");
10296     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10297         ip = fetch_long_imm();
10298     }
10299     else {
10300         ip = fetch_word_imm();
10301     }
10302     cs = fetch_word_imm();
10303     DECODE_PRINTF2("%04x:", cs);
10304     DECODE_PRINTF2("%04x\n", ip);
10305     TRACE_AND_STEP();
10306     M.x86.R_EIP = ip & 0xffff;
10307     M.x86.R_CS = cs;
10308     DECODE_CLEAR_SEGOVR();
10309     END_OF_INSTR();
10310 }
10311 
10312 /****************************************************************************
10313 REMARKS:
10314 Handles opcode 0xeb
10315 ****************************************************************************/
10316 static void
x86emuOp_jump_byte_IMM(u8 X86EMU_UNUSED (op1))10317 x86emuOp_jump_byte_IMM(u8 X86EMU_UNUSED(op1))
10318 {
10319     u16 target;
10320     s8 offset;
10321 
10322     START_OF_INSTR();
10323     DECODE_PRINTF("JMP\t");
10324     offset = (s8) fetch_byte_imm();
10325     target = (u16) (M.x86.R_IP + offset);
10326     DECODE_PRINTF2("%x\n", target);
10327     TRACE_AND_STEP();
10328     M.x86.R_IP = target;
10329     DECODE_CLEAR_SEGOVR();
10330     END_OF_INSTR();
10331 }
10332 
10333 /****************************************************************************
10334 REMARKS:
10335 Handles opcode 0xec
10336 ****************************************************************************/
10337 static void
x86emuOp_in_byte_AL_DX(u8 X86EMU_UNUSED (op1))10338 x86emuOp_in_byte_AL_DX(u8 X86EMU_UNUSED(op1))
10339 {
10340     START_OF_INSTR();
10341     DECODE_PRINTF("IN\tAL,DX\n");
10342     TRACE_AND_STEP();
10343     M.x86.R_AL = (*sys_inb) (M.x86.R_DX);
10344     DECODE_CLEAR_SEGOVR();
10345     END_OF_INSTR();
10346 }
10347 
10348 /****************************************************************************
10349 REMARKS:
10350 Handles opcode 0xed
10351 ****************************************************************************/
10352 static void
x86emuOp_in_word_AX_DX(u8 X86EMU_UNUSED (op1))10353 x86emuOp_in_word_AX_DX(u8 X86EMU_UNUSED(op1))
10354 {
10355     START_OF_INSTR();
10356     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10357         DECODE_PRINTF("IN\tEAX,DX\n");
10358     }
10359     else {
10360         DECODE_PRINTF("IN\tAX,DX\n");
10361     }
10362     TRACE_AND_STEP();
10363     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10364         M.x86.R_EAX = (*sys_inl) (M.x86.R_DX);
10365     }
10366     else {
10367         M.x86.R_AX = (*sys_inw) (M.x86.R_DX);
10368     }
10369     DECODE_CLEAR_SEGOVR();
10370     END_OF_INSTR();
10371 }
10372 
10373 /****************************************************************************
10374 REMARKS:
10375 Handles opcode 0xee
10376 ****************************************************************************/
10377 static void
x86emuOp_out_byte_DX_AL(u8 X86EMU_UNUSED (op1))10378 x86emuOp_out_byte_DX_AL(u8 X86EMU_UNUSED(op1))
10379 {
10380     START_OF_INSTR();
10381     DECODE_PRINTF("OUT\tDX,AL\n");
10382     TRACE_AND_STEP();
10383     (*sys_outb) (M.x86.R_DX, M.x86.R_AL);
10384     DECODE_CLEAR_SEGOVR();
10385     END_OF_INSTR();
10386 }
10387 
10388 /****************************************************************************
10389 REMARKS:
10390 Handles opcode 0xef
10391 ****************************************************************************/
10392 static void
x86emuOp_out_word_DX_AX(u8 X86EMU_UNUSED (op1))10393 x86emuOp_out_word_DX_AX(u8 X86EMU_UNUSED(op1))
10394 {
10395     START_OF_INSTR();
10396     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10397         DECODE_PRINTF("OUT\tDX,EAX\n");
10398     }
10399     else {
10400         DECODE_PRINTF("OUT\tDX,AX\n");
10401     }
10402     TRACE_AND_STEP();
10403     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10404         (*sys_outl) (M.x86.R_DX, M.x86.R_EAX);
10405     }
10406     else {
10407         (*sys_outw) (M.x86.R_DX, M.x86.R_AX);
10408     }
10409     DECODE_CLEAR_SEGOVR();
10410     END_OF_INSTR();
10411 }
10412 
10413 /****************************************************************************
10414 REMARKS:
10415 Handles opcode 0xf0
10416 ****************************************************************************/
10417 static void
x86emuOp_lock(u8 X86EMU_UNUSED (op1))10418 x86emuOp_lock(u8 X86EMU_UNUSED(op1))
10419 {
10420     START_OF_INSTR();
10421     DECODE_PRINTF("LOCK:\n");
10422     TRACE_AND_STEP();
10423     DECODE_CLEAR_SEGOVR();
10424     END_OF_INSTR();
10425 }
10426 
10427 /*opcode 0xf1 ILLEGAL OPERATION */
10428 
10429 /****************************************************************************
10430 REMARKS:
10431 Handles opcode 0xf2
10432 ****************************************************************************/
10433 static void
x86emuOp_repne(u8 X86EMU_UNUSED (op1))10434 x86emuOp_repne(u8 X86EMU_UNUSED(op1))
10435 {
10436     START_OF_INSTR();
10437     DECODE_PRINTF("REPNE\n");
10438     TRACE_AND_STEP();
10439     M.x86.mode |= SYSMODE_PREFIX_REPNE;
10440     DECODE_CLEAR_SEGOVR();
10441     END_OF_INSTR();
10442 }
10443 
10444 /****************************************************************************
10445 REMARKS:
10446 Handles opcode 0xf3
10447 ****************************************************************************/
10448 static void
x86emuOp_repe(u8 X86EMU_UNUSED (op1))10449 x86emuOp_repe(u8 X86EMU_UNUSED(op1))
10450 {
10451     START_OF_INSTR();
10452     DECODE_PRINTF("REPE\n");
10453     TRACE_AND_STEP();
10454     M.x86.mode |= SYSMODE_PREFIX_REPE;
10455     DECODE_CLEAR_SEGOVR();
10456     END_OF_INSTR();
10457 }
10458 
10459 /****************************************************************************
10460 REMARKS:
10461 Handles opcode 0xf4
10462 ****************************************************************************/
10463 static void
x86emuOp_halt(u8 X86EMU_UNUSED (op1))10464 x86emuOp_halt(u8 X86EMU_UNUSED(op1))
10465 {
10466     START_OF_INSTR();
10467     DECODE_PRINTF("HALT\n");
10468     TRACE_AND_STEP();
10469     HALT_SYS();
10470     DECODE_CLEAR_SEGOVR();
10471     END_OF_INSTR();
10472 }
10473 
10474 /****************************************************************************
10475 REMARKS:
10476 Handles opcode 0xf5
10477 ****************************************************************************/
10478 static void
x86emuOp_cmc(u8 X86EMU_UNUSED (op1))10479 x86emuOp_cmc(u8 X86EMU_UNUSED(op1))
10480 {
10481     /* complement the carry flag. */
10482     START_OF_INSTR();
10483     DECODE_PRINTF("CMC\n");
10484     TRACE_AND_STEP();
10485     TOGGLE_FLAG(F_CF);
10486     DECODE_CLEAR_SEGOVR();
10487     END_OF_INSTR();
10488 }
10489 
10490 /****************************************************************************
10491 REMARKS:
10492 Handles opcode 0xf6
10493 ****************************************************************************/
10494 static void
x86emuOp_opcF6_byte_RM(u8 X86EMU_UNUSED (op1))10495 x86emuOp_opcF6_byte_RM(u8 X86EMU_UNUSED(op1))
10496 {
10497     int mod, rl, rh;
10498     u8 *destreg;
10499     uint destoffset;
10500     u8 destval, srcval;
10501 
10502     /* long, drawn out code follows.  Double switch for a total
10503        of 32 cases.  */
10504     START_OF_INSTR();
10505     FETCH_DECODE_MODRM(mod, rh, rl);
10506     switch (mod) {
10507     case 0:                    /* mod=00 */
10508         switch (rh) {
10509         case 0:                /* test byte imm */
10510             DECODE_PRINTF("TEST\tBYTE PTR ");
10511             destoffset = decode_rm00_address(rl);
10512             DECODE_PRINTF(",");
10513             srcval = fetch_byte_imm();
10514             DECODE_PRINTF2("%02x\n", srcval);
10515             destval = fetch_data_byte(destoffset);
10516             TRACE_AND_STEP();
10517             test_byte(destval, srcval);
10518             break;
10519         case 1:
10520             DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n");
10521             HALT_SYS();
10522             break;
10523         case 2:
10524             DECODE_PRINTF("NOT\tBYTE PTR ");
10525             destoffset = decode_rm00_address(rl);
10526             DECODE_PRINTF("\n");
10527             destval = fetch_data_byte(destoffset);
10528             TRACE_AND_STEP();
10529             destval = not_byte(destval);
10530             store_data_byte(destoffset, destval);
10531             break;
10532         case 3:
10533             DECODE_PRINTF("NEG\tBYTE PTR ");
10534             destoffset = decode_rm00_address(rl);
10535             DECODE_PRINTF("\n");
10536             destval = fetch_data_byte(destoffset);
10537             TRACE_AND_STEP();
10538             destval = neg_byte(destval);
10539             store_data_byte(destoffset, destval);
10540             break;
10541         case 4:
10542             DECODE_PRINTF("MUL\tBYTE PTR ");
10543             destoffset = decode_rm00_address(rl);
10544             DECODE_PRINTF("\n");
10545             destval = fetch_data_byte(destoffset);
10546             TRACE_AND_STEP();
10547             mul_byte(destval);
10548             break;
10549         case 5:
10550             DECODE_PRINTF("IMUL\tBYTE PTR ");
10551             destoffset = decode_rm00_address(rl);
10552             DECODE_PRINTF("\n");
10553             destval = fetch_data_byte(destoffset);
10554             TRACE_AND_STEP();
10555             imul_byte(destval);
10556             break;
10557         case 6:
10558             DECODE_PRINTF("DIV\tBYTE PTR ");
10559             destoffset = decode_rm00_address(rl);
10560             DECODE_PRINTF("\n");
10561             destval = fetch_data_byte(destoffset);
10562             TRACE_AND_STEP();
10563             div_byte(destval);
10564             break;
10565         case 7:
10566             DECODE_PRINTF("IDIV\tBYTE PTR ");
10567             destoffset = decode_rm00_address(rl);
10568             DECODE_PRINTF("\n");
10569             destval = fetch_data_byte(destoffset);
10570             TRACE_AND_STEP();
10571             idiv_byte(destval);
10572             break;
10573         }
10574         break;                  /* end mod==00 */
10575     case 1:                    /* mod=01 */
10576         switch (rh) {
10577         case 0:                /* test byte imm */
10578             DECODE_PRINTF("TEST\tBYTE PTR ");
10579             destoffset = decode_rm01_address(rl);
10580             DECODE_PRINTF(",");
10581             srcval = fetch_byte_imm();
10582             DECODE_PRINTF2("%02x\n", srcval);
10583             destval = fetch_data_byte(destoffset);
10584             TRACE_AND_STEP();
10585             test_byte(destval, srcval);
10586             break;
10587         case 1:
10588             DECODE_PRINTF("ILLEGAL OP MOD=01 RH=01 OP=F6\n");
10589             HALT_SYS();
10590             break;
10591         case 2:
10592             DECODE_PRINTF("NOT\tBYTE PTR ");
10593             destoffset = decode_rm01_address(rl);
10594             DECODE_PRINTF("\n");
10595             destval = fetch_data_byte(destoffset);
10596             TRACE_AND_STEP();
10597             destval = not_byte(destval);
10598             store_data_byte(destoffset, destval);
10599             break;
10600         case 3:
10601             DECODE_PRINTF("NEG\tBYTE PTR ");
10602             destoffset = decode_rm01_address(rl);
10603             DECODE_PRINTF("\n");
10604             destval = fetch_data_byte(destoffset);
10605             TRACE_AND_STEP();
10606             destval = neg_byte(destval);
10607             store_data_byte(destoffset, destval);
10608             break;
10609         case 4:
10610             DECODE_PRINTF("MUL\tBYTE PTR ");
10611             destoffset = decode_rm01_address(rl);
10612             DECODE_PRINTF("\n");
10613             destval = fetch_data_byte(destoffset);
10614             TRACE_AND_STEP();
10615             mul_byte(destval);
10616             break;
10617         case 5:
10618             DECODE_PRINTF("IMUL\tBYTE PTR ");
10619             destoffset = decode_rm01_address(rl);
10620             DECODE_PRINTF("\n");
10621             destval = fetch_data_byte(destoffset);
10622             TRACE_AND_STEP();
10623             imul_byte(destval);
10624             break;
10625         case 6:
10626             DECODE_PRINTF("DIV\tBYTE PTR ");
10627             destoffset = decode_rm01_address(rl);
10628             DECODE_PRINTF("\n");
10629             destval = fetch_data_byte(destoffset);
10630             TRACE_AND_STEP();
10631             div_byte(destval);
10632             break;
10633         case 7:
10634             DECODE_PRINTF("IDIV\tBYTE PTR ");
10635             destoffset = decode_rm01_address(rl);
10636             DECODE_PRINTF("\n");
10637             destval = fetch_data_byte(destoffset);
10638             TRACE_AND_STEP();
10639             idiv_byte(destval);
10640             break;
10641         }
10642         break;                  /* end mod==01 */
10643     case 2:                    /* mod=10 */
10644         switch (rh) {
10645         case 0:                /* test byte imm */
10646             DECODE_PRINTF("TEST\tBYTE PTR ");
10647             destoffset = decode_rm10_address(rl);
10648             DECODE_PRINTF(",");
10649             srcval = fetch_byte_imm();
10650             DECODE_PRINTF2("%02x\n", srcval);
10651             destval = fetch_data_byte(destoffset);
10652             TRACE_AND_STEP();
10653             test_byte(destval, srcval);
10654             break;
10655         case 1:
10656             DECODE_PRINTF("ILLEGAL OP MOD=10 RH=01 OP=F6\n");
10657             HALT_SYS();
10658             break;
10659         case 2:
10660             DECODE_PRINTF("NOT\tBYTE PTR ");
10661             destoffset = decode_rm10_address(rl);
10662             DECODE_PRINTF("\n");
10663             destval = fetch_data_byte(destoffset);
10664             TRACE_AND_STEP();
10665             destval = not_byte(destval);
10666             store_data_byte(destoffset, destval);
10667             break;
10668         case 3:
10669             DECODE_PRINTF("NEG\tBYTE PTR ");
10670             destoffset = decode_rm10_address(rl);
10671             DECODE_PRINTF("\n");
10672             destval = fetch_data_byte(destoffset);
10673             TRACE_AND_STEP();
10674             destval = neg_byte(destval);
10675             store_data_byte(destoffset, destval);
10676             break;
10677         case 4:
10678             DECODE_PRINTF("MUL\tBYTE PTR ");
10679             destoffset = decode_rm10_address(rl);
10680             DECODE_PRINTF("\n");
10681             destval = fetch_data_byte(destoffset);
10682             TRACE_AND_STEP();
10683             mul_byte(destval);
10684             break;
10685         case 5:
10686             DECODE_PRINTF("IMUL\tBYTE PTR ");
10687             destoffset = decode_rm10_address(rl);
10688             DECODE_PRINTF("\n");
10689             destval = fetch_data_byte(destoffset);
10690             TRACE_AND_STEP();
10691             imul_byte(destval);
10692             break;
10693         case 6:
10694             DECODE_PRINTF("DIV\tBYTE PTR ");
10695             destoffset = decode_rm10_address(rl);
10696             DECODE_PRINTF("\n");
10697             destval = fetch_data_byte(destoffset);
10698             TRACE_AND_STEP();
10699             div_byte(destval);
10700             break;
10701         case 7:
10702             DECODE_PRINTF("IDIV\tBYTE PTR ");
10703             destoffset = decode_rm10_address(rl);
10704             DECODE_PRINTF("\n");
10705             destval = fetch_data_byte(destoffset);
10706             TRACE_AND_STEP();
10707             idiv_byte(destval);
10708             break;
10709         }
10710         break;                  /* end mod==10 */
10711     case 3:                    /* mod=11 */
10712         switch (rh) {
10713         case 0:                /* test byte imm */
10714             DECODE_PRINTF("TEST\t");
10715             destreg = DECODE_RM_BYTE_REGISTER(rl);
10716             DECODE_PRINTF(",");
10717             srcval = fetch_byte_imm();
10718             DECODE_PRINTF2("%02x\n", srcval);
10719             TRACE_AND_STEP();
10720             test_byte(*destreg, srcval);
10721             break;
10722         case 1:
10723             DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n");
10724             HALT_SYS();
10725             break;
10726         case 2:
10727             DECODE_PRINTF("NOT\t");
10728             destreg = DECODE_RM_BYTE_REGISTER(rl);
10729             DECODE_PRINTF("\n");
10730             TRACE_AND_STEP();
10731             *destreg = not_byte(*destreg);
10732             break;
10733         case 3:
10734             DECODE_PRINTF("NEG\t");
10735             destreg = DECODE_RM_BYTE_REGISTER(rl);
10736             DECODE_PRINTF("\n");
10737             TRACE_AND_STEP();
10738             *destreg = neg_byte(*destreg);
10739             break;
10740         case 4:
10741             DECODE_PRINTF("MUL\t");
10742             destreg = DECODE_RM_BYTE_REGISTER(rl);
10743             DECODE_PRINTF("\n");
10744             TRACE_AND_STEP();
10745             mul_byte(*destreg); /*!!!  */
10746             break;
10747         case 5:
10748             DECODE_PRINTF("IMUL\t");
10749             destreg = DECODE_RM_BYTE_REGISTER(rl);
10750             DECODE_PRINTF("\n");
10751             TRACE_AND_STEP();
10752             imul_byte(*destreg);
10753             break;
10754         case 6:
10755             DECODE_PRINTF("DIV\t");
10756             destreg = DECODE_RM_BYTE_REGISTER(rl);
10757             DECODE_PRINTF("\n");
10758             TRACE_AND_STEP();
10759             div_byte(*destreg);
10760             break;
10761         case 7:
10762             DECODE_PRINTF("IDIV\t");
10763             destreg = DECODE_RM_BYTE_REGISTER(rl);
10764             DECODE_PRINTF("\n");
10765             TRACE_AND_STEP();
10766             idiv_byte(*destreg);
10767             break;
10768         }
10769         break;                  /* end mod==11 */
10770     }
10771     DECODE_CLEAR_SEGOVR();
10772     END_OF_INSTR();
10773 }
10774 
10775 /****************************************************************************
10776 REMARKS:
10777 Handles opcode 0xf7
10778 ****************************************************************************/
10779 static void
x86emuOp_opcF7_word_RM(u8 X86EMU_UNUSED (op1))10780 x86emuOp_opcF7_word_RM(u8 X86EMU_UNUSED(op1))
10781 {
10782     int mod, rl, rh;
10783     uint destoffset;
10784 
10785     /* long, drawn out code follows.  Double switch for a total
10786        of 32 cases.  */
10787     START_OF_INSTR();
10788     FETCH_DECODE_MODRM(mod, rh, rl);
10789     switch (mod) {
10790     case 0:                    /* mod=00 */
10791         switch (rh) {
10792         case 0:                /* test word imm */
10793             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10794                 u32 destval, srcval;
10795 
10796                 DECODE_PRINTF("TEST\tDWORD PTR ");
10797                 destoffset = decode_rm00_address(rl);
10798                 DECODE_PRINTF(",");
10799                 srcval = fetch_long_imm();
10800                 DECODE_PRINTF2("%x\n", srcval);
10801                 destval = fetch_data_long(destoffset);
10802                 TRACE_AND_STEP();
10803                 test_long(destval, srcval);
10804             }
10805             else {
10806                 u16 destval, srcval;
10807 
10808                 DECODE_PRINTF("TEST\tWORD PTR ");
10809                 destoffset = decode_rm00_address(rl);
10810                 DECODE_PRINTF(",");
10811                 srcval = fetch_word_imm();
10812                 DECODE_PRINTF2("%x\n", srcval);
10813                 destval = fetch_data_word(destoffset);
10814                 TRACE_AND_STEP();
10815                 test_word(destval, srcval);
10816             }
10817             break;
10818         case 1:
10819             DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F7\n");
10820             HALT_SYS();
10821             break;
10822         case 2:
10823             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10824                 u32 destval;
10825 
10826                 DECODE_PRINTF("NOT\tDWORD PTR ");
10827                 destoffset = decode_rm00_address(rl);
10828                 DECODE_PRINTF("\n");
10829                 destval = fetch_data_long(destoffset);
10830                 TRACE_AND_STEP();
10831                 destval = not_long(destval);
10832                 store_data_long(destoffset, destval);
10833             }
10834             else {
10835                 u16 destval;
10836 
10837                 DECODE_PRINTF("NOT\tWORD PTR ");
10838                 destoffset = decode_rm00_address(rl);
10839                 DECODE_PRINTF("\n");
10840                 destval = fetch_data_word(destoffset);
10841                 TRACE_AND_STEP();
10842                 destval = not_word(destval);
10843                 store_data_word(destoffset, destval);
10844             }
10845             break;
10846         case 3:
10847             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10848                 u32 destval;
10849 
10850                 DECODE_PRINTF("NEG\tDWORD PTR ");
10851                 destoffset = decode_rm00_address(rl);
10852                 DECODE_PRINTF("\n");
10853                 destval = fetch_data_long(destoffset);
10854                 TRACE_AND_STEP();
10855                 destval = neg_long(destval);
10856                 store_data_long(destoffset, destval);
10857             }
10858             else {
10859                 u16 destval;
10860 
10861                 DECODE_PRINTF("NEG\tWORD PTR ");
10862                 destoffset = decode_rm00_address(rl);
10863                 DECODE_PRINTF("\n");
10864                 destval = fetch_data_word(destoffset);
10865                 TRACE_AND_STEP();
10866                 destval = neg_word(destval);
10867                 store_data_word(destoffset, destval);
10868             }
10869             break;
10870         case 4:
10871             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10872                 u32 destval;
10873 
10874                 DECODE_PRINTF("MUL\tDWORD PTR ");
10875                 destoffset = decode_rm00_address(rl);
10876                 DECODE_PRINTF("\n");
10877                 destval = fetch_data_long(destoffset);
10878                 TRACE_AND_STEP();
10879                 mul_long(destval);
10880             }
10881             else {
10882                 u16 destval;
10883 
10884                 DECODE_PRINTF("MUL\tWORD PTR ");
10885                 destoffset = decode_rm00_address(rl);
10886                 DECODE_PRINTF("\n");
10887                 destval = fetch_data_word(destoffset);
10888                 TRACE_AND_STEP();
10889                 mul_word(destval);
10890             }
10891             break;
10892         case 5:
10893             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10894                 u32 destval;
10895 
10896                 DECODE_PRINTF("IMUL\tDWORD PTR ");
10897                 destoffset = decode_rm00_address(rl);
10898                 DECODE_PRINTF("\n");
10899                 destval = fetch_data_long(destoffset);
10900                 TRACE_AND_STEP();
10901                 imul_long(destval);
10902             }
10903             else {
10904                 u16 destval;
10905 
10906                 DECODE_PRINTF("IMUL\tWORD PTR ");
10907                 destoffset = decode_rm00_address(rl);
10908                 DECODE_PRINTF("\n");
10909                 destval = fetch_data_word(destoffset);
10910                 TRACE_AND_STEP();
10911                 imul_word(destval);
10912             }
10913             break;
10914         case 6:
10915             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10916                 u32 destval;
10917 
10918                 DECODE_PRINTF("DIV\tDWORD PTR ");
10919                 destoffset = decode_rm00_address(rl);
10920                 DECODE_PRINTF("\n");
10921                 destval = fetch_data_long(destoffset);
10922                 TRACE_AND_STEP();
10923                 div_long(destval);
10924             }
10925             else {
10926                 u16 destval;
10927 
10928                 DECODE_PRINTF("DIV\tWORD PTR ");
10929                 destoffset = decode_rm00_address(rl);
10930                 DECODE_PRINTF("\n");
10931                 destval = fetch_data_word(destoffset);
10932                 TRACE_AND_STEP();
10933                 div_word(destval);
10934             }
10935             break;
10936         case 7:
10937             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10938                 u32 destval;
10939 
10940                 DECODE_PRINTF("IDIV\tDWORD PTR ");
10941                 destoffset = decode_rm00_address(rl);
10942                 DECODE_PRINTF("\n");
10943                 destval = fetch_data_long(destoffset);
10944                 TRACE_AND_STEP();
10945                 idiv_long(destval);
10946             }
10947             else {
10948                 u16 destval;
10949 
10950                 DECODE_PRINTF("IDIV\tWORD PTR ");
10951                 destoffset = decode_rm00_address(rl);
10952                 DECODE_PRINTF("\n");
10953                 destval = fetch_data_word(destoffset);
10954                 TRACE_AND_STEP();
10955                 idiv_word(destval);
10956             }
10957             break;
10958         }
10959         break;                  /* end mod==00 */
10960     case 1:                    /* mod=01 */
10961         switch (rh) {
10962         case 0:                /* test word imm */
10963             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10964                 u32 destval, srcval;
10965 
10966                 DECODE_PRINTF("TEST\tDWORD PTR ");
10967                 destoffset = decode_rm01_address(rl);
10968                 DECODE_PRINTF(",");
10969                 srcval = fetch_long_imm();
10970                 DECODE_PRINTF2("%x\n", srcval);
10971                 destval = fetch_data_long(destoffset);
10972                 TRACE_AND_STEP();
10973                 test_long(destval, srcval);
10974             }
10975             else {
10976                 u16 destval, srcval;
10977 
10978                 DECODE_PRINTF("TEST\tWORD PTR ");
10979                 destoffset = decode_rm01_address(rl);
10980                 DECODE_PRINTF(",");
10981                 srcval = fetch_word_imm();
10982                 DECODE_PRINTF2("%x\n", srcval);
10983                 destval = fetch_data_word(destoffset);
10984                 TRACE_AND_STEP();
10985                 test_word(destval, srcval);
10986             }
10987             break;
10988         case 1:
10989             DECODE_PRINTF("ILLEGAL OP MOD=01 RH=01 OP=F6\n");
10990             HALT_SYS();
10991             break;
10992         case 2:
10993             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10994                 u32 destval;
10995 
10996                 DECODE_PRINTF("NOT\tDWORD PTR ");
10997                 destoffset = decode_rm01_address(rl);
10998                 DECODE_PRINTF("\n");
10999                 destval = fetch_data_long(destoffset);
11000                 TRACE_AND_STEP();
11001                 destval = not_long(destval);
11002                 store_data_long(destoffset, destval);
11003             }
11004             else {
11005                 u16 destval;
11006 
11007                 DECODE_PRINTF("NOT\tWORD PTR ");
11008                 destoffset = decode_rm01_address(rl);
11009                 DECODE_PRINTF("\n");
11010                 destval = fetch_data_word(destoffset);
11011                 TRACE_AND_STEP();
11012                 destval = not_word(destval);
11013                 store_data_word(destoffset, destval);
11014             }
11015             break;
11016         case 3:
11017             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11018                 u32 destval;
11019 
11020                 DECODE_PRINTF("NEG\tDWORD PTR ");
11021                 destoffset = decode_rm01_address(rl);
11022                 DECODE_PRINTF("\n");
11023                 destval = fetch_data_long(destoffset);
11024                 TRACE_AND_STEP();
11025                 destval = neg_long(destval);
11026                 store_data_long(destoffset, destval);
11027             }
11028             else {
11029                 u16 destval;
11030 
11031                 DECODE_PRINTF("NEG\tWORD PTR ");
11032                 destoffset = decode_rm01_address(rl);
11033                 DECODE_PRINTF("\n");
11034                 destval = fetch_data_word(destoffset);
11035                 TRACE_AND_STEP();
11036                 destval = neg_word(destval);
11037                 store_data_word(destoffset, destval);
11038             }
11039             break;
11040         case 4:
11041             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11042                 u32 destval;
11043 
11044                 DECODE_PRINTF("MUL\tDWORD PTR ");
11045                 destoffset = decode_rm01_address(rl);
11046                 DECODE_PRINTF("\n");
11047                 destval = fetch_data_long(destoffset);
11048                 TRACE_AND_STEP();
11049                 mul_long(destval);
11050             }
11051             else {
11052                 u16 destval;
11053 
11054                 DECODE_PRINTF("MUL\tWORD PTR ");
11055                 destoffset = decode_rm01_address(rl);
11056                 DECODE_PRINTF("\n");
11057                 destval = fetch_data_word(destoffset);
11058                 TRACE_AND_STEP();
11059                 mul_word(destval);
11060             }
11061             break;
11062         case 5:
11063             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11064                 u32 destval;
11065 
11066                 DECODE_PRINTF("IMUL\tDWORD PTR ");
11067                 destoffset = decode_rm01_address(rl);
11068                 DECODE_PRINTF("\n");
11069                 destval = fetch_data_long(destoffset);
11070                 TRACE_AND_STEP();
11071                 imul_long(destval);
11072             }
11073             else {
11074                 u16 destval;
11075 
11076                 DECODE_PRINTF("IMUL\tWORD PTR ");
11077                 destoffset = decode_rm01_address(rl);
11078                 DECODE_PRINTF("\n");
11079                 destval = fetch_data_word(destoffset);
11080                 TRACE_AND_STEP();
11081                 imul_word(destval);
11082             }
11083             break;
11084         case 6:
11085             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11086                 u32 destval;
11087 
11088                 DECODE_PRINTF("DIV\tDWORD PTR ");
11089                 destoffset = decode_rm01_address(rl);
11090                 DECODE_PRINTF("\n");
11091                 destval = fetch_data_long(destoffset);
11092                 TRACE_AND_STEP();
11093                 div_long(destval);
11094             }
11095             else {
11096                 u16 destval;
11097 
11098                 DECODE_PRINTF("DIV\tWORD PTR ");
11099                 destoffset = decode_rm01_address(rl);
11100                 DECODE_PRINTF("\n");
11101                 destval = fetch_data_word(destoffset);
11102                 TRACE_AND_STEP();
11103                 div_word(destval);
11104             }
11105             break;
11106         case 7:
11107             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11108                 u32 destval;
11109 
11110                 DECODE_PRINTF("IDIV\tDWORD PTR ");
11111                 destoffset = decode_rm01_address(rl);
11112                 DECODE_PRINTF("\n");
11113                 destval = fetch_data_long(destoffset);
11114                 TRACE_AND_STEP();
11115                 idiv_long(destval);
11116             }
11117             else {
11118                 u16 destval;
11119 
11120                 DECODE_PRINTF("IDIV\tWORD PTR ");
11121                 destoffset = decode_rm01_address(rl);
11122                 DECODE_PRINTF("\n");
11123                 destval = fetch_data_word(destoffset);
11124                 TRACE_AND_STEP();
11125                 idiv_word(destval);
11126             }
11127             break;
11128         }
11129         break;                  /* end mod==01 */
11130     case 2:                    /* mod=10 */
11131         switch (rh) {
11132         case 0:                /* test word imm */
11133             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11134                 u32 destval, srcval;
11135 
11136                 DECODE_PRINTF("TEST\tDWORD PTR ");
11137                 destoffset = decode_rm10_address(rl);
11138                 DECODE_PRINTF(",");
11139                 srcval = fetch_long_imm();
11140                 DECODE_PRINTF2("%x\n", srcval);
11141                 destval = fetch_data_long(destoffset);
11142                 TRACE_AND_STEP();
11143                 test_long(destval, srcval);
11144             }
11145             else {
11146                 u16 destval, srcval;
11147 
11148                 DECODE_PRINTF("TEST\tWORD PTR ");
11149                 destoffset = decode_rm10_address(rl);
11150                 DECODE_PRINTF(",");
11151                 srcval = fetch_word_imm();
11152                 DECODE_PRINTF2("%x\n", srcval);
11153                 destval = fetch_data_word(destoffset);
11154                 TRACE_AND_STEP();
11155                 test_word(destval, srcval);
11156             }
11157             break;
11158         case 1:
11159             DECODE_PRINTF("ILLEGAL OP MOD=10 RH=01 OP=F6\n");
11160             HALT_SYS();
11161             break;
11162         case 2:
11163             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11164                 u32 destval;
11165 
11166                 DECODE_PRINTF("NOT\tDWORD PTR ");
11167                 destoffset = decode_rm10_address(rl);
11168                 DECODE_PRINTF("\n");
11169                 destval = fetch_data_long(destoffset);
11170                 TRACE_AND_STEP();
11171                 destval = not_long(destval);
11172                 store_data_long(destoffset, destval);
11173             }
11174             else {
11175                 u16 destval;
11176 
11177                 DECODE_PRINTF("NOT\tWORD PTR ");
11178                 destoffset = decode_rm10_address(rl);
11179                 DECODE_PRINTF("\n");
11180                 destval = fetch_data_word(destoffset);
11181                 TRACE_AND_STEP();
11182                 destval = not_word(destval);
11183                 store_data_word(destoffset, destval);
11184             }
11185             break;
11186         case 3:
11187             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11188                 u32 destval;
11189 
11190                 DECODE_PRINTF("NEG\tDWORD PTR ");
11191                 destoffset = decode_rm10_address(rl);
11192                 DECODE_PRINTF("\n");
11193                 destval = fetch_data_long(destoffset);
11194                 TRACE_AND_STEP();
11195                 destval = neg_long(destval);
11196                 store_data_long(destoffset, destval);
11197             }
11198             else {
11199                 u16 destval;
11200 
11201                 DECODE_PRINTF("NEG\tWORD PTR ");
11202                 destoffset = decode_rm10_address(rl);
11203                 DECODE_PRINTF("\n");
11204                 destval = fetch_data_word(destoffset);
11205                 TRACE_AND_STEP();
11206                 destval = neg_word(destval);
11207                 store_data_word(destoffset, destval);
11208             }
11209             break;
11210         case 4:
11211             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11212                 u32 destval;
11213 
11214                 DECODE_PRINTF("MUL\tDWORD PTR ");
11215                 destoffset = decode_rm10_address(rl);
11216                 DECODE_PRINTF("\n");
11217                 destval = fetch_data_long(destoffset);
11218                 TRACE_AND_STEP();
11219                 mul_long(destval);
11220             }
11221             else {
11222                 u16 destval;
11223 
11224                 DECODE_PRINTF("MUL\tWORD PTR ");
11225                 destoffset = decode_rm10_address(rl);
11226                 DECODE_PRINTF("\n");
11227                 destval = fetch_data_word(destoffset);
11228                 TRACE_AND_STEP();
11229                 mul_word(destval);
11230             }
11231             break;
11232         case 5:
11233             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11234                 u32 destval;
11235 
11236                 DECODE_PRINTF("IMUL\tDWORD PTR ");
11237                 destoffset = decode_rm10_address(rl);
11238                 DECODE_PRINTF("\n");
11239                 destval = fetch_data_long(destoffset);
11240                 TRACE_AND_STEP();
11241                 imul_long(destval);
11242             }
11243             else {
11244                 u16 destval;
11245 
11246                 DECODE_PRINTF("IMUL\tWORD PTR ");
11247                 destoffset = decode_rm10_address(rl);
11248                 DECODE_PRINTF("\n");
11249                 destval = fetch_data_word(destoffset);
11250                 TRACE_AND_STEP();
11251                 imul_word(destval);
11252             }
11253             break;
11254         case 6:
11255             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11256                 u32 destval;
11257 
11258                 DECODE_PRINTF("DIV\tDWORD PTR ");
11259                 destoffset = decode_rm10_address(rl);
11260                 DECODE_PRINTF("\n");
11261                 destval = fetch_data_long(destoffset);
11262                 TRACE_AND_STEP();
11263                 div_long(destval);
11264             }
11265             else {
11266                 u16 destval;
11267 
11268                 DECODE_PRINTF("DIV\tWORD PTR ");
11269                 destoffset = decode_rm10_address(rl);
11270                 DECODE_PRINTF("\n");
11271                 destval = fetch_data_word(destoffset);
11272                 TRACE_AND_STEP();
11273                 div_word(destval);
11274             }
11275             break;
11276         case 7:
11277             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11278                 u32 destval;
11279 
11280                 DECODE_PRINTF("IDIV\tDWORD PTR ");
11281                 destoffset = decode_rm10_address(rl);
11282                 DECODE_PRINTF("\n");
11283                 destval = fetch_data_long(destoffset);
11284                 TRACE_AND_STEP();
11285                 idiv_long(destval);
11286             }
11287             else {
11288                 u16 destval;
11289 
11290                 DECODE_PRINTF("IDIV\tWORD PTR ");
11291                 destoffset = decode_rm10_address(rl);
11292                 DECODE_PRINTF("\n");
11293                 destval = fetch_data_word(destoffset);
11294                 TRACE_AND_STEP();
11295                 idiv_word(destval);
11296             }
11297             break;
11298         }
11299         break;                  /* end mod==10 */
11300     case 3:                    /* mod=11 */
11301         switch (rh) {
11302         case 0:                /* test word imm */
11303             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11304                 u32 *destreg;
11305                 u32 srcval;
11306 
11307                 DECODE_PRINTF("TEST\t");
11308                 destreg = DECODE_RM_LONG_REGISTER(rl);
11309                 DECODE_PRINTF(",");
11310                 srcval = fetch_long_imm();
11311                 DECODE_PRINTF2("%x\n", srcval);
11312                 TRACE_AND_STEP();
11313                 test_long(*destreg, srcval);
11314             }
11315             else {
11316                 u16 *destreg;
11317                 u16 srcval;
11318 
11319                 DECODE_PRINTF("TEST\t");
11320                 destreg = DECODE_RM_WORD_REGISTER(rl);
11321                 DECODE_PRINTF(",");
11322                 srcval = fetch_word_imm();
11323                 DECODE_PRINTF2("%x\n", srcval);
11324                 TRACE_AND_STEP();
11325                 test_word(*destreg, srcval);
11326             }
11327             break;
11328         case 1:
11329             DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n");
11330             HALT_SYS();
11331             break;
11332         case 2:
11333             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11334                 u32 *destreg;
11335 
11336                 DECODE_PRINTF("NOT\t");
11337                 destreg = DECODE_RM_LONG_REGISTER(rl);
11338                 DECODE_PRINTF("\n");
11339                 TRACE_AND_STEP();
11340                 *destreg = not_long(*destreg);
11341             }
11342             else {
11343                 u16 *destreg;
11344 
11345                 DECODE_PRINTF("NOT\t");
11346                 destreg = DECODE_RM_WORD_REGISTER(rl);
11347                 DECODE_PRINTF("\n");
11348                 TRACE_AND_STEP();
11349                 *destreg = not_word(*destreg);
11350             }
11351             break;
11352         case 3:
11353             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11354                 u32 *destreg;
11355 
11356                 DECODE_PRINTF("NEG\t");
11357                 destreg = DECODE_RM_LONG_REGISTER(rl);
11358                 DECODE_PRINTF("\n");
11359                 TRACE_AND_STEP();
11360                 *destreg = neg_long(*destreg);
11361             }
11362             else {
11363                 u16 *destreg;
11364 
11365                 DECODE_PRINTF("NEG\t");
11366                 destreg = DECODE_RM_WORD_REGISTER(rl);
11367                 DECODE_PRINTF("\n");
11368                 TRACE_AND_STEP();
11369                 *destreg = neg_word(*destreg);
11370             }
11371             break;
11372         case 4:
11373             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11374                 u32 *destreg;
11375 
11376                 DECODE_PRINTF("MUL\t");
11377                 destreg = DECODE_RM_LONG_REGISTER(rl);
11378                 DECODE_PRINTF("\n");
11379                 TRACE_AND_STEP();
11380                 mul_long(*destreg);     /*!!!  */
11381             }
11382             else {
11383                 u16 *destreg;
11384 
11385                 DECODE_PRINTF("MUL\t");
11386                 destreg = DECODE_RM_WORD_REGISTER(rl);
11387                 DECODE_PRINTF("\n");
11388                 TRACE_AND_STEP();
11389                 mul_word(*destreg);     /*!!!  */
11390             }
11391             break;
11392         case 5:
11393             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11394                 u32 *destreg;
11395 
11396                 DECODE_PRINTF("IMUL\t");
11397                 destreg = DECODE_RM_LONG_REGISTER(rl);
11398                 DECODE_PRINTF("\n");
11399                 TRACE_AND_STEP();
11400                 imul_long(*destreg);
11401             }
11402             else {
11403                 u16 *destreg;
11404 
11405                 DECODE_PRINTF("IMUL\t");
11406                 destreg = DECODE_RM_WORD_REGISTER(rl);
11407                 DECODE_PRINTF("\n");
11408                 TRACE_AND_STEP();
11409                 imul_word(*destreg);
11410             }
11411             break;
11412         case 6:
11413             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11414                 u32 *destreg;
11415 
11416                 DECODE_PRINTF("DIV\t");
11417                 destreg = DECODE_RM_LONG_REGISTER(rl);
11418                 DECODE_PRINTF("\n");
11419                 TRACE_AND_STEP();
11420                 div_long(*destreg);
11421             }
11422             else {
11423                 u16 *destreg;
11424 
11425                 DECODE_PRINTF("DIV\t");
11426                 destreg = DECODE_RM_WORD_REGISTER(rl);
11427                 DECODE_PRINTF("\n");
11428                 TRACE_AND_STEP();
11429                 div_word(*destreg);
11430             }
11431             break;
11432         case 7:
11433             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11434                 u32 *destreg;
11435 
11436                 DECODE_PRINTF("IDIV\t");
11437                 destreg = DECODE_RM_LONG_REGISTER(rl);
11438                 DECODE_PRINTF("\n");
11439                 TRACE_AND_STEP();
11440                 idiv_long(*destreg);
11441             }
11442             else {
11443                 u16 *destreg;
11444 
11445                 DECODE_PRINTF("IDIV\t");
11446                 destreg = DECODE_RM_WORD_REGISTER(rl);
11447                 DECODE_PRINTF("\n");
11448                 TRACE_AND_STEP();
11449                 idiv_word(*destreg);
11450             }
11451             break;
11452         }
11453         break;                  /* end mod==11 */
11454     }
11455     DECODE_CLEAR_SEGOVR();
11456     END_OF_INSTR();
11457 }
11458 
11459 /****************************************************************************
11460 REMARKS:
11461 Handles opcode 0xf8
11462 ****************************************************************************/
11463 static void
x86emuOp_clc(u8 X86EMU_UNUSED (op1))11464 x86emuOp_clc(u8 X86EMU_UNUSED(op1))
11465 {
11466     /* clear the carry flag. */
11467     START_OF_INSTR();
11468     DECODE_PRINTF("CLC\n");
11469     TRACE_AND_STEP();
11470     CLEAR_FLAG(F_CF);
11471     DECODE_CLEAR_SEGOVR();
11472     END_OF_INSTR();
11473 }
11474 
11475 /****************************************************************************
11476 REMARKS:
11477 Handles opcode 0xf9
11478 ****************************************************************************/
11479 static void
x86emuOp_stc(u8 X86EMU_UNUSED (op1))11480 x86emuOp_stc(u8 X86EMU_UNUSED(op1))
11481 {
11482     /* set the carry flag. */
11483     START_OF_INSTR();
11484     DECODE_PRINTF("STC\n");
11485     TRACE_AND_STEP();
11486     SET_FLAG(F_CF);
11487     DECODE_CLEAR_SEGOVR();
11488     END_OF_INSTR();
11489 }
11490 
11491 /****************************************************************************
11492 REMARKS:
11493 Handles opcode 0xfa
11494 ****************************************************************************/
11495 static void
x86emuOp_cli(u8 X86EMU_UNUSED (op1))11496 x86emuOp_cli(u8 X86EMU_UNUSED(op1))
11497 {
11498     /* clear interrupts. */
11499     START_OF_INSTR();
11500     DECODE_PRINTF("CLI\n");
11501     TRACE_AND_STEP();
11502     CLEAR_FLAG(F_IF);
11503     DECODE_CLEAR_SEGOVR();
11504     END_OF_INSTR();
11505 }
11506 
11507 /****************************************************************************
11508 REMARKS:
11509 Handles opcode 0xfb
11510 ****************************************************************************/
11511 static void
x86emuOp_sti(u8 X86EMU_UNUSED (op1))11512 x86emuOp_sti(u8 X86EMU_UNUSED(op1))
11513 {
11514     /* enable  interrupts. */
11515     START_OF_INSTR();
11516     DECODE_PRINTF("STI\n");
11517     TRACE_AND_STEP();
11518     SET_FLAG(F_IF);
11519     DECODE_CLEAR_SEGOVR();
11520     END_OF_INSTR();
11521 }
11522 
11523 /****************************************************************************
11524 REMARKS:
11525 Handles opcode 0xfc
11526 ****************************************************************************/
11527 static void
x86emuOp_cld(u8 X86EMU_UNUSED (op1))11528 x86emuOp_cld(u8 X86EMU_UNUSED(op1))
11529 {
11530     /* clear interrupts. */
11531     START_OF_INSTR();
11532     DECODE_PRINTF("CLD\n");
11533     TRACE_AND_STEP();
11534     CLEAR_FLAG(F_DF);
11535     DECODE_CLEAR_SEGOVR();
11536     END_OF_INSTR();
11537 }
11538 
11539 /****************************************************************************
11540 REMARKS:
11541 Handles opcode 0xfd
11542 ****************************************************************************/
11543 static void
x86emuOp_std(u8 X86EMU_UNUSED (op1))11544 x86emuOp_std(u8 X86EMU_UNUSED(op1))
11545 {
11546     /* clear interrupts. */
11547     START_OF_INSTR();
11548     DECODE_PRINTF("STD\n");
11549     TRACE_AND_STEP();
11550     SET_FLAG(F_DF);
11551     DECODE_CLEAR_SEGOVR();
11552     END_OF_INSTR();
11553 }
11554 
11555 /****************************************************************************
11556 REMARKS:
11557 Handles opcode 0xfe
11558 ****************************************************************************/
11559 static void
x86emuOp_opcFE_byte_RM(u8 X86EMU_UNUSED (op1))11560 x86emuOp_opcFE_byte_RM(u8 X86EMU_UNUSED(op1))
11561 {
11562     int mod, rh, rl;
11563     u8 destval;
11564     uint destoffset;
11565     u8 *destreg;
11566 
11567     /* Yet another special case instruction. */
11568     START_OF_INSTR();
11569     FETCH_DECODE_MODRM(mod, rh, rl);
11570 #ifdef DEBUG
11571     if (DEBUG_DECODE()) {
11572         /* XXX DECODE_PRINTF may be changed to something more
11573            general, so that it is important to leave the strings
11574            in the same format, even though the result is that the
11575            above test is done twice. */
11576 
11577         switch (rh) {
11578         case 0:
11579             DECODE_PRINTF("INC\t");
11580             break;
11581         case 1:
11582             DECODE_PRINTF("DEC\t");
11583             break;
11584         case 2:
11585         case 3:
11586         case 4:
11587         case 5:
11588         case 6:
11589         case 7:
11590             DECODE_PRINTF2("ILLEGAL OP MAJOR OP 0xFE MINOR OP %x \n", mod);
11591             HALT_SYS();
11592             break;
11593         }
11594     }
11595 #endif
11596     switch (mod) {
11597     case 0:
11598         DECODE_PRINTF("BYTE PTR ");
11599         destoffset = decode_rm00_address(rl);
11600         DECODE_PRINTF("\n");
11601         switch (rh) {
11602         case 0:                /* inc word ptr ... */
11603             destval = fetch_data_byte(destoffset);
11604             TRACE_AND_STEP();
11605             destval = inc_byte(destval);
11606             store_data_byte(destoffset, destval);
11607             break;
11608         case 1:                /* dec word ptr ... */
11609             destval = fetch_data_byte(destoffset);
11610             TRACE_AND_STEP();
11611             destval = dec_byte(destval);
11612             store_data_byte(destoffset, destval);
11613             break;
11614         }
11615         break;
11616     case 1:
11617         DECODE_PRINTF("BYTE PTR ");
11618         destoffset = decode_rm01_address(rl);
11619         DECODE_PRINTF("\n");
11620         switch (rh) {
11621         case 0:
11622             destval = fetch_data_byte(destoffset);
11623             TRACE_AND_STEP();
11624             destval = inc_byte(destval);
11625             store_data_byte(destoffset, destval);
11626             break;
11627         case 1:
11628             destval = fetch_data_byte(destoffset);
11629             TRACE_AND_STEP();
11630             destval = dec_byte(destval);
11631             store_data_byte(destoffset, destval);
11632             break;
11633         }
11634         break;
11635     case 2:
11636         DECODE_PRINTF("BYTE PTR ");
11637         destoffset = decode_rm10_address(rl);
11638         DECODE_PRINTF("\n");
11639         switch (rh) {
11640         case 0:
11641             destval = fetch_data_byte(destoffset);
11642             TRACE_AND_STEP();
11643             destval = inc_byte(destval);
11644             store_data_byte(destoffset, destval);
11645             break;
11646         case 1:
11647             destval = fetch_data_byte(destoffset);
11648             TRACE_AND_STEP();
11649             destval = dec_byte(destval);
11650             store_data_byte(destoffset, destval);
11651             break;
11652         }
11653         break;
11654     case 3:
11655         destreg = DECODE_RM_BYTE_REGISTER(rl);
11656         DECODE_PRINTF("\n");
11657         switch (rh) {
11658         case 0:
11659             TRACE_AND_STEP();
11660             *destreg = inc_byte(*destreg);
11661             break;
11662         case 1:
11663             TRACE_AND_STEP();
11664             *destreg = dec_byte(*destreg);
11665             break;
11666         }
11667         break;
11668     }
11669     DECODE_CLEAR_SEGOVR();
11670     END_OF_INSTR();
11671 }
11672 
11673 /****************************************************************************
11674 REMARKS:
11675 Handles opcode 0xff
11676 ****************************************************************************/
11677 static void
x86emuOp_opcFF_word_RM(u8 X86EMU_UNUSED (op1))11678 x86emuOp_opcFF_word_RM(u8 X86EMU_UNUSED(op1))
11679 {
11680     int mod, rh, rl;
11681     uint destoffset = 0;
11682     u16 *destreg;
11683     u16 destval, destval2;
11684 
11685     /* Yet another special case instruction. */
11686     START_OF_INSTR();
11687     FETCH_DECODE_MODRM(mod, rh, rl);
11688 #ifdef DEBUG
11689     if (DEBUG_DECODE()) {
11690         /* XXX DECODE_PRINTF may be changed to something more
11691            general, so that it is important to leave the strings
11692            in the same format, even though the result is that the
11693            above test is done twice. */
11694 
11695         switch (rh) {
11696         case 0:
11697             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11698                 DECODE_PRINTF("INC\tDWORD PTR ");
11699             }
11700             else {
11701                 DECODE_PRINTF("INC\tWORD PTR ");
11702             }
11703             break;
11704         case 1:
11705             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11706                 DECODE_PRINTF("DEC\tDWORD PTR ");
11707             }
11708             else {
11709                 DECODE_PRINTF("DEC\tWORD PTR ");
11710             }
11711             break;
11712         case 2:
11713             DECODE_PRINTF("CALL\t");
11714             break;
11715         case 3:
11716             DECODE_PRINTF("CALL\tFAR ");
11717             break;
11718         case 4:
11719             DECODE_PRINTF("JMP\t");
11720             break;
11721         case 5:
11722             DECODE_PRINTF("JMP\tFAR ");
11723             break;
11724         case 6:
11725             DECODE_PRINTF("PUSH\t");
11726             break;
11727         case 7:
11728             DECODE_PRINTF("ILLEGAL DECODING OF OPCODE FF\t");
11729             HALT_SYS();
11730             break;
11731         }
11732     }
11733 #endif
11734     switch (mod) {
11735     case 0:
11736         destoffset = decode_rm00_address(rl);
11737         DECODE_PRINTF("\n");
11738         switch (rh) {
11739         case 0:                /* inc word ptr ... */
11740             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11741                 u32 destval32;
11742 
11743                 destval32 = fetch_data_long(destoffset);
11744                 TRACE_AND_STEP();
11745                 destval32 = inc_long(destval32);
11746                 store_data_long(destoffset, destval32);
11747             }
11748             else {
11749                 u16 destval16;
11750 
11751                 destval16 = fetch_data_word(destoffset);
11752                 TRACE_AND_STEP();
11753                 destval16 = inc_word(destval16);
11754                 store_data_word(destoffset, destval16);
11755             }
11756             break;
11757         case 1:                /* dec word ptr ... */
11758             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11759                 u32 destval32;
11760 
11761                 destval32 = fetch_data_long(destoffset);
11762                 TRACE_AND_STEP();
11763                 destval32 = dec_long(destval32);
11764                 store_data_long(destoffset, destval32);
11765             }
11766             else {
11767                 u16 destval16;
11768 
11769                 destval16 = fetch_data_word(destoffset);
11770                 TRACE_AND_STEP();
11771                 destval16 = dec_word(destval16);
11772                 store_data_word(destoffset, destval16);
11773             }
11774             break;
11775         case 2:                /* call word ptr ... */
11776             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11777                 destval = fetch_data_long(destoffset);
11778                 TRACE_AND_STEP();
11779                 push_long(M.x86.R_EIP);
11780                 M.x86.R_EIP = destval;
11781             } else {
11782                 destval = fetch_data_word(destoffset);
11783                 TRACE_AND_STEP();
11784                 push_word(M.x86.R_IP);
11785                 M.x86.R_IP = destval;
11786             }
11787             break;
11788         case 3:                /* call far ptr ... */
11789             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11790                 destval = fetch_data_long(destoffset);
11791                 destval2 = fetch_data_word(destoffset + 4);
11792                 TRACE_AND_STEP();
11793                 push_long(M.x86.R_CS);
11794                 M.x86.R_CS = destval2;
11795                 push_long(M.x86.R_EIP);
11796                 M.x86.R_EIP = destval;
11797             } else {
11798                 destval = fetch_data_word(destoffset);
11799                 destval2 = fetch_data_word(destoffset + 2);
11800                 TRACE_AND_STEP();
11801                 push_word(M.x86.R_CS);
11802                 M.x86.R_CS = destval2;
11803                 push_word(M.x86.R_IP);
11804                 M.x86.R_IP = destval;
11805             }
11806             break;
11807         case 4:                /* jmp word ptr ... */
11808             destval = fetch_data_word(destoffset);
11809             TRACE_AND_STEP();
11810             M.x86.R_IP = destval;
11811             break;
11812         case 5:                /* jmp far ptr ... */
11813             destval = fetch_data_word(destoffset);
11814             destval2 = fetch_data_word(destoffset + 2);
11815             TRACE_AND_STEP();
11816             M.x86.R_IP = destval;
11817             M.x86.R_CS = destval2;
11818             break;
11819         case 6:                /*  push word ptr ... */
11820             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11821                 u32 destval32;
11822 
11823                 destval32 = fetch_data_long(destoffset);
11824                 TRACE_AND_STEP();
11825                 push_long(destval32);
11826             }
11827             else {
11828                 u16 destval16;
11829 
11830                 destval16 = fetch_data_word(destoffset);
11831                 TRACE_AND_STEP();
11832                 push_word(destval16);
11833             }
11834             break;
11835         }
11836         break;
11837     case 1:
11838         destoffset = decode_rm01_address(rl);
11839         DECODE_PRINTF("\n");
11840         switch (rh) {
11841         case 0:
11842             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11843                 u32 destval32;
11844 
11845                 destval32 = fetch_data_long(destoffset);
11846                 TRACE_AND_STEP();
11847                 destval32 = inc_long(destval32);
11848                 store_data_long(destoffset, destval32);
11849             }
11850             else {
11851                 u16 destval16;
11852 
11853                 destval16 = fetch_data_word(destoffset);
11854                 TRACE_AND_STEP();
11855                 destval16 = inc_word(destval16);
11856                 store_data_word(destoffset, destval16);
11857             }
11858             break;
11859         case 1:
11860             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11861                 u32 destval32;
11862 
11863                 destval32 = fetch_data_long(destoffset);
11864                 TRACE_AND_STEP();
11865                 destval32 = dec_long(destval32);
11866                 store_data_long(destoffset, destval32);
11867             }
11868             else {
11869                 u16 destval16;
11870 
11871                 destval16 = fetch_data_word(destoffset);
11872                 TRACE_AND_STEP();
11873                 destval16 = dec_word(destval16);
11874                 store_data_word(destoffset, destval16);
11875             }
11876             break;
11877         case 2:                /* call word ptr ... */
11878             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11879                 destval = fetch_data_long(destoffset);
11880                 TRACE_AND_STEP();
11881                 push_long(M.x86.R_EIP);
11882                 M.x86.R_EIP = destval;
11883             } else {
11884                 destval = fetch_data_word(destoffset);
11885                 TRACE_AND_STEP();
11886                 push_word(M.x86.R_IP);
11887                 M.x86.R_IP = destval;
11888             }
11889             break;
11890         case 3:                /* call far ptr ... */
11891             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11892                 destval = fetch_data_long(destoffset);
11893                 destval2 = fetch_data_word(destoffset + 4);
11894                 TRACE_AND_STEP();
11895                 push_long(M.x86.R_CS);
11896                 M.x86.R_CS = destval2;
11897                 push_long(M.x86.R_EIP);
11898                 M.x86.R_EIP = destval;
11899             } else {
11900                 destval = fetch_data_word(destoffset);
11901                 destval2 = fetch_data_word(destoffset + 2);
11902                 TRACE_AND_STEP();
11903                 push_word(M.x86.R_CS);
11904                 M.x86.R_CS = destval2;
11905                 push_word(M.x86.R_IP);
11906                 M.x86.R_IP = destval;
11907             }
11908             break;
11909         case 4:                /* jmp word ptr ... */
11910             destval = fetch_data_word(destoffset);
11911             TRACE_AND_STEP();
11912             M.x86.R_IP = destval;
11913             break;
11914         case 5:                /* jmp far ptr ... */
11915             destval = fetch_data_word(destoffset);
11916             destval2 = fetch_data_word(destoffset + 2);
11917             TRACE_AND_STEP();
11918             M.x86.R_IP = destval;
11919             M.x86.R_CS = destval2;
11920             break;
11921         case 6:                /*  push word ptr ... */
11922             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11923                 u32 destval32;
11924 
11925                 destval32 = fetch_data_long(destoffset);
11926                 TRACE_AND_STEP();
11927                 push_long(destval32);
11928             }
11929             else {
11930                 u16 destval16;
11931 
11932                 destval16 = fetch_data_word(destoffset);
11933                 TRACE_AND_STEP();
11934                 push_word(destval16);
11935             }
11936             break;
11937         }
11938         break;
11939     case 2:
11940         destoffset = decode_rm10_address(rl);
11941         DECODE_PRINTF("\n");
11942         switch (rh) {
11943         case 0:
11944             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11945                 u32 destval32;
11946 
11947                 destval32 = fetch_data_long(destoffset);
11948                 TRACE_AND_STEP();
11949                 destval32 = inc_long(destval32);
11950                 store_data_long(destoffset, destval32);
11951             }
11952             else {
11953                 u16 destval16;
11954 
11955                 destval16 = fetch_data_word(destoffset);
11956                 TRACE_AND_STEP();
11957                 destval16 = inc_word(destval16);
11958                 store_data_word(destoffset, destval16);
11959             }
11960             break;
11961         case 1:
11962             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11963                 u32 destval32;
11964 
11965                 destval32 = fetch_data_long(destoffset);
11966                 TRACE_AND_STEP();
11967                 destval32 = dec_long(destval32);
11968                 store_data_long(destoffset, destval32);
11969             }
11970             else {
11971                 u16 destval16;
11972 
11973                 destval16 = fetch_data_word(destoffset);
11974                 TRACE_AND_STEP();
11975                 destval16 = dec_word(destval16);
11976                 store_data_word(destoffset, destval16);
11977             }
11978             break;
11979         case 2:                /* call word ptr ... */
11980             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11981                 destval = fetch_data_long(destoffset);
11982                 TRACE_AND_STEP();
11983                 push_long(M.x86.R_EIP);
11984                 M.x86.R_EIP = destval;
11985             } else {
11986                 destval = fetch_data_word(destoffset);
11987                 TRACE_AND_STEP();
11988                 push_word(M.x86.R_IP);
11989                 M.x86.R_IP = destval;
11990             }
11991             break;
11992         case 3:                /* call far ptr ... */
11993             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11994                 destval = fetch_data_long(destoffset);
11995                 destval2 = fetch_data_word(destoffset + 4);
11996                 TRACE_AND_STEP();
11997                 push_long(M.x86.R_CS);
11998                 M.x86.R_CS = destval2;
11999                 push_long(M.x86.R_EIP);
12000                 M.x86.R_EIP = destval;
12001             } else {
12002                 destval = fetch_data_word(destoffset);
12003                 destval2 = fetch_data_word(destoffset + 2);
12004                 TRACE_AND_STEP();
12005                 push_word(M.x86.R_CS);
12006                 M.x86.R_CS = destval2;
12007                 push_word(M.x86.R_IP);
12008                 M.x86.R_IP = destval;
12009             }
12010             break;
12011         case 4:                /* jmp word ptr ... */
12012             destval = fetch_data_word(destoffset);
12013             TRACE_AND_STEP();
12014             M.x86.R_IP = destval;
12015             break;
12016         case 5:                /* jmp far ptr ... */
12017             destval = fetch_data_word(destoffset);
12018             destval2 = fetch_data_word(destoffset + 2);
12019             TRACE_AND_STEP();
12020             M.x86.R_IP = destval;
12021             M.x86.R_CS = destval2;
12022             break;
12023         case 6:                /*  push word ptr ... */
12024             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
12025                 u32 destval32;
12026 
12027                 destval32 = fetch_data_long(destoffset);
12028                 TRACE_AND_STEP();
12029                 push_long(destval32);
12030             }
12031             else {
12032                 u16 destval16;
12033 
12034                 destval16 = fetch_data_word(destoffset);
12035                 TRACE_AND_STEP();
12036                 push_word(destval16);
12037             }
12038             break;
12039         }
12040         break;
12041     case 3:
12042         switch (rh) {
12043         case 0:
12044             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
12045                 u32 *destreg32;
12046 
12047                 destreg32 = DECODE_RM_LONG_REGISTER(rl);
12048                 DECODE_PRINTF("\n");
12049                 TRACE_AND_STEP();
12050                 *destreg32 = inc_long(*destreg32);
12051             }
12052             else {
12053                 u16 *destreg16;
12054 
12055                 destreg16 = DECODE_RM_WORD_REGISTER(rl);
12056                 DECODE_PRINTF("\n");
12057                 TRACE_AND_STEP();
12058                 *destreg16 = inc_word(*destreg16);
12059             }
12060             break;
12061         case 1:
12062             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
12063                 u32 *destreg32;
12064 
12065                 destreg32 = DECODE_RM_LONG_REGISTER(rl);
12066                 DECODE_PRINTF("\n");
12067                 TRACE_AND_STEP();
12068                 *destreg32 = dec_long(*destreg32);
12069             }
12070             else {
12071                 u16 *destreg16;
12072 
12073                 destreg16 = DECODE_RM_WORD_REGISTER(rl);
12074                 DECODE_PRINTF("\n");
12075                 TRACE_AND_STEP();
12076                 *destreg16 = dec_word(*destreg16);
12077             }
12078             break;
12079         case 2:                /* call word ptr ... */
12080             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
12081                 destreg = (u16 *)DECODE_RM_LONG_REGISTER(rl);
12082                 DECODE_PRINTF("\n");
12083                 TRACE_AND_STEP();
12084                 push_long(M.x86.R_EIP);
12085                 M.x86.R_EIP = *destreg;
12086             } else {
12087                 destreg = DECODE_RM_WORD_REGISTER(rl);
12088                 DECODE_PRINTF("\n");
12089                 TRACE_AND_STEP();
12090                 push_word(M.x86.R_IP);
12091                 M.x86.R_IP = *destreg;
12092             }
12093             break;
12094         case 3:                /* jmp far ptr ... */
12095             DECODE_PRINTF("OPERATION UNDEFINED 0XFF \n");
12096             TRACE_AND_STEP();
12097             HALT_SYS();
12098             break;
12099 
12100         case 4:                /* jmp  ... */
12101             destreg = DECODE_RM_WORD_REGISTER(rl);
12102             DECODE_PRINTF("\n");
12103             TRACE_AND_STEP();
12104             M.x86.R_IP = (u16) (*destreg);
12105             break;
12106         case 5:                /* jmp far ptr ... */
12107             DECODE_PRINTF("OPERATION UNDEFINED 0XFF \n");
12108             TRACE_AND_STEP();
12109             HALT_SYS();
12110             break;
12111         case 6:
12112             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
12113                 u32 *destreg32;
12114 
12115                 destreg32 = DECODE_RM_LONG_REGISTER(rl);
12116                 DECODE_PRINTF("\n");
12117                 TRACE_AND_STEP();
12118                 push_long(*destreg32);
12119             }
12120             else {
12121                 u16 *destreg16;
12122 
12123                 destreg16 = DECODE_RM_WORD_REGISTER(rl);
12124                 DECODE_PRINTF("\n");
12125                 TRACE_AND_STEP();
12126                 push_word(*destreg16);
12127             }
12128             break;
12129         }
12130         break;
12131     }
12132     DECODE_CLEAR_SEGOVR();
12133     END_OF_INSTR();
12134 }
12135 
12136 /***************************************************************************
12137  * Single byte operation code table:
12138  **************************************************************************/
12139 void (*x86emu_optab[256]) (u8) = {
12140 /*  0x00 */ x86emuOp_add_byte_RM_R,
12141 /*  0x01 */ x86emuOp_add_word_RM_R,
12142 /*  0x02 */ x86emuOp_add_byte_R_RM,
12143 /*  0x03 */ x86emuOp_add_word_R_RM,
12144 /*  0x04 */ x86emuOp_add_byte_AL_IMM,
12145 /*  0x05 */ x86emuOp_add_word_AX_IMM,
12146 /*  0x06 */ x86emuOp_push_ES,
12147 /*  0x07 */ x86emuOp_pop_ES,
12148 /*  0x08 */ x86emuOp_or_byte_RM_R,
12149 /*  0x09 */ x86emuOp_or_word_RM_R,
12150 /*  0x0a */ x86emuOp_or_byte_R_RM,
12151 /*  0x0b */ x86emuOp_or_word_R_RM,
12152 /*  0x0c */ x86emuOp_or_byte_AL_IMM,
12153 /*  0x0d */ x86emuOp_or_word_AX_IMM,
12154 /*  0x0e */ x86emuOp_push_CS,
12155 /*  0x0f */ x86emuOp_two_byte,
12156 /*  0x10 */ x86emuOp_adc_byte_RM_R,
12157 /*  0x11 */ x86emuOp_adc_word_RM_R,
12158 /*  0x12 */ x86emuOp_adc_byte_R_RM,
12159 /*  0x13 */ x86emuOp_adc_word_R_RM,
12160 /*  0x14 */ x86emuOp_adc_byte_AL_IMM,
12161 /*  0x15 */ x86emuOp_adc_word_AX_IMM,
12162 /*  0x16 */ x86emuOp_push_SS,
12163 /*  0x17 */ x86emuOp_pop_SS,
12164 /*  0x18 */ x86emuOp_sbb_byte_RM_R,
12165 /*  0x19 */ x86emuOp_sbb_word_RM_R,
12166 /*  0x1a */ x86emuOp_sbb_byte_R_RM,
12167 /*  0x1b */ x86emuOp_sbb_word_R_RM,
12168 /*  0x1c */ x86emuOp_sbb_byte_AL_IMM,
12169 /*  0x1d */ x86emuOp_sbb_word_AX_IMM,
12170 /*  0x1e */ x86emuOp_push_DS,
12171 /*  0x1f */ x86emuOp_pop_DS,
12172 /*  0x20 */ x86emuOp_and_byte_RM_R,
12173 /*  0x21 */ x86emuOp_and_word_RM_R,
12174 /*  0x22 */ x86emuOp_and_byte_R_RM,
12175 /*  0x23 */ x86emuOp_and_word_R_RM,
12176 /*  0x24 */ x86emuOp_and_byte_AL_IMM,
12177 /*  0x25 */ x86emuOp_and_word_AX_IMM,
12178 /*  0x26 */ x86emuOp_segovr_ES,
12179 /*  0x27 */ x86emuOp_daa,
12180 /*  0x28 */ x86emuOp_sub_byte_RM_R,
12181 /*  0x29 */ x86emuOp_sub_word_RM_R,
12182 /*  0x2a */ x86emuOp_sub_byte_R_RM,
12183 /*  0x2b */ x86emuOp_sub_word_R_RM,
12184 /*  0x2c */ x86emuOp_sub_byte_AL_IMM,
12185 /*  0x2d */ x86emuOp_sub_word_AX_IMM,
12186 /*  0x2e */ x86emuOp_segovr_CS,
12187 /*  0x2f */ x86emuOp_das,
12188 /*  0x30 */ x86emuOp_xor_byte_RM_R,
12189 /*  0x31 */ x86emuOp_xor_word_RM_R,
12190 /*  0x32 */ x86emuOp_xor_byte_R_RM,
12191 /*  0x33 */ x86emuOp_xor_word_R_RM,
12192 /*  0x34 */ x86emuOp_xor_byte_AL_IMM,
12193 /*  0x35 */ x86emuOp_xor_word_AX_IMM,
12194 /*  0x36 */ x86emuOp_segovr_SS,
12195 /*  0x37 */ x86emuOp_aaa,
12196 /*  0x38 */ x86emuOp_cmp_byte_RM_R,
12197 /*  0x39 */ x86emuOp_cmp_word_RM_R,
12198 /*  0x3a */ x86emuOp_cmp_byte_R_RM,
12199 /*  0x3b */ x86emuOp_cmp_word_R_RM,
12200 /*  0x3c */ x86emuOp_cmp_byte_AL_IMM,
12201 /*  0x3d */ x86emuOp_cmp_word_AX_IMM,
12202 /*  0x3e */ x86emuOp_segovr_DS,
12203 /*  0x3f */ x86emuOp_aas,
12204 /*  0x40 */ x86emuOp_inc_AX,
12205 /*  0x41 */ x86emuOp_inc_CX,
12206 /*  0x42 */ x86emuOp_inc_DX,
12207 /*  0x43 */ x86emuOp_inc_BX,
12208 /*  0x44 */ x86emuOp_inc_SP,
12209 /*  0x45 */ x86emuOp_inc_BP,
12210 /*  0x46 */ x86emuOp_inc_SI,
12211 /*  0x47 */ x86emuOp_inc_DI,
12212 /*  0x48 */ x86emuOp_dec_AX,
12213 /*  0x49 */ x86emuOp_dec_CX,
12214 /*  0x4a */ x86emuOp_dec_DX,
12215 /*  0x4b */ x86emuOp_dec_BX,
12216 /*  0x4c */ x86emuOp_dec_SP,
12217 /*  0x4d */ x86emuOp_dec_BP,
12218 /*  0x4e */ x86emuOp_dec_SI,
12219 /*  0x4f */ x86emuOp_dec_DI,
12220 /*  0x50 */ x86emuOp_push_AX,
12221 /*  0x51 */ x86emuOp_push_CX,
12222 /*  0x52 */ x86emuOp_push_DX,
12223 /*  0x53 */ x86emuOp_push_BX,
12224 /*  0x54 */ x86emuOp_push_SP,
12225 /*  0x55 */ x86emuOp_push_BP,
12226 /*  0x56 */ x86emuOp_push_SI,
12227 /*  0x57 */ x86emuOp_push_DI,
12228 /*  0x58 */ x86emuOp_pop_AX,
12229 /*  0x59 */ x86emuOp_pop_CX,
12230 /*  0x5a */ x86emuOp_pop_DX,
12231 /*  0x5b */ x86emuOp_pop_BX,
12232 /*  0x5c */ x86emuOp_pop_SP,
12233 /*  0x5d */ x86emuOp_pop_BP,
12234 /*  0x5e */ x86emuOp_pop_SI,
12235 /*  0x5f */ x86emuOp_pop_DI,
12236 /*  0x60 */ x86emuOp_push_all,
12237 /*  0x61 */ x86emuOp_pop_all,
12238                                                 /*  0x62 */ x86emuOp_illegal_op,
12239                                                 /* bound */
12240                                                 /*  0x63 */ x86emuOp_illegal_op,
12241                                                 /* arpl */
12242 /*  0x64 */ x86emuOp_segovr_FS,
12243 /*  0x65 */ x86emuOp_segovr_GS,
12244 /*  0x66 */ x86emuOp_prefix_data,
12245 /*  0x67 */ x86emuOp_prefix_addr,
12246 /*  0x68 */ x86emuOp_push_word_IMM,
12247 /*  0x69 */ x86emuOp_imul_word_IMM,
12248 /*  0x6a */ x86emuOp_push_byte_IMM,
12249 /*  0x6b */ x86emuOp_imul_byte_IMM,
12250 /*  0x6c */ x86emuOp_ins_byte,
12251 /*  0x6d */ x86emuOp_ins_word,
12252 /*  0x6e */ x86emuOp_outs_byte,
12253 /*  0x6f */ x86emuOp_outs_word,
12254 /*  0x70 */ x86emuOp_jump_near_O,
12255 /*  0x71 */ x86emuOp_jump_near_NO,
12256 /*  0x72 */ x86emuOp_jump_near_B,
12257 /*  0x73 */ x86emuOp_jump_near_NB,
12258 /*  0x74 */ x86emuOp_jump_near_Z,
12259 /*  0x75 */ x86emuOp_jump_near_NZ,
12260 /*  0x76 */ x86emuOp_jump_near_BE,
12261 /*  0x77 */ x86emuOp_jump_near_NBE,
12262 /*  0x78 */ x86emuOp_jump_near_S,
12263 /*  0x79 */ x86emuOp_jump_near_NS,
12264 /*  0x7a */ x86emuOp_jump_near_P,
12265 /*  0x7b */ x86emuOp_jump_near_NP,
12266 /*  0x7c */ x86emuOp_jump_near_L,
12267 /*  0x7d */ x86emuOp_jump_near_NL,
12268 /*  0x7e */ x86emuOp_jump_near_LE,
12269 /*  0x7f */ x86emuOp_jump_near_NLE,
12270 /*  0x80 */ x86emuOp_opc80_byte_RM_IMM,
12271 /*  0x81 */ x86emuOp_opc81_word_RM_IMM,
12272 /*  0x82 */ x86emuOp_opc82_byte_RM_IMM,
12273 /*  0x83 */ x86emuOp_opc83_word_RM_IMM,
12274 /*  0x84 */ x86emuOp_test_byte_RM_R,
12275 /*  0x85 */ x86emuOp_test_word_RM_R,
12276 /*  0x86 */ x86emuOp_xchg_byte_RM_R,
12277 /*  0x87 */ x86emuOp_xchg_word_RM_R,
12278 /*  0x88 */ x86emuOp_mov_byte_RM_R,
12279 /*  0x89 */ x86emuOp_mov_word_RM_R,
12280 /*  0x8a */ x86emuOp_mov_byte_R_RM,
12281 /*  0x8b */ x86emuOp_mov_word_R_RM,
12282 /*  0x8c */ x86emuOp_mov_word_RM_SR,
12283 /*  0x8d */ x86emuOp_lea_word_R_M,
12284 /*  0x8e */ x86emuOp_mov_word_SR_RM,
12285 /*  0x8f */ x86emuOp_pop_RM,
12286 /*  0x90 */ x86emuOp_nop,
12287 /*  0x91 */ x86emuOp_xchg_word_AX_CX,
12288 /*  0x92 */ x86emuOp_xchg_word_AX_DX,
12289 /*  0x93 */ x86emuOp_xchg_word_AX_BX,
12290 /*  0x94 */ x86emuOp_xchg_word_AX_SP,
12291 /*  0x95 */ x86emuOp_xchg_word_AX_BP,
12292 /*  0x96 */ x86emuOp_xchg_word_AX_SI,
12293 /*  0x97 */ x86emuOp_xchg_word_AX_DI,
12294 /*  0x98 */ x86emuOp_cbw,
12295 /*  0x99 */ x86emuOp_cwd,
12296 /*  0x9a */ x86emuOp_call_far_IMM,
12297 /*  0x9b */ x86emuOp_wait,
12298 /*  0x9c */ x86emuOp_pushf_word,
12299 /*  0x9d */ x86emuOp_popf_word,
12300 /*  0x9e */ x86emuOp_sahf,
12301 /*  0x9f */ x86emuOp_lahf,
12302 /*  0xa0 */ x86emuOp_mov_AL_M_IMM,
12303 /*  0xa1 */ x86emuOp_mov_AX_M_IMM,
12304 /*  0xa2 */ x86emuOp_mov_M_AL_IMM,
12305 /*  0xa3 */ x86emuOp_mov_M_AX_IMM,
12306 /*  0xa4 */ x86emuOp_movs_byte,
12307 /*  0xa5 */ x86emuOp_movs_word,
12308 /*  0xa6 */ x86emuOp_cmps_byte,
12309 /*  0xa7 */ x86emuOp_cmps_word,
12310 /*  0xa8 */ x86emuOp_test_AL_IMM,
12311 /*  0xa9 */ x86emuOp_test_AX_IMM,
12312 /*  0xaa */ x86emuOp_stos_byte,
12313 /*  0xab */ x86emuOp_stos_word,
12314 /*  0xac */ x86emuOp_lods_byte,
12315 /*  0xad */ x86emuOp_lods_word,
12316 /*  0xac */ x86emuOp_scas_byte,
12317 /*  0xad */ x86emuOp_scas_word,
12318 /*  0xb0 */ x86emuOp_mov_byte_AL_IMM,
12319 /*  0xb1 */ x86emuOp_mov_byte_CL_IMM,
12320 /*  0xb2 */ x86emuOp_mov_byte_DL_IMM,
12321 /*  0xb3 */ x86emuOp_mov_byte_BL_IMM,
12322 /*  0xb4 */ x86emuOp_mov_byte_AH_IMM,
12323 /*  0xb5 */ x86emuOp_mov_byte_CH_IMM,
12324 /*  0xb6 */ x86emuOp_mov_byte_DH_IMM,
12325 /*  0xb7 */ x86emuOp_mov_byte_BH_IMM,
12326 /*  0xb8 */ x86emuOp_mov_word_AX_IMM,
12327 /*  0xb9 */ x86emuOp_mov_word_CX_IMM,
12328 /*  0xba */ x86emuOp_mov_word_DX_IMM,
12329 /*  0xbb */ x86emuOp_mov_word_BX_IMM,
12330 /*  0xbc */ x86emuOp_mov_word_SP_IMM,
12331 /*  0xbd */ x86emuOp_mov_word_BP_IMM,
12332 /*  0xbe */ x86emuOp_mov_word_SI_IMM,
12333 /*  0xbf */ x86emuOp_mov_word_DI_IMM,
12334 /*  0xc0 */ x86emuOp_opcC0_byte_RM_MEM,
12335 /*  0xc1 */ x86emuOp_opcC1_word_RM_MEM,
12336 /*  0xc2 */ x86emuOp_ret_near_IMM,
12337 /*  0xc3 */ x86emuOp_ret_near,
12338 /*  0xc4 */ x86emuOp_les_R_IMM,
12339 /*  0xc5 */ x86emuOp_lds_R_IMM,
12340 /*  0xc6 */ x86emuOp_mov_byte_RM_IMM,
12341 /*  0xc7 */ x86emuOp_mov_word_RM_IMM,
12342 /*  0xc8 */ x86emuOp_enter,
12343 /*  0xc9 */ x86emuOp_leave,
12344 /*  0xca */ x86emuOp_ret_far_IMM,
12345 /*  0xcb */ x86emuOp_ret_far,
12346 /*  0xcc */ x86emuOp_int3,
12347 /*  0xcd */ x86emuOp_int_IMM,
12348 /*  0xce */ x86emuOp_into,
12349 /*  0xcf */ x86emuOp_iret,
12350 /*  0xd0 */ x86emuOp_opcD0_byte_RM_1,
12351 /*  0xd1 */ x86emuOp_opcD1_word_RM_1,
12352 /*  0xd2 */ x86emuOp_opcD2_byte_RM_CL,
12353 /*  0xd3 */ x86emuOp_opcD3_word_RM_CL,
12354 /*  0xd4 */ x86emuOp_aam,
12355 /*  0xd5 */ x86emuOp_aad,
12356                                                 /*  0xd6 */ x86emuOp_illegal_op,
12357                                                 /* Undocumented SETALC instruction */
12358 /*  0xd7 */ x86emuOp_xlat,
12359 /*  0xd8 */ x86emuOp_esc_coprocess_d8,
12360 /*  0xd9 */ x86emuOp_esc_coprocess_d9,
12361 /*  0xda */ x86emuOp_esc_coprocess_da,
12362 /*  0xdb */ x86emuOp_esc_coprocess_db,
12363 /*  0xdc */ x86emuOp_esc_coprocess_dc,
12364 /*  0xdd */ x86emuOp_esc_coprocess_dd,
12365 /*  0xde */ x86emuOp_esc_coprocess_de,
12366 /*  0xdf */ x86emuOp_esc_coprocess_df,
12367 /*  0xe0 */ x86emuOp_loopne,
12368 /*  0xe1 */ x86emuOp_loope,
12369 /*  0xe2 */ x86emuOp_loop,
12370 /*  0xe3 */ x86emuOp_jcxz,
12371 /*  0xe4 */ x86emuOp_in_byte_AL_IMM,
12372 /*  0xe5 */ x86emuOp_in_word_AX_IMM,
12373 /*  0xe6 */ x86emuOp_out_byte_IMM_AL,
12374 /*  0xe7 */ x86emuOp_out_word_IMM_AX,
12375 /*  0xe8 */ x86emuOp_call_near_IMM,
12376 /*  0xe9 */ x86emuOp_jump_near_IMM,
12377 /*  0xea */ x86emuOp_jump_far_IMM,
12378 /*  0xeb */ x86emuOp_jump_byte_IMM,
12379 /*  0xec */ x86emuOp_in_byte_AL_DX,
12380 /*  0xed */ x86emuOp_in_word_AX_DX,
12381 /*  0xee */ x86emuOp_out_byte_DX_AL,
12382 /*  0xef */ x86emuOp_out_word_DX_AX,
12383 /*  0xf0 */ x86emuOp_lock,
12384 /*  0xf1 */ x86emuOp_illegal_op,
12385 /*  0xf2 */ x86emuOp_repne,
12386 /*  0xf3 */ x86emuOp_repe,
12387 /*  0xf4 */ x86emuOp_halt,
12388 /*  0xf5 */ x86emuOp_cmc,
12389 /*  0xf6 */ x86emuOp_opcF6_byte_RM,
12390 /*  0xf7 */ x86emuOp_opcF7_word_RM,
12391 /*  0xf8 */ x86emuOp_clc,
12392 /*  0xf9 */ x86emuOp_stc,
12393 /*  0xfa */ x86emuOp_cli,
12394 /*  0xfb */ x86emuOp_sti,
12395 /*  0xfc */ x86emuOp_cld,
12396 /*  0xfd */ x86emuOp_std,
12397 /*  0xfe */ x86emuOp_opcFE_byte_RM,
12398 /*  0xff */ x86emuOp_opcFF_word_RM,
12399 };
12400