xref: /haiku/src/libs/x86emu/ops.c (revision 25a7b01d15612846f332751841da3579db313082)
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     M.x86.R_IP = pop_word();
8953     M.x86.R_SP += imm;
8954     DECODE_CLEAR_SEGOVR();
8955     END_OF_INSTR();
8956 }
8957 
8958 /****************************************************************************
8959 REMARKS:
8960 Handles opcode 0xc3
8961 ****************************************************************************/
8962 static void
x86emuOp_ret_near(u8 X86EMU_UNUSED (op1))8963 x86emuOp_ret_near(u8 X86EMU_UNUSED(op1))
8964 {
8965     START_OF_INSTR();
8966     DECODE_PRINTF("RET\n");
8967     RETURN_TRACE("RET", M.x86.saved_cs, M.x86.saved_ip);
8968     TRACE_AND_STEP();
8969     M.x86.R_IP = pop_word();
8970     DECODE_CLEAR_SEGOVR();
8971     END_OF_INSTR();
8972 }
8973 
8974 /****************************************************************************
8975 REMARKS:
8976 Handles opcode 0xc4
8977 ****************************************************************************/
8978 static void
x86emuOp_les_R_IMM(u8 X86EMU_UNUSED (op1))8979 x86emuOp_les_R_IMM(u8 X86EMU_UNUSED(op1))
8980 {
8981     int mod, rh, rl;
8982     u16 *dstreg;
8983     uint srcoffset;
8984 
8985     START_OF_INSTR();
8986     DECODE_PRINTF("LES\t");
8987     FETCH_DECODE_MODRM(mod, rh, rl);
8988     switch (mod) {
8989     case 0:
8990         dstreg = DECODE_RM_WORD_REGISTER(rh);
8991         DECODE_PRINTF(",");
8992         srcoffset = decode_rm00_address(rl);
8993         DECODE_PRINTF("\n");
8994         TRACE_AND_STEP();
8995         *dstreg = fetch_data_word(srcoffset);
8996         M.x86.R_ES = fetch_data_word(srcoffset + 2);
8997         break;
8998     case 1:
8999         dstreg = DECODE_RM_WORD_REGISTER(rh);
9000         DECODE_PRINTF(",");
9001         srcoffset = decode_rm01_address(rl);
9002         DECODE_PRINTF("\n");
9003         TRACE_AND_STEP();
9004         *dstreg = fetch_data_word(srcoffset);
9005         M.x86.R_ES = fetch_data_word(srcoffset + 2);
9006         break;
9007     case 2:
9008         dstreg = DECODE_RM_WORD_REGISTER(rh);
9009         DECODE_PRINTF(",");
9010         srcoffset = decode_rm10_address(rl);
9011         DECODE_PRINTF("\n");
9012         TRACE_AND_STEP();
9013         *dstreg = fetch_data_word(srcoffset);
9014         M.x86.R_ES = fetch_data_word(srcoffset + 2);
9015         break;
9016     case 3:                    /* register to register */
9017         /* UNDEFINED! */
9018         TRACE_AND_STEP();
9019     }
9020     DECODE_CLEAR_SEGOVR();
9021     END_OF_INSTR();
9022 }
9023 
9024 /****************************************************************************
9025 REMARKS:
9026 Handles opcode 0xc5
9027 ****************************************************************************/
9028 static void
x86emuOp_lds_R_IMM(u8 X86EMU_UNUSED (op1))9029 x86emuOp_lds_R_IMM(u8 X86EMU_UNUSED(op1))
9030 {
9031     int mod, rh, rl;
9032     u16 *dstreg;
9033     uint srcoffset;
9034 
9035     START_OF_INSTR();
9036     DECODE_PRINTF("LDS\t");
9037     FETCH_DECODE_MODRM(mod, rh, rl);
9038     switch (mod) {
9039     case 0:
9040         dstreg = DECODE_RM_WORD_REGISTER(rh);
9041         DECODE_PRINTF(",");
9042         srcoffset = decode_rm00_address(rl);
9043         DECODE_PRINTF("\n");
9044         TRACE_AND_STEP();
9045         *dstreg = fetch_data_word(srcoffset);
9046         M.x86.R_DS = fetch_data_word(srcoffset + 2);
9047         break;
9048     case 1:
9049         dstreg = DECODE_RM_WORD_REGISTER(rh);
9050         DECODE_PRINTF(",");
9051         srcoffset = decode_rm01_address(rl);
9052         DECODE_PRINTF("\n");
9053         TRACE_AND_STEP();
9054         *dstreg = fetch_data_word(srcoffset);
9055         M.x86.R_DS = fetch_data_word(srcoffset + 2);
9056         break;
9057     case 2:
9058         dstreg = DECODE_RM_WORD_REGISTER(rh);
9059         DECODE_PRINTF(",");
9060         srcoffset = decode_rm10_address(rl);
9061         DECODE_PRINTF("\n");
9062         TRACE_AND_STEP();
9063         *dstreg = fetch_data_word(srcoffset);
9064         M.x86.R_DS = fetch_data_word(srcoffset + 2);
9065         break;
9066     case 3:                    /* register to register */
9067         /* UNDEFINED! */
9068         TRACE_AND_STEP();
9069     }
9070     DECODE_CLEAR_SEGOVR();
9071     END_OF_INSTR();
9072 }
9073 
9074 /****************************************************************************
9075 REMARKS:
9076 Handles opcode 0xc6
9077 ****************************************************************************/
9078 static void
x86emuOp_mov_byte_RM_IMM(u8 X86EMU_UNUSED (op1))9079 x86emuOp_mov_byte_RM_IMM(u8 X86EMU_UNUSED(op1))
9080 {
9081     int mod, rl, rh;
9082     u8 *destreg;
9083     uint destoffset;
9084     u8 imm;
9085 
9086     START_OF_INSTR();
9087     DECODE_PRINTF("MOV\t");
9088     FETCH_DECODE_MODRM(mod, rh, rl);
9089     if (rh != 0) {
9090         DECODE_PRINTF("ILLEGAL DECODE OF OPCODE c6\n");
9091         HALT_SYS();
9092     }
9093     switch (mod) {
9094     case 0:
9095         DECODE_PRINTF("BYTE PTR ");
9096         destoffset = decode_rm00_address(rl);
9097         imm = fetch_byte_imm();
9098         DECODE_PRINTF2(",%2x\n", imm);
9099         TRACE_AND_STEP();
9100         store_data_byte(destoffset, imm);
9101         break;
9102     case 1:
9103         DECODE_PRINTF("BYTE PTR ");
9104         destoffset = decode_rm01_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 2:
9111         DECODE_PRINTF("BYTE PTR ");
9112         destoffset = decode_rm10_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 3:                    /* register to register */
9119         destreg = DECODE_RM_BYTE_REGISTER(rl);
9120         imm = fetch_byte_imm();
9121         DECODE_PRINTF2(",%2x\n", imm);
9122         TRACE_AND_STEP();
9123         *destreg = imm;
9124         break;
9125     }
9126     DECODE_CLEAR_SEGOVR();
9127     END_OF_INSTR();
9128 }
9129 
9130 /****************************************************************************
9131 REMARKS:
9132 Handles opcode 0xc7
9133 ****************************************************************************/
9134 static void
x86emuOp_mov_word_RM_IMM(u8 X86EMU_UNUSED (op1))9135 x86emuOp_mov_word_RM_IMM(u8 X86EMU_UNUSED(op1))
9136 {
9137     int mod, rl, rh;
9138     uint destoffset;
9139 
9140     START_OF_INSTR();
9141     DECODE_PRINTF("MOV\t");
9142     FETCH_DECODE_MODRM(mod, rh, rl);
9143     if (rh != 0) {
9144         DECODE_PRINTF("ILLEGAL DECODE OF OPCODE 8F\n");
9145         HALT_SYS();
9146     }
9147     switch (mod) {
9148     case 0:
9149         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9150             u32 imm;
9151 
9152             DECODE_PRINTF("DWORD PTR ");
9153             destoffset = decode_rm00_address(rl);
9154             imm = fetch_long_imm();
9155             DECODE_PRINTF2(",%x\n", imm);
9156             TRACE_AND_STEP();
9157             store_data_long(destoffset, imm);
9158         }
9159         else {
9160             u16 imm;
9161 
9162             DECODE_PRINTF("WORD PTR ");
9163             destoffset = decode_rm00_address(rl);
9164             imm = fetch_word_imm();
9165             DECODE_PRINTF2(",%x\n", imm);
9166             TRACE_AND_STEP();
9167             store_data_word(destoffset, imm);
9168         }
9169         break;
9170     case 1:
9171         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9172             u32 imm;
9173 
9174             DECODE_PRINTF("DWORD PTR ");
9175             destoffset = decode_rm01_address(rl);
9176             imm = fetch_long_imm();
9177             DECODE_PRINTF2(",%x\n", imm);
9178             TRACE_AND_STEP();
9179             store_data_long(destoffset, imm);
9180         }
9181         else {
9182             u16 imm;
9183 
9184             DECODE_PRINTF("WORD PTR ");
9185             destoffset = decode_rm01_address(rl);
9186             imm = fetch_word_imm();
9187             DECODE_PRINTF2(",%x\n", imm);
9188             TRACE_AND_STEP();
9189             store_data_word(destoffset, imm);
9190         }
9191         break;
9192     case 2:
9193         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9194             u32 imm;
9195 
9196             DECODE_PRINTF("DWORD PTR ");
9197             destoffset = decode_rm10_address(rl);
9198             imm = fetch_long_imm();
9199             DECODE_PRINTF2(",%x\n", imm);
9200             TRACE_AND_STEP();
9201             store_data_long(destoffset, imm);
9202         }
9203         else {
9204             u16 imm;
9205 
9206             DECODE_PRINTF("WORD PTR ");
9207             destoffset = decode_rm10_address(rl);
9208             imm = fetch_word_imm();
9209             DECODE_PRINTF2(",%x\n", imm);
9210             TRACE_AND_STEP();
9211             store_data_word(destoffset, imm);
9212         }
9213         break;
9214     case 3:                    /* register to register */
9215         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9216             u32 *destreg;
9217             u32 imm;
9218 
9219             destreg = DECODE_RM_LONG_REGISTER(rl);
9220             imm = fetch_long_imm();
9221             DECODE_PRINTF2(",%x\n", imm);
9222             TRACE_AND_STEP();
9223             *destreg = imm;
9224         }
9225         else {
9226             u16 *destreg;
9227             u16 imm;
9228 
9229             destreg = DECODE_RM_WORD_REGISTER(rl);
9230             imm = fetch_word_imm();
9231             DECODE_PRINTF2(",%x\n", imm);
9232             TRACE_AND_STEP();
9233             *destreg = imm;
9234         }
9235         break;
9236     }
9237     DECODE_CLEAR_SEGOVR();
9238     END_OF_INSTR();
9239 }
9240 
9241 /****************************************************************************
9242 REMARKS:
9243 Handles opcode 0xc8
9244 ****************************************************************************/
9245 static void
x86emuOp_enter(u8 X86EMU_UNUSED (op1))9246 x86emuOp_enter(u8 X86EMU_UNUSED(op1))
9247 {
9248     u16 local, frame_pointer;
9249     u8 nesting;
9250     int i;
9251 
9252     START_OF_INSTR();
9253     local = fetch_word_imm();
9254     nesting = fetch_byte_imm();
9255     DECODE_PRINTF2("ENTER %x\n", local);
9256     DECODE_PRINTF2(",%x\n", nesting);
9257     TRACE_AND_STEP();
9258     push_word(M.x86.R_BP);
9259     frame_pointer = M.x86.R_SP;
9260     if (nesting > 0) {
9261         for (i = 1; i < nesting; i++) {
9262             M.x86.R_BP -= 2;
9263             push_word(fetch_data_word_abs(M.x86.R_SS, M.x86.R_BP));
9264         }
9265         push_word(frame_pointer);
9266     }
9267     M.x86.R_BP = frame_pointer;
9268     M.x86.R_SP = (u16) (M.x86.R_SP - local);
9269     DECODE_CLEAR_SEGOVR();
9270     END_OF_INSTR();
9271 }
9272 
9273 /****************************************************************************
9274 REMARKS:
9275 Handles opcode 0xc9
9276 ****************************************************************************/
9277 static void
x86emuOp_leave(u8 X86EMU_UNUSED (op1))9278 x86emuOp_leave(u8 X86EMU_UNUSED(op1))
9279 {
9280     START_OF_INSTR();
9281     DECODE_PRINTF("LEAVE\n");
9282     TRACE_AND_STEP();
9283     M.x86.R_SP = M.x86.R_BP;
9284     M.x86.R_BP = pop_word();
9285     DECODE_CLEAR_SEGOVR();
9286     END_OF_INSTR();
9287 }
9288 
9289 /****************************************************************************
9290 REMARKS:
9291 Handles opcode 0xca
9292 ****************************************************************************/
9293 static void
x86emuOp_ret_far_IMM(u8 X86EMU_UNUSED (op1))9294 x86emuOp_ret_far_IMM(u8 X86EMU_UNUSED(op1))
9295 {
9296     u16 imm;
9297 
9298     START_OF_INSTR();
9299     DECODE_PRINTF("RETF\t");
9300     imm = fetch_word_imm();
9301     DECODE_PRINTF2("%x\n", imm);
9302     RETURN_TRACE("RETF", M.x86.saved_cs, M.x86.saved_ip);
9303     TRACE_AND_STEP();
9304     M.x86.R_IP = pop_word();
9305     M.x86.R_CS = pop_word();
9306     M.x86.R_SP += imm;
9307     DECODE_CLEAR_SEGOVR();
9308     END_OF_INSTR();
9309 }
9310 
9311 /****************************************************************************
9312 REMARKS:
9313 Handles opcode 0xcb
9314 ****************************************************************************/
9315 static void
x86emuOp_ret_far(u8 X86EMU_UNUSED (op1))9316 x86emuOp_ret_far(u8 X86EMU_UNUSED(op1))
9317 {
9318     START_OF_INSTR();
9319     DECODE_PRINTF("RETF\n");
9320     RETURN_TRACE("RETF", M.x86.saved_cs, M.x86.saved_ip);
9321     TRACE_AND_STEP();
9322     M.x86.R_IP = pop_word();
9323     M.x86.R_CS = pop_word();
9324     DECODE_CLEAR_SEGOVR();
9325     END_OF_INSTR();
9326 }
9327 
9328 /****************************************************************************
9329 REMARKS:
9330 Handles opcode 0xcc
9331 ****************************************************************************/
9332 static void
x86emuOp_int3(u8 X86EMU_UNUSED (op1))9333 x86emuOp_int3(u8 X86EMU_UNUSED(op1))
9334 {
9335     START_OF_INSTR();
9336     DECODE_PRINTF("INT 3\n");
9337     TRACE_AND_STEP();
9338     if (_X86EMU_intrTab[3]) {
9339         (*_X86EMU_intrTab[3]) (3);
9340     }
9341     else {
9342         push_word((u16) M.x86.R_FLG);
9343         CLEAR_FLAG(F_IF);
9344         CLEAR_FLAG(F_TF);
9345         push_word(M.x86.R_CS);
9346         M.x86.R_CS = mem_access_word(3 * 4 + 2);
9347         push_word(M.x86.R_IP);
9348         M.x86.R_IP = mem_access_word(3 * 4);
9349     }
9350     DECODE_CLEAR_SEGOVR();
9351     END_OF_INSTR();
9352 }
9353 
9354 /****************************************************************************
9355 REMARKS:
9356 Handles opcode 0xcd
9357 ****************************************************************************/
9358 static void
x86emuOp_int_IMM(u8 X86EMU_UNUSED (op1))9359 x86emuOp_int_IMM(u8 X86EMU_UNUSED(op1))
9360 {
9361     u8 intnum;
9362 
9363     START_OF_INSTR();
9364     DECODE_PRINTF("INT\t");
9365     intnum = fetch_byte_imm();
9366     DECODE_PRINTF2("%x\n", intnum);
9367     TRACE_AND_STEP();
9368     if (_X86EMU_intrTab[intnum]) {
9369         (*_X86EMU_intrTab[intnum]) (intnum);
9370     }
9371     else {
9372         push_word((u16) M.x86.R_FLG);
9373         CLEAR_FLAG(F_IF);
9374         CLEAR_FLAG(F_TF);
9375         push_word(M.x86.R_CS);
9376         M.x86.R_CS = mem_access_word(intnum * 4 + 2);
9377         push_word(M.x86.R_IP);
9378         M.x86.R_IP = mem_access_word(intnum * 4);
9379     }
9380     DECODE_CLEAR_SEGOVR();
9381     END_OF_INSTR();
9382 }
9383 
9384 /****************************************************************************
9385 REMARKS:
9386 Handles opcode 0xce
9387 ****************************************************************************/
9388 static void
x86emuOp_into(u8 X86EMU_UNUSED (op1))9389 x86emuOp_into(u8 X86EMU_UNUSED(op1))
9390 {
9391     START_OF_INSTR();
9392     DECODE_PRINTF("INTO\n");
9393     TRACE_AND_STEP();
9394     if (ACCESS_FLAG(F_OF)) {
9395         if (_X86EMU_intrTab[4]) {
9396             (*_X86EMU_intrTab[4]) (4);
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(4 * 4 + 2);
9404             push_word(M.x86.R_IP);
9405             M.x86.R_IP = mem_access_word(4 * 4);
9406         }
9407     }
9408     DECODE_CLEAR_SEGOVR();
9409     END_OF_INSTR();
9410 }
9411 
9412 /****************************************************************************
9413 REMARKS:
9414 Handles opcode 0xcf
9415 ****************************************************************************/
9416 static void
x86emuOp_iret(u8 X86EMU_UNUSED (op1))9417 x86emuOp_iret(u8 X86EMU_UNUSED(op1))
9418 {
9419     START_OF_INSTR();
9420     DECODE_PRINTF("IRET\n");
9421 
9422     TRACE_AND_STEP();
9423 
9424     M.x86.R_IP = pop_word();
9425     M.x86.R_CS = pop_word();
9426     M.x86.R_FLG = pop_word();
9427     DECODE_CLEAR_SEGOVR();
9428     END_OF_INSTR();
9429 }
9430 
9431 /****************************************************************************
9432 REMARKS:
9433 Handles opcode 0xd0
9434 ****************************************************************************/
9435 static void
x86emuOp_opcD0_byte_RM_1(u8 X86EMU_UNUSED (op1))9436 x86emuOp_opcD0_byte_RM_1(u8 X86EMU_UNUSED(op1))
9437 {
9438     int mod, rl, rh;
9439     u8 *destreg;
9440     uint destoffset;
9441     u8 destval;
9442 
9443     /*
9444      * Yet another weirdo special case instruction format.  Part of
9445      * the opcode held below in "RH".  Doubly nested case would
9446      * result, except that the decoded instruction
9447      */
9448     START_OF_INSTR();
9449     FETCH_DECODE_MODRM(mod, rh, rl);
9450 #ifdef DEBUG
9451     if (DEBUG_DECODE()) {
9452         /* XXX DECODE_PRINTF may be changed to something more
9453            general, so that it is important to leave the strings
9454            in the same format, even though the result is that the
9455            above test is done twice. */
9456         switch (rh) {
9457         case 0:
9458             DECODE_PRINTF("ROL\t");
9459             break;
9460         case 1:
9461             DECODE_PRINTF("ROR\t");
9462             break;
9463         case 2:
9464             DECODE_PRINTF("RCL\t");
9465             break;
9466         case 3:
9467             DECODE_PRINTF("RCR\t");
9468             break;
9469         case 4:
9470             DECODE_PRINTF("SHL\t");
9471             break;
9472         case 5:
9473             DECODE_PRINTF("SHR\t");
9474             break;
9475         case 6:
9476             DECODE_PRINTF("SAL\t");
9477             break;
9478         case 7:
9479             DECODE_PRINTF("SAR\t");
9480             break;
9481         }
9482     }
9483 #endif
9484     /* know operation, decode the mod byte to find the addressing
9485        mode. */
9486     switch (mod) {
9487     case 0:
9488         DECODE_PRINTF("BYTE PTR ");
9489         destoffset = decode_rm00_address(rl);
9490         DECODE_PRINTF(",1\n");
9491         destval = fetch_data_byte(destoffset);
9492         TRACE_AND_STEP();
9493         destval = (*opcD0_byte_operation[rh]) (destval, 1);
9494         store_data_byte(destoffset, destval);
9495         break;
9496     case 1:
9497         DECODE_PRINTF("BYTE PTR ");
9498         destoffset = decode_rm01_address(rl);
9499         DECODE_PRINTF(",1\n");
9500         destval = fetch_data_byte(destoffset);
9501         TRACE_AND_STEP();
9502         destval = (*opcD0_byte_operation[rh]) (destval, 1);
9503         store_data_byte(destoffset, destval);
9504         break;
9505     case 2:
9506         DECODE_PRINTF("BYTE PTR ");
9507         destoffset = decode_rm10_address(rl);
9508         DECODE_PRINTF(",1\n");
9509         destval = fetch_data_byte(destoffset);
9510         TRACE_AND_STEP();
9511         destval = (*opcD0_byte_operation[rh]) (destval, 1);
9512         store_data_byte(destoffset, destval);
9513         break;
9514     case 3:                    /* register to register */
9515         destreg = DECODE_RM_BYTE_REGISTER(rl);
9516         DECODE_PRINTF(",1\n");
9517         TRACE_AND_STEP();
9518         destval = (*opcD0_byte_operation[rh]) (*destreg, 1);
9519         *destreg = destval;
9520         break;
9521     }
9522     DECODE_CLEAR_SEGOVR();
9523     END_OF_INSTR();
9524 }
9525 
9526 /****************************************************************************
9527 REMARKS:
9528 Handles opcode 0xd1
9529 ****************************************************************************/
9530 static void
x86emuOp_opcD1_word_RM_1(u8 X86EMU_UNUSED (op1))9531 x86emuOp_opcD1_word_RM_1(u8 X86EMU_UNUSED(op1))
9532 {
9533     int mod, rl, rh;
9534     uint destoffset;
9535 
9536     /*
9537      * Yet another weirdo special case instruction format.  Part of
9538      * the opcode held below in "RH".  Doubly nested case would
9539      * result, except that the decoded instruction
9540      */
9541     START_OF_INSTR();
9542     FETCH_DECODE_MODRM(mod, rh, rl);
9543 #ifdef DEBUG
9544     if (DEBUG_DECODE()) {
9545         /* XXX DECODE_PRINTF may be changed to something more
9546            general, so that it is important to leave the strings
9547            in the same format, even though the result is that the
9548            above test is done twice. */
9549         switch (rh) {
9550         case 0:
9551             DECODE_PRINTF("ROL\t");
9552             break;
9553         case 1:
9554             DECODE_PRINTF("ROR\t");
9555             break;
9556         case 2:
9557             DECODE_PRINTF("RCL\t");
9558             break;
9559         case 3:
9560             DECODE_PRINTF("RCR\t");
9561             break;
9562         case 4:
9563             DECODE_PRINTF("SHL\t");
9564             break;
9565         case 5:
9566             DECODE_PRINTF("SHR\t");
9567             break;
9568         case 6:
9569             DECODE_PRINTF("SAL\t");
9570             break;
9571         case 7:
9572             DECODE_PRINTF("SAR\t");
9573             break;
9574         }
9575     }
9576 #endif
9577     /* know operation, decode the mod byte to find the addressing
9578        mode. */
9579     switch (mod) {
9580     case 0:
9581         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9582             u32 destval;
9583 
9584             DECODE_PRINTF("DWORD PTR ");
9585             destoffset = decode_rm00_address(rl);
9586             DECODE_PRINTF(",1\n");
9587             destval = fetch_data_long(destoffset);
9588             TRACE_AND_STEP();
9589             destval = (*opcD1_long_operation[rh]) (destval, 1);
9590             store_data_long(destoffset, destval);
9591         }
9592         else {
9593             u16 destval;
9594 
9595             DECODE_PRINTF("WORD PTR ");
9596             destoffset = decode_rm00_address(rl);
9597             DECODE_PRINTF(",1\n");
9598             destval = fetch_data_word(destoffset);
9599             TRACE_AND_STEP();
9600             destval = (*opcD1_word_operation[rh]) (destval, 1);
9601             store_data_word(destoffset, destval);
9602         }
9603         break;
9604     case 1:
9605         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9606             u32 destval;
9607 
9608             DECODE_PRINTF("DWORD PTR ");
9609             destoffset = decode_rm01_address(rl);
9610             DECODE_PRINTF(",1\n");
9611             destval = fetch_data_long(destoffset);
9612             TRACE_AND_STEP();
9613             destval = (*opcD1_long_operation[rh]) (destval, 1);
9614             store_data_long(destoffset, destval);
9615         }
9616         else {
9617             u16 destval;
9618 
9619             DECODE_PRINTF("WORD PTR ");
9620             destoffset = decode_rm01_address(rl);
9621             DECODE_PRINTF(",1\n");
9622             destval = fetch_data_word(destoffset);
9623             TRACE_AND_STEP();
9624             destval = (*opcD1_word_operation[rh]) (destval, 1);
9625             store_data_word(destoffset, destval);
9626         }
9627         break;
9628     case 2:
9629         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9630             u32 destval;
9631 
9632             DECODE_PRINTF("DWORD PTR ");
9633             destoffset = decode_rm10_address(rl);
9634             DECODE_PRINTF(",1\n");
9635             destval = fetch_data_long(destoffset);
9636             TRACE_AND_STEP();
9637             destval = (*opcD1_long_operation[rh]) (destval, 1);
9638             store_data_long(destoffset, destval);
9639         }
9640         else {
9641             u16 destval;
9642 
9643             DECODE_PRINTF("BYTE PTR ");
9644             destoffset = decode_rm10_address(rl);
9645             DECODE_PRINTF(",1\n");
9646             destval = fetch_data_word(destoffset);
9647             TRACE_AND_STEP();
9648             destval = (*opcD1_word_operation[rh]) (destval, 1);
9649             store_data_word(destoffset, destval);
9650         }
9651         break;
9652     case 3:                    /* register to register */
9653         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9654             u32 destval;
9655             u32 *destreg;
9656 
9657             destreg = DECODE_RM_LONG_REGISTER(rl);
9658             DECODE_PRINTF(",1\n");
9659             TRACE_AND_STEP();
9660             destval = (*opcD1_long_operation[rh]) (*destreg, 1);
9661             *destreg = destval;
9662         }
9663         else {
9664             u16 destval;
9665             u16 *destreg;
9666 
9667             destreg = DECODE_RM_WORD_REGISTER(rl);
9668             DECODE_PRINTF(",1\n");
9669             TRACE_AND_STEP();
9670             destval = (*opcD1_word_operation[rh]) (*destreg, 1);
9671             *destreg = destval;
9672         }
9673         break;
9674     }
9675     DECODE_CLEAR_SEGOVR();
9676     END_OF_INSTR();
9677 }
9678 
9679 /****************************************************************************
9680 REMARKS:
9681 Handles opcode 0xd2
9682 ****************************************************************************/
9683 static void
x86emuOp_opcD2_byte_RM_CL(u8 X86EMU_UNUSED (op1))9684 x86emuOp_opcD2_byte_RM_CL(u8 X86EMU_UNUSED(op1))
9685 {
9686     int mod, rl, rh;
9687     u8 *destreg;
9688     uint destoffset;
9689     u8 destval;
9690     u8 amt;
9691 
9692     /*
9693      * Yet another weirdo special case instruction format.  Part of
9694      * the opcode held below in "RH".  Doubly nested case would
9695      * result, except that the decoded instruction
9696      */
9697     START_OF_INSTR();
9698     FETCH_DECODE_MODRM(mod, rh, rl);
9699 #ifdef DEBUG
9700     if (DEBUG_DECODE()) {
9701         /* XXX DECODE_PRINTF may be changed to something more
9702            general, so that it is important to leave the strings
9703            in the same format, even though the result is that the
9704            above test is done twice. */
9705         switch (rh) {
9706         case 0:
9707             DECODE_PRINTF("ROL\t");
9708             break;
9709         case 1:
9710             DECODE_PRINTF("ROR\t");
9711             break;
9712         case 2:
9713             DECODE_PRINTF("RCL\t");
9714             break;
9715         case 3:
9716             DECODE_PRINTF("RCR\t");
9717             break;
9718         case 4:
9719             DECODE_PRINTF("SHL\t");
9720             break;
9721         case 5:
9722             DECODE_PRINTF("SHR\t");
9723             break;
9724         case 6:
9725             DECODE_PRINTF("SAL\t");
9726             break;
9727         case 7:
9728             DECODE_PRINTF("SAR\t");
9729             break;
9730         }
9731     }
9732 #endif
9733     /* know operation, decode the mod byte to find the addressing
9734        mode. */
9735     amt = M.x86.R_CL;
9736     switch (mod) {
9737     case 0:
9738         DECODE_PRINTF("BYTE PTR ");
9739         destoffset = decode_rm00_address(rl);
9740         DECODE_PRINTF(",CL\n");
9741         destval = fetch_data_byte(destoffset);
9742         TRACE_AND_STEP();
9743         destval = (*opcD0_byte_operation[rh]) (destval, amt);
9744         store_data_byte(destoffset, destval);
9745         break;
9746     case 1:
9747         DECODE_PRINTF("BYTE PTR ");
9748         destoffset = decode_rm01_address(rl);
9749         DECODE_PRINTF(",CL\n");
9750         destval = fetch_data_byte(destoffset);
9751         TRACE_AND_STEP();
9752         destval = (*opcD0_byte_operation[rh]) (destval, amt);
9753         store_data_byte(destoffset, destval);
9754         break;
9755     case 2:
9756         DECODE_PRINTF("BYTE PTR ");
9757         destoffset = decode_rm10_address(rl);
9758         DECODE_PRINTF(",CL\n");
9759         destval = fetch_data_byte(destoffset);
9760         TRACE_AND_STEP();
9761         destval = (*opcD0_byte_operation[rh]) (destval, amt);
9762         store_data_byte(destoffset, destval);
9763         break;
9764     case 3:                    /* register to register */
9765         destreg = DECODE_RM_BYTE_REGISTER(rl);
9766         DECODE_PRINTF(",CL\n");
9767         TRACE_AND_STEP();
9768         destval = (*opcD0_byte_operation[rh]) (*destreg, amt);
9769         *destreg = destval;
9770         break;
9771     }
9772     DECODE_CLEAR_SEGOVR();
9773     END_OF_INSTR();
9774 }
9775 
9776 /****************************************************************************
9777 REMARKS:
9778 Handles opcode 0xd3
9779 ****************************************************************************/
9780 static void
x86emuOp_opcD3_word_RM_CL(u8 X86EMU_UNUSED (op1))9781 x86emuOp_opcD3_word_RM_CL(u8 X86EMU_UNUSED(op1))
9782 {
9783     int mod, rl, rh;
9784     uint destoffset;
9785     u8 amt;
9786 
9787     /*
9788      * Yet another weirdo special case instruction format.  Part of
9789      * the opcode held below in "RH".  Doubly nested case would
9790      * result, except that the decoded instruction
9791      */
9792     START_OF_INSTR();
9793     FETCH_DECODE_MODRM(mod, rh, rl);
9794 #ifdef DEBUG
9795     if (DEBUG_DECODE()) {
9796         /* XXX DECODE_PRINTF may be changed to something more
9797            general, so that it is important to leave the strings
9798            in the same format, even though the result is that the
9799            above test is done twice. */
9800         switch (rh) {
9801         case 0:
9802             DECODE_PRINTF("ROL\t");
9803             break;
9804         case 1:
9805             DECODE_PRINTF("ROR\t");
9806             break;
9807         case 2:
9808             DECODE_PRINTF("RCL\t");
9809             break;
9810         case 3:
9811             DECODE_PRINTF("RCR\t");
9812             break;
9813         case 4:
9814             DECODE_PRINTF("SHL\t");
9815             break;
9816         case 5:
9817             DECODE_PRINTF("SHR\t");
9818             break;
9819         case 6:
9820             DECODE_PRINTF("SAL\t");
9821             break;
9822         case 7:
9823             DECODE_PRINTF("SAR\t");
9824             break;
9825         }
9826     }
9827 #endif
9828     /* know operation, decode the mod byte to find the addressing
9829        mode. */
9830     amt = M.x86.R_CL;
9831     switch (mod) {
9832     case 0:
9833         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9834             u32 destval;
9835 
9836             DECODE_PRINTF("DWORD PTR ");
9837             destoffset = decode_rm00_address(rl);
9838             DECODE_PRINTF(",CL\n");
9839             destval = fetch_data_long(destoffset);
9840             TRACE_AND_STEP();
9841             destval = (*opcD1_long_operation[rh]) (destval, amt);
9842             store_data_long(destoffset, destval);
9843         }
9844         else {
9845             u16 destval;
9846 
9847             DECODE_PRINTF("WORD PTR ");
9848             destoffset = decode_rm00_address(rl);
9849             DECODE_PRINTF(",CL\n");
9850             destval = fetch_data_word(destoffset);
9851             TRACE_AND_STEP();
9852             destval = (*opcD1_word_operation[rh]) (destval, amt);
9853             store_data_word(destoffset, destval);
9854         }
9855         break;
9856     case 1:
9857         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9858             u32 destval;
9859 
9860             DECODE_PRINTF("DWORD PTR ");
9861             destoffset = decode_rm01_address(rl);
9862             DECODE_PRINTF(",CL\n");
9863             destval = fetch_data_long(destoffset);
9864             TRACE_AND_STEP();
9865             destval = (*opcD1_long_operation[rh]) (destval, amt);
9866             store_data_long(destoffset, destval);
9867         }
9868         else {
9869             u16 destval;
9870 
9871             DECODE_PRINTF("WORD PTR ");
9872             destoffset = decode_rm01_address(rl);
9873             DECODE_PRINTF(",CL\n");
9874             destval = fetch_data_word(destoffset);
9875             TRACE_AND_STEP();
9876             destval = (*opcD1_word_operation[rh]) (destval, amt);
9877             store_data_word(destoffset, destval);
9878         }
9879         break;
9880     case 2:
9881         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9882             u32 destval;
9883 
9884             DECODE_PRINTF("DWORD PTR ");
9885             destoffset = decode_rm10_address(rl);
9886             DECODE_PRINTF(",CL\n");
9887             destval = fetch_data_long(destoffset);
9888             TRACE_AND_STEP();
9889             destval = (*opcD1_long_operation[rh]) (destval, amt);
9890             store_data_long(destoffset, destval);
9891         }
9892         else {
9893             u16 destval;
9894 
9895             DECODE_PRINTF("WORD PTR ");
9896             destoffset = decode_rm10_address(rl);
9897             DECODE_PRINTF(",CL\n");
9898             destval = fetch_data_word(destoffset);
9899             TRACE_AND_STEP();
9900             destval = (*opcD1_word_operation[rh]) (destval, amt);
9901             store_data_word(destoffset, destval);
9902         }
9903         break;
9904     case 3:                    /* register to register */
9905         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9906             u32 *destreg;
9907 
9908             destreg = DECODE_RM_LONG_REGISTER(rl);
9909             DECODE_PRINTF(",CL\n");
9910             TRACE_AND_STEP();
9911             *destreg = (*opcD1_long_operation[rh]) (*destreg, amt);
9912         }
9913         else {
9914             u16 *destreg;
9915 
9916             destreg = DECODE_RM_WORD_REGISTER(rl);
9917             DECODE_PRINTF(",CL\n");
9918             TRACE_AND_STEP();
9919             *destreg = (*opcD1_word_operation[rh]) (*destreg, amt);
9920         }
9921         break;
9922     }
9923     DECODE_CLEAR_SEGOVR();
9924     END_OF_INSTR();
9925 }
9926 
9927 /****************************************************************************
9928 REMARKS:
9929 Handles opcode 0xd4
9930 ****************************************************************************/
9931 static void
x86emuOp_aam(u8 X86EMU_UNUSED (op1))9932 x86emuOp_aam(u8 X86EMU_UNUSED(op1))
9933 {
9934     u8 a;
9935 
9936     START_OF_INSTR();
9937     DECODE_PRINTF("AAM\n");
9938     a = fetch_byte_imm();       /* this is a stupid encoding. */
9939     if (a != 10) {
9940         /* fix: add base decoding
9941            aam_word(u8 val, int base a) */
9942         DECODE_PRINTF("ERROR DECODING AAM\n");
9943         TRACE_REGS();
9944         HALT_SYS();
9945     }
9946     TRACE_AND_STEP();
9947     /* note the type change here --- returning AL and AH in AX. */
9948     M.x86.R_AX = aam_word(M.x86.R_AL);
9949     DECODE_CLEAR_SEGOVR();
9950     END_OF_INSTR();
9951 }
9952 
9953 /****************************************************************************
9954 REMARKS:
9955 Handles opcode 0xd5
9956 ****************************************************************************/
9957 static void
x86emuOp_aad(u8 X86EMU_UNUSED (op1))9958 x86emuOp_aad(u8 X86EMU_UNUSED(op1))
9959 {
9960     u8 a;
9961 
9962     START_OF_INSTR();
9963     DECODE_PRINTF("AAD\n");
9964     a = fetch_byte_imm();
9965     if (a != 10) {
9966         /* fix: add base decoding
9967            aad_word(u16 val, int base a) */
9968         DECODE_PRINTF("ERROR DECODING AAM\n");
9969         TRACE_REGS();
9970         HALT_SYS();
9971     }
9972     TRACE_AND_STEP();
9973     M.x86.R_AX = aad_word(M.x86.R_AX);
9974     DECODE_CLEAR_SEGOVR();
9975     END_OF_INSTR();
9976 }
9977 
9978 /* opcode 0xd6 ILLEGAL OPCODE */
9979 
9980 /****************************************************************************
9981 REMARKS:
9982 Handles opcode 0xd7
9983 ****************************************************************************/
9984 static void
x86emuOp_xlat(u8 X86EMU_UNUSED (op1))9985 x86emuOp_xlat(u8 X86EMU_UNUSED(op1))
9986 {
9987     u16 addr;
9988 
9989     START_OF_INSTR();
9990     DECODE_PRINTF("XLAT\n");
9991     TRACE_AND_STEP();
9992     addr = (u16) (M.x86.R_BX + (u8) M.x86.R_AL);
9993     M.x86.R_AL = fetch_data_byte(addr);
9994     DECODE_CLEAR_SEGOVR();
9995     END_OF_INSTR();
9996 }
9997 
9998 /* instuctions  D8 .. DF are in i87_ops.c */
9999 
10000 /****************************************************************************
10001 REMARKS:
10002 Handles opcode 0xe0
10003 ****************************************************************************/
10004 static void
x86emuOp_loopne(u8 X86EMU_UNUSED (op1))10005 x86emuOp_loopne(u8 X86EMU_UNUSED(op1))
10006 {
10007     s16 ip;
10008 
10009     START_OF_INSTR();
10010     DECODE_PRINTF("LOOPNE\t");
10011     ip = (s8) fetch_byte_imm();
10012     ip += (s16) M.x86.R_IP;
10013     DECODE_PRINTF2("%04x\n", ip);
10014     TRACE_AND_STEP();
10015     M.x86.R_CX -= 1;
10016     if (M.x86.R_CX != 0 && !ACCESS_FLAG(F_ZF))  /* CX != 0 and !ZF */
10017         M.x86.R_IP = ip;
10018     DECODE_CLEAR_SEGOVR();
10019     END_OF_INSTR();
10020 }
10021 
10022 /****************************************************************************
10023 REMARKS:
10024 Handles opcode 0xe1
10025 ****************************************************************************/
10026 static void
x86emuOp_loope(u8 X86EMU_UNUSED (op1))10027 x86emuOp_loope(u8 X86EMU_UNUSED(op1))
10028 {
10029     s16 ip;
10030 
10031     START_OF_INSTR();
10032     DECODE_PRINTF("LOOPE\t");
10033     ip = (s8) fetch_byte_imm();
10034     ip += (s16) M.x86.R_IP;
10035     DECODE_PRINTF2("%04x\n", ip);
10036     TRACE_AND_STEP();
10037     M.x86.R_CX -= 1;
10038     if (M.x86.R_CX != 0 && ACCESS_FLAG(F_ZF))   /* CX != 0 and ZF */
10039         M.x86.R_IP = ip;
10040     DECODE_CLEAR_SEGOVR();
10041     END_OF_INSTR();
10042 }
10043 
10044 /****************************************************************************
10045 REMARKS:
10046 Handles opcode 0xe2
10047 ****************************************************************************/
10048 static void
x86emuOp_loop(u8 X86EMU_UNUSED (op1))10049 x86emuOp_loop(u8 X86EMU_UNUSED(op1))
10050 {
10051     s16 ip;
10052 
10053     START_OF_INSTR();
10054     DECODE_PRINTF("LOOP\t");
10055     ip = (s8) fetch_byte_imm();
10056     ip += (s16) M.x86.R_IP;
10057     DECODE_PRINTF2("%04x\n", ip);
10058     TRACE_AND_STEP();
10059     M.x86.R_CX -= 1;
10060     if (M.x86.R_CX != 0)
10061         M.x86.R_IP = ip;
10062     DECODE_CLEAR_SEGOVR();
10063     END_OF_INSTR();
10064 }
10065 
10066 /****************************************************************************
10067 REMARKS:
10068 Handles opcode 0xe3
10069 ****************************************************************************/
10070 static void
x86emuOp_jcxz(u8 X86EMU_UNUSED (op1))10071 x86emuOp_jcxz(u8 X86EMU_UNUSED(op1))
10072 {
10073     u16 target;
10074     s8 offset;
10075 
10076     /* jump to byte offset if overflow flag is set */
10077     START_OF_INSTR();
10078     DECODE_PRINTF("JCXZ\t");
10079     offset = (s8) fetch_byte_imm();
10080     target = (u16) (M.x86.R_IP + offset);
10081     DECODE_PRINTF2("%x\n", target);
10082     TRACE_AND_STEP();
10083     if (M.x86.R_CX == 0)
10084         M.x86.R_IP = target;
10085     DECODE_CLEAR_SEGOVR();
10086     END_OF_INSTR();
10087 }
10088 
10089 /****************************************************************************
10090 REMARKS:
10091 Handles opcode 0xe4
10092 ****************************************************************************/
10093 static void
x86emuOp_in_byte_AL_IMM(u8 X86EMU_UNUSED (op1))10094 x86emuOp_in_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
10095 {
10096     u8 port;
10097 
10098     START_OF_INSTR();
10099     DECODE_PRINTF("IN\t");
10100     port = (u8) fetch_byte_imm();
10101     DECODE_PRINTF2("%x,AL\n", port);
10102     TRACE_AND_STEP();
10103     M.x86.R_AL = (*sys_inb) (port);
10104     DECODE_CLEAR_SEGOVR();
10105     END_OF_INSTR();
10106 }
10107 
10108 /****************************************************************************
10109 REMARKS:
10110 Handles opcode 0xe5
10111 ****************************************************************************/
10112 static void
x86emuOp_in_word_AX_IMM(u8 X86EMU_UNUSED (op1))10113 x86emuOp_in_word_AX_IMM(u8 X86EMU_UNUSED(op1))
10114 {
10115     u8 port;
10116 
10117     START_OF_INSTR();
10118     DECODE_PRINTF("IN\t");
10119     port = (u8) fetch_byte_imm();
10120     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10121         DECODE_PRINTF2("EAX,%x\n", port);
10122     }
10123     else {
10124         DECODE_PRINTF2("AX,%x\n", port);
10125     }
10126     TRACE_AND_STEP();
10127     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10128         M.x86.R_EAX = (*sys_inl) (port);
10129     }
10130     else {
10131         M.x86.R_AX = (*sys_inw) (port);
10132     }
10133     DECODE_CLEAR_SEGOVR();
10134     END_OF_INSTR();
10135 }
10136 
10137 /****************************************************************************
10138 REMARKS:
10139 Handles opcode 0xe6
10140 ****************************************************************************/
10141 static void
x86emuOp_out_byte_IMM_AL(u8 X86EMU_UNUSED (op1))10142 x86emuOp_out_byte_IMM_AL(u8 X86EMU_UNUSED(op1))
10143 {
10144     u8 port;
10145 
10146     START_OF_INSTR();
10147     DECODE_PRINTF("OUT\t");
10148     port = (u8) fetch_byte_imm();
10149     DECODE_PRINTF2("%x,AL\n", port);
10150     TRACE_AND_STEP();
10151     (*sys_outb) (port, M.x86.R_AL);
10152     DECODE_CLEAR_SEGOVR();
10153     END_OF_INSTR();
10154 }
10155 
10156 /****************************************************************************
10157 REMARKS:
10158 Handles opcode 0xe7
10159 ****************************************************************************/
10160 static void
x86emuOp_out_word_IMM_AX(u8 X86EMU_UNUSED (op1))10161 x86emuOp_out_word_IMM_AX(u8 X86EMU_UNUSED(op1))
10162 {
10163     u8 port;
10164 
10165     START_OF_INSTR();
10166     DECODE_PRINTF("OUT\t");
10167     port = (u8) fetch_byte_imm();
10168     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10169         DECODE_PRINTF2("%x,EAX\n", port);
10170     }
10171     else {
10172         DECODE_PRINTF2("%x,AX\n", port);
10173     }
10174     TRACE_AND_STEP();
10175     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10176         (*sys_outl) (port, M.x86.R_EAX);
10177     }
10178     else {
10179         (*sys_outw) (port, M.x86.R_AX);
10180     }
10181     DECODE_CLEAR_SEGOVR();
10182     END_OF_INSTR();
10183 }
10184 
10185 /****************************************************************************
10186 REMARKS:
10187 Handles opcode 0xe8
10188 ****************************************************************************/
10189 static void
x86emuOp_call_near_IMM(u8 X86EMU_UNUSED (op1))10190 x86emuOp_call_near_IMM(u8 X86EMU_UNUSED(op1))
10191 {
10192     s16 ip16 = 0;
10193     s32 ip32 = 0;
10194 
10195     START_OF_INSTR();
10196     DECODE_PRINTF("CALL\t");
10197     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10198         ip32 = (s32) fetch_long_imm();
10199         ip32 += (s16) M.x86.R_IP;       /* CHECK SIGN */
10200         DECODE_PRINTF2("%04x\n", (u16) ip32);
10201         CALL_TRACE(M.x86.saved_cs, M.x86.saved_ip, M.x86.R_CS, ip32, "");
10202     }
10203     else {
10204         ip16 = (s16) fetch_word_imm();
10205         ip16 += (s16) M.x86.R_IP;       /* CHECK SIGN */
10206         DECODE_PRINTF2("%04x\n", (u16) ip16);
10207         CALL_TRACE(M.x86.saved_cs, M.x86.saved_ip, M.x86.R_CS, ip16, "");
10208     }
10209     TRACE_AND_STEP();
10210     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10211         push_long(M.x86.R_EIP);
10212         M.x86.R_EIP = ip32 & 0xffff;
10213     }
10214     else {
10215         push_word(M.x86.R_IP);
10216         M.x86.R_EIP = ip16;
10217     }
10218     DECODE_CLEAR_SEGOVR();
10219     END_OF_INSTR();
10220 }
10221 
10222 /****************************************************************************
10223 REMARKS:
10224 Handles opcode 0xe9
10225 ****************************************************************************/
10226 static void
x86emuOp_jump_near_IMM(u8 X86EMU_UNUSED (op1))10227 x86emuOp_jump_near_IMM(u8 X86EMU_UNUSED(op1))
10228 {
10229     u32 ip;
10230 
10231     START_OF_INSTR();
10232     DECODE_PRINTF("JMP\t");
10233     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10234         ip = (u32) fetch_long_imm();
10235         ip += (u32) M.x86.R_EIP;
10236         DECODE_PRINTF2("%08x\n", (u32) ip);
10237         TRACE_AND_STEP();
10238         M.x86.R_EIP = (u32) ip;
10239     }
10240     else {
10241         ip = (s16) fetch_word_imm();
10242         ip += (s16) M.x86.R_IP;
10243         DECODE_PRINTF2("%04x\n", (u16) ip);
10244         TRACE_AND_STEP();
10245         M.x86.R_IP = (u16) ip;
10246     }
10247     DECODE_CLEAR_SEGOVR();
10248     END_OF_INSTR();
10249 }
10250 
10251 /****************************************************************************
10252 REMARKS:
10253 Handles opcode 0xea
10254 ****************************************************************************/
10255 static void
x86emuOp_jump_far_IMM(u8 X86EMU_UNUSED (op1))10256 x86emuOp_jump_far_IMM(u8 X86EMU_UNUSED(op1))
10257 {
10258     u16 cs;
10259     u32 ip;
10260 
10261     START_OF_INSTR();
10262     DECODE_PRINTF("JMP\tFAR ");
10263     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10264         ip = fetch_long_imm();
10265     }
10266     else {
10267         ip = fetch_word_imm();
10268     }
10269     cs = fetch_word_imm();
10270     DECODE_PRINTF2("%04x:", cs);
10271     DECODE_PRINTF2("%04x\n", ip);
10272     TRACE_AND_STEP();
10273     M.x86.R_EIP = ip & 0xffff;
10274     M.x86.R_CS = cs;
10275     DECODE_CLEAR_SEGOVR();
10276     END_OF_INSTR();
10277 }
10278 
10279 /****************************************************************************
10280 REMARKS:
10281 Handles opcode 0xeb
10282 ****************************************************************************/
10283 static void
x86emuOp_jump_byte_IMM(u8 X86EMU_UNUSED (op1))10284 x86emuOp_jump_byte_IMM(u8 X86EMU_UNUSED(op1))
10285 {
10286     u16 target;
10287     s8 offset;
10288 
10289     START_OF_INSTR();
10290     DECODE_PRINTF("JMP\t");
10291     offset = (s8) fetch_byte_imm();
10292     target = (u16) (M.x86.R_IP + offset);
10293     DECODE_PRINTF2("%x\n", target);
10294     TRACE_AND_STEP();
10295     M.x86.R_IP = target;
10296     DECODE_CLEAR_SEGOVR();
10297     END_OF_INSTR();
10298 }
10299 
10300 /****************************************************************************
10301 REMARKS:
10302 Handles opcode 0xec
10303 ****************************************************************************/
10304 static void
x86emuOp_in_byte_AL_DX(u8 X86EMU_UNUSED (op1))10305 x86emuOp_in_byte_AL_DX(u8 X86EMU_UNUSED(op1))
10306 {
10307     START_OF_INSTR();
10308     DECODE_PRINTF("IN\tAL,DX\n");
10309     TRACE_AND_STEP();
10310     M.x86.R_AL = (*sys_inb) (M.x86.R_DX);
10311     DECODE_CLEAR_SEGOVR();
10312     END_OF_INSTR();
10313 }
10314 
10315 /****************************************************************************
10316 REMARKS:
10317 Handles opcode 0xed
10318 ****************************************************************************/
10319 static void
x86emuOp_in_word_AX_DX(u8 X86EMU_UNUSED (op1))10320 x86emuOp_in_word_AX_DX(u8 X86EMU_UNUSED(op1))
10321 {
10322     START_OF_INSTR();
10323     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10324         DECODE_PRINTF("IN\tEAX,DX\n");
10325     }
10326     else {
10327         DECODE_PRINTF("IN\tAX,DX\n");
10328     }
10329     TRACE_AND_STEP();
10330     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10331         M.x86.R_EAX = (*sys_inl) (M.x86.R_DX);
10332     }
10333     else {
10334         M.x86.R_AX = (*sys_inw) (M.x86.R_DX);
10335     }
10336     DECODE_CLEAR_SEGOVR();
10337     END_OF_INSTR();
10338 }
10339 
10340 /****************************************************************************
10341 REMARKS:
10342 Handles opcode 0xee
10343 ****************************************************************************/
10344 static void
x86emuOp_out_byte_DX_AL(u8 X86EMU_UNUSED (op1))10345 x86emuOp_out_byte_DX_AL(u8 X86EMU_UNUSED(op1))
10346 {
10347     START_OF_INSTR();
10348     DECODE_PRINTF("OUT\tDX,AL\n");
10349     TRACE_AND_STEP();
10350     (*sys_outb) (M.x86.R_DX, M.x86.R_AL);
10351     DECODE_CLEAR_SEGOVR();
10352     END_OF_INSTR();
10353 }
10354 
10355 /****************************************************************************
10356 REMARKS:
10357 Handles opcode 0xef
10358 ****************************************************************************/
10359 static void
x86emuOp_out_word_DX_AX(u8 X86EMU_UNUSED (op1))10360 x86emuOp_out_word_DX_AX(u8 X86EMU_UNUSED(op1))
10361 {
10362     START_OF_INSTR();
10363     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10364         DECODE_PRINTF("OUT\tDX,EAX\n");
10365     }
10366     else {
10367         DECODE_PRINTF("OUT\tDX,AX\n");
10368     }
10369     TRACE_AND_STEP();
10370     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10371         (*sys_outl) (M.x86.R_DX, M.x86.R_EAX);
10372     }
10373     else {
10374         (*sys_outw) (M.x86.R_DX, M.x86.R_AX);
10375     }
10376     DECODE_CLEAR_SEGOVR();
10377     END_OF_INSTR();
10378 }
10379 
10380 /****************************************************************************
10381 REMARKS:
10382 Handles opcode 0xf0
10383 ****************************************************************************/
10384 static void
x86emuOp_lock(u8 X86EMU_UNUSED (op1))10385 x86emuOp_lock(u8 X86EMU_UNUSED(op1))
10386 {
10387     START_OF_INSTR();
10388     DECODE_PRINTF("LOCK:\n");
10389     TRACE_AND_STEP();
10390     DECODE_CLEAR_SEGOVR();
10391     END_OF_INSTR();
10392 }
10393 
10394 /*opcode 0xf1 ILLEGAL OPERATION */
10395 
10396 /****************************************************************************
10397 REMARKS:
10398 Handles opcode 0xf2
10399 ****************************************************************************/
10400 static void
x86emuOp_repne(u8 X86EMU_UNUSED (op1))10401 x86emuOp_repne(u8 X86EMU_UNUSED(op1))
10402 {
10403     START_OF_INSTR();
10404     DECODE_PRINTF("REPNE\n");
10405     TRACE_AND_STEP();
10406     M.x86.mode |= SYSMODE_PREFIX_REPNE;
10407     DECODE_CLEAR_SEGOVR();
10408     END_OF_INSTR();
10409 }
10410 
10411 /****************************************************************************
10412 REMARKS:
10413 Handles opcode 0xf3
10414 ****************************************************************************/
10415 static void
x86emuOp_repe(u8 X86EMU_UNUSED (op1))10416 x86emuOp_repe(u8 X86EMU_UNUSED(op1))
10417 {
10418     START_OF_INSTR();
10419     DECODE_PRINTF("REPE\n");
10420     TRACE_AND_STEP();
10421     M.x86.mode |= SYSMODE_PREFIX_REPE;
10422     DECODE_CLEAR_SEGOVR();
10423     END_OF_INSTR();
10424 }
10425 
10426 /****************************************************************************
10427 REMARKS:
10428 Handles opcode 0xf4
10429 ****************************************************************************/
10430 static void
x86emuOp_halt(u8 X86EMU_UNUSED (op1))10431 x86emuOp_halt(u8 X86EMU_UNUSED(op1))
10432 {
10433     START_OF_INSTR();
10434     DECODE_PRINTF("HALT\n");
10435     TRACE_AND_STEP();
10436     HALT_SYS();
10437     DECODE_CLEAR_SEGOVR();
10438     END_OF_INSTR();
10439 }
10440 
10441 /****************************************************************************
10442 REMARKS:
10443 Handles opcode 0xf5
10444 ****************************************************************************/
10445 static void
x86emuOp_cmc(u8 X86EMU_UNUSED (op1))10446 x86emuOp_cmc(u8 X86EMU_UNUSED(op1))
10447 {
10448     /* complement the carry flag. */
10449     START_OF_INSTR();
10450     DECODE_PRINTF("CMC\n");
10451     TRACE_AND_STEP();
10452     TOGGLE_FLAG(F_CF);
10453     DECODE_CLEAR_SEGOVR();
10454     END_OF_INSTR();
10455 }
10456 
10457 /****************************************************************************
10458 REMARKS:
10459 Handles opcode 0xf6
10460 ****************************************************************************/
10461 static void
x86emuOp_opcF6_byte_RM(u8 X86EMU_UNUSED (op1))10462 x86emuOp_opcF6_byte_RM(u8 X86EMU_UNUSED(op1))
10463 {
10464     int mod, rl, rh;
10465     u8 *destreg;
10466     uint destoffset;
10467     u8 destval, srcval;
10468 
10469     /* long, drawn out code follows.  Double switch for a total
10470        of 32 cases.  */
10471     START_OF_INSTR();
10472     FETCH_DECODE_MODRM(mod, rh, rl);
10473     switch (mod) {
10474     case 0:                    /* mod=00 */
10475         switch (rh) {
10476         case 0:                /* test byte imm */
10477             DECODE_PRINTF("TEST\tBYTE PTR ");
10478             destoffset = decode_rm00_address(rl);
10479             DECODE_PRINTF(",");
10480             srcval = fetch_byte_imm();
10481             DECODE_PRINTF2("%02x\n", srcval);
10482             destval = fetch_data_byte(destoffset);
10483             TRACE_AND_STEP();
10484             test_byte(destval, srcval);
10485             break;
10486         case 1:
10487             DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n");
10488             HALT_SYS();
10489             break;
10490         case 2:
10491             DECODE_PRINTF("NOT\tBYTE PTR ");
10492             destoffset = decode_rm00_address(rl);
10493             DECODE_PRINTF("\n");
10494             destval = fetch_data_byte(destoffset);
10495             TRACE_AND_STEP();
10496             destval = not_byte(destval);
10497             store_data_byte(destoffset, destval);
10498             break;
10499         case 3:
10500             DECODE_PRINTF("NEG\tBYTE PTR ");
10501             destoffset = decode_rm00_address(rl);
10502             DECODE_PRINTF("\n");
10503             destval = fetch_data_byte(destoffset);
10504             TRACE_AND_STEP();
10505             destval = neg_byte(destval);
10506             store_data_byte(destoffset, destval);
10507             break;
10508         case 4:
10509             DECODE_PRINTF("MUL\tBYTE PTR ");
10510             destoffset = decode_rm00_address(rl);
10511             DECODE_PRINTF("\n");
10512             destval = fetch_data_byte(destoffset);
10513             TRACE_AND_STEP();
10514             mul_byte(destval);
10515             break;
10516         case 5:
10517             DECODE_PRINTF("IMUL\tBYTE PTR ");
10518             destoffset = decode_rm00_address(rl);
10519             DECODE_PRINTF("\n");
10520             destval = fetch_data_byte(destoffset);
10521             TRACE_AND_STEP();
10522             imul_byte(destval);
10523             break;
10524         case 6:
10525             DECODE_PRINTF("DIV\tBYTE PTR ");
10526             destoffset = decode_rm00_address(rl);
10527             DECODE_PRINTF("\n");
10528             destval = fetch_data_byte(destoffset);
10529             TRACE_AND_STEP();
10530             div_byte(destval);
10531             break;
10532         case 7:
10533             DECODE_PRINTF("IDIV\tBYTE PTR ");
10534             destoffset = decode_rm00_address(rl);
10535             DECODE_PRINTF("\n");
10536             destval = fetch_data_byte(destoffset);
10537             TRACE_AND_STEP();
10538             idiv_byte(destval);
10539             break;
10540         }
10541         break;                  /* end mod==00 */
10542     case 1:                    /* mod=01 */
10543         switch (rh) {
10544         case 0:                /* test byte imm */
10545             DECODE_PRINTF("TEST\tBYTE PTR ");
10546             destoffset = decode_rm01_address(rl);
10547             DECODE_PRINTF(",");
10548             srcval = fetch_byte_imm();
10549             DECODE_PRINTF2("%02x\n", srcval);
10550             destval = fetch_data_byte(destoffset);
10551             TRACE_AND_STEP();
10552             test_byte(destval, srcval);
10553             break;
10554         case 1:
10555             DECODE_PRINTF("ILLEGAL OP MOD=01 RH=01 OP=F6\n");
10556             HALT_SYS();
10557             break;
10558         case 2:
10559             DECODE_PRINTF("NOT\tBYTE PTR ");
10560             destoffset = decode_rm01_address(rl);
10561             DECODE_PRINTF("\n");
10562             destval = fetch_data_byte(destoffset);
10563             TRACE_AND_STEP();
10564             destval = not_byte(destval);
10565             store_data_byte(destoffset, destval);
10566             break;
10567         case 3:
10568             DECODE_PRINTF("NEG\tBYTE PTR ");
10569             destoffset = decode_rm01_address(rl);
10570             DECODE_PRINTF("\n");
10571             destval = fetch_data_byte(destoffset);
10572             TRACE_AND_STEP();
10573             destval = neg_byte(destval);
10574             store_data_byte(destoffset, destval);
10575             break;
10576         case 4:
10577             DECODE_PRINTF("MUL\tBYTE PTR ");
10578             destoffset = decode_rm01_address(rl);
10579             DECODE_PRINTF("\n");
10580             destval = fetch_data_byte(destoffset);
10581             TRACE_AND_STEP();
10582             mul_byte(destval);
10583             break;
10584         case 5:
10585             DECODE_PRINTF("IMUL\tBYTE PTR ");
10586             destoffset = decode_rm01_address(rl);
10587             DECODE_PRINTF("\n");
10588             destval = fetch_data_byte(destoffset);
10589             TRACE_AND_STEP();
10590             imul_byte(destval);
10591             break;
10592         case 6:
10593             DECODE_PRINTF("DIV\tBYTE PTR ");
10594             destoffset = decode_rm01_address(rl);
10595             DECODE_PRINTF("\n");
10596             destval = fetch_data_byte(destoffset);
10597             TRACE_AND_STEP();
10598             div_byte(destval);
10599             break;
10600         case 7:
10601             DECODE_PRINTF("IDIV\tBYTE PTR ");
10602             destoffset = decode_rm01_address(rl);
10603             DECODE_PRINTF("\n");
10604             destval = fetch_data_byte(destoffset);
10605             TRACE_AND_STEP();
10606             idiv_byte(destval);
10607             break;
10608         }
10609         break;                  /* end mod==01 */
10610     case 2:                    /* mod=10 */
10611         switch (rh) {
10612         case 0:                /* test byte imm */
10613             DECODE_PRINTF("TEST\tBYTE PTR ");
10614             destoffset = decode_rm10_address(rl);
10615             DECODE_PRINTF(",");
10616             srcval = fetch_byte_imm();
10617             DECODE_PRINTF2("%02x\n", srcval);
10618             destval = fetch_data_byte(destoffset);
10619             TRACE_AND_STEP();
10620             test_byte(destval, srcval);
10621             break;
10622         case 1:
10623             DECODE_PRINTF("ILLEGAL OP MOD=10 RH=01 OP=F6\n");
10624             HALT_SYS();
10625             break;
10626         case 2:
10627             DECODE_PRINTF("NOT\tBYTE PTR ");
10628             destoffset = decode_rm10_address(rl);
10629             DECODE_PRINTF("\n");
10630             destval = fetch_data_byte(destoffset);
10631             TRACE_AND_STEP();
10632             destval = not_byte(destval);
10633             store_data_byte(destoffset, destval);
10634             break;
10635         case 3:
10636             DECODE_PRINTF("NEG\tBYTE PTR ");
10637             destoffset = decode_rm10_address(rl);
10638             DECODE_PRINTF("\n");
10639             destval = fetch_data_byte(destoffset);
10640             TRACE_AND_STEP();
10641             destval = neg_byte(destval);
10642             store_data_byte(destoffset, destval);
10643             break;
10644         case 4:
10645             DECODE_PRINTF("MUL\tBYTE PTR ");
10646             destoffset = decode_rm10_address(rl);
10647             DECODE_PRINTF("\n");
10648             destval = fetch_data_byte(destoffset);
10649             TRACE_AND_STEP();
10650             mul_byte(destval);
10651             break;
10652         case 5:
10653             DECODE_PRINTF("IMUL\tBYTE PTR ");
10654             destoffset = decode_rm10_address(rl);
10655             DECODE_PRINTF("\n");
10656             destval = fetch_data_byte(destoffset);
10657             TRACE_AND_STEP();
10658             imul_byte(destval);
10659             break;
10660         case 6:
10661             DECODE_PRINTF("DIV\tBYTE PTR ");
10662             destoffset = decode_rm10_address(rl);
10663             DECODE_PRINTF("\n");
10664             destval = fetch_data_byte(destoffset);
10665             TRACE_AND_STEP();
10666             div_byte(destval);
10667             break;
10668         case 7:
10669             DECODE_PRINTF("IDIV\tBYTE PTR ");
10670             destoffset = decode_rm10_address(rl);
10671             DECODE_PRINTF("\n");
10672             destval = fetch_data_byte(destoffset);
10673             TRACE_AND_STEP();
10674             idiv_byte(destval);
10675             break;
10676         }
10677         break;                  /* end mod==10 */
10678     case 3:                    /* mod=11 */
10679         switch (rh) {
10680         case 0:                /* test byte imm */
10681             DECODE_PRINTF("TEST\t");
10682             destreg = DECODE_RM_BYTE_REGISTER(rl);
10683             DECODE_PRINTF(",");
10684             srcval = fetch_byte_imm();
10685             DECODE_PRINTF2("%02x\n", srcval);
10686             TRACE_AND_STEP();
10687             test_byte(*destreg, srcval);
10688             break;
10689         case 1:
10690             DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n");
10691             HALT_SYS();
10692             break;
10693         case 2:
10694             DECODE_PRINTF("NOT\t");
10695             destreg = DECODE_RM_BYTE_REGISTER(rl);
10696             DECODE_PRINTF("\n");
10697             TRACE_AND_STEP();
10698             *destreg = not_byte(*destreg);
10699             break;
10700         case 3:
10701             DECODE_PRINTF("NEG\t");
10702             destreg = DECODE_RM_BYTE_REGISTER(rl);
10703             DECODE_PRINTF("\n");
10704             TRACE_AND_STEP();
10705             *destreg = neg_byte(*destreg);
10706             break;
10707         case 4:
10708             DECODE_PRINTF("MUL\t");
10709             destreg = DECODE_RM_BYTE_REGISTER(rl);
10710             DECODE_PRINTF("\n");
10711             TRACE_AND_STEP();
10712             mul_byte(*destreg); /*!!!  */
10713             break;
10714         case 5:
10715             DECODE_PRINTF("IMUL\t");
10716             destreg = DECODE_RM_BYTE_REGISTER(rl);
10717             DECODE_PRINTF("\n");
10718             TRACE_AND_STEP();
10719             imul_byte(*destreg);
10720             break;
10721         case 6:
10722             DECODE_PRINTF("DIV\t");
10723             destreg = DECODE_RM_BYTE_REGISTER(rl);
10724             DECODE_PRINTF("\n");
10725             TRACE_AND_STEP();
10726             div_byte(*destreg);
10727             break;
10728         case 7:
10729             DECODE_PRINTF("IDIV\t");
10730             destreg = DECODE_RM_BYTE_REGISTER(rl);
10731             DECODE_PRINTF("\n");
10732             TRACE_AND_STEP();
10733             idiv_byte(*destreg);
10734             break;
10735         }
10736         break;                  /* end mod==11 */
10737     }
10738     DECODE_CLEAR_SEGOVR();
10739     END_OF_INSTR();
10740 }
10741 
10742 /****************************************************************************
10743 REMARKS:
10744 Handles opcode 0xf7
10745 ****************************************************************************/
10746 static void
x86emuOp_opcF7_word_RM(u8 X86EMU_UNUSED (op1))10747 x86emuOp_opcF7_word_RM(u8 X86EMU_UNUSED(op1))
10748 {
10749     int mod, rl, rh;
10750     uint destoffset;
10751 
10752     /* long, drawn out code follows.  Double switch for a total
10753        of 32 cases.  */
10754     START_OF_INSTR();
10755     FETCH_DECODE_MODRM(mod, rh, rl);
10756     switch (mod) {
10757     case 0:                    /* mod=00 */
10758         switch (rh) {
10759         case 0:                /* test word imm */
10760             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10761                 u32 destval, srcval;
10762 
10763                 DECODE_PRINTF("TEST\tDWORD PTR ");
10764                 destoffset = decode_rm00_address(rl);
10765                 DECODE_PRINTF(",");
10766                 srcval = fetch_long_imm();
10767                 DECODE_PRINTF2("%x\n", srcval);
10768                 destval = fetch_data_long(destoffset);
10769                 TRACE_AND_STEP();
10770                 test_long(destval, srcval);
10771             }
10772             else {
10773                 u16 destval, srcval;
10774 
10775                 DECODE_PRINTF("TEST\tWORD PTR ");
10776                 destoffset = decode_rm00_address(rl);
10777                 DECODE_PRINTF(",");
10778                 srcval = fetch_word_imm();
10779                 DECODE_PRINTF2("%x\n", srcval);
10780                 destval = fetch_data_word(destoffset);
10781                 TRACE_AND_STEP();
10782                 test_word(destval, srcval);
10783             }
10784             break;
10785         case 1:
10786             DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F7\n");
10787             HALT_SYS();
10788             break;
10789         case 2:
10790             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10791                 u32 destval;
10792 
10793                 DECODE_PRINTF("NOT\tDWORD PTR ");
10794                 destoffset = decode_rm00_address(rl);
10795                 DECODE_PRINTF("\n");
10796                 destval = fetch_data_long(destoffset);
10797                 TRACE_AND_STEP();
10798                 destval = not_long(destval);
10799                 store_data_long(destoffset, destval);
10800             }
10801             else {
10802                 u16 destval;
10803 
10804                 DECODE_PRINTF("NOT\tWORD PTR ");
10805                 destoffset = decode_rm00_address(rl);
10806                 DECODE_PRINTF("\n");
10807                 destval = fetch_data_word(destoffset);
10808                 TRACE_AND_STEP();
10809                 destval = not_word(destval);
10810                 store_data_word(destoffset, destval);
10811             }
10812             break;
10813         case 3:
10814             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10815                 u32 destval;
10816 
10817                 DECODE_PRINTF("NEG\tDWORD PTR ");
10818                 destoffset = decode_rm00_address(rl);
10819                 DECODE_PRINTF("\n");
10820                 destval = fetch_data_long(destoffset);
10821                 TRACE_AND_STEP();
10822                 destval = neg_long(destval);
10823                 store_data_long(destoffset, destval);
10824             }
10825             else {
10826                 u16 destval;
10827 
10828                 DECODE_PRINTF("NEG\tWORD PTR ");
10829                 destoffset = decode_rm00_address(rl);
10830                 DECODE_PRINTF("\n");
10831                 destval = fetch_data_word(destoffset);
10832                 TRACE_AND_STEP();
10833                 destval = neg_word(destval);
10834                 store_data_word(destoffset, destval);
10835             }
10836             break;
10837         case 4:
10838             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10839                 u32 destval;
10840 
10841                 DECODE_PRINTF("MUL\tDWORD PTR ");
10842                 destoffset = decode_rm00_address(rl);
10843                 DECODE_PRINTF("\n");
10844                 destval = fetch_data_long(destoffset);
10845                 TRACE_AND_STEP();
10846                 mul_long(destval);
10847             }
10848             else {
10849                 u16 destval;
10850 
10851                 DECODE_PRINTF("MUL\tWORD PTR ");
10852                 destoffset = decode_rm00_address(rl);
10853                 DECODE_PRINTF("\n");
10854                 destval = fetch_data_word(destoffset);
10855                 TRACE_AND_STEP();
10856                 mul_word(destval);
10857             }
10858             break;
10859         case 5:
10860             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10861                 u32 destval;
10862 
10863                 DECODE_PRINTF("IMUL\tDWORD PTR ");
10864                 destoffset = decode_rm00_address(rl);
10865                 DECODE_PRINTF("\n");
10866                 destval = fetch_data_long(destoffset);
10867                 TRACE_AND_STEP();
10868                 imul_long(destval);
10869             }
10870             else {
10871                 u16 destval;
10872 
10873                 DECODE_PRINTF("IMUL\tWORD PTR ");
10874                 destoffset = decode_rm00_address(rl);
10875                 DECODE_PRINTF("\n");
10876                 destval = fetch_data_word(destoffset);
10877                 TRACE_AND_STEP();
10878                 imul_word(destval);
10879             }
10880             break;
10881         case 6:
10882             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10883                 u32 destval;
10884 
10885                 DECODE_PRINTF("DIV\tDWORD PTR ");
10886                 destoffset = decode_rm00_address(rl);
10887                 DECODE_PRINTF("\n");
10888                 destval = fetch_data_long(destoffset);
10889                 TRACE_AND_STEP();
10890                 div_long(destval);
10891             }
10892             else {
10893                 u16 destval;
10894 
10895                 DECODE_PRINTF("DIV\tWORD PTR ");
10896                 destoffset = decode_rm00_address(rl);
10897                 DECODE_PRINTF("\n");
10898                 destval = fetch_data_word(destoffset);
10899                 TRACE_AND_STEP();
10900                 div_word(destval);
10901             }
10902             break;
10903         case 7:
10904             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10905                 u32 destval;
10906 
10907                 DECODE_PRINTF("IDIV\tDWORD PTR ");
10908                 destoffset = decode_rm00_address(rl);
10909                 DECODE_PRINTF("\n");
10910                 destval = fetch_data_long(destoffset);
10911                 TRACE_AND_STEP();
10912                 idiv_long(destval);
10913             }
10914             else {
10915                 u16 destval;
10916 
10917                 DECODE_PRINTF("IDIV\tWORD PTR ");
10918                 destoffset = decode_rm00_address(rl);
10919                 DECODE_PRINTF("\n");
10920                 destval = fetch_data_word(destoffset);
10921                 TRACE_AND_STEP();
10922                 idiv_word(destval);
10923             }
10924             break;
10925         }
10926         break;                  /* end mod==00 */
10927     case 1:                    /* mod=01 */
10928         switch (rh) {
10929         case 0:                /* test word imm */
10930             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10931                 u32 destval, srcval;
10932 
10933                 DECODE_PRINTF("TEST\tDWORD PTR ");
10934                 destoffset = decode_rm01_address(rl);
10935                 DECODE_PRINTF(",");
10936                 srcval = fetch_long_imm();
10937                 DECODE_PRINTF2("%x\n", srcval);
10938                 destval = fetch_data_long(destoffset);
10939                 TRACE_AND_STEP();
10940                 test_long(destval, srcval);
10941             }
10942             else {
10943                 u16 destval, srcval;
10944 
10945                 DECODE_PRINTF("TEST\tWORD PTR ");
10946                 destoffset = decode_rm01_address(rl);
10947                 DECODE_PRINTF(",");
10948                 srcval = fetch_word_imm();
10949                 DECODE_PRINTF2("%x\n", srcval);
10950                 destval = fetch_data_word(destoffset);
10951                 TRACE_AND_STEP();
10952                 test_word(destval, srcval);
10953             }
10954             break;
10955         case 1:
10956             DECODE_PRINTF("ILLEGAL OP MOD=01 RH=01 OP=F6\n");
10957             HALT_SYS();
10958             break;
10959         case 2:
10960             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10961                 u32 destval;
10962 
10963                 DECODE_PRINTF("NOT\tDWORD PTR ");
10964                 destoffset = decode_rm01_address(rl);
10965                 DECODE_PRINTF("\n");
10966                 destval = fetch_data_long(destoffset);
10967                 TRACE_AND_STEP();
10968                 destval = not_long(destval);
10969                 store_data_long(destoffset, destval);
10970             }
10971             else {
10972                 u16 destval;
10973 
10974                 DECODE_PRINTF("NOT\tWORD PTR ");
10975                 destoffset = decode_rm01_address(rl);
10976                 DECODE_PRINTF("\n");
10977                 destval = fetch_data_word(destoffset);
10978                 TRACE_AND_STEP();
10979                 destval = not_word(destval);
10980                 store_data_word(destoffset, destval);
10981             }
10982             break;
10983         case 3:
10984             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10985                 u32 destval;
10986 
10987                 DECODE_PRINTF("NEG\tDWORD PTR ");
10988                 destoffset = decode_rm01_address(rl);
10989                 DECODE_PRINTF("\n");
10990                 destval = fetch_data_long(destoffset);
10991                 TRACE_AND_STEP();
10992                 destval = neg_long(destval);
10993                 store_data_long(destoffset, destval);
10994             }
10995             else {
10996                 u16 destval;
10997 
10998                 DECODE_PRINTF("NEG\tWORD PTR ");
10999                 destoffset = decode_rm01_address(rl);
11000                 DECODE_PRINTF("\n");
11001                 destval = fetch_data_word(destoffset);
11002                 TRACE_AND_STEP();
11003                 destval = neg_word(destval);
11004                 store_data_word(destoffset, destval);
11005             }
11006             break;
11007         case 4:
11008             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11009                 u32 destval;
11010 
11011                 DECODE_PRINTF("MUL\tDWORD PTR ");
11012                 destoffset = decode_rm01_address(rl);
11013                 DECODE_PRINTF("\n");
11014                 destval = fetch_data_long(destoffset);
11015                 TRACE_AND_STEP();
11016                 mul_long(destval);
11017             }
11018             else {
11019                 u16 destval;
11020 
11021                 DECODE_PRINTF("MUL\tWORD PTR ");
11022                 destoffset = decode_rm01_address(rl);
11023                 DECODE_PRINTF("\n");
11024                 destval = fetch_data_word(destoffset);
11025                 TRACE_AND_STEP();
11026                 mul_word(destval);
11027             }
11028             break;
11029         case 5:
11030             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11031                 u32 destval;
11032 
11033                 DECODE_PRINTF("IMUL\tDWORD PTR ");
11034                 destoffset = decode_rm01_address(rl);
11035                 DECODE_PRINTF("\n");
11036                 destval = fetch_data_long(destoffset);
11037                 TRACE_AND_STEP();
11038                 imul_long(destval);
11039             }
11040             else {
11041                 u16 destval;
11042 
11043                 DECODE_PRINTF("IMUL\tWORD PTR ");
11044                 destoffset = decode_rm01_address(rl);
11045                 DECODE_PRINTF("\n");
11046                 destval = fetch_data_word(destoffset);
11047                 TRACE_AND_STEP();
11048                 imul_word(destval);
11049             }
11050             break;
11051         case 6:
11052             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11053                 u32 destval;
11054 
11055                 DECODE_PRINTF("DIV\tDWORD PTR ");
11056                 destoffset = decode_rm01_address(rl);
11057                 DECODE_PRINTF("\n");
11058                 destval = fetch_data_long(destoffset);
11059                 TRACE_AND_STEP();
11060                 div_long(destval);
11061             }
11062             else {
11063                 u16 destval;
11064 
11065                 DECODE_PRINTF("DIV\tWORD PTR ");
11066                 destoffset = decode_rm01_address(rl);
11067                 DECODE_PRINTF("\n");
11068                 destval = fetch_data_word(destoffset);
11069                 TRACE_AND_STEP();
11070                 div_word(destval);
11071             }
11072             break;
11073         case 7:
11074             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11075                 u32 destval;
11076 
11077                 DECODE_PRINTF("IDIV\tDWORD PTR ");
11078                 destoffset = decode_rm01_address(rl);
11079                 DECODE_PRINTF("\n");
11080                 destval = fetch_data_long(destoffset);
11081                 TRACE_AND_STEP();
11082                 idiv_long(destval);
11083             }
11084             else {
11085                 u16 destval;
11086 
11087                 DECODE_PRINTF("IDIV\tWORD PTR ");
11088                 destoffset = decode_rm01_address(rl);
11089                 DECODE_PRINTF("\n");
11090                 destval = fetch_data_word(destoffset);
11091                 TRACE_AND_STEP();
11092                 idiv_word(destval);
11093             }
11094             break;
11095         }
11096         break;                  /* end mod==01 */
11097     case 2:                    /* mod=10 */
11098         switch (rh) {
11099         case 0:                /* test word imm */
11100             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11101                 u32 destval, srcval;
11102 
11103                 DECODE_PRINTF("TEST\tDWORD PTR ");
11104                 destoffset = decode_rm10_address(rl);
11105                 DECODE_PRINTF(",");
11106                 srcval = fetch_long_imm();
11107                 DECODE_PRINTF2("%x\n", srcval);
11108                 destval = fetch_data_long(destoffset);
11109                 TRACE_AND_STEP();
11110                 test_long(destval, srcval);
11111             }
11112             else {
11113                 u16 destval, srcval;
11114 
11115                 DECODE_PRINTF("TEST\tWORD PTR ");
11116                 destoffset = decode_rm10_address(rl);
11117                 DECODE_PRINTF(",");
11118                 srcval = fetch_word_imm();
11119                 DECODE_PRINTF2("%x\n", srcval);
11120                 destval = fetch_data_word(destoffset);
11121                 TRACE_AND_STEP();
11122                 test_word(destval, srcval);
11123             }
11124             break;
11125         case 1:
11126             DECODE_PRINTF("ILLEGAL OP MOD=10 RH=01 OP=F6\n");
11127             HALT_SYS();
11128             break;
11129         case 2:
11130             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11131                 u32 destval;
11132 
11133                 DECODE_PRINTF("NOT\tDWORD PTR ");
11134                 destoffset = decode_rm10_address(rl);
11135                 DECODE_PRINTF("\n");
11136                 destval = fetch_data_long(destoffset);
11137                 TRACE_AND_STEP();
11138                 destval = not_long(destval);
11139                 store_data_long(destoffset, destval);
11140             }
11141             else {
11142                 u16 destval;
11143 
11144                 DECODE_PRINTF("NOT\tWORD PTR ");
11145                 destoffset = decode_rm10_address(rl);
11146                 DECODE_PRINTF("\n");
11147                 destval = fetch_data_word(destoffset);
11148                 TRACE_AND_STEP();
11149                 destval = not_word(destval);
11150                 store_data_word(destoffset, destval);
11151             }
11152             break;
11153         case 3:
11154             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11155                 u32 destval;
11156 
11157                 DECODE_PRINTF("NEG\tDWORD PTR ");
11158                 destoffset = decode_rm10_address(rl);
11159                 DECODE_PRINTF("\n");
11160                 destval = fetch_data_long(destoffset);
11161                 TRACE_AND_STEP();
11162                 destval = neg_long(destval);
11163                 store_data_long(destoffset, destval);
11164             }
11165             else {
11166                 u16 destval;
11167 
11168                 DECODE_PRINTF("NEG\tWORD PTR ");
11169                 destoffset = decode_rm10_address(rl);
11170                 DECODE_PRINTF("\n");
11171                 destval = fetch_data_word(destoffset);
11172                 TRACE_AND_STEP();
11173                 destval = neg_word(destval);
11174                 store_data_word(destoffset, destval);
11175             }
11176             break;
11177         case 4:
11178             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11179                 u32 destval;
11180 
11181                 DECODE_PRINTF("MUL\tDWORD PTR ");
11182                 destoffset = decode_rm10_address(rl);
11183                 DECODE_PRINTF("\n");
11184                 destval = fetch_data_long(destoffset);
11185                 TRACE_AND_STEP();
11186                 mul_long(destval);
11187             }
11188             else {
11189                 u16 destval;
11190 
11191                 DECODE_PRINTF("MUL\tWORD PTR ");
11192                 destoffset = decode_rm10_address(rl);
11193                 DECODE_PRINTF("\n");
11194                 destval = fetch_data_word(destoffset);
11195                 TRACE_AND_STEP();
11196                 mul_word(destval);
11197             }
11198             break;
11199         case 5:
11200             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11201                 u32 destval;
11202 
11203                 DECODE_PRINTF("IMUL\tDWORD PTR ");
11204                 destoffset = decode_rm10_address(rl);
11205                 DECODE_PRINTF("\n");
11206                 destval = fetch_data_long(destoffset);
11207                 TRACE_AND_STEP();
11208                 imul_long(destval);
11209             }
11210             else {
11211                 u16 destval;
11212 
11213                 DECODE_PRINTF("IMUL\tWORD PTR ");
11214                 destoffset = decode_rm10_address(rl);
11215                 DECODE_PRINTF("\n");
11216                 destval = fetch_data_word(destoffset);
11217                 TRACE_AND_STEP();
11218                 imul_word(destval);
11219             }
11220             break;
11221         case 6:
11222             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11223                 u32 destval;
11224 
11225                 DECODE_PRINTF("DIV\tDWORD PTR ");
11226                 destoffset = decode_rm10_address(rl);
11227                 DECODE_PRINTF("\n");
11228                 destval = fetch_data_long(destoffset);
11229                 TRACE_AND_STEP();
11230                 div_long(destval);
11231             }
11232             else {
11233                 u16 destval;
11234 
11235                 DECODE_PRINTF("DIV\tWORD PTR ");
11236                 destoffset = decode_rm10_address(rl);
11237                 DECODE_PRINTF("\n");
11238                 destval = fetch_data_word(destoffset);
11239                 TRACE_AND_STEP();
11240                 div_word(destval);
11241             }
11242             break;
11243         case 7:
11244             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11245                 u32 destval;
11246 
11247                 DECODE_PRINTF("IDIV\tDWORD PTR ");
11248                 destoffset = decode_rm10_address(rl);
11249                 DECODE_PRINTF("\n");
11250                 destval = fetch_data_long(destoffset);
11251                 TRACE_AND_STEP();
11252                 idiv_long(destval);
11253             }
11254             else {
11255                 u16 destval;
11256 
11257                 DECODE_PRINTF("IDIV\tWORD PTR ");
11258                 destoffset = decode_rm10_address(rl);
11259                 DECODE_PRINTF("\n");
11260                 destval = fetch_data_word(destoffset);
11261                 TRACE_AND_STEP();
11262                 idiv_word(destval);
11263             }
11264             break;
11265         }
11266         break;                  /* end mod==10 */
11267     case 3:                    /* mod=11 */
11268         switch (rh) {
11269         case 0:                /* test word imm */
11270             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11271                 u32 *destreg;
11272                 u32 srcval;
11273 
11274                 DECODE_PRINTF("TEST\t");
11275                 destreg = DECODE_RM_LONG_REGISTER(rl);
11276                 DECODE_PRINTF(",");
11277                 srcval = fetch_long_imm();
11278                 DECODE_PRINTF2("%x\n", srcval);
11279                 TRACE_AND_STEP();
11280                 test_long(*destreg, srcval);
11281             }
11282             else {
11283                 u16 *destreg;
11284                 u16 srcval;
11285 
11286                 DECODE_PRINTF("TEST\t");
11287                 destreg = DECODE_RM_WORD_REGISTER(rl);
11288                 DECODE_PRINTF(",");
11289                 srcval = fetch_word_imm();
11290                 DECODE_PRINTF2("%x\n", srcval);
11291                 TRACE_AND_STEP();
11292                 test_word(*destreg, srcval);
11293             }
11294             break;
11295         case 1:
11296             DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n");
11297             HALT_SYS();
11298             break;
11299         case 2:
11300             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11301                 u32 *destreg;
11302 
11303                 DECODE_PRINTF("NOT\t");
11304                 destreg = DECODE_RM_LONG_REGISTER(rl);
11305                 DECODE_PRINTF("\n");
11306                 TRACE_AND_STEP();
11307                 *destreg = not_long(*destreg);
11308             }
11309             else {
11310                 u16 *destreg;
11311 
11312                 DECODE_PRINTF("NOT\t");
11313                 destreg = DECODE_RM_WORD_REGISTER(rl);
11314                 DECODE_PRINTF("\n");
11315                 TRACE_AND_STEP();
11316                 *destreg = not_word(*destreg);
11317             }
11318             break;
11319         case 3:
11320             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11321                 u32 *destreg;
11322 
11323                 DECODE_PRINTF("NEG\t");
11324                 destreg = DECODE_RM_LONG_REGISTER(rl);
11325                 DECODE_PRINTF("\n");
11326                 TRACE_AND_STEP();
11327                 *destreg = neg_long(*destreg);
11328             }
11329             else {
11330                 u16 *destreg;
11331 
11332                 DECODE_PRINTF("NEG\t");
11333                 destreg = DECODE_RM_WORD_REGISTER(rl);
11334                 DECODE_PRINTF("\n");
11335                 TRACE_AND_STEP();
11336                 *destreg = neg_word(*destreg);
11337             }
11338             break;
11339         case 4:
11340             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11341                 u32 *destreg;
11342 
11343                 DECODE_PRINTF("MUL\t");
11344                 destreg = DECODE_RM_LONG_REGISTER(rl);
11345                 DECODE_PRINTF("\n");
11346                 TRACE_AND_STEP();
11347                 mul_long(*destreg);     /*!!!  */
11348             }
11349             else {
11350                 u16 *destreg;
11351 
11352                 DECODE_PRINTF("MUL\t");
11353                 destreg = DECODE_RM_WORD_REGISTER(rl);
11354                 DECODE_PRINTF("\n");
11355                 TRACE_AND_STEP();
11356                 mul_word(*destreg);     /*!!!  */
11357             }
11358             break;
11359         case 5:
11360             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11361                 u32 *destreg;
11362 
11363                 DECODE_PRINTF("IMUL\t");
11364                 destreg = DECODE_RM_LONG_REGISTER(rl);
11365                 DECODE_PRINTF("\n");
11366                 TRACE_AND_STEP();
11367                 imul_long(*destreg);
11368             }
11369             else {
11370                 u16 *destreg;
11371 
11372                 DECODE_PRINTF("IMUL\t");
11373                 destreg = DECODE_RM_WORD_REGISTER(rl);
11374                 DECODE_PRINTF("\n");
11375                 TRACE_AND_STEP();
11376                 imul_word(*destreg);
11377             }
11378             break;
11379         case 6:
11380             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11381                 u32 *destreg;
11382 
11383                 DECODE_PRINTF("DIV\t");
11384                 destreg = DECODE_RM_LONG_REGISTER(rl);
11385                 DECODE_PRINTF("\n");
11386                 TRACE_AND_STEP();
11387                 div_long(*destreg);
11388             }
11389             else {
11390                 u16 *destreg;
11391 
11392                 DECODE_PRINTF("DIV\t");
11393                 destreg = DECODE_RM_WORD_REGISTER(rl);
11394                 DECODE_PRINTF("\n");
11395                 TRACE_AND_STEP();
11396                 div_word(*destreg);
11397             }
11398             break;
11399         case 7:
11400             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11401                 u32 *destreg;
11402 
11403                 DECODE_PRINTF("IDIV\t");
11404                 destreg = DECODE_RM_LONG_REGISTER(rl);
11405                 DECODE_PRINTF("\n");
11406                 TRACE_AND_STEP();
11407                 idiv_long(*destreg);
11408             }
11409             else {
11410                 u16 *destreg;
11411 
11412                 DECODE_PRINTF("IDIV\t");
11413                 destreg = DECODE_RM_WORD_REGISTER(rl);
11414                 DECODE_PRINTF("\n");
11415                 TRACE_AND_STEP();
11416                 idiv_word(*destreg);
11417             }
11418             break;
11419         }
11420         break;                  /* end mod==11 */
11421     }
11422     DECODE_CLEAR_SEGOVR();
11423     END_OF_INSTR();
11424 }
11425 
11426 /****************************************************************************
11427 REMARKS:
11428 Handles opcode 0xf8
11429 ****************************************************************************/
11430 static void
x86emuOp_clc(u8 X86EMU_UNUSED (op1))11431 x86emuOp_clc(u8 X86EMU_UNUSED(op1))
11432 {
11433     /* clear the carry flag. */
11434     START_OF_INSTR();
11435     DECODE_PRINTF("CLC\n");
11436     TRACE_AND_STEP();
11437     CLEAR_FLAG(F_CF);
11438     DECODE_CLEAR_SEGOVR();
11439     END_OF_INSTR();
11440 }
11441 
11442 /****************************************************************************
11443 REMARKS:
11444 Handles opcode 0xf9
11445 ****************************************************************************/
11446 static void
x86emuOp_stc(u8 X86EMU_UNUSED (op1))11447 x86emuOp_stc(u8 X86EMU_UNUSED(op1))
11448 {
11449     /* set the carry flag. */
11450     START_OF_INSTR();
11451     DECODE_PRINTF("STC\n");
11452     TRACE_AND_STEP();
11453     SET_FLAG(F_CF);
11454     DECODE_CLEAR_SEGOVR();
11455     END_OF_INSTR();
11456 }
11457 
11458 /****************************************************************************
11459 REMARKS:
11460 Handles opcode 0xfa
11461 ****************************************************************************/
11462 static void
x86emuOp_cli(u8 X86EMU_UNUSED (op1))11463 x86emuOp_cli(u8 X86EMU_UNUSED(op1))
11464 {
11465     /* clear interrupts. */
11466     START_OF_INSTR();
11467     DECODE_PRINTF("CLI\n");
11468     TRACE_AND_STEP();
11469     CLEAR_FLAG(F_IF);
11470     DECODE_CLEAR_SEGOVR();
11471     END_OF_INSTR();
11472 }
11473 
11474 /****************************************************************************
11475 REMARKS:
11476 Handles opcode 0xfb
11477 ****************************************************************************/
11478 static void
x86emuOp_sti(u8 X86EMU_UNUSED (op1))11479 x86emuOp_sti(u8 X86EMU_UNUSED(op1))
11480 {
11481     /* enable  interrupts. */
11482     START_OF_INSTR();
11483     DECODE_PRINTF("STI\n");
11484     TRACE_AND_STEP();
11485     SET_FLAG(F_IF);
11486     DECODE_CLEAR_SEGOVR();
11487     END_OF_INSTR();
11488 }
11489 
11490 /****************************************************************************
11491 REMARKS:
11492 Handles opcode 0xfc
11493 ****************************************************************************/
11494 static void
x86emuOp_cld(u8 X86EMU_UNUSED (op1))11495 x86emuOp_cld(u8 X86EMU_UNUSED(op1))
11496 {
11497     /* clear interrupts. */
11498     START_OF_INSTR();
11499     DECODE_PRINTF("CLD\n");
11500     TRACE_AND_STEP();
11501     CLEAR_FLAG(F_DF);
11502     DECODE_CLEAR_SEGOVR();
11503     END_OF_INSTR();
11504 }
11505 
11506 /****************************************************************************
11507 REMARKS:
11508 Handles opcode 0xfd
11509 ****************************************************************************/
11510 static void
x86emuOp_std(u8 X86EMU_UNUSED (op1))11511 x86emuOp_std(u8 X86EMU_UNUSED(op1))
11512 {
11513     /* clear interrupts. */
11514     START_OF_INSTR();
11515     DECODE_PRINTF("STD\n");
11516     TRACE_AND_STEP();
11517     SET_FLAG(F_DF);
11518     DECODE_CLEAR_SEGOVR();
11519     END_OF_INSTR();
11520 }
11521 
11522 /****************************************************************************
11523 REMARKS:
11524 Handles opcode 0xfe
11525 ****************************************************************************/
11526 static void
x86emuOp_opcFE_byte_RM(u8 X86EMU_UNUSED (op1))11527 x86emuOp_opcFE_byte_RM(u8 X86EMU_UNUSED(op1))
11528 {
11529     int mod, rh, rl;
11530     u8 destval;
11531     uint destoffset;
11532     u8 *destreg;
11533 
11534     /* Yet another special case instruction. */
11535     START_OF_INSTR();
11536     FETCH_DECODE_MODRM(mod, rh, rl);
11537 #ifdef DEBUG
11538     if (DEBUG_DECODE()) {
11539         /* XXX DECODE_PRINTF may be changed to something more
11540            general, so that it is important to leave the strings
11541            in the same format, even though the result is that the
11542            above test is done twice. */
11543 
11544         switch (rh) {
11545         case 0:
11546             DECODE_PRINTF("INC\t");
11547             break;
11548         case 1:
11549             DECODE_PRINTF("DEC\t");
11550             break;
11551         case 2:
11552         case 3:
11553         case 4:
11554         case 5:
11555         case 6:
11556         case 7:
11557             DECODE_PRINTF2("ILLEGAL OP MAJOR OP 0xFE MINOR OP %x \n", mod);
11558             HALT_SYS();
11559             break;
11560         }
11561     }
11562 #endif
11563     switch (mod) {
11564     case 0:
11565         DECODE_PRINTF("BYTE PTR ");
11566         destoffset = decode_rm00_address(rl);
11567         DECODE_PRINTF("\n");
11568         switch (rh) {
11569         case 0:                /* inc word ptr ... */
11570             destval = fetch_data_byte(destoffset);
11571             TRACE_AND_STEP();
11572             destval = inc_byte(destval);
11573             store_data_byte(destoffset, destval);
11574             break;
11575         case 1:                /* dec word ptr ... */
11576             destval = fetch_data_byte(destoffset);
11577             TRACE_AND_STEP();
11578             destval = dec_byte(destval);
11579             store_data_byte(destoffset, destval);
11580             break;
11581         }
11582         break;
11583     case 1:
11584         DECODE_PRINTF("BYTE PTR ");
11585         destoffset = decode_rm01_address(rl);
11586         DECODE_PRINTF("\n");
11587         switch (rh) {
11588         case 0:
11589             destval = fetch_data_byte(destoffset);
11590             TRACE_AND_STEP();
11591             destval = inc_byte(destval);
11592             store_data_byte(destoffset, destval);
11593             break;
11594         case 1:
11595             destval = fetch_data_byte(destoffset);
11596             TRACE_AND_STEP();
11597             destval = dec_byte(destval);
11598             store_data_byte(destoffset, destval);
11599             break;
11600         }
11601         break;
11602     case 2:
11603         DECODE_PRINTF("BYTE PTR ");
11604         destoffset = decode_rm10_address(rl);
11605         DECODE_PRINTF("\n");
11606         switch (rh) {
11607         case 0:
11608             destval = fetch_data_byte(destoffset);
11609             TRACE_AND_STEP();
11610             destval = inc_byte(destval);
11611             store_data_byte(destoffset, destval);
11612             break;
11613         case 1:
11614             destval = fetch_data_byte(destoffset);
11615             TRACE_AND_STEP();
11616             destval = dec_byte(destval);
11617             store_data_byte(destoffset, destval);
11618             break;
11619         }
11620         break;
11621     case 3:
11622         destreg = DECODE_RM_BYTE_REGISTER(rl);
11623         DECODE_PRINTF("\n");
11624         switch (rh) {
11625         case 0:
11626             TRACE_AND_STEP();
11627             *destreg = inc_byte(*destreg);
11628             break;
11629         case 1:
11630             TRACE_AND_STEP();
11631             *destreg = dec_byte(*destreg);
11632             break;
11633         }
11634         break;
11635     }
11636     DECODE_CLEAR_SEGOVR();
11637     END_OF_INSTR();
11638 }
11639 
11640 /****************************************************************************
11641 REMARKS:
11642 Handles opcode 0xff
11643 ****************************************************************************/
11644 static void
x86emuOp_opcFF_word_RM(u8 X86EMU_UNUSED (op1))11645 x86emuOp_opcFF_word_RM(u8 X86EMU_UNUSED(op1))
11646 {
11647     int mod, rh, rl;
11648     uint destoffset = 0;
11649     u16 *destreg;
11650     u16 destval, destval2;
11651 
11652     /* Yet another special case instruction. */
11653     START_OF_INSTR();
11654     FETCH_DECODE_MODRM(mod, rh, rl);
11655 #ifdef DEBUG
11656     if (DEBUG_DECODE()) {
11657         /* XXX DECODE_PRINTF may be changed to something more
11658            general, so that it is important to leave the strings
11659            in the same format, even though the result is that the
11660            above test is done twice. */
11661 
11662         switch (rh) {
11663         case 0:
11664             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11665                 DECODE_PRINTF("INC\tDWORD PTR ");
11666             }
11667             else {
11668                 DECODE_PRINTF("INC\tWORD PTR ");
11669             }
11670             break;
11671         case 1:
11672             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11673                 DECODE_PRINTF("DEC\tDWORD PTR ");
11674             }
11675             else {
11676                 DECODE_PRINTF("DEC\tWORD PTR ");
11677             }
11678             break;
11679         case 2:
11680             DECODE_PRINTF("CALL\t");
11681             break;
11682         case 3:
11683             DECODE_PRINTF("CALL\tFAR ");
11684             break;
11685         case 4:
11686             DECODE_PRINTF("JMP\t");
11687             break;
11688         case 5:
11689             DECODE_PRINTF("JMP\tFAR ");
11690             break;
11691         case 6:
11692             DECODE_PRINTF("PUSH\t");
11693             break;
11694         case 7:
11695             DECODE_PRINTF("ILLEGAL DECODING OF OPCODE FF\t");
11696             HALT_SYS();
11697             break;
11698         }
11699     }
11700 #endif
11701     switch (mod) {
11702     case 0:
11703         destoffset = decode_rm00_address(rl);
11704         DECODE_PRINTF("\n");
11705         switch (rh) {
11706         case 0:                /* inc word ptr ... */
11707             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11708                 u32 destval;
11709 
11710                 destval = fetch_data_long(destoffset);
11711                 TRACE_AND_STEP();
11712                 destval = inc_long(destval);
11713                 store_data_long(destoffset, destval);
11714             }
11715             else {
11716                 u16 destval;
11717 
11718                 destval = fetch_data_word(destoffset);
11719                 TRACE_AND_STEP();
11720                 destval = inc_word(destval);
11721                 store_data_word(destoffset, destval);
11722             }
11723             break;
11724         case 1:                /* dec word ptr ... */
11725             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11726                 u32 destval;
11727 
11728                 destval = fetch_data_long(destoffset);
11729                 TRACE_AND_STEP();
11730                 destval = dec_long(destval);
11731                 store_data_long(destoffset, destval);
11732             }
11733             else {
11734                 u16 destval;
11735 
11736                 destval = fetch_data_word(destoffset);
11737                 TRACE_AND_STEP();
11738                 destval = dec_word(destval);
11739                 store_data_word(destoffset, destval);
11740             }
11741             break;
11742         case 2:                /* call word ptr ... */
11743             destval = fetch_data_word(destoffset);
11744             TRACE_AND_STEP();
11745             push_word(M.x86.R_IP);
11746             M.x86.R_IP = destval;
11747             break;
11748         case 3:                /* call far ptr ... */
11749             destval = fetch_data_word(destoffset);
11750             destval2 = fetch_data_word(destoffset + 2);
11751             TRACE_AND_STEP();
11752             push_word(M.x86.R_CS);
11753             M.x86.R_CS = destval2;
11754             push_word(M.x86.R_IP);
11755             M.x86.R_IP = destval;
11756             break;
11757         case 4:                /* jmp word ptr ... */
11758             destval = fetch_data_word(destoffset);
11759             TRACE_AND_STEP();
11760             M.x86.R_IP = destval;
11761             break;
11762         case 5:                /* jmp far ptr ... */
11763             destval = fetch_data_word(destoffset);
11764             destval2 = fetch_data_word(destoffset + 2);
11765             TRACE_AND_STEP();
11766             M.x86.R_IP = destval;
11767             M.x86.R_CS = destval2;
11768             break;
11769         case 6:                /*  push word ptr ... */
11770             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11771                 u32 destval;
11772 
11773                 destval = fetch_data_long(destoffset);
11774                 TRACE_AND_STEP();
11775                 push_long(destval);
11776             }
11777             else {
11778                 u16 destval;
11779 
11780                 destval = fetch_data_word(destoffset);
11781                 TRACE_AND_STEP();
11782                 push_word(destval);
11783             }
11784             break;
11785         }
11786         break;
11787     case 1:
11788         destoffset = decode_rm01_address(rl);
11789         DECODE_PRINTF("\n");
11790         switch (rh) {
11791         case 0:
11792             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11793                 u32 destval;
11794 
11795                 destval = fetch_data_long(destoffset);
11796                 TRACE_AND_STEP();
11797                 destval = inc_long(destval);
11798                 store_data_long(destoffset, destval);
11799             }
11800             else {
11801                 u16 destval;
11802 
11803                 destval = fetch_data_word(destoffset);
11804                 TRACE_AND_STEP();
11805                 destval = inc_word(destval);
11806                 store_data_word(destoffset, destval);
11807             }
11808             break;
11809         case 1:
11810             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11811                 u32 destval;
11812 
11813                 destval = fetch_data_long(destoffset);
11814                 TRACE_AND_STEP();
11815                 destval = dec_long(destval);
11816                 store_data_long(destoffset, destval);
11817             }
11818             else {
11819                 u16 destval;
11820 
11821                 destval = fetch_data_word(destoffset);
11822                 TRACE_AND_STEP();
11823                 destval = dec_word(destval);
11824                 store_data_word(destoffset, destval);
11825             }
11826             break;
11827         case 2:                /* call word ptr ... */
11828             destval = fetch_data_word(destoffset);
11829             TRACE_AND_STEP();
11830             push_word(M.x86.R_IP);
11831             M.x86.R_IP = destval;
11832             break;
11833         case 3:                /* call far ptr ... */
11834             destval = fetch_data_word(destoffset);
11835             destval2 = fetch_data_word(destoffset + 2);
11836             TRACE_AND_STEP();
11837             push_word(M.x86.R_CS);
11838             M.x86.R_CS = destval2;
11839             push_word(M.x86.R_IP);
11840             M.x86.R_IP = destval;
11841             break;
11842         case 4:                /* jmp word ptr ... */
11843             destval = fetch_data_word(destoffset);
11844             TRACE_AND_STEP();
11845             M.x86.R_IP = destval;
11846             break;
11847         case 5:                /* jmp far ptr ... */
11848             destval = fetch_data_word(destoffset);
11849             destval2 = fetch_data_word(destoffset + 2);
11850             TRACE_AND_STEP();
11851             M.x86.R_IP = destval;
11852             M.x86.R_CS = destval2;
11853             break;
11854         case 6:                /*  push word ptr ... */
11855             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11856                 u32 destval;
11857 
11858                 destval = fetch_data_long(destoffset);
11859                 TRACE_AND_STEP();
11860                 push_long(destval);
11861             }
11862             else {
11863                 u16 destval;
11864 
11865                 destval = fetch_data_word(destoffset);
11866                 TRACE_AND_STEP();
11867                 push_word(destval);
11868             }
11869             break;
11870         }
11871         break;
11872     case 2:
11873         destoffset = decode_rm10_address(rl);
11874         DECODE_PRINTF("\n");
11875         switch (rh) {
11876         case 0:
11877             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11878                 u32 destval;
11879 
11880                 destval = fetch_data_long(destoffset);
11881                 TRACE_AND_STEP();
11882                 destval = inc_long(destval);
11883                 store_data_long(destoffset, destval);
11884             }
11885             else {
11886                 u16 destval;
11887 
11888                 destval = fetch_data_word(destoffset);
11889                 TRACE_AND_STEP();
11890                 destval = inc_word(destval);
11891                 store_data_word(destoffset, destval);
11892             }
11893             break;
11894         case 1:
11895             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11896                 u32 destval;
11897 
11898                 destval = fetch_data_long(destoffset);
11899                 TRACE_AND_STEP();
11900                 destval = dec_long(destval);
11901                 store_data_long(destoffset, destval);
11902             }
11903             else {
11904                 u16 destval;
11905 
11906                 destval = fetch_data_word(destoffset);
11907                 TRACE_AND_STEP();
11908                 destval = dec_word(destval);
11909                 store_data_word(destoffset, destval);
11910             }
11911             break;
11912         case 2:                /* call word ptr ... */
11913             destval = fetch_data_word(destoffset);
11914             TRACE_AND_STEP();
11915             push_word(M.x86.R_IP);
11916             M.x86.R_IP = destval;
11917             break;
11918         case 3:                /* call far ptr ... */
11919             destval = fetch_data_word(destoffset);
11920             destval2 = fetch_data_word(destoffset + 2);
11921             TRACE_AND_STEP();
11922             push_word(M.x86.R_CS);
11923             M.x86.R_CS = destval2;
11924             push_word(M.x86.R_IP);
11925             M.x86.R_IP = destval;
11926             break;
11927         case 4:                /* jmp word ptr ... */
11928             destval = fetch_data_word(destoffset);
11929             TRACE_AND_STEP();
11930             M.x86.R_IP = destval;
11931             break;
11932         case 5:                /* jmp far ptr ... */
11933             destval = fetch_data_word(destoffset);
11934             destval2 = fetch_data_word(destoffset + 2);
11935             TRACE_AND_STEP();
11936             M.x86.R_IP = destval;
11937             M.x86.R_CS = destval2;
11938             break;
11939         case 6:                /*  push word ptr ... */
11940             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11941                 u32 destval;
11942 
11943                 destval = fetch_data_long(destoffset);
11944                 TRACE_AND_STEP();
11945                 push_long(destval);
11946             }
11947             else {
11948                 u16 destval;
11949 
11950                 destval = fetch_data_word(destoffset);
11951                 TRACE_AND_STEP();
11952                 push_word(destval);
11953             }
11954             break;
11955         }
11956         break;
11957     case 3:
11958         switch (rh) {
11959         case 0:
11960             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11961                 u32 *destreg;
11962 
11963                 destreg = DECODE_RM_LONG_REGISTER(rl);
11964                 DECODE_PRINTF("\n");
11965                 TRACE_AND_STEP();
11966                 *destreg = inc_long(*destreg);
11967             }
11968             else {
11969                 u16 *destreg;
11970 
11971                 destreg = DECODE_RM_WORD_REGISTER(rl);
11972                 DECODE_PRINTF("\n");
11973                 TRACE_AND_STEP();
11974                 *destreg = inc_word(*destreg);
11975             }
11976             break;
11977         case 1:
11978             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11979                 u32 *destreg;
11980 
11981                 destreg = DECODE_RM_LONG_REGISTER(rl);
11982                 DECODE_PRINTF("\n");
11983                 TRACE_AND_STEP();
11984                 *destreg = dec_long(*destreg);
11985             }
11986             else {
11987                 u16 *destreg;
11988 
11989                 destreg = DECODE_RM_WORD_REGISTER(rl);
11990                 DECODE_PRINTF("\n");
11991                 TRACE_AND_STEP();
11992                 *destreg = dec_word(*destreg);
11993             }
11994             break;
11995         case 2:                /* call word ptr ... */
11996             destreg = DECODE_RM_WORD_REGISTER(rl);
11997             DECODE_PRINTF("\n");
11998             TRACE_AND_STEP();
11999             push_word(M.x86.R_IP);
12000             M.x86.R_IP = *destreg;
12001             break;
12002         case 3:                /* jmp far ptr ... */
12003             DECODE_PRINTF("OPERATION UNDEFINED 0XFF \n");
12004             TRACE_AND_STEP();
12005             HALT_SYS();
12006             break;
12007 
12008         case 4:                /* jmp  ... */
12009             destreg = DECODE_RM_WORD_REGISTER(rl);
12010             DECODE_PRINTF("\n");
12011             TRACE_AND_STEP();
12012             M.x86.R_IP = (u16) (*destreg);
12013             break;
12014         case 5:                /* jmp far ptr ... */
12015             DECODE_PRINTF("OPERATION UNDEFINED 0XFF \n");
12016             TRACE_AND_STEP();
12017             HALT_SYS();
12018             break;
12019         case 6:
12020             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
12021                 u32 *destreg;
12022 
12023                 destreg = DECODE_RM_LONG_REGISTER(rl);
12024                 DECODE_PRINTF("\n");
12025                 TRACE_AND_STEP();
12026                 push_long(*destreg);
12027             }
12028             else {
12029                 u16 *destreg;
12030 
12031                 destreg = DECODE_RM_WORD_REGISTER(rl);
12032                 DECODE_PRINTF("\n");
12033                 TRACE_AND_STEP();
12034                 push_word(*destreg);
12035             }
12036             break;
12037         }
12038         break;
12039     }
12040     DECODE_CLEAR_SEGOVR();
12041     END_OF_INSTR();
12042 }
12043 
12044 /***************************************************************************
12045  * Single byte operation code table:
12046  **************************************************************************/
12047 void (*x86emu_optab[256]) (u8) = {
12048 /*  0x00 */ x86emuOp_add_byte_RM_R,
12049 /*  0x01 */ x86emuOp_add_word_RM_R,
12050 /*  0x02 */ x86emuOp_add_byte_R_RM,
12051 /*  0x03 */ x86emuOp_add_word_R_RM,
12052 /*  0x04 */ x86emuOp_add_byte_AL_IMM,
12053 /*  0x05 */ x86emuOp_add_word_AX_IMM,
12054 /*  0x06 */ x86emuOp_push_ES,
12055 /*  0x07 */ x86emuOp_pop_ES,
12056 /*  0x08 */ x86emuOp_or_byte_RM_R,
12057 /*  0x09 */ x86emuOp_or_word_RM_R,
12058 /*  0x0a */ x86emuOp_or_byte_R_RM,
12059 /*  0x0b */ x86emuOp_or_word_R_RM,
12060 /*  0x0c */ x86emuOp_or_byte_AL_IMM,
12061 /*  0x0d */ x86emuOp_or_word_AX_IMM,
12062 /*  0x0e */ x86emuOp_push_CS,
12063 /*  0x0f */ x86emuOp_two_byte,
12064 /*  0x10 */ x86emuOp_adc_byte_RM_R,
12065 /*  0x11 */ x86emuOp_adc_word_RM_R,
12066 /*  0x12 */ x86emuOp_adc_byte_R_RM,
12067 /*  0x13 */ x86emuOp_adc_word_R_RM,
12068 /*  0x14 */ x86emuOp_adc_byte_AL_IMM,
12069 /*  0x15 */ x86emuOp_adc_word_AX_IMM,
12070 /*  0x16 */ x86emuOp_push_SS,
12071 /*  0x17 */ x86emuOp_pop_SS,
12072 /*  0x18 */ x86emuOp_sbb_byte_RM_R,
12073 /*  0x19 */ x86emuOp_sbb_word_RM_R,
12074 /*  0x1a */ x86emuOp_sbb_byte_R_RM,
12075 /*  0x1b */ x86emuOp_sbb_word_R_RM,
12076 /*  0x1c */ x86emuOp_sbb_byte_AL_IMM,
12077 /*  0x1d */ x86emuOp_sbb_word_AX_IMM,
12078 /*  0x1e */ x86emuOp_push_DS,
12079 /*  0x1f */ x86emuOp_pop_DS,
12080 /*  0x20 */ x86emuOp_and_byte_RM_R,
12081 /*  0x21 */ x86emuOp_and_word_RM_R,
12082 /*  0x22 */ x86emuOp_and_byte_R_RM,
12083 /*  0x23 */ x86emuOp_and_word_R_RM,
12084 /*  0x24 */ x86emuOp_and_byte_AL_IMM,
12085 /*  0x25 */ x86emuOp_and_word_AX_IMM,
12086 /*  0x26 */ x86emuOp_segovr_ES,
12087 /*  0x27 */ x86emuOp_daa,
12088 /*  0x28 */ x86emuOp_sub_byte_RM_R,
12089 /*  0x29 */ x86emuOp_sub_word_RM_R,
12090 /*  0x2a */ x86emuOp_sub_byte_R_RM,
12091 /*  0x2b */ x86emuOp_sub_word_R_RM,
12092 /*  0x2c */ x86emuOp_sub_byte_AL_IMM,
12093 /*  0x2d */ x86emuOp_sub_word_AX_IMM,
12094 /*  0x2e */ x86emuOp_segovr_CS,
12095 /*  0x2f */ x86emuOp_das,
12096 /*  0x30 */ x86emuOp_xor_byte_RM_R,
12097 /*  0x31 */ x86emuOp_xor_word_RM_R,
12098 /*  0x32 */ x86emuOp_xor_byte_R_RM,
12099 /*  0x33 */ x86emuOp_xor_word_R_RM,
12100 /*  0x34 */ x86emuOp_xor_byte_AL_IMM,
12101 /*  0x35 */ x86emuOp_xor_word_AX_IMM,
12102 /*  0x36 */ x86emuOp_segovr_SS,
12103 /*  0x37 */ x86emuOp_aaa,
12104 /*  0x38 */ x86emuOp_cmp_byte_RM_R,
12105 /*  0x39 */ x86emuOp_cmp_word_RM_R,
12106 /*  0x3a */ x86emuOp_cmp_byte_R_RM,
12107 /*  0x3b */ x86emuOp_cmp_word_R_RM,
12108 /*  0x3c */ x86emuOp_cmp_byte_AL_IMM,
12109 /*  0x3d */ x86emuOp_cmp_word_AX_IMM,
12110 /*  0x3e */ x86emuOp_segovr_DS,
12111 /*  0x3f */ x86emuOp_aas,
12112 /*  0x40 */ x86emuOp_inc_AX,
12113 /*  0x41 */ x86emuOp_inc_CX,
12114 /*  0x42 */ x86emuOp_inc_DX,
12115 /*  0x43 */ x86emuOp_inc_BX,
12116 /*  0x44 */ x86emuOp_inc_SP,
12117 /*  0x45 */ x86emuOp_inc_BP,
12118 /*  0x46 */ x86emuOp_inc_SI,
12119 /*  0x47 */ x86emuOp_inc_DI,
12120 /*  0x48 */ x86emuOp_dec_AX,
12121 /*  0x49 */ x86emuOp_dec_CX,
12122 /*  0x4a */ x86emuOp_dec_DX,
12123 /*  0x4b */ x86emuOp_dec_BX,
12124 /*  0x4c */ x86emuOp_dec_SP,
12125 /*  0x4d */ x86emuOp_dec_BP,
12126 /*  0x4e */ x86emuOp_dec_SI,
12127 /*  0x4f */ x86emuOp_dec_DI,
12128 /*  0x50 */ x86emuOp_push_AX,
12129 /*  0x51 */ x86emuOp_push_CX,
12130 /*  0x52 */ x86emuOp_push_DX,
12131 /*  0x53 */ x86emuOp_push_BX,
12132 /*  0x54 */ x86emuOp_push_SP,
12133 /*  0x55 */ x86emuOp_push_BP,
12134 /*  0x56 */ x86emuOp_push_SI,
12135 /*  0x57 */ x86emuOp_push_DI,
12136 /*  0x58 */ x86emuOp_pop_AX,
12137 /*  0x59 */ x86emuOp_pop_CX,
12138 /*  0x5a */ x86emuOp_pop_DX,
12139 /*  0x5b */ x86emuOp_pop_BX,
12140 /*  0x5c */ x86emuOp_pop_SP,
12141 /*  0x5d */ x86emuOp_pop_BP,
12142 /*  0x5e */ x86emuOp_pop_SI,
12143 /*  0x5f */ x86emuOp_pop_DI,
12144 /*  0x60 */ x86emuOp_push_all,
12145 /*  0x61 */ x86emuOp_pop_all,
12146                                                 /*  0x62 */ x86emuOp_illegal_op,
12147                                                 /* bound */
12148                                                 /*  0x63 */ x86emuOp_illegal_op,
12149                                                 /* arpl */
12150 /*  0x64 */ x86emuOp_segovr_FS,
12151 /*  0x65 */ x86emuOp_segovr_GS,
12152 /*  0x66 */ x86emuOp_prefix_data,
12153 /*  0x67 */ x86emuOp_prefix_addr,
12154 /*  0x68 */ x86emuOp_push_word_IMM,
12155 /*  0x69 */ x86emuOp_imul_word_IMM,
12156 /*  0x6a */ x86emuOp_push_byte_IMM,
12157 /*  0x6b */ x86emuOp_imul_byte_IMM,
12158 /*  0x6c */ x86emuOp_ins_byte,
12159 /*  0x6d */ x86emuOp_ins_word,
12160 /*  0x6e */ x86emuOp_outs_byte,
12161 /*  0x6f */ x86emuOp_outs_word,
12162 /*  0x70 */ x86emuOp_jump_near_O,
12163 /*  0x71 */ x86emuOp_jump_near_NO,
12164 /*  0x72 */ x86emuOp_jump_near_B,
12165 /*  0x73 */ x86emuOp_jump_near_NB,
12166 /*  0x74 */ x86emuOp_jump_near_Z,
12167 /*  0x75 */ x86emuOp_jump_near_NZ,
12168 /*  0x76 */ x86emuOp_jump_near_BE,
12169 /*  0x77 */ x86emuOp_jump_near_NBE,
12170 /*  0x78 */ x86emuOp_jump_near_S,
12171 /*  0x79 */ x86emuOp_jump_near_NS,
12172 /*  0x7a */ x86emuOp_jump_near_P,
12173 /*  0x7b */ x86emuOp_jump_near_NP,
12174 /*  0x7c */ x86emuOp_jump_near_L,
12175 /*  0x7d */ x86emuOp_jump_near_NL,
12176 /*  0x7e */ x86emuOp_jump_near_LE,
12177 /*  0x7f */ x86emuOp_jump_near_NLE,
12178 /*  0x80 */ x86emuOp_opc80_byte_RM_IMM,
12179 /*  0x81 */ x86emuOp_opc81_word_RM_IMM,
12180 /*  0x82 */ x86emuOp_opc82_byte_RM_IMM,
12181 /*  0x83 */ x86emuOp_opc83_word_RM_IMM,
12182 /*  0x84 */ x86emuOp_test_byte_RM_R,
12183 /*  0x85 */ x86emuOp_test_word_RM_R,
12184 /*  0x86 */ x86emuOp_xchg_byte_RM_R,
12185 /*  0x87 */ x86emuOp_xchg_word_RM_R,
12186 /*  0x88 */ x86emuOp_mov_byte_RM_R,
12187 /*  0x89 */ x86emuOp_mov_word_RM_R,
12188 /*  0x8a */ x86emuOp_mov_byte_R_RM,
12189 /*  0x8b */ x86emuOp_mov_word_R_RM,
12190 /*  0x8c */ x86emuOp_mov_word_RM_SR,
12191 /*  0x8d */ x86emuOp_lea_word_R_M,
12192 /*  0x8e */ x86emuOp_mov_word_SR_RM,
12193 /*  0x8f */ x86emuOp_pop_RM,
12194 /*  0x90 */ x86emuOp_nop,
12195 /*  0x91 */ x86emuOp_xchg_word_AX_CX,
12196 /*  0x92 */ x86emuOp_xchg_word_AX_DX,
12197 /*  0x93 */ x86emuOp_xchg_word_AX_BX,
12198 /*  0x94 */ x86emuOp_xchg_word_AX_SP,
12199 /*  0x95 */ x86emuOp_xchg_word_AX_BP,
12200 /*  0x96 */ x86emuOp_xchg_word_AX_SI,
12201 /*  0x97 */ x86emuOp_xchg_word_AX_DI,
12202 /*  0x98 */ x86emuOp_cbw,
12203 /*  0x99 */ x86emuOp_cwd,
12204 /*  0x9a */ x86emuOp_call_far_IMM,
12205 /*  0x9b */ x86emuOp_wait,
12206 /*  0x9c */ x86emuOp_pushf_word,
12207 /*  0x9d */ x86emuOp_popf_word,
12208 /*  0x9e */ x86emuOp_sahf,
12209 /*  0x9f */ x86emuOp_lahf,
12210 /*  0xa0 */ x86emuOp_mov_AL_M_IMM,
12211 /*  0xa1 */ x86emuOp_mov_AX_M_IMM,
12212 /*  0xa2 */ x86emuOp_mov_M_AL_IMM,
12213 /*  0xa3 */ x86emuOp_mov_M_AX_IMM,
12214 /*  0xa4 */ x86emuOp_movs_byte,
12215 /*  0xa5 */ x86emuOp_movs_word,
12216 /*  0xa6 */ x86emuOp_cmps_byte,
12217 /*  0xa7 */ x86emuOp_cmps_word,
12218 /*  0xa8 */ x86emuOp_test_AL_IMM,
12219 /*  0xa9 */ x86emuOp_test_AX_IMM,
12220 /*  0xaa */ x86emuOp_stos_byte,
12221 /*  0xab */ x86emuOp_stos_word,
12222 /*  0xac */ x86emuOp_lods_byte,
12223 /*  0xad */ x86emuOp_lods_word,
12224 /*  0xac */ x86emuOp_scas_byte,
12225 /*  0xad */ x86emuOp_scas_word,
12226 /*  0xb0 */ x86emuOp_mov_byte_AL_IMM,
12227 /*  0xb1 */ x86emuOp_mov_byte_CL_IMM,
12228 /*  0xb2 */ x86emuOp_mov_byte_DL_IMM,
12229 /*  0xb3 */ x86emuOp_mov_byte_BL_IMM,
12230 /*  0xb4 */ x86emuOp_mov_byte_AH_IMM,
12231 /*  0xb5 */ x86emuOp_mov_byte_CH_IMM,
12232 /*  0xb6 */ x86emuOp_mov_byte_DH_IMM,
12233 /*  0xb7 */ x86emuOp_mov_byte_BH_IMM,
12234 /*  0xb8 */ x86emuOp_mov_word_AX_IMM,
12235 /*  0xb9 */ x86emuOp_mov_word_CX_IMM,
12236 /*  0xba */ x86emuOp_mov_word_DX_IMM,
12237 /*  0xbb */ x86emuOp_mov_word_BX_IMM,
12238 /*  0xbc */ x86emuOp_mov_word_SP_IMM,
12239 /*  0xbd */ x86emuOp_mov_word_BP_IMM,
12240 /*  0xbe */ x86emuOp_mov_word_SI_IMM,
12241 /*  0xbf */ x86emuOp_mov_word_DI_IMM,
12242 /*  0xc0 */ x86emuOp_opcC0_byte_RM_MEM,
12243 /*  0xc1 */ x86emuOp_opcC1_word_RM_MEM,
12244 /*  0xc2 */ x86emuOp_ret_near_IMM,
12245 /*  0xc3 */ x86emuOp_ret_near,
12246 /*  0xc4 */ x86emuOp_les_R_IMM,
12247 /*  0xc5 */ x86emuOp_lds_R_IMM,
12248 /*  0xc6 */ x86emuOp_mov_byte_RM_IMM,
12249 /*  0xc7 */ x86emuOp_mov_word_RM_IMM,
12250 /*  0xc8 */ x86emuOp_enter,
12251 /*  0xc9 */ x86emuOp_leave,
12252 /*  0xca */ x86emuOp_ret_far_IMM,
12253 /*  0xcb */ x86emuOp_ret_far,
12254 /*  0xcc */ x86emuOp_int3,
12255 /*  0xcd */ x86emuOp_int_IMM,
12256 /*  0xce */ x86emuOp_into,
12257 /*  0xcf */ x86emuOp_iret,
12258 /*  0xd0 */ x86emuOp_opcD0_byte_RM_1,
12259 /*  0xd1 */ x86emuOp_opcD1_word_RM_1,
12260 /*  0xd2 */ x86emuOp_opcD2_byte_RM_CL,
12261 /*  0xd3 */ x86emuOp_opcD3_word_RM_CL,
12262 /*  0xd4 */ x86emuOp_aam,
12263 /*  0xd5 */ x86emuOp_aad,
12264                                                 /*  0xd6 */ x86emuOp_illegal_op,
12265                                                 /* Undocumented SETALC instruction */
12266 /*  0xd7 */ x86emuOp_xlat,
12267 /*  0xd8 */ x86emuOp_esc_coprocess_d8,
12268 /*  0xd9 */ x86emuOp_esc_coprocess_d9,
12269 /*  0xda */ x86emuOp_esc_coprocess_da,
12270 /*  0xdb */ x86emuOp_esc_coprocess_db,
12271 /*  0xdc */ x86emuOp_esc_coprocess_dc,
12272 /*  0xdd */ x86emuOp_esc_coprocess_dd,
12273 /*  0xde */ x86emuOp_esc_coprocess_de,
12274 /*  0xdf */ x86emuOp_esc_coprocess_df,
12275 /*  0xe0 */ x86emuOp_loopne,
12276 /*  0xe1 */ x86emuOp_loope,
12277 /*  0xe2 */ x86emuOp_loop,
12278 /*  0xe3 */ x86emuOp_jcxz,
12279 /*  0xe4 */ x86emuOp_in_byte_AL_IMM,
12280 /*  0xe5 */ x86emuOp_in_word_AX_IMM,
12281 /*  0xe6 */ x86emuOp_out_byte_IMM_AL,
12282 /*  0xe7 */ x86emuOp_out_word_IMM_AX,
12283 /*  0xe8 */ x86emuOp_call_near_IMM,
12284 /*  0xe9 */ x86emuOp_jump_near_IMM,
12285 /*  0xea */ x86emuOp_jump_far_IMM,
12286 /*  0xeb */ x86emuOp_jump_byte_IMM,
12287 /*  0xec */ x86emuOp_in_byte_AL_DX,
12288 /*  0xed */ x86emuOp_in_word_AX_DX,
12289 /*  0xee */ x86emuOp_out_byte_DX_AL,
12290 /*  0xef */ x86emuOp_out_word_DX_AX,
12291 /*  0xf0 */ x86emuOp_lock,
12292 /*  0xf1 */ x86emuOp_illegal_op,
12293 /*  0xf2 */ x86emuOp_repne,
12294 /*  0xf3 */ x86emuOp_repe,
12295 /*  0xf4 */ x86emuOp_halt,
12296 /*  0xf5 */ x86emuOp_cmc,
12297 /*  0xf6 */ x86emuOp_opcF6_byte_RM,
12298 /*  0xf7 */ x86emuOp_opcF7_word_RM,
12299 /*  0xf8 */ x86emuOp_clc,
12300 /*  0xf9 */ x86emuOp_stc,
12301 /*  0xfa */ x86emuOp_cli,
12302 /*  0xfb */ x86emuOp_sti,
12303 /*  0xfc */ x86emuOp_cld,
12304 /*  0xfd */ x86emuOp_std,
12305 /*  0xfe */ x86emuOp_opcFE_byte_RM,
12306 /*  0xff */ x86emuOp_opcFF_word_RM,
12307 };
12308