1 /****************************************************************************
2 *
3 *                       Realmode X86 Emulator Library
4 *
5 *               Copyright (C) 1991-2004 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 ****************************************************************************/
x86emuOp_illegal_op(u8 op1)84 void x86emuOp_illegal_op(
85     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 ****************************************************************************/
x86emuOp_add_byte_RM_R(u8 X86EMU_UNUSED (op1))111 void x86emuOp_add_byte_RM_R(u8 X86EMU_UNUSED(op1))
112 {
113     int mod, rl, rh;
114     uint destoffset;
115     u8 *destreg, *srcreg;
116     u8 destval;
117 
118     START_OF_INSTR();
119     DECODE_PRINTF("ADD\t");
120     FETCH_DECODE_MODRM(mod, rh, rl);
121     switch (mod) {
122     case 0:
123         destoffset = decode_rm00_address(rl);
124         DECODE_PRINTF(",");
125         destval = fetch_data_byte(destoffset);
126         srcreg = DECODE_RM_BYTE_REGISTER(rh);
127         DECODE_PRINTF("\n");
128         TRACE_AND_STEP();
129         destval = add_byte(destval, *srcreg);
130         store_data_byte(destoffset, destval);
131         break;
132     case 1:
133         destoffset = decode_rm01_address(rl);
134         DECODE_PRINTF(",");
135         destval = fetch_data_byte(destoffset);
136         srcreg = DECODE_RM_BYTE_REGISTER(rh);
137         DECODE_PRINTF("\n");
138         TRACE_AND_STEP();
139         destval = add_byte(destval, *srcreg);
140         store_data_byte(destoffset, destval);
141         break;
142     case 2:
143         destoffset = decode_rm10_address(rl);
144         DECODE_PRINTF(",");
145         destval = fetch_data_byte(destoffset);
146         srcreg = DECODE_RM_BYTE_REGISTER(rh);
147         DECODE_PRINTF("\n");
148         TRACE_AND_STEP();
149         destval = add_byte(destval, *srcreg);
150         store_data_byte(destoffset, destval);
151         break;
152     case 3:                     /* register to register */
153         destreg = DECODE_RM_BYTE_REGISTER(rl);
154         DECODE_PRINTF(",");
155         srcreg = DECODE_RM_BYTE_REGISTER(rh);
156         DECODE_PRINTF("\n");
157         TRACE_AND_STEP();
158         *destreg = add_byte(*destreg, *srcreg);
159         break;
160     }
161     DECODE_CLEAR_SEGOVR();
162     END_OF_INSTR();
163 }
164 
165 /****************************************************************************
166 REMARKS:
167 Handles opcode 0x01
168 ****************************************************************************/
x86emuOp_add_word_RM_R(u8 X86EMU_UNUSED (op1))169 void x86emuOp_add_word_RM_R(u8 X86EMU_UNUSED(op1))
170 {
171     int mod, rl, rh;
172     uint destoffset;
173 
174     START_OF_INSTR();
175     DECODE_PRINTF("ADD\t");
176     FETCH_DECODE_MODRM(mod, rh, rl);
177     switch (mod) {
178     case 0:
179         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
180             u32 destval;
181             u32 *srcreg;
182 
183             destoffset = decode_rm00_address(rl);
184             DECODE_PRINTF(",");
185             destval = fetch_data_long(destoffset);
186             srcreg = DECODE_RM_LONG_REGISTER(rh);
187             DECODE_PRINTF("\n");
188             TRACE_AND_STEP();
189             destval = add_long(destval, *srcreg);
190             store_data_long(destoffset, destval);
191         } else {
192             u16 destval;
193             u16 *srcreg;
194 
195             destoffset = decode_rm00_address(rl);
196             DECODE_PRINTF(",");
197             destval = fetch_data_word(destoffset);
198             srcreg = DECODE_RM_WORD_REGISTER(rh);
199             DECODE_PRINTF("\n");
200             TRACE_AND_STEP();
201             destval = add_word(destval, *srcreg);
202             store_data_word(destoffset, destval);
203         }
204         break;
205     case 1:
206         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
207             u32 destval;
208             u32 *srcreg;
209 
210             destoffset = decode_rm01_address(rl);
211             DECODE_PRINTF(",");
212             destval = fetch_data_long(destoffset);
213             srcreg = DECODE_RM_LONG_REGISTER(rh);
214             DECODE_PRINTF("\n");
215             TRACE_AND_STEP();
216             destval = add_long(destval, *srcreg);
217             store_data_long(destoffset, destval);
218         } else {
219             u16 destval;
220             u16 *srcreg;
221 
222             destoffset = decode_rm01_address(rl);
223             DECODE_PRINTF(",");
224             destval = fetch_data_word(destoffset);
225             srcreg = DECODE_RM_WORD_REGISTER(rh);
226             DECODE_PRINTF("\n");
227             TRACE_AND_STEP();
228             destval = add_word(destval, *srcreg);
229             store_data_word(destoffset, destval);
230         }
231         break;
232     case 2:
233         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
234             u32 destval;
235             u32 *srcreg;
236 
237             destoffset = decode_rm10_address(rl);
238             DECODE_PRINTF(",");
239             destval = fetch_data_long(destoffset);
240             srcreg = DECODE_RM_LONG_REGISTER(rh);
241             DECODE_PRINTF("\n");
242             TRACE_AND_STEP();
243             destval = add_long(destval, *srcreg);
244             store_data_long(destoffset, destval);
245         } else {
246             u16 destval;
247             u16 *srcreg;
248 
249             destoffset = decode_rm10_address(rl);
250             DECODE_PRINTF(",");
251             destval = fetch_data_word(destoffset);
252             srcreg = DECODE_RM_WORD_REGISTER(rh);
253             DECODE_PRINTF("\n");
254             TRACE_AND_STEP();
255             destval = add_word(destval, *srcreg);
256             store_data_word(destoffset, destval);
257         }
258         break;
259     case 3:                     /* register to register */
260         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
261             u32 *destreg,*srcreg;
262 
263             destreg = DECODE_RM_LONG_REGISTER(rl);
264             DECODE_PRINTF(",");
265             srcreg = DECODE_RM_LONG_REGISTER(rh);
266             DECODE_PRINTF("\n");
267             TRACE_AND_STEP();
268             *destreg = add_long(*destreg, *srcreg);
269         } else {
270             u16 *destreg,*srcreg;
271 
272             destreg = DECODE_RM_WORD_REGISTER(rl);
273             DECODE_PRINTF(",");
274             srcreg = DECODE_RM_WORD_REGISTER(rh);
275             DECODE_PRINTF("\n");
276             TRACE_AND_STEP();
277             *destreg = add_word(*destreg, *srcreg);
278         }
279         break;
280     }
281     DECODE_CLEAR_SEGOVR();
282     END_OF_INSTR();
283 }
284 
285 /****************************************************************************
286 REMARKS:
287 Handles opcode 0x02
288 ****************************************************************************/
x86emuOp_add_byte_R_RM(u8 X86EMU_UNUSED (op1))289 void x86emuOp_add_byte_R_RM(u8 X86EMU_UNUSED(op1))
290 {
291     int mod, rl, rh;
292     u8 *destreg, *srcreg;
293     uint srcoffset;
294     u8 srcval;
295 
296     START_OF_INSTR();
297     DECODE_PRINTF("ADD\t");
298     FETCH_DECODE_MODRM(mod, rh, rl);
299     switch (mod) {
300     case 0:
301         destreg = DECODE_RM_BYTE_REGISTER(rh);
302         DECODE_PRINTF(",");
303         srcoffset = decode_rm00_address(rl);
304         srcval = fetch_data_byte(srcoffset);
305         DECODE_PRINTF("\n");
306         TRACE_AND_STEP();
307         *destreg = add_byte(*destreg, srcval);
308         break;
309     case 1:
310         destreg = DECODE_RM_BYTE_REGISTER(rh);
311         DECODE_PRINTF(",");
312         srcoffset = decode_rm01_address(rl);
313         srcval = fetch_data_byte(srcoffset);
314         DECODE_PRINTF("\n");
315         TRACE_AND_STEP();
316         *destreg = add_byte(*destreg, srcval);
317         break;
318     case 2:
319         destreg = DECODE_RM_BYTE_REGISTER(rh);
320         DECODE_PRINTF(",");
321         srcoffset = decode_rm10_address(rl);
322         srcval = fetch_data_byte(srcoffset);
323         DECODE_PRINTF("\n");
324         TRACE_AND_STEP();
325         *destreg = add_byte(*destreg, srcval);
326         break;
327     case 3:                     /* register to register */
328         destreg = DECODE_RM_BYTE_REGISTER(rh);
329         DECODE_PRINTF(",");
330         srcreg = DECODE_RM_BYTE_REGISTER(rl);
331         DECODE_PRINTF("\n");
332         TRACE_AND_STEP();
333         *destreg = add_byte(*destreg, *srcreg);
334         break;
335     }
336     DECODE_CLEAR_SEGOVR();
337     END_OF_INSTR();
338 }
339 
340 /****************************************************************************
341 REMARKS:
342 Handles opcode 0x03
343 ****************************************************************************/
x86emuOp_add_word_R_RM(u8 X86EMU_UNUSED (op1))344 void x86emuOp_add_word_R_RM(u8 X86EMU_UNUSED(op1))
345 {
346     int mod, rl, rh;
347     uint srcoffset;
348 
349     START_OF_INSTR();
350     DECODE_PRINTF("ADD\t");
351     FETCH_DECODE_MODRM(mod, rh, rl);
352     switch (mod) {
353     case 0:
354         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
355             u32 *destreg;
356             u32 srcval;
357 
358             destreg = DECODE_RM_LONG_REGISTER(rh);
359             DECODE_PRINTF(",");
360             srcoffset = decode_rm00_address(rl);
361             srcval = fetch_data_long(srcoffset);
362             DECODE_PRINTF("\n");
363             TRACE_AND_STEP();
364             *destreg = add_long(*destreg, srcval);
365         } else {
366             u16 *destreg;
367             u16 srcval;
368 
369             destreg = DECODE_RM_WORD_REGISTER(rh);
370             DECODE_PRINTF(",");
371             srcoffset = decode_rm00_address(rl);
372             srcval = fetch_data_word(srcoffset);
373             DECODE_PRINTF("\n");
374             TRACE_AND_STEP();
375             *destreg = add_word(*destreg, srcval);
376         }
377         break;
378     case 1:
379         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
380             u32 *destreg;
381             u32 srcval;
382 
383             destreg = DECODE_RM_LONG_REGISTER(rh);
384             DECODE_PRINTF(",");
385             srcoffset = decode_rm01_address(rl);
386             srcval = fetch_data_long(srcoffset);
387             DECODE_PRINTF("\n");
388             TRACE_AND_STEP();
389             *destreg = add_long(*destreg, srcval);
390         } else {
391             u16 *destreg;
392             u16 srcval;
393 
394             destreg = DECODE_RM_WORD_REGISTER(rh);
395             DECODE_PRINTF(",");
396             srcoffset = decode_rm01_address(rl);
397             srcval = fetch_data_word(srcoffset);
398             DECODE_PRINTF("\n");
399             TRACE_AND_STEP();
400             *destreg = add_word(*destreg, srcval);
401         }
402         break;
403     case 2:
404         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
405             u32 *destreg;
406             u32 srcval;
407 
408             destreg = DECODE_RM_LONG_REGISTER(rh);
409             DECODE_PRINTF(",");
410             srcoffset = decode_rm10_address(rl);
411             srcval = fetch_data_long(srcoffset);
412             DECODE_PRINTF("\n");
413             TRACE_AND_STEP();
414             *destreg = add_long(*destreg, srcval);
415         } else {
416             u16 *destreg;
417             u16 srcval;
418 
419             destreg = DECODE_RM_WORD_REGISTER(rh);
420             DECODE_PRINTF(",");
421             srcoffset = decode_rm10_address(rl);
422             srcval = fetch_data_word(srcoffset);
423             DECODE_PRINTF("\n");
424             TRACE_AND_STEP();
425             *destreg = add_word(*destreg, srcval);
426         }
427         break;
428     case 3:                     /* register to register */
429         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
430             u32 *destreg,*srcreg;
431 
432             destreg = DECODE_RM_LONG_REGISTER(rh);
433             DECODE_PRINTF(",");
434             srcreg = DECODE_RM_LONG_REGISTER(rl);
435             DECODE_PRINTF("\n");
436             TRACE_AND_STEP();
437             *destreg = add_long(*destreg, *srcreg);
438         } else {
439             u16 *destreg,*srcreg;
440 
441             destreg = DECODE_RM_WORD_REGISTER(rh);
442             DECODE_PRINTF(",");
443             srcreg = DECODE_RM_WORD_REGISTER(rl);
444             DECODE_PRINTF("\n");
445             TRACE_AND_STEP();
446             *destreg = add_word(*destreg, *srcreg);
447         }
448         break;
449     }
450     DECODE_CLEAR_SEGOVR();
451     END_OF_INSTR();
452 }
453 
454 /****************************************************************************
455 REMARKS:
456 Handles opcode 0x04
457 ****************************************************************************/
x86emuOp_add_byte_AL_IMM(u8 X86EMU_UNUSED (op1))458 void x86emuOp_add_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
459 {
460     u8 srcval;
461 
462     START_OF_INSTR();
463     DECODE_PRINTF("ADD\tAL,");
464     srcval = fetch_byte_imm();
465     DECODE_PRINTF2("%x\n", srcval);
466     TRACE_AND_STEP();
467     M.x86.R_AL = add_byte(M.x86.R_AL, srcval);
468     DECODE_CLEAR_SEGOVR();
469     END_OF_INSTR();
470 }
471 
472 /****************************************************************************
473 REMARKS:
474 Handles opcode 0x05
475 ****************************************************************************/
x86emuOp_add_word_AX_IMM(u8 X86EMU_UNUSED (op1))476 void x86emuOp_add_word_AX_IMM(u8 X86EMU_UNUSED(op1))
477 {
478     u32 srcval;
479 
480     START_OF_INSTR();
481     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
482         DECODE_PRINTF("ADD\tEAX,");
483         srcval = fetch_long_imm();
484     } else {
485         DECODE_PRINTF("ADD\tAX,");
486         srcval = fetch_word_imm();
487     }
488     DECODE_PRINTF2("%x\n", srcval);
489     TRACE_AND_STEP();
490     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
491         M.x86.R_EAX = add_long(M.x86.R_EAX, srcval);
492     } else {
493         M.x86.R_AX = add_word(M.x86.R_AX, (u16)srcval);
494     }
495     DECODE_CLEAR_SEGOVR();
496     END_OF_INSTR();
497 }
498 
499 /****************************************************************************
500 REMARKS:
501 Handles opcode 0x06
502 ****************************************************************************/
x86emuOp_push_ES(u8 X86EMU_UNUSED (op1))503 void x86emuOp_push_ES(u8 X86EMU_UNUSED(op1))
504 {
505     START_OF_INSTR();
506     DECODE_PRINTF("PUSH\tES\n");
507     TRACE_AND_STEP();
508     push_word(M.x86.R_ES);
509     DECODE_CLEAR_SEGOVR();
510     END_OF_INSTR();
511 }
512 
513 /****************************************************************************
514 REMARKS:
515 Handles opcode 0x07
516 ****************************************************************************/
x86emuOp_pop_ES(u8 X86EMU_UNUSED (op1))517 void x86emuOp_pop_ES(u8 X86EMU_UNUSED(op1))
518 {
519     START_OF_INSTR();
520     DECODE_PRINTF("POP\tES\n");
521     TRACE_AND_STEP();
522     M.x86.R_ES = pop_word();
523     DECODE_CLEAR_SEGOVR();
524     END_OF_INSTR();
525 }
526 
527 /****************************************************************************
528 REMARKS:
529 Handles opcode 0x08
530 ****************************************************************************/
x86emuOp_or_byte_RM_R(u8 X86EMU_UNUSED (op1))531 void x86emuOp_or_byte_RM_R(u8 X86EMU_UNUSED(op1))
532 {
533     int mod, rl, rh;
534     u8 *destreg, *srcreg;
535     uint destoffset;
536     u8 destval;
537 
538     START_OF_INSTR();
539     DECODE_PRINTF("OR\t");
540     FETCH_DECODE_MODRM(mod, rh, rl);
541     switch (mod) {
542     case 0:
543         destoffset = decode_rm00_address(rl);
544         DECODE_PRINTF(",");
545         destval = fetch_data_byte(destoffset);
546         srcreg = DECODE_RM_BYTE_REGISTER(rh);
547         DECODE_PRINTF("\n");
548         TRACE_AND_STEP();
549         destval = or_byte(destval, *srcreg);
550         store_data_byte(destoffset, destval);
551         break;
552     case 1:
553         destoffset = decode_rm01_address(rl);
554         DECODE_PRINTF(",");
555         destval = fetch_data_byte(destoffset);
556         srcreg = DECODE_RM_BYTE_REGISTER(rh);
557         DECODE_PRINTF("\n");
558         TRACE_AND_STEP();
559         destval = or_byte(destval, *srcreg);
560         store_data_byte(destoffset, destval);
561         break;
562     case 2:
563         destoffset = decode_rm10_address(rl);
564         DECODE_PRINTF(",");
565         destval = fetch_data_byte(destoffset);
566         srcreg = DECODE_RM_BYTE_REGISTER(rh);
567         DECODE_PRINTF("\n");
568         TRACE_AND_STEP();
569         destval = or_byte(destval, *srcreg);
570         store_data_byte(destoffset, destval);
571         break;
572     case 3:                     /* register to register */
573         destreg = DECODE_RM_BYTE_REGISTER(rl);
574         DECODE_PRINTF(",");
575         srcreg = DECODE_RM_BYTE_REGISTER(rh);
576         DECODE_PRINTF("\n");
577         TRACE_AND_STEP();
578         *destreg = or_byte(*destreg, *srcreg);
579         break;
580     }
581     DECODE_CLEAR_SEGOVR();
582     END_OF_INSTR();
583 }
584 
585 /****************************************************************************
586 REMARKS:
587 Handles opcode 0x09
588 ****************************************************************************/
x86emuOp_or_word_RM_R(u8 X86EMU_UNUSED (op1))589 void x86emuOp_or_word_RM_R(u8 X86EMU_UNUSED(op1))
590 {
591     int mod, rl, rh;
592     uint destoffset;
593 
594     START_OF_INSTR();
595     DECODE_PRINTF("OR\t");
596     FETCH_DECODE_MODRM(mod, rh, rl);
597     switch (mod) {
598     case 0:
599         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
600             u32 destval;
601             u32 *srcreg;
602 
603             destoffset = decode_rm00_address(rl);
604             DECODE_PRINTF(",");
605             destval = fetch_data_long(destoffset);
606             srcreg = DECODE_RM_LONG_REGISTER(rh);
607             DECODE_PRINTF("\n");
608             TRACE_AND_STEP();
609             destval = or_long(destval, *srcreg);
610             store_data_long(destoffset, destval);
611         } else {
612             u16 destval;
613             u16 *srcreg;
614 
615             destoffset = decode_rm00_address(rl);
616             DECODE_PRINTF(",");
617             destval = fetch_data_word(destoffset);
618             srcreg = DECODE_RM_WORD_REGISTER(rh);
619             DECODE_PRINTF("\n");
620             TRACE_AND_STEP();
621             destval = or_word(destval, *srcreg);
622             store_data_word(destoffset, destval);
623         }
624         break;
625     case 1:
626         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
627             u32 destval;
628             u32 *srcreg;
629 
630             destoffset = decode_rm01_address(rl);
631             DECODE_PRINTF(",");
632             destval = fetch_data_long(destoffset);
633             srcreg = DECODE_RM_LONG_REGISTER(rh);
634             DECODE_PRINTF("\n");
635             TRACE_AND_STEP();
636             destval = or_long(destval, *srcreg);
637             store_data_long(destoffset, destval);
638         } else {
639             u16 destval;
640             u16 *srcreg;
641 
642             destoffset = decode_rm01_address(rl);
643             DECODE_PRINTF(",");
644             destval = fetch_data_word(destoffset);
645             srcreg = DECODE_RM_WORD_REGISTER(rh);
646             DECODE_PRINTF("\n");
647             TRACE_AND_STEP();
648             destval = or_word(destval, *srcreg);
649             store_data_word(destoffset, destval);
650         }
651         break;
652     case 2:
653         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
654             u32 destval;
655             u32 *srcreg;
656 
657             destoffset = decode_rm10_address(rl);
658             DECODE_PRINTF(",");
659             destval = fetch_data_long(destoffset);
660             srcreg = DECODE_RM_LONG_REGISTER(rh);
661             DECODE_PRINTF("\n");
662             TRACE_AND_STEP();
663             destval = or_long(destval, *srcreg);
664             store_data_long(destoffset, destval);
665         } else {
666             u16 destval;
667             u16 *srcreg;
668 
669             destoffset = decode_rm10_address(rl);
670             DECODE_PRINTF(",");
671             destval = fetch_data_word(destoffset);
672             srcreg = DECODE_RM_WORD_REGISTER(rh);
673             DECODE_PRINTF("\n");
674             TRACE_AND_STEP();
675             destval = or_word(destval, *srcreg);
676             store_data_word(destoffset, destval);
677         }
678         break;
679     case 3:                     /* register to register */
680         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
681             u32 *destreg,*srcreg;
682 
683             destreg = DECODE_RM_LONG_REGISTER(rl);
684             DECODE_PRINTF(",");
685             srcreg = DECODE_RM_LONG_REGISTER(rh);
686             DECODE_PRINTF("\n");
687             TRACE_AND_STEP();
688             *destreg = or_long(*destreg, *srcreg);
689         } else {
690             u16 *destreg,*srcreg;
691 
692             destreg = DECODE_RM_WORD_REGISTER(rl);
693             DECODE_PRINTF(",");
694             srcreg = DECODE_RM_WORD_REGISTER(rh);
695             DECODE_PRINTF("\n");
696             TRACE_AND_STEP();
697             *destreg = or_word(*destreg, *srcreg);
698         }
699         break;
700     }
701     DECODE_CLEAR_SEGOVR();
702     END_OF_INSTR();
703 }
704 
705 /****************************************************************************
706 REMARKS:
707 Handles opcode 0x0a
708 ****************************************************************************/
x86emuOp_or_byte_R_RM(u8 X86EMU_UNUSED (op1))709 void x86emuOp_or_byte_R_RM(u8 X86EMU_UNUSED(op1))
710 {
711     int mod, rl, rh;
712     u8 *destreg, *srcreg;
713     uint srcoffset;
714     u8 srcval;
715 
716     START_OF_INSTR();
717     DECODE_PRINTF("OR\t");
718     FETCH_DECODE_MODRM(mod, rh, rl);
719     switch (mod) {
720     case 0:
721         destreg = DECODE_RM_BYTE_REGISTER(rh);
722         DECODE_PRINTF(",");
723         srcoffset = decode_rm00_address(rl);
724         srcval = fetch_data_byte(srcoffset);
725         DECODE_PRINTF("\n");
726         TRACE_AND_STEP();
727         *destreg = or_byte(*destreg, srcval);
728         break;
729     case 1:
730         destreg = DECODE_RM_BYTE_REGISTER(rh);
731         DECODE_PRINTF(",");
732         srcoffset = decode_rm01_address(rl);
733         srcval = fetch_data_byte(srcoffset);
734         DECODE_PRINTF("\n");
735         TRACE_AND_STEP();
736         *destreg = or_byte(*destreg, srcval);
737         break;
738     case 2:
739         destreg = DECODE_RM_BYTE_REGISTER(rh);
740         DECODE_PRINTF(",");
741         srcoffset = decode_rm10_address(rl);
742         srcval = fetch_data_byte(srcoffset);
743         DECODE_PRINTF("\n");
744         TRACE_AND_STEP();
745         *destreg = or_byte(*destreg, srcval);
746         break;
747     case 3:                     /* register to register */
748         destreg = DECODE_RM_BYTE_REGISTER(rh);
749         DECODE_PRINTF(",");
750         srcreg = DECODE_RM_BYTE_REGISTER(rl);
751         DECODE_PRINTF("\n");
752         TRACE_AND_STEP();
753         *destreg = or_byte(*destreg, *srcreg);
754         break;
755     }
756     DECODE_CLEAR_SEGOVR();
757     END_OF_INSTR();
758 }
759 
760 /****************************************************************************
761 REMARKS:
762 Handles opcode 0x0b
763 ****************************************************************************/
x86emuOp_or_word_R_RM(u8 X86EMU_UNUSED (op1))764 void x86emuOp_or_word_R_RM(u8 X86EMU_UNUSED(op1))
765 {
766     int mod, rl, rh;
767     uint srcoffset;
768 
769     START_OF_INSTR();
770     DECODE_PRINTF("OR\t");
771     FETCH_DECODE_MODRM(mod, rh, rl);
772     switch (mod) {
773     case 0:
774         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
775             u32 *destreg;
776             u32 srcval;
777 
778             destreg = DECODE_RM_LONG_REGISTER(rh);
779             DECODE_PRINTF(",");
780             srcoffset = decode_rm00_address(rl);
781             srcval = fetch_data_long(srcoffset);
782             DECODE_PRINTF("\n");
783             TRACE_AND_STEP();
784             *destreg = or_long(*destreg, srcval);
785         } else {
786             u16 *destreg;
787             u16 srcval;
788 
789             destreg = DECODE_RM_WORD_REGISTER(rh);
790             DECODE_PRINTF(",");
791             srcoffset = decode_rm00_address(rl);
792             srcval = fetch_data_word(srcoffset);
793             DECODE_PRINTF("\n");
794             TRACE_AND_STEP();
795             *destreg = or_word(*destreg, srcval);
796         }
797         break;
798     case 1:
799         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
800             u32 *destreg;
801             u32 srcval;
802 
803             destreg = DECODE_RM_LONG_REGISTER(rh);
804             DECODE_PRINTF(",");
805             srcoffset = decode_rm01_address(rl);
806             srcval = fetch_data_long(srcoffset);
807             DECODE_PRINTF("\n");
808             TRACE_AND_STEP();
809             *destreg = or_long(*destreg, srcval);
810         } else {
811             u16 *destreg;
812             u16 srcval;
813 
814             destreg = DECODE_RM_WORD_REGISTER(rh);
815             DECODE_PRINTF(",");
816             srcoffset = decode_rm01_address(rl);
817             srcval = fetch_data_word(srcoffset);
818             DECODE_PRINTF("\n");
819             TRACE_AND_STEP();
820             *destreg = or_word(*destreg, srcval);
821         }
822         break;
823     case 2:
824         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
825             u32 *destreg;
826             u32 srcval;
827 
828             destreg = DECODE_RM_LONG_REGISTER(rh);
829             DECODE_PRINTF(",");
830             srcoffset = decode_rm10_address(rl);
831             srcval = fetch_data_long(srcoffset);
832             DECODE_PRINTF("\n");
833             TRACE_AND_STEP();
834             *destreg = or_long(*destreg, srcval);
835         } else {
836             u16 *destreg;
837             u16 srcval;
838 
839             destreg = DECODE_RM_WORD_REGISTER(rh);
840             DECODE_PRINTF(",");
841             srcoffset = decode_rm10_address(rl);
842             srcval = fetch_data_word(srcoffset);
843             DECODE_PRINTF("\n");
844             TRACE_AND_STEP();
845             *destreg = or_word(*destreg, srcval);
846         }
847         break;
848     case 3:                     /* register to register */
849         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
850             u32 *destreg,*srcreg;
851 
852             destreg = DECODE_RM_LONG_REGISTER(rh);
853             DECODE_PRINTF(",");
854             srcreg = DECODE_RM_LONG_REGISTER(rl);
855             DECODE_PRINTF("\n");
856             TRACE_AND_STEP();
857             *destreg = or_long(*destreg, *srcreg);
858         } else {
859             u16 *destreg,*srcreg;
860 
861             destreg = DECODE_RM_WORD_REGISTER(rh);
862             DECODE_PRINTF(",");
863             srcreg = DECODE_RM_WORD_REGISTER(rl);
864             DECODE_PRINTF("\n");
865             TRACE_AND_STEP();
866             *destreg = or_word(*destreg, *srcreg);
867         }
868         break;
869     }
870     DECODE_CLEAR_SEGOVR();
871     END_OF_INSTR();
872 }
873 
874 /****************************************************************************
875 REMARKS:
876 Handles opcode 0x0c
877 ****************************************************************************/
x86emuOp_or_byte_AL_IMM(u8 X86EMU_UNUSED (op1))878 void x86emuOp_or_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
879 {
880     u8 srcval;
881 
882     START_OF_INSTR();
883     DECODE_PRINTF("OR\tAL,");
884     srcval = fetch_byte_imm();
885     DECODE_PRINTF2("%x\n", srcval);
886     TRACE_AND_STEP();
887     M.x86.R_AL = or_byte(M.x86.R_AL, srcval);
888     DECODE_CLEAR_SEGOVR();
889     END_OF_INSTR();
890 }
891 
892 /****************************************************************************
893 REMARKS:
894 Handles opcode 0x0d
895 ****************************************************************************/
x86emuOp_or_word_AX_IMM(u8 X86EMU_UNUSED (op1))896 void x86emuOp_or_word_AX_IMM(u8 X86EMU_UNUSED(op1))
897 {
898     u32 srcval;
899 
900     START_OF_INSTR();
901     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
902         DECODE_PRINTF("OR\tEAX,");
903         srcval = fetch_long_imm();
904     } else {
905         DECODE_PRINTF("OR\tAX,");
906         srcval = fetch_word_imm();
907     }
908     DECODE_PRINTF2("%x\n", srcval);
909     TRACE_AND_STEP();
910     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
911         M.x86.R_EAX = or_long(M.x86.R_EAX, srcval);
912     } else {
913         M.x86.R_AX = or_word(M.x86.R_AX, (u16)srcval);
914     }
915     DECODE_CLEAR_SEGOVR();
916     END_OF_INSTR();
917 }
918 
919 /****************************************************************************
920 REMARKS:
921 Handles opcode 0x0e
922 ****************************************************************************/
x86emuOp_push_CS(u8 X86EMU_UNUSED (op1))923 void x86emuOp_push_CS(u8 X86EMU_UNUSED(op1))
924 {
925     START_OF_INSTR();
926     DECODE_PRINTF("PUSH\tCS\n");
927     TRACE_AND_STEP();
928     push_word(M.x86.R_CS);
929     DECODE_CLEAR_SEGOVR();
930     END_OF_INSTR();
931 }
932 
933 /****************************************************************************
934 REMARKS:
935 Handles opcode 0x0f. Escape for two-byte opcode (286 or better)
936 ****************************************************************************/
x86emuOp_two_byte(u8 X86EMU_UNUSED (op1))937 void x86emuOp_two_byte(u8 X86EMU_UNUSED(op1))
938 {
939     u8 op2 = (*sys_rdb)(((u32)M.x86.R_CS << 4) + (M.x86.R_IP++));
940     INC_DECODED_INST_LEN(1);
941     (*x86emu_optab2[op2])(op2);
942 }
943 
944 /****************************************************************************
945 REMARKS:
946 Handles opcode 0x10
947 ****************************************************************************/
x86emuOp_adc_byte_RM_R(u8 X86EMU_UNUSED (op1))948 void x86emuOp_adc_byte_RM_R(u8 X86EMU_UNUSED(op1))
949 {
950     int mod, rl, rh;
951     u8 *destreg, *srcreg;
952     uint destoffset;
953     u8 destval;
954 
955     START_OF_INSTR();
956     DECODE_PRINTF("ADC\t");
957     FETCH_DECODE_MODRM(mod, rh, rl);
958     switch (mod) {
959     case 0:
960         destoffset = decode_rm00_address(rl);
961         DECODE_PRINTF(",");
962         destval = fetch_data_byte(destoffset);
963         srcreg = DECODE_RM_BYTE_REGISTER(rh);
964         DECODE_PRINTF("\n");
965         TRACE_AND_STEP();
966         destval = adc_byte(destval, *srcreg);
967         store_data_byte(destoffset, destval);
968         break;
969     case 1:
970         destoffset = decode_rm01_address(rl);
971         DECODE_PRINTF(",");
972         destval = fetch_data_byte(destoffset);
973         srcreg = DECODE_RM_BYTE_REGISTER(rh);
974         DECODE_PRINTF("\n");
975         TRACE_AND_STEP();
976         destval = adc_byte(destval, *srcreg);
977         store_data_byte(destoffset, destval);
978         break;
979     case 2:
980         destoffset = decode_rm10_address(rl);
981         DECODE_PRINTF(",");
982         destval = fetch_data_byte(destoffset);
983         srcreg = DECODE_RM_BYTE_REGISTER(rh);
984         DECODE_PRINTF("\n");
985         TRACE_AND_STEP();
986         destval = adc_byte(destval, *srcreg);
987         store_data_byte(destoffset, destval);
988         break;
989     case 3:                     /* register to register */
990         destreg = DECODE_RM_BYTE_REGISTER(rl);
991         DECODE_PRINTF(",");
992         srcreg = DECODE_RM_BYTE_REGISTER(rh);
993         DECODE_PRINTF("\n");
994         TRACE_AND_STEP();
995         *destreg = adc_byte(*destreg, *srcreg);
996         break;
997     }
998     DECODE_CLEAR_SEGOVR();
999     END_OF_INSTR();
1000 }
1001 
1002 /****************************************************************************
1003 REMARKS:
1004 Handles opcode 0x11
1005 ****************************************************************************/
x86emuOp_adc_word_RM_R(u8 X86EMU_UNUSED (op1))1006 void x86emuOp_adc_word_RM_R(u8 X86EMU_UNUSED(op1))
1007 {
1008     int mod, rl, rh;
1009     uint destoffset;
1010 
1011     START_OF_INSTR();
1012     DECODE_PRINTF("ADC\t");
1013     FETCH_DECODE_MODRM(mod, rh, rl);
1014     switch (mod) {
1015     case 0:
1016         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1017             u32 destval;
1018             u32 *srcreg;
1019 
1020             destoffset = decode_rm00_address(rl);
1021             DECODE_PRINTF(",");
1022             destval = fetch_data_long(destoffset);
1023             srcreg = DECODE_RM_LONG_REGISTER(rh);
1024             DECODE_PRINTF("\n");
1025             TRACE_AND_STEP();
1026             destval = adc_long(destval, *srcreg);
1027             store_data_long(destoffset, destval);
1028         } else {
1029             u16 destval;
1030             u16 *srcreg;
1031 
1032             destoffset = decode_rm00_address(rl);
1033             DECODE_PRINTF(",");
1034             destval = fetch_data_word(destoffset);
1035             srcreg = DECODE_RM_WORD_REGISTER(rh);
1036             DECODE_PRINTF("\n");
1037             TRACE_AND_STEP();
1038             destval = adc_word(destval, *srcreg);
1039             store_data_word(destoffset, destval);
1040         }
1041         break;
1042     case 1:
1043         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1044             u32 destval;
1045             u32 *srcreg;
1046 
1047             destoffset = decode_rm01_address(rl);
1048             DECODE_PRINTF(",");
1049             destval = fetch_data_long(destoffset);
1050             srcreg = DECODE_RM_LONG_REGISTER(rh);
1051             DECODE_PRINTF("\n");
1052             TRACE_AND_STEP();
1053             destval = adc_long(destval, *srcreg);
1054             store_data_long(destoffset, destval);
1055         } else {
1056             u16 destval;
1057             u16 *srcreg;
1058 
1059             destoffset = decode_rm01_address(rl);
1060             DECODE_PRINTF(",");
1061             destval = fetch_data_word(destoffset);
1062             srcreg = DECODE_RM_WORD_REGISTER(rh);
1063             DECODE_PRINTF("\n");
1064             TRACE_AND_STEP();
1065             destval = adc_word(destval, *srcreg);
1066             store_data_word(destoffset, destval);
1067         }
1068         break;
1069     case 2:
1070         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1071             u32 destval;
1072             u32 *srcreg;
1073 
1074             destoffset = decode_rm10_address(rl);
1075             DECODE_PRINTF(",");
1076             destval = fetch_data_long(destoffset);
1077             srcreg = DECODE_RM_LONG_REGISTER(rh);
1078             DECODE_PRINTF("\n");
1079             TRACE_AND_STEP();
1080             destval = adc_long(destval, *srcreg);
1081             store_data_long(destoffset, destval);
1082         } else {
1083             u16 destval;
1084             u16 *srcreg;
1085 
1086             destoffset = decode_rm10_address(rl);
1087             DECODE_PRINTF(",");
1088             destval = fetch_data_word(destoffset);
1089             srcreg = DECODE_RM_WORD_REGISTER(rh);
1090             DECODE_PRINTF("\n");
1091             TRACE_AND_STEP();
1092             destval = adc_word(destval, *srcreg);
1093             store_data_word(destoffset, destval);
1094         }
1095         break;
1096     case 3:                     /* register to register */
1097         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1098             u32 *destreg,*srcreg;
1099 
1100             destreg = DECODE_RM_LONG_REGISTER(rl);
1101             DECODE_PRINTF(",");
1102             srcreg = DECODE_RM_LONG_REGISTER(rh);
1103             DECODE_PRINTF("\n");
1104             TRACE_AND_STEP();
1105             *destreg = adc_long(*destreg, *srcreg);
1106         } else {
1107             u16 *destreg,*srcreg;
1108 
1109             destreg = DECODE_RM_WORD_REGISTER(rl);
1110             DECODE_PRINTF(",");
1111             srcreg = DECODE_RM_WORD_REGISTER(rh);
1112             DECODE_PRINTF("\n");
1113             TRACE_AND_STEP();
1114             *destreg = adc_word(*destreg, *srcreg);
1115         }
1116         break;
1117     }
1118     DECODE_CLEAR_SEGOVR();
1119     END_OF_INSTR();
1120 }
1121 
1122 /****************************************************************************
1123 REMARKS:
1124 Handles opcode 0x12
1125 ****************************************************************************/
x86emuOp_adc_byte_R_RM(u8 X86EMU_UNUSED (op1))1126 void x86emuOp_adc_byte_R_RM(u8 X86EMU_UNUSED(op1))
1127 {
1128     int mod, rl, rh;
1129     u8 *destreg, *srcreg;
1130     uint srcoffset;
1131     u8 srcval;
1132 
1133     START_OF_INSTR();
1134     DECODE_PRINTF("ADC\t");
1135     FETCH_DECODE_MODRM(mod, rh, rl);
1136     switch (mod) {
1137     case 0:
1138         destreg = DECODE_RM_BYTE_REGISTER(rh);
1139         DECODE_PRINTF(",");
1140         srcoffset = decode_rm00_address(rl);
1141         srcval = fetch_data_byte(srcoffset);
1142         DECODE_PRINTF("\n");
1143         TRACE_AND_STEP();
1144         *destreg = adc_byte(*destreg, srcval);
1145         break;
1146     case 1:
1147         destreg = DECODE_RM_BYTE_REGISTER(rh);
1148         DECODE_PRINTF(",");
1149         srcoffset = decode_rm01_address(rl);
1150         srcval = fetch_data_byte(srcoffset);
1151         DECODE_PRINTF("\n");
1152         TRACE_AND_STEP();
1153         *destreg = adc_byte(*destreg, srcval);
1154         break;
1155     case 2:
1156         destreg = DECODE_RM_BYTE_REGISTER(rh);
1157         DECODE_PRINTF(",");
1158         srcoffset = decode_rm10_address(rl);
1159         srcval = fetch_data_byte(srcoffset);
1160         DECODE_PRINTF("\n");
1161         TRACE_AND_STEP();
1162         *destreg = adc_byte(*destreg, srcval);
1163         break;
1164     case 3:                     /* register to register */
1165         destreg = DECODE_RM_BYTE_REGISTER(rh);
1166         DECODE_PRINTF(",");
1167         srcreg = DECODE_RM_BYTE_REGISTER(rl);
1168         DECODE_PRINTF("\n");
1169         TRACE_AND_STEP();
1170         *destreg = adc_byte(*destreg, *srcreg);
1171         break;
1172     }
1173     DECODE_CLEAR_SEGOVR();
1174     END_OF_INSTR();
1175 }
1176 
1177 /****************************************************************************
1178 REMARKS:
1179 Handles opcode 0x13
1180 ****************************************************************************/
x86emuOp_adc_word_R_RM(u8 X86EMU_UNUSED (op1))1181 void x86emuOp_adc_word_R_RM(u8 X86EMU_UNUSED(op1))
1182 {
1183     int mod, rl, rh;
1184     uint srcoffset;
1185 
1186     START_OF_INSTR();
1187     DECODE_PRINTF("ADC\t");
1188     FETCH_DECODE_MODRM(mod, rh, rl);
1189     switch (mod) {
1190     case 0:
1191         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1192             u32 *destreg;
1193             u32 srcval;
1194 
1195             destreg = DECODE_RM_LONG_REGISTER(rh);
1196             DECODE_PRINTF(",");
1197             srcoffset = decode_rm00_address(rl);
1198             srcval = fetch_data_long(srcoffset);
1199             DECODE_PRINTF("\n");
1200             TRACE_AND_STEP();
1201             *destreg = adc_long(*destreg, srcval);
1202         } else {
1203             u16 *destreg;
1204             u16 srcval;
1205 
1206             destreg = DECODE_RM_WORD_REGISTER(rh);
1207             DECODE_PRINTF(",");
1208             srcoffset = decode_rm00_address(rl);
1209             srcval = fetch_data_word(srcoffset);
1210             DECODE_PRINTF("\n");
1211             TRACE_AND_STEP();
1212             *destreg = adc_word(*destreg, srcval);
1213         }
1214         break;
1215     case 1:
1216         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1217             u32 *destreg;
1218             u32 srcval;
1219 
1220             destreg = DECODE_RM_LONG_REGISTER(rh);
1221             DECODE_PRINTF(",");
1222             srcoffset = decode_rm01_address(rl);
1223             srcval = fetch_data_long(srcoffset);
1224             DECODE_PRINTF("\n");
1225             TRACE_AND_STEP();
1226             *destreg = adc_long(*destreg, srcval);
1227         } else {
1228             u16 *destreg;
1229             u16 srcval;
1230 
1231             destreg = DECODE_RM_WORD_REGISTER(rh);
1232             DECODE_PRINTF(",");
1233             srcoffset = decode_rm01_address(rl);
1234             srcval = fetch_data_word(srcoffset);
1235             DECODE_PRINTF("\n");
1236             TRACE_AND_STEP();
1237             *destreg = adc_word(*destreg, srcval);
1238         }
1239         break;
1240     case 2:
1241         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1242             u32 *destreg;
1243             u32 srcval;
1244 
1245             destreg = DECODE_RM_LONG_REGISTER(rh);
1246             DECODE_PRINTF(",");
1247             srcoffset = decode_rm10_address(rl);
1248             srcval = fetch_data_long(srcoffset);
1249             DECODE_PRINTF("\n");
1250             TRACE_AND_STEP();
1251             *destreg = adc_long(*destreg, srcval);
1252         } else {
1253             u16 *destreg;
1254             u16 srcval;
1255 
1256             destreg = DECODE_RM_WORD_REGISTER(rh);
1257             DECODE_PRINTF(",");
1258             srcoffset = decode_rm10_address(rl);
1259             srcval = fetch_data_word(srcoffset);
1260             DECODE_PRINTF("\n");
1261             TRACE_AND_STEP();
1262             *destreg = adc_word(*destreg, srcval);
1263         }
1264         break;
1265     case 3:                     /* register to register */
1266         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1267             u32 *destreg,*srcreg;
1268 
1269             destreg = DECODE_RM_LONG_REGISTER(rh);
1270             DECODE_PRINTF(",");
1271             srcreg = DECODE_RM_LONG_REGISTER(rl);
1272             DECODE_PRINTF("\n");
1273             TRACE_AND_STEP();
1274             *destreg = adc_long(*destreg, *srcreg);
1275         } else {
1276             u16 *destreg,*srcreg;
1277 
1278             destreg = DECODE_RM_WORD_REGISTER(rh);
1279             DECODE_PRINTF(",");
1280             srcreg = DECODE_RM_WORD_REGISTER(rl);
1281             DECODE_PRINTF("\n");
1282             TRACE_AND_STEP();
1283             *destreg = adc_word(*destreg, *srcreg);
1284         }
1285         break;
1286     }
1287     DECODE_CLEAR_SEGOVR();
1288     END_OF_INSTR();
1289 }
1290 
1291 /****************************************************************************
1292 REMARKS:
1293 Handles opcode 0x14
1294 ****************************************************************************/
x86emuOp_adc_byte_AL_IMM(u8 X86EMU_UNUSED (op1))1295 void x86emuOp_adc_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
1296 {
1297     u8 srcval;
1298 
1299     START_OF_INSTR();
1300     DECODE_PRINTF("ADC\tAL,");
1301     srcval = fetch_byte_imm();
1302     DECODE_PRINTF2("%x\n", srcval);
1303     TRACE_AND_STEP();
1304     M.x86.R_AL = adc_byte(M.x86.R_AL, srcval);
1305     DECODE_CLEAR_SEGOVR();
1306     END_OF_INSTR();
1307 }
1308 
1309 /****************************************************************************
1310 REMARKS:
1311 Handles opcode 0x15
1312 ****************************************************************************/
x86emuOp_adc_word_AX_IMM(u8 X86EMU_UNUSED (op1))1313 void x86emuOp_adc_word_AX_IMM(u8 X86EMU_UNUSED(op1))
1314 {
1315     u32 srcval;
1316 
1317     START_OF_INSTR();
1318     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1319         DECODE_PRINTF("ADC\tEAX,");
1320         srcval = fetch_long_imm();
1321     } else {
1322         DECODE_PRINTF("ADC\tAX,");
1323         srcval = fetch_word_imm();
1324     }
1325     DECODE_PRINTF2("%x\n", srcval);
1326     TRACE_AND_STEP();
1327     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1328         M.x86.R_EAX = adc_long(M.x86.R_EAX, srcval);
1329     } else {
1330         M.x86.R_AX = adc_word(M.x86.R_AX, (u16)srcval);
1331     }
1332     DECODE_CLEAR_SEGOVR();
1333     END_OF_INSTR();
1334 }
1335 
1336 /****************************************************************************
1337 REMARKS:
1338 Handles opcode 0x16
1339 ****************************************************************************/
x86emuOp_push_SS(u8 X86EMU_UNUSED (op1))1340 void x86emuOp_push_SS(u8 X86EMU_UNUSED(op1))
1341 {
1342     START_OF_INSTR();
1343     DECODE_PRINTF("PUSH\tSS\n");
1344     TRACE_AND_STEP();
1345     push_word(M.x86.R_SS);
1346     DECODE_CLEAR_SEGOVR();
1347     END_OF_INSTR();
1348 }
1349 
1350 /****************************************************************************
1351 REMARKS:
1352 Handles opcode 0x17
1353 ****************************************************************************/
x86emuOp_pop_SS(u8 X86EMU_UNUSED (op1))1354 void x86emuOp_pop_SS(u8 X86EMU_UNUSED(op1))
1355 {
1356     START_OF_INSTR();
1357     DECODE_PRINTF("POP\tSS\n");
1358     TRACE_AND_STEP();
1359     M.x86.R_SS = pop_word();
1360     DECODE_CLEAR_SEGOVR();
1361     END_OF_INSTR();
1362 }
1363 
1364 /****************************************************************************
1365 REMARKS:
1366 Handles opcode 0x18
1367 ****************************************************************************/
x86emuOp_sbb_byte_RM_R(u8 X86EMU_UNUSED (op1))1368 void x86emuOp_sbb_byte_RM_R(u8 X86EMU_UNUSED(op1))
1369 {
1370     int mod, rl, rh;
1371     u8 *destreg, *srcreg;
1372     uint destoffset;
1373     u8 destval;
1374 
1375     START_OF_INSTR();
1376     DECODE_PRINTF("SBB\t");
1377     FETCH_DECODE_MODRM(mod, rh, rl);
1378     switch (mod) {
1379     case 0:
1380         destoffset = decode_rm00_address(rl);
1381         DECODE_PRINTF(",");
1382         destval = fetch_data_byte(destoffset);
1383         srcreg = DECODE_RM_BYTE_REGISTER(rh);
1384         DECODE_PRINTF("\n");
1385         TRACE_AND_STEP();
1386         destval = sbb_byte(destval, *srcreg);
1387         store_data_byte(destoffset, destval);
1388         break;
1389     case 1:
1390         destoffset = decode_rm01_address(rl);
1391         DECODE_PRINTF(",");
1392         destval = fetch_data_byte(destoffset);
1393         srcreg = DECODE_RM_BYTE_REGISTER(rh);
1394         DECODE_PRINTF("\n");
1395         TRACE_AND_STEP();
1396         destval = sbb_byte(destval, *srcreg);
1397         store_data_byte(destoffset, destval);
1398         break;
1399     case 2:
1400         destoffset = decode_rm10_address(rl);
1401         DECODE_PRINTF(",");
1402         destval = fetch_data_byte(destoffset);
1403         srcreg = DECODE_RM_BYTE_REGISTER(rh);
1404         DECODE_PRINTF("\n");
1405         TRACE_AND_STEP();
1406         destval = sbb_byte(destval, *srcreg);
1407         store_data_byte(destoffset, destval);
1408         break;
1409     case 3:                     /* register to register */
1410         destreg = DECODE_RM_BYTE_REGISTER(rl);
1411         DECODE_PRINTF(",");
1412         srcreg = DECODE_RM_BYTE_REGISTER(rh);
1413         DECODE_PRINTF("\n");
1414         TRACE_AND_STEP();
1415         *destreg = sbb_byte(*destreg, *srcreg);
1416         break;
1417     }
1418     DECODE_CLEAR_SEGOVR();
1419     END_OF_INSTR();
1420 }
1421 
1422 /****************************************************************************
1423 REMARKS:
1424 Handles opcode 0x19
1425 ****************************************************************************/
x86emuOp_sbb_word_RM_R(u8 X86EMU_UNUSED (op1))1426 void x86emuOp_sbb_word_RM_R(u8 X86EMU_UNUSED(op1))
1427 {
1428     int mod, rl, rh;
1429     uint destoffset;
1430 
1431     START_OF_INSTR();
1432     DECODE_PRINTF("SBB\t");
1433     FETCH_DECODE_MODRM(mod, rh, rl);
1434     switch (mod) {
1435     case 0:
1436         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1437             u32 destval;
1438             u32 *srcreg;
1439 
1440             destoffset = decode_rm00_address(rl);
1441             DECODE_PRINTF(",");
1442             destval = fetch_data_long(destoffset);
1443             srcreg = DECODE_RM_LONG_REGISTER(rh);
1444             DECODE_PRINTF("\n");
1445             TRACE_AND_STEP();
1446             destval = sbb_long(destval, *srcreg);
1447             store_data_long(destoffset, destval);
1448         } else {
1449             u16 destval;
1450             u16 *srcreg;
1451 
1452             destoffset = decode_rm00_address(rl);
1453             DECODE_PRINTF(",");
1454             destval = fetch_data_word(destoffset);
1455             srcreg = DECODE_RM_WORD_REGISTER(rh);
1456             DECODE_PRINTF("\n");
1457             TRACE_AND_STEP();
1458             destval = sbb_word(destval, *srcreg);
1459             store_data_word(destoffset, destval);
1460         }
1461         break;
1462     case 1:
1463         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1464             u32 destval;
1465             u32 *srcreg;
1466 
1467             destoffset = decode_rm01_address(rl);
1468             DECODE_PRINTF(",");
1469             destval = fetch_data_long(destoffset);
1470             srcreg = DECODE_RM_LONG_REGISTER(rh);
1471             DECODE_PRINTF("\n");
1472             TRACE_AND_STEP();
1473             destval = sbb_long(destval, *srcreg);
1474             store_data_long(destoffset, destval);
1475         } else {
1476             u16 destval;
1477             u16 *srcreg;
1478 
1479             destoffset = decode_rm01_address(rl);
1480             DECODE_PRINTF(",");
1481             destval = fetch_data_word(destoffset);
1482             srcreg = DECODE_RM_WORD_REGISTER(rh);
1483             DECODE_PRINTF("\n");
1484             TRACE_AND_STEP();
1485             destval = sbb_word(destval, *srcreg);
1486             store_data_word(destoffset, destval);
1487         }
1488         break;
1489     case 2:
1490         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1491             u32 destval;
1492             u32 *srcreg;
1493 
1494             destoffset = decode_rm10_address(rl);
1495             DECODE_PRINTF(",");
1496             destval = fetch_data_long(destoffset);
1497             srcreg = DECODE_RM_LONG_REGISTER(rh);
1498             DECODE_PRINTF("\n");
1499             TRACE_AND_STEP();
1500             destval = sbb_long(destval, *srcreg);
1501             store_data_long(destoffset, destval);
1502         } else {
1503             u16 destval;
1504             u16 *srcreg;
1505 
1506             destoffset = decode_rm10_address(rl);
1507             DECODE_PRINTF(",");
1508             destval = fetch_data_word(destoffset);
1509             srcreg = DECODE_RM_WORD_REGISTER(rh);
1510             DECODE_PRINTF("\n");
1511             TRACE_AND_STEP();
1512             destval = sbb_word(destval, *srcreg);
1513             store_data_word(destoffset, destval);
1514         }
1515         break;
1516     case 3:                     /* register to register */
1517         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1518             u32 *destreg,*srcreg;
1519 
1520             destreg = DECODE_RM_LONG_REGISTER(rl);
1521             DECODE_PRINTF(",");
1522             srcreg = DECODE_RM_LONG_REGISTER(rh);
1523             DECODE_PRINTF("\n");
1524             TRACE_AND_STEP();
1525             *destreg = sbb_long(*destreg, *srcreg);
1526         } else {
1527             u16 *destreg,*srcreg;
1528 
1529             destreg = DECODE_RM_WORD_REGISTER(rl);
1530             DECODE_PRINTF(",");
1531             srcreg = DECODE_RM_WORD_REGISTER(rh);
1532             DECODE_PRINTF("\n");
1533             TRACE_AND_STEP();
1534             *destreg = sbb_word(*destreg, *srcreg);
1535         }
1536         break;
1537     }
1538     DECODE_CLEAR_SEGOVR();
1539     END_OF_INSTR();
1540 }
1541 
1542 /****************************************************************************
1543 REMARKS:
1544 Handles opcode 0x1a
1545 ****************************************************************************/
x86emuOp_sbb_byte_R_RM(u8 X86EMU_UNUSED (op1))1546 void x86emuOp_sbb_byte_R_RM(u8 X86EMU_UNUSED(op1))
1547 {
1548     int mod, rl, rh;
1549     u8 *destreg, *srcreg;
1550     uint srcoffset;
1551     u8 srcval;
1552 
1553     START_OF_INSTR();
1554     DECODE_PRINTF("SBB\t");
1555     FETCH_DECODE_MODRM(mod, rh, rl);
1556     switch (mod) {
1557     case 0:
1558         destreg = DECODE_RM_BYTE_REGISTER(rh);
1559         DECODE_PRINTF(",");
1560         srcoffset = decode_rm00_address(rl);
1561         srcval = fetch_data_byte(srcoffset);
1562         DECODE_PRINTF("\n");
1563         TRACE_AND_STEP();
1564         *destreg = sbb_byte(*destreg, srcval);
1565         break;
1566     case 1:
1567         destreg = DECODE_RM_BYTE_REGISTER(rh);
1568         DECODE_PRINTF(",");
1569         srcoffset = decode_rm01_address(rl);
1570         srcval = fetch_data_byte(srcoffset);
1571         DECODE_PRINTF("\n");
1572         TRACE_AND_STEP();
1573         *destreg = sbb_byte(*destreg, srcval);
1574         break;
1575     case 2:
1576         destreg = DECODE_RM_BYTE_REGISTER(rh);
1577         DECODE_PRINTF(",");
1578         srcoffset = decode_rm10_address(rl);
1579         srcval = fetch_data_byte(srcoffset);
1580         DECODE_PRINTF("\n");
1581         TRACE_AND_STEP();
1582         *destreg = sbb_byte(*destreg, srcval);
1583         break;
1584     case 3:                     /* register to register */
1585         destreg = DECODE_RM_BYTE_REGISTER(rh);
1586         DECODE_PRINTF(",");
1587         srcreg = DECODE_RM_BYTE_REGISTER(rl);
1588         DECODE_PRINTF("\n");
1589         TRACE_AND_STEP();
1590         *destreg = sbb_byte(*destreg, *srcreg);
1591         break;
1592     }
1593     DECODE_CLEAR_SEGOVR();
1594     END_OF_INSTR();
1595 }
1596 
1597 /****************************************************************************
1598 REMARKS:
1599 Handles opcode 0x1b
1600 ****************************************************************************/
x86emuOp_sbb_word_R_RM(u8 X86EMU_UNUSED (op1))1601 void x86emuOp_sbb_word_R_RM(u8 X86EMU_UNUSED(op1))
1602 {
1603     int mod, rl, rh;
1604     uint srcoffset;
1605 
1606     START_OF_INSTR();
1607     DECODE_PRINTF("SBB\t");
1608     FETCH_DECODE_MODRM(mod, rh, rl);
1609     switch (mod) {
1610     case 0:
1611         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1612             u32 *destreg;
1613             u32 srcval;
1614 
1615             destreg = DECODE_RM_LONG_REGISTER(rh);
1616             DECODE_PRINTF(",");
1617             srcoffset = decode_rm00_address(rl);
1618             srcval = fetch_data_long(srcoffset);
1619             DECODE_PRINTF("\n");
1620             TRACE_AND_STEP();
1621             *destreg = sbb_long(*destreg, srcval);
1622         } else {
1623             u16 *destreg;
1624             u16 srcval;
1625 
1626             destreg = DECODE_RM_WORD_REGISTER(rh);
1627             DECODE_PRINTF(",");
1628             srcoffset = decode_rm00_address(rl);
1629             srcval = fetch_data_word(srcoffset);
1630             DECODE_PRINTF("\n");
1631             TRACE_AND_STEP();
1632             *destreg = sbb_word(*destreg, srcval);
1633         }
1634         break;
1635     case 1:
1636         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1637             u32 *destreg;
1638             u32 srcval;
1639 
1640             destreg = DECODE_RM_LONG_REGISTER(rh);
1641             DECODE_PRINTF(",");
1642             srcoffset = decode_rm01_address(rl);
1643             srcval = fetch_data_long(srcoffset);
1644             DECODE_PRINTF("\n");
1645             TRACE_AND_STEP();
1646             *destreg = sbb_long(*destreg, srcval);
1647         } else {
1648             u16 *destreg;
1649             u16 srcval;
1650 
1651             destreg = DECODE_RM_WORD_REGISTER(rh);
1652             DECODE_PRINTF(",");
1653             srcoffset = decode_rm01_address(rl);
1654             srcval = fetch_data_word(srcoffset);
1655             DECODE_PRINTF("\n");
1656             TRACE_AND_STEP();
1657             *destreg = sbb_word(*destreg, srcval);
1658         }
1659         break;
1660     case 2:
1661         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1662             u32 *destreg;
1663             u32 srcval;
1664 
1665             destreg = DECODE_RM_LONG_REGISTER(rh);
1666             DECODE_PRINTF(",");
1667             srcoffset = decode_rm10_address(rl);
1668             srcval = fetch_data_long(srcoffset);
1669             DECODE_PRINTF("\n");
1670             TRACE_AND_STEP();
1671             *destreg = sbb_long(*destreg, srcval);
1672         } else {
1673             u16 *destreg;
1674             u16 srcval;
1675 
1676             destreg = DECODE_RM_WORD_REGISTER(rh);
1677             DECODE_PRINTF(",");
1678             srcoffset = decode_rm10_address(rl);
1679             srcval = fetch_data_word(srcoffset);
1680             DECODE_PRINTF("\n");
1681             TRACE_AND_STEP();
1682             *destreg = sbb_word(*destreg, srcval);
1683         }
1684         break;
1685     case 3:                     /* register to register */
1686         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1687             u32 *destreg,*srcreg;
1688 
1689             destreg = DECODE_RM_LONG_REGISTER(rh);
1690             DECODE_PRINTF(",");
1691             srcreg = DECODE_RM_LONG_REGISTER(rl);
1692             DECODE_PRINTF("\n");
1693             TRACE_AND_STEP();
1694             *destreg = sbb_long(*destreg, *srcreg);
1695         } else {
1696             u16 *destreg,*srcreg;
1697 
1698             destreg = DECODE_RM_WORD_REGISTER(rh);
1699             DECODE_PRINTF(",");
1700             srcreg = DECODE_RM_WORD_REGISTER(rl);
1701             DECODE_PRINTF("\n");
1702             TRACE_AND_STEP();
1703             *destreg = sbb_word(*destreg, *srcreg);
1704         }
1705         break;
1706     }
1707     DECODE_CLEAR_SEGOVR();
1708     END_OF_INSTR();
1709 }
1710 
1711 /****************************************************************************
1712 REMARKS:
1713 Handles opcode 0x1c
1714 ****************************************************************************/
x86emuOp_sbb_byte_AL_IMM(u8 X86EMU_UNUSED (op1))1715 void x86emuOp_sbb_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
1716 {
1717     u8 srcval;
1718 
1719     START_OF_INSTR();
1720     DECODE_PRINTF("SBB\tAL,");
1721     srcval = fetch_byte_imm();
1722     DECODE_PRINTF2("%x\n", srcval);
1723     TRACE_AND_STEP();
1724     M.x86.R_AL = sbb_byte(M.x86.R_AL, srcval);
1725     DECODE_CLEAR_SEGOVR();
1726     END_OF_INSTR();
1727 }
1728 
1729 /****************************************************************************
1730 REMARKS:
1731 Handles opcode 0x1d
1732 ****************************************************************************/
x86emuOp_sbb_word_AX_IMM(u8 X86EMU_UNUSED (op1))1733 void x86emuOp_sbb_word_AX_IMM(u8 X86EMU_UNUSED(op1))
1734 {
1735     u32 srcval;
1736 
1737     START_OF_INSTR();
1738     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1739         DECODE_PRINTF("SBB\tEAX,");
1740         srcval = fetch_long_imm();
1741     } else {
1742         DECODE_PRINTF("SBB\tAX,");
1743         srcval = fetch_word_imm();
1744     }
1745     DECODE_PRINTF2("%x\n", srcval);
1746     TRACE_AND_STEP();
1747     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1748         M.x86.R_EAX = sbb_long(M.x86.R_EAX, srcval);
1749     } else {
1750         M.x86.R_AX = sbb_word(M.x86.R_AX, (u16)srcval);
1751     }
1752     DECODE_CLEAR_SEGOVR();
1753     END_OF_INSTR();
1754 }
1755 
1756 /****************************************************************************
1757 REMARKS:
1758 Handles opcode 0x1e
1759 ****************************************************************************/
x86emuOp_push_DS(u8 X86EMU_UNUSED (op1))1760 void x86emuOp_push_DS(u8 X86EMU_UNUSED(op1))
1761 {
1762     START_OF_INSTR();
1763     DECODE_PRINTF("PUSH\tDS\n");
1764     TRACE_AND_STEP();
1765     push_word(M.x86.R_DS);
1766     DECODE_CLEAR_SEGOVR();
1767     END_OF_INSTR();
1768 }
1769 
1770 /****************************************************************************
1771 REMARKS:
1772 Handles opcode 0x1f
1773 ****************************************************************************/
x86emuOp_pop_DS(u8 X86EMU_UNUSED (op1))1774 void x86emuOp_pop_DS(u8 X86EMU_UNUSED(op1))
1775 {
1776     START_OF_INSTR();
1777     DECODE_PRINTF("POP\tDS\n");
1778     TRACE_AND_STEP();
1779     M.x86.R_DS = pop_word();
1780     DECODE_CLEAR_SEGOVR();
1781     END_OF_INSTR();
1782 }
1783 
1784 /****************************************************************************
1785 REMARKS:
1786 Handles opcode 0x20
1787 ****************************************************************************/
x86emuOp_and_byte_RM_R(u8 X86EMU_UNUSED (op1))1788 void x86emuOp_and_byte_RM_R(u8 X86EMU_UNUSED(op1))
1789 {
1790     int mod, rl, rh;
1791     u8 *destreg, *srcreg;
1792     uint destoffset;
1793     u8 destval;
1794 
1795     START_OF_INSTR();
1796     DECODE_PRINTF("AND\t");
1797     FETCH_DECODE_MODRM(mod, rh, rl);
1798 
1799     switch (mod) {
1800     case 0:
1801         destoffset = decode_rm00_address(rl);
1802         DECODE_PRINTF(",");
1803         destval = fetch_data_byte(destoffset);
1804         srcreg = DECODE_RM_BYTE_REGISTER(rh);
1805         DECODE_PRINTF("\n");
1806         TRACE_AND_STEP();
1807         destval = and_byte(destval, *srcreg);
1808         store_data_byte(destoffset, destval);
1809         break;
1810 
1811     case 1:
1812         destoffset = decode_rm01_address(rl);
1813         DECODE_PRINTF(",");
1814         destval = fetch_data_byte(destoffset);
1815         srcreg = DECODE_RM_BYTE_REGISTER(rh);
1816         DECODE_PRINTF("\n");
1817         TRACE_AND_STEP();
1818         destval = and_byte(destval, *srcreg);
1819         store_data_byte(destoffset, destval);
1820         break;
1821 
1822     case 2:
1823         destoffset = decode_rm10_address(rl);
1824         DECODE_PRINTF(",");
1825         destval = fetch_data_byte(destoffset);
1826         srcreg = DECODE_RM_BYTE_REGISTER(rh);
1827         DECODE_PRINTF("\n");
1828         TRACE_AND_STEP();
1829         destval = and_byte(destval, *srcreg);
1830         store_data_byte(destoffset, destval);
1831         break;
1832 
1833     case 3:                     /* register to register */
1834         destreg = DECODE_RM_BYTE_REGISTER(rl);
1835         DECODE_PRINTF(",");
1836         srcreg = DECODE_RM_BYTE_REGISTER(rh);
1837         DECODE_PRINTF("\n");
1838         TRACE_AND_STEP();
1839         *destreg = and_byte(*destreg, *srcreg);
1840         break;
1841     }
1842     DECODE_CLEAR_SEGOVR();
1843     END_OF_INSTR();
1844 }
1845 
1846 /****************************************************************************
1847 REMARKS:
1848 Handles opcode 0x21
1849 ****************************************************************************/
x86emuOp_and_word_RM_R(u8 X86EMU_UNUSED (op1))1850 void x86emuOp_and_word_RM_R(u8 X86EMU_UNUSED(op1))
1851 {
1852     int mod, rl, rh;
1853     uint destoffset;
1854 
1855     START_OF_INSTR();
1856     DECODE_PRINTF("AND\t");
1857     FETCH_DECODE_MODRM(mod, rh, rl);
1858     switch (mod) {
1859     case 0:
1860         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1861             u32 destval;
1862             u32 *srcreg;
1863 
1864             destoffset = decode_rm00_address(rl);
1865             DECODE_PRINTF(",");
1866             destval = fetch_data_long(destoffset);
1867             srcreg = DECODE_RM_LONG_REGISTER(rh);
1868             DECODE_PRINTF("\n");
1869             TRACE_AND_STEP();
1870             destval = and_long(destval, *srcreg);
1871             store_data_long(destoffset, destval);
1872         } else {
1873             u16 destval;
1874             u16 *srcreg;
1875 
1876             destoffset = decode_rm00_address(rl);
1877             DECODE_PRINTF(",");
1878             destval = fetch_data_word(destoffset);
1879             srcreg = DECODE_RM_WORD_REGISTER(rh);
1880             DECODE_PRINTF("\n");
1881             TRACE_AND_STEP();
1882             destval = and_word(destval, *srcreg);
1883             store_data_word(destoffset, destval);
1884         }
1885         break;
1886     case 1:
1887         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1888             u32 destval;
1889             u32 *srcreg;
1890 
1891             destoffset = decode_rm01_address(rl);
1892             DECODE_PRINTF(",");
1893             destval = fetch_data_long(destoffset);
1894             srcreg = DECODE_RM_LONG_REGISTER(rh);
1895             DECODE_PRINTF("\n");
1896             TRACE_AND_STEP();
1897             destval = and_long(destval, *srcreg);
1898             store_data_long(destoffset, destval);
1899         } else {
1900             u16 destval;
1901             u16 *srcreg;
1902 
1903             destoffset = decode_rm01_address(rl);
1904             DECODE_PRINTF(",");
1905             destval = fetch_data_word(destoffset);
1906             srcreg = DECODE_RM_WORD_REGISTER(rh);
1907             DECODE_PRINTF("\n");
1908             TRACE_AND_STEP();
1909             destval = and_word(destval, *srcreg);
1910             store_data_word(destoffset, destval);
1911         }
1912         break;
1913     case 2:
1914         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1915             u32 destval;
1916             u32 *srcreg;
1917 
1918             destoffset = decode_rm10_address(rl);
1919             DECODE_PRINTF(",");
1920             destval = fetch_data_long(destoffset);
1921             srcreg = DECODE_RM_LONG_REGISTER(rh);
1922             DECODE_PRINTF("\n");
1923             TRACE_AND_STEP();
1924             destval = and_long(destval, *srcreg);
1925             store_data_long(destoffset, destval);
1926         } else {
1927             u16 destval;
1928             u16 *srcreg;
1929 
1930             destoffset = decode_rm10_address(rl);
1931             DECODE_PRINTF(",");
1932             destval = fetch_data_word(destoffset);
1933             srcreg = DECODE_RM_WORD_REGISTER(rh);
1934             DECODE_PRINTF("\n");
1935             TRACE_AND_STEP();
1936             destval = and_word(destval, *srcreg);
1937             store_data_word(destoffset, destval);
1938         }
1939         break;
1940     case 3:                     /* register to register */
1941         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
1942             u32 *destreg,*srcreg;
1943 
1944             destreg = DECODE_RM_LONG_REGISTER(rl);
1945             DECODE_PRINTF(",");
1946             srcreg = DECODE_RM_LONG_REGISTER(rh);
1947             DECODE_PRINTF("\n");
1948             TRACE_AND_STEP();
1949             *destreg = and_long(*destreg, *srcreg);
1950         } else {
1951             u16 *destreg,*srcreg;
1952 
1953             destreg = DECODE_RM_WORD_REGISTER(rl);
1954             DECODE_PRINTF(",");
1955             srcreg = DECODE_RM_WORD_REGISTER(rh);
1956             DECODE_PRINTF("\n");
1957             TRACE_AND_STEP();
1958             *destreg = and_word(*destreg, *srcreg);
1959         }
1960         break;
1961     }
1962     DECODE_CLEAR_SEGOVR();
1963     END_OF_INSTR();
1964 }
1965 
1966 /****************************************************************************
1967 REMARKS:
1968 Handles opcode 0x22
1969 ****************************************************************************/
x86emuOp_and_byte_R_RM(u8 X86EMU_UNUSED (op1))1970 void x86emuOp_and_byte_R_RM(u8 X86EMU_UNUSED(op1))
1971 {
1972     int mod, rl, rh;
1973     u8 *destreg, *srcreg;
1974     uint srcoffset;
1975     u8 srcval;
1976 
1977     START_OF_INSTR();
1978     DECODE_PRINTF("AND\t");
1979     FETCH_DECODE_MODRM(mod, rh, rl);
1980     switch (mod) {
1981     case 0:
1982         destreg = DECODE_RM_BYTE_REGISTER(rh);
1983         DECODE_PRINTF(",");
1984         srcoffset = decode_rm00_address(rl);
1985         srcval = fetch_data_byte(srcoffset);
1986         DECODE_PRINTF("\n");
1987         TRACE_AND_STEP();
1988         *destreg = and_byte(*destreg, srcval);
1989         break;
1990     case 1:
1991         destreg = DECODE_RM_BYTE_REGISTER(rh);
1992         DECODE_PRINTF(",");
1993         srcoffset = decode_rm01_address(rl);
1994         srcval = fetch_data_byte(srcoffset);
1995         DECODE_PRINTF("\n");
1996         TRACE_AND_STEP();
1997         *destreg = and_byte(*destreg, srcval);
1998         break;
1999     case 2:
2000         destreg = DECODE_RM_BYTE_REGISTER(rh);
2001         DECODE_PRINTF(",");
2002         srcoffset = decode_rm10_address(rl);
2003         srcval = fetch_data_byte(srcoffset);
2004         DECODE_PRINTF("\n");
2005         TRACE_AND_STEP();
2006         *destreg = and_byte(*destreg, srcval);
2007         break;
2008     case 3:                     /* register to register */
2009         destreg = DECODE_RM_BYTE_REGISTER(rh);
2010         DECODE_PRINTF(",");
2011         srcreg = DECODE_RM_BYTE_REGISTER(rl);
2012         DECODE_PRINTF("\n");
2013         TRACE_AND_STEP();
2014         *destreg = and_byte(*destreg, *srcreg);
2015         break;
2016     }
2017     DECODE_CLEAR_SEGOVR();
2018     END_OF_INSTR();
2019 }
2020 
2021 /****************************************************************************
2022 REMARKS:
2023 Handles opcode 0x23
2024 ****************************************************************************/
x86emuOp_and_word_R_RM(u8 X86EMU_UNUSED (op1))2025 void x86emuOp_and_word_R_RM(u8 X86EMU_UNUSED(op1))
2026 {
2027     int mod, rl, rh;
2028     uint srcoffset;
2029 
2030     START_OF_INSTR();
2031     DECODE_PRINTF("AND\t");
2032     FETCH_DECODE_MODRM(mod, rh, rl);
2033     switch (mod) {
2034     case 0:
2035         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2036             u32 *destreg;
2037             u32 srcval;
2038 
2039             destreg = DECODE_RM_LONG_REGISTER(rh);
2040             DECODE_PRINTF(",");
2041             srcoffset = decode_rm00_address(rl);
2042             srcval = fetch_data_long(srcoffset);
2043             DECODE_PRINTF("\n");
2044             TRACE_AND_STEP();
2045             *destreg = and_long(*destreg, srcval);
2046         } else {
2047             u16 *destreg;
2048             u16 srcval;
2049 
2050             destreg = DECODE_RM_WORD_REGISTER(rh);
2051             DECODE_PRINTF(",");
2052             srcoffset = decode_rm00_address(rl);
2053             srcval = fetch_data_word(srcoffset);
2054             DECODE_PRINTF("\n");
2055             TRACE_AND_STEP();
2056             *destreg = and_word(*destreg, srcval);
2057         }
2058         break;
2059     case 1:
2060         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2061             u32 *destreg;
2062             u32 srcval;
2063 
2064             destreg = DECODE_RM_LONG_REGISTER(rh);
2065             DECODE_PRINTF(",");
2066             srcoffset = decode_rm01_address(rl);
2067             srcval = fetch_data_long(srcoffset);
2068             DECODE_PRINTF("\n");
2069             TRACE_AND_STEP();
2070             *destreg = and_long(*destreg, srcval);
2071             break;
2072         } else {
2073             u16 *destreg;
2074             u16 srcval;
2075 
2076             destreg = DECODE_RM_WORD_REGISTER(rh);
2077             DECODE_PRINTF(",");
2078             srcoffset = decode_rm01_address(rl);
2079             srcval = fetch_data_word(srcoffset);
2080             DECODE_PRINTF("\n");
2081             TRACE_AND_STEP();
2082             *destreg = and_word(*destreg, srcval);
2083             break;
2084         }
2085     case 2:
2086         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2087             u32 *destreg;
2088             u32 srcval;
2089 
2090             destreg = DECODE_RM_LONG_REGISTER(rh);
2091             DECODE_PRINTF(",");
2092             srcoffset = decode_rm10_address(rl);
2093             srcval = fetch_data_long(srcoffset);
2094             DECODE_PRINTF("\n");
2095             TRACE_AND_STEP();
2096             *destreg = and_long(*destreg, srcval);
2097         } else {
2098             u16 *destreg;
2099             u16 srcval;
2100 
2101             destreg = DECODE_RM_WORD_REGISTER(rh);
2102             DECODE_PRINTF(",");
2103             srcoffset = decode_rm10_address(rl);
2104             srcval = fetch_data_word(srcoffset);
2105             DECODE_PRINTF("\n");
2106             TRACE_AND_STEP();
2107             *destreg = and_word(*destreg, srcval);
2108         }
2109         break;
2110     case 3:                     /* register to register */
2111         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2112             u32 *destreg,*srcreg;
2113 
2114             destreg = DECODE_RM_LONG_REGISTER(rh);
2115             DECODE_PRINTF(",");
2116             srcreg = DECODE_RM_LONG_REGISTER(rl);
2117             DECODE_PRINTF("\n");
2118             TRACE_AND_STEP();
2119             *destreg = and_long(*destreg, *srcreg);
2120         } else {
2121             u16 *destreg,*srcreg;
2122 
2123             destreg = DECODE_RM_WORD_REGISTER(rh);
2124             DECODE_PRINTF(",");
2125             srcreg = DECODE_RM_WORD_REGISTER(rl);
2126             DECODE_PRINTF("\n");
2127             TRACE_AND_STEP();
2128             *destreg = and_word(*destreg, *srcreg);
2129         }
2130         break;
2131     }
2132     DECODE_CLEAR_SEGOVR();
2133     END_OF_INSTR();
2134 }
2135 
2136 /****************************************************************************
2137 REMARKS:
2138 Handles opcode 0x24
2139 ****************************************************************************/
x86emuOp_and_byte_AL_IMM(u8 X86EMU_UNUSED (op1))2140 void x86emuOp_and_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
2141 {
2142     u8 srcval;
2143 
2144     START_OF_INSTR();
2145     DECODE_PRINTF("AND\tAL,");
2146     srcval = fetch_byte_imm();
2147     DECODE_PRINTF2("%x\n", srcval);
2148     TRACE_AND_STEP();
2149     M.x86.R_AL = and_byte(M.x86.R_AL, srcval);
2150     DECODE_CLEAR_SEGOVR();
2151     END_OF_INSTR();
2152 }
2153 
2154 /****************************************************************************
2155 REMARKS:
2156 Handles opcode 0x25
2157 ****************************************************************************/
x86emuOp_and_word_AX_IMM(u8 X86EMU_UNUSED (op1))2158 void x86emuOp_and_word_AX_IMM(u8 X86EMU_UNUSED(op1))
2159 {
2160     u32 srcval;
2161 
2162     START_OF_INSTR();
2163     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2164         DECODE_PRINTF("AND\tEAX,");
2165         srcval = fetch_long_imm();
2166     } else {
2167         DECODE_PRINTF("AND\tAX,");
2168         srcval = fetch_word_imm();
2169     }
2170     DECODE_PRINTF2("%x\n", srcval);
2171     TRACE_AND_STEP();
2172     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2173         M.x86.R_EAX = and_long(M.x86.R_EAX, srcval);
2174     } else {
2175         M.x86.R_AX = and_word(M.x86.R_AX, (u16)srcval);
2176     }
2177     DECODE_CLEAR_SEGOVR();
2178     END_OF_INSTR();
2179 }
2180 
2181 /****************************************************************************
2182 REMARKS:
2183 Handles opcode 0x26
2184 ****************************************************************************/
x86emuOp_segovr_ES(u8 X86EMU_UNUSED (op1))2185 void x86emuOp_segovr_ES(u8 X86EMU_UNUSED(op1))
2186 {
2187     START_OF_INSTR();
2188     DECODE_PRINTF("ES:\n");
2189     TRACE_AND_STEP();
2190     M.x86.mode |= SYSMODE_SEGOVR_ES;
2191     /*
2192      * note the lack of DECODE_CLEAR_SEGOVR(r) since, here is one of 4
2193      * opcode subroutines we do not want to do this.
2194      */
2195     END_OF_INSTR();
2196 }
2197 
2198 /****************************************************************************
2199 REMARKS:
2200 Handles opcode 0x27
2201 ****************************************************************************/
x86emuOp_daa(u8 X86EMU_UNUSED (op1))2202 void x86emuOp_daa(u8 X86EMU_UNUSED(op1))
2203 {
2204     START_OF_INSTR();
2205     DECODE_PRINTF("DAA\n");
2206     TRACE_AND_STEP();
2207     M.x86.R_AL = daa_byte(M.x86.R_AL);
2208     DECODE_CLEAR_SEGOVR();
2209     END_OF_INSTR();
2210 }
2211 
2212 /****************************************************************************
2213 REMARKS:
2214 Handles opcode 0x28
2215 ****************************************************************************/
x86emuOp_sub_byte_RM_R(u8 X86EMU_UNUSED (op1))2216 void x86emuOp_sub_byte_RM_R(u8 X86EMU_UNUSED(op1))
2217 {
2218     int mod, rl, rh;
2219     u8 *destreg, *srcreg;
2220     uint destoffset;
2221     u8 destval;
2222 
2223     START_OF_INSTR();
2224     DECODE_PRINTF("SUB\t");
2225     FETCH_DECODE_MODRM(mod, rh, rl);
2226     switch (mod) {
2227     case 0:
2228         destoffset = decode_rm00_address(rl);
2229         DECODE_PRINTF(",");
2230         destval = fetch_data_byte(destoffset);
2231         srcreg = DECODE_RM_BYTE_REGISTER(rh);
2232         DECODE_PRINTF("\n");
2233         TRACE_AND_STEP();
2234         destval = sub_byte(destval, *srcreg);
2235         store_data_byte(destoffset, destval);
2236         break;
2237     case 1:
2238         destoffset = decode_rm01_address(rl);
2239         DECODE_PRINTF(",");
2240         destval = fetch_data_byte(destoffset);
2241         srcreg = DECODE_RM_BYTE_REGISTER(rh);
2242         DECODE_PRINTF("\n");
2243         TRACE_AND_STEP();
2244         destval = sub_byte(destval, *srcreg);
2245         store_data_byte(destoffset, destval);
2246         break;
2247     case 2:
2248         destoffset = decode_rm10_address(rl);
2249         DECODE_PRINTF(",");
2250         destval = fetch_data_byte(destoffset);
2251         srcreg = DECODE_RM_BYTE_REGISTER(rh);
2252         DECODE_PRINTF("\n");
2253         TRACE_AND_STEP();
2254         destval = sub_byte(destval, *srcreg);
2255         store_data_byte(destoffset, destval);
2256         break;
2257     case 3:                     /* register to register */
2258         destreg = DECODE_RM_BYTE_REGISTER(rl);
2259         DECODE_PRINTF(",");
2260         srcreg = DECODE_RM_BYTE_REGISTER(rh);
2261         DECODE_PRINTF("\n");
2262         TRACE_AND_STEP();
2263         *destreg = sub_byte(*destreg, *srcreg);
2264         break;
2265     }
2266     DECODE_CLEAR_SEGOVR();
2267     END_OF_INSTR();
2268 }
2269 
2270 /****************************************************************************
2271 REMARKS:
2272 Handles opcode 0x29
2273 ****************************************************************************/
x86emuOp_sub_word_RM_R(u8 X86EMU_UNUSED (op1))2274 void x86emuOp_sub_word_RM_R(u8 X86EMU_UNUSED(op1))
2275 {
2276     int mod, rl, rh;
2277     uint destoffset;
2278 
2279     START_OF_INSTR();
2280     DECODE_PRINTF("SUB\t");
2281     FETCH_DECODE_MODRM(mod, rh, rl);
2282     switch (mod) {
2283     case 0:
2284         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2285             u32 destval;
2286             u32 *srcreg;
2287 
2288             destoffset = decode_rm00_address(rl);
2289             DECODE_PRINTF(",");
2290             destval = fetch_data_long(destoffset);
2291             srcreg = DECODE_RM_LONG_REGISTER(rh);
2292             DECODE_PRINTF("\n");
2293             TRACE_AND_STEP();
2294             destval = sub_long(destval, *srcreg);
2295             store_data_long(destoffset, destval);
2296         } else {
2297             u16 destval;
2298             u16 *srcreg;
2299 
2300             destoffset = decode_rm00_address(rl);
2301             DECODE_PRINTF(",");
2302             destval = fetch_data_word(destoffset);
2303             srcreg = DECODE_RM_WORD_REGISTER(rh);
2304             DECODE_PRINTF("\n");
2305             TRACE_AND_STEP();
2306             destval = sub_word(destval, *srcreg);
2307             store_data_word(destoffset, destval);
2308         }
2309         break;
2310     case 1:
2311         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2312             u32 destval;
2313             u32 *srcreg;
2314 
2315             destoffset = decode_rm01_address(rl);
2316             DECODE_PRINTF(",");
2317             destval = fetch_data_long(destoffset);
2318             srcreg = DECODE_RM_LONG_REGISTER(rh);
2319             DECODE_PRINTF("\n");
2320             TRACE_AND_STEP();
2321             destval = sub_long(destval, *srcreg);
2322             store_data_long(destoffset, destval);
2323         } else {
2324             u16 destval;
2325             u16 *srcreg;
2326 
2327             destoffset = decode_rm01_address(rl);
2328             DECODE_PRINTF(",");
2329             destval = fetch_data_word(destoffset);
2330             srcreg = DECODE_RM_WORD_REGISTER(rh);
2331             DECODE_PRINTF("\n");
2332             TRACE_AND_STEP();
2333             destval = sub_word(destval, *srcreg);
2334             store_data_word(destoffset, destval);
2335         }
2336         break;
2337     case 2:
2338         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2339             u32 destval;
2340             u32 *srcreg;
2341 
2342             destoffset = decode_rm10_address(rl);
2343             DECODE_PRINTF(",");
2344             destval = fetch_data_long(destoffset);
2345             srcreg = DECODE_RM_LONG_REGISTER(rh);
2346             DECODE_PRINTF("\n");
2347             TRACE_AND_STEP();
2348             destval = sub_long(destval, *srcreg);
2349             store_data_long(destoffset, destval);
2350         } else {
2351             u16 destval;
2352             u16 *srcreg;
2353 
2354             destoffset = decode_rm10_address(rl);
2355             DECODE_PRINTF(",");
2356             destval = fetch_data_word(destoffset);
2357             srcreg = DECODE_RM_WORD_REGISTER(rh);
2358             DECODE_PRINTF("\n");
2359             TRACE_AND_STEP();
2360             destval = sub_word(destval, *srcreg);
2361             store_data_word(destoffset, destval);
2362         }
2363         break;
2364     case 3:                     /* register to register */
2365         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2366             u32 *destreg,*srcreg;
2367 
2368             destreg = DECODE_RM_LONG_REGISTER(rl);
2369             DECODE_PRINTF(",");
2370             srcreg = DECODE_RM_LONG_REGISTER(rh);
2371             DECODE_PRINTF("\n");
2372             TRACE_AND_STEP();
2373             *destreg = sub_long(*destreg, *srcreg);
2374         } else {
2375             u16 *destreg,*srcreg;
2376 
2377             destreg = DECODE_RM_WORD_REGISTER(rl);
2378             DECODE_PRINTF(",");
2379             srcreg = DECODE_RM_WORD_REGISTER(rh);
2380             DECODE_PRINTF("\n");
2381             TRACE_AND_STEP();
2382             *destreg = sub_word(*destreg, *srcreg);
2383         }
2384         break;
2385     }
2386     DECODE_CLEAR_SEGOVR();
2387     END_OF_INSTR();
2388 }
2389 
2390 /****************************************************************************
2391 REMARKS:
2392 Handles opcode 0x2a
2393 ****************************************************************************/
x86emuOp_sub_byte_R_RM(u8 X86EMU_UNUSED (op1))2394 void x86emuOp_sub_byte_R_RM(u8 X86EMU_UNUSED(op1))
2395 {
2396     int mod, rl, rh;
2397     u8 *destreg, *srcreg;
2398     uint srcoffset;
2399     u8 srcval;
2400 
2401     START_OF_INSTR();
2402     DECODE_PRINTF("SUB\t");
2403     FETCH_DECODE_MODRM(mod, rh, rl);
2404     switch (mod) {
2405     case 0:
2406         destreg = DECODE_RM_BYTE_REGISTER(rh);
2407         DECODE_PRINTF(",");
2408         srcoffset = decode_rm00_address(rl);
2409         srcval = fetch_data_byte(srcoffset);
2410         DECODE_PRINTF("\n");
2411         TRACE_AND_STEP();
2412         *destreg = sub_byte(*destreg, srcval);
2413         break;
2414     case 1:
2415         destreg = DECODE_RM_BYTE_REGISTER(rh);
2416         DECODE_PRINTF(",");
2417         srcoffset = decode_rm01_address(rl);
2418         srcval = fetch_data_byte(srcoffset);
2419         DECODE_PRINTF("\n");
2420         TRACE_AND_STEP();
2421         *destreg = sub_byte(*destreg, srcval);
2422         break;
2423     case 2:
2424         destreg = DECODE_RM_BYTE_REGISTER(rh);
2425         DECODE_PRINTF(",");
2426         srcoffset = decode_rm10_address(rl);
2427         srcval = fetch_data_byte(srcoffset);
2428         DECODE_PRINTF("\n");
2429         TRACE_AND_STEP();
2430         *destreg = sub_byte(*destreg, srcval);
2431         break;
2432     case 3:                     /* register to register */
2433         destreg = DECODE_RM_BYTE_REGISTER(rh);
2434         DECODE_PRINTF(",");
2435         srcreg = DECODE_RM_BYTE_REGISTER(rl);
2436         DECODE_PRINTF("\n");
2437         TRACE_AND_STEP();
2438         *destreg = sub_byte(*destreg, *srcreg);
2439         break;
2440     }
2441     DECODE_CLEAR_SEGOVR();
2442     END_OF_INSTR();
2443 }
2444 
2445 /****************************************************************************
2446 REMARKS:
2447 Handles opcode 0x2b
2448 ****************************************************************************/
x86emuOp_sub_word_R_RM(u8 X86EMU_UNUSED (op1))2449 void x86emuOp_sub_word_R_RM(u8 X86EMU_UNUSED(op1))
2450 {
2451     int mod, rl, rh;
2452     uint srcoffset;
2453 
2454     START_OF_INSTR();
2455     DECODE_PRINTF("SUB\t");
2456     FETCH_DECODE_MODRM(mod, rh, rl);
2457     switch (mod) {
2458     case 0:
2459         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2460             u32 *destreg;
2461             u32 srcval;
2462 
2463             destreg = DECODE_RM_LONG_REGISTER(rh);
2464             DECODE_PRINTF(",");
2465             srcoffset = decode_rm00_address(rl);
2466             srcval = fetch_data_long(srcoffset);
2467             DECODE_PRINTF("\n");
2468             TRACE_AND_STEP();
2469             *destreg = sub_long(*destreg, srcval);
2470         } else {
2471             u16 *destreg;
2472             u16 srcval;
2473 
2474             destreg = DECODE_RM_WORD_REGISTER(rh);
2475             DECODE_PRINTF(",");
2476             srcoffset = decode_rm00_address(rl);
2477             srcval = fetch_data_word(srcoffset);
2478             DECODE_PRINTF("\n");
2479             TRACE_AND_STEP();
2480             *destreg = sub_word(*destreg, srcval);
2481         }
2482         break;
2483     case 1:
2484         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2485             u32 *destreg;
2486             u32 srcval;
2487 
2488             destreg = DECODE_RM_LONG_REGISTER(rh);
2489             DECODE_PRINTF(",");
2490             srcoffset = decode_rm01_address(rl);
2491             srcval = fetch_data_long(srcoffset);
2492             DECODE_PRINTF("\n");
2493             TRACE_AND_STEP();
2494             *destreg = sub_long(*destreg, srcval);
2495         } else {
2496             u16 *destreg;
2497             u16 srcval;
2498 
2499             destreg = DECODE_RM_WORD_REGISTER(rh);
2500             DECODE_PRINTF(",");
2501             srcoffset = decode_rm01_address(rl);
2502             srcval = fetch_data_word(srcoffset);
2503             DECODE_PRINTF("\n");
2504             TRACE_AND_STEP();
2505             *destreg = sub_word(*destreg, srcval);
2506         }
2507         break;
2508     case 2:
2509         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2510             u32 *destreg;
2511             u32 srcval;
2512 
2513             destreg = DECODE_RM_LONG_REGISTER(rh);
2514             DECODE_PRINTF(",");
2515             srcoffset = decode_rm10_address(rl);
2516             srcval = fetch_data_long(srcoffset);
2517             DECODE_PRINTF("\n");
2518             TRACE_AND_STEP();
2519             *destreg = sub_long(*destreg, srcval);
2520         } else {
2521             u16 *destreg;
2522             u16 srcval;
2523 
2524             destreg = DECODE_RM_WORD_REGISTER(rh);
2525             DECODE_PRINTF(",");
2526             srcoffset = decode_rm10_address(rl);
2527             srcval = fetch_data_word(srcoffset);
2528             DECODE_PRINTF("\n");
2529             TRACE_AND_STEP();
2530             *destreg = sub_word(*destreg, srcval);
2531         }
2532         break;
2533     case 3:                     /* register to register */
2534         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2535             u32 *destreg,*srcreg;
2536 
2537             destreg = DECODE_RM_LONG_REGISTER(rh);
2538             DECODE_PRINTF(",");
2539             srcreg = DECODE_RM_LONG_REGISTER(rl);
2540             DECODE_PRINTF("\n");
2541             TRACE_AND_STEP();
2542             *destreg = sub_long(*destreg, *srcreg);
2543         } else {
2544             u16 *destreg,*srcreg;
2545 
2546             destreg = DECODE_RM_WORD_REGISTER(rh);
2547             DECODE_PRINTF(",");
2548             srcreg = DECODE_RM_WORD_REGISTER(rl);
2549             DECODE_PRINTF("\n");
2550             TRACE_AND_STEP();
2551             *destreg = sub_word(*destreg, *srcreg);
2552         }
2553         break;
2554     }
2555     DECODE_CLEAR_SEGOVR();
2556     END_OF_INSTR();
2557 }
2558 
2559 /****************************************************************************
2560 REMARKS:
2561 Handles opcode 0x2c
2562 ****************************************************************************/
x86emuOp_sub_byte_AL_IMM(u8 X86EMU_UNUSED (op1))2563 void x86emuOp_sub_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
2564 {
2565     u8 srcval;
2566 
2567     START_OF_INSTR();
2568     DECODE_PRINTF("SUB\tAL,");
2569     srcval = fetch_byte_imm();
2570     DECODE_PRINTF2("%x\n", srcval);
2571     TRACE_AND_STEP();
2572     M.x86.R_AL = sub_byte(M.x86.R_AL, srcval);
2573     DECODE_CLEAR_SEGOVR();
2574     END_OF_INSTR();
2575 }
2576 
2577 /****************************************************************************
2578 REMARKS:
2579 Handles opcode 0x2d
2580 ****************************************************************************/
x86emuOp_sub_word_AX_IMM(u8 X86EMU_UNUSED (op1))2581 void x86emuOp_sub_word_AX_IMM(u8 X86EMU_UNUSED(op1))
2582 {
2583     u32 srcval;
2584 
2585     START_OF_INSTR();
2586     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2587         DECODE_PRINTF("SUB\tEAX,");
2588         srcval = fetch_long_imm();
2589     } else {
2590         DECODE_PRINTF("SUB\tAX,");
2591         srcval = fetch_word_imm();
2592     }
2593     DECODE_PRINTF2("%x\n", srcval);
2594     TRACE_AND_STEP();
2595     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2596         M.x86.R_EAX = sub_long(M.x86.R_EAX, srcval);
2597     } else {
2598         M.x86.R_AX = sub_word(M.x86.R_AX, (u16)srcval);
2599     }
2600     DECODE_CLEAR_SEGOVR();
2601     END_OF_INSTR();
2602 }
2603 
2604 /****************************************************************************
2605 REMARKS:
2606 Handles opcode 0x2e
2607 ****************************************************************************/
x86emuOp_segovr_CS(u8 X86EMU_UNUSED (op1))2608 void x86emuOp_segovr_CS(u8 X86EMU_UNUSED(op1))
2609 {
2610     START_OF_INSTR();
2611     DECODE_PRINTF("CS:\n");
2612     TRACE_AND_STEP();
2613     M.x86.mode |= SYSMODE_SEGOVR_CS;
2614     /* note no DECODE_CLEAR_SEGOVR here. */
2615     END_OF_INSTR();
2616 }
2617 
2618 /****************************************************************************
2619 REMARKS:
2620 Handles opcode 0x2f
2621 ****************************************************************************/
x86emuOp_das(u8 X86EMU_UNUSED (op1))2622 void x86emuOp_das(u8 X86EMU_UNUSED(op1))
2623 {
2624     START_OF_INSTR();
2625     DECODE_PRINTF("DAS\n");
2626     TRACE_AND_STEP();
2627     M.x86.R_AL = das_byte(M.x86.R_AL);
2628     DECODE_CLEAR_SEGOVR();
2629     END_OF_INSTR();
2630 }
2631 
2632 /****************************************************************************
2633 REMARKS:
2634 Handles opcode 0x30
2635 ****************************************************************************/
x86emuOp_xor_byte_RM_R(u8 X86EMU_UNUSED (op1))2636 void x86emuOp_xor_byte_RM_R(u8 X86EMU_UNUSED(op1))
2637 {
2638     int mod, rl, rh;
2639     u8 *destreg, *srcreg;
2640     uint destoffset;
2641     u8 destval;
2642 
2643     START_OF_INSTR();
2644     DECODE_PRINTF("XOR\t");
2645     FETCH_DECODE_MODRM(mod, rh, rl);
2646     switch (mod) {
2647     case 0:
2648         destoffset = decode_rm00_address(rl);
2649         DECODE_PRINTF(",");
2650         destval = fetch_data_byte(destoffset);
2651         srcreg = DECODE_RM_BYTE_REGISTER(rh);
2652         DECODE_PRINTF("\n");
2653         TRACE_AND_STEP();
2654         destval = xor_byte(destval, *srcreg);
2655         store_data_byte(destoffset, destval);
2656         break;
2657     case 1:
2658         destoffset = decode_rm01_address(rl);
2659         DECODE_PRINTF(",");
2660         destval = fetch_data_byte(destoffset);
2661         srcreg = DECODE_RM_BYTE_REGISTER(rh);
2662         DECODE_PRINTF("\n");
2663         TRACE_AND_STEP();
2664         destval = xor_byte(destval, *srcreg);
2665         store_data_byte(destoffset, destval);
2666         break;
2667     case 2:
2668         destoffset = decode_rm10_address(rl);
2669         DECODE_PRINTF(",");
2670         destval = fetch_data_byte(destoffset);
2671         srcreg = DECODE_RM_BYTE_REGISTER(rh);
2672         DECODE_PRINTF("\n");
2673         TRACE_AND_STEP();
2674         destval = xor_byte(destval, *srcreg);
2675         store_data_byte(destoffset, destval);
2676         break;
2677     case 3:                     /* register to register */
2678         destreg = DECODE_RM_BYTE_REGISTER(rl);
2679         DECODE_PRINTF(",");
2680         srcreg = DECODE_RM_BYTE_REGISTER(rh);
2681         DECODE_PRINTF("\n");
2682         TRACE_AND_STEP();
2683         *destreg = xor_byte(*destreg, *srcreg);
2684         break;
2685     }
2686     DECODE_CLEAR_SEGOVR();
2687     END_OF_INSTR();
2688 }
2689 
2690 /****************************************************************************
2691 REMARKS:
2692 Handles opcode 0x31
2693 ****************************************************************************/
x86emuOp_xor_word_RM_R(u8 X86EMU_UNUSED (op1))2694 void x86emuOp_xor_word_RM_R(u8 X86EMU_UNUSED(op1))
2695 {
2696     int mod, rl, rh;
2697     uint destoffset;
2698 
2699     START_OF_INSTR();
2700     DECODE_PRINTF("XOR\t");
2701     FETCH_DECODE_MODRM(mod, rh, rl);
2702     switch (mod) {
2703     case 0:
2704         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2705             u32 destval;
2706             u32 *srcreg;
2707 
2708             destoffset = decode_rm00_address(rl);
2709             DECODE_PRINTF(",");
2710             destval = fetch_data_long(destoffset);
2711             srcreg = DECODE_RM_LONG_REGISTER(rh);
2712             DECODE_PRINTF("\n");
2713             TRACE_AND_STEP();
2714             destval = xor_long(destval, *srcreg);
2715             store_data_long(destoffset, destval);
2716         } else {
2717             u16 destval;
2718             u16 *srcreg;
2719 
2720             destoffset = decode_rm00_address(rl);
2721             DECODE_PRINTF(",");
2722             destval = fetch_data_word(destoffset);
2723             srcreg = DECODE_RM_WORD_REGISTER(rh);
2724             DECODE_PRINTF("\n");
2725             TRACE_AND_STEP();
2726             destval = xor_word(destval, *srcreg);
2727             store_data_word(destoffset, destval);
2728         }
2729         break;
2730     case 1:
2731         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2732             u32 destval;
2733             u32 *srcreg;
2734 
2735             destoffset = decode_rm01_address(rl);
2736             DECODE_PRINTF(",");
2737             destval = fetch_data_long(destoffset);
2738             srcreg = DECODE_RM_LONG_REGISTER(rh);
2739             DECODE_PRINTF("\n");
2740             TRACE_AND_STEP();
2741             destval = xor_long(destval, *srcreg);
2742             store_data_long(destoffset, destval);
2743         } else {
2744             u16 destval;
2745             u16 *srcreg;
2746 
2747             destoffset = decode_rm01_address(rl);
2748             DECODE_PRINTF(",");
2749             destval = fetch_data_word(destoffset);
2750             srcreg = DECODE_RM_WORD_REGISTER(rh);
2751             DECODE_PRINTF("\n");
2752             TRACE_AND_STEP();
2753             destval = xor_word(destval, *srcreg);
2754             store_data_word(destoffset, destval);
2755         }
2756         break;
2757     case 2:
2758         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2759             u32 destval;
2760             u32 *srcreg;
2761 
2762             destoffset = decode_rm10_address(rl);
2763             DECODE_PRINTF(",");
2764             destval = fetch_data_long(destoffset);
2765             srcreg = DECODE_RM_LONG_REGISTER(rh);
2766             DECODE_PRINTF("\n");
2767             TRACE_AND_STEP();
2768             destval = xor_long(destval, *srcreg);
2769             store_data_long(destoffset, destval);
2770         } else {
2771             u16 destval;
2772             u16 *srcreg;
2773 
2774             destoffset = decode_rm10_address(rl);
2775             DECODE_PRINTF(",");
2776             destval = fetch_data_word(destoffset);
2777             srcreg = DECODE_RM_WORD_REGISTER(rh);
2778             DECODE_PRINTF("\n");
2779             TRACE_AND_STEP();
2780             destval = xor_word(destval, *srcreg);
2781             store_data_word(destoffset, destval);
2782         }
2783         break;
2784     case 3:                     /* register to register */
2785         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2786             u32 *destreg,*srcreg;
2787 
2788             destreg = DECODE_RM_LONG_REGISTER(rl);
2789             DECODE_PRINTF(",");
2790             srcreg = DECODE_RM_LONG_REGISTER(rh);
2791             DECODE_PRINTF("\n");
2792             TRACE_AND_STEP();
2793             *destreg = xor_long(*destreg, *srcreg);
2794         } else {
2795             u16 *destreg,*srcreg;
2796 
2797             destreg = DECODE_RM_WORD_REGISTER(rl);
2798             DECODE_PRINTF(",");
2799             srcreg = DECODE_RM_WORD_REGISTER(rh);
2800             DECODE_PRINTF("\n");
2801             TRACE_AND_STEP();
2802             *destreg = xor_word(*destreg, *srcreg);
2803         }
2804         break;
2805     }
2806     DECODE_CLEAR_SEGOVR();
2807     END_OF_INSTR();
2808 }
2809 
2810 /****************************************************************************
2811 REMARKS:
2812 Handles opcode 0x32
2813 ****************************************************************************/
x86emuOp_xor_byte_R_RM(u8 X86EMU_UNUSED (op1))2814 void x86emuOp_xor_byte_R_RM(u8 X86EMU_UNUSED(op1))
2815 {
2816     int mod, rl, rh;
2817     u8 *destreg, *srcreg;
2818     uint srcoffset;
2819     u8 srcval;
2820 
2821     START_OF_INSTR();
2822     DECODE_PRINTF("XOR\t");
2823     FETCH_DECODE_MODRM(mod, rh, rl);
2824     switch (mod) {
2825     case 0:
2826         destreg = DECODE_RM_BYTE_REGISTER(rh);
2827         DECODE_PRINTF(",");
2828         srcoffset = decode_rm00_address(rl);
2829         srcval = fetch_data_byte(srcoffset);
2830         DECODE_PRINTF("\n");
2831         TRACE_AND_STEP();
2832         *destreg = xor_byte(*destreg, srcval);
2833         break;
2834     case 1:
2835         destreg = DECODE_RM_BYTE_REGISTER(rh);
2836         DECODE_PRINTF(",");
2837         srcoffset = decode_rm01_address(rl);
2838         srcval = fetch_data_byte(srcoffset);
2839         DECODE_PRINTF("\n");
2840         TRACE_AND_STEP();
2841         *destreg = xor_byte(*destreg, srcval);
2842         break;
2843     case 2:
2844         destreg = DECODE_RM_BYTE_REGISTER(rh);
2845         DECODE_PRINTF(",");
2846         srcoffset = decode_rm10_address(rl);
2847         srcval = fetch_data_byte(srcoffset);
2848         DECODE_PRINTF("\n");
2849         TRACE_AND_STEP();
2850         *destreg = xor_byte(*destreg, srcval);
2851         break;
2852     case 3:                     /* register to register */
2853         destreg = DECODE_RM_BYTE_REGISTER(rh);
2854         DECODE_PRINTF(",");
2855         srcreg = DECODE_RM_BYTE_REGISTER(rl);
2856         DECODE_PRINTF("\n");
2857         TRACE_AND_STEP();
2858         *destreg = xor_byte(*destreg, *srcreg);
2859         break;
2860     }
2861     DECODE_CLEAR_SEGOVR();
2862     END_OF_INSTR();
2863 }
2864 
2865 /****************************************************************************
2866 REMARKS:
2867 Handles opcode 0x33
2868 ****************************************************************************/
x86emuOp_xor_word_R_RM(u8 X86EMU_UNUSED (op1))2869 void x86emuOp_xor_word_R_RM(u8 X86EMU_UNUSED(op1))
2870 {
2871     int mod, rl, rh;
2872     uint srcoffset;
2873 
2874     START_OF_INSTR();
2875     DECODE_PRINTF("XOR\t");
2876     FETCH_DECODE_MODRM(mod, rh, rl);
2877     switch (mod) {
2878     case 0:
2879         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2880             u32 *destreg;
2881             u32 srcval;
2882 
2883             destreg = DECODE_RM_LONG_REGISTER(rh);
2884             DECODE_PRINTF(",");
2885             srcoffset = decode_rm00_address(rl);
2886             srcval = fetch_data_long(srcoffset);
2887             DECODE_PRINTF("\n");
2888             TRACE_AND_STEP();
2889             *destreg = xor_long(*destreg, srcval);
2890         } else {
2891             u16 *destreg;
2892             u16 srcval;
2893 
2894             destreg = DECODE_RM_WORD_REGISTER(rh);
2895             DECODE_PRINTF(",");
2896             srcoffset = decode_rm00_address(rl);
2897             srcval = fetch_data_word(srcoffset);
2898             DECODE_PRINTF("\n");
2899             TRACE_AND_STEP();
2900             *destreg = xor_word(*destreg, srcval);
2901         }
2902         break;
2903     case 1:
2904         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2905             u32 *destreg;
2906             u32 srcval;
2907 
2908             destreg = DECODE_RM_LONG_REGISTER(rh);
2909             DECODE_PRINTF(",");
2910             srcoffset = decode_rm01_address(rl);
2911             srcval = fetch_data_long(srcoffset);
2912             DECODE_PRINTF("\n");
2913             TRACE_AND_STEP();
2914             *destreg = xor_long(*destreg, srcval);
2915         } else {
2916             u16 *destreg;
2917             u16 srcval;
2918 
2919             destreg = DECODE_RM_WORD_REGISTER(rh);
2920             DECODE_PRINTF(",");
2921             srcoffset = decode_rm01_address(rl);
2922             srcval = fetch_data_word(srcoffset);
2923             DECODE_PRINTF("\n");
2924             TRACE_AND_STEP();
2925             *destreg = xor_word(*destreg, srcval);
2926         }
2927         break;
2928     case 2:
2929         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2930             u32 *destreg;
2931             u32 srcval;
2932 
2933             destreg = DECODE_RM_LONG_REGISTER(rh);
2934             DECODE_PRINTF(",");
2935             srcoffset = decode_rm10_address(rl);
2936             srcval = fetch_data_long(srcoffset);
2937             DECODE_PRINTF("\n");
2938             TRACE_AND_STEP();
2939             *destreg = xor_long(*destreg, srcval);
2940         } else {
2941             u16 *destreg;
2942             u16 srcval;
2943 
2944             destreg = DECODE_RM_WORD_REGISTER(rh);
2945             DECODE_PRINTF(",");
2946             srcoffset = decode_rm10_address(rl);
2947             srcval = fetch_data_word(srcoffset);
2948             DECODE_PRINTF("\n");
2949             TRACE_AND_STEP();
2950             *destreg = xor_word(*destreg, srcval);
2951         }
2952         break;
2953     case 3:                     /* register to register */
2954         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
2955             u32 *destreg,*srcreg;
2956 
2957             destreg = DECODE_RM_LONG_REGISTER(rh);
2958             DECODE_PRINTF(",");
2959             srcreg = DECODE_RM_LONG_REGISTER(rl);
2960             DECODE_PRINTF("\n");
2961             TRACE_AND_STEP();
2962             *destreg = xor_long(*destreg, *srcreg);
2963         } else {
2964             u16 *destreg,*srcreg;
2965 
2966             destreg = DECODE_RM_WORD_REGISTER(rh);
2967             DECODE_PRINTF(",");
2968             srcreg = DECODE_RM_WORD_REGISTER(rl);
2969             DECODE_PRINTF("\n");
2970             TRACE_AND_STEP();
2971             *destreg = xor_word(*destreg, *srcreg);
2972         }
2973         break;
2974     }
2975     DECODE_CLEAR_SEGOVR();
2976     END_OF_INSTR();
2977 }
2978 
2979 /****************************************************************************
2980 REMARKS:
2981 Handles opcode 0x34
2982 ****************************************************************************/
x86emuOp_xor_byte_AL_IMM(u8 X86EMU_UNUSED (op1))2983 void x86emuOp_xor_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
2984 {
2985     u8 srcval;
2986 
2987     START_OF_INSTR();
2988     DECODE_PRINTF("XOR\tAL,");
2989     srcval = fetch_byte_imm();
2990     DECODE_PRINTF2("%x\n", srcval);
2991     TRACE_AND_STEP();
2992     M.x86.R_AL = xor_byte(M.x86.R_AL, srcval);
2993     DECODE_CLEAR_SEGOVR();
2994     END_OF_INSTR();
2995 }
2996 
2997 /****************************************************************************
2998 REMARKS:
2999 Handles opcode 0x35
3000 ****************************************************************************/
x86emuOp_xor_word_AX_IMM(u8 X86EMU_UNUSED (op1))3001 void x86emuOp_xor_word_AX_IMM(u8 X86EMU_UNUSED(op1))
3002 {
3003     u32 srcval;
3004 
3005     START_OF_INSTR();
3006     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3007         DECODE_PRINTF("XOR\tEAX,");
3008         srcval = fetch_long_imm();
3009     } else {
3010         DECODE_PRINTF("XOR\tAX,");
3011         srcval = fetch_word_imm();
3012     }
3013     DECODE_PRINTF2("%x\n", srcval);
3014     TRACE_AND_STEP();
3015     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3016         M.x86.R_EAX = xor_long(M.x86.R_EAX, srcval);
3017     } else {
3018         M.x86.R_AX = xor_word(M.x86.R_AX, (u16)srcval);
3019     }
3020     DECODE_CLEAR_SEGOVR();
3021     END_OF_INSTR();
3022 }
3023 
3024 /****************************************************************************
3025 REMARKS:
3026 Handles opcode 0x36
3027 ****************************************************************************/
x86emuOp_segovr_SS(u8 X86EMU_UNUSED (op1))3028 void x86emuOp_segovr_SS(u8 X86EMU_UNUSED(op1))
3029 {
3030     START_OF_INSTR();
3031     DECODE_PRINTF("SS:\n");
3032     TRACE_AND_STEP();
3033     M.x86.mode |= SYSMODE_SEGOVR_SS;
3034     /* no DECODE_CLEAR_SEGOVR ! */
3035     END_OF_INSTR();
3036 }
3037 
3038 /****************************************************************************
3039 REMARKS:
3040 Handles opcode 0x37
3041 ****************************************************************************/
x86emuOp_aaa(u8 X86EMU_UNUSED (op1))3042 void x86emuOp_aaa(u8 X86EMU_UNUSED(op1))
3043 {
3044     START_OF_INSTR();
3045     DECODE_PRINTF("AAA\n");
3046     TRACE_AND_STEP();
3047     M.x86.R_AX = aaa_word(M.x86.R_AX);
3048     DECODE_CLEAR_SEGOVR();
3049     END_OF_INSTR();
3050 }
3051 
3052 /****************************************************************************
3053 REMARKS:
3054 Handles opcode 0x38
3055 ****************************************************************************/
x86emuOp_cmp_byte_RM_R(u8 X86EMU_UNUSED (op1))3056 void x86emuOp_cmp_byte_RM_R(u8 X86EMU_UNUSED(op1))
3057 {
3058     int mod, rl, rh;
3059     uint destoffset;
3060     u8 *destreg, *srcreg;
3061     u8 destval;
3062 
3063     START_OF_INSTR();
3064     DECODE_PRINTF("CMP\t");
3065     FETCH_DECODE_MODRM(mod, rh, rl);
3066     switch (mod) {
3067     case 0:
3068         destoffset = decode_rm00_address(rl);
3069         DECODE_PRINTF(",");
3070         destval = fetch_data_byte(destoffset);
3071         srcreg = DECODE_RM_BYTE_REGISTER(rh);
3072         DECODE_PRINTF("\n");
3073         TRACE_AND_STEP();
3074         cmp_byte(destval, *srcreg);
3075         break;
3076     case 1:
3077         destoffset = decode_rm01_address(rl);
3078         DECODE_PRINTF(",");
3079         destval = fetch_data_byte(destoffset);
3080         srcreg = DECODE_RM_BYTE_REGISTER(rh);
3081         DECODE_PRINTF("\n");
3082         TRACE_AND_STEP();
3083         cmp_byte(destval, *srcreg);
3084         break;
3085     case 2:
3086         destoffset = decode_rm10_address(rl);
3087         DECODE_PRINTF(",");
3088         destval = fetch_data_byte(destoffset);
3089         srcreg = DECODE_RM_BYTE_REGISTER(rh);
3090         DECODE_PRINTF("\n");
3091         TRACE_AND_STEP();
3092         cmp_byte(destval, *srcreg);
3093         break;
3094     case 3:                     /* register to register */
3095         destreg = DECODE_RM_BYTE_REGISTER(rl);
3096         DECODE_PRINTF(",");
3097         srcreg = DECODE_RM_BYTE_REGISTER(rh);
3098         DECODE_PRINTF("\n");
3099         TRACE_AND_STEP();
3100         cmp_byte(*destreg, *srcreg);
3101         break;
3102     }
3103     DECODE_CLEAR_SEGOVR();
3104     END_OF_INSTR();
3105 }
3106 
3107 /****************************************************************************
3108 REMARKS:
3109 Handles opcode 0x39
3110 ****************************************************************************/
x86emuOp_cmp_word_RM_R(u8 X86EMU_UNUSED (op1))3111 void x86emuOp_cmp_word_RM_R(u8 X86EMU_UNUSED(op1))
3112 {
3113     int mod, rl, rh;
3114     uint destoffset;
3115 
3116     START_OF_INSTR();
3117     DECODE_PRINTF("CMP\t");
3118     FETCH_DECODE_MODRM(mod, rh, rl);
3119     switch (mod) {
3120     case 0:
3121         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3122             u32 destval;
3123             u32 *srcreg;
3124 
3125             destoffset = decode_rm00_address(rl);
3126             DECODE_PRINTF(",");
3127             destval = fetch_data_long(destoffset);
3128             srcreg = DECODE_RM_LONG_REGISTER(rh);
3129             DECODE_PRINTF("\n");
3130             TRACE_AND_STEP();
3131             cmp_long(destval, *srcreg);
3132         } else {
3133             u16 destval;
3134             u16 *srcreg;
3135 
3136             destoffset = decode_rm00_address(rl);
3137             DECODE_PRINTF(",");
3138             destval = fetch_data_word(destoffset);
3139             srcreg = DECODE_RM_WORD_REGISTER(rh);
3140             DECODE_PRINTF("\n");
3141             TRACE_AND_STEP();
3142             cmp_word(destval, *srcreg);
3143         }
3144         break;
3145     case 1:
3146         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3147             u32 destval;
3148             u32 *srcreg;
3149 
3150             destoffset = decode_rm01_address(rl);
3151             DECODE_PRINTF(",");
3152             destval = fetch_data_long(destoffset);
3153             srcreg = DECODE_RM_LONG_REGISTER(rh);
3154             DECODE_PRINTF("\n");
3155             TRACE_AND_STEP();
3156             cmp_long(destval, *srcreg);
3157         } else {
3158             u16 destval;
3159             u16 *srcreg;
3160 
3161             destoffset = decode_rm01_address(rl);
3162             DECODE_PRINTF(",");
3163             destval = fetch_data_word(destoffset);
3164             srcreg = DECODE_RM_WORD_REGISTER(rh);
3165             DECODE_PRINTF("\n");
3166             TRACE_AND_STEP();
3167             cmp_word(destval, *srcreg);
3168         }
3169         break;
3170     case 2:
3171         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3172             u32 destval;
3173             u32 *srcreg;
3174 
3175             destoffset = decode_rm10_address(rl);
3176             DECODE_PRINTF(",");
3177             destval = fetch_data_long(destoffset);
3178             srcreg = DECODE_RM_LONG_REGISTER(rh);
3179             DECODE_PRINTF("\n");
3180             TRACE_AND_STEP();
3181             cmp_long(destval, *srcreg);
3182         } else {
3183             u16 destval;
3184             u16 *srcreg;
3185 
3186             destoffset = decode_rm10_address(rl);
3187             DECODE_PRINTF(",");
3188             destval = fetch_data_word(destoffset);
3189             srcreg = DECODE_RM_WORD_REGISTER(rh);
3190             DECODE_PRINTF("\n");
3191             TRACE_AND_STEP();
3192             cmp_word(destval, *srcreg);
3193         }
3194         break;
3195     case 3:                     /* register to register */
3196         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3197             u32 *destreg,*srcreg;
3198 
3199             destreg = DECODE_RM_LONG_REGISTER(rl);
3200             DECODE_PRINTF(",");
3201             srcreg = DECODE_RM_LONG_REGISTER(rh);
3202             DECODE_PRINTF("\n");
3203             TRACE_AND_STEP();
3204             cmp_long(*destreg, *srcreg);
3205         } else {
3206             u16 *destreg,*srcreg;
3207 
3208             destreg = DECODE_RM_WORD_REGISTER(rl);
3209             DECODE_PRINTF(",");
3210             srcreg = DECODE_RM_WORD_REGISTER(rh);
3211             DECODE_PRINTF("\n");
3212             TRACE_AND_STEP();
3213             cmp_word(*destreg, *srcreg);
3214         }
3215         break;
3216     }
3217     DECODE_CLEAR_SEGOVR();
3218     END_OF_INSTR();
3219 }
3220 
3221 /****************************************************************************
3222 REMARKS:
3223 Handles opcode 0x3a
3224 ****************************************************************************/
x86emuOp_cmp_byte_R_RM(u8 X86EMU_UNUSED (op1))3225 void x86emuOp_cmp_byte_R_RM(u8 X86EMU_UNUSED(op1))
3226 {
3227     int mod, rl, rh;
3228     u8 *destreg, *srcreg;
3229     uint srcoffset;
3230     u8 srcval;
3231 
3232     START_OF_INSTR();
3233     DECODE_PRINTF("CMP\t");
3234     FETCH_DECODE_MODRM(mod, rh, rl);
3235     switch (mod) {
3236     case 0:
3237         destreg = DECODE_RM_BYTE_REGISTER(rh);
3238         DECODE_PRINTF(",");
3239         srcoffset = decode_rm00_address(rl);
3240         srcval = fetch_data_byte(srcoffset);
3241         DECODE_PRINTF("\n");
3242         TRACE_AND_STEP();
3243         cmp_byte(*destreg, srcval);
3244         break;
3245     case 1:
3246         destreg = DECODE_RM_BYTE_REGISTER(rh);
3247         DECODE_PRINTF(",");
3248         srcoffset = decode_rm01_address(rl);
3249         srcval = fetch_data_byte(srcoffset);
3250         DECODE_PRINTF("\n");
3251         TRACE_AND_STEP();
3252         cmp_byte(*destreg, srcval);
3253         break;
3254     case 2:
3255         destreg = DECODE_RM_BYTE_REGISTER(rh);
3256         DECODE_PRINTF(",");
3257         srcoffset = decode_rm10_address(rl);
3258         srcval = fetch_data_byte(srcoffset);
3259         DECODE_PRINTF("\n");
3260         TRACE_AND_STEP();
3261         cmp_byte(*destreg, srcval);
3262         break;
3263     case 3:                     /* register to register */
3264         destreg = DECODE_RM_BYTE_REGISTER(rh);
3265         DECODE_PRINTF(",");
3266         srcreg = DECODE_RM_BYTE_REGISTER(rl);
3267         DECODE_PRINTF("\n");
3268         TRACE_AND_STEP();
3269         cmp_byte(*destreg, *srcreg);
3270         break;
3271     }
3272     DECODE_CLEAR_SEGOVR();
3273     END_OF_INSTR();
3274 }
3275 
3276 /****************************************************************************
3277 REMARKS:
3278 Handles opcode 0x3b
3279 ****************************************************************************/
x86emuOp_cmp_word_R_RM(u8 X86EMU_UNUSED (op1))3280 void x86emuOp_cmp_word_R_RM(u8 X86EMU_UNUSED(op1))
3281 {
3282     int mod, rl, rh;
3283     uint srcoffset;
3284 
3285     START_OF_INSTR();
3286     DECODE_PRINTF("CMP\t");
3287     FETCH_DECODE_MODRM(mod, rh, rl);
3288     switch (mod) {
3289     case 0:
3290         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3291             u32 *destreg;
3292             u32 srcval;
3293 
3294             destreg = DECODE_RM_LONG_REGISTER(rh);
3295             DECODE_PRINTF(",");
3296             srcoffset = decode_rm00_address(rl);
3297             srcval = fetch_data_long(srcoffset);
3298             DECODE_PRINTF("\n");
3299             TRACE_AND_STEP();
3300             cmp_long(*destreg, srcval);
3301         } else {
3302             u16 *destreg;
3303             u16 srcval;
3304 
3305             destreg = DECODE_RM_WORD_REGISTER(rh);
3306             DECODE_PRINTF(",");
3307             srcoffset = decode_rm00_address(rl);
3308             srcval = fetch_data_word(srcoffset);
3309             DECODE_PRINTF("\n");
3310             TRACE_AND_STEP();
3311             cmp_word(*destreg, srcval);
3312         }
3313         break;
3314     case 1:
3315         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3316             u32 *destreg;
3317             u32 srcval;
3318 
3319             destreg = DECODE_RM_LONG_REGISTER(rh);
3320             DECODE_PRINTF(",");
3321             srcoffset = decode_rm01_address(rl);
3322             srcval = fetch_data_long(srcoffset);
3323             DECODE_PRINTF("\n");
3324             TRACE_AND_STEP();
3325             cmp_long(*destreg, srcval);
3326         } else {
3327             u16 *destreg;
3328             u16 srcval;
3329 
3330             destreg = DECODE_RM_WORD_REGISTER(rh);
3331             DECODE_PRINTF(",");
3332             srcoffset = decode_rm01_address(rl);
3333             srcval = fetch_data_word(srcoffset);
3334             DECODE_PRINTF("\n");
3335             TRACE_AND_STEP();
3336             cmp_word(*destreg, srcval);
3337         }
3338         break;
3339     case 2:
3340         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3341             u32 *destreg;
3342             u32 srcval;
3343 
3344             destreg = DECODE_RM_LONG_REGISTER(rh);
3345             DECODE_PRINTF(",");
3346             srcoffset = decode_rm10_address(rl);
3347             srcval = fetch_data_long(srcoffset);
3348             DECODE_PRINTF("\n");
3349             TRACE_AND_STEP();
3350             cmp_long(*destreg, srcval);
3351         } else {
3352             u16 *destreg;
3353             u16 srcval;
3354 
3355             destreg = DECODE_RM_WORD_REGISTER(rh);
3356             DECODE_PRINTF(",");
3357             srcoffset = decode_rm10_address(rl);
3358             srcval = fetch_data_word(srcoffset);
3359             DECODE_PRINTF("\n");
3360             TRACE_AND_STEP();
3361             cmp_word(*destreg, srcval);
3362         }
3363         break;
3364     case 3:                     /* register to register */
3365         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3366             u32 *destreg,*srcreg;
3367 
3368             destreg = DECODE_RM_LONG_REGISTER(rh);
3369             DECODE_PRINTF(",");
3370             srcreg = DECODE_RM_LONG_REGISTER(rl);
3371             DECODE_PRINTF("\n");
3372             TRACE_AND_STEP();
3373             cmp_long(*destreg, *srcreg);
3374         } else {
3375             u16 *destreg,*srcreg;
3376 
3377             destreg = DECODE_RM_WORD_REGISTER(rh);
3378             DECODE_PRINTF(",");
3379             srcreg = DECODE_RM_WORD_REGISTER(rl);
3380             DECODE_PRINTF("\n");
3381             TRACE_AND_STEP();
3382             cmp_word(*destreg, *srcreg);
3383         }
3384         break;
3385     }
3386     DECODE_CLEAR_SEGOVR();
3387     END_OF_INSTR();
3388 }
3389 
3390 /****************************************************************************
3391 REMARKS:
3392 Handles opcode 0x3c
3393 ****************************************************************************/
x86emuOp_cmp_byte_AL_IMM(u8 X86EMU_UNUSED (op1))3394 void x86emuOp_cmp_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
3395 {
3396     u8 srcval;
3397 
3398     START_OF_INSTR();
3399     DECODE_PRINTF("CMP\tAL,");
3400     srcval = fetch_byte_imm();
3401     DECODE_PRINTF2("%x\n", srcval);
3402     TRACE_AND_STEP();
3403     cmp_byte(M.x86.R_AL, srcval);
3404     DECODE_CLEAR_SEGOVR();
3405     END_OF_INSTR();
3406 }
3407 
3408 /****************************************************************************
3409 REMARKS:
3410 Handles opcode 0x3d
3411 ****************************************************************************/
x86emuOp_cmp_word_AX_IMM(u8 X86EMU_UNUSED (op1))3412 void x86emuOp_cmp_word_AX_IMM(u8 X86EMU_UNUSED(op1))
3413 {
3414     u32 srcval;
3415 
3416     START_OF_INSTR();
3417     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3418         DECODE_PRINTF("CMP\tEAX,");
3419         srcval = fetch_long_imm();
3420     } else {
3421         DECODE_PRINTF("CMP\tAX,");
3422         srcval = fetch_word_imm();
3423     }
3424     DECODE_PRINTF2("%x\n", srcval);
3425     TRACE_AND_STEP();
3426     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3427         cmp_long(M.x86.R_EAX, srcval);
3428     } else {
3429         cmp_word(M.x86.R_AX, (u16)srcval);
3430     }
3431     DECODE_CLEAR_SEGOVR();
3432     END_OF_INSTR();
3433 }
3434 
3435 /****************************************************************************
3436 REMARKS:
3437 Handles opcode 0x3e
3438 ****************************************************************************/
x86emuOp_segovr_DS(u8 X86EMU_UNUSED (op1))3439 void x86emuOp_segovr_DS(u8 X86EMU_UNUSED(op1))
3440 {
3441     START_OF_INSTR();
3442     DECODE_PRINTF("DS:\n");
3443     TRACE_AND_STEP();
3444     M.x86.mode |= SYSMODE_SEGOVR_DS;
3445     /* NO DECODE_CLEAR_SEGOVR! */
3446     END_OF_INSTR();
3447 }
3448 
3449 /****************************************************************************
3450 REMARKS:
3451 Handles opcode 0x3f
3452 ****************************************************************************/
x86emuOp_aas(u8 X86EMU_UNUSED (op1))3453 void x86emuOp_aas(u8 X86EMU_UNUSED(op1))
3454 {
3455     START_OF_INSTR();
3456     DECODE_PRINTF("AAS\n");
3457     TRACE_AND_STEP();
3458     M.x86.R_AX = aas_word(M.x86.R_AX);
3459     DECODE_CLEAR_SEGOVR();
3460     END_OF_INSTR();
3461 }
3462 
3463 /****************************************************************************
3464 REMARKS:
3465 Handles opcode 0x40
3466 ****************************************************************************/
x86emuOp_inc_AX(u8 X86EMU_UNUSED (op1))3467 void x86emuOp_inc_AX(u8 X86EMU_UNUSED(op1))
3468 {
3469     START_OF_INSTR();
3470     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3471         DECODE_PRINTF("INC\tEAX\n");
3472     } else {
3473         DECODE_PRINTF("INC\tAX\n");
3474     }
3475     TRACE_AND_STEP();
3476     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3477         M.x86.R_EAX = inc_long(M.x86.R_EAX);
3478     } else {
3479         M.x86.R_AX = inc_word(M.x86.R_AX);
3480     }
3481     DECODE_CLEAR_SEGOVR();
3482     END_OF_INSTR();
3483 }
3484 
3485 /****************************************************************************
3486 REMARKS:
3487 Handles opcode 0x41
3488 ****************************************************************************/
x86emuOp_inc_CX(u8 X86EMU_UNUSED (op1))3489 void x86emuOp_inc_CX(u8 X86EMU_UNUSED(op1))
3490 {
3491     START_OF_INSTR();
3492     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3493         DECODE_PRINTF("INC\tECX\n");
3494     } else {
3495         DECODE_PRINTF("INC\tCX\n");
3496     }
3497     TRACE_AND_STEP();
3498     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3499         M.x86.R_ECX = inc_long(M.x86.R_ECX);
3500     } else {
3501         M.x86.R_CX = inc_word(M.x86.R_CX);
3502     }
3503     DECODE_CLEAR_SEGOVR();
3504     END_OF_INSTR();
3505 }
3506 
3507 /****************************************************************************
3508 REMARKS:
3509 Handles opcode 0x42
3510 ****************************************************************************/
x86emuOp_inc_DX(u8 X86EMU_UNUSED (op1))3511 void x86emuOp_inc_DX(u8 X86EMU_UNUSED(op1))
3512 {
3513     START_OF_INSTR();
3514     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3515         DECODE_PRINTF("INC\tEDX\n");
3516     } else {
3517         DECODE_PRINTF("INC\tDX\n");
3518     }
3519     TRACE_AND_STEP();
3520     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3521         M.x86.R_EDX = inc_long(M.x86.R_EDX);
3522     } else {
3523         M.x86.R_DX = inc_word(M.x86.R_DX);
3524     }
3525     DECODE_CLEAR_SEGOVR();
3526     END_OF_INSTR();
3527 }
3528 
3529 /****************************************************************************
3530 REMARKS:
3531 Handles opcode 0x43
3532 ****************************************************************************/
x86emuOp_inc_BX(u8 X86EMU_UNUSED (op1))3533 void x86emuOp_inc_BX(u8 X86EMU_UNUSED(op1))
3534 {
3535     START_OF_INSTR();
3536     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3537         DECODE_PRINTF("INC\tEBX\n");
3538     } else {
3539         DECODE_PRINTF("INC\tBX\n");
3540     }
3541     TRACE_AND_STEP();
3542     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3543         M.x86.R_EBX = inc_long(M.x86.R_EBX);
3544     } else {
3545         M.x86.R_BX = inc_word(M.x86.R_BX);
3546     }
3547     DECODE_CLEAR_SEGOVR();
3548     END_OF_INSTR();
3549 }
3550 
3551 /****************************************************************************
3552 REMARKS:
3553 Handles opcode 0x44
3554 ****************************************************************************/
x86emuOp_inc_SP(u8 X86EMU_UNUSED (op1))3555 void x86emuOp_inc_SP(u8 X86EMU_UNUSED(op1))
3556 {
3557     START_OF_INSTR();
3558     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3559         DECODE_PRINTF("INC\tESP\n");
3560     } else {
3561         DECODE_PRINTF("INC\tSP\n");
3562     }
3563     TRACE_AND_STEP();
3564     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3565         M.x86.R_ESP = inc_long(M.x86.R_ESP);
3566     } else {
3567         M.x86.R_SP = inc_word(M.x86.R_SP);
3568     }
3569     DECODE_CLEAR_SEGOVR();
3570     END_OF_INSTR();
3571 }
3572 
3573 /****************************************************************************
3574 REMARKS:
3575 Handles opcode 0x45
3576 ****************************************************************************/
x86emuOp_inc_BP(u8 X86EMU_UNUSED (op1))3577 void x86emuOp_inc_BP(u8 X86EMU_UNUSED(op1))
3578 {
3579     START_OF_INSTR();
3580     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3581         DECODE_PRINTF("INC\tEBP\n");
3582     } else {
3583         DECODE_PRINTF("INC\tBP\n");
3584     }
3585     TRACE_AND_STEP();
3586     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3587         M.x86.R_EBP = inc_long(M.x86.R_EBP);
3588     } else {
3589         M.x86.R_BP = inc_word(M.x86.R_BP);
3590     }
3591     DECODE_CLEAR_SEGOVR();
3592     END_OF_INSTR();
3593 }
3594 
3595 /****************************************************************************
3596 REMARKS:
3597 Handles opcode 0x46
3598 ****************************************************************************/
x86emuOp_inc_SI(u8 X86EMU_UNUSED (op1))3599 void x86emuOp_inc_SI(u8 X86EMU_UNUSED(op1))
3600 {
3601     START_OF_INSTR();
3602     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3603         DECODE_PRINTF("INC\tESI\n");
3604     } else {
3605         DECODE_PRINTF("INC\tSI\n");
3606     }
3607     TRACE_AND_STEP();
3608     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3609         M.x86.R_ESI = inc_long(M.x86.R_ESI);
3610     } else {
3611         M.x86.R_SI = inc_word(M.x86.R_SI);
3612     }
3613     DECODE_CLEAR_SEGOVR();
3614     END_OF_INSTR();
3615 }
3616 
3617 /****************************************************************************
3618 REMARKS:
3619 Handles opcode 0x47
3620 ****************************************************************************/
x86emuOp_inc_DI(u8 X86EMU_UNUSED (op1))3621 void x86emuOp_inc_DI(u8 X86EMU_UNUSED(op1))
3622 {
3623     START_OF_INSTR();
3624     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3625         DECODE_PRINTF("INC\tEDI\n");
3626     } else {
3627         DECODE_PRINTF("INC\tDI\n");
3628     }
3629     TRACE_AND_STEP();
3630     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3631         M.x86.R_EDI = inc_long(M.x86.R_EDI);
3632     } else {
3633         M.x86.R_DI = inc_word(M.x86.R_DI);
3634     }
3635     DECODE_CLEAR_SEGOVR();
3636     END_OF_INSTR();
3637 }
3638 
3639 /****************************************************************************
3640 REMARKS:
3641 Handles opcode 0x48
3642 ****************************************************************************/
x86emuOp_dec_AX(u8 X86EMU_UNUSED (op1))3643 void x86emuOp_dec_AX(u8 X86EMU_UNUSED(op1))
3644 {
3645     START_OF_INSTR();
3646     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3647         DECODE_PRINTF("DEC\tEAX\n");
3648     } else {
3649         DECODE_PRINTF("DEC\tAX\n");
3650     }
3651     TRACE_AND_STEP();
3652     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3653         M.x86.R_EAX = dec_long(M.x86.R_EAX);
3654     } else {
3655         M.x86.R_AX = dec_word(M.x86.R_AX);
3656     }
3657     DECODE_CLEAR_SEGOVR();
3658     END_OF_INSTR();
3659 }
3660 
3661 /****************************************************************************
3662 REMARKS:
3663 Handles opcode 0x49
3664 ****************************************************************************/
x86emuOp_dec_CX(u8 X86EMU_UNUSED (op1))3665 void x86emuOp_dec_CX(u8 X86EMU_UNUSED(op1))
3666 {
3667     START_OF_INSTR();
3668     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3669         DECODE_PRINTF("DEC\tECX\n");
3670     } else {
3671         DECODE_PRINTF("DEC\tCX\n");
3672     }
3673     TRACE_AND_STEP();
3674     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3675         M.x86.R_ECX = dec_long(M.x86.R_ECX);
3676     } else {
3677         M.x86.R_CX = dec_word(M.x86.R_CX);
3678     }
3679     DECODE_CLEAR_SEGOVR();
3680     END_OF_INSTR();
3681 }
3682 
3683 /****************************************************************************
3684 REMARKS:
3685 Handles opcode 0x4a
3686 ****************************************************************************/
x86emuOp_dec_DX(u8 X86EMU_UNUSED (op1))3687 void x86emuOp_dec_DX(u8 X86EMU_UNUSED(op1))
3688 {
3689     START_OF_INSTR();
3690     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3691         DECODE_PRINTF("DEC\tEDX\n");
3692     } else {
3693         DECODE_PRINTF("DEC\tDX\n");
3694     }
3695     TRACE_AND_STEP();
3696     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3697         M.x86.R_EDX = dec_long(M.x86.R_EDX);
3698     } else {
3699         M.x86.R_DX = dec_word(M.x86.R_DX);
3700     }
3701     DECODE_CLEAR_SEGOVR();
3702     END_OF_INSTR();
3703 }
3704 
3705 /****************************************************************************
3706 REMARKS:
3707 Handles opcode 0x4b
3708 ****************************************************************************/
x86emuOp_dec_BX(u8 X86EMU_UNUSED (op1))3709 void x86emuOp_dec_BX(u8 X86EMU_UNUSED(op1))
3710 {
3711     START_OF_INSTR();
3712     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3713         DECODE_PRINTF("DEC\tEBX\n");
3714     } else {
3715         DECODE_PRINTF("DEC\tBX\n");
3716     }
3717     TRACE_AND_STEP();
3718     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3719         M.x86.R_EBX = dec_long(M.x86.R_EBX);
3720     } else {
3721         M.x86.R_BX = dec_word(M.x86.R_BX);
3722     }
3723     DECODE_CLEAR_SEGOVR();
3724     END_OF_INSTR();
3725 }
3726 
3727 /****************************************************************************
3728 REMARKS:
3729 Handles opcode 0x4c
3730 ****************************************************************************/
x86emuOp_dec_SP(u8 X86EMU_UNUSED (op1))3731 void x86emuOp_dec_SP(u8 X86EMU_UNUSED(op1))
3732 {
3733     START_OF_INSTR();
3734     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3735         DECODE_PRINTF("DEC\tESP\n");
3736     } else {
3737         DECODE_PRINTF("DEC\tSP\n");
3738     }
3739     TRACE_AND_STEP();
3740     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3741         M.x86.R_ESP = dec_long(M.x86.R_ESP);
3742     } else {
3743         M.x86.R_SP = dec_word(M.x86.R_SP);
3744     }
3745     DECODE_CLEAR_SEGOVR();
3746     END_OF_INSTR();
3747 }
3748 
3749 /****************************************************************************
3750 REMARKS:
3751 Handles opcode 0x4d
3752 ****************************************************************************/
x86emuOp_dec_BP(u8 X86EMU_UNUSED (op1))3753 void x86emuOp_dec_BP(u8 X86EMU_UNUSED(op1))
3754 {
3755     START_OF_INSTR();
3756     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3757         DECODE_PRINTF("DEC\tEBP\n");
3758     } else {
3759         DECODE_PRINTF("DEC\tBP\n");
3760     }
3761     TRACE_AND_STEP();
3762     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3763         M.x86.R_EBP = dec_long(M.x86.R_EBP);
3764     } else {
3765         M.x86.R_BP = dec_word(M.x86.R_BP);
3766     }
3767     DECODE_CLEAR_SEGOVR();
3768     END_OF_INSTR();
3769 }
3770 
3771 /****************************************************************************
3772 REMARKS:
3773 Handles opcode 0x4e
3774 ****************************************************************************/
x86emuOp_dec_SI(u8 X86EMU_UNUSED (op1))3775 void x86emuOp_dec_SI(u8 X86EMU_UNUSED(op1))
3776 {
3777     START_OF_INSTR();
3778     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3779         DECODE_PRINTF("DEC\tESI\n");
3780     } else {
3781         DECODE_PRINTF("DEC\tSI\n");
3782     }
3783     TRACE_AND_STEP();
3784     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3785         M.x86.R_ESI = dec_long(M.x86.R_ESI);
3786     } else {
3787         M.x86.R_SI = dec_word(M.x86.R_SI);
3788     }
3789     DECODE_CLEAR_SEGOVR();
3790     END_OF_INSTR();
3791 }
3792 
3793 /****************************************************************************
3794 REMARKS:
3795 Handles opcode 0x4f
3796 ****************************************************************************/
x86emuOp_dec_DI(u8 X86EMU_UNUSED (op1))3797 void x86emuOp_dec_DI(u8 X86EMU_UNUSED(op1))
3798 {
3799     START_OF_INSTR();
3800     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3801         DECODE_PRINTF("DEC\tEDI\n");
3802     } else {
3803         DECODE_PRINTF("DEC\tDI\n");
3804     }
3805     TRACE_AND_STEP();
3806     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3807         M.x86.R_EDI = dec_long(M.x86.R_EDI);
3808     } else {
3809         M.x86.R_DI = dec_word(M.x86.R_DI);
3810     }
3811     DECODE_CLEAR_SEGOVR();
3812     END_OF_INSTR();
3813 }
3814 
3815 /****************************************************************************
3816 REMARKS:
3817 Handles opcode 0x50
3818 ****************************************************************************/
x86emuOp_push_AX(u8 X86EMU_UNUSED (op1))3819 void x86emuOp_push_AX(u8 X86EMU_UNUSED(op1))
3820 {
3821     START_OF_INSTR();
3822     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3823         DECODE_PRINTF("PUSH\tEAX\n");
3824     } else {
3825         DECODE_PRINTF("PUSH\tAX\n");
3826     }
3827     TRACE_AND_STEP();
3828     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3829         push_long(M.x86.R_EAX);
3830     } else {
3831         push_word(M.x86.R_AX);
3832     }
3833     DECODE_CLEAR_SEGOVR();
3834     END_OF_INSTR();
3835 }
3836 
3837 /****************************************************************************
3838 REMARKS:
3839 Handles opcode 0x51
3840 ****************************************************************************/
x86emuOp_push_CX(u8 X86EMU_UNUSED (op1))3841 void x86emuOp_push_CX(u8 X86EMU_UNUSED(op1))
3842 {
3843     START_OF_INSTR();
3844     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3845         DECODE_PRINTF("PUSH\tECX\n");
3846     } else {
3847         DECODE_PRINTF("PUSH\tCX\n");
3848     }
3849     TRACE_AND_STEP();
3850     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3851         push_long(M.x86.R_ECX);
3852     } else {
3853         push_word(M.x86.R_CX);
3854     }
3855     DECODE_CLEAR_SEGOVR();
3856     END_OF_INSTR();
3857 }
3858 
3859 /****************************************************************************
3860 REMARKS:
3861 Handles opcode 0x52
3862 ****************************************************************************/
x86emuOp_push_DX(u8 X86EMU_UNUSED (op1))3863 void x86emuOp_push_DX(u8 X86EMU_UNUSED(op1))
3864 {
3865     START_OF_INSTR();
3866     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3867         DECODE_PRINTF("PUSH\tEDX\n");
3868     } else {
3869         DECODE_PRINTF("PUSH\tDX\n");
3870     }
3871     TRACE_AND_STEP();
3872     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3873         push_long(M.x86.R_EDX);
3874     } else {
3875         push_word(M.x86.R_DX);
3876     }
3877     DECODE_CLEAR_SEGOVR();
3878     END_OF_INSTR();
3879 }
3880 
3881 /****************************************************************************
3882 REMARKS:
3883 Handles opcode 0x53
3884 ****************************************************************************/
x86emuOp_push_BX(u8 X86EMU_UNUSED (op1))3885 void x86emuOp_push_BX(u8 X86EMU_UNUSED(op1))
3886 {
3887     START_OF_INSTR();
3888     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3889         DECODE_PRINTF("PUSH\tEBX\n");
3890     } else {
3891         DECODE_PRINTF("PUSH\tBX\n");
3892     }
3893     TRACE_AND_STEP();
3894     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3895         push_long(M.x86.R_EBX);
3896     } else {
3897         push_word(M.x86.R_BX);
3898     }
3899     DECODE_CLEAR_SEGOVR();
3900     END_OF_INSTR();
3901 }
3902 
3903 /****************************************************************************
3904 REMARKS:
3905 Handles opcode 0x54
3906 ****************************************************************************/
x86emuOp_push_SP(u8 X86EMU_UNUSED (op1))3907 void x86emuOp_push_SP(u8 X86EMU_UNUSED(op1))
3908 {
3909     START_OF_INSTR();
3910     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3911         DECODE_PRINTF("PUSH\tESP\n");
3912     } else {
3913         DECODE_PRINTF("PUSH\tSP\n");
3914     }
3915     TRACE_AND_STEP();
3916     /* Always push (E)SP, since we are emulating an i386 and above
3917      * processor. This is necessary as some BIOS'es use this to check
3918      * what type of processor is in the system.
3919      */
3920     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3921         push_long(M.x86.R_ESP);
3922     } else {
3923         push_word((u16)(M.x86.R_SP));
3924     }
3925     DECODE_CLEAR_SEGOVR();
3926     END_OF_INSTR();
3927 }
3928 
3929 /****************************************************************************
3930 REMARKS:
3931 Handles opcode 0x55
3932 ****************************************************************************/
x86emuOp_push_BP(u8 X86EMU_UNUSED (op1))3933 void x86emuOp_push_BP(u8 X86EMU_UNUSED(op1))
3934 {
3935     START_OF_INSTR();
3936     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3937         DECODE_PRINTF("PUSH\tEBP\n");
3938     } else {
3939         DECODE_PRINTF("PUSH\tBP\n");
3940     }
3941     TRACE_AND_STEP();
3942     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3943         push_long(M.x86.R_EBP);
3944     } else {
3945         push_word(M.x86.R_BP);
3946     }
3947     DECODE_CLEAR_SEGOVR();
3948     END_OF_INSTR();
3949 }
3950 
3951 /****************************************************************************
3952 REMARKS:
3953 Handles opcode 0x56
3954 ****************************************************************************/
x86emuOp_push_SI(u8 X86EMU_UNUSED (op1))3955 void x86emuOp_push_SI(u8 X86EMU_UNUSED(op1))
3956 {
3957     START_OF_INSTR();
3958     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3959         DECODE_PRINTF("PUSH\tESI\n");
3960     } else {
3961         DECODE_PRINTF("PUSH\tSI\n");
3962     }
3963     TRACE_AND_STEP();
3964     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3965         push_long(M.x86.R_ESI);
3966     } else {
3967         push_word(M.x86.R_SI);
3968     }
3969     DECODE_CLEAR_SEGOVR();
3970     END_OF_INSTR();
3971 }
3972 
3973 /****************************************************************************
3974 REMARKS:
3975 Handles opcode 0x57
3976 ****************************************************************************/
x86emuOp_push_DI(u8 X86EMU_UNUSED (op1))3977 void x86emuOp_push_DI(u8 X86EMU_UNUSED(op1))
3978 {
3979     START_OF_INSTR();
3980     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3981         DECODE_PRINTF("PUSH\tEDI\n");
3982     } else {
3983         DECODE_PRINTF("PUSH\tDI\n");
3984     }
3985     TRACE_AND_STEP();
3986     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
3987         push_long(M.x86.R_EDI);
3988     } else {
3989         push_word(M.x86.R_DI);
3990     }
3991     DECODE_CLEAR_SEGOVR();
3992     END_OF_INSTR();
3993 }
3994 
3995 /****************************************************************************
3996 REMARKS:
3997 Handles opcode 0x58
3998 ****************************************************************************/
x86emuOp_pop_AX(u8 X86EMU_UNUSED (op1))3999 void x86emuOp_pop_AX(u8 X86EMU_UNUSED(op1))
4000 {
4001     START_OF_INSTR();
4002     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4003         DECODE_PRINTF("POP\tEAX\n");
4004     } else {
4005         DECODE_PRINTF("POP\tAX\n");
4006     }
4007     TRACE_AND_STEP();
4008     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4009         M.x86.R_EAX = pop_long();
4010     } else {
4011         M.x86.R_AX = pop_word();
4012     }
4013     DECODE_CLEAR_SEGOVR();
4014     END_OF_INSTR();
4015 }
4016 
4017 /****************************************************************************
4018 REMARKS:
4019 Handles opcode 0x59
4020 ****************************************************************************/
x86emuOp_pop_CX(u8 X86EMU_UNUSED (op1))4021 void x86emuOp_pop_CX(u8 X86EMU_UNUSED(op1))
4022 {
4023     START_OF_INSTR();
4024     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4025         DECODE_PRINTF("POP\tECX\n");
4026     } else {
4027         DECODE_PRINTF("POP\tCX\n");
4028     }
4029     TRACE_AND_STEP();
4030     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4031         M.x86.R_ECX = pop_long();
4032     } else {
4033         M.x86.R_CX = pop_word();
4034     }
4035     DECODE_CLEAR_SEGOVR();
4036     END_OF_INSTR();
4037 }
4038 
4039 /****************************************************************************
4040 REMARKS:
4041 Handles opcode 0x5a
4042 ****************************************************************************/
x86emuOp_pop_DX(u8 X86EMU_UNUSED (op1))4043 void x86emuOp_pop_DX(u8 X86EMU_UNUSED(op1))
4044 {
4045     START_OF_INSTR();
4046     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4047         DECODE_PRINTF("POP\tEDX\n");
4048     } else {
4049         DECODE_PRINTF("POP\tDX\n");
4050     }
4051     TRACE_AND_STEP();
4052     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4053         M.x86.R_EDX = pop_long();
4054     } else {
4055         M.x86.R_DX = pop_word();
4056     }
4057     DECODE_CLEAR_SEGOVR();
4058     END_OF_INSTR();
4059 }
4060 
4061 /****************************************************************************
4062 REMARKS:
4063 Handles opcode 0x5b
4064 ****************************************************************************/
x86emuOp_pop_BX(u8 X86EMU_UNUSED (op1))4065 void x86emuOp_pop_BX(u8 X86EMU_UNUSED(op1))
4066 {
4067     START_OF_INSTR();
4068     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4069         DECODE_PRINTF("POP\tEBX\n");
4070     } else {
4071         DECODE_PRINTF("POP\tBX\n");
4072     }
4073     TRACE_AND_STEP();
4074     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4075         M.x86.R_EBX = pop_long();
4076     } else {
4077         M.x86.R_BX = pop_word();
4078     }
4079     DECODE_CLEAR_SEGOVR();
4080     END_OF_INSTR();
4081 }
4082 
4083 /****************************************************************************
4084 REMARKS:
4085 Handles opcode 0x5c
4086 ****************************************************************************/
x86emuOp_pop_SP(u8 X86EMU_UNUSED (op1))4087 void x86emuOp_pop_SP(u8 X86EMU_UNUSED(op1))
4088 {
4089     START_OF_INSTR();
4090     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4091         DECODE_PRINTF("POP\tESP\n");
4092     } else {
4093         DECODE_PRINTF("POP\tSP\n");
4094     }
4095     TRACE_AND_STEP();
4096     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4097         M.x86.R_ESP = pop_long();
4098     } else {
4099         M.x86.R_SP = pop_word();
4100     }
4101     DECODE_CLEAR_SEGOVR();
4102     END_OF_INSTR();
4103 }
4104 
4105 /****************************************************************************
4106 REMARKS:
4107 Handles opcode 0x5d
4108 ****************************************************************************/
x86emuOp_pop_BP(u8 X86EMU_UNUSED (op1))4109 void x86emuOp_pop_BP(u8 X86EMU_UNUSED(op1))
4110 {
4111     START_OF_INSTR();
4112     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4113         DECODE_PRINTF("POP\tEBP\n");
4114     } else {
4115         DECODE_PRINTF("POP\tBP\n");
4116     }
4117     TRACE_AND_STEP();
4118     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4119         M.x86.R_EBP = pop_long();
4120     } else {
4121         M.x86.R_BP = pop_word();
4122     }
4123     DECODE_CLEAR_SEGOVR();
4124     END_OF_INSTR();
4125 }
4126 
4127 /****************************************************************************
4128 REMARKS:
4129 Handles opcode 0x5e
4130 ****************************************************************************/
x86emuOp_pop_SI(u8 X86EMU_UNUSED (op1))4131 void x86emuOp_pop_SI(u8 X86EMU_UNUSED(op1))
4132 {
4133     START_OF_INSTR();
4134     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4135         DECODE_PRINTF("POP\tESI\n");
4136     } else {
4137         DECODE_PRINTF("POP\tSI\n");
4138     }
4139     TRACE_AND_STEP();
4140     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4141         M.x86.R_ESI = pop_long();
4142     } else {
4143         M.x86.R_SI = pop_word();
4144     }
4145     DECODE_CLEAR_SEGOVR();
4146     END_OF_INSTR();
4147 }
4148 
4149 /****************************************************************************
4150 REMARKS:
4151 Handles opcode 0x5f
4152 ****************************************************************************/
x86emuOp_pop_DI(u8 X86EMU_UNUSED (op1))4153 void x86emuOp_pop_DI(u8 X86EMU_UNUSED(op1))
4154 {
4155     START_OF_INSTR();
4156     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4157         DECODE_PRINTF("POP\tEDI\n");
4158     } else {
4159         DECODE_PRINTF("POP\tDI\n");
4160     }
4161     TRACE_AND_STEP();
4162     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4163         M.x86.R_EDI = pop_long();
4164     } else {
4165         M.x86.R_DI = pop_word();
4166     }
4167     DECODE_CLEAR_SEGOVR();
4168     END_OF_INSTR();
4169 }
4170 
4171 /****************************************************************************
4172 REMARKS:
4173 Handles opcode 0x60
4174 ****************************************************************************/
x86emuOp_push_all(u8 X86EMU_UNUSED (op1))4175 void x86emuOp_push_all(u8 X86EMU_UNUSED(op1))
4176 {
4177     START_OF_INSTR();
4178     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4179         DECODE_PRINTF("PUSHAD\n");
4180     } else {
4181         DECODE_PRINTF("PUSHA\n");
4182     }
4183     TRACE_AND_STEP();
4184     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4185         u32 old_sp = M.x86.R_ESP;
4186 
4187         push_long(M.x86.R_EAX);
4188         push_long(M.x86.R_ECX);
4189         push_long(M.x86.R_EDX);
4190         push_long(M.x86.R_EBX);
4191         push_long(old_sp);
4192         push_long(M.x86.R_EBP);
4193         push_long(M.x86.R_ESI);
4194         push_long(M.x86.R_EDI);
4195     } else {
4196         u16 old_sp = M.x86.R_SP;
4197 
4198         push_word(M.x86.R_AX);
4199         push_word(M.x86.R_CX);
4200         push_word(M.x86.R_DX);
4201         push_word(M.x86.R_BX);
4202         push_word(old_sp);
4203         push_word(M.x86.R_BP);
4204         push_word(M.x86.R_SI);
4205         push_word(M.x86.R_DI);
4206     }
4207     DECODE_CLEAR_SEGOVR();
4208     END_OF_INSTR();
4209 }
4210 
4211 /****************************************************************************
4212 REMARKS:
4213 Handles opcode 0x61
4214 ****************************************************************************/
x86emuOp_pop_all(u8 X86EMU_UNUSED (op1))4215 void x86emuOp_pop_all(u8 X86EMU_UNUSED(op1))
4216 {
4217     START_OF_INSTR();
4218     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4219         DECODE_PRINTF("POPAD\n");
4220     } else {
4221         DECODE_PRINTF("POPA\n");
4222     }
4223     TRACE_AND_STEP();
4224     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4225         M.x86.R_EDI = pop_long();
4226         M.x86.R_ESI = pop_long();
4227         M.x86.R_EBP = pop_long();
4228         M.x86.R_ESP += 4;              /* skip ESP */
4229         M.x86.R_EBX = pop_long();
4230         M.x86.R_EDX = pop_long();
4231         M.x86.R_ECX = pop_long();
4232         M.x86.R_EAX = pop_long();
4233     } else {
4234         M.x86.R_DI = pop_word();
4235         M.x86.R_SI = pop_word();
4236         M.x86.R_BP = pop_word();
4237         M.x86.R_SP += 2;               /* skip SP */
4238         M.x86.R_BX = pop_word();
4239         M.x86.R_DX = pop_word();
4240         M.x86.R_CX = pop_word();
4241         M.x86.R_AX = pop_word();
4242     }
4243     DECODE_CLEAR_SEGOVR();
4244     END_OF_INSTR();
4245 }
4246 
4247 /*opcode 0x62   ILLEGAL OP, calls x86emuOp_illegal_op() */
4248 /*opcode 0x63   ILLEGAL OP, calls x86emuOp_illegal_op() */
4249 
4250 /****************************************************************************
4251 REMARKS:
4252 Handles opcode 0x64
4253 ****************************************************************************/
x86emuOp_segovr_FS(u8 X86EMU_UNUSED (op1))4254 void x86emuOp_segovr_FS(u8 X86EMU_UNUSED(op1))
4255 {
4256     START_OF_INSTR();
4257     DECODE_PRINTF("FS:\n");
4258     TRACE_AND_STEP();
4259     M.x86.mode |= SYSMODE_SEGOVR_FS;
4260     /*
4261      * note the lack of DECODE_CLEAR_SEGOVR(r) since, here is one of 4
4262      * opcode subroutines we do not want to do this.
4263      */
4264     END_OF_INSTR();
4265 }
4266 
4267 /****************************************************************************
4268 REMARKS:
4269 Handles opcode 0x65
4270 ****************************************************************************/
x86emuOp_segovr_GS(u8 X86EMU_UNUSED (op1))4271 void x86emuOp_segovr_GS(u8 X86EMU_UNUSED(op1))
4272 {
4273     START_OF_INSTR();
4274     DECODE_PRINTF("GS:\n");
4275     TRACE_AND_STEP();
4276     M.x86.mode |= SYSMODE_SEGOVR_GS;
4277     /*
4278      * note the lack of DECODE_CLEAR_SEGOVR(r) since, here is one of 4
4279      * opcode subroutines we do not want to do this.
4280      */
4281     END_OF_INSTR();
4282 }
4283 
4284 /****************************************************************************
4285 REMARKS:
4286 Handles opcode 0x66 - prefix for 32-bit register
4287 ****************************************************************************/
x86emuOp_prefix_data(u8 X86EMU_UNUSED (op1))4288 void x86emuOp_prefix_data(u8 X86EMU_UNUSED(op1))
4289 {
4290     START_OF_INSTR();
4291     DECODE_PRINTF("DATA:\n");
4292     TRACE_AND_STEP();
4293     M.x86.mode |= SYSMODE_PREFIX_DATA;
4294     /* note no DECODE_CLEAR_SEGOVR here. */
4295     END_OF_INSTR();
4296 }
4297 
4298 /****************************************************************************
4299 REMARKS:
4300 Handles opcode 0x67 - prefix for 32-bit address
4301 ****************************************************************************/
x86emuOp_prefix_addr(u8 X86EMU_UNUSED (op1))4302 void x86emuOp_prefix_addr(u8 X86EMU_UNUSED(op1))
4303 {
4304     START_OF_INSTR();
4305     DECODE_PRINTF("ADDR:\n");
4306     TRACE_AND_STEP();
4307     M.x86.mode |= SYSMODE_PREFIX_ADDR;
4308     /* note no DECODE_CLEAR_SEGOVR here. */
4309     END_OF_INSTR();
4310 }
4311 
4312 /****************************************************************************
4313 REMARKS:
4314 Handles opcode 0x68
4315 ****************************************************************************/
x86emuOp_push_word_IMM(u8 X86EMU_UNUSED (op1))4316 void x86emuOp_push_word_IMM(u8 X86EMU_UNUSED(op1))
4317 {
4318     u32 imm;
4319 
4320     START_OF_INSTR();
4321     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4322         imm = fetch_long_imm();
4323     } else {
4324         imm = fetch_word_imm();
4325     }
4326     DECODE_PRINTF2("PUSH\t%x\n", imm);
4327     TRACE_AND_STEP();
4328     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4329         push_long(imm);
4330     } else {
4331         push_word((u16)imm);
4332     }
4333     DECODE_CLEAR_SEGOVR();
4334     END_OF_INSTR();
4335 }
4336 
4337 /****************************************************************************
4338 REMARKS:
4339 Handles opcode 0x69
4340 ****************************************************************************/
x86emuOp_imul_word_IMM(u8 X86EMU_UNUSED (op1))4341 void x86emuOp_imul_word_IMM(u8 X86EMU_UNUSED(op1))
4342 {
4343     int mod, rl, rh;
4344     uint srcoffset;
4345 
4346     START_OF_INSTR();
4347     DECODE_PRINTF("IMUL\t");
4348     FETCH_DECODE_MODRM(mod, rh, rl);
4349     switch (mod) {
4350     case 0:
4351         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4352             u32 *destreg;
4353             u32 srcval;
4354             u32 res_lo,res_hi;
4355             s32 imm;
4356 
4357             destreg = DECODE_RM_LONG_REGISTER(rh);
4358             DECODE_PRINTF(",");
4359             srcoffset = decode_rm00_address(rl);
4360             srcval = fetch_data_long(srcoffset);
4361             imm = fetch_long_imm();
4362             DECODE_PRINTF2(",%d\n", (s32)imm);
4363             TRACE_AND_STEP();
4364             imul_long_direct(&res_lo,&res_hi,(s32)srcval,(s32)imm);
4365             if ((((res_lo & 0x80000000) == 0) && (res_hi == 0x00000000)) ||
4366                 (((res_lo & 0x80000000) != 0) && (res_hi == 0xFFFFFFFF))) {
4367                 CLEAR_FLAG(F_CF);
4368                 CLEAR_FLAG(F_OF);
4369             } else {
4370                 SET_FLAG(F_CF);
4371                 SET_FLAG(F_OF);
4372             }
4373             *destreg = (u32)res_lo;
4374         } else {
4375             u16 *destreg;
4376             u16 srcval;
4377             u32 res;
4378             s16 imm;
4379 
4380             destreg = DECODE_RM_WORD_REGISTER(rh);
4381             DECODE_PRINTF(",");
4382             srcoffset = decode_rm00_address(rl);
4383             srcval = fetch_data_word(srcoffset);
4384             imm = fetch_word_imm();
4385             DECODE_PRINTF2(",%d\n", (s32)imm);
4386             TRACE_AND_STEP();
4387             res = (s16)srcval * (s16)imm;
4388             if ((((res & 0x8000) == 0) && ((res >> 16) == 0x0000)) ||
4389                 (((res & 0x8000) != 0) && ((res >> 16) == 0xFFFF))) {
4390                 CLEAR_FLAG(F_CF);
4391                 CLEAR_FLAG(F_OF);
4392             } else {
4393                 SET_FLAG(F_CF);
4394                 SET_FLAG(F_OF);
4395             }
4396             *destreg = (u16)res;
4397         }
4398         break;
4399     case 1:
4400         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4401             u32 *destreg;
4402             u32 srcval;
4403             u32 res_lo,res_hi;
4404             s32 imm;
4405 
4406             destreg = DECODE_RM_LONG_REGISTER(rh);
4407             DECODE_PRINTF(",");
4408             srcoffset = decode_rm01_address(rl);
4409             srcval = fetch_data_long(srcoffset);
4410             imm = fetch_long_imm();
4411             DECODE_PRINTF2(",%d\n", (s32)imm);
4412             TRACE_AND_STEP();
4413             imul_long_direct(&res_lo,&res_hi,(s32)srcval,(s32)imm);
4414             if ((((res_lo & 0x80000000) == 0) && (res_hi == 0x00000000)) ||
4415                 (((res_lo & 0x80000000) != 0) && (res_hi == 0xFFFFFFFF))) {
4416                 CLEAR_FLAG(F_CF);
4417                 CLEAR_FLAG(F_OF);
4418             } else {
4419                 SET_FLAG(F_CF);
4420                 SET_FLAG(F_OF);
4421             }
4422             *destreg = (u32)res_lo;
4423         } else {
4424             u16 *destreg;
4425             u16 srcval;
4426             u32 res;
4427             s16 imm;
4428 
4429             destreg = DECODE_RM_WORD_REGISTER(rh);
4430             DECODE_PRINTF(",");
4431             srcoffset = decode_rm01_address(rl);
4432             srcval = fetch_data_word(srcoffset);
4433             imm = fetch_word_imm();
4434             DECODE_PRINTF2(",%d\n", (s32)imm);
4435             TRACE_AND_STEP();
4436             res = (s16)srcval * (s16)imm;
4437             if ((((res & 0x8000) == 0) && ((res >> 16) == 0x0000)) ||
4438                 (((res & 0x8000) != 0) && ((res >> 16) == 0xFFFF))) {
4439                 CLEAR_FLAG(F_CF);
4440                 CLEAR_FLAG(F_OF);
4441             } else {
4442                 SET_FLAG(F_CF);
4443                 SET_FLAG(F_OF);
4444             }
4445             *destreg = (u16)res;
4446         }
4447         break;
4448     case 2:
4449         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4450             u32 *destreg;
4451             u32 srcval;
4452             u32 res_lo,res_hi;
4453             s32 imm;
4454 
4455             destreg = DECODE_RM_LONG_REGISTER(rh);
4456             DECODE_PRINTF(",");
4457             srcoffset = decode_rm10_address(rl);
4458             srcval = fetch_data_long(srcoffset);
4459             imm = fetch_long_imm();
4460             DECODE_PRINTF2(",%d\n", (s32)imm);
4461             TRACE_AND_STEP();
4462             imul_long_direct(&res_lo,&res_hi,(s32)srcval,(s32)imm);
4463             if ((((res_lo & 0x80000000) == 0) && (res_hi == 0x00000000)) ||
4464                 (((res_lo & 0x80000000) != 0) && (res_hi == 0xFFFFFFFF))) {
4465                 CLEAR_FLAG(F_CF);
4466                 CLEAR_FLAG(F_OF);
4467             } else {
4468                 SET_FLAG(F_CF);
4469                 SET_FLAG(F_OF);
4470             }
4471             *destreg = (u32)res_lo;
4472         } else {
4473             u16 *destreg;
4474             u16 srcval;
4475             u32 res;
4476             s16 imm;
4477 
4478             destreg = DECODE_RM_WORD_REGISTER(rh);
4479             DECODE_PRINTF(",");
4480             srcoffset = decode_rm10_address(rl);
4481             srcval = fetch_data_word(srcoffset);
4482             imm = fetch_word_imm();
4483             DECODE_PRINTF2(",%d\n", (s32)imm);
4484             TRACE_AND_STEP();
4485             res = (s16)srcval * (s16)imm;
4486             if ((((res & 0x8000) == 0) && ((res >> 16) == 0x0000)) ||
4487                 (((res & 0x8000) != 0) && ((res >> 16) == 0xFFFF))) {
4488                 CLEAR_FLAG(F_CF);
4489                 CLEAR_FLAG(F_OF);
4490             } else {
4491                 SET_FLAG(F_CF);
4492                 SET_FLAG(F_OF);
4493             }
4494             *destreg = (u16)res;
4495         }
4496         break;
4497     case 3:                     /* register to register */
4498         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4499             u32 *destreg,*srcreg;
4500             u32 res_lo,res_hi;
4501             s32 imm;
4502 
4503             destreg = DECODE_RM_LONG_REGISTER(rh);
4504             DECODE_PRINTF(",");
4505             srcreg = DECODE_RM_LONG_REGISTER(rl);
4506             imm = fetch_long_imm();
4507             DECODE_PRINTF2(",%d\n", (s32)imm);
4508             TRACE_AND_STEP();
4509             imul_long_direct(&res_lo,&res_hi,(s32)*srcreg,(s32)imm);
4510             if ((((res_lo & 0x80000000) == 0) && (res_hi == 0x00000000)) ||
4511                 (((res_lo & 0x80000000) != 0) && (res_hi == 0xFFFFFFFF))) {
4512                 CLEAR_FLAG(F_CF);
4513                 CLEAR_FLAG(F_OF);
4514             } else {
4515                 SET_FLAG(F_CF);
4516                 SET_FLAG(F_OF);
4517             }
4518             *destreg = (u32)res_lo;
4519         } else {
4520             u16 *destreg,*srcreg;
4521             u32 res;
4522             s16 imm;
4523 
4524             destreg = DECODE_RM_WORD_REGISTER(rh);
4525             DECODE_PRINTF(",");
4526             srcreg = DECODE_RM_WORD_REGISTER(rl);
4527             imm = fetch_word_imm();
4528             DECODE_PRINTF2(",%d\n", (s32)imm);
4529             TRACE_AND_STEP();
4530             res = (s16)*srcreg * (s16)imm;
4531             if ((((res & 0x8000) == 0) && ((res >> 16) == 0x0000)) ||
4532                 (((res & 0x8000) != 0) && ((res >> 16) == 0xFFFF))) {
4533                 CLEAR_FLAG(F_CF);
4534                 CLEAR_FLAG(F_OF);
4535             } else {
4536                 SET_FLAG(F_CF);
4537                 SET_FLAG(F_OF);
4538             }
4539             *destreg = (u16)res;
4540         }
4541         break;
4542     }
4543     DECODE_CLEAR_SEGOVR();
4544     END_OF_INSTR();
4545 }
4546 
4547 /****************************************************************************
4548 REMARKS:
4549 Handles opcode 0x6a
4550 ****************************************************************************/
x86emuOp_push_byte_IMM(u8 X86EMU_UNUSED (op1))4551 void x86emuOp_push_byte_IMM(u8 X86EMU_UNUSED(op1))
4552 {
4553     s16 imm;
4554 
4555     START_OF_INSTR();
4556     imm = (s8)fetch_byte_imm();
4557     DECODE_PRINTF2("PUSH\t%d\n", imm);
4558     TRACE_AND_STEP();
4559     push_word(imm);
4560     DECODE_CLEAR_SEGOVR();
4561     END_OF_INSTR();
4562 }
4563 
4564 /****************************************************************************
4565 REMARKS:
4566 Handles opcode 0x6b
4567 ****************************************************************************/
x86emuOp_imul_byte_IMM(u8 X86EMU_UNUSED (op1))4568 void x86emuOp_imul_byte_IMM(u8 X86EMU_UNUSED(op1))
4569 {
4570     int mod, rl, rh;
4571     uint srcoffset;
4572     s8  imm;
4573 
4574     START_OF_INSTR();
4575     DECODE_PRINTF("IMUL\t");
4576     FETCH_DECODE_MODRM(mod, rh, rl);
4577     switch (mod) {
4578     case 0:
4579         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4580             u32 *destreg;
4581             u32 srcval;
4582             u32 res_lo,res_hi;
4583 
4584             destreg = DECODE_RM_LONG_REGISTER(rh);
4585             DECODE_PRINTF(",");
4586             srcoffset = decode_rm00_address(rl);
4587             srcval = fetch_data_long(srcoffset);
4588             imm = fetch_byte_imm();
4589             DECODE_PRINTF2(",%d\n", (s32)imm);
4590             TRACE_AND_STEP();
4591             imul_long_direct(&res_lo,&res_hi,(s32)srcval,(s32)imm);
4592             if ((((res_lo & 0x80000000) == 0) && (res_hi == 0x00000000)) ||
4593                 (((res_lo & 0x80000000) != 0) && (res_hi == 0xFFFFFFFF))) {
4594                 CLEAR_FLAG(F_CF);
4595                 CLEAR_FLAG(F_OF);
4596             } else {
4597                 SET_FLAG(F_CF);
4598                 SET_FLAG(F_OF);
4599             }
4600             *destreg = (u32)res_lo;
4601         } else {
4602             u16 *destreg;
4603             u16 srcval;
4604             u32 res;
4605 
4606             destreg = DECODE_RM_WORD_REGISTER(rh);
4607             DECODE_PRINTF(",");
4608             srcoffset = decode_rm00_address(rl);
4609             srcval = fetch_data_word(srcoffset);
4610             imm = fetch_byte_imm();
4611             DECODE_PRINTF2(",%d\n", (s32)imm);
4612             TRACE_AND_STEP();
4613             res = (s16)srcval * (s16)imm;
4614             if ((((res & 0x8000) == 0) && ((res >> 16) == 0x0000)) ||
4615                 (((res & 0x8000) != 0) && ((res >> 16) == 0xFFFF))) {
4616                 CLEAR_FLAG(F_CF);
4617                 CLEAR_FLAG(F_OF);
4618             } else {
4619                 SET_FLAG(F_CF);
4620                 SET_FLAG(F_OF);
4621             }
4622             *destreg = (u16)res;
4623         }
4624         break;
4625     case 1:
4626         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4627             u32 *destreg;
4628             u32 srcval;
4629             u32 res_lo,res_hi;
4630 
4631             destreg = DECODE_RM_LONG_REGISTER(rh);
4632             DECODE_PRINTF(",");
4633             srcoffset = decode_rm01_address(rl);
4634             srcval = fetch_data_long(srcoffset);
4635             imm = fetch_byte_imm();
4636             DECODE_PRINTF2(",%d\n", (s32)imm);
4637             TRACE_AND_STEP();
4638             imul_long_direct(&res_lo,&res_hi,(s32)srcval,(s32)imm);
4639             if ((((res_lo & 0x80000000) == 0) && (res_hi == 0x00000000)) ||
4640                 (((res_lo & 0x80000000) != 0) && (res_hi == 0xFFFFFFFF))) {
4641                 CLEAR_FLAG(F_CF);
4642                 CLEAR_FLAG(F_OF);
4643             } else {
4644                 SET_FLAG(F_CF);
4645                 SET_FLAG(F_OF);
4646             }
4647             *destreg = (u32)res_lo;
4648         } else {
4649             u16 *destreg;
4650             u16 srcval;
4651             u32 res;
4652 
4653             destreg = DECODE_RM_WORD_REGISTER(rh);
4654             DECODE_PRINTF(",");
4655             srcoffset = decode_rm01_address(rl);
4656             srcval = fetch_data_word(srcoffset);
4657             imm = fetch_byte_imm();
4658             DECODE_PRINTF2(",%d\n", (s32)imm);
4659             TRACE_AND_STEP();
4660             res = (s16)srcval * (s16)imm;
4661             if ((((res & 0x8000) == 0) && ((res >> 16) == 0x0000)) ||
4662                 (((res & 0x8000) != 0) && ((res >> 16) == 0xFFFF))) {
4663                 CLEAR_FLAG(F_CF);
4664                 CLEAR_FLAG(F_OF);
4665             } else {
4666                 SET_FLAG(F_CF);
4667                 SET_FLAG(F_OF);
4668             }
4669             *destreg = (u16)res;
4670         }
4671         break;
4672     case 2:
4673         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4674             u32 *destreg;
4675             u32 srcval;
4676             u32 res_lo,res_hi;
4677 
4678             destreg = DECODE_RM_LONG_REGISTER(rh);
4679             DECODE_PRINTF(",");
4680             srcoffset = decode_rm10_address(rl);
4681             srcval = fetch_data_long(srcoffset);
4682             imm = fetch_byte_imm();
4683             DECODE_PRINTF2(",%d\n", (s32)imm);
4684             TRACE_AND_STEP();
4685             imul_long_direct(&res_lo,&res_hi,(s32)srcval,(s32)imm);
4686             if ((((res_lo & 0x80000000) == 0) && (res_hi == 0x00000000)) ||
4687                 (((res_lo & 0x80000000) != 0) && (res_hi == 0xFFFFFFFF))) {
4688                 CLEAR_FLAG(F_CF);
4689                 CLEAR_FLAG(F_OF);
4690             } else {
4691                 SET_FLAG(F_CF);
4692                 SET_FLAG(F_OF);
4693             }
4694             *destreg = (u32)res_lo;
4695         } else {
4696             u16 *destreg;
4697             u16 srcval;
4698             u32 res;
4699 
4700             destreg = DECODE_RM_WORD_REGISTER(rh);
4701             DECODE_PRINTF(",");
4702             srcoffset = decode_rm10_address(rl);
4703             srcval = fetch_data_word(srcoffset);
4704             imm = fetch_byte_imm();
4705             DECODE_PRINTF2(",%d\n", (s32)imm);
4706             TRACE_AND_STEP();
4707             res = (s16)srcval * (s16)imm;
4708             if ((((res & 0x8000) == 0) && ((res >> 16) == 0x0000)) ||
4709                 (((res & 0x8000) != 0) && ((res >> 16) == 0xFFFF))) {
4710                 CLEAR_FLAG(F_CF);
4711                 CLEAR_FLAG(F_OF);
4712             } else {
4713                 SET_FLAG(F_CF);
4714                 SET_FLAG(F_OF);
4715             }
4716             *destreg = (u16)res;
4717         }
4718         break;
4719     case 3:                     /* register to register */
4720         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4721             u32 *destreg,*srcreg;
4722             u32 res_lo,res_hi;
4723 
4724             destreg = DECODE_RM_LONG_REGISTER(rh);
4725             DECODE_PRINTF(",");
4726             srcreg = DECODE_RM_LONG_REGISTER(rl);
4727             imm = fetch_byte_imm();
4728             DECODE_PRINTF2(",%d\n", (s32)imm);
4729             TRACE_AND_STEP();
4730             imul_long_direct(&res_lo,&res_hi,(s32)*srcreg,(s32)imm);
4731             if ((((res_lo & 0x80000000) == 0) && (res_hi == 0x00000000)) ||
4732                 (((res_lo & 0x80000000) != 0) && (res_hi == 0xFFFFFFFF))) {
4733                 CLEAR_FLAG(F_CF);
4734                 CLEAR_FLAG(F_OF);
4735             } else {
4736                 SET_FLAG(F_CF);
4737                 SET_FLAG(F_OF);
4738             }
4739             *destreg = (u32)res_lo;
4740         } else {
4741             u16 *destreg,*srcreg;
4742             u32 res;
4743 
4744             destreg = DECODE_RM_WORD_REGISTER(rh);
4745             DECODE_PRINTF(",");
4746             srcreg = DECODE_RM_WORD_REGISTER(rl);
4747             imm = fetch_byte_imm();
4748             DECODE_PRINTF2(",%d\n", (s32)imm);
4749             TRACE_AND_STEP();
4750             res = (s16)*srcreg * (s16)imm;
4751             if ((((res & 0x8000) == 0) && ((res >> 16) == 0x0000)) ||
4752                 (((res & 0x8000) != 0) && ((res >> 16) == 0xFFFF))) {
4753                 CLEAR_FLAG(F_CF);
4754                 CLEAR_FLAG(F_OF);
4755             } else {
4756                 SET_FLAG(F_CF);
4757                 SET_FLAG(F_OF);
4758             }
4759             *destreg = (u16)res;
4760         }
4761         break;
4762     }
4763     DECODE_CLEAR_SEGOVR();
4764     END_OF_INSTR();
4765 }
4766 
4767 /****************************************************************************
4768 REMARKS:
4769 Handles opcode 0x6c
4770 ****************************************************************************/
x86emuOp_ins_byte(u8 X86EMU_UNUSED (op1))4771 void x86emuOp_ins_byte(u8 X86EMU_UNUSED(op1))
4772 {
4773     START_OF_INSTR();
4774     DECODE_PRINTF("INSB\n");
4775     ins(1);
4776     TRACE_AND_STEP();
4777     DECODE_CLEAR_SEGOVR();
4778     END_OF_INSTR();
4779 }
4780 
4781 /****************************************************************************
4782 REMARKS:
4783 Handles opcode 0x6d
4784 ****************************************************************************/
x86emuOp_ins_word(u8 X86EMU_UNUSED (op1))4785 void x86emuOp_ins_word(u8 X86EMU_UNUSED(op1))
4786 {
4787     START_OF_INSTR();
4788     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4789         DECODE_PRINTF("INSD\n");
4790         ins(4);
4791     } else {
4792         DECODE_PRINTF("INSW\n");
4793         ins(2);
4794     }
4795     TRACE_AND_STEP();
4796     DECODE_CLEAR_SEGOVR();
4797     END_OF_INSTR();
4798 }
4799 
4800 /****************************************************************************
4801 REMARKS:
4802 Handles opcode 0x6e
4803 ****************************************************************************/
x86emuOp_outs_byte(u8 X86EMU_UNUSED (op1))4804 void x86emuOp_outs_byte(u8 X86EMU_UNUSED(op1))
4805 {
4806     START_OF_INSTR();
4807     DECODE_PRINTF("OUTSB\n");
4808     outs(1);
4809     TRACE_AND_STEP();
4810     DECODE_CLEAR_SEGOVR();
4811     END_OF_INSTR();
4812 }
4813 
4814 /****************************************************************************
4815 REMARKS:
4816 Handles opcode 0x6f
4817 ****************************************************************************/
x86emuOp_outs_word(u8 X86EMU_UNUSED (op1))4818 void x86emuOp_outs_word(u8 X86EMU_UNUSED(op1))
4819 {
4820     START_OF_INSTR();
4821     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
4822         DECODE_PRINTF("OUTSD\n");
4823         outs(4);
4824     } else {
4825         DECODE_PRINTF("OUTSW\n");
4826         outs(2);
4827     }
4828     TRACE_AND_STEP();
4829     DECODE_CLEAR_SEGOVR();
4830     END_OF_INSTR();
4831 }
4832 
4833 /****************************************************************************
4834 REMARKS:
4835 Handles opcode 0x70
4836 ****************************************************************************/
x86emuOp_jump_near_O(u8 X86EMU_UNUSED (op1))4837 void x86emuOp_jump_near_O(u8 X86EMU_UNUSED(op1))
4838 {
4839     s8 offset;
4840     u16 target;
4841 
4842     /* jump to byte offset if overflow flag is set */
4843     START_OF_INSTR();
4844     DECODE_PRINTF("JO\t");
4845     offset = (s8)fetch_byte_imm();
4846     target = (u16)(M.x86.R_IP + (s16)offset);
4847     DECODE_PRINTF2("%x\n", target);
4848     TRACE_AND_STEP();
4849     if (ACCESS_FLAG(F_OF))
4850         M.x86.R_IP = target;
4851     DECODE_CLEAR_SEGOVR();
4852     END_OF_INSTR();
4853 }
4854 
4855 /****************************************************************************
4856 REMARKS:
4857 Handles opcode 0x71
4858 ****************************************************************************/
x86emuOp_jump_near_NO(u8 X86EMU_UNUSED (op1))4859 void x86emuOp_jump_near_NO(u8 X86EMU_UNUSED(op1))
4860 {
4861     s8 offset;
4862     u16 target;
4863 
4864     /* jump to byte offset if overflow is not set */
4865     START_OF_INSTR();
4866     DECODE_PRINTF("JNO\t");
4867     offset = (s8)fetch_byte_imm();
4868     target = (u16)(M.x86.R_IP + (s16)offset);
4869     DECODE_PRINTF2("%x\n", target);
4870     TRACE_AND_STEP();
4871     if (!ACCESS_FLAG(F_OF))
4872         M.x86.R_IP = target;
4873     DECODE_CLEAR_SEGOVR();
4874     END_OF_INSTR();
4875 }
4876 
4877 /****************************************************************************
4878 REMARKS:
4879 Handles opcode 0x72
4880 ****************************************************************************/
x86emuOp_jump_near_B(u8 X86EMU_UNUSED (op1))4881 void x86emuOp_jump_near_B(u8 X86EMU_UNUSED(op1))
4882 {
4883     s8 offset;
4884     u16 target;
4885 
4886     /* jump to byte offset if carry flag is set. */
4887     START_OF_INSTR();
4888     DECODE_PRINTF("JB\t");
4889     offset = (s8)fetch_byte_imm();
4890     target = (u16)(M.x86.R_IP + (s16)offset);
4891     DECODE_PRINTF2("%x\n", target);
4892     TRACE_AND_STEP();
4893     if (ACCESS_FLAG(F_CF))
4894         M.x86.R_IP = target;
4895     DECODE_CLEAR_SEGOVR();
4896     END_OF_INSTR();
4897 }
4898 
4899 /****************************************************************************
4900 REMARKS:
4901 Handles opcode 0x73
4902 ****************************************************************************/
x86emuOp_jump_near_NB(u8 X86EMU_UNUSED (op1))4903 void x86emuOp_jump_near_NB(u8 X86EMU_UNUSED(op1))
4904 {
4905     s8 offset;
4906     u16 target;
4907 
4908     /* jump to byte offset if carry flag is clear. */
4909     START_OF_INSTR();
4910     DECODE_PRINTF("JNB\t");
4911     offset = (s8)fetch_byte_imm();
4912     target = (u16)(M.x86.R_IP + (s16)offset);
4913     DECODE_PRINTF2("%x\n", target);
4914     TRACE_AND_STEP();
4915     if (!ACCESS_FLAG(F_CF))
4916         M.x86.R_IP = target;
4917     DECODE_CLEAR_SEGOVR();
4918     END_OF_INSTR();
4919 }
4920 
4921 /****************************************************************************
4922 REMARKS:
4923 Handles opcode 0x74
4924 ****************************************************************************/
x86emuOp_jump_near_Z(u8 X86EMU_UNUSED (op1))4925 void x86emuOp_jump_near_Z(u8 X86EMU_UNUSED(op1))
4926 {
4927     s8 offset;
4928     u16 target;
4929 
4930     /* jump to byte offset if zero flag is set. */
4931     START_OF_INSTR();
4932     DECODE_PRINTF("JZ\t");
4933     offset = (s8)fetch_byte_imm();
4934     target = (u16)(M.x86.R_IP + (s16)offset);
4935     DECODE_PRINTF2("%x\n", target);
4936     TRACE_AND_STEP();
4937     if (ACCESS_FLAG(F_ZF))
4938         M.x86.R_IP = target;
4939     DECODE_CLEAR_SEGOVR();
4940     END_OF_INSTR();
4941 }
4942 
4943 /****************************************************************************
4944 REMARKS:
4945 Handles opcode 0x75
4946 ****************************************************************************/
x86emuOp_jump_near_NZ(u8 X86EMU_UNUSED (op1))4947 void x86emuOp_jump_near_NZ(u8 X86EMU_UNUSED(op1))
4948 {
4949     s8 offset;
4950     u16 target;
4951 
4952     /* jump to byte offset if zero flag is clear. */
4953     START_OF_INSTR();
4954     DECODE_PRINTF("JNZ\t");
4955     offset = (s8)fetch_byte_imm();
4956     target = (u16)(M.x86.R_IP + (s16)offset);
4957     DECODE_PRINTF2("%x\n", target);
4958     TRACE_AND_STEP();
4959     if (!ACCESS_FLAG(F_ZF))
4960         M.x86.R_IP = target;
4961     DECODE_CLEAR_SEGOVR();
4962     END_OF_INSTR();
4963 }
4964 
4965 /****************************************************************************
4966 REMARKS:
4967 Handles opcode 0x76
4968 ****************************************************************************/
x86emuOp_jump_near_BE(u8 X86EMU_UNUSED (op1))4969 void x86emuOp_jump_near_BE(u8 X86EMU_UNUSED(op1))
4970 {
4971     s8 offset;
4972     u16 target;
4973 
4974     /* jump to byte offset if carry flag is set or if the zero
4975        flag is set. */
4976     START_OF_INSTR();
4977     DECODE_PRINTF("JBE\t");
4978     offset = (s8)fetch_byte_imm();
4979     target = (u16)(M.x86.R_IP + (s16)offset);
4980     DECODE_PRINTF2("%x\n", target);
4981     TRACE_AND_STEP();
4982     if (ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF))
4983         M.x86.R_IP = target;
4984     DECODE_CLEAR_SEGOVR();
4985     END_OF_INSTR();
4986 }
4987 
4988 /****************************************************************************
4989 REMARKS:
4990 Handles opcode 0x77
4991 ****************************************************************************/
x86emuOp_jump_near_NBE(u8 X86EMU_UNUSED (op1))4992 void x86emuOp_jump_near_NBE(u8 X86EMU_UNUSED(op1))
4993 {
4994     s8 offset;
4995     u16 target;
4996 
4997     /* jump to byte offset if carry flag is clear and if the zero
4998        flag is clear */
4999     START_OF_INSTR();
5000     DECODE_PRINTF("JNBE\t");
5001     offset = (s8)fetch_byte_imm();
5002     target = (u16)(M.x86.R_IP + (s16)offset);
5003     DECODE_PRINTF2("%x\n", target);
5004     TRACE_AND_STEP();
5005     if (!(ACCESS_FLAG(F_CF) || ACCESS_FLAG(F_ZF)))
5006         M.x86.R_IP = target;
5007     DECODE_CLEAR_SEGOVR();
5008     END_OF_INSTR();
5009 }
5010 
5011 /****************************************************************************
5012 REMARKS:
5013 Handles opcode 0x78
5014 ****************************************************************************/
x86emuOp_jump_near_S(u8 X86EMU_UNUSED (op1))5015 void x86emuOp_jump_near_S(u8 X86EMU_UNUSED(op1))
5016 {
5017     s8 offset;
5018     u16 target;
5019 
5020     /* jump to byte offset if sign flag is set */
5021     START_OF_INSTR();
5022     DECODE_PRINTF("JS\t");
5023     offset = (s8)fetch_byte_imm();
5024     target = (u16)(M.x86.R_IP + (s16)offset);
5025     DECODE_PRINTF2("%x\n", target);
5026     TRACE_AND_STEP();
5027     if (ACCESS_FLAG(F_SF))
5028         M.x86.R_IP = target;
5029     DECODE_CLEAR_SEGOVR();
5030     END_OF_INSTR();
5031 }
5032 
5033 /****************************************************************************
5034 REMARKS:
5035 Handles opcode 0x79
5036 ****************************************************************************/
x86emuOp_jump_near_NS(u8 X86EMU_UNUSED (op1))5037 void x86emuOp_jump_near_NS(u8 X86EMU_UNUSED(op1))
5038 {
5039     s8 offset;
5040     u16 target;
5041 
5042     /* jump to byte offset if sign flag is clear */
5043     START_OF_INSTR();
5044     DECODE_PRINTF("JNS\t");
5045     offset = (s8)fetch_byte_imm();
5046     target = (u16)(M.x86.R_IP + (s16)offset);
5047     DECODE_PRINTF2("%x\n", target);
5048     TRACE_AND_STEP();
5049     if (!ACCESS_FLAG(F_SF))
5050         M.x86.R_IP = target;
5051     DECODE_CLEAR_SEGOVR();
5052     END_OF_INSTR();
5053 }
5054 
5055 /****************************************************************************
5056 REMARKS:
5057 Handles opcode 0x7a
5058 ****************************************************************************/
x86emuOp_jump_near_P(u8 X86EMU_UNUSED (op1))5059 void x86emuOp_jump_near_P(u8 X86EMU_UNUSED(op1))
5060 {
5061     s8 offset;
5062     u16 target;
5063 
5064     /* jump to byte offset if parity flag is set (even parity) */
5065     START_OF_INSTR();
5066     DECODE_PRINTF("JP\t");
5067     offset = (s8)fetch_byte_imm();
5068     target = (u16)(M.x86.R_IP + (s16)offset);
5069     DECODE_PRINTF2("%x\n", target);
5070     TRACE_AND_STEP();
5071     if (ACCESS_FLAG(F_PF))
5072         M.x86.R_IP = target;
5073     DECODE_CLEAR_SEGOVR();
5074     END_OF_INSTR();
5075 }
5076 
5077 /****************************************************************************
5078 REMARKS:
5079 Handles opcode 0x7b
5080 ****************************************************************************/
x86emuOp_jump_near_NP(u8 X86EMU_UNUSED (op1))5081 void x86emuOp_jump_near_NP(u8 X86EMU_UNUSED(op1))
5082 {
5083     s8 offset;
5084     u16 target;
5085 
5086     /* jump to byte offset if parity flag is clear (odd parity) */
5087     START_OF_INSTR();
5088     DECODE_PRINTF("JNP\t");
5089     offset = (s8)fetch_byte_imm();
5090     target = (u16)(M.x86.R_IP + (s16)offset);
5091     DECODE_PRINTF2("%x\n", target);
5092     TRACE_AND_STEP();
5093     if (!ACCESS_FLAG(F_PF))
5094         M.x86.R_IP = target;
5095     DECODE_CLEAR_SEGOVR();
5096     END_OF_INSTR();
5097 }
5098 
5099 /****************************************************************************
5100 REMARKS:
5101 Handles opcode 0x7c
5102 ****************************************************************************/
x86emuOp_jump_near_L(u8 X86EMU_UNUSED (op1))5103 void x86emuOp_jump_near_L(u8 X86EMU_UNUSED(op1))
5104 {
5105     s8 offset;
5106     u16 target;
5107     int sf, of;
5108 
5109     /* jump to byte offset if sign flag not equal to overflow flag. */
5110     START_OF_INSTR();
5111     DECODE_PRINTF("JL\t");
5112     offset = (s8)fetch_byte_imm();
5113     target = (u16)(M.x86.R_IP + (s16)offset);
5114     DECODE_PRINTF2("%x\n", target);
5115     TRACE_AND_STEP();
5116     sf = ACCESS_FLAG(F_SF) != 0;
5117     of = ACCESS_FLAG(F_OF) != 0;
5118     if (sf ^ of)
5119         M.x86.R_IP = target;
5120     DECODE_CLEAR_SEGOVR();
5121     END_OF_INSTR();
5122 }
5123 
5124 /****************************************************************************
5125 REMARKS:
5126 Handles opcode 0x7d
5127 ****************************************************************************/
x86emuOp_jump_near_NL(u8 X86EMU_UNUSED (op1))5128 void x86emuOp_jump_near_NL(u8 X86EMU_UNUSED(op1))
5129 {
5130     s8 offset;
5131     u16 target;
5132     int sf, of;
5133 
5134     /* jump to byte offset if sign flag not equal to overflow flag. */
5135     START_OF_INSTR();
5136     DECODE_PRINTF("JNL\t");
5137     offset = (s8)fetch_byte_imm();
5138     target = (u16)(M.x86.R_IP + (s16)offset);
5139     DECODE_PRINTF2("%x\n", target);
5140     TRACE_AND_STEP();
5141     sf = ACCESS_FLAG(F_SF) != 0;
5142     of = ACCESS_FLAG(F_OF) != 0;
5143     /* note: inverse of above, but using == instead of xor. */
5144     if (sf == of)
5145         M.x86.R_IP = target;
5146     DECODE_CLEAR_SEGOVR();
5147     END_OF_INSTR();
5148 }
5149 
5150 /****************************************************************************
5151 REMARKS:
5152 Handles opcode 0x7e
5153 ****************************************************************************/
x86emuOp_jump_near_LE(u8 X86EMU_UNUSED (op1))5154 void x86emuOp_jump_near_LE(u8 X86EMU_UNUSED(op1))
5155 {
5156     s8 offset;
5157     u16 target;
5158     int sf, of;
5159 
5160     /* jump to byte offset if sign flag not equal to overflow flag
5161        or the zero flag is set */
5162     START_OF_INSTR();
5163     DECODE_PRINTF("JLE\t");
5164     offset = (s8)fetch_byte_imm();
5165     target = (u16)(M.x86.R_IP + (s16)offset);
5166     DECODE_PRINTF2("%x\n", target);
5167     TRACE_AND_STEP();
5168     sf = ACCESS_FLAG(F_SF) != 0;
5169     of = ACCESS_FLAG(F_OF) != 0;
5170     if ((sf ^ of) || ACCESS_FLAG(F_ZF))
5171         M.x86.R_IP = target;
5172     DECODE_CLEAR_SEGOVR();
5173     END_OF_INSTR();
5174 }
5175 
5176 /****************************************************************************
5177 REMARKS:
5178 Handles opcode 0x7f
5179 ****************************************************************************/
x86emuOp_jump_near_NLE(u8 X86EMU_UNUSED (op1))5180 void x86emuOp_jump_near_NLE(u8 X86EMU_UNUSED(op1))
5181 {
5182     s8 offset;
5183     u16 target;
5184     int sf, of;
5185 
5186     /* jump to byte offset if sign flag equal to overflow flag.
5187        and the zero flag is clear */
5188     START_OF_INSTR();
5189     DECODE_PRINTF("JNLE\t");
5190     offset = (s8)fetch_byte_imm();
5191     target = (u16)(M.x86.R_IP + (s16)offset);
5192     DECODE_PRINTF2("%x\n", target);
5193     TRACE_AND_STEP();
5194     sf = ACCESS_FLAG(F_SF) != 0;
5195     of = ACCESS_FLAG(F_OF) != 0;
5196     if ((sf == of) && !ACCESS_FLAG(F_ZF))
5197         M.x86.R_IP = target;
5198     DECODE_CLEAR_SEGOVR();
5199     END_OF_INSTR();
5200 }
5201 
5202 static u8 (*opc80_byte_operation[])(u8 d, u8 s) =
5203 {
5204     add_byte,           /* 00 */
5205     or_byte,            /* 01 */
5206     adc_byte,           /* 02 */
5207     sbb_byte,           /* 03 */
5208     and_byte,           /* 04 */
5209     sub_byte,           /* 05 */
5210     xor_byte,           /* 06 */
5211     cmp_byte,           /* 07 */
5212 };
5213 
5214 /****************************************************************************
5215 REMARKS:
5216 Handles opcode 0x80
5217 ****************************************************************************/
x86emuOp_opc80_byte_RM_IMM(u8 X86EMU_UNUSED (op1))5218 void x86emuOp_opc80_byte_RM_IMM(u8 X86EMU_UNUSED(op1))
5219 {
5220     int mod, rl, rh;
5221     u8 *destreg;
5222     uint destoffset;
5223     u8 imm;
5224     u8 destval;
5225 
5226     /*
5227      * Weirdo special case instruction format.  Part of the opcode
5228      * held below in "RH".  Doubly nested case would result, except
5229      * that the decoded instruction
5230      */
5231     START_OF_INSTR();
5232     FETCH_DECODE_MODRM(mod, rh, rl);
5233 #ifdef DEBUG
5234     if (DEBUG_DECODE()) {
5235         /* XXX DECODE_PRINTF may be changed to something more
5236            general, so that it is important to leave the strings
5237            in the same format, even though the result is that the
5238            above test is done twice. */
5239 
5240         switch (rh) {
5241         case 0:
5242             DECODE_PRINTF("ADD\t");
5243             break;
5244         case 1:
5245             DECODE_PRINTF("OR\t");
5246             break;
5247         case 2:
5248             DECODE_PRINTF("ADC\t");
5249             break;
5250         case 3:
5251             DECODE_PRINTF("SBB\t");
5252             break;
5253         case 4:
5254             DECODE_PRINTF("AND\t");
5255             break;
5256         case 5:
5257             DECODE_PRINTF("SUB\t");
5258             break;
5259         case 6:
5260             DECODE_PRINTF("XOR\t");
5261             break;
5262         case 7:
5263             DECODE_PRINTF("CMP\t");
5264             break;
5265         }
5266     }
5267 #endif
5268     /* know operation, decode the mod byte to find the addressing
5269        mode. */
5270     switch (mod) {
5271     case 0:
5272         DECODE_PRINTF("BYTE PTR ");
5273         destoffset = decode_rm00_address(rl);
5274         DECODE_PRINTF(",");
5275         destval = fetch_data_byte(destoffset);
5276         imm = fetch_byte_imm();
5277         DECODE_PRINTF2("%x\n", imm);
5278         TRACE_AND_STEP();
5279         destval = (*opc80_byte_operation[rh]) (destval, imm);
5280         if (rh != 7)
5281             store_data_byte(destoffset, destval);
5282         break;
5283     case 1:
5284         DECODE_PRINTF("BYTE PTR ");
5285         destoffset = decode_rm01_address(rl);
5286         DECODE_PRINTF(",");
5287         destval = fetch_data_byte(destoffset);
5288         imm = fetch_byte_imm();
5289         DECODE_PRINTF2("%x\n", imm);
5290         TRACE_AND_STEP();
5291         destval = (*opc80_byte_operation[rh]) (destval, imm);
5292         if (rh != 7)
5293             store_data_byte(destoffset, destval);
5294         break;
5295     case 2:
5296         DECODE_PRINTF("BYTE PTR ");
5297         destoffset = decode_rm10_address(rl);
5298         DECODE_PRINTF(",");
5299         destval = fetch_data_byte(destoffset);
5300         imm = fetch_byte_imm();
5301         DECODE_PRINTF2("%x\n", imm);
5302         TRACE_AND_STEP();
5303         destval = (*opc80_byte_operation[rh]) (destval, imm);
5304         if (rh != 7)
5305             store_data_byte(destoffset, destval);
5306         break;
5307     case 3:                     /* register to register */
5308         destreg = DECODE_RM_BYTE_REGISTER(rl);
5309         DECODE_PRINTF(",");
5310         imm = fetch_byte_imm();
5311         DECODE_PRINTF2("%x\n", imm);
5312         TRACE_AND_STEP();
5313         destval = (*opc80_byte_operation[rh]) (*destreg, imm);
5314         if (rh != 7)
5315             *destreg = destval;
5316         break;
5317     }
5318     DECODE_CLEAR_SEGOVR();
5319     END_OF_INSTR();
5320 }
5321 
5322 static u16 (*opc81_word_operation[])(u16 d, u16 s) =
5323 {
5324     add_word,           /*00 */
5325     or_word,            /*01 */
5326     adc_word,           /*02 */
5327     sbb_word,           /*03 */
5328     and_word,           /*04 */
5329     sub_word,           /*05 */
5330     xor_word,           /*06 */
5331     cmp_word,           /*07 */
5332 };
5333 
5334 static u32 (*opc81_long_operation[])(u32 d, u32 s) =
5335 {
5336     add_long,           /*00 */
5337     or_long,            /*01 */
5338     adc_long,           /*02 */
5339     sbb_long,           /*03 */
5340     and_long,           /*04 */
5341     sub_long,           /*05 */
5342     xor_long,           /*06 */
5343     cmp_long,           /*07 */
5344 };
5345 
5346 /****************************************************************************
5347 REMARKS:
5348 Handles opcode 0x81
5349 ****************************************************************************/
x86emuOp_opc81_word_RM_IMM(u8 X86EMU_UNUSED (op1))5350 void x86emuOp_opc81_word_RM_IMM(u8 X86EMU_UNUSED(op1))
5351 {
5352     int mod, rl, rh;
5353     uint destoffset;
5354 
5355     /*
5356      * Weirdo special case instruction format.  Part of the opcode
5357      * held below in "RH".  Doubly nested case would result, except
5358      * that the decoded instruction
5359      */
5360     START_OF_INSTR();
5361     FETCH_DECODE_MODRM(mod, rh, rl);
5362 #ifdef DEBUG
5363     if (DEBUG_DECODE()) {
5364         /* XXX DECODE_PRINTF may be changed to something more
5365            general, so that it is important to leave the strings
5366            in the same format, even though the result is that the
5367            above test is done twice. */
5368 
5369         switch (rh) {
5370         case 0:
5371             DECODE_PRINTF("ADD\t");
5372             break;
5373         case 1:
5374             DECODE_PRINTF("OR\t");
5375             break;
5376         case 2:
5377             DECODE_PRINTF("ADC\t");
5378             break;
5379         case 3:
5380             DECODE_PRINTF("SBB\t");
5381             break;
5382         case 4:
5383             DECODE_PRINTF("AND\t");
5384             break;
5385         case 5:
5386             DECODE_PRINTF("SUB\t");
5387             break;
5388         case 6:
5389             DECODE_PRINTF("XOR\t");
5390             break;
5391         case 7:
5392             DECODE_PRINTF("CMP\t");
5393             break;
5394         }
5395     }
5396 #endif
5397     /*
5398      * Know operation, decode the mod byte to find the addressing
5399      * mode.
5400      */
5401     switch (mod) {
5402     case 0:
5403         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5404             u32 destval,imm;
5405 
5406             DECODE_PRINTF("DWORD PTR ");
5407             destoffset = decode_rm00_address(rl);
5408             DECODE_PRINTF(",");
5409             destval = fetch_data_long(destoffset);
5410             imm = fetch_long_imm();
5411             DECODE_PRINTF2("%x\n", imm);
5412             TRACE_AND_STEP();
5413             destval = (*opc81_long_operation[rh]) (destval, imm);
5414             if (rh != 7)
5415                 store_data_long(destoffset, destval);
5416         } else {
5417             u16 destval,imm;
5418 
5419             DECODE_PRINTF("WORD PTR ");
5420             destoffset = decode_rm00_address(rl);
5421             DECODE_PRINTF(",");
5422             destval = fetch_data_word(destoffset);
5423             imm = fetch_word_imm();
5424             DECODE_PRINTF2("%x\n", imm);
5425             TRACE_AND_STEP();
5426             destval = (*opc81_word_operation[rh]) (destval, imm);
5427             if (rh != 7)
5428                 store_data_word(destoffset, destval);
5429         }
5430         break;
5431     case 1:
5432         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5433             u32 destval,imm;
5434 
5435             DECODE_PRINTF("DWORD PTR ");
5436             destoffset = decode_rm01_address(rl);
5437             DECODE_PRINTF(",");
5438             destval = fetch_data_long(destoffset);
5439             imm = fetch_long_imm();
5440             DECODE_PRINTF2("%x\n", imm);
5441             TRACE_AND_STEP();
5442             destval = (*opc81_long_operation[rh]) (destval, imm);
5443             if (rh != 7)
5444                 store_data_long(destoffset, destval);
5445         } else {
5446             u16 destval,imm;
5447 
5448             DECODE_PRINTF("WORD PTR ");
5449             destoffset = decode_rm01_address(rl);
5450             DECODE_PRINTF(",");
5451             destval = fetch_data_word(destoffset);
5452             imm = fetch_word_imm();
5453             DECODE_PRINTF2("%x\n", imm);
5454             TRACE_AND_STEP();
5455             destval = (*opc81_word_operation[rh]) (destval, imm);
5456             if (rh != 7)
5457                 store_data_word(destoffset, destval);
5458         }
5459         break;
5460     case 2:
5461         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5462             u32 destval,imm;
5463 
5464             DECODE_PRINTF("DWORD PTR ");
5465             destoffset = decode_rm10_address(rl);
5466             DECODE_PRINTF(",");
5467             destval = fetch_data_long(destoffset);
5468             imm = fetch_long_imm();
5469             DECODE_PRINTF2("%x\n", imm);
5470             TRACE_AND_STEP();
5471             destval = (*opc81_long_operation[rh]) (destval, imm);
5472             if (rh != 7)
5473                 store_data_long(destoffset, destval);
5474         } else {
5475             u16 destval,imm;
5476 
5477             DECODE_PRINTF("WORD PTR ");
5478             destoffset = decode_rm10_address(rl);
5479             DECODE_PRINTF(",");
5480             destval = fetch_data_word(destoffset);
5481             imm = fetch_word_imm();
5482             DECODE_PRINTF2("%x\n", imm);
5483             TRACE_AND_STEP();
5484             destval = (*opc81_word_operation[rh]) (destval, imm);
5485             if (rh != 7)
5486                 store_data_word(destoffset, destval);
5487         }
5488         break;
5489     case 3:                     /* register to register */
5490         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5491             u32 *destreg;
5492             u32 destval,imm;
5493 
5494             destreg = DECODE_RM_LONG_REGISTER(rl);
5495             DECODE_PRINTF(",");
5496             imm = fetch_long_imm();
5497             DECODE_PRINTF2("%x\n", imm);
5498             TRACE_AND_STEP();
5499             destval = (*opc81_long_operation[rh]) (*destreg, imm);
5500             if (rh != 7)
5501                 *destreg = destval;
5502         } else {
5503             u16 *destreg;
5504             u16 destval,imm;
5505 
5506             destreg = DECODE_RM_WORD_REGISTER(rl);
5507             DECODE_PRINTF(",");
5508             imm = fetch_word_imm();
5509             DECODE_PRINTF2("%x\n", imm);
5510             TRACE_AND_STEP();
5511             destval = (*opc81_word_operation[rh]) (*destreg, imm);
5512             if (rh != 7)
5513                 *destreg = destval;
5514         }
5515         break;
5516     }
5517     DECODE_CLEAR_SEGOVR();
5518     END_OF_INSTR();
5519 }
5520 
5521 static u8 (*opc82_byte_operation[])(u8 s, u8 d) =
5522 {
5523     add_byte,           /*00 */
5524     or_byte,            /*01 *//*YYY UNUSED ???? */
5525     adc_byte,           /*02 */
5526     sbb_byte,           /*03 */
5527     and_byte,           /*04 *//*YYY UNUSED ???? */
5528     sub_byte,           /*05 */
5529     xor_byte,           /*06 *//*YYY UNUSED ???? */
5530     cmp_byte,           /*07 */
5531 };
5532 
5533 /****************************************************************************
5534 REMARKS:
5535 Handles opcode 0x82
5536 ****************************************************************************/
x86emuOp_opc82_byte_RM_IMM(u8 X86EMU_UNUSED (op1))5537 void x86emuOp_opc82_byte_RM_IMM(u8 X86EMU_UNUSED(op1))
5538 {
5539     int mod, rl, rh;
5540     u8 *destreg;
5541     uint destoffset;
5542     u8 imm;
5543     u8 destval;
5544 
5545     /*
5546      * Weirdo special case instruction format.  Part of the opcode
5547      * held below in "RH".  Doubly nested case would result, except
5548      * that the decoded instruction Similar to opcode 81, except that
5549      * the immediate byte is sign extended to a word length.
5550      */
5551     START_OF_INSTR();
5552     FETCH_DECODE_MODRM(mod, rh, rl);
5553 #ifdef DEBUG
5554     if (DEBUG_DECODE()) {
5555         /* XXX DECODE_PRINTF may be changed to something more
5556            general, so that it is important to leave the strings
5557            in the same format, even though the result is that the
5558            above test is done twice. */
5559         switch (rh) {
5560         case 0:
5561             DECODE_PRINTF("ADD\t");
5562             break;
5563         case 1:
5564             DECODE_PRINTF("OR\t");
5565             break;
5566         case 2:
5567             DECODE_PRINTF("ADC\t");
5568             break;
5569         case 3:
5570             DECODE_PRINTF("SBB\t");
5571             break;
5572         case 4:
5573             DECODE_PRINTF("AND\t");
5574             break;
5575         case 5:
5576             DECODE_PRINTF("SUB\t");
5577             break;
5578         case 6:
5579             DECODE_PRINTF("XOR\t");
5580             break;
5581         case 7:
5582             DECODE_PRINTF("CMP\t");
5583             break;
5584         }
5585     }
5586 #endif
5587     /* know operation, decode the mod byte to find the addressing
5588        mode. */
5589     switch (mod) {
5590     case 0:
5591         DECODE_PRINTF("BYTE PTR ");
5592         destoffset = decode_rm00_address(rl);
5593         destval = fetch_data_byte(destoffset);
5594         imm = fetch_byte_imm();
5595         DECODE_PRINTF2(",%x\n", imm);
5596         TRACE_AND_STEP();
5597         destval = (*opc82_byte_operation[rh]) (destval, imm);
5598         if (rh != 7)
5599             store_data_byte(destoffset, destval);
5600         break;
5601     case 1:
5602         DECODE_PRINTF("BYTE PTR ");
5603         destoffset = decode_rm01_address(rl);
5604         destval = fetch_data_byte(destoffset);
5605         imm = fetch_byte_imm();
5606         DECODE_PRINTF2(",%x\n", imm);
5607         TRACE_AND_STEP();
5608         destval = (*opc82_byte_operation[rh]) (destval, imm);
5609         if (rh != 7)
5610             store_data_byte(destoffset, destval);
5611         break;
5612     case 2:
5613         DECODE_PRINTF("BYTE PTR ");
5614         destoffset = decode_rm10_address(rl);
5615         destval = fetch_data_byte(destoffset);
5616         imm = fetch_byte_imm();
5617         DECODE_PRINTF2(",%x\n", imm);
5618         TRACE_AND_STEP();
5619         destval = (*opc82_byte_operation[rh]) (destval, imm);
5620         if (rh != 7)
5621             store_data_byte(destoffset, destval);
5622         break;
5623     case 3:                     /* register to register */
5624         destreg = DECODE_RM_BYTE_REGISTER(rl);
5625         imm = fetch_byte_imm();
5626         DECODE_PRINTF2(",%x\n", imm);
5627         TRACE_AND_STEP();
5628         destval = (*opc82_byte_operation[rh]) (*destreg, imm);
5629         if (rh != 7)
5630             *destreg = destval;
5631         break;
5632     }
5633     DECODE_CLEAR_SEGOVR();
5634     END_OF_INSTR();
5635 }
5636 
5637 static u16 (*opc83_word_operation[])(u16 s, u16 d) =
5638 {
5639     add_word,           /*00 */
5640     or_word,            /*01 *//*YYY UNUSED ???? */
5641     adc_word,           /*02 */
5642     sbb_word,           /*03 */
5643     and_word,           /*04 *//*YYY UNUSED ???? */
5644     sub_word,           /*05 */
5645     xor_word,           /*06 *//*YYY UNUSED ???? */
5646     cmp_word,           /*07 */
5647 };
5648 
5649 static u32 (*opc83_long_operation[])(u32 s, u32 d) =
5650 {
5651     add_long,           /*00 */
5652     or_long,            /*01 *//*YYY UNUSED ???? */
5653     adc_long,           /*02 */
5654     sbb_long,           /*03 */
5655     and_long,           /*04 *//*YYY UNUSED ???? */
5656     sub_long,           /*05 */
5657     xor_long,           /*06 *//*YYY UNUSED ???? */
5658     cmp_long,           /*07 */
5659 };
5660 
5661 /****************************************************************************
5662 REMARKS:
5663 Handles opcode 0x83
5664 ****************************************************************************/
x86emuOp_opc83_word_RM_IMM(u8 X86EMU_UNUSED (op1))5665 void x86emuOp_opc83_word_RM_IMM(u8 X86EMU_UNUSED(op1))
5666 {
5667     int mod, rl, rh;
5668     uint destoffset;
5669 
5670     /*
5671      * Weirdo special case instruction format.  Part of the opcode
5672      * held below in "RH".  Doubly nested case would result, except
5673      * that the decoded instruction Similar to opcode 81, except that
5674      * the immediate byte is sign extended to a word length.
5675      */
5676     START_OF_INSTR();
5677     FETCH_DECODE_MODRM(mod, rh, rl);
5678 #ifdef DEBUG
5679     if (DEBUG_DECODE()) {
5680         /* XXX DECODE_PRINTF may be changed to something more
5681            general, so that it is important to leave the strings
5682            in the same format, even though the result is that the
5683            above test is done twice. */
5684        switch (rh) {
5685         case 0:
5686             DECODE_PRINTF("ADD\t");
5687             break;
5688         case 1:
5689             DECODE_PRINTF("OR\t");
5690             break;
5691         case 2:
5692             DECODE_PRINTF("ADC\t");
5693             break;
5694         case 3:
5695             DECODE_PRINTF("SBB\t");
5696             break;
5697         case 4:
5698             DECODE_PRINTF("AND\t");
5699             break;
5700         case 5:
5701             DECODE_PRINTF("SUB\t");
5702             break;
5703         case 6:
5704             DECODE_PRINTF("XOR\t");
5705             break;
5706         case 7:
5707             DECODE_PRINTF("CMP\t");
5708             break;
5709         }
5710     }
5711 #endif
5712     /* know operation, decode the mod byte to find the addressing
5713        mode. */
5714     switch (mod) {
5715     case 0:
5716         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5717             u32 destval,imm;
5718 
5719             DECODE_PRINTF("DWORD PTR ");
5720             destoffset = decode_rm00_address(rl);
5721             destval = fetch_data_long(destoffset);
5722             imm = (s8) fetch_byte_imm();
5723             DECODE_PRINTF2(",%x\n", imm);
5724             TRACE_AND_STEP();
5725             destval = (*opc83_long_operation[rh]) (destval, imm);
5726             if (rh != 7)
5727                 store_data_long(destoffset, destval);
5728         } else {
5729             u16 destval,imm;
5730 
5731             DECODE_PRINTF("WORD PTR ");
5732             destoffset = decode_rm00_address(rl);
5733             destval = fetch_data_word(destoffset);
5734             imm = (s8) fetch_byte_imm();
5735             DECODE_PRINTF2(",%x\n", imm);
5736             TRACE_AND_STEP();
5737             destval = (*opc83_word_operation[rh]) (destval, imm);
5738             if (rh != 7)
5739                 store_data_word(destoffset, destval);
5740         }
5741         break;
5742     case 1:
5743         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5744             u32 destval,imm;
5745 
5746             DECODE_PRINTF("DWORD PTR ");
5747             destoffset = decode_rm01_address(rl);
5748             destval = fetch_data_long(destoffset);
5749             imm = (s8) fetch_byte_imm();
5750             DECODE_PRINTF2(",%x\n", imm);
5751             TRACE_AND_STEP();
5752             destval = (*opc83_long_operation[rh]) (destval, imm);
5753             if (rh != 7)
5754                 store_data_long(destoffset, destval);
5755         } else {
5756             u16 destval,imm;
5757 
5758             DECODE_PRINTF("WORD PTR ");
5759             destoffset = decode_rm01_address(rl);
5760             destval = fetch_data_word(destoffset);
5761             imm = (s8) fetch_byte_imm();
5762             DECODE_PRINTF2(",%x\n", imm);
5763             TRACE_AND_STEP();
5764             destval = (*opc83_word_operation[rh]) (destval, imm);
5765             if (rh != 7)
5766                 store_data_word(destoffset, destval);
5767         }
5768         break;
5769     case 2:
5770         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5771             u32 destval,imm;
5772 
5773             DECODE_PRINTF("DWORD PTR ");
5774             destoffset = decode_rm10_address(rl);
5775             destval = fetch_data_long(destoffset);
5776             imm = (s8) fetch_byte_imm();
5777             DECODE_PRINTF2(",%x\n", imm);
5778             TRACE_AND_STEP();
5779             destval = (*opc83_long_operation[rh]) (destval, imm);
5780             if (rh != 7)
5781                 store_data_long(destoffset, destval);
5782         } else {
5783             u16 destval,imm;
5784 
5785             DECODE_PRINTF("WORD PTR ");
5786             destoffset = decode_rm10_address(rl);
5787             destval = fetch_data_word(destoffset);
5788             imm = (s8) fetch_byte_imm();
5789             DECODE_PRINTF2(",%x\n", imm);
5790             TRACE_AND_STEP();
5791             destval = (*opc83_word_operation[rh]) (destval, imm);
5792             if (rh != 7)
5793                 store_data_word(destoffset, destval);
5794         }
5795         break;
5796     case 3:                     /* register to register */
5797         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5798             u32 *destreg;
5799             u32 destval,imm;
5800 
5801             destreg = DECODE_RM_LONG_REGISTER(rl);
5802             imm = (s8) fetch_byte_imm();
5803             DECODE_PRINTF2(",%x\n", imm);
5804             TRACE_AND_STEP();
5805             destval = (*opc83_long_operation[rh]) (*destreg, imm);
5806             if (rh != 7)
5807                 *destreg = destval;
5808         } else {
5809             u16 *destreg;
5810             u16 destval,imm;
5811 
5812             destreg = DECODE_RM_WORD_REGISTER(rl);
5813             imm = (s8) fetch_byte_imm();
5814             DECODE_PRINTF2(",%x\n", imm);
5815             TRACE_AND_STEP();
5816             destval = (*opc83_word_operation[rh]) (*destreg, imm);
5817             if (rh != 7)
5818                 *destreg = destval;
5819         }
5820         break;
5821     }
5822     DECODE_CLEAR_SEGOVR();
5823     END_OF_INSTR();
5824 }
5825 
5826 /****************************************************************************
5827 REMARKS:
5828 Handles opcode 0x84
5829 ****************************************************************************/
x86emuOp_test_byte_RM_R(u8 X86EMU_UNUSED (op1))5830 void x86emuOp_test_byte_RM_R(u8 X86EMU_UNUSED(op1))
5831 {
5832     int mod, rl, rh;
5833     u8 *destreg, *srcreg;
5834     uint destoffset;
5835     u8 destval;
5836 
5837     START_OF_INSTR();
5838     DECODE_PRINTF("TEST\t");
5839     FETCH_DECODE_MODRM(mod, rh, rl);
5840     switch (mod) {
5841     case 0:
5842         destoffset = decode_rm00_address(rl);
5843         DECODE_PRINTF(",");
5844         destval = fetch_data_byte(destoffset);
5845         srcreg = DECODE_RM_BYTE_REGISTER(rh);
5846         DECODE_PRINTF("\n");
5847         TRACE_AND_STEP();
5848         test_byte(destval, *srcreg);
5849         break;
5850     case 1:
5851         destoffset = decode_rm01_address(rl);
5852         DECODE_PRINTF(",");
5853         destval = fetch_data_byte(destoffset);
5854         srcreg = DECODE_RM_BYTE_REGISTER(rh);
5855         DECODE_PRINTF("\n");
5856         TRACE_AND_STEP();
5857         test_byte(destval, *srcreg);
5858         break;
5859     case 2:
5860         destoffset = decode_rm10_address(rl);
5861         DECODE_PRINTF(",");
5862         destval = fetch_data_byte(destoffset);
5863         srcreg = DECODE_RM_BYTE_REGISTER(rh);
5864         DECODE_PRINTF("\n");
5865         TRACE_AND_STEP();
5866         test_byte(destval, *srcreg);
5867         break;
5868     case 3:                     /* register to register */
5869         destreg = DECODE_RM_BYTE_REGISTER(rl);
5870         DECODE_PRINTF(",");
5871         srcreg = DECODE_RM_BYTE_REGISTER(rh);
5872         DECODE_PRINTF("\n");
5873         TRACE_AND_STEP();
5874         test_byte(*destreg, *srcreg);
5875         break;
5876     }
5877     DECODE_CLEAR_SEGOVR();
5878     END_OF_INSTR();
5879 }
5880 
5881 /****************************************************************************
5882 REMARKS:
5883 Handles opcode 0x85
5884 ****************************************************************************/
x86emuOp_test_word_RM_R(u8 X86EMU_UNUSED (op1))5885 void x86emuOp_test_word_RM_R(u8 X86EMU_UNUSED(op1))
5886 {
5887     int mod, rl, rh;
5888     uint destoffset;
5889 
5890     START_OF_INSTR();
5891     DECODE_PRINTF("TEST\t");
5892     FETCH_DECODE_MODRM(mod, rh, rl);
5893     switch (mod) {
5894     case 0:
5895         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5896             u32 destval;
5897             u32 *srcreg;
5898 
5899             destoffset = decode_rm00_address(rl);
5900             DECODE_PRINTF(",");
5901             destval = fetch_data_long(destoffset);
5902             srcreg = DECODE_RM_LONG_REGISTER(rh);
5903             DECODE_PRINTF("\n");
5904             TRACE_AND_STEP();
5905             test_long(destval, *srcreg);
5906         } else {
5907             u16 destval;
5908             u16 *srcreg;
5909 
5910             destoffset = decode_rm00_address(rl);
5911             DECODE_PRINTF(",");
5912             destval = fetch_data_word(destoffset);
5913             srcreg = DECODE_RM_WORD_REGISTER(rh);
5914             DECODE_PRINTF("\n");
5915             TRACE_AND_STEP();
5916             test_word(destval, *srcreg);
5917         }
5918         break;
5919     case 1:
5920         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5921             u32 destval;
5922             u32 *srcreg;
5923 
5924             destoffset = decode_rm01_address(rl);
5925             DECODE_PRINTF(",");
5926             destval = fetch_data_long(destoffset);
5927             srcreg = DECODE_RM_LONG_REGISTER(rh);
5928             DECODE_PRINTF("\n");
5929             TRACE_AND_STEP();
5930             test_long(destval, *srcreg);
5931         } else {
5932             u16 destval;
5933             u16 *srcreg;
5934 
5935             destoffset = decode_rm01_address(rl);
5936             DECODE_PRINTF(",");
5937             destval = fetch_data_word(destoffset);
5938             srcreg = DECODE_RM_WORD_REGISTER(rh);
5939             DECODE_PRINTF("\n");
5940             TRACE_AND_STEP();
5941             test_word(destval, *srcreg);
5942         }
5943         break;
5944     case 2:
5945         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5946             u32 destval;
5947             u32 *srcreg;
5948 
5949             destoffset = decode_rm10_address(rl);
5950             DECODE_PRINTF(",");
5951             destval = fetch_data_long(destoffset);
5952             srcreg = DECODE_RM_LONG_REGISTER(rh);
5953             DECODE_PRINTF("\n");
5954             TRACE_AND_STEP();
5955             test_long(destval, *srcreg);
5956         } else {
5957             u16 destval;
5958             u16 *srcreg;
5959 
5960             destoffset = decode_rm10_address(rl);
5961             DECODE_PRINTF(",");
5962             destval = fetch_data_word(destoffset);
5963             srcreg = DECODE_RM_WORD_REGISTER(rh);
5964             DECODE_PRINTF("\n");
5965             TRACE_AND_STEP();
5966             test_word(destval, *srcreg);
5967         }
5968         break;
5969     case 3:                     /* register to register */
5970         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
5971             u32 *destreg,*srcreg;
5972 
5973             destreg = DECODE_RM_LONG_REGISTER(rl);
5974             DECODE_PRINTF(",");
5975             srcreg = DECODE_RM_LONG_REGISTER(rh);
5976             DECODE_PRINTF("\n");
5977             TRACE_AND_STEP();
5978             test_long(*destreg, *srcreg);
5979         } else {
5980             u16 *destreg,*srcreg;
5981 
5982             destreg = DECODE_RM_WORD_REGISTER(rl);
5983             DECODE_PRINTF(",");
5984             srcreg = DECODE_RM_WORD_REGISTER(rh);
5985             DECODE_PRINTF("\n");
5986             TRACE_AND_STEP();
5987             test_word(*destreg, *srcreg);
5988         }
5989         break;
5990     }
5991     DECODE_CLEAR_SEGOVR();
5992     END_OF_INSTR();
5993 }
5994 
5995 /****************************************************************************
5996 REMARKS:
5997 Handles opcode 0x86
5998 ****************************************************************************/
x86emuOp_xchg_byte_RM_R(u8 X86EMU_UNUSED (op1))5999 void x86emuOp_xchg_byte_RM_R(u8 X86EMU_UNUSED(op1))
6000 {
6001     int mod, rl, rh;
6002     u8 *destreg, *srcreg;
6003     uint destoffset;
6004     u8 destval;
6005     u8 tmp;
6006 
6007     START_OF_INSTR();
6008     DECODE_PRINTF("XCHG\t");
6009     FETCH_DECODE_MODRM(mod, rh, rl);
6010     switch (mod) {
6011     case 0:
6012         destoffset = decode_rm00_address(rl);
6013         DECODE_PRINTF(",");
6014         destval = fetch_data_byte(destoffset);
6015         srcreg = DECODE_RM_BYTE_REGISTER(rh);
6016         DECODE_PRINTF("\n");
6017         TRACE_AND_STEP();
6018         tmp = *srcreg;
6019         *srcreg = destval;
6020         destval = tmp;
6021         store_data_byte(destoffset, destval);
6022         break;
6023     case 1:
6024         destoffset = decode_rm01_address(rl);
6025         DECODE_PRINTF(",");
6026         destval = fetch_data_byte(destoffset);
6027         srcreg = DECODE_RM_BYTE_REGISTER(rh);
6028         DECODE_PRINTF("\n");
6029         TRACE_AND_STEP();
6030         tmp = *srcreg;
6031         *srcreg = destval;
6032         destval = tmp;
6033         store_data_byte(destoffset, destval);
6034         break;
6035     case 2:
6036         destoffset = decode_rm10_address(rl);
6037         DECODE_PRINTF(",");
6038         destval = fetch_data_byte(destoffset);
6039         srcreg = DECODE_RM_BYTE_REGISTER(rh);
6040         DECODE_PRINTF("\n");
6041         TRACE_AND_STEP();
6042         tmp = *srcreg;
6043         *srcreg = destval;
6044         destval = tmp;
6045         store_data_byte(destoffset, destval);
6046         break;
6047     case 3:                     /* register to register */
6048         destreg = DECODE_RM_BYTE_REGISTER(rl);
6049         DECODE_PRINTF(",");
6050         srcreg = DECODE_RM_BYTE_REGISTER(rh);
6051         DECODE_PRINTF("\n");
6052         TRACE_AND_STEP();
6053         tmp = *srcreg;
6054         *srcreg = *destreg;
6055         *destreg = tmp;
6056         break;
6057     }
6058     DECODE_CLEAR_SEGOVR();
6059     END_OF_INSTR();
6060 }
6061 
6062 /****************************************************************************
6063 REMARKS:
6064 Handles opcode 0x87
6065 ****************************************************************************/
x86emuOp_xchg_word_RM_R(u8 X86EMU_UNUSED (op1))6066 void x86emuOp_xchg_word_RM_R(u8 X86EMU_UNUSED(op1))
6067 {
6068     int mod, rl, rh;
6069     uint destoffset;
6070 
6071     START_OF_INSTR();
6072     DECODE_PRINTF("XCHG\t");
6073     FETCH_DECODE_MODRM(mod, rh, rl);
6074     switch (mod) {
6075     case 0:
6076         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6077             u32 *srcreg;
6078             u32 destval,tmp;
6079 
6080             destoffset = decode_rm00_address(rl);
6081             DECODE_PRINTF(",");
6082             destval = fetch_data_long(destoffset);
6083             srcreg = DECODE_RM_LONG_REGISTER(rh);
6084             DECODE_PRINTF("\n");
6085             TRACE_AND_STEP();
6086             tmp = *srcreg;
6087             *srcreg = destval;
6088             destval = tmp;
6089             store_data_long(destoffset, destval);
6090         } else {
6091             u16 *srcreg;
6092             u16 destval,tmp;
6093 
6094             destoffset = decode_rm00_address(rl);
6095             DECODE_PRINTF(",");
6096             destval = fetch_data_word(destoffset);
6097             srcreg = DECODE_RM_WORD_REGISTER(rh);
6098             DECODE_PRINTF("\n");
6099             TRACE_AND_STEP();
6100             tmp = *srcreg;
6101             *srcreg = destval;
6102             destval = tmp;
6103             store_data_word(destoffset, destval);
6104         }
6105         break;
6106     case 1:
6107         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6108             u32 *srcreg;
6109             u32 destval,tmp;
6110 
6111             destoffset = decode_rm01_address(rl);
6112             DECODE_PRINTF(",");
6113             destval = fetch_data_long(destoffset);
6114             srcreg = DECODE_RM_LONG_REGISTER(rh);
6115             DECODE_PRINTF("\n");
6116             TRACE_AND_STEP();
6117             tmp = *srcreg;
6118             *srcreg = destval;
6119             destval = tmp;
6120             store_data_long(destoffset, destval);
6121         } else {
6122             u16 *srcreg;
6123             u16 destval,tmp;
6124 
6125             destoffset = decode_rm01_address(rl);
6126             DECODE_PRINTF(",");
6127             destval = fetch_data_word(destoffset);
6128             srcreg = DECODE_RM_WORD_REGISTER(rh);
6129             DECODE_PRINTF("\n");
6130             TRACE_AND_STEP();
6131             tmp = *srcreg;
6132             *srcreg = destval;
6133             destval = tmp;
6134             store_data_word(destoffset, destval);
6135         }
6136         break;
6137     case 2:
6138         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6139             u32 *srcreg;
6140             u32 destval,tmp;
6141 
6142             destoffset = decode_rm10_address(rl);
6143             DECODE_PRINTF(",");
6144             destval = fetch_data_long(destoffset);
6145             srcreg = DECODE_RM_LONG_REGISTER(rh);
6146             DECODE_PRINTF("\n");
6147             TRACE_AND_STEP();
6148             tmp = *srcreg;
6149             *srcreg = destval;
6150             destval = tmp;
6151             store_data_long(destoffset, destval);
6152         } else {
6153             u16 *srcreg;
6154             u16 destval,tmp;
6155 
6156             destoffset = decode_rm10_address(rl);
6157             DECODE_PRINTF(",");
6158             destval = fetch_data_word(destoffset);
6159             srcreg = DECODE_RM_WORD_REGISTER(rh);
6160             DECODE_PRINTF("\n");
6161             TRACE_AND_STEP();
6162             tmp = *srcreg;
6163             *srcreg = destval;
6164             destval = tmp;
6165             store_data_word(destoffset, destval);
6166         }
6167         break;
6168     case 3:                     /* register to register */
6169         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6170             u32 *destreg,*srcreg;
6171             u32 tmp;
6172 
6173             destreg = DECODE_RM_LONG_REGISTER(rl);
6174             DECODE_PRINTF(",");
6175             srcreg = DECODE_RM_LONG_REGISTER(rh);
6176             DECODE_PRINTF("\n");
6177             TRACE_AND_STEP();
6178             tmp = *srcreg;
6179             *srcreg = *destreg;
6180             *destreg = tmp;
6181         } else {
6182             u16 *destreg,*srcreg;
6183             u16 tmp;
6184 
6185             destreg = DECODE_RM_WORD_REGISTER(rl);
6186             DECODE_PRINTF(",");
6187             srcreg = DECODE_RM_WORD_REGISTER(rh);
6188             DECODE_PRINTF("\n");
6189             TRACE_AND_STEP();
6190             tmp = *srcreg;
6191             *srcreg = *destreg;
6192             *destreg = tmp;
6193         }
6194         break;
6195     }
6196     DECODE_CLEAR_SEGOVR();
6197     END_OF_INSTR();
6198 }
6199 
6200 /****************************************************************************
6201 REMARKS:
6202 Handles opcode 0x88
6203 ****************************************************************************/
x86emuOp_mov_byte_RM_R(u8 X86EMU_UNUSED (op1))6204 void x86emuOp_mov_byte_RM_R(u8 X86EMU_UNUSED(op1))
6205 {
6206     int mod, rl, rh;
6207     u8 *destreg, *srcreg;
6208     uint destoffset;
6209 
6210     START_OF_INSTR();
6211     DECODE_PRINTF("MOV\t");
6212     FETCH_DECODE_MODRM(mod, rh, rl);
6213     switch (mod) {
6214     case 0:
6215         destoffset = decode_rm00_address(rl);
6216         DECODE_PRINTF(",");
6217         srcreg = DECODE_RM_BYTE_REGISTER(rh);
6218         DECODE_PRINTF("\n");
6219         TRACE_AND_STEP();
6220         store_data_byte(destoffset, *srcreg);
6221         break;
6222     case 1:
6223         destoffset = decode_rm01_address(rl);
6224         DECODE_PRINTF(",");
6225         srcreg = DECODE_RM_BYTE_REGISTER(rh);
6226         DECODE_PRINTF("\n");
6227         TRACE_AND_STEP();
6228         store_data_byte(destoffset, *srcreg);
6229         break;
6230     case 2:
6231         destoffset = decode_rm10_address(rl);
6232         DECODE_PRINTF(",");
6233         srcreg = DECODE_RM_BYTE_REGISTER(rh);
6234         DECODE_PRINTF("\n");
6235         TRACE_AND_STEP();
6236         store_data_byte(destoffset, *srcreg);
6237         break;
6238     case 3:                     /* register to register */
6239         destreg = DECODE_RM_BYTE_REGISTER(rl);
6240         DECODE_PRINTF(",");
6241         srcreg = DECODE_RM_BYTE_REGISTER(rh);
6242         DECODE_PRINTF("\n");
6243         TRACE_AND_STEP();
6244         *destreg = *srcreg;
6245         break;
6246     }
6247     DECODE_CLEAR_SEGOVR();
6248     END_OF_INSTR();
6249 }
6250 
6251 /****************************************************************************
6252 REMARKS:
6253 Handles opcode 0x89
6254 ****************************************************************************/
x86emuOp_mov_word_RM_R(u8 X86EMU_UNUSED (op1))6255 void x86emuOp_mov_word_RM_R(u8 X86EMU_UNUSED(op1))
6256 {
6257     int mod, rl, rh;
6258     uint destoffset;
6259 
6260     START_OF_INSTR();
6261     DECODE_PRINTF("MOV\t");
6262     FETCH_DECODE_MODRM(mod, rh, rl);
6263     switch (mod) {
6264     case 0:
6265         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6266             u32 *srcreg;
6267 
6268             destoffset = decode_rm00_address(rl);
6269             DECODE_PRINTF(",");
6270             srcreg = DECODE_RM_LONG_REGISTER(rh);
6271             DECODE_PRINTF("\n");
6272             TRACE_AND_STEP();
6273             store_data_long(destoffset, *srcreg);
6274         } else {
6275             u16 *srcreg;
6276 
6277             destoffset = decode_rm00_address(rl);
6278             DECODE_PRINTF(",");
6279             srcreg = DECODE_RM_WORD_REGISTER(rh);
6280             DECODE_PRINTF("\n");
6281             TRACE_AND_STEP();
6282             store_data_word(destoffset, *srcreg);
6283         }
6284         break;
6285     case 1:
6286         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6287             u32 *srcreg;
6288 
6289             destoffset = decode_rm01_address(rl);
6290             DECODE_PRINTF(",");
6291             srcreg = DECODE_RM_LONG_REGISTER(rh);
6292             DECODE_PRINTF("\n");
6293             TRACE_AND_STEP();
6294             store_data_long(destoffset, *srcreg);
6295         } else {
6296             u16 *srcreg;
6297 
6298             destoffset = decode_rm01_address(rl);
6299             DECODE_PRINTF(",");
6300             srcreg = DECODE_RM_WORD_REGISTER(rh);
6301             DECODE_PRINTF("\n");
6302             TRACE_AND_STEP();
6303             store_data_word(destoffset, *srcreg);
6304         }
6305         break;
6306     case 2:
6307         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6308             u32 *srcreg;
6309 
6310             destoffset = decode_rm10_address(rl);
6311             DECODE_PRINTF(",");
6312             srcreg = DECODE_RM_LONG_REGISTER(rh);
6313             DECODE_PRINTF("\n");
6314             TRACE_AND_STEP();
6315             store_data_long(destoffset, *srcreg);
6316         } else {
6317             u16 *srcreg;
6318 
6319             destoffset = decode_rm10_address(rl);
6320             DECODE_PRINTF(",");
6321             srcreg = DECODE_RM_WORD_REGISTER(rh);
6322             DECODE_PRINTF("\n");
6323             TRACE_AND_STEP();
6324             store_data_word(destoffset, *srcreg);
6325         }
6326         break;
6327     case 3:                     /* register to register */
6328         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6329             u32 *destreg,*srcreg;
6330 
6331             destreg = DECODE_RM_LONG_REGISTER(rl);
6332             DECODE_PRINTF(",");
6333             srcreg = DECODE_RM_LONG_REGISTER(rh);
6334             DECODE_PRINTF("\n");
6335             TRACE_AND_STEP();
6336             *destreg = *srcreg;
6337         } else {
6338             u16 *destreg,*srcreg;
6339 
6340             destreg = DECODE_RM_WORD_REGISTER(rl);
6341             DECODE_PRINTF(",");
6342             srcreg = DECODE_RM_WORD_REGISTER(rh);
6343             DECODE_PRINTF("\n");
6344             TRACE_AND_STEP();
6345             *destreg = *srcreg;
6346         }
6347         break;
6348     }
6349     DECODE_CLEAR_SEGOVR();
6350     END_OF_INSTR();
6351 }
6352 
6353 /****************************************************************************
6354 REMARKS:
6355 Handles opcode 0x8a
6356 ****************************************************************************/
x86emuOp_mov_byte_R_RM(u8 X86EMU_UNUSED (op1))6357 void x86emuOp_mov_byte_R_RM(u8 X86EMU_UNUSED(op1))
6358 {
6359     int mod, rl, rh;
6360     u8 *destreg, *srcreg;
6361     uint srcoffset;
6362     u8 srcval;
6363 
6364     START_OF_INSTR();
6365     DECODE_PRINTF("MOV\t");
6366     FETCH_DECODE_MODRM(mod, rh, rl);
6367     switch (mod) {
6368     case 0:
6369         destreg = DECODE_RM_BYTE_REGISTER(rh);
6370         DECODE_PRINTF(",");
6371         srcoffset = decode_rm00_address(rl);
6372         srcval = fetch_data_byte(srcoffset);
6373         DECODE_PRINTF("\n");
6374         TRACE_AND_STEP();
6375         *destreg = srcval;
6376         break;
6377     case 1:
6378         destreg = DECODE_RM_BYTE_REGISTER(rh);
6379         DECODE_PRINTF(",");
6380         srcoffset = decode_rm01_address(rl);
6381         srcval = fetch_data_byte(srcoffset);
6382         DECODE_PRINTF("\n");
6383         TRACE_AND_STEP();
6384         *destreg = srcval;
6385         break;
6386     case 2:
6387         destreg = DECODE_RM_BYTE_REGISTER(rh);
6388         DECODE_PRINTF(",");
6389         srcoffset = decode_rm10_address(rl);
6390         srcval = fetch_data_byte(srcoffset);
6391         DECODE_PRINTF("\n");
6392         TRACE_AND_STEP();
6393         *destreg = srcval;
6394         break;
6395     case 3:                     /* register to register */
6396         destreg = DECODE_RM_BYTE_REGISTER(rh);
6397         DECODE_PRINTF(",");
6398         srcreg = DECODE_RM_BYTE_REGISTER(rl);
6399         DECODE_PRINTF("\n");
6400         TRACE_AND_STEP();
6401         *destreg = *srcreg;
6402         break;
6403     }
6404     DECODE_CLEAR_SEGOVR();
6405     END_OF_INSTR();
6406 }
6407 
6408 /****************************************************************************
6409 REMARKS:
6410 Handles opcode 0x8b
6411 ****************************************************************************/
x86emuOp_mov_word_R_RM(u8 X86EMU_UNUSED (op1))6412 void x86emuOp_mov_word_R_RM(u8 X86EMU_UNUSED(op1))
6413 {
6414     int mod, rl, rh;
6415     uint srcoffset;
6416 
6417     START_OF_INSTR();
6418     DECODE_PRINTF("MOV\t");
6419     FETCH_DECODE_MODRM(mod, rh, rl);
6420     switch (mod) {
6421     case 0:
6422         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6423             u32 *destreg;
6424             u32 srcval;
6425 
6426             destreg = DECODE_RM_LONG_REGISTER(rh);
6427             DECODE_PRINTF(",");
6428             srcoffset = decode_rm00_address(rl);
6429             srcval = fetch_data_long(srcoffset);
6430             DECODE_PRINTF("\n");
6431             TRACE_AND_STEP();
6432             *destreg = srcval;
6433         } else {
6434             u16 *destreg;
6435             u16 srcval;
6436 
6437             destreg = DECODE_RM_WORD_REGISTER(rh);
6438             DECODE_PRINTF(",");
6439             srcoffset = decode_rm00_address(rl);
6440             srcval = fetch_data_word(srcoffset);
6441             DECODE_PRINTF("\n");
6442             TRACE_AND_STEP();
6443             *destreg = srcval;
6444         }
6445         break;
6446     case 1:
6447         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6448             u32 *destreg;
6449             u32 srcval;
6450 
6451             destreg = DECODE_RM_LONG_REGISTER(rh);
6452             DECODE_PRINTF(",");
6453             srcoffset = decode_rm01_address(rl);
6454             srcval = fetch_data_long(srcoffset);
6455             DECODE_PRINTF("\n");
6456             TRACE_AND_STEP();
6457             *destreg = srcval;
6458         } else {
6459             u16 *destreg;
6460             u16 srcval;
6461 
6462             destreg = DECODE_RM_WORD_REGISTER(rh);
6463             DECODE_PRINTF(",");
6464             srcoffset = decode_rm01_address(rl);
6465             srcval = fetch_data_word(srcoffset);
6466             DECODE_PRINTF("\n");
6467             TRACE_AND_STEP();
6468             *destreg = srcval;
6469         }
6470         break;
6471     case 2:
6472         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6473             u32 *destreg;
6474             u32 srcval;
6475 
6476             destreg = DECODE_RM_LONG_REGISTER(rh);
6477             DECODE_PRINTF(",");
6478             srcoffset = decode_rm10_address(rl);
6479             srcval = fetch_data_long(srcoffset);
6480             DECODE_PRINTF("\n");
6481             TRACE_AND_STEP();
6482             *destreg = srcval;
6483         } else {
6484             u16 *destreg;
6485             u16 srcval;
6486 
6487             destreg = DECODE_RM_WORD_REGISTER(rh);
6488             DECODE_PRINTF(",");
6489             srcoffset = decode_rm10_address(rl);
6490             srcval = fetch_data_word(srcoffset);
6491             DECODE_PRINTF("\n");
6492             TRACE_AND_STEP();
6493             *destreg = srcval;
6494         }
6495         break;
6496     case 3:                     /* register to register */
6497         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6498             u32 *destreg, *srcreg;
6499 
6500             destreg = DECODE_RM_LONG_REGISTER(rh);
6501             DECODE_PRINTF(",");
6502             srcreg = DECODE_RM_LONG_REGISTER(rl);
6503             DECODE_PRINTF("\n");
6504             TRACE_AND_STEP();
6505             *destreg = *srcreg;
6506         } else {
6507             u16 *destreg, *srcreg;
6508 
6509             destreg = DECODE_RM_WORD_REGISTER(rh);
6510             DECODE_PRINTF(",");
6511             srcreg = DECODE_RM_WORD_REGISTER(rl);
6512             DECODE_PRINTF("\n");
6513             TRACE_AND_STEP();
6514             *destreg = *srcreg;
6515         }
6516         break;
6517     }
6518     DECODE_CLEAR_SEGOVR();
6519     END_OF_INSTR();
6520 }
6521 
6522 /****************************************************************************
6523 REMARKS:
6524 Handles opcode 0x8c
6525 ****************************************************************************/
x86emuOp_mov_word_RM_SR(u8 X86EMU_UNUSED (op1))6526 void x86emuOp_mov_word_RM_SR(u8 X86EMU_UNUSED(op1))
6527 {
6528     int mod, rl, rh;
6529     u16 *destreg, *srcreg;
6530     uint destoffset;
6531     u16 destval;
6532 
6533     START_OF_INSTR();
6534     DECODE_PRINTF("MOV\t");
6535     FETCH_DECODE_MODRM(mod, rh, rl);
6536     switch (mod) {
6537     case 0:
6538         destoffset = decode_rm00_address(rl);
6539         DECODE_PRINTF(",");
6540         srcreg = decode_rm_seg_register(rh);
6541         DECODE_PRINTF("\n");
6542         TRACE_AND_STEP();
6543         destval = *srcreg;
6544         store_data_word(destoffset, destval);
6545         break;
6546     case 1:
6547         destoffset = decode_rm01_address(rl);
6548         DECODE_PRINTF(",");
6549         srcreg = decode_rm_seg_register(rh);
6550         DECODE_PRINTF("\n");
6551         TRACE_AND_STEP();
6552         destval = *srcreg;
6553         store_data_word(destoffset, destval);
6554         break;
6555     case 2:
6556         destoffset = decode_rm10_address(rl);
6557         DECODE_PRINTF(",");
6558         srcreg = decode_rm_seg_register(rh);
6559         DECODE_PRINTF("\n");
6560         TRACE_AND_STEP();
6561         destval = *srcreg;
6562         store_data_word(destoffset, destval);
6563         break;
6564     case 3:                     /* register to register */
6565         destreg = DECODE_RM_WORD_REGISTER(rl);
6566         DECODE_PRINTF(",");
6567         srcreg = decode_rm_seg_register(rh);
6568         DECODE_PRINTF("\n");
6569         TRACE_AND_STEP();
6570         *destreg = *srcreg;
6571         break;
6572     }
6573     DECODE_CLEAR_SEGOVR();
6574     END_OF_INSTR();
6575 }
6576 
6577 /****************************************************************************
6578 REMARKS:
6579 Handles opcode 0x8d
6580 ****************************************************************************/
x86emuOp_lea_word_R_M(u8 X86EMU_UNUSED (op1))6581 void x86emuOp_lea_word_R_M(u8 X86EMU_UNUSED(op1))
6582 {
6583     int mod, rl, rh;
6584     u16 *srcreg;
6585     uint destoffset;
6586 
6587 /*
6588  * TODO: Need to handle address size prefix!
6589  *
6590  * lea  eax,[eax+ebx*2] ??
6591  */
6592 
6593     START_OF_INSTR();
6594     DECODE_PRINTF("LEA\t");
6595     FETCH_DECODE_MODRM(mod, rh, rl);
6596     switch (mod) {
6597     case 0:
6598         srcreg = DECODE_RM_WORD_REGISTER(rh);
6599         DECODE_PRINTF(",");
6600         destoffset = decode_rm00_address(rl);
6601         DECODE_PRINTF("\n");
6602         TRACE_AND_STEP();
6603         *srcreg = (u16)destoffset;
6604         break;
6605     case 1:
6606         srcreg = DECODE_RM_WORD_REGISTER(rh);
6607         DECODE_PRINTF(",");
6608         destoffset = decode_rm01_address(rl);
6609         DECODE_PRINTF("\n");
6610         TRACE_AND_STEP();
6611         *srcreg = (u16)destoffset;
6612         break;
6613     case 2:
6614         srcreg = DECODE_RM_WORD_REGISTER(rh);
6615         DECODE_PRINTF(",");
6616         destoffset = decode_rm10_address(rl);
6617         DECODE_PRINTF("\n");
6618         TRACE_AND_STEP();
6619         *srcreg = (u16)destoffset;
6620         break;
6621     case 3:                     /* register to register */
6622         /* undefined.  Do nothing. */
6623         break;
6624     }
6625     DECODE_CLEAR_SEGOVR();
6626     END_OF_INSTR();
6627 }
6628 
6629 /****************************************************************************
6630 REMARKS:
6631 Handles opcode 0x8e
6632 ****************************************************************************/
x86emuOp_mov_word_SR_RM(u8 X86EMU_UNUSED (op1))6633 void x86emuOp_mov_word_SR_RM(u8 X86EMU_UNUSED(op1))
6634 {
6635     int mod, rl, rh;
6636     u16 *destreg, *srcreg;
6637     uint srcoffset;
6638     u16 srcval;
6639 
6640     START_OF_INSTR();
6641     DECODE_PRINTF("MOV\t");
6642     FETCH_DECODE_MODRM(mod, rh, rl);
6643     switch (mod) {
6644     case 0:
6645         destreg = decode_rm_seg_register(rh);
6646         DECODE_PRINTF(",");
6647         srcoffset = decode_rm00_address(rl);
6648         srcval = fetch_data_word(srcoffset);
6649         DECODE_PRINTF("\n");
6650         TRACE_AND_STEP();
6651         *destreg = srcval;
6652         break;
6653     case 1:
6654         destreg = decode_rm_seg_register(rh);
6655         DECODE_PRINTF(",");
6656         srcoffset = decode_rm01_address(rl);
6657         srcval = fetch_data_word(srcoffset);
6658         DECODE_PRINTF("\n");
6659         TRACE_AND_STEP();
6660         *destreg = srcval;
6661         break;
6662     case 2:
6663         destreg = decode_rm_seg_register(rh);
6664         DECODE_PRINTF(",");
6665         srcoffset = decode_rm10_address(rl);
6666         srcval = fetch_data_word(srcoffset);
6667         DECODE_PRINTF("\n");
6668         TRACE_AND_STEP();
6669         *destreg = srcval;
6670         break;
6671     case 3:                     /* register to register */
6672         destreg = decode_rm_seg_register(rh);
6673         DECODE_PRINTF(",");
6674         srcreg = DECODE_RM_WORD_REGISTER(rl);
6675         DECODE_PRINTF("\n");
6676         TRACE_AND_STEP();
6677         *destreg = *srcreg;
6678         break;
6679     }
6680     /*
6681      * Clean up, and reset all the R_xSP pointers to the correct
6682      * locations.  This is about 3x too much overhead (doing all the
6683      * segreg ptrs when only one is needed, but this instruction
6684      * *cannot* be that common, and this isn't too much work anyway.
6685      */
6686     DECODE_CLEAR_SEGOVR();
6687     END_OF_INSTR();
6688 }
6689 
6690 /****************************************************************************
6691 REMARKS:
6692 Handles opcode 0x8f
6693 ****************************************************************************/
x86emuOp_pop_RM(u8 X86EMU_UNUSED (op1))6694 void x86emuOp_pop_RM(u8 X86EMU_UNUSED(op1))
6695 {
6696     int mod, rl, rh;
6697     uint destoffset;
6698 
6699     START_OF_INSTR();
6700     DECODE_PRINTF("POP\t");
6701     FETCH_DECODE_MODRM(mod, rh, rl);
6702     if (rh != 0) {
6703         DECODE_PRINTF("ILLEGAL DECODE OF OPCODE 8F\n");
6704         HALT_SYS();
6705     }
6706     switch (mod) {
6707     case 0:
6708         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6709             u32 destval;
6710 
6711             destoffset = decode_rm00_address(rl);
6712             DECODE_PRINTF("\n");
6713             TRACE_AND_STEP();
6714             destval = pop_long();
6715             store_data_long(destoffset, destval);
6716         } else {
6717             u16 destval;
6718 
6719             destoffset = decode_rm00_address(rl);
6720             DECODE_PRINTF("\n");
6721             TRACE_AND_STEP();
6722             destval = pop_word();
6723             store_data_word(destoffset, destval);
6724         }
6725         break;
6726     case 1:
6727         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6728             u32 destval;
6729 
6730             destoffset = decode_rm01_address(rl);
6731             DECODE_PRINTF("\n");
6732             TRACE_AND_STEP();
6733             destval = pop_long();
6734             store_data_long(destoffset, destval);
6735         } else {
6736             u16 destval;
6737 
6738             destoffset = decode_rm01_address(rl);
6739             DECODE_PRINTF("\n");
6740             TRACE_AND_STEP();
6741             destval = pop_word();
6742             store_data_word(destoffset, destval);
6743         }
6744         break;
6745     case 2:
6746         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6747             u32 destval;
6748 
6749             destoffset = decode_rm10_address(rl);
6750             DECODE_PRINTF("\n");
6751             TRACE_AND_STEP();
6752             destval = pop_long();
6753             store_data_long(destoffset, destval);
6754         } else {
6755             u16 destval;
6756 
6757             destoffset = decode_rm10_address(rl);
6758             DECODE_PRINTF("\n");
6759             TRACE_AND_STEP();
6760             destval = pop_word();
6761             store_data_word(destoffset, destval);
6762         }
6763         break;
6764     case 3:                     /* register to register */
6765         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6766             u32 *destreg;
6767 
6768             destreg = DECODE_RM_LONG_REGISTER(rl);
6769             DECODE_PRINTF("\n");
6770             TRACE_AND_STEP();
6771             *destreg = pop_long();
6772         } else {
6773             u16 *destreg;
6774 
6775             destreg = DECODE_RM_WORD_REGISTER(rl);
6776             DECODE_PRINTF("\n");
6777             TRACE_AND_STEP();
6778             *destreg = pop_word();
6779         }
6780         break;
6781     }
6782     DECODE_CLEAR_SEGOVR();
6783     END_OF_INSTR();
6784 }
6785 
6786 /****************************************************************************
6787 REMARKS:
6788 Handles opcode 0x90
6789 ****************************************************************************/
x86emuOp_nop(u8 X86EMU_UNUSED (op1))6790 void x86emuOp_nop(u8 X86EMU_UNUSED(op1))
6791 {
6792     START_OF_INSTR();
6793     DECODE_PRINTF("NOP\n");
6794     TRACE_AND_STEP();
6795     DECODE_CLEAR_SEGOVR();
6796     END_OF_INSTR();
6797 }
6798 
6799 /****************************************************************************
6800 REMARKS:
6801 Handles opcode 0x91
6802 ****************************************************************************/
x86emuOp_xchg_word_AX_CX(u8 X86EMU_UNUSED (op1))6803 void x86emuOp_xchg_word_AX_CX(u8 X86EMU_UNUSED(op1))
6804 {
6805     u32 tmp;
6806 
6807     START_OF_INSTR();
6808     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6809         DECODE_PRINTF("XCHG\tEAX,ECX\n");
6810     } else {
6811         DECODE_PRINTF("XCHG\tAX,CX\n");
6812     }
6813     TRACE_AND_STEP();
6814     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6815         tmp = M.x86.R_EAX;
6816         M.x86.R_EAX = M.x86.R_ECX;
6817         M.x86.R_ECX = tmp;
6818     } else {
6819         tmp = M.x86.R_AX;
6820         M.x86.R_AX = M.x86.R_CX;
6821         M.x86.R_CX = (u16)tmp;
6822     }
6823     DECODE_CLEAR_SEGOVR();
6824     END_OF_INSTR();
6825 }
6826 
6827 /****************************************************************************
6828 REMARKS:
6829 Handles opcode 0x92
6830 ****************************************************************************/
x86emuOp_xchg_word_AX_DX(u8 X86EMU_UNUSED (op1))6831 void x86emuOp_xchg_word_AX_DX(u8 X86EMU_UNUSED(op1))
6832 {
6833     u32 tmp;
6834 
6835     START_OF_INSTR();
6836     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6837         DECODE_PRINTF("XCHG\tEAX,EDX\n");
6838     } else {
6839         DECODE_PRINTF("XCHG\tAX,DX\n");
6840     }
6841     TRACE_AND_STEP();
6842     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6843         tmp = M.x86.R_EAX;
6844         M.x86.R_EAX = M.x86.R_EDX;
6845         M.x86.R_EDX = tmp;
6846     } else {
6847         tmp = M.x86.R_AX;
6848         M.x86.R_AX = M.x86.R_DX;
6849         M.x86.R_DX = (u16)tmp;
6850     }
6851     DECODE_CLEAR_SEGOVR();
6852     END_OF_INSTR();
6853 }
6854 
6855 /****************************************************************************
6856 REMARKS:
6857 Handles opcode 0x93
6858 ****************************************************************************/
x86emuOp_xchg_word_AX_BX(u8 X86EMU_UNUSED (op1))6859 void x86emuOp_xchg_word_AX_BX(u8 X86EMU_UNUSED(op1))
6860 {
6861     u32 tmp;
6862 
6863     START_OF_INSTR();
6864     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6865         DECODE_PRINTF("XCHG\tEAX,EBX\n");
6866     } else {
6867         DECODE_PRINTF("XCHG\tAX,BX\n");
6868     }
6869     TRACE_AND_STEP();
6870     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6871         tmp = M.x86.R_EAX;
6872         M.x86.R_EAX = M.x86.R_EBX;
6873         M.x86.R_EBX = tmp;
6874     } else {
6875         tmp = M.x86.R_AX;
6876         M.x86.R_AX = M.x86.R_BX;
6877         M.x86.R_BX = (u16)tmp;
6878     }
6879     DECODE_CLEAR_SEGOVR();
6880     END_OF_INSTR();
6881 }
6882 
6883 /****************************************************************************
6884 REMARKS:
6885 Handles opcode 0x94
6886 ****************************************************************************/
x86emuOp_xchg_word_AX_SP(u8 X86EMU_UNUSED (op1))6887 void x86emuOp_xchg_word_AX_SP(u8 X86EMU_UNUSED(op1))
6888 {
6889     u32 tmp;
6890 
6891     START_OF_INSTR();
6892     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6893         DECODE_PRINTF("XCHG\tEAX,ESP\n");
6894     } else {
6895         DECODE_PRINTF("XCHG\tAX,SP\n");
6896     }
6897     TRACE_AND_STEP();
6898     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6899         tmp = M.x86.R_EAX;
6900         M.x86.R_EAX = M.x86.R_ESP;
6901         M.x86.R_ESP = tmp;
6902     } else {
6903         tmp = M.x86.R_AX;
6904         M.x86.R_AX = M.x86.R_SP;
6905         M.x86.R_SP = (u16)tmp;
6906     }
6907     DECODE_CLEAR_SEGOVR();
6908     END_OF_INSTR();
6909 }
6910 
6911 /****************************************************************************
6912 REMARKS:
6913 Handles opcode 0x95
6914 ****************************************************************************/
x86emuOp_xchg_word_AX_BP(u8 X86EMU_UNUSED (op1))6915 void x86emuOp_xchg_word_AX_BP(u8 X86EMU_UNUSED(op1))
6916 {
6917     u32 tmp;
6918 
6919     START_OF_INSTR();
6920     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6921         DECODE_PRINTF("XCHG\tEAX,EBP\n");
6922     } else {
6923         DECODE_PRINTF("XCHG\tAX,BP\n");
6924     }
6925     TRACE_AND_STEP();
6926     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6927         tmp = M.x86.R_EAX;
6928         M.x86.R_EAX = M.x86.R_EBP;
6929         M.x86.R_EBP = tmp;
6930     } else {
6931         tmp = M.x86.R_AX;
6932         M.x86.R_AX = M.x86.R_BP;
6933         M.x86.R_BP = (u16)tmp;
6934     }
6935     DECODE_CLEAR_SEGOVR();
6936     END_OF_INSTR();
6937 }
6938 
6939 /****************************************************************************
6940 REMARKS:
6941 Handles opcode 0x96
6942 ****************************************************************************/
x86emuOp_xchg_word_AX_SI(u8 X86EMU_UNUSED (op1))6943 void x86emuOp_xchg_word_AX_SI(u8 X86EMU_UNUSED(op1))
6944 {
6945     u32 tmp;
6946 
6947     START_OF_INSTR();
6948     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6949         DECODE_PRINTF("XCHG\tEAX,ESI\n");
6950     } else {
6951         DECODE_PRINTF("XCHG\tAX,SI\n");
6952     }
6953     TRACE_AND_STEP();
6954     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6955         tmp = M.x86.R_EAX;
6956         M.x86.R_EAX = M.x86.R_ESI;
6957         M.x86.R_ESI = tmp;
6958     } else {
6959         tmp = M.x86.R_AX;
6960         M.x86.R_AX = M.x86.R_SI;
6961         M.x86.R_SI = (u16)tmp;
6962     }
6963     DECODE_CLEAR_SEGOVR();
6964     END_OF_INSTR();
6965 }
6966 
6967 /****************************************************************************
6968 REMARKS:
6969 Handles opcode 0x97
6970 ****************************************************************************/
x86emuOp_xchg_word_AX_DI(u8 X86EMU_UNUSED (op1))6971 void x86emuOp_xchg_word_AX_DI(u8 X86EMU_UNUSED(op1))
6972 {
6973     u32 tmp;
6974 
6975     START_OF_INSTR();
6976     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6977         DECODE_PRINTF("XCHG\tEAX,EDI\n");
6978     } else {
6979         DECODE_PRINTF("XCHG\tAX,DI\n");
6980     }
6981     TRACE_AND_STEP();
6982     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
6983         tmp = M.x86.R_EAX;
6984         M.x86.R_EAX = M.x86.R_EDI;
6985         M.x86.R_EDI = tmp;
6986     } else {
6987         tmp = M.x86.R_AX;
6988         M.x86.R_AX = M.x86.R_DI;
6989         M.x86.R_DI = (u16)tmp;
6990     }
6991     DECODE_CLEAR_SEGOVR();
6992     END_OF_INSTR();
6993 }
6994 
6995 /****************************************************************************
6996 REMARKS:
6997 Handles opcode 0x98
6998 ****************************************************************************/
x86emuOp_cbw(u8 X86EMU_UNUSED (op1))6999 void x86emuOp_cbw(u8 X86EMU_UNUSED(op1))
7000 {
7001     START_OF_INSTR();
7002     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7003         DECODE_PRINTF("CWDE\n");
7004     } else {
7005         DECODE_PRINTF("CBW\n");
7006     }
7007     TRACE_AND_STEP();
7008     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7009         if (M.x86.R_AX & 0x8000) {
7010             M.x86.R_EAX |= 0xffff0000;
7011         } else {
7012             M.x86.R_EAX &= 0x0000ffff;
7013         }
7014     } else {
7015         if (M.x86.R_AL & 0x80) {
7016             M.x86.R_AH = 0xff;
7017         } else {
7018             M.x86.R_AH = 0x0;
7019         }
7020     }
7021     DECODE_CLEAR_SEGOVR();
7022     END_OF_INSTR();
7023 }
7024 
7025 /****************************************************************************
7026 REMARKS:
7027 Handles opcode 0x99
7028 ****************************************************************************/
x86emuOp_cwd(u8 X86EMU_UNUSED (op1))7029 void x86emuOp_cwd(u8 X86EMU_UNUSED(op1))
7030 {
7031     START_OF_INSTR();
7032     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7033         DECODE_PRINTF("CDQ\n");
7034     } else {
7035         DECODE_PRINTF("CWD\n");
7036     }
7037     DECODE_PRINTF("CWD\n");
7038     TRACE_AND_STEP();
7039     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7040         if (M.x86.R_EAX & 0x80000000) {
7041             M.x86.R_EDX = 0xffffffff;
7042         } else {
7043             M.x86.R_EDX = 0x0;
7044         }
7045     } else {
7046         if (M.x86.R_AX & 0x8000) {
7047             M.x86.R_DX = 0xffff;
7048         } else {
7049             M.x86.R_DX = 0x0;
7050         }
7051     }
7052     DECODE_CLEAR_SEGOVR();
7053     END_OF_INSTR();
7054 }
7055 
7056 /****************************************************************************
7057 REMARKS:
7058 Handles opcode 0x9a
7059 ****************************************************************************/
x86emuOp_call_far_IMM(u8 X86EMU_UNUSED (op1))7060 void x86emuOp_call_far_IMM(u8 X86EMU_UNUSED(op1))
7061 {
7062     u16 farseg, faroff;
7063 
7064     START_OF_INSTR();
7065     DECODE_PRINTF("CALL\t");
7066     faroff = fetch_word_imm();
7067     farseg = fetch_word_imm();
7068     DECODE_PRINTF2("%04x:", farseg);
7069     DECODE_PRINTF2("%04x\n", faroff);
7070     CALL_TRACE(M.x86.saved_cs, M.x86.saved_ip, farseg, faroff, "FAR ");
7071 
7072     /* XXX
7073      *
7074      * Hooked interrupt vectors calling into our "BIOS" will cause
7075      * problems unless all intersegment stuff is checked for BIOS
7076      * access.  Check needed here.  For moment, let it alone.
7077      */
7078     TRACE_AND_STEP();
7079     push_word(M.x86.R_CS);
7080     M.x86.R_CS = farseg;
7081     push_word(M.x86.R_IP);
7082     M.x86.R_IP = faroff;
7083     DECODE_CLEAR_SEGOVR();
7084     END_OF_INSTR();
7085 }
7086 
7087 /****************************************************************************
7088 REMARKS:
7089 Handles opcode 0x9b
7090 ****************************************************************************/
x86emuOp_wait(u8 X86EMU_UNUSED (op1))7091 void x86emuOp_wait(u8 X86EMU_UNUSED(op1))
7092 {
7093     START_OF_INSTR();
7094     DECODE_PRINTF("WAIT");
7095     TRACE_AND_STEP();
7096     /* NADA.  */
7097     DECODE_CLEAR_SEGOVR();
7098     END_OF_INSTR();
7099 }
7100 
7101 /****************************************************************************
7102 REMARKS:
7103 Handles opcode 0x9c
7104 ****************************************************************************/
x86emuOp_pushf_word(u8 X86EMU_UNUSED (op1))7105 void x86emuOp_pushf_word(u8 X86EMU_UNUSED(op1))
7106 {
7107     u32 flags;
7108 
7109     START_OF_INSTR();
7110     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7111         DECODE_PRINTF("PUSHFD\n");
7112     } else {
7113         DECODE_PRINTF("PUSHF\n");
7114     }
7115     TRACE_AND_STEP();
7116 
7117     /* clear out *all* bits not representing flags, and turn on real bits */
7118     flags = (M.x86.R_EFLG & F_MSK) | F_ALWAYS_ON;
7119     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7120         push_long(flags);
7121     } else {
7122         push_word((u16)flags);
7123     }
7124     DECODE_CLEAR_SEGOVR();
7125     END_OF_INSTR();
7126 }
7127 
7128 /****************************************************************************
7129 REMARKS:
7130 Handles opcode 0x9d
7131 ****************************************************************************/
x86emuOp_popf_word(u8 X86EMU_UNUSED (op1))7132 void x86emuOp_popf_word(u8 X86EMU_UNUSED(op1))
7133 {
7134     START_OF_INSTR();
7135     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7136         DECODE_PRINTF("POPFD\n");
7137     } else {
7138         DECODE_PRINTF("POPF\n");
7139     }
7140     TRACE_AND_STEP();
7141     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7142         M.x86.R_EFLG = pop_long();
7143     } else {
7144         M.x86.R_FLG = pop_word();
7145     }
7146     DECODE_CLEAR_SEGOVR();
7147     END_OF_INSTR();
7148 }
7149 
7150 /****************************************************************************
7151 REMARKS:
7152 Handles opcode 0x9e
7153 ****************************************************************************/
x86emuOp_sahf(u8 X86EMU_UNUSED (op1))7154 void x86emuOp_sahf(u8 X86EMU_UNUSED(op1))
7155 {
7156     START_OF_INSTR();
7157     DECODE_PRINTF("SAHF\n");
7158     TRACE_AND_STEP();
7159     /* clear the lower bits of the flag register */
7160     M.x86.R_FLG &= 0xffffff00;
7161     /* or in the AH register into the flags register */
7162     M.x86.R_FLG |= M.x86.R_AH;
7163     DECODE_CLEAR_SEGOVR();
7164     END_OF_INSTR();
7165 }
7166 
7167 /****************************************************************************
7168 REMARKS:
7169 Handles opcode 0x9f
7170 ****************************************************************************/
x86emuOp_lahf(u8 X86EMU_UNUSED (op1))7171 void x86emuOp_lahf(u8 X86EMU_UNUSED(op1))
7172 {
7173     START_OF_INSTR();
7174     DECODE_PRINTF("LAHF\n");
7175     TRACE_AND_STEP();
7176     M.x86.R_AH = (u8)(M.x86.R_FLG & 0xff);
7177     /*undocumented TC++ behavior??? Nope.  It's documented, but
7178        you have too look real hard to notice it. */
7179     M.x86.R_AH |= 0x2;
7180     DECODE_CLEAR_SEGOVR();
7181     END_OF_INSTR();
7182 }
7183 
7184 /****************************************************************************
7185 REMARKS:
7186 Handles opcode 0xa0
7187 ****************************************************************************/
x86emuOp_mov_AL_M_IMM(u8 X86EMU_UNUSED (op1))7188 void x86emuOp_mov_AL_M_IMM(u8 X86EMU_UNUSED(op1))
7189 {
7190     u16 offset;
7191 
7192     START_OF_INSTR();
7193     DECODE_PRINTF("MOV\tAL,");
7194     offset = fetch_word_imm();
7195     DECODE_PRINTF2("[%04x]\n", offset);
7196     TRACE_AND_STEP();
7197     M.x86.R_AL = fetch_data_byte(offset);
7198     DECODE_CLEAR_SEGOVR();
7199     END_OF_INSTR();
7200 }
7201 
7202 /****************************************************************************
7203 REMARKS:
7204 Handles opcode 0xa1
7205 ****************************************************************************/
x86emuOp_mov_AX_M_IMM(u8 X86EMU_UNUSED (op1))7206 void x86emuOp_mov_AX_M_IMM(u8 X86EMU_UNUSED(op1))
7207 {
7208     u16 offset;
7209 
7210     START_OF_INSTR();
7211     offset = fetch_word_imm();
7212     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7213         DECODE_PRINTF2("MOV\tEAX,[%04x]\n", offset);
7214     } else {
7215         DECODE_PRINTF2("MOV\tAX,[%04x]\n", offset);
7216     }
7217     TRACE_AND_STEP();
7218     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7219         M.x86.R_EAX = fetch_data_long(offset);
7220     } else {
7221         M.x86.R_AX = fetch_data_word(offset);
7222     }
7223     DECODE_CLEAR_SEGOVR();
7224     END_OF_INSTR();
7225 }
7226 
7227 /****************************************************************************
7228 REMARKS:
7229 Handles opcode 0xa2
7230 ****************************************************************************/
x86emuOp_mov_M_AL_IMM(u8 X86EMU_UNUSED (op1))7231 void x86emuOp_mov_M_AL_IMM(u8 X86EMU_UNUSED(op1))
7232 {
7233     u16 offset;
7234 
7235     START_OF_INSTR();
7236     DECODE_PRINTF("MOV\t");
7237     offset = fetch_word_imm();
7238     DECODE_PRINTF2("[%04x],AL\n", offset);
7239     TRACE_AND_STEP();
7240     store_data_byte(offset, M.x86.R_AL);
7241     DECODE_CLEAR_SEGOVR();
7242     END_OF_INSTR();
7243 }
7244 
7245 /****************************************************************************
7246 REMARKS:
7247 Handles opcode 0xa3
7248 ****************************************************************************/
x86emuOp_mov_M_AX_IMM(u8 X86EMU_UNUSED (op1))7249 void x86emuOp_mov_M_AX_IMM(u8 X86EMU_UNUSED(op1))
7250 {
7251     u16 offset;
7252 
7253     START_OF_INSTR();
7254     offset = fetch_word_imm();
7255     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7256         DECODE_PRINTF2("MOV\t[%04x],EAX\n", offset);
7257     } else {
7258         DECODE_PRINTF2("MOV\t[%04x],AX\n", offset);
7259     }
7260     TRACE_AND_STEP();
7261     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7262         store_data_long(offset, M.x86.R_EAX);
7263     } else {
7264         store_data_word(offset, M.x86.R_AX);
7265     }
7266     DECODE_CLEAR_SEGOVR();
7267     END_OF_INSTR();
7268 }
7269 
7270 /****************************************************************************
7271 REMARKS:
7272 Handles opcode 0xa4
7273 ****************************************************************************/
x86emuOp_movs_byte(u8 X86EMU_UNUSED (op1))7274 void x86emuOp_movs_byte(u8 X86EMU_UNUSED(op1))
7275 {
7276     u8  val;
7277     u32 count;
7278     int inc;
7279 
7280     START_OF_INSTR();
7281     DECODE_PRINTF("MOVS\tBYTE\n");
7282     if (ACCESS_FLAG(F_DF))   /* down */
7283         inc = -1;
7284     else
7285         inc = 1;
7286     TRACE_AND_STEP();
7287     count = 1;
7288     if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
7289         /* dont care whether REPE or REPNE */
7290         /* move them until CX is ZERO. */
7291         count = M.x86.R_CX;
7292         M.x86.R_CX = 0;
7293         M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
7294     }
7295     while (count--) {
7296         val = fetch_data_byte(M.x86.R_SI);
7297         store_data_byte_abs(M.x86.R_ES, M.x86.R_DI, val);
7298         M.x86.R_SI += inc;
7299         M.x86.R_DI += inc;
7300     }
7301     DECODE_CLEAR_SEGOVR();
7302     END_OF_INSTR();
7303 }
7304 
7305 /****************************************************************************
7306 REMARKS:
7307 Handles opcode 0xa5
7308 ****************************************************************************/
x86emuOp_movs_word(u8 X86EMU_UNUSED (op1))7309 void x86emuOp_movs_word(u8 X86EMU_UNUSED(op1))
7310 {
7311     u32 val;
7312     int inc;
7313     u32 count;
7314 
7315     START_OF_INSTR();
7316     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7317         DECODE_PRINTF("MOVS\tDWORD\n");
7318         if (ACCESS_FLAG(F_DF))      /* down */
7319             inc = -4;
7320         else
7321             inc = 4;
7322     } else {
7323         DECODE_PRINTF("MOVS\tWORD\n");
7324         if (ACCESS_FLAG(F_DF))      /* down */
7325             inc = -2;
7326         else
7327             inc = 2;
7328     }
7329     TRACE_AND_STEP();
7330     count = 1;
7331     if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
7332         /* dont care whether REPE or REPNE */
7333         /* move them until CX is ZERO. */
7334         count = M.x86.R_CX;
7335         M.x86.R_CX = 0;
7336         M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
7337     }
7338     while (count--) {
7339         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7340             val = fetch_data_long(M.x86.R_SI);
7341             store_data_long_abs(M.x86.R_ES, M.x86.R_DI, val);
7342         } else {
7343             val = fetch_data_word(M.x86.R_SI);
7344             store_data_word_abs(M.x86.R_ES, M.x86.R_DI, (u16)val);
7345         }
7346         M.x86.R_SI += inc;
7347         M.x86.R_DI += inc;
7348     }
7349     DECODE_CLEAR_SEGOVR();
7350     END_OF_INSTR();
7351 }
7352 
7353 /****************************************************************************
7354 REMARKS:
7355 Handles opcode 0xa6
7356 ****************************************************************************/
x86emuOp_cmps_byte(u8 X86EMU_UNUSED (op1))7357 void x86emuOp_cmps_byte(u8 X86EMU_UNUSED(op1))
7358 {
7359     s8 val1, val2;
7360     int inc;
7361 
7362     START_OF_INSTR();
7363     DECODE_PRINTF("CMPS\tBYTE\n");
7364     TRACE_AND_STEP();
7365     if (ACCESS_FLAG(F_DF))   /* down */
7366         inc = -1;
7367     else
7368         inc = 1;
7369 
7370     if (M.x86.mode & SYSMODE_PREFIX_REPE) {
7371         /* REPE  */
7372         /* move them until CX is ZERO. */
7373         while (M.x86.R_CX != 0) {
7374             val1 = fetch_data_byte(M.x86.R_SI);
7375             val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
7376                      cmp_byte(val1, val2);
7377             M.x86.R_CX -= 1;
7378             M.x86.R_SI += inc;
7379             M.x86.R_DI += inc;
7380             if (ACCESS_FLAG(F_ZF) == 0)
7381                 break;
7382         }
7383         M.x86.mode &= ~SYSMODE_PREFIX_REPE;
7384     } else if (M.x86.mode & SYSMODE_PREFIX_REPNE) {
7385         /* REPNE  */
7386         /* move them until CX is ZERO. */
7387         while (M.x86.R_CX != 0) {
7388             val1 = fetch_data_byte(M.x86.R_SI);
7389             val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
7390             cmp_byte(val1, val2);
7391             M.x86.R_CX -= 1;
7392             M.x86.R_SI += inc;
7393             M.x86.R_DI += inc;
7394             if (ACCESS_FLAG(F_ZF))
7395                 break;          /* zero flag set means equal */
7396         }
7397         M.x86.mode &= ~SYSMODE_PREFIX_REPNE;
7398     } else {
7399         val1 = fetch_data_byte(M.x86.R_SI);
7400         val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
7401         cmp_byte(val1, val2);
7402         M.x86.R_SI += inc;
7403         M.x86.R_DI += inc;
7404     }
7405     DECODE_CLEAR_SEGOVR();
7406     END_OF_INSTR();
7407 }
7408 
7409 /****************************************************************************
7410 REMARKS:
7411 Handles opcode 0xa7
7412 ****************************************************************************/
x86emuOp_cmps_word(u8 X86EMU_UNUSED (op1))7413 void x86emuOp_cmps_word(u8 X86EMU_UNUSED(op1))
7414 {
7415     u32 val1,val2;
7416     int inc;
7417 
7418     START_OF_INSTR();
7419     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7420         DECODE_PRINTF("CMPS\tDWORD\n");
7421         if (ACCESS_FLAG(F_DF))   /* down */
7422             inc = -4;
7423         else
7424             inc = 4;
7425     } else {
7426         DECODE_PRINTF("CMPS\tWORD\n");
7427         if (ACCESS_FLAG(F_DF))   /* down */
7428             inc = -2;
7429         else
7430             inc = 2;
7431     }
7432     TRACE_AND_STEP();
7433     if (M.x86.mode & SYSMODE_PREFIX_REPE) {
7434         /* REPE  */
7435         /* move them until CX is ZERO. */
7436         while (M.x86.R_CX != 0) {
7437             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7438                 val1 = fetch_data_long(M.x86.R_SI);
7439                 val2 = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
7440                 cmp_long(val1, val2);
7441             } else {
7442                 val1 = fetch_data_word(M.x86.R_SI);
7443                 val2 = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
7444                 cmp_word((u16)val1, (u16)val2);
7445             }
7446             M.x86.R_CX -= 1;
7447             M.x86.R_SI += inc;
7448             M.x86.R_DI += inc;
7449             if (ACCESS_FLAG(F_ZF) == 0)
7450                 break;
7451         }
7452         M.x86.mode &= ~SYSMODE_PREFIX_REPE;
7453     } else if (M.x86.mode & SYSMODE_PREFIX_REPNE) {
7454         /* REPNE  */
7455         /* move them until CX is ZERO. */
7456         while (M.x86.R_CX != 0) {
7457             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7458                 val1 = fetch_data_long(M.x86.R_SI);
7459                 val2 = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
7460                 cmp_long(val1, val2);
7461             } else {
7462                 val1 = fetch_data_word(M.x86.R_SI);
7463                 val2 = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
7464                 cmp_word((u16)val1, (u16)val2);
7465             }
7466             M.x86.R_CX -= 1;
7467             M.x86.R_SI += inc;
7468             M.x86.R_DI += inc;
7469             if (ACCESS_FLAG(F_ZF))
7470                 break;          /* zero flag set means equal */
7471         }
7472         M.x86.mode &= ~SYSMODE_PREFIX_REPNE;
7473     } else {
7474         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7475             val1 = fetch_data_long(M.x86.R_SI);
7476             val2 = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
7477             cmp_long(val1, val2);
7478         } else {
7479             val1 = fetch_data_word(M.x86.R_SI);
7480             val2 = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
7481             cmp_word((u16)val1, (u16)val2);
7482         }
7483         M.x86.R_SI += inc;
7484         M.x86.R_DI += inc;
7485     }
7486     DECODE_CLEAR_SEGOVR();
7487     END_OF_INSTR();
7488 }
7489 
7490 /****************************************************************************
7491 REMARKS:
7492 Handles opcode 0xa8
7493 ****************************************************************************/
x86emuOp_test_AL_IMM(u8 X86EMU_UNUSED (op1))7494 void x86emuOp_test_AL_IMM(u8 X86EMU_UNUSED(op1))
7495 {
7496     int imm;
7497 
7498     START_OF_INSTR();
7499     DECODE_PRINTF("TEST\tAL,");
7500     imm = fetch_byte_imm();
7501     DECODE_PRINTF2("%04x\n", imm);
7502     TRACE_AND_STEP();
7503     test_byte(M.x86.R_AL, (u8)imm);
7504     DECODE_CLEAR_SEGOVR();
7505     END_OF_INSTR();
7506 }
7507 
7508 /****************************************************************************
7509 REMARKS:
7510 Handles opcode 0xa9
7511 ****************************************************************************/
x86emuOp_test_AX_IMM(u8 X86EMU_UNUSED (op1))7512 void x86emuOp_test_AX_IMM(u8 X86EMU_UNUSED(op1))
7513 {
7514     u32 srcval;
7515 
7516     START_OF_INSTR();
7517     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7518         DECODE_PRINTF("TEST\tEAX,");
7519         srcval = fetch_long_imm();
7520     } else {
7521         DECODE_PRINTF("TEST\tAX,");
7522         srcval = fetch_word_imm();
7523     }
7524     DECODE_PRINTF2("%x\n", srcval);
7525     TRACE_AND_STEP();
7526     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7527         test_long(M.x86.R_EAX, srcval);
7528     } else {
7529         test_word(M.x86.R_AX, (u16)srcval);
7530     }
7531     DECODE_CLEAR_SEGOVR();
7532     END_OF_INSTR();
7533 }
7534 
7535 /****************************************************************************
7536 REMARKS:
7537 Handles opcode 0xaa
7538 ****************************************************************************/
x86emuOp_stos_byte(u8 X86EMU_UNUSED (op1))7539 void x86emuOp_stos_byte(u8 X86EMU_UNUSED(op1))
7540 {
7541     int inc;
7542 
7543     START_OF_INSTR();
7544     DECODE_PRINTF("STOS\tBYTE\n");
7545     if (ACCESS_FLAG(F_DF))   /* down */
7546         inc = -1;
7547     else
7548         inc = 1;
7549     TRACE_AND_STEP();
7550     if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
7551         /* dont care whether REPE or REPNE */
7552         /* move them until CX is ZERO. */
7553         while (M.x86.R_CX != 0) {
7554             store_data_byte_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_AL);
7555             M.x86.R_CX -= 1;
7556             M.x86.R_DI += inc;
7557         }
7558         M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
7559     } else {
7560         store_data_byte_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_AL);
7561         M.x86.R_DI += inc;
7562     }
7563     DECODE_CLEAR_SEGOVR();
7564     END_OF_INSTR();
7565 }
7566 
7567 /****************************************************************************
7568 REMARKS:
7569 Handles opcode 0xab
7570 ****************************************************************************/
x86emuOp_stos_word(u8 X86EMU_UNUSED (op1))7571 void x86emuOp_stos_word(u8 X86EMU_UNUSED(op1))
7572 {
7573     int inc;
7574     u32 count;
7575 
7576     START_OF_INSTR();
7577     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7578         DECODE_PRINTF("STOS\tDWORD\n");
7579         if (ACCESS_FLAG(F_DF))   /* down */
7580             inc = -4;
7581         else
7582             inc = 4;
7583     } else {
7584         DECODE_PRINTF("STOS\tWORD\n");
7585         if (ACCESS_FLAG(F_DF))   /* down */
7586             inc = -2;
7587         else
7588             inc = 2;
7589     }
7590     TRACE_AND_STEP();
7591     count = 1;
7592     if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
7593         /* dont care whether REPE or REPNE */
7594         /* move them until CX is ZERO. */
7595         count = M.x86.R_CX;
7596         M.x86.R_CX = 0;
7597         M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
7598     }
7599     while (count--) {
7600         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7601             store_data_long_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_EAX);
7602         } else {
7603             store_data_word_abs(M.x86.R_ES, M.x86.R_DI, M.x86.R_AX);
7604         }
7605         M.x86.R_DI += inc;
7606     }
7607     DECODE_CLEAR_SEGOVR();
7608     END_OF_INSTR();
7609 }
7610 
7611 /****************************************************************************
7612 REMARKS:
7613 Handles opcode 0xac
7614 ****************************************************************************/
x86emuOp_lods_byte(u8 X86EMU_UNUSED (op1))7615 void x86emuOp_lods_byte(u8 X86EMU_UNUSED(op1))
7616 {
7617     int inc;
7618 
7619     START_OF_INSTR();
7620     DECODE_PRINTF("LODS\tBYTE\n");
7621     TRACE_AND_STEP();
7622     if (ACCESS_FLAG(F_DF))   /* down */
7623         inc = -1;
7624     else
7625         inc = 1;
7626     if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
7627         /* dont care whether REPE or REPNE */
7628         /* move them until CX is ZERO. */
7629         while (M.x86.R_CX != 0) {
7630             M.x86.R_AL = fetch_data_byte(M.x86.R_SI);
7631             M.x86.R_CX -= 1;
7632             M.x86.R_SI += inc;
7633         }
7634         M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
7635     } else {
7636         M.x86.R_AL = fetch_data_byte(M.x86.R_SI);
7637         M.x86.R_SI += inc;
7638     }
7639     DECODE_CLEAR_SEGOVR();
7640     END_OF_INSTR();
7641 }
7642 
7643 /****************************************************************************
7644 REMARKS:
7645 Handles opcode 0xad
7646 ****************************************************************************/
x86emuOp_lods_word(u8 X86EMU_UNUSED (op1))7647 void x86emuOp_lods_word(u8 X86EMU_UNUSED(op1))
7648 {
7649     int inc;
7650     u32 count;
7651 
7652     START_OF_INSTR();
7653     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7654         DECODE_PRINTF("LODS\tDWORD\n");
7655         if (ACCESS_FLAG(F_DF))   /* down */
7656             inc = -4;
7657         else
7658             inc = 4;
7659     } else {
7660         DECODE_PRINTF("LODS\tWORD\n");
7661         if (ACCESS_FLAG(F_DF))   /* down */
7662             inc = -2;
7663         else
7664             inc = 2;
7665     }
7666     TRACE_AND_STEP();
7667     count = 1;
7668     if (M.x86.mode & (SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE)) {
7669         /* dont care whether REPE or REPNE */
7670         /* move them until CX is ZERO. */
7671         count = M.x86.R_CX;
7672         M.x86.R_CX = 0;
7673         M.x86.mode &= ~(SYSMODE_PREFIX_REPE | SYSMODE_PREFIX_REPNE);
7674     }
7675     while (count--) {
7676         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7677             M.x86.R_EAX = fetch_data_long(M.x86.R_SI);
7678         } else {
7679             M.x86.R_AX = fetch_data_word(M.x86.R_SI);
7680         }
7681         M.x86.R_SI += inc;
7682     }
7683     DECODE_CLEAR_SEGOVR();
7684     END_OF_INSTR();
7685 }
7686 
7687 /****************************************************************************
7688 REMARKS:
7689 Handles opcode 0xae
7690 ****************************************************************************/
x86emuOp_scas_byte(u8 X86EMU_UNUSED (op1))7691 void x86emuOp_scas_byte(u8 X86EMU_UNUSED(op1))
7692 {
7693     s8 val2;
7694     int inc;
7695 
7696     START_OF_INSTR();
7697     DECODE_PRINTF("SCAS\tBYTE\n");
7698     TRACE_AND_STEP();
7699     if (ACCESS_FLAG(F_DF))   /* down */
7700         inc = -1;
7701     else
7702         inc = 1;
7703     if (M.x86.mode & SYSMODE_PREFIX_REPE) {
7704         /* REPE  */
7705         /* move them until CX is ZERO. */
7706         while (M.x86.R_CX != 0) {
7707             val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
7708             cmp_byte(M.x86.R_AL, val2);
7709             M.x86.R_CX -= 1;
7710             M.x86.R_DI += inc;
7711             if (ACCESS_FLAG(F_ZF) == 0)
7712                 break;
7713         }
7714         M.x86.mode &= ~SYSMODE_PREFIX_REPE;
7715     } else if (M.x86.mode & SYSMODE_PREFIX_REPNE) {
7716         /* REPNE  */
7717         /* move them until CX is ZERO. */
7718         while (M.x86.R_CX != 0) {
7719             val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
7720             cmp_byte(M.x86.R_AL, val2);
7721             M.x86.R_CX -= 1;
7722             M.x86.R_DI += inc;
7723             if (ACCESS_FLAG(F_ZF))
7724                 break;          /* zero flag set means equal */
7725         }
7726         M.x86.mode &= ~SYSMODE_PREFIX_REPNE;
7727     } else {
7728         val2 = fetch_data_byte_abs(M.x86.R_ES, M.x86.R_DI);
7729         cmp_byte(M.x86.R_AL, val2);
7730         M.x86.R_DI += inc;
7731     }
7732     DECODE_CLEAR_SEGOVR();
7733     END_OF_INSTR();
7734 }
7735 
7736 /****************************************************************************
7737 REMARKS:
7738 Handles opcode 0xaf
7739 ****************************************************************************/
x86emuOp_scas_word(u8 X86EMU_UNUSED (op1))7740 void x86emuOp_scas_word(u8 X86EMU_UNUSED(op1))
7741 {
7742     int inc;
7743     u32 val;
7744 
7745     START_OF_INSTR();
7746     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7747         DECODE_PRINTF("SCAS\tDWORD\n");
7748         if (ACCESS_FLAG(F_DF))   /* down */
7749             inc = -4;
7750         else
7751             inc = 4;
7752     } else {
7753         DECODE_PRINTF("SCAS\tWORD\n");
7754         if (ACCESS_FLAG(F_DF))   /* down */
7755             inc = -2;
7756         else
7757             inc = 2;
7758     }
7759     TRACE_AND_STEP();
7760     if (M.x86.mode & SYSMODE_PREFIX_REPE) {
7761         /* REPE  */
7762         /* move them until CX is ZERO. */
7763         while (M.x86.R_CX != 0) {
7764             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7765                 val = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
7766                 cmp_long(M.x86.R_EAX, val);
7767             } else {
7768                 val = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
7769                 cmp_word(M.x86.R_AX, (u16)val);
7770             }
7771             M.x86.R_CX -= 1;
7772             M.x86.R_DI += inc;
7773             if (ACCESS_FLAG(F_ZF) == 0)
7774                 break;
7775         }
7776         M.x86.mode &= ~SYSMODE_PREFIX_REPE;
7777     } else if (M.x86.mode & SYSMODE_PREFIX_REPNE) {
7778         /* REPNE  */
7779         /* move them until CX is ZERO. */
7780         while (M.x86.R_CX != 0) {
7781             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7782                 val = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
7783                 cmp_long(M.x86.R_EAX, val);
7784             } else {
7785                 val = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
7786                 cmp_word(M.x86.R_AX, (u16)val);
7787             }
7788             M.x86.R_CX -= 1;
7789             M.x86.R_DI += inc;
7790             if (ACCESS_FLAG(F_ZF))
7791                 break;          /* zero flag set means equal */
7792         }
7793         M.x86.mode &= ~SYSMODE_PREFIX_REPNE;
7794     } else {
7795         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7796             val = fetch_data_long_abs(M.x86.R_ES, M.x86.R_DI);
7797             cmp_long(M.x86.R_EAX, val);
7798         } else {
7799             val = fetch_data_word_abs(M.x86.R_ES, M.x86.R_DI);
7800             cmp_word(M.x86.R_AX, (u16)val);
7801         }
7802         M.x86.R_DI += inc;
7803     }
7804     DECODE_CLEAR_SEGOVR();
7805     END_OF_INSTR();
7806 }
7807 
7808 /****************************************************************************
7809 REMARKS:
7810 Handles opcode 0xb0
7811 ****************************************************************************/
x86emuOp_mov_byte_AL_IMM(u8 X86EMU_UNUSED (op1))7812 void x86emuOp_mov_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
7813 {
7814     u8 imm;
7815 
7816     START_OF_INSTR();
7817     DECODE_PRINTF("MOV\tAL,");
7818     imm = fetch_byte_imm();
7819     DECODE_PRINTF2("%x\n", imm);
7820     TRACE_AND_STEP();
7821     M.x86.R_AL = imm;
7822     DECODE_CLEAR_SEGOVR();
7823     END_OF_INSTR();
7824 }
7825 
7826 /****************************************************************************
7827 REMARKS:
7828 Handles opcode 0xb1
7829 ****************************************************************************/
x86emuOp_mov_byte_CL_IMM(u8 X86EMU_UNUSED (op1))7830 void x86emuOp_mov_byte_CL_IMM(u8 X86EMU_UNUSED(op1))
7831 {
7832     u8 imm;
7833 
7834     START_OF_INSTR();
7835     DECODE_PRINTF("MOV\tCL,");
7836     imm = fetch_byte_imm();
7837     DECODE_PRINTF2("%x\n", imm);
7838     TRACE_AND_STEP();
7839     M.x86.R_CL = imm;
7840     DECODE_CLEAR_SEGOVR();
7841     END_OF_INSTR();
7842 }
7843 
7844 /****************************************************************************
7845 REMARKS:
7846 Handles opcode 0xb2
7847 ****************************************************************************/
x86emuOp_mov_byte_DL_IMM(u8 X86EMU_UNUSED (op1))7848 void x86emuOp_mov_byte_DL_IMM(u8 X86EMU_UNUSED(op1))
7849 {
7850     u8 imm;
7851 
7852     START_OF_INSTR();
7853     DECODE_PRINTF("MOV\tDL,");
7854     imm = fetch_byte_imm();
7855     DECODE_PRINTF2("%x\n", imm);
7856     TRACE_AND_STEP();
7857     M.x86.R_DL = imm;
7858     DECODE_CLEAR_SEGOVR();
7859     END_OF_INSTR();
7860 }
7861 
7862 /****************************************************************************
7863 REMARKS:
7864 Handles opcode 0xb3
7865 ****************************************************************************/
x86emuOp_mov_byte_BL_IMM(u8 X86EMU_UNUSED (op1))7866 void x86emuOp_mov_byte_BL_IMM(u8 X86EMU_UNUSED(op1))
7867 {
7868     u8 imm;
7869 
7870     START_OF_INSTR();
7871     DECODE_PRINTF("MOV\tBL,");
7872     imm = fetch_byte_imm();
7873     DECODE_PRINTF2("%x\n", imm);
7874     TRACE_AND_STEP();
7875     M.x86.R_BL = imm;
7876     DECODE_CLEAR_SEGOVR();
7877     END_OF_INSTR();
7878 }
7879 
7880 /****************************************************************************
7881 REMARKS:
7882 Handles opcode 0xb4
7883 ****************************************************************************/
x86emuOp_mov_byte_AH_IMM(u8 X86EMU_UNUSED (op1))7884 void x86emuOp_mov_byte_AH_IMM(u8 X86EMU_UNUSED(op1))
7885 {
7886     u8 imm;
7887 
7888     START_OF_INSTR();
7889     DECODE_PRINTF("MOV\tAH,");
7890     imm = fetch_byte_imm();
7891     DECODE_PRINTF2("%x\n", imm);
7892     TRACE_AND_STEP();
7893     M.x86.R_AH = imm;
7894     DECODE_CLEAR_SEGOVR();
7895     END_OF_INSTR();
7896 }
7897 
7898 /****************************************************************************
7899 REMARKS:
7900 Handles opcode 0xb5
7901 ****************************************************************************/
x86emuOp_mov_byte_CH_IMM(u8 X86EMU_UNUSED (op1))7902 void x86emuOp_mov_byte_CH_IMM(u8 X86EMU_UNUSED(op1))
7903 {
7904     u8 imm;
7905 
7906     START_OF_INSTR();
7907     DECODE_PRINTF("MOV\tCH,");
7908     imm = fetch_byte_imm();
7909     DECODE_PRINTF2("%x\n", imm);
7910     TRACE_AND_STEP();
7911     M.x86.R_CH = imm;
7912     DECODE_CLEAR_SEGOVR();
7913     END_OF_INSTR();
7914 }
7915 
7916 /****************************************************************************
7917 REMARKS:
7918 Handles opcode 0xb6
7919 ****************************************************************************/
x86emuOp_mov_byte_DH_IMM(u8 X86EMU_UNUSED (op1))7920 void x86emuOp_mov_byte_DH_IMM(u8 X86EMU_UNUSED(op1))
7921 {
7922     u8 imm;
7923 
7924     START_OF_INSTR();
7925     DECODE_PRINTF("MOV\tDH,");
7926     imm = fetch_byte_imm();
7927     DECODE_PRINTF2("%x\n", imm);
7928     TRACE_AND_STEP();
7929     M.x86.R_DH = imm;
7930     DECODE_CLEAR_SEGOVR();
7931     END_OF_INSTR();
7932 }
7933 
7934 /****************************************************************************
7935 REMARKS:
7936 Handles opcode 0xb7
7937 ****************************************************************************/
x86emuOp_mov_byte_BH_IMM(u8 X86EMU_UNUSED (op1))7938 void x86emuOp_mov_byte_BH_IMM(u8 X86EMU_UNUSED(op1))
7939 {
7940     u8 imm;
7941 
7942     START_OF_INSTR();
7943     DECODE_PRINTF("MOV\tBH,");
7944     imm = fetch_byte_imm();
7945     DECODE_PRINTF2("%x\n", imm);
7946     TRACE_AND_STEP();
7947     M.x86.R_BH = imm;
7948     DECODE_CLEAR_SEGOVR();
7949     END_OF_INSTR();
7950 }
7951 
7952 /****************************************************************************
7953 REMARKS:
7954 Handles opcode 0xb8
7955 ****************************************************************************/
x86emuOp_mov_word_AX_IMM(u8 X86EMU_UNUSED (op1))7956 void x86emuOp_mov_word_AX_IMM(u8 X86EMU_UNUSED(op1))
7957 {
7958     u32 srcval;
7959     START_OF_INSTR();
7960     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7961         DECODE_PRINTF("MOV\tEAX,");
7962         srcval = fetch_long_imm();
7963     } else {
7964         DECODE_PRINTF("MOV\tAX,");
7965         srcval = fetch_word_imm();
7966     }
7967     DECODE_PRINTF2("%x\n", srcval);
7968     TRACE_AND_STEP();
7969     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7970         M.x86.R_EAX = srcval;
7971     } else {
7972         M.x86.R_AX = (u16)srcval;
7973     }
7974     DECODE_CLEAR_SEGOVR();
7975     END_OF_INSTR();
7976 }
7977 
7978 /****************************************************************************
7979 REMARKS:
7980 Handles opcode 0xb9
7981 ****************************************************************************/
x86emuOp_mov_word_CX_IMM(u8 X86EMU_UNUSED (op1))7982 void x86emuOp_mov_word_CX_IMM(u8 X86EMU_UNUSED(op1))
7983 {
7984     u32 srcval;
7985 
7986     START_OF_INSTR();
7987     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7988         DECODE_PRINTF("MOV\tECX,");
7989         srcval = fetch_long_imm();
7990     } else {
7991         DECODE_PRINTF("MOV\tCX,");
7992         srcval = fetch_word_imm();
7993     }
7994     DECODE_PRINTF2("%x\n", srcval);
7995     TRACE_AND_STEP();
7996     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
7997         M.x86.R_ECX = srcval;
7998     } else {
7999         M.x86.R_CX = (u16)srcval;
8000     }
8001     DECODE_CLEAR_SEGOVR();
8002     END_OF_INSTR();
8003 }
8004 
8005 /****************************************************************************
8006 REMARKS:
8007 Handles opcode 0xba
8008 ****************************************************************************/
x86emuOp_mov_word_DX_IMM(u8 X86EMU_UNUSED (op1))8009 void x86emuOp_mov_word_DX_IMM(u8 X86EMU_UNUSED(op1))
8010 {
8011     u32 srcval;
8012 
8013     START_OF_INSTR();
8014     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8015         DECODE_PRINTF("MOV\tEDX,");
8016         srcval = fetch_long_imm();
8017     } else {
8018         DECODE_PRINTF("MOV\tDX,");
8019         srcval = fetch_word_imm();
8020     }
8021     DECODE_PRINTF2("%x\n", srcval);
8022     TRACE_AND_STEP();
8023     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8024         M.x86.R_EDX = srcval;
8025     } else {
8026         M.x86.R_DX = (u16)srcval;
8027     }
8028     DECODE_CLEAR_SEGOVR();
8029     END_OF_INSTR();
8030 }
8031 
8032 /****************************************************************************
8033 REMARKS:
8034 Handles opcode 0xbb
8035 ****************************************************************************/
x86emuOp_mov_word_BX_IMM(u8 X86EMU_UNUSED (op1))8036 void x86emuOp_mov_word_BX_IMM(u8 X86EMU_UNUSED(op1))
8037 {
8038     u32 srcval;
8039 
8040     START_OF_INSTR();
8041     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8042         DECODE_PRINTF("MOV\tEBX,");
8043         srcval = fetch_long_imm();
8044     } else {
8045         DECODE_PRINTF("MOV\tBX,");
8046         srcval = fetch_word_imm();
8047     }
8048     DECODE_PRINTF2("%x\n", srcval);
8049     TRACE_AND_STEP();
8050     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8051         M.x86.R_EBX = srcval;
8052     } else {
8053         M.x86.R_BX = (u16)srcval;
8054     }
8055     DECODE_CLEAR_SEGOVR();
8056     END_OF_INSTR();
8057 }
8058 
8059 /****************************************************************************
8060 REMARKS:
8061 Handles opcode 0xbc
8062 ****************************************************************************/
x86emuOp_mov_word_SP_IMM(u8 X86EMU_UNUSED (op1))8063 void x86emuOp_mov_word_SP_IMM(u8 X86EMU_UNUSED(op1))
8064 {
8065     u32 srcval;
8066 
8067     START_OF_INSTR();
8068     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8069         DECODE_PRINTF("MOV\tESP,");
8070         srcval = fetch_long_imm();
8071     } else {
8072         DECODE_PRINTF("MOV\tSP,");
8073         srcval = fetch_word_imm();
8074     }
8075     DECODE_PRINTF2("%x\n", srcval);
8076     TRACE_AND_STEP();
8077     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8078         M.x86.R_ESP = srcval;
8079     } else {
8080         M.x86.R_SP = (u16)srcval;
8081     }
8082     DECODE_CLEAR_SEGOVR();
8083     END_OF_INSTR();
8084 }
8085 
8086 /****************************************************************************
8087 REMARKS:
8088 Handles opcode 0xbd
8089 ****************************************************************************/
x86emuOp_mov_word_BP_IMM(u8 X86EMU_UNUSED (op1))8090 void x86emuOp_mov_word_BP_IMM(u8 X86EMU_UNUSED(op1))
8091 {
8092     u32 srcval;
8093 
8094     START_OF_INSTR();
8095     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8096         DECODE_PRINTF("MOV\tEBP,");
8097         srcval = fetch_long_imm();
8098     } else {
8099         DECODE_PRINTF("MOV\tBP,");
8100         srcval = fetch_word_imm();
8101     }
8102     DECODE_PRINTF2("%x\n", srcval);
8103     TRACE_AND_STEP();
8104     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8105         M.x86.R_EBP = srcval;
8106     } else {
8107         M.x86.R_BP = (u16)srcval;
8108     }
8109     DECODE_CLEAR_SEGOVR();
8110     END_OF_INSTR();
8111 }
8112 
8113 /****************************************************************************
8114 REMARKS:
8115 Handles opcode 0xbe
8116 ****************************************************************************/
x86emuOp_mov_word_SI_IMM(u8 X86EMU_UNUSED (op1))8117 void x86emuOp_mov_word_SI_IMM(u8 X86EMU_UNUSED(op1))
8118 {
8119     u32 srcval;
8120 
8121     START_OF_INSTR();
8122     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8123         DECODE_PRINTF("MOV\tESI,");
8124         srcval = fetch_long_imm();
8125     } else {
8126         DECODE_PRINTF("MOV\tSI,");
8127         srcval = fetch_word_imm();
8128     }
8129     DECODE_PRINTF2("%x\n", srcval);
8130     TRACE_AND_STEP();
8131     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8132         M.x86.R_ESI = srcval;
8133     } else {
8134         M.x86.R_SI = (u16)srcval;
8135     }
8136     DECODE_CLEAR_SEGOVR();
8137     END_OF_INSTR();
8138 }
8139 
8140 /****************************************************************************
8141 REMARKS:
8142 Handles opcode 0xbf
8143 ****************************************************************************/
x86emuOp_mov_word_DI_IMM(u8 X86EMU_UNUSED (op1))8144 void x86emuOp_mov_word_DI_IMM(u8 X86EMU_UNUSED(op1))
8145 {
8146     u32 srcval;
8147 
8148     START_OF_INSTR();
8149     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8150         DECODE_PRINTF("MOV\tEDI,");
8151         srcval = fetch_long_imm();
8152     } else {
8153         DECODE_PRINTF("MOV\tDI,");
8154         srcval = fetch_word_imm();
8155     }
8156     DECODE_PRINTF2("%x\n", srcval);
8157     TRACE_AND_STEP();
8158     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8159         M.x86.R_EDI = srcval;
8160     } else {
8161         M.x86.R_DI = (u16)srcval;
8162     }
8163     DECODE_CLEAR_SEGOVR();
8164     END_OF_INSTR();
8165 }
8166 
8167 /* used by opcodes c0, d0, and d2. */
8168 static u8(*opcD0_byte_operation[])(u8 d, u8 s) =
8169 {
8170     rol_byte,
8171     ror_byte,
8172     rcl_byte,
8173     rcr_byte,
8174     shl_byte,
8175     shr_byte,
8176     shl_byte,           /* sal_byte === shl_byte  by definition */
8177     sar_byte,
8178 };
8179 
8180 /****************************************************************************
8181 REMARKS:
8182 Handles opcode 0xc0
8183 ****************************************************************************/
x86emuOp_opcC0_byte_RM_MEM(u8 X86EMU_UNUSED (op1))8184 void x86emuOp_opcC0_byte_RM_MEM(u8 X86EMU_UNUSED(op1))
8185 {
8186     int mod, rl, rh;
8187     u8 *destreg;
8188     uint destoffset;
8189     u8 destval;
8190     u8 amt;
8191 
8192     /*
8193      * Yet another weirdo special case instruction format.  Part of
8194      * the opcode held below in "RH".  Doubly nested case would
8195      * result, except that the decoded instruction
8196      */
8197     START_OF_INSTR();
8198     FETCH_DECODE_MODRM(mod, rh, rl);
8199 #ifdef DEBUG
8200     if (DEBUG_DECODE()) {
8201         /* XXX DECODE_PRINTF may be changed to something more
8202            general, so that it is important to leave the strings
8203            in the same format, even though the result is that the
8204            above test is done twice. */
8205 
8206         switch (rh) {
8207         case 0:
8208             DECODE_PRINTF("ROL\t");
8209             break;
8210         case 1:
8211             DECODE_PRINTF("ROR\t");
8212             break;
8213         case 2:
8214             DECODE_PRINTF("RCL\t");
8215             break;
8216         case 3:
8217             DECODE_PRINTF("RCR\t");
8218             break;
8219         case 4:
8220             DECODE_PRINTF("SHL\t");
8221             break;
8222         case 5:
8223             DECODE_PRINTF("SHR\t");
8224             break;
8225         case 6:
8226             DECODE_PRINTF("SAL\t");
8227             break;
8228         case 7:
8229             DECODE_PRINTF("SAR\t");
8230             break;
8231         }
8232     }
8233 #endif
8234     /* know operation, decode the mod byte to find the addressing
8235        mode. */
8236     switch (mod) {
8237     case 0:
8238         DECODE_PRINTF("BYTE PTR ");
8239         destoffset = decode_rm00_address(rl);
8240         amt = fetch_byte_imm();
8241         DECODE_PRINTF2(",%x\n", amt);
8242         destval = fetch_data_byte(destoffset);
8243         TRACE_AND_STEP();
8244         destval = (*opcD0_byte_operation[rh]) (destval, amt);
8245         store_data_byte(destoffset, destval);
8246         break;
8247     case 1:
8248         DECODE_PRINTF("BYTE PTR ");
8249         destoffset = decode_rm01_address(rl);
8250         amt = fetch_byte_imm();
8251         DECODE_PRINTF2(",%x\n", amt);
8252         destval = fetch_data_byte(destoffset);
8253         TRACE_AND_STEP();
8254         destval = (*opcD0_byte_operation[rh]) (destval, amt);
8255         store_data_byte(destoffset, destval);
8256         break;
8257     case 2:
8258         DECODE_PRINTF("BYTE PTR ");
8259         destoffset = decode_rm10_address(rl);
8260         amt = fetch_byte_imm();
8261         DECODE_PRINTF2(",%x\n", amt);
8262         destval = fetch_data_byte(destoffset);
8263         TRACE_AND_STEP();
8264         destval = (*opcD0_byte_operation[rh]) (destval, amt);
8265         store_data_byte(destoffset, destval);
8266         break;
8267     case 3:                     /* register to register */
8268         destreg = DECODE_RM_BYTE_REGISTER(rl);
8269         amt = fetch_byte_imm();
8270         DECODE_PRINTF2(",%x\n", amt);
8271         TRACE_AND_STEP();
8272         destval = (*opcD0_byte_operation[rh]) (*destreg, amt);
8273         *destreg = destval;
8274         break;
8275     }
8276     DECODE_CLEAR_SEGOVR();
8277     END_OF_INSTR();
8278 }
8279 
8280 /* used by opcodes c1, d1, and d3. */
8281 static u16(*opcD1_word_operation[])(u16 s, u8 d) =
8282 {
8283     rol_word,
8284     ror_word,
8285     rcl_word,
8286     rcr_word,
8287     shl_word,
8288     shr_word,
8289     shl_word,           /* sal_byte === shl_byte  by definition */
8290     sar_word,
8291 };
8292 
8293 /* used by opcodes c1, d1, and d3. */
8294 static u32 (*opcD1_long_operation[])(u32 s, u8 d) =
8295 {
8296     rol_long,
8297     ror_long,
8298     rcl_long,
8299     rcr_long,
8300     shl_long,
8301     shr_long,
8302     shl_long,           /* sal_byte === shl_byte  by definition */
8303     sar_long,
8304 };
8305 
8306 /****************************************************************************
8307 REMARKS:
8308 Handles opcode 0xc1
8309 ****************************************************************************/
x86emuOp_opcC1_word_RM_MEM(u8 X86EMU_UNUSED (op1))8310 void x86emuOp_opcC1_word_RM_MEM(u8 X86EMU_UNUSED(op1))
8311 {
8312     int mod, rl, rh;
8313     uint destoffset;
8314     u8 amt;
8315 
8316     /*
8317      * Yet another weirdo special case instruction format.  Part of
8318      * the opcode held below in "RH".  Doubly nested case would
8319      * result, except that the decoded instruction
8320      */
8321     START_OF_INSTR();
8322     FETCH_DECODE_MODRM(mod, rh, rl);
8323 #ifdef DEBUG
8324     if (DEBUG_DECODE()) {
8325         /* XXX DECODE_PRINTF may be changed to something more
8326            general, so that it is important to leave the strings
8327            in the same format, even though the result is that the
8328            above test is done twice. */
8329 
8330         switch (rh) {
8331         case 0:
8332             DECODE_PRINTF("ROL\t");
8333             break;
8334         case 1:
8335             DECODE_PRINTF("ROR\t");
8336             break;
8337         case 2:
8338             DECODE_PRINTF("RCL\t");
8339             break;
8340         case 3:
8341             DECODE_PRINTF("RCR\t");
8342             break;
8343         case 4:
8344             DECODE_PRINTF("SHL\t");
8345             break;
8346         case 5:
8347             DECODE_PRINTF("SHR\t");
8348             break;
8349         case 6:
8350             DECODE_PRINTF("SAL\t");
8351             break;
8352         case 7:
8353             DECODE_PRINTF("SAR\t");
8354             break;
8355         }
8356     }
8357 #endif
8358     /* know operation, decode the mod byte to find the addressing
8359        mode. */
8360     switch (mod) {
8361     case 0:
8362         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8363             u32 destval;
8364 
8365             DECODE_PRINTF("DWORD PTR ");
8366             destoffset = decode_rm00_address(rl);
8367             amt = fetch_byte_imm();
8368             DECODE_PRINTF2(",%x\n", amt);
8369             destval = fetch_data_long(destoffset);
8370             TRACE_AND_STEP();
8371             destval = (*opcD1_long_operation[rh]) (destval, amt);
8372             store_data_long(destoffset, destval);
8373         } else {
8374             u16 destval;
8375 
8376             DECODE_PRINTF("WORD PTR ");
8377             destoffset = decode_rm00_address(rl);
8378             amt = fetch_byte_imm();
8379             DECODE_PRINTF2(",%x\n", amt);
8380             destval = fetch_data_word(destoffset);
8381             TRACE_AND_STEP();
8382             destval = (*opcD1_word_operation[rh]) (destval, amt);
8383             store_data_word(destoffset, destval);
8384         }
8385         break;
8386     case 1:
8387         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8388             u32 destval;
8389 
8390             DECODE_PRINTF("DWORD PTR ");
8391             destoffset = decode_rm01_address(rl);
8392             amt = fetch_byte_imm();
8393             DECODE_PRINTF2(",%x\n", amt);
8394             destval = fetch_data_long(destoffset);
8395             TRACE_AND_STEP();
8396             destval = (*opcD1_long_operation[rh]) (destval, amt);
8397             store_data_long(destoffset, destval);
8398         } else {
8399             u16 destval;
8400 
8401             DECODE_PRINTF("WORD PTR ");
8402             destoffset = decode_rm01_address(rl);
8403             amt = fetch_byte_imm();
8404             DECODE_PRINTF2(",%x\n", amt);
8405             destval = fetch_data_word(destoffset);
8406             TRACE_AND_STEP();
8407             destval = (*opcD1_word_operation[rh]) (destval, amt);
8408             store_data_word(destoffset, destval);
8409         }
8410         break;
8411     case 2:
8412         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8413             u32 destval;
8414 
8415             DECODE_PRINTF("DWORD PTR ");
8416             destoffset = decode_rm10_address(rl);
8417             amt = fetch_byte_imm();
8418             DECODE_PRINTF2(",%x\n", amt);
8419             destval = fetch_data_long(destoffset);
8420             TRACE_AND_STEP();
8421             destval = (*opcD1_long_operation[rh]) (destval, amt);
8422             store_data_long(destoffset, destval);
8423         } else {
8424             u16 destval;
8425 
8426             DECODE_PRINTF("WORD PTR ");
8427             destoffset = decode_rm10_address(rl);
8428             amt = fetch_byte_imm();
8429             DECODE_PRINTF2(",%x\n", amt);
8430             destval = fetch_data_word(destoffset);
8431             TRACE_AND_STEP();
8432             destval = (*opcD1_word_operation[rh]) (destval, amt);
8433             store_data_word(destoffset, destval);
8434         }
8435         break;
8436     case 3:                     /* register to register */
8437         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8438             u32 *destreg;
8439 
8440             destreg = DECODE_RM_LONG_REGISTER(rl);
8441             amt = fetch_byte_imm();
8442             DECODE_PRINTF2(",%x\n", amt);
8443             TRACE_AND_STEP();
8444             *destreg = (*opcD1_long_operation[rh]) (*destreg, amt);
8445         } else {
8446             u16 *destreg;
8447 
8448             destreg = DECODE_RM_WORD_REGISTER(rl);
8449             amt = fetch_byte_imm();
8450             DECODE_PRINTF2(",%x\n", amt);
8451             TRACE_AND_STEP();
8452             *destreg = (*opcD1_word_operation[rh]) (*destreg, amt);
8453         }
8454         break;
8455     }
8456     DECODE_CLEAR_SEGOVR();
8457     END_OF_INSTR();
8458 }
8459 
8460 /****************************************************************************
8461 REMARKS:
8462 Handles opcode 0xc2
8463 ****************************************************************************/
x86emuOp_ret_near_IMM(u8 X86EMU_UNUSED (op1))8464 void x86emuOp_ret_near_IMM(u8 X86EMU_UNUSED(op1))
8465 {
8466     u16 imm;
8467 
8468     START_OF_INSTR();
8469     DECODE_PRINTF("RET\t");
8470     imm = fetch_word_imm();
8471     DECODE_PRINTF2("%x\n", imm);
8472     RETURN_TRACE("RET",M.x86.saved_cs,M.x86.saved_ip);
8473     TRACE_AND_STEP();
8474     M.x86.R_IP = pop_word();
8475     M.x86.R_SP += imm;
8476     DECODE_CLEAR_SEGOVR();
8477     END_OF_INSTR();
8478 }
8479 
8480 /****************************************************************************
8481 REMARKS:
8482 Handles opcode 0xc3
8483 ****************************************************************************/
x86emuOp_ret_near(u8 X86EMU_UNUSED (op1))8484 void x86emuOp_ret_near(u8 X86EMU_UNUSED(op1))
8485 {
8486     START_OF_INSTR();
8487     DECODE_PRINTF("RET\n");
8488     RETURN_TRACE("RET",M.x86.saved_cs,M.x86.saved_ip);
8489     TRACE_AND_STEP();
8490     M.x86.R_IP = pop_word();
8491     DECODE_CLEAR_SEGOVR();
8492     END_OF_INSTR();
8493 }
8494 
8495 /****************************************************************************
8496 REMARKS:
8497 Handles opcode 0xc4
8498 ****************************************************************************/
x86emuOp_les_R_IMM(u8 X86EMU_UNUSED (op1))8499 void x86emuOp_les_R_IMM(u8 X86EMU_UNUSED(op1))
8500 {
8501     int mod, rh, rl;
8502     u16 *dstreg;
8503     uint srcoffset;
8504 
8505     START_OF_INSTR();
8506     DECODE_PRINTF("LES\t");
8507     FETCH_DECODE_MODRM(mod, rh, rl);
8508     switch (mod) {
8509     case 0:
8510         dstreg = DECODE_RM_WORD_REGISTER(rh);
8511         DECODE_PRINTF(",");
8512         srcoffset = decode_rm00_address(rl);
8513         DECODE_PRINTF("\n");
8514         TRACE_AND_STEP();
8515         *dstreg = fetch_data_word(srcoffset);
8516         M.x86.R_ES = fetch_data_word(srcoffset + 2);
8517         break;
8518     case 1:
8519         dstreg = DECODE_RM_WORD_REGISTER(rh);
8520         DECODE_PRINTF(",");
8521         srcoffset = decode_rm01_address(rl);
8522         DECODE_PRINTF("\n");
8523         TRACE_AND_STEP();
8524         *dstreg = fetch_data_word(srcoffset);
8525         M.x86.R_ES = fetch_data_word(srcoffset + 2);
8526         break;
8527     case 2:
8528         dstreg = DECODE_RM_WORD_REGISTER(rh);
8529         DECODE_PRINTF(",");
8530         srcoffset = decode_rm10_address(rl);
8531         DECODE_PRINTF("\n");
8532         TRACE_AND_STEP();
8533         *dstreg = fetch_data_word(srcoffset);
8534         M.x86.R_ES = fetch_data_word(srcoffset + 2);
8535         break;
8536     case 3:                     /* register to register */
8537         /* UNDEFINED! */
8538         TRACE_AND_STEP();
8539     }
8540     DECODE_CLEAR_SEGOVR();
8541     END_OF_INSTR();
8542 }
8543 
8544 /****************************************************************************
8545 REMARKS:
8546 Handles opcode 0xc5
8547 ****************************************************************************/
x86emuOp_lds_R_IMM(u8 X86EMU_UNUSED (op1))8548 void x86emuOp_lds_R_IMM(u8 X86EMU_UNUSED(op1))
8549 {
8550     int mod, rh, rl;
8551     u16 *dstreg;
8552     uint srcoffset;
8553 
8554     START_OF_INSTR();
8555     DECODE_PRINTF("LDS\t");
8556     FETCH_DECODE_MODRM(mod, rh, rl);
8557     switch (mod) {
8558     case 0:
8559         dstreg = DECODE_RM_WORD_REGISTER(rh);
8560         DECODE_PRINTF(",");
8561         srcoffset = decode_rm00_address(rl);
8562         DECODE_PRINTF("\n");
8563         TRACE_AND_STEP();
8564         *dstreg = fetch_data_word(srcoffset);
8565         M.x86.R_DS = fetch_data_word(srcoffset + 2);
8566         break;
8567     case 1:
8568         dstreg = DECODE_RM_WORD_REGISTER(rh);
8569         DECODE_PRINTF(",");
8570         srcoffset = decode_rm01_address(rl);
8571         DECODE_PRINTF("\n");
8572         TRACE_AND_STEP();
8573         *dstreg = fetch_data_word(srcoffset);
8574         M.x86.R_DS = fetch_data_word(srcoffset + 2);
8575         break;
8576     case 2:
8577         dstreg = DECODE_RM_WORD_REGISTER(rh);
8578         DECODE_PRINTF(",");
8579         srcoffset = decode_rm10_address(rl);
8580         DECODE_PRINTF("\n");
8581         TRACE_AND_STEP();
8582         *dstreg = fetch_data_word(srcoffset);
8583         M.x86.R_DS = fetch_data_word(srcoffset + 2);
8584         break;
8585     case 3:                     /* register to register */
8586         /* UNDEFINED! */
8587         TRACE_AND_STEP();
8588     }
8589     DECODE_CLEAR_SEGOVR();
8590     END_OF_INSTR();
8591 }
8592 
8593 /****************************************************************************
8594 REMARKS:
8595 Handles opcode 0xc6
8596 ****************************************************************************/
x86emuOp_mov_byte_RM_IMM(u8 X86EMU_UNUSED (op1))8597 void x86emuOp_mov_byte_RM_IMM(u8 X86EMU_UNUSED(op1))
8598 {
8599     int mod, rl, rh;
8600     u8 *destreg;
8601     uint destoffset;
8602     u8 imm;
8603 
8604     START_OF_INSTR();
8605     DECODE_PRINTF("MOV\t");
8606     FETCH_DECODE_MODRM(mod, rh, rl);
8607     if (rh != 0) {
8608         DECODE_PRINTF("ILLEGAL DECODE OF OPCODE c6\n");
8609         HALT_SYS();
8610     }
8611     switch (mod) {
8612     case 0:
8613         DECODE_PRINTF("BYTE PTR ");
8614         destoffset = decode_rm00_address(rl);
8615         imm = fetch_byte_imm();
8616         DECODE_PRINTF2(",%2x\n", imm);
8617         TRACE_AND_STEP();
8618         store_data_byte(destoffset, imm);
8619         break;
8620     case 1:
8621         DECODE_PRINTF("BYTE PTR ");
8622         destoffset = decode_rm01_address(rl);
8623         imm = fetch_byte_imm();
8624         DECODE_PRINTF2(",%2x\n", imm);
8625         TRACE_AND_STEP();
8626         store_data_byte(destoffset, imm);
8627         break;
8628     case 2:
8629         DECODE_PRINTF("BYTE PTR ");
8630         destoffset = decode_rm10_address(rl);
8631         imm = fetch_byte_imm();
8632         DECODE_PRINTF2(",%2x\n", imm);
8633         TRACE_AND_STEP();
8634         store_data_byte(destoffset, imm);
8635         break;
8636     case 3:                     /* register to register */
8637         destreg = DECODE_RM_BYTE_REGISTER(rl);
8638         imm = fetch_byte_imm();
8639         DECODE_PRINTF2(",%2x\n", imm);
8640         TRACE_AND_STEP();
8641         *destreg = imm;
8642         break;
8643     }
8644     DECODE_CLEAR_SEGOVR();
8645     END_OF_INSTR();
8646 }
8647 
8648 /****************************************************************************
8649 REMARKS:
8650 Handles opcode 0xc7
8651 ****************************************************************************/
x86emuOp_mov_word_RM_IMM(u8 X86EMU_UNUSED (op1))8652 void x86emuOp_mov_word_RM_IMM(u8 X86EMU_UNUSED(op1))
8653 {
8654     int mod, rl, rh;
8655     uint destoffset;
8656 
8657     START_OF_INSTR();
8658     DECODE_PRINTF("MOV\t");
8659     FETCH_DECODE_MODRM(mod, rh, rl);
8660     if (rh != 0) {
8661         DECODE_PRINTF("ILLEGAL DECODE OF OPCODE 8F\n");
8662         HALT_SYS();
8663     }
8664     switch (mod) {
8665     case 0:
8666         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8667             u32 imm;
8668 
8669             DECODE_PRINTF("DWORD PTR ");
8670             destoffset = decode_rm00_address(rl);
8671             imm = fetch_long_imm();
8672             DECODE_PRINTF2(",%x\n", imm);
8673             TRACE_AND_STEP();
8674             store_data_long(destoffset, imm);
8675         } else {
8676             u16 imm;
8677 
8678             DECODE_PRINTF("WORD PTR ");
8679             destoffset = decode_rm00_address(rl);
8680             imm = fetch_word_imm();
8681             DECODE_PRINTF2(",%x\n", imm);
8682             TRACE_AND_STEP();
8683             store_data_word(destoffset, imm);
8684         }
8685         break;
8686     case 1:
8687         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8688             u32 imm;
8689 
8690             DECODE_PRINTF("DWORD PTR ");
8691             destoffset = decode_rm01_address(rl);
8692             imm = fetch_long_imm();
8693             DECODE_PRINTF2(",%x\n", imm);
8694             TRACE_AND_STEP();
8695             store_data_long(destoffset, imm);
8696         } else {
8697             u16 imm;
8698 
8699             DECODE_PRINTF("WORD PTR ");
8700             destoffset = decode_rm01_address(rl);
8701             imm = fetch_word_imm();
8702             DECODE_PRINTF2(",%x\n", imm);
8703             TRACE_AND_STEP();
8704             store_data_word(destoffset, imm);
8705         }
8706         break;
8707     case 2:
8708         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8709             u32 imm;
8710 
8711             DECODE_PRINTF("DWORD PTR ");
8712             destoffset = decode_rm10_address(rl);
8713             imm = fetch_long_imm();
8714             DECODE_PRINTF2(",%x\n", imm);
8715             TRACE_AND_STEP();
8716             store_data_long(destoffset, imm);
8717         } else {
8718             u16 imm;
8719 
8720             DECODE_PRINTF("WORD PTR ");
8721             destoffset = decode_rm10_address(rl);
8722             imm = fetch_word_imm();
8723             DECODE_PRINTF2(",%x\n", imm);
8724             TRACE_AND_STEP();
8725             store_data_word(destoffset, imm);
8726         }
8727         break;
8728     case 3:                     /* register to register */
8729         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
8730             u32 *destreg;
8731             u32 imm;
8732 
8733             destreg = DECODE_RM_LONG_REGISTER(rl);
8734             imm = fetch_long_imm();
8735             DECODE_PRINTF2(",%x\n", imm);
8736             TRACE_AND_STEP();
8737             *destreg = imm;
8738         } else {
8739             u16 *destreg;
8740             u16 imm;
8741 
8742             destreg = DECODE_RM_WORD_REGISTER(rl);
8743             imm = fetch_word_imm();
8744             DECODE_PRINTF2(",%x\n", imm);
8745             TRACE_AND_STEP();
8746             *destreg = imm;
8747         }
8748         break;
8749     }
8750     DECODE_CLEAR_SEGOVR();
8751     END_OF_INSTR();
8752 }
8753 
8754 /****************************************************************************
8755 REMARKS:
8756 Handles opcode 0xc8
8757 ****************************************************************************/
x86emuOp_enter(u8 X86EMU_UNUSED (op1))8758 void x86emuOp_enter(u8 X86EMU_UNUSED(op1))
8759 {
8760     u16 local,frame_pointer;
8761     u8  nesting;
8762     int i;
8763 
8764     START_OF_INSTR();
8765     local = fetch_word_imm();
8766     nesting = fetch_byte_imm();
8767     DECODE_PRINTF2("ENTER %x\n", local);
8768     DECODE_PRINTF2(",%x\n", nesting);
8769     TRACE_AND_STEP();
8770     push_word(M.x86.R_BP);
8771     frame_pointer = M.x86.R_SP;
8772     if (nesting > 0) {
8773         for (i = 1; i < nesting; i++) {
8774             M.x86.R_BP -= 2;
8775             push_word(fetch_data_word_abs(M.x86.R_SS, M.x86.R_BP));
8776             }
8777         push_word(frame_pointer);
8778         }
8779     M.x86.R_BP = frame_pointer;
8780     M.x86.R_SP = (u16)(M.x86.R_SP - local);
8781     DECODE_CLEAR_SEGOVR();
8782     END_OF_INSTR();
8783 }
8784 
8785 /****************************************************************************
8786 REMARKS:
8787 Handles opcode 0xc9
8788 ****************************************************************************/
x86emuOp_leave(u8 X86EMU_UNUSED (op1))8789 void x86emuOp_leave(u8 X86EMU_UNUSED(op1))
8790 {
8791     START_OF_INSTR();
8792     DECODE_PRINTF("LEAVE\n");
8793     TRACE_AND_STEP();
8794     M.x86.R_SP = M.x86.R_BP;
8795     M.x86.R_BP = pop_word();
8796     DECODE_CLEAR_SEGOVR();
8797     END_OF_INSTR();
8798 }
8799 
8800 /****************************************************************************
8801 REMARKS:
8802 Handles opcode 0xca
8803 ****************************************************************************/
x86emuOp_ret_far_IMM(u8 X86EMU_UNUSED (op1))8804 void x86emuOp_ret_far_IMM(u8 X86EMU_UNUSED(op1))
8805 {
8806     u16 imm;
8807 
8808     START_OF_INSTR();
8809     DECODE_PRINTF("RETF\t");
8810     imm = fetch_word_imm();
8811     DECODE_PRINTF2("%x\n", imm);
8812     RETURN_TRACE("RETF",M.x86.saved_cs,M.x86.saved_ip);
8813     TRACE_AND_STEP();
8814     M.x86.R_IP = pop_word();
8815     M.x86.R_CS = pop_word();
8816     M.x86.R_SP += imm;
8817     DECODE_CLEAR_SEGOVR();
8818     END_OF_INSTR();
8819 }
8820 
8821 /****************************************************************************
8822 REMARKS:
8823 Handles opcode 0xcb
8824 ****************************************************************************/
x86emuOp_ret_far(u8 X86EMU_UNUSED (op1))8825 void x86emuOp_ret_far(u8 X86EMU_UNUSED(op1))
8826 {
8827     START_OF_INSTR();
8828     DECODE_PRINTF("RETF\n");
8829     RETURN_TRACE("RETF",M.x86.saved_cs,M.x86.saved_ip);
8830     TRACE_AND_STEP();
8831     M.x86.R_IP = pop_word();
8832     M.x86.R_CS = pop_word();
8833     DECODE_CLEAR_SEGOVR();
8834     END_OF_INSTR();
8835 }
8836 
8837 /****************************************************************************
8838 REMARKS:
8839 Handles opcode 0xcc
8840 ****************************************************************************/
x86emuOp_int3(u8 X86EMU_UNUSED (op1))8841 void x86emuOp_int3(u8 X86EMU_UNUSED(op1))
8842 {
8843     u16 tmp;
8844 
8845     START_OF_INSTR();
8846     DECODE_PRINTF("INT 3\n");
8847     tmp = (u16) mem_access_word(3 * 4 + 2);
8848     /* access the segment register */
8849     TRACE_AND_STEP();
8850     if (_X86EMU_intrTab[3]) {
8851         (*_X86EMU_intrTab[3])(3);
8852     } else {
8853         push_word((u16)M.x86.R_FLG);
8854         CLEAR_FLAG(F_IF);
8855         CLEAR_FLAG(F_TF);
8856         push_word(M.x86.R_CS);
8857         M.x86.R_CS = mem_access_word(3 * 4 + 2);
8858         push_word(M.x86.R_IP);
8859         M.x86.R_IP = mem_access_word(3 * 4);
8860     }
8861     DECODE_CLEAR_SEGOVR();
8862     END_OF_INSTR();
8863 }
8864 
8865 /****************************************************************************
8866 REMARKS:
8867 Handles opcode 0xcd
8868 ****************************************************************************/
x86emuOp_int_IMM(u8 X86EMU_UNUSED (op1))8869 void x86emuOp_int_IMM(u8 X86EMU_UNUSED(op1))
8870 {
8871     u16 tmp;
8872     u8 intnum;
8873 
8874     START_OF_INSTR();
8875     DECODE_PRINTF("INT\t");
8876     intnum = fetch_byte_imm();
8877     DECODE_PRINTF2("%x\n", intnum);
8878     tmp = mem_access_word(intnum * 4 + 2);
8879     TRACE_AND_STEP();
8880     if (_X86EMU_intrTab[intnum]) {
8881         (*_X86EMU_intrTab[intnum])(intnum);
8882     } else {
8883         push_word((u16)M.x86.R_FLG);
8884         CLEAR_FLAG(F_IF);
8885         CLEAR_FLAG(F_TF);
8886         push_word(M.x86.R_CS);
8887         M.x86.R_CS = mem_access_word(intnum * 4 + 2);
8888         push_word(M.x86.R_IP);
8889         M.x86.R_IP = mem_access_word(intnum * 4);
8890     }
8891     DECODE_CLEAR_SEGOVR();
8892     END_OF_INSTR();
8893 }
8894 
8895 /****************************************************************************
8896 REMARKS:
8897 Handles opcode 0xce
8898 ****************************************************************************/
x86emuOp_into(u8 X86EMU_UNUSED (op1))8899 void x86emuOp_into(u8 X86EMU_UNUSED(op1))
8900 {
8901     u16 tmp;
8902 
8903     START_OF_INSTR();
8904     DECODE_PRINTF("INTO\n");
8905     TRACE_AND_STEP();
8906     if (ACCESS_FLAG(F_OF)) {
8907         tmp = mem_access_word(4 * 4 + 2);
8908         if (_X86EMU_intrTab[4]) {
8909             (*_X86EMU_intrTab[4])(4);
8910         } else {
8911             push_word((u16)M.x86.R_FLG);
8912             CLEAR_FLAG(F_IF);
8913             CLEAR_FLAG(F_TF);
8914             push_word(M.x86.R_CS);
8915             M.x86.R_CS = mem_access_word(4 * 4 + 2);
8916             push_word(M.x86.R_IP);
8917             M.x86.R_IP = mem_access_word(4 * 4);
8918         }
8919     }
8920     DECODE_CLEAR_SEGOVR();
8921     END_OF_INSTR();
8922 }
8923 
8924 /****************************************************************************
8925 REMARKS:
8926 Handles opcode 0xcf
8927 ****************************************************************************/
x86emuOp_iret(u8 X86EMU_UNUSED (op1))8928 void x86emuOp_iret(u8 X86EMU_UNUSED(op1))
8929 {
8930     START_OF_INSTR();
8931     DECODE_PRINTF("IRET\n");
8932 
8933     TRACE_AND_STEP();
8934 
8935     M.x86.R_IP = pop_word();
8936     M.x86.R_CS = pop_word();
8937     M.x86.R_FLG = pop_word();
8938     DECODE_CLEAR_SEGOVR();
8939     END_OF_INSTR();
8940 }
8941 
8942 /****************************************************************************
8943 REMARKS:
8944 Handles opcode 0xd0
8945 ****************************************************************************/
x86emuOp_opcD0_byte_RM_1(u8 X86EMU_UNUSED (op1))8946 void x86emuOp_opcD0_byte_RM_1(u8 X86EMU_UNUSED(op1))
8947 {
8948     int mod, rl, rh;
8949     u8 *destreg;
8950     uint destoffset;
8951     u8 destval;
8952 
8953     /*
8954      * Yet another weirdo special case instruction format.  Part of
8955      * the opcode held below in "RH".  Doubly nested case would
8956      * result, except that the decoded instruction
8957      */
8958     START_OF_INSTR();
8959     FETCH_DECODE_MODRM(mod, rh, rl);
8960 #ifdef DEBUG
8961     if (DEBUG_DECODE()) {
8962         /* XXX DECODE_PRINTF may be changed to something more
8963            general, so that it is important to leave the strings
8964            in the same format, even though the result is that the
8965            above test is done twice. */
8966         switch (rh) {
8967         case 0:
8968             DECODE_PRINTF("ROL\t");
8969             break;
8970         case 1:
8971             DECODE_PRINTF("ROR\t");
8972             break;
8973         case 2:
8974             DECODE_PRINTF("RCL\t");
8975             break;
8976         case 3:
8977             DECODE_PRINTF("RCR\t");
8978             break;
8979         case 4:
8980             DECODE_PRINTF("SHL\t");
8981             break;
8982         case 5:
8983             DECODE_PRINTF("SHR\t");
8984             break;
8985         case 6:
8986             DECODE_PRINTF("SAL\t");
8987             break;
8988         case 7:
8989             DECODE_PRINTF("SAR\t");
8990             break;
8991         }
8992     }
8993 #endif
8994     /* know operation, decode the mod byte to find the addressing
8995        mode. */
8996     switch (mod) {
8997     case 0:
8998         DECODE_PRINTF("BYTE PTR ");
8999         destoffset = decode_rm00_address(rl);
9000         DECODE_PRINTF(",1\n");
9001         destval = fetch_data_byte(destoffset);
9002         TRACE_AND_STEP();
9003         destval = (*opcD0_byte_operation[rh]) (destval, 1);
9004         store_data_byte(destoffset, destval);
9005         break;
9006     case 1:
9007         DECODE_PRINTF("BYTE PTR ");
9008         destoffset = decode_rm01_address(rl);
9009         DECODE_PRINTF(",1\n");
9010         destval = fetch_data_byte(destoffset);
9011         TRACE_AND_STEP();
9012         destval = (*opcD0_byte_operation[rh]) (destval, 1);
9013         store_data_byte(destoffset, destval);
9014         break;
9015     case 2:
9016         DECODE_PRINTF("BYTE PTR ");
9017         destoffset = decode_rm10_address(rl);
9018         DECODE_PRINTF(",1\n");
9019         destval = fetch_data_byte(destoffset);
9020         TRACE_AND_STEP();
9021         destval = (*opcD0_byte_operation[rh]) (destval, 1);
9022         store_data_byte(destoffset, destval);
9023         break;
9024     case 3:                     /* register to register */
9025         destreg = DECODE_RM_BYTE_REGISTER(rl);
9026         DECODE_PRINTF(",1\n");
9027         TRACE_AND_STEP();
9028         destval = (*opcD0_byte_operation[rh]) (*destreg, 1);
9029         *destreg = destval;
9030         break;
9031     }
9032     DECODE_CLEAR_SEGOVR();
9033     END_OF_INSTR();
9034 }
9035 
9036 /****************************************************************************
9037 REMARKS:
9038 Handles opcode 0xd1
9039 ****************************************************************************/
x86emuOp_opcD1_word_RM_1(u8 X86EMU_UNUSED (op1))9040 void x86emuOp_opcD1_word_RM_1(u8 X86EMU_UNUSED(op1))
9041 {
9042     int mod, rl, rh;
9043     uint destoffset;
9044 
9045     /*
9046      * Yet another weirdo special case instruction format.  Part of
9047      * the opcode held below in "RH".  Doubly nested case would
9048      * result, except that the decoded instruction
9049      */
9050     START_OF_INSTR();
9051     FETCH_DECODE_MODRM(mod, rh, rl);
9052 #ifdef DEBUG
9053     if (DEBUG_DECODE()) {
9054         /* XXX DECODE_PRINTF may be changed to something more
9055            general, so that it is important to leave the strings
9056            in the same format, even though the result is that the
9057            above test is done twice. */
9058         switch (rh) {
9059         case 0:
9060             DECODE_PRINTF("ROL\t");
9061             break;
9062         case 1:
9063             DECODE_PRINTF("ROR\t");
9064             break;
9065         case 2:
9066             DECODE_PRINTF("RCL\t");
9067             break;
9068         case 3:
9069             DECODE_PRINTF("RCR\t");
9070             break;
9071         case 4:
9072             DECODE_PRINTF("SHL\t");
9073             break;
9074         case 5:
9075             DECODE_PRINTF("SHR\t");
9076             break;
9077         case 6:
9078             DECODE_PRINTF("SAL\t");
9079             break;
9080         case 7:
9081             DECODE_PRINTF("SAR\t");
9082             break;
9083         }
9084     }
9085 #endif
9086     /* know operation, decode the mod byte to find the addressing
9087        mode. */
9088     switch (mod) {
9089     case 0:
9090         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9091             u32 destval;
9092 
9093             DECODE_PRINTF("DWORD PTR ");
9094             destoffset = decode_rm00_address(rl);
9095             DECODE_PRINTF(",1\n");
9096             destval = fetch_data_long(destoffset);
9097             TRACE_AND_STEP();
9098             destval = (*opcD1_long_operation[rh]) (destval, 1);
9099             store_data_long(destoffset, destval);
9100         } else {
9101             u16 destval;
9102 
9103             DECODE_PRINTF("WORD PTR ");
9104             destoffset = decode_rm00_address(rl);
9105             DECODE_PRINTF(",1\n");
9106             destval = fetch_data_word(destoffset);
9107             TRACE_AND_STEP();
9108             destval = (*opcD1_word_operation[rh]) (destval, 1);
9109             store_data_word(destoffset, destval);
9110         }
9111         break;
9112     case 1:
9113         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9114             u32 destval;
9115 
9116             DECODE_PRINTF("DWORD PTR ");
9117             destoffset = decode_rm01_address(rl);
9118             DECODE_PRINTF(",1\n");
9119             destval = fetch_data_long(destoffset);
9120             TRACE_AND_STEP();
9121             destval = (*opcD1_long_operation[rh]) (destval, 1);
9122             store_data_long(destoffset, destval);
9123         } else {
9124             u16 destval;
9125 
9126             DECODE_PRINTF("WORD PTR ");
9127             destoffset = decode_rm01_address(rl);
9128             DECODE_PRINTF(",1\n");
9129             destval = fetch_data_word(destoffset);
9130             TRACE_AND_STEP();
9131             destval = (*opcD1_word_operation[rh]) (destval, 1);
9132             store_data_word(destoffset, destval);
9133         }
9134         break;
9135     case 2:
9136         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9137             u32 destval;
9138 
9139             DECODE_PRINTF("DWORD PTR ");
9140             destoffset = decode_rm10_address(rl);
9141             DECODE_PRINTF(",1\n");
9142             destval = fetch_data_long(destoffset);
9143             TRACE_AND_STEP();
9144             destval = (*opcD1_long_operation[rh]) (destval, 1);
9145             store_data_long(destoffset, destval);
9146         } else {
9147             u16 destval;
9148 
9149             DECODE_PRINTF("BYTE PTR ");
9150             destoffset = decode_rm10_address(rl);
9151             DECODE_PRINTF(",1\n");
9152             destval = fetch_data_word(destoffset);
9153             TRACE_AND_STEP();
9154             destval = (*opcD1_word_operation[rh]) (destval, 1);
9155             store_data_word(destoffset, destval);
9156         }
9157         break;
9158     case 3:                     /* register to register */
9159         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9160             u32 destval;
9161             u32 *destreg;
9162 
9163             destreg = DECODE_RM_LONG_REGISTER(rl);
9164             DECODE_PRINTF(",1\n");
9165             TRACE_AND_STEP();
9166             destval = (*opcD1_long_operation[rh]) (*destreg, 1);
9167             *destreg = destval;
9168         } else {
9169             u16 destval;
9170             u16 *destreg;
9171 
9172             destreg = DECODE_RM_WORD_REGISTER(rl);
9173             DECODE_PRINTF(",1\n");
9174             TRACE_AND_STEP();
9175             destval = (*opcD1_word_operation[rh]) (*destreg, 1);
9176             *destreg = destval;
9177         }
9178         break;
9179     }
9180     DECODE_CLEAR_SEGOVR();
9181     END_OF_INSTR();
9182 }
9183 
9184 /****************************************************************************
9185 REMARKS:
9186 Handles opcode 0xd2
9187 ****************************************************************************/
x86emuOp_opcD2_byte_RM_CL(u8 X86EMU_UNUSED (op1))9188 void x86emuOp_opcD2_byte_RM_CL(u8 X86EMU_UNUSED(op1))
9189 {
9190     int mod, rl, rh;
9191     u8 *destreg;
9192     uint destoffset;
9193     u8 destval;
9194     u8 amt;
9195 
9196     /*
9197      * Yet another weirdo special case instruction format.  Part of
9198      * the opcode held below in "RH".  Doubly nested case would
9199      * result, except that the decoded instruction
9200      */
9201     START_OF_INSTR();
9202     FETCH_DECODE_MODRM(mod, rh, rl);
9203 #ifdef DEBUG
9204     if (DEBUG_DECODE()) {
9205         /* XXX DECODE_PRINTF may be changed to something more
9206            general, so that it is important to leave the strings
9207            in the same format, even though the result is that the
9208            above test is done twice. */
9209         switch (rh) {
9210         case 0:
9211             DECODE_PRINTF("ROL\t");
9212             break;
9213         case 1:
9214             DECODE_PRINTF("ROR\t");
9215             break;
9216         case 2:
9217             DECODE_PRINTF("RCL\t");
9218             break;
9219         case 3:
9220             DECODE_PRINTF("RCR\t");
9221             break;
9222         case 4:
9223             DECODE_PRINTF("SHL\t");
9224             break;
9225         case 5:
9226             DECODE_PRINTF("SHR\t");
9227             break;
9228         case 6:
9229             DECODE_PRINTF("SAL\t");
9230             break;
9231         case 7:
9232             DECODE_PRINTF("SAR\t");
9233             break;
9234         }
9235     }
9236 #endif
9237     /* know operation, decode the mod byte to find the addressing
9238        mode. */
9239     amt = M.x86.R_CL;
9240     switch (mod) {
9241     case 0:
9242         DECODE_PRINTF("BYTE PTR ");
9243         destoffset = decode_rm00_address(rl);
9244         DECODE_PRINTF(",CL\n");
9245         destval = fetch_data_byte(destoffset);
9246         TRACE_AND_STEP();
9247         destval = (*opcD0_byte_operation[rh]) (destval, amt);
9248         store_data_byte(destoffset, destval);
9249         break;
9250     case 1:
9251         DECODE_PRINTF("BYTE PTR ");
9252         destoffset = decode_rm01_address(rl);
9253         DECODE_PRINTF(",CL\n");
9254         destval = fetch_data_byte(destoffset);
9255         TRACE_AND_STEP();
9256         destval = (*opcD0_byte_operation[rh]) (destval, amt);
9257         store_data_byte(destoffset, destval);
9258         break;
9259     case 2:
9260         DECODE_PRINTF("BYTE PTR ");
9261         destoffset = decode_rm10_address(rl);
9262         DECODE_PRINTF(",CL\n");
9263         destval = fetch_data_byte(destoffset);
9264         TRACE_AND_STEP();
9265         destval = (*opcD0_byte_operation[rh]) (destval, amt);
9266         store_data_byte(destoffset, destval);
9267         break;
9268     case 3:                     /* register to register */
9269         destreg = DECODE_RM_BYTE_REGISTER(rl);
9270         DECODE_PRINTF(",CL\n");
9271         TRACE_AND_STEP();
9272         destval = (*opcD0_byte_operation[rh]) (*destreg, amt);
9273         *destreg = destval;
9274         break;
9275     }
9276     DECODE_CLEAR_SEGOVR();
9277     END_OF_INSTR();
9278 }
9279 
9280 /****************************************************************************
9281 REMARKS:
9282 Handles opcode 0xd3
9283 ****************************************************************************/
x86emuOp_opcD3_word_RM_CL(u8 X86EMU_UNUSED (op1))9284 void x86emuOp_opcD3_word_RM_CL(u8 X86EMU_UNUSED(op1))
9285 {
9286     int mod, rl, rh;
9287     uint destoffset;
9288     u8 amt;
9289 
9290     /*
9291      * Yet another weirdo special case instruction format.  Part of
9292      * the opcode held below in "RH".  Doubly nested case would
9293      * result, except that the decoded instruction
9294      */
9295     START_OF_INSTR();
9296     FETCH_DECODE_MODRM(mod, rh, rl);
9297 #ifdef DEBUG
9298     if (DEBUG_DECODE()) {
9299         /* XXX DECODE_PRINTF may be changed to something more
9300            general, so that it is important to leave the strings
9301            in the same format, even though the result is that the
9302            above test is done twice. */
9303         switch (rh) {
9304         case 0:
9305             DECODE_PRINTF("ROL\t");
9306             break;
9307         case 1:
9308             DECODE_PRINTF("ROR\t");
9309             break;
9310         case 2:
9311             DECODE_PRINTF("RCL\t");
9312             break;
9313         case 3:
9314             DECODE_PRINTF("RCR\t");
9315             break;
9316         case 4:
9317             DECODE_PRINTF("SHL\t");
9318             break;
9319         case 5:
9320             DECODE_PRINTF("SHR\t");
9321             break;
9322         case 6:
9323             DECODE_PRINTF("SAL\t");
9324             break;
9325         case 7:
9326             DECODE_PRINTF("SAR\t");
9327             break;
9328         }
9329     }
9330 #endif
9331     /* know operation, decode the mod byte to find the addressing
9332        mode. */
9333     amt = M.x86.R_CL;
9334     switch (mod) {
9335     case 0:
9336         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9337             u32 destval;
9338 
9339             DECODE_PRINTF("DWORD PTR ");
9340             destoffset = decode_rm00_address(rl);
9341             DECODE_PRINTF(",CL\n");
9342             destval = fetch_data_long(destoffset);
9343             TRACE_AND_STEP();
9344             destval = (*opcD1_long_operation[rh]) (destval, amt);
9345             store_data_long(destoffset, destval);
9346         } else {
9347             u16 destval;
9348 
9349             DECODE_PRINTF("WORD PTR ");
9350             destoffset = decode_rm00_address(rl);
9351             DECODE_PRINTF(",CL\n");
9352             destval = fetch_data_word(destoffset);
9353             TRACE_AND_STEP();
9354             destval = (*opcD1_word_operation[rh]) (destval, amt);
9355             store_data_word(destoffset, destval);
9356         }
9357         break;
9358     case 1:
9359         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9360             u32 destval;
9361 
9362             DECODE_PRINTF("DWORD PTR ");
9363             destoffset = decode_rm01_address(rl);
9364             DECODE_PRINTF(",CL\n");
9365             destval = fetch_data_long(destoffset);
9366             TRACE_AND_STEP();
9367             destval = (*opcD1_long_operation[rh]) (destval, amt);
9368             store_data_long(destoffset, destval);
9369         } else {
9370             u16 destval;
9371 
9372             DECODE_PRINTF("WORD PTR ");
9373             destoffset = decode_rm01_address(rl);
9374             DECODE_PRINTF(",CL\n");
9375             destval = fetch_data_word(destoffset);
9376             TRACE_AND_STEP();
9377             destval = (*opcD1_word_operation[rh]) (destval, amt);
9378             store_data_word(destoffset, destval);
9379         }
9380         break;
9381     case 2:
9382         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9383             u32 destval;
9384 
9385             DECODE_PRINTF("DWORD PTR ");
9386             destoffset = decode_rm10_address(rl);
9387             DECODE_PRINTF(",CL\n");
9388             destval = fetch_data_long(destoffset);
9389             TRACE_AND_STEP();
9390             destval = (*opcD1_long_operation[rh]) (destval, amt);
9391             store_data_long(destoffset, destval);
9392         } else {
9393             u16 destval;
9394 
9395             DECODE_PRINTF("WORD PTR ");
9396             destoffset = decode_rm10_address(rl);
9397             DECODE_PRINTF(",CL\n");
9398             destval = fetch_data_word(destoffset);
9399             TRACE_AND_STEP();
9400             destval = (*opcD1_word_operation[rh]) (destval, amt);
9401             store_data_word(destoffset, destval);
9402         }
9403         break;
9404     case 3:                     /* register to register */
9405         if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9406             u32 *destreg;
9407 
9408             destreg = DECODE_RM_LONG_REGISTER(rl);
9409             DECODE_PRINTF(",CL\n");
9410             TRACE_AND_STEP();
9411             *destreg = (*opcD1_long_operation[rh]) (*destreg, amt);
9412         } else {
9413             u16 *destreg;
9414 
9415             destreg = DECODE_RM_WORD_REGISTER(rl);
9416             DECODE_PRINTF(",CL\n");
9417             TRACE_AND_STEP();
9418             *destreg = (*opcD1_word_operation[rh]) (*destreg, amt);
9419         }
9420         break;
9421     }
9422     DECODE_CLEAR_SEGOVR();
9423     END_OF_INSTR();
9424 }
9425 
9426 /****************************************************************************
9427 REMARKS:
9428 Handles opcode 0xd4
9429 ****************************************************************************/
x86emuOp_aam(u8 X86EMU_UNUSED (op1))9430 void x86emuOp_aam(u8 X86EMU_UNUSED(op1))
9431 {
9432     u8 a;
9433 
9434     START_OF_INSTR();
9435     DECODE_PRINTF("AAM\n");
9436     a = fetch_byte_imm();      /* this is a stupid encoding. */
9437     if (a != 10) {
9438         DECODE_PRINTF("ERROR DECODING AAM\n");
9439         TRACE_REGS();
9440         HALT_SYS();
9441     }
9442     TRACE_AND_STEP();
9443     /* note the type change here --- returning AL and AH in AX. */
9444     M.x86.R_AX = aam_word(M.x86.R_AL);
9445     DECODE_CLEAR_SEGOVR();
9446     END_OF_INSTR();
9447 }
9448 
9449 /****************************************************************************
9450 REMARKS:
9451 Handles opcode 0xd5
9452 ****************************************************************************/
x86emuOp_aad(u8 X86EMU_UNUSED (op1))9453 void x86emuOp_aad(u8 X86EMU_UNUSED(op1))
9454 {
9455     u8 a;
9456 
9457     START_OF_INSTR();
9458     DECODE_PRINTF("AAD\n");
9459     a = fetch_byte_imm();
9460     TRACE_AND_STEP();
9461     M.x86.R_AX = aad_word(M.x86.R_AX);
9462     DECODE_CLEAR_SEGOVR();
9463     END_OF_INSTR();
9464 }
9465 
9466 /* opcode 0xd6 ILLEGAL OPCODE */
9467 
9468 /****************************************************************************
9469 REMARKS:
9470 Handles opcode 0xd7
9471 ****************************************************************************/
x86emuOp_xlat(u8 X86EMU_UNUSED (op1))9472 void x86emuOp_xlat(u8 X86EMU_UNUSED(op1))
9473 {
9474     u16 addr;
9475 
9476     START_OF_INSTR();
9477     DECODE_PRINTF("XLAT\n");
9478     TRACE_AND_STEP();
9479     addr = (u16)(M.x86.R_BX + (u8)M.x86.R_AL);
9480     M.x86.R_AL = fetch_data_byte(addr);
9481     DECODE_CLEAR_SEGOVR();
9482     END_OF_INSTR();
9483 }
9484 
9485 /* instuctions  D8 .. DF are in i87_ops.c */
9486 
9487 /****************************************************************************
9488 REMARKS:
9489 Handles opcode 0xe0
9490 ****************************************************************************/
x86emuOp_loopne(u8 X86EMU_UNUSED (op1))9491 void x86emuOp_loopne(u8 X86EMU_UNUSED(op1))
9492 {
9493     s16 ip;
9494 
9495     START_OF_INSTR();
9496     DECODE_PRINTF("LOOPNE\t");
9497     ip = (s8) fetch_byte_imm();
9498     ip += (s16) M.x86.R_IP;
9499     DECODE_PRINTF2("%04x\n", ip);
9500     TRACE_AND_STEP();
9501     M.x86.R_CX -= 1;
9502     if (M.x86.R_CX != 0 && !ACCESS_FLAG(F_ZF))      /* CX != 0 and !ZF */
9503         M.x86.R_IP = ip;
9504     DECODE_CLEAR_SEGOVR();
9505     END_OF_INSTR();
9506 }
9507 
9508 /****************************************************************************
9509 REMARKS:
9510 Handles opcode 0xe1
9511 ****************************************************************************/
x86emuOp_loope(u8 X86EMU_UNUSED (op1))9512 void x86emuOp_loope(u8 X86EMU_UNUSED(op1))
9513 {
9514     s16 ip;
9515 
9516     START_OF_INSTR();
9517     DECODE_PRINTF("LOOPE\t");
9518     ip = (s8) fetch_byte_imm();
9519     ip += (s16) M.x86.R_IP;
9520     DECODE_PRINTF2("%04x\n", ip);
9521     TRACE_AND_STEP();
9522     M.x86.R_CX -= 1;
9523     if (M.x86.R_CX != 0 && ACCESS_FLAG(F_ZF))       /* CX != 0 and ZF */
9524         M.x86.R_IP = ip;
9525     DECODE_CLEAR_SEGOVR();
9526     END_OF_INSTR();
9527 }
9528 
9529 /****************************************************************************
9530 REMARKS:
9531 Handles opcode 0xe2
9532 ****************************************************************************/
x86emuOp_loop(u8 X86EMU_UNUSED (op1))9533 void x86emuOp_loop(u8 X86EMU_UNUSED(op1))
9534 {
9535     s16 ip;
9536 
9537     START_OF_INSTR();
9538     DECODE_PRINTF("LOOP\t");
9539     ip = (s8) fetch_byte_imm();
9540     ip += (s16) M.x86.R_IP;
9541     DECODE_PRINTF2("%04x\n", ip);
9542     TRACE_AND_STEP();
9543     M.x86.R_CX -= 1;
9544     if (M.x86.R_CX != 0)
9545         M.x86.R_IP = ip;
9546     DECODE_CLEAR_SEGOVR();
9547     END_OF_INSTR();
9548 }
9549 
9550 /****************************************************************************
9551 REMARKS:
9552 Handles opcode 0xe3
9553 ****************************************************************************/
x86emuOp_jcxz(u8 X86EMU_UNUSED (op1))9554 void x86emuOp_jcxz(u8 X86EMU_UNUSED(op1))
9555 {
9556     u16 target;
9557     s8  offset;
9558 
9559     /* jump to byte offset if overflow flag is set */
9560     START_OF_INSTR();
9561     DECODE_PRINTF("JCXZ\t");
9562     offset = (s8)fetch_byte_imm();
9563     target = (u16)(M.x86.R_IP + offset);
9564     DECODE_PRINTF2("%x\n", target);
9565     TRACE_AND_STEP();
9566     if (M.x86.R_CX == 0)
9567         M.x86.R_IP = target;
9568     DECODE_CLEAR_SEGOVR();
9569     END_OF_INSTR();
9570 }
9571 
9572 /****************************************************************************
9573 REMARKS:
9574 Handles opcode 0xe4
9575 ****************************************************************************/
x86emuOp_in_byte_AL_IMM(u8 X86EMU_UNUSED (op1))9576 void x86emuOp_in_byte_AL_IMM(u8 X86EMU_UNUSED(op1))
9577 {
9578     u8 port;
9579 
9580     START_OF_INSTR();
9581     DECODE_PRINTF("IN\t");
9582     port = (u8) fetch_byte_imm();
9583     DECODE_PRINTF2("%x,AL\n", port);
9584     TRACE_AND_STEP();
9585     M.x86.R_AL = (*sys_inb)(port);
9586     DECODE_CLEAR_SEGOVR();
9587     END_OF_INSTR();
9588 }
9589 
9590 /****************************************************************************
9591 REMARKS:
9592 Handles opcode 0xe5
9593 ****************************************************************************/
x86emuOp_in_word_AX_IMM(u8 X86EMU_UNUSED (op1))9594 void x86emuOp_in_word_AX_IMM(u8 X86EMU_UNUSED(op1))
9595 {
9596     u8 port;
9597 
9598     START_OF_INSTR();
9599     DECODE_PRINTF("IN\t");
9600     port = (u8) fetch_byte_imm();
9601     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9602         DECODE_PRINTF2("EAX,%x\n", port);
9603     } else {
9604         DECODE_PRINTF2("AX,%x\n", port);
9605     }
9606     TRACE_AND_STEP();
9607     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9608         M.x86.R_EAX = (*sys_inl)(port);
9609     } else {
9610         M.x86.R_AX = (*sys_inw)(port);
9611     }
9612     DECODE_CLEAR_SEGOVR();
9613     END_OF_INSTR();
9614 }
9615 
9616 /****************************************************************************
9617 REMARKS:
9618 Handles opcode 0xe6
9619 ****************************************************************************/
x86emuOp_out_byte_IMM_AL(u8 X86EMU_UNUSED (op1))9620 void x86emuOp_out_byte_IMM_AL(u8 X86EMU_UNUSED(op1))
9621 {
9622     u8 port;
9623 
9624     START_OF_INSTR();
9625     DECODE_PRINTF("OUT\t");
9626     port = (u8) fetch_byte_imm();
9627     DECODE_PRINTF2("%x,AL\n", port);
9628     TRACE_AND_STEP();
9629     (*sys_outb)(port, M.x86.R_AL);
9630     DECODE_CLEAR_SEGOVR();
9631     END_OF_INSTR();
9632 }
9633 
9634 /****************************************************************************
9635 REMARKS:
9636 Handles opcode 0xe7
9637 ****************************************************************************/
x86emuOp_out_word_IMM_AX(u8 X86EMU_UNUSED (op1))9638 void x86emuOp_out_word_IMM_AX(u8 X86EMU_UNUSED(op1))
9639 {
9640     u8 port;
9641 
9642     START_OF_INSTR();
9643     DECODE_PRINTF("OUT\t");
9644     port = (u8) fetch_byte_imm();
9645     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9646         DECODE_PRINTF2("%x,EAX\n", port);
9647     } else {
9648         DECODE_PRINTF2("%x,AX\n", port);
9649     }
9650     TRACE_AND_STEP();
9651     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9652         (*sys_outl)(port, M.x86.R_EAX);
9653     } else {
9654         (*sys_outw)(port, M.x86.R_AX);
9655     }
9656     DECODE_CLEAR_SEGOVR();
9657     END_OF_INSTR();
9658 }
9659 
9660 /****************************************************************************
9661 REMARKS:
9662 Handles opcode 0xe8
9663 ****************************************************************************/
x86emuOp_call_near_IMM(u8 X86EMU_UNUSED (op1))9664 void x86emuOp_call_near_IMM(u8 X86EMU_UNUSED(op1))
9665 {
9666     s16 ip;
9667 
9668     START_OF_INSTR();
9669     DECODE_PRINTF("CALL\t");
9670     ip = (s16) fetch_word_imm();
9671     ip += (s16) M.x86.R_IP;    /* CHECK SIGN */
9672     DECODE_PRINTF2("%04x\n", ip);
9673     CALL_TRACE(M.x86.saved_cs, M.x86.saved_ip, M.x86.R_CS, ip, "");
9674     TRACE_AND_STEP();
9675     push_word(M.x86.R_IP);
9676     M.x86.R_IP = ip;
9677     DECODE_CLEAR_SEGOVR();
9678     END_OF_INSTR();
9679 }
9680 
9681 /****************************************************************************
9682 REMARKS:
9683 Handles opcode 0xe9
9684 ****************************************************************************/
x86emuOp_jump_near_IMM(u8 X86EMU_UNUSED (op1))9685 void x86emuOp_jump_near_IMM(u8 X86EMU_UNUSED(op1))
9686 {
9687     int ip;
9688 
9689     START_OF_INSTR();
9690     DECODE_PRINTF("JMP\t");
9691     ip = (s16)fetch_word_imm();
9692     ip += (s16)M.x86.R_IP;
9693     DECODE_PRINTF2("%04x\n", ip);
9694     TRACE_AND_STEP();
9695     M.x86.R_IP = (u16)ip;
9696     DECODE_CLEAR_SEGOVR();
9697     END_OF_INSTR();
9698 }
9699 
9700 /****************************************************************************
9701 REMARKS:
9702 Handles opcode 0xea
9703 ****************************************************************************/
x86emuOp_jump_far_IMM(u8 X86EMU_UNUSED (op1))9704 void x86emuOp_jump_far_IMM(u8 X86EMU_UNUSED(op1))
9705 {
9706     u16 cs, ip;
9707 
9708     START_OF_INSTR();
9709     DECODE_PRINTF("JMP\tFAR ");
9710     ip = fetch_word_imm();
9711     cs = fetch_word_imm();
9712     DECODE_PRINTF2("%04x:", cs);
9713     DECODE_PRINTF2("%04x\n", ip);
9714     TRACE_AND_STEP();
9715     M.x86.R_IP = ip;
9716     M.x86.R_CS = cs;
9717     DECODE_CLEAR_SEGOVR();
9718     END_OF_INSTR();
9719 }
9720 
9721 /****************************************************************************
9722 REMARKS:
9723 Handles opcode 0xeb
9724 ****************************************************************************/
x86emuOp_jump_byte_IMM(u8 X86EMU_UNUSED (op1))9725 void x86emuOp_jump_byte_IMM(u8 X86EMU_UNUSED(op1))
9726 {
9727     u16 target;
9728     s8 offset;
9729 
9730     START_OF_INSTR();
9731     DECODE_PRINTF("JMP\t");
9732     offset = (s8)fetch_byte_imm();
9733     target = (u16)(M.x86.R_IP + offset);
9734     DECODE_PRINTF2("%x\n", target);
9735     TRACE_AND_STEP();
9736     M.x86.R_IP = target;
9737     DECODE_CLEAR_SEGOVR();
9738     END_OF_INSTR();
9739 }
9740 
9741 /****************************************************************************
9742 REMARKS:
9743 Handles opcode 0xec
9744 ****************************************************************************/
x86emuOp_in_byte_AL_DX(u8 X86EMU_UNUSED (op1))9745 void x86emuOp_in_byte_AL_DX(u8 X86EMU_UNUSED(op1))
9746 {
9747     START_OF_INSTR();
9748     DECODE_PRINTF("IN\tAL,DX\n");
9749     TRACE_AND_STEP();
9750     M.x86.R_AL = (*sys_inb)(M.x86.R_DX);
9751     DECODE_CLEAR_SEGOVR();
9752     END_OF_INSTR();
9753 }
9754 
9755 /****************************************************************************
9756 REMARKS:
9757 Handles opcode 0xed
9758 ****************************************************************************/
x86emuOp_in_word_AX_DX(u8 X86EMU_UNUSED (op1))9759 void x86emuOp_in_word_AX_DX(u8 X86EMU_UNUSED(op1))
9760 {
9761     START_OF_INSTR();
9762     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9763         DECODE_PRINTF("IN\tEAX,DX\n");
9764     } else {
9765         DECODE_PRINTF("IN\tAX,DX\n");
9766     }
9767     TRACE_AND_STEP();
9768     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9769         M.x86.R_EAX = (*sys_inl)(M.x86.R_DX);
9770     } else {
9771         M.x86.R_AX = (*sys_inw)(M.x86.R_DX);
9772     }
9773     DECODE_CLEAR_SEGOVR();
9774     END_OF_INSTR();
9775 }
9776 
9777 /****************************************************************************
9778 REMARKS:
9779 Handles opcode 0xee
9780 ****************************************************************************/
x86emuOp_out_byte_DX_AL(u8 X86EMU_UNUSED (op1))9781 void x86emuOp_out_byte_DX_AL(u8 X86EMU_UNUSED(op1))
9782 {
9783     START_OF_INSTR();
9784     DECODE_PRINTF("OUT\tDX,AL\n");
9785     TRACE_AND_STEP();
9786     (*sys_outb)(M.x86.R_DX, M.x86.R_AL);
9787     DECODE_CLEAR_SEGOVR();
9788     END_OF_INSTR();
9789 }
9790 
9791 /****************************************************************************
9792 REMARKS:
9793 Handles opcode 0xef
9794 ****************************************************************************/
x86emuOp_out_word_DX_AX(u8 X86EMU_UNUSED (op1))9795 void x86emuOp_out_word_DX_AX(u8 X86EMU_UNUSED(op1))
9796 {
9797     START_OF_INSTR();
9798     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9799         DECODE_PRINTF("OUT\tDX,EAX\n");
9800     } else {
9801         DECODE_PRINTF("OUT\tDX,AX\n");
9802     }
9803     TRACE_AND_STEP();
9804     if (M.x86.mode & SYSMODE_PREFIX_DATA) {
9805         (*sys_outl)(M.x86.R_DX, M.x86.R_EAX);
9806     } else {
9807         (*sys_outw)(M.x86.R_DX, M.x86.R_AX);
9808     }
9809     DECODE_CLEAR_SEGOVR();
9810     END_OF_INSTR();
9811 }
9812 
9813 /****************************************************************************
9814 REMARKS:
9815 Handles opcode 0xf0
9816 ****************************************************************************/
x86emuOp_lock(u8 X86EMU_UNUSED (op1))9817 void x86emuOp_lock(u8 X86EMU_UNUSED(op1))
9818 {
9819     START_OF_INSTR();
9820     DECODE_PRINTF("LOCK:\n");
9821     TRACE_AND_STEP();
9822     DECODE_CLEAR_SEGOVR();
9823     END_OF_INSTR();
9824 }
9825 
9826 /*opcode 0xf1 ILLEGAL OPERATION */
9827 
9828 /****************************************************************************
9829 REMARKS:
9830 Handles opcode 0xf2
9831 ****************************************************************************/
x86emuOp_repne(u8 X86EMU_UNUSED (op1))9832 void x86emuOp_repne(u8 X86EMU_UNUSED(op1))
9833 {
9834     START_OF_INSTR();
9835     DECODE_PRINTF("REPNE\n");
9836     TRACE_AND_STEP();
9837     M.x86.mode |= SYSMODE_PREFIX_REPNE;
9838     DECODE_CLEAR_SEGOVR();
9839     END_OF_INSTR();
9840 }
9841 
9842 /****************************************************************************
9843 REMARKS:
9844 Handles opcode 0xf3
9845 ****************************************************************************/
x86emuOp_repe(u8 X86EMU_UNUSED (op1))9846 void x86emuOp_repe(u8 X86EMU_UNUSED(op1))
9847 {
9848     START_OF_INSTR();
9849     DECODE_PRINTF("REPE\n");
9850     TRACE_AND_STEP();
9851     M.x86.mode |= SYSMODE_PREFIX_REPE;
9852     DECODE_CLEAR_SEGOVR();
9853     END_OF_INSTR();
9854 }
9855 
9856 /****************************************************************************
9857 REMARKS:
9858 Handles opcode 0xf4
9859 ****************************************************************************/
x86emuOp_halt(u8 X86EMU_UNUSED (op1))9860 void x86emuOp_halt(u8 X86EMU_UNUSED(op1))
9861 {
9862     START_OF_INSTR();
9863     DECODE_PRINTF("HALT\n");
9864     TRACE_AND_STEP();
9865     HALT_SYS();
9866     DECODE_CLEAR_SEGOVR();
9867     END_OF_INSTR();
9868 }
9869 
9870 /****************************************************************************
9871 REMARKS:
9872 Handles opcode 0xf5
9873 ****************************************************************************/
x86emuOp_cmc(u8 X86EMU_UNUSED (op1))9874 void x86emuOp_cmc(u8 X86EMU_UNUSED(op1))
9875 {
9876     /* complement the carry flag. */
9877     START_OF_INSTR();
9878     DECODE_PRINTF("CMC\n");
9879     TRACE_AND_STEP();
9880     TOGGLE_FLAG(F_CF);
9881     DECODE_CLEAR_SEGOVR();
9882     END_OF_INSTR();
9883 }
9884 
9885 /****************************************************************************
9886 REMARKS:
9887 Handles opcode 0xf6
9888 ****************************************************************************/
x86emuOp_opcF6_byte_RM(u8 X86EMU_UNUSED (op1))9889 void x86emuOp_opcF6_byte_RM(u8 X86EMU_UNUSED(op1))
9890 {
9891     int mod, rl, rh;
9892     u8 *destreg;
9893     uint destoffset;
9894     u8 destval, srcval;
9895 
9896     /* long, drawn out code follows.  Double switch for a total
9897        of 32 cases.  */
9898     START_OF_INSTR();
9899     FETCH_DECODE_MODRM(mod, rh, rl);
9900     switch (mod) {
9901     case 0:                     /* mod=00 */
9902         switch (rh) {
9903         case 0:         /* test byte imm */
9904             DECODE_PRINTF("TEST\tBYTE PTR ");
9905             destoffset = decode_rm00_address(rl);
9906             DECODE_PRINTF(",");
9907             srcval = fetch_byte_imm();
9908             DECODE_PRINTF2("%02x\n", srcval);
9909             destval = fetch_data_byte(destoffset);
9910             TRACE_AND_STEP();
9911             test_byte(destval, srcval);
9912             break;
9913         case 1:
9914             DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n");
9915             HALT_SYS();
9916             break;
9917         case 2:
9918             DECODE_PRINTF("NOT\tBYTE PTR ");
9919             destoffset = decode_rm00_address(rl);
9920             DECODE_PRINTF("\n");
9921             destval = fetch_data_byte(destoffset);
9922             TRACE_AND_STEP();
9923             destval = not_byte(destval);
9924             store_data_byte(destoffset, destval);
9925             break;
9926         case 3:
9927             DECODE_PRINTF("NEG\tBYTE PTR ");
9928             destoffset = decode_rm00_address(rl);
9929             DECODE_PRINTF("\n");
9930             destval = fetch_data_byte(destoffset);
9931             TRACE_AND_STEP();
9932             destval = neg_byte(destval);
9933             store_data_byte(destoffset, destval);
9934             break;
9935         case 4:
9936             DECODE_PRINTF("MUL\tBYTE PTR ");
9937             destoffset = decode_rm00_address(rl);
9938             DECODE_PRINTF("\n");
9939             destval = fetch_data_byte(destoffset);
9940             TRACE_AND_STEP();
9941             mul_byte(destval);
9942             break;
9943         case 5:
9944             DECODE_PRINTF("IMUL\tBYTE PTR ");
9945             destoffset = decode_rm00_address(rl);
9946             DECODE_PRINTF("\n");
9947             destval = fetch_data_byte(destoffset);
9948             TRACE_AND_STEP();
9949             imul_byte(destval);
9950             break;
9951         case 6:
9952             DECODE_PRINTF("DIV\tBYTE PTR ");
9953             destoffset = decode_rm00_address(rl);
9954             DECODE_PRINTF("\n");
9955             destval = fetch_data_byte(destoffset);
9956             TRACE_AND_STEP();
9957             div_byte(destval);
9958             break;
9959         case 7:
9960             DECODE_PRINTF("IDIV\tBYTE PTR ");
9961             destoffset = decode_rm00_address(rl);
9962             DECODE_PRINTF("\n");
9963             destval = fetch_data_byte(destoffset);
9964             TRACE_AND_STEP();
9965             idiv_byte(destval);
9966             break;
9967         }
9968         break;                  /* end mod==00 */
9969     case 1:                     /* mod=01 */
9970         switch (rh) {
9971         case 0:         /* test byte imm */
9972             DECODE_PRINTF("TEST\tBYTE PTR ");
9973             destoffset = decode_rm01_address(rl);
9974             DECODE_PRINTF(",");
9975             srcval = fetch_byte_imm();
9976             DECODE_PRINTF2("%02x\n", srcval);
9977             destval = fetch_data_byte(destoffset);
9978             TRACE_AND_STEP();
9979             test_byte(destval, srcval);
9980             break;
9981         case 1:
9982             DECODE_PRINTF("ILLEGAL OP MOD=01 RH=01 OP=F6\n");
9983             HALT_SYS();
9984             break;
9985         case 2:
9986             DECODE_PRINTF("NOT\tBYTE PTR ");
9987             destoffset = decode_rm01_address(rl);
9988             DECODE_PRINTF("\n");
9989             destval = fetch_data_byte(destoffset);
9990             TRACE_AND_STEP();
9991             destval = not_byte(destval);
9992             store_data_byte(destoffset, destval);
9993             break;
9994         case 3:
9995             DECODE_PRINTF("NEG\tBYTE PTR ");
9996             destoffset = decode_rm01_address(rl);
9997             DECODE_PRINTF("\n");
9998             destval = fetch_data_byte(destoffset);
9999             TRACE_AND_STEP();
10000             destval = neg_byte(destval);
10001             store_data_byte(destoffset, destval);
10002             break;
10003         case 4:
10004             DECODE_PRINTF("MUL\tBYTE PTR ");
10005             destoffset = decode_rm01_address(rl);
10006             DECODE_PRINTF("\n");
10007             destval = fetch_data_byte(destoffset);
10008             TRACE_AND_STEP();
10009             mul_byte(destval);
10010             break;
10011         case 5:
10012             DECODE_PRINTF("IMUL\tBYTE PTR ");
10013             destoffset = decode_rm01_address(rl);
10014             DECODE_PRINTF("\n");
10015             destval = fetch_data_byte(destoffset);
10016             TRACE_AND_STEP();
10017             imul_byte(destval);
10018             break;
10019         case 6:
10020             DECODE_PRINTF("DIV\tBYTE PTR ");
10021             destoffset = decode_rm01_address(rl);
10022             DECODE_PRINTF("\n");
10023             destval = fetch_data_byte(destoffset);
10024             TRACE_AND_STEP();
10025             div_byte(destval);
10026             break;
10027         case 7:
10028             DECODE_PRINTF("IDIV\tBYTE PTR ");
10029             destoffset = decode_rm01_address(rl);
10030             DECODE_PRINTF("\n");
10031             destval = fetch_data_byte(destoffset);
10032             TRACE_AND_STEP();
10033             idiv_byte(destval);
10034             break;
10035         }
10036         break;                  /* end mod==01 */
10037     case 2:                     /* mod=10 */
10038         switch (rh) {
10039         case 0:         /* test byte imm */
10040             DECODE_PRINTF("TEST\tBYTE PTR ");
10041             destoffset = decode_rm10_address(rl);
10042             DECODE_PRINTF(",");
10043             srcval = fetch_byte_imm();
10044             DECODE_PRINTF2("%02x\n", srcval);
10045             destval = fetch_data_byte(destoffset);
10046             TRACE_AND_STEP();
10047             test_byte(destval, srcval);
10048             break;
10049         case 1:
10050             DECODE_PRINTF("ILLEGAL OP MOD=10 RH=01 OP=F6\n");
10051             HALT_SYS();
10052             break;
10053         case 2:
10054             DECODE_PRINTF("NOT\tBYTE PTR ");
10055             destoffset = decode_rm10_address(rl);
10056             DECODE_PRINTF("\n");
10057             destval = fetch_data_byte(destoffset);
10058             TRACE_AND_STEP();
10059             destval = not_byte(destval);
10060             store_data_byte(destoffset, destval);
10061             break;
10062         case 3:
10063             DECODE_PRINTF("NEG\tBYTE PTR ");
10064             destoffset = decode_rm10_address(rl);
10065             DECODE_PRINTF("\n");
10066             destval = fetch_data_byte(destoffset);
10067             TRACE_AND_STEP();
10068             destval = neg_byte(destval);
10069             store_data_byte(destoffset, destval);
10070             break;
10071         case 4:
10072             DECODE_PRINTF("MUL\tBYTE PTR ");
10073             destoffset = decode_rm10_address(rl);
10074             DECODE_PRINTF("\n");
10075             destval = fetch_data_byte(destoffset);
10076             TRACE_AND_STEP();
10077             mul_byte(destval);
10078             break;
10079         case 5:
10080             DECODE_PRINTF("IMUL\tBYTE PTR ");
10081             destoffset = decode_rm10_address(rl);
10082             DECODE_PRINTF("\n");
10083             destval = fetch_data_byte(destoffset);
10084             TRACE_AND_STEP();
10085             imul_byte(destval);
10086             break;
10087         case 6:
10088             DECODE_PRINTF("DIV\tBYTE PTR ");
10089             destoffset = decode_rm10_address(rl);
10090             DECODE_PRINTF("\n");
10091             destval = fetch_data_byte(destoffset);
10092             TRACE_AND_STEP();
10093             div_byte(destval);
10094             break;
10095         case 7:
10096             DECODE_PRINTF("IDIV\tBYTE PTR ");
10097             destoffset = decode_rm10_address(rl);
10098             DECODE_PRINTF("\n");
10099             destval = fetch_data_byte(destoffset);
10100             TRACE_AND_STEP();
10101             idiv_byte(destval);
10102             break;
10103         }
10104         break;                  /* end mod==10 */
10105     case 3:                     /* mod=11 */
10106         switch (rh) {
10107         case 0:         /* test byte imm */
10108             DECODE_PRINTF("TEST\t");
10109             destreg = DECODE_RM_BYTE_REGISTER(rl);
10110             DECODE_PRINTF(",");
10111             srcval = fetch_byte_imm();
10112             DECODE_PRINTF2("%02x\n", srcval);
10113             TRACE_AND_STEP();
10114             test_byte(*destreg, srcval);
10115             break;
10116         case 1:
10117             DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n");
10118             HALT_SYS();
10119             break;
10120         case 2:
10121             DECODE_PRINTF("NOT\t");
10122             destreg = DECODE_RM_BYTE_REGISTER(rl);
10123             DECODE_PRINTF("\n");
10124             TRACE_AND_STEP();
10125             *destreg = not_byte(*destreg);
10126             break;
10127         case 3:
10128             DECODE_PRINTF("NEG\t");
10129             destreg = DECODE_RM_BYTE_REGISTER(rl);
10130             DECODE_PRINTF("\n");
10131             TRACE_AND_STEP();
10132             *destreg = neg_byte(*destreg);
10133             break;
10134         case 4:
10135             DECODE_PRINTF("MUL\t");
10136             destreg = DECODE_RM_BYTE_REGISTER(rl);
10137             DECODE_PRINTF("\n");
10138             TRACE_AND_STEP();
10139             mul_byte(*destreg);      /*!!!  */
10140             break;
10141         case 5:
10142             DECODE_PRINTF("IMUL\t");
10143             destreg = DECODE_RM_BYTE_REGISTER(rl);
10144             DECODE_PRINTF("\n");
10145             TRACE_AND_STEP();
10146             imul_byte(*destreg);
10147             break;
10148         case 6:
10149             DECODE_PRINTF("DIV\t");
10150             destreg = DECODE_RM_BYTE_REGISTER(rl);
10151             DECODE_PRINTF("\n");
10152             TRACE_AND_STEP();
10153             div_byte(*destreg);
10154             break;
10155         case 7:
10156             DECODE_PRINTF("IDIV\t");
10157             destreg = DECODE_RM_BYTE_REGISTER(rl);
10158             DECODE_PRINTF("\n");
10159             TRACE_AND_STEP();
10160             idiv_byte(*destreg);
10161             break;
10162         }
10163         break;                  /* end mod==11 */
10164     }
10165     DECODE_CLEAR_SEGOVR();
10166     END_OF_INSTR();
10167 }
10168 
10169 /****************************************************************************
10170 REMARKS:
10171 Handles opcode 0xf7
10172 ****************************************************************************/
x86emuOp_opcF7_word_RM(u8 X86EMU_UNUSED (op1))10173 void x86emuOp_opcF7_word_RM(u8 X86EMU_UNUSED(op1))
10174 {
10175     int mod, rl, rh;
10176     uint destoffset;
10177 
10178     /* long, drawn out code follows.  Double switch for a total
10179        of 32 cases.  */
10180     START_OF_INSTR();
10181     FETCH_DECODE_MODRM(mod, rh, rl);
10182     switch (mod) {
10183     case 0:                     /* mod=00 */
10184         switch (rh) {
10185         case 0:         /* test word imm */
10186             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10187                 u32 destval,srcval;
10188 
10189                 DECODE_PRINTF("TEST\tDWORD PTR ");
10190                 destoffset = decode_rm00_address(rl);
10191                 DECODE_PRINTF(",");
10192                 srcval = fetch_long_imm();
10193                 DECODE_PRINTF2("%x\n", srcval);
10194                 destval = fetch_data_long(destoffset);
10195                 TRACE_AND_STEP();
10196                 test_long(destval, srcval);
10197             } else {
10198                 u16 destval,srcval;
10199 
10200                 DECODE_PRINTF("TEST\tWORD PTR ");
10201                 destoffset = decode_rm00_address(rl);
10202                 DECODE_PRINTF(",");
10203                 srcval = fetch_word_imm();
10204                 DECODE_PRINTF2("%x\n", srcval);
10205                 destval = fetch_data_word(destoffset);
10206                 TRACE_AND_STEP();
10207                 test_word(destval, srcval);
10208             }
10209             break;
10210         case 1:
10211             DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F7\n");
10212             HALT_SYS();
10213             break;
10214         case 2:
10215             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10216                 u32 destval;
10217 
10218                 DECODE_PRINTF("NOT\tDWORD PTR ");
10219                 destoffset = decode_rm00_address(rl);
10220                 DECODE_PRINTF("\n");
10221                 destval = fetch_data_long(destoffset);
10222                 TRACE_AND_STEP();
10223                 destval = not_long(destval);
10224                 store_data_long(destoffset, destval);
10225             } else {
10226                 u16 destval;
10227 
10228                 DECODE_PRINTF("NOT\tWORD PTR ");
10229                 destoffset = decode_rm00_address(rl);
10230                 DECODE_PRINTF("\n");
10231                 destval = fetch_data_word(destoffset);
10232                 TRACE_AND_STEP();
10233                 destval = not_word(destval);
10234                 store_data_word(destoffset, destval);
10235             }
10236             break;
10237         case 3:
10238             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10239                 u32 destval;
10240 
10241                 DECODE_PRINTF("NEG\tDWORD PTR ");
10242                 destoffset = decode_rm00_address(rl);
10243                 DECODE_PRINTF("\n");
10244                 destval = fetch_data_long(destoffset);
10245                 TRACE_AND_STEP();
10246                 destval = neg_long(destval);
10247                 store_data_long(destoffset, destval);
10248             } else {
10249                 u16 destval;
10250 
10251                 DECODE_PRINTF("NEG\tWORD PTR ");
10252                 destoffset = decode_rm00_address(rl);
10253                 DECODE_PRINTF("\n");
10254                 destval = fetch_data_word(destoffset);
10255                 TRACE_AND_STEP();
10256                 destval = neg_word(destval);
10257                 store_data_word(destoffset, destval);
10258             }
10259             break;
10260         case 4:
10261             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10262                 u32 destval;
10263 
10264                 DECODE_PRINTF("MUL\tDWORD PTR ");
10265                 destoffset = decode_rm00_address(rl);
10266                 DECODE_PRINTF("\n");
10267                 destval = fetch_data_long(destoffset);
10268                 TRACE_AND_STEP();
10269                 mul_long(destval);
10270             } else {
10271                 u16 destval;
10272 
10273                 DECODE_PRINTF("MUL\tWORD PTR ");
10274                 destoffset = decode_rm00_address(rl);
10275                 DECODE_PRINTF("\n");
10276                 destval = fetch_data_word(destoffset);
10277                 TRACE_AND_STEP();
10278                 mul_word(destval);
10279             }
10280             break;
10281         case 5:
10282             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10283                 u32 destval;
10284 
10285                 DECODE_PRINTF("IMUL\tDWORD PTR ");
10286                 destoffset = decode_rm00_address(rl);
10287                 DECODE_PRINTF("\n");
10288                 destval = fetch_data_long(destoffset);
10289                 TRACE_AND_STEP();
10290                 imul_long(destval);
10291             } else {
10292                 u16 destval;
10293 
10294                 DECODE_PRINTF("IMUL\tWORD PTR ");
10295                 destoffset = decode_rm00_address(rl);
10296                 DECODE_PRINTF("\n");
10297                 destval = fetch_data_word(destoffset);
10298                 TRACE_AND_STEP();
10299                 imul_word(destval);
10300             }
10301             break;
10302         case 6:
10303             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10304                 u32 destval;
10305 
10306                 DECODE_PRINTF("DIV\tDWORD PTR ");
10307                 destoffset = decode_rm00_address(rl);
10308                 DECODE_PRINTF("\n");
10309                 destval = fetch_data_long(destoffset);
10310                 TRACE_AND_STEP();
10311                 div_long(destval);
10312             } else {
10313                 u16 destval;
10314 
10315                 DECODE_PRINTF("DIV\tWORD PTR ");
10316                 destoffset = decode_rm00_address(rl);
10317                 DECODE_PRINTF("\n");
10318                 destval = fetch_data_word(destoffset);
10319                 TRACE_AND_STEP();
10320                 div_word(destval);
10321             }
10322             break;
10323         case 7:
10324             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10325                 u32 destval;
10326 
10327                 DECODE_PRINTF("IDIV\tDWORD PTR ");
10328                 destoffset = decode_rm00_address(rl);
10329                 DECODE_PRINTF("\n");
10330                 destval = fetch_data_long(destoffset);
10331                 TRACE_AND_STEP();
10332                 idiv_long(destval);
10333             } else {
10334                 u16 destval;
10335 
10336                 DECODE_PRINTF("IDIV\tWORD PTR ");
10337                 destoffset = decode_rm00_address(rl);
10338                 DECODE_PRINTF("\n");
10339                 destval = fetch_data_word(destoffset);
10340                 TRACE_AND_STEP();
10341                 idiv_word(destval);
10342             }
10343             break;
10344         }
10345         break;                  /* end mod==00 */
10346     case 1:                     /* mod=01 */
10347         switch (rh) {
10348         case 0:         /* test word imm */
10349             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10350                 u32 destval,srcval;
10351 
10352                 DECODE_PRINTF("TEST\tDWORD PTR ");
10353                 destoffset = decode_rm01_address(rl);
10354                 DECODE_PRINTF(",");
10355                 srcval = fetch_long_imm();
10356                 DECODE_PRINTF2("%x\n", srcval);
10357                 destval = fetch_data_long(destoffset);
10358                 TRACE_AND_STEP();
10359                 test_long(destval, srcval);
10360             } else {
10361                 u16 destval,srcval;
10362 
10363                 DECODE_PRINTF("TEST\tWORD PTR ");
10364                 destoffset = decode_rm01_address(rl);
10365                 DECODE_PRINTF(",");
10366                 srcval = fetch_word_imm();
10367                 DECODE_PRINTF2("%x\n", srcval);
10368                 destval = fetch_data_word(destoffset);
10369                 TRACE_AND_STEP();
10370                 test_word(destval, srcval);
10371             }
10372             break;
10373         case 1:
10374             DECODE_PRINTF("ILLEGAL OP MOD=01 RH=01 OP=F6\n");
10375             HALT_SYS();
10376             break;
10377         case 2:
10378             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10379                 u32 destval;
10380 
10381                 DECODE_PRINTF("NOT\tDWORD PTR ");
10382                 destoffset = decode_rm01_address(rl);
10383                 DECODE_PRINTF("\n");
10384                 destval = fetch_data_long(destoffset);
10385                 TRACE_AND_STEP();
10386                 destval = not_long(destval);
10387                 store_data_long(destoffset, destval);
10388             } else {
10389                 u16 destval;
10390 
10391                 DECODE_PRINTF("NOT\tWORD PTR ");
10392                 destoffset = decode_rm01_address(rl);
10393                 DECODE_PRINTF("\n");
10394                 destval = fetch_data_word(destoffset);
10395                 TRACE_AND_STEP();
10396                 destval = not_word(destval);
10397                 store_data_word(destoffset, destval);
10398             }
10399             break;
10400         case 3:
10401             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10402                 u32 destval;
10403 
10404                 DECODE_PRINTF("NEG\tDWORD PTR ");
10405                 destoffset = decode_rm01_address(rl);
10406                 DECODE_PRINTF("\n");
10407                 destval = fetch_data_long(destoffset);
10408                 TRACE_AND_STEP();
10409                 destval = neg_long(destval);
10410                 store_data_long(destoffset, destval);
10411             } else {
10412                 u16 destval;
10413 
10414                 DECODE_PRINTF("NEG\tWORD PTR ");
10415                 destoffset = decode_rm01_address(rl);
10416                 DECODE_PRINTF("\n");
10417                 destval = fetch_data_word(destoffset);
10418                 TRACE_AND_STEP();
10419                 destval = neg_word(destval);
10420                 store_data_word(destoffset, destval);
10421             }
10422             break;
10423         case 4:
10424             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10425                 u32 destval;
10426 
10427                 DECODE_PRINTF("MUL\tDWORD PTR ");
10428                 destoffset = decode_rm01_address(rl);
10429                 DECODE_PRINTF("\n");
10430                 destval = fetch_data_long(destoffset);
10431                 TRACE_AND_STEP();
10432                 mul_long(destval);
10433             } else {
10434                 u16 destval;
10435 
10436                 DECODE_PRINTF("MUL\tWORD PTR ");
10437                 destoffset = decode_rm01_address(rl);
10438                 DECODE_PRINTF("\n");
10439                 destval = fetch_data_word(destoffset);
10440                 TRACE_AND_STEP();
10441                 mul_word(destval);
10442             }
10443             break;
10444         case 5:
10445             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10446                 u32 destval;
10447 
10448                 DECODE_PRINTF("IMUL\tDWORD PTR ");
10449                 destoffset = decode_rm01_address(rl);
10450                 DECODE_PRINTF("\n");
10451                 destval = fetch_data_long(destoffset);
10452                 TRACE_AND_STEP();
10453                 imul_long(destval);
10454             } else {
10455                 u16 destval;
10456 
10457                 DECODE_PRINTF("IMUL\tWORD PTR ");
10458                 destoffset = decode_rm01_address(rl);
10459                 DECODE_PRINTF("\n");
10460                 destval = fetch_data_word(destoffset);
10461                 TRACE_AND_STEP();
10462                 imul_word(destval);
10463             }
10464             break;
10465         case 6:
10466             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10467                 u32 destval;
10468 
10469                 DECODE_PRINTF("DIV\tDWORD PTR ");
10470                 destoffset = decode_rm01_address(rl);
10471                 DECODE_PRINTF("\n");
10472                 destval = fetch_data_long(destoffset);
10473                 TRACE_AND_STEP();
10474                 div_long(destval);
10475             } else {
10476                 u16 destval;
10477 
10478                 DECODE_PRINTF("DIV\tWORD PTR ");
10479                 destoffset = decode_rm01_address(rl);
10480                 DECODE_PRINTF("\n");
10481                 destval = fetch_data_word(destoffset);
10482                 TRACE_AND_STEP();
10483                 div_word(destval);
10484             }
10485             break;
10486         case 7:
10487             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10488                 u32 destval;
10489 
10490                 DECODE_PRINTF("IDIV\tDWORD PTR ");
10491                 destoffset = decode_rm01_address(rl);
10492                 DECODE_PRINTF("\n");
10493                 destval = fetch_data_long(destoffset);
10494                 TRACE_AND_STEP();
10495                 idiv_long(destval);
10496             } else {
10497                 u16 destval;
10498 
10499                 DECODE_PRINTF("IDIV\tWORD PTR ");
10500                 destoffset = decode_rm01_address(rl);
10501                 DECODE_PRINTF("\n");
10502                 destval = fetch_data_word(destoffset);
10503                 TRACE_AND_STEP();
10504                 idiv_word(destval);
10505             }
10506             break;
10507         }
10508         break;                  /* end mod==01 */
10509     case 2:                     /* mod=10 */
10510         switch (rh) {
10511         case 0:         /* test word imm */
10512             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10513                 u32 destval,srcval;
10514 
10515                 DECODE_PRINTF("TEST\tDWORD PTR ");
10516                 destoffset = decode_rm10_address(rl);
10517                 DECODE_PRINTF(",");
10518                 srcval = fetch_long_imm();
10519                 DECODE_PRINTF2("%x\n", srcval);
10520                 destval = fetch_data_long(destoffset);
10521                 TRACE_AND_STEP();
10522                 test_long(destval, srcval);
10523             } else {
10524                 u16 destval,srcval;
10525 
10526                 DECODE_PRINTF("TEST\tWORD PTR ");
10527                 destoffset = decode_rm10_address(rl);
10528                 DECODE_PRINTF(",");
10529                 srcval = fetch_word_imm();
10530                 DECODE_PRINTF2("%x\n", srcval);
10531                 destval = fetch_data_word(destoffset);
10532                 TRACE_AND_STEP();
10533                 test_word(destval, srcval);
10534             }
10535             break;
10536         case 1:
10537             DECODE_PRINTF("ILLEGAL OP MOD=10 RH=01 OP=F6\n");
10538             HALT_SYS();
10539             break;
10540         case 2:
10541             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10542                 u32 destval;
10543 
10544                 DECODE_PRINTF("NOT\tDWORD PTR ");
10545                 destoffset = decode_rm10_address(rl);
10546                 DECODE_PRINTF("\n");
10547                 destval = fetch_data_long(destoffset);
10548                 TRACE_AND_STEP();
10549                 destval = not_long(destval);
10550                 store_data_long(destoffset, destval);
10551             } else {
10552                 u16 destval;
10553 
10554                 DECODE_PRINTF("NOT\tWORD PTR ");
10555                 destoffset = decode_rm10_address(rl);
10556                 DECODE_PRINTF("\n");
10557                 destval = fetch_data_word(destoffset);
10558                 TRACE_AND_STEP();
10559                 destval = not_word(destval);
10560                 store_data_word(destoffset, destval);
10561             }
10562             break;
10563         case 3:
10564             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10565                 u32 destval;
10566 
10567                 DECODE_PRINTF("NEG\tDWORD PTR ");
10568                 destoffset = decode_rm10_address(rl);
10569                 DECODE_PRINTF("\n");
10570                 destval = fetch_data_long(destoffset);
10571                 TRACE_AND_STEP();
10572                 destval = neg_long(destval);
10573                 store_data_long(destoffset, destval);
10574             } else {
10575                 u16 destval;
10576 
10577                 DECODE_PRINTF("NEG\tWORD PTR ");
10578                 destoffset = decode_rm10_address(rl);
10579                 DECODE_PRINTF("\n");
10580                 destval = fetch_data_word(destoffset);
10581                 TRACE_AND_STEP();
10582                 destval = neg_word(destval);
10583                 store_data_word(destoffset, destval);
10584             }
10585             break;
10586         case 4:
10587             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10588                 u32 destval;
10589 
10590                 DECODE_PRINTF("MUL\tDWORD PTR ");
10591                 destoffset = decode_rm10_address(rl);
10592                 DECODE_PRINTF("\n");
10593                 destval = fetch_data_long(destoffset);
10594                 TRACE_AND_STEP();
10595                 mul_long(destval);
10596             } else {
10597                 u16 destval;
10598 
10599                 DECODE_PRINTF("MUL\tWORD PTR ");
10600                 destoffset = decode_rm10_address(rl);
10601                 DECODE_PRINTF("\n");
10602                 destval = fetch_data_word(destoffset);
10603                 TRACE_AND_STEP();
10604                 mul_word(destval);
10605             }
10606             break;
10607         case 5:
10608             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10609                 u32 destval;
10610 
10611                 DECODE_PRINTF("IMUL\tDWORD PTR ");
10612                 destoffset = decode_rm10_address(rl);
10613                 DECODE_PRINTF("\n");
10614                 destval = fetch_data_long(destoffset);
10615                 TRACE_AND_STEP();
10616                 imul_long(destval);
10617             } else {
10618                 u16 destval;
10619 
10620                 DECODE_PRINTF("IMUL\tWORD PTR ");
10621                 destoffset = decode_rm10_address(rl);
10622                 DECODE_PRINTF("\n");
10623                 destval = fetch_data_word(destoffset);
10624                 TRACE_AND_STEP();
10625                 imul_word(destval);
10626             }
10627             break;
10628         case 6:
10629             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10630                 u32 destval;
10631 
10632                 DECODE_PRINTF("DIV\tDWORD PTR ");
10633                 destoffset = decode_rm10_address(rl);
10634                 DECODE_PRINTF("\n");
10635                 destval = fetch_data_long(destoffset);
10636                 TRACE_AND_STEP();
10637                 div_long(destval);
10638             } else {
10639                 u16 destval;
10640 
10641                 DECODE_PRINTF("DIV\tWORD PTR ");
10642                 destoffset = decode_rm10_address(rl);
10643                 DECODE_PRINTF("\n");
10644                 destval = fetch_data_word(destoffset);
10645                 TRACE_AND_STEP();
10646                 div_word(destval);
10647             }
10648             break;
10649         case 7:
10650             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10651                 u32 destval;
10652 
10653                 DECODE_PRINTF("IDIV\tDWORD PTR ");
10654                 destoffset = decode_rm10_address(rl);
10655                 DECODE_PRINTF("\n");
10656                 destval = fetch_data_long(destoffset);
10657                 TRACE_AND_STEP();
10658                 idiv_long(destval);
10659             } else {
10660                 u16 destval;
10661 
10662                 DECODE_PRINTF("IDIV\tWORD PTR ");
10663                 destoffset = decode_rm10_address(rl);
10664                 DECODE_PRINTF("\n");
10665                 destval = fetch_data_word(destoffset);
10666                 TRACE_AND_STEP();
10667                 idiv_word(destval);
10668             }
10669             break;
10670         }
10671         break;                  /* end mod==10 */
10672     case 3:                     /* mod=11 */
10673         switch (rh) {
10674         case 0:         /* test word imm */
10675             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10676                 u32 *destreg;
10677                 u32 srcval;
10678 
10679                 DECODE_PRINTF("TEST\t");
10680                 destreg = DECODE_RM_LONG_REGISTER(rl);
10681                 DECODE_PRINTF(",");
10682                 srcval = fetch_long_imm();
10683                 DECODE_PRINTF2("%x\n", srcval);
10684                 TRACE_AND_STEP();
10685                 test_long(*destreg, srcval);
10686             } else {
10687                 u16 *destreg;
10688                 u16 srcval;
10689 
10690                 DECODE_PRINTF("TEST\t");
10691                 destreg = DECODE_RM_WORD_REGISTER(rl);
10692                 DECODE_PRINTF(",");
10693                 srcval = fetch_word_imm();
10694                 DECODE_PRINTF2("%x\n", srcval);
10695                 TRACE_AND_STEP();
10696                 test_word(*destreg, srcval);
10697             }
10698             break;
10699         case 1:
10700             DECODE_PRINTF("ILLEGAL OP MOD=00 RH=01 OP=F6\n");
10701             HALT_SYS();
10702             break;
10703         case 2:
10704             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10705                 u32 *destreg;
10706 
10707                 DECODE_PRINTF("NOT\t");
10708                 destreg = DECODE_RM_LONG_REGISTER(rl);
10709                 DECODE_PRINTF("\n");
10710                 TRACE_AND_STEP();
10711                 *destreg = not_long(*destreg);
10712             } else {
10713                 u16 *destreg;
10714 
10715                 DECODE_PRINTF("NOT\t");
10716                 destreg = DECODE_RM_WORD_REGISTER(rl);
10717                 DECODE_PRINTF("\n");
10718                 TRACE_AND_STEP();
10719                 *destreg = not_word(*destreg);
10720             }
10721             break;
10722         case 3:
10723             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10724                 u32 *destreg;
10725 
10726                 DECODE_PRINTF("NEG\t");
10727                 destreg = DECODE_RM_LONG_REGISTER(rl);
10728                 DECODE_PRINTF("\n");
10729                 TRACE_AND_STEP();
10730                 *destreg = neg_long(*destreg);
10731             } else {
10732                 u16 *destreg;
10733 
10734                 DECODE_PRINTF("NEG\t");
10735                 destreg = DECODE_RM_WORD_REGISTER(rl);
10736                 DECODE_PRINTF("\n");
10737                 TRACE_AND_STEP();
10738                 *destreg = neg_word(*destreg);
10739             }
10740             break;
10741         case 4:
10742             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10743                 u32 *destreg;
10744 
10745                 DECODE_PRINTF("MUL\t");
10746                 destreg = DECODE_RM_LONG_REGISTER(rl);
10747                 DECODE_PRINTF("\n");
10748                 TRACE_AND_STEP();
10749                 mul_long(*destreg);      /*!!!  */
10750             } else {
10751                 u16 *destreg;
10752 
10753                 DECODE_PRINTF("MUL\t");
10754                 destreg = DECODE_RM_WORD_REGISTER(rl);
10755                 DECODE_PRINTF("\n");
10756                 TRACE_AND_STEP();
10757                 mul_word(*destreg);      /*!!!  */
10758             }
10759             break;
10760         case 5:
10761             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10762                 u32 *destreg;
10763 
10764                 DECODE_PRINTF("IMUL\t");
10765                 destreg = DECODE_RM_LONG_REGISTER(rl);
10766                 DECODE_PRINTF("\n");
10767                 TRACE_AND_STEP();
10768                 imul_long(*destreg);
10769             } else {
10770                 u16 *destreg;
10771 
10772                 DECODE_PRINTF("IMUL\t");
10773                 destreg = DECODE_RM_WORD_REGISTER(rl);
10774                 DECODE_PRINTF("\n");
10775                 TRACE_AND_STEP();
10776                 imul_word(*destreg);
10777             }
10778             break;
10779         case 6:
10780             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10781                 u32 *destreg;
10782 
10783                 DECODE_PRINTF("DIV\t");
10784                 destreg = DECODE_RM_LONG_REGISTER(rl);
10785                 DECODE_PRINTF("\n");
10786                 TRACE_AND_STEP();
10787                 div_long(*destreg);
10788             } else {
10789                 u16 *destreg;
10790 
10791                 DECODE_PRINTF("DIV\t");
10792                 destreg = DECODE_RM_WORD_REGISTER(rl);
10793                 DECODE_PRINTF("\n");
10794                 TRACE_AND_STEP();
10795                 div_word(*destreg);
10796             }
10797             break;
10798         case 7:
10799             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
10800                 u32 *destreg;
10801 
10802                 DECODE_PRINTF("IDIV\t");
10803                 destreg = DECODE_RM_LONG_REGISTER(rl);
10804                 DECODE_PRINTF("\n");
10805                 TRACE_AND_STEP();
10806                 idiv_long(*destreg);
10807             } else {
10808                 u16 *destreg;
10809 
10810                 DECODE_PRINTF("IDIV\t");
10811                 destreg = DECODE_RM_WORD_REGISTER(rl);
10812                 DECODE_PRINTF("\n");
10813                 TRACE_AND_STEP();
10814                 idiv_word(*destreg);
10815             }
10816             break;
10817         }
10818         break;                  /* end mod==11 */
10819     }
10820     DECODE_CLEAR_SEGOVR();
10821     END_OF_INSTR();
10822 }
10823 
10824 /****************************************************************************
10825 REMARKS:
10826 Handles opcode 0xf8
10827 ****************************************************************************/
x86emuOp_clc(u8 X86EMU_UNUSED (op1))10828 void x86emuOp_clc(u8 X86EMU_UNUSED(op1))
10829 {
10830     /* clear the carry flag. */
10831     START_OF_INSTR();
10832     DECODE_PRINTF("CLC\n");
10833     TRACE_AND_STEP();
10834     CLEAR_FLAG(F_CF);
10835     DECODE_CLEAR_SEGOVR();
10836     END_OF_INSTR();
10837 }
10838 
10839 /****************************************************************************
10840 REMARKS:
10841 Handles opcode 0xf9
10842 ****************************************************************************/
x86emuOp_stc(u8 X86EMU_UNUSED (op1))10843 void x86emuOp_stc(u8 X86EMU_UNUSED(op1))
10844 {
10845     /* set the carry flag. */
10846     START_OF_INSTR();
10847     DECODE_PRINTF("STC\n");
10848     TRACE_AND_STEP();
10849     SET_FLAG(F_CF);
10850     DECODE_CLEAR_SEGOVR();
10851     END_OF_INSTR();
10852 }
10853 
10854 /****************************************************************************
10855 REMARKS:
10856 Handles opcode 0xfa
10857 ****************************************************************************/
x86emuOp_cli(u8 X86EMU_UNUSED (op1))10858 void x86emuOp_cli(u8 X86EMU_UNUSED(op1))
10859 {
10860     /* clear interrupts. */
10861     START_OF_INSTR();
10862     DECODE_PRINTF("CLI\n");
10863     TRACE_AND_STEP();
10864     CLEAR_FLAG(F_IF);
10865     DECODE_CLEAR_SEGOVR();
10866     END_OF_INSTR();
10867 }
10868 
10869 /****************************************************************************
10870 REMARKS:
10871 Handles opcode 0xfb
10872 ****************************************************************************/
x86emuOp_sti(u8 X86EMU_UNUSED (op1))10873 void x86emuOp_sti(u8 X86EMU_UNUSED(op1))
10874 {
10875     /* enable  interrupts. */
10876     START_OF_INSTR();
10877     DECODE_PRINTF("STI\n");
10878     TRACE_AND_STEP();
10879     SET_FLAG(F_IF);
10880     DECODE_CLEAR_SEGOVR();
10881     END_OF_INSTR();
10882 }
10883 
10884 /****************************************************************************
10885 REMARKS:
10886 Handles opcode 0xfc
10887 ****************************************************************************/
x86emuOp_cld(u8 X86EMU_UNUSED (op1))10888 void x86emuOp_cld(u8 X86EMU_UNUSED(op1))
10889 {
10890     /* clear interrupts. */
10891     START_OF_INSTR();
10892     DECODE_PRINTF("CLD\n");
10893     TRACE_AND_STEP();
10894     CLEAR_FLAG(F_DF);
10895     DECODE_CLEAR_SEGOVR();
10896     END_OF_INSTR();
10897 }
10898 
10899 /****************************************************************************
10900 REMARKS:
10901 Handles opcode 0xfd
10902 ****************************************************************************/
x86emuOp_std(u8 X86EMU_UNUSED (op1))10903 void x86emuOp_std(u8 X86EMU_UNUSED(op1))
10904 {
10905     /* clear interrupts. */
10906     START_OF_INSTR();
10907     DECODE_PRINTF("STD\n");
10908     TRACE_AND_STEP();
10909     SET_FLAG(F_DF);
10910     DECODE_CLEAR_SEGOVR();
10911     END_OF_INSTR();
10912 }
10913 
10914 /****************************************************************************
10915 REMARKS:
10916 Handles opcode 0xfe
10917 ****************************************************************************/
x86emuOp_opcFE_byte_RM(u8 X86EMU_UNUSED (op1))10918 void x86emuOp_opcFE_byte_RM(u8 X86EMU_UNUSED(op1))
10919 {
10920     int mod, rh, rl;
10921     u8 destval;
10922     uint destoffset;
10923     u8 *destreg;
10924 
10925     /* Yet another special case instruction. */
10926     START_OF_INSTR();
10927     FETCH_DECODE_MODRM(mod, rh, rl);
10928 #ifdef DEBUG
10929     if (DEBUG_DECODE()) {
10930         /* XXX DECODE_PRINTF may be changed to something more
10931            general, so that it is important to leave the strings
10932            in the same format, even though the result is that the
10933            above test is done twice. */
10934 
10935         switch (rh) {
10936         case 0:
10937             DECODE_PRINTF("INC\t");
10938             break;
10939         case 1:
10940             DECODE_PRINTF("DEC\t");
10941             break;
10942         case 2:
10943         case 3:
10944         case 4:
10945         case 5:
10946         case 6:
10947         case 7:
10948             DECODE_PRINTF2("ILLEGAL OP MAJOR OP 0xFE MINOR OP %x \n", mod);
10949             HALT_SYS();
10950             break;
10951         }
10952     }
10953 #endif
10954     switch (mod) {
10955     case 0:
10956         DECODE_PRINTF("BYTE PTR ");
10957         destoffset = decode_rm00_address(rl);
10958         DECODE_PRINTF("\n");
10959         switch (rh) {
10960         case 0:         /* inc word ptr ... */
10961             destval = fetch_data_byte(destoffset);
10962             TRACE_AND_STEP();
10963             destval = inc_byte(destval);
10964             store_data_byte(destoffset, destval);
10965             break;
10966         case 1:         /* dec word ptr ... */
10967             destval = fetch_data_byte(destoffset);
10968             TRACE_AND_STEP();
10969             destval = dec_byte(destval);
10970             store_data_byte(destoffset, destval);
10971             break;
10972         }
10973         break;
10974     case 1:
10975         DECODE_PRINTF("BYTE PTR ");
10976         destoffset = decode_rm01_address(rl);
10977         DECODE_PRINTF("\n");
10978         switch (rh) {
10979         case 0:
10980             destval = fetch_data_byte(destoffset);
10981             TRACE_AND_STEP();
10982             destval = inc_byte(destval);
10983             store_data_byte(destoffset, destval);
10984             break;
10985         case 1:
10986             destval = fetch_data_byte(destoffset);
10987             TRACE_AND_STEP();
10988             destval = dec_byte(destval);
10989             store_data_byte(destoffset, destval);
10990             break;
10991         }
10992         break;
10993     case 2:
10994         DECODE_PRINTF("BYTE PTR ");
10995         destoffset = decode_rm10_address(rl);
10996         DECODE_PRINTF("\n");
10997         switch (rh) {
10998         case 0:
10999             destval = fetch_data_byte(destoffset);
11000             TRACE_AND_STEP();
11001             destval = inc_byte(destval);
11002             store_data_byte(destoffset, destval);
11003             break;
11004         case 1:
11005             destval = fetch_data_byte(destoffset);
11006             TRACE_AND_STEP();
11007             destval = dec_byte(destval);
11008             store_data_byte(destoffset, destval);
11009             break;
11010         }
11011         break;
11012     case 3:
11013         destreg = DECODE_RM_BYTE_REGISTER(rl);
11014         DECODE_PRINTF("\n");
11015         switch (rh) {
11016         case 0:
11017             TRACE_AND_STEP();
11018             *destreg = inc_byte(*destreg);
11019             break;
11020         case 1:
11021             TRACE_AND_STEP();
11022             *destreg = dec_byte(*destreg);
11023             break;
11024         }
11025         break;
11026     }
11027     DECODE_CLEAR_SEGOVR();
11028     END_OF_INSTR();
11029 }
11030 
11031 /****************************************************************************
11032 REMARKS:
11033 Handles opcode 0xff
11034 ****************************************************************************/
x86emuOp_opcFF_word_RM(u8 X86EMU_UNUSED (op1))11035 void x86emuOp_opcFF_word_RM(u8 X86EMU_UNUSED(op1))
11036 {
11037     int mod, rh, rl;
11038     uint destoffset = 0;
11039     u16 *destreg;
11040     u16 destval,destval2;
11041 
11042     /* Yet another special case instruction. */
11043     START_OF_INSTR();
11044     FETCH_DECODE_MODRM(mod, rh, rl);
11045 #ifdef DEBUG
11046     if (DEBUG_DECODE()) {
11047         /* XXX DECODE_PRINTF may be changed to something more
11048            general, so that it is important to leave the strings
11049            in the same format, even though the result is that the
11050            above test is done twice. */
11051 
11052         switch (rh) {
11053         case 0:
11054             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11055                 DECODE_PRINTF("INC\tDWORD PTR ");
11056             } else {
11057                 DECODE_PRINTF("INC\tWORD PTR ");
11058             }
11059             break;
11060         case 1:
11061             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11062                 DECODE_PRINTF("DEC\tDWORD PTR ");
11063             } else {
11064                 DECODE_PRINTF("DEC\tWORD PTR ");
11065             }
11066             break;
11067         case 2:
11068             DECODE_PRINTF("CALL\t ");
11069             break;
11070         case 3:
11071             DECODE_PRINTF("CALL\tFAR ");
11072             break;
11073         case 4:
11074             DECODE_PRINTF("JMP\t");
11075             break;
11076         case 5:
11077             DECODE_PRINTF("JMP\tFAR ");
11078             break;
11079         case 6:
11080             DECODE_PRINTF("PUSH\t");
11081             break;
11082         case 7:
11083             DECODE_PRINTF("ILLEGAL DECODING OF OPCODE FF\t");
11084             HALT_SYS();
11085             break;
11086         }
11087     }
11088 #endif
11089     switch (mod) {
11090     case 0:
11091         destoffset = decode_rm00_address(rl);
11092         DECODE_PRINTF("\n");
11093         switch (rh) {
11094         case 0:         /* inc word ptr ... */
11095             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11096                 u32 destval;
11097 
11098                 destval = fetch_data_long(destoffset);
11099                 TRACE_AND_STEP();
11100                 destval = inc_long(destval);
11101                 store_data_long(destoffset, destval);
11102             } else {
11103                 u16 destval;
11104 
11105                 destval = fetch_data_word(destoffset);
11106                 TRACE_AND_STEP();
11107                 destval = inc_word(destval);
11108                 store_data_word(destoffset, destval);
11109             }
11110             break;
11111         case 1:         /* dec word ptr ... */
11112             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11113                 u32 destval;
11114 
11115                 destval = fetch_data_long(destoffset);
11116                 TRACE_AND_STEP();
11117                 destval = dec_long(destval);
11118                 store_data_long(destoffset, destval);
11119             } else {
11120                 u16 destval;
11121 
11122                 destval = fetch_data_word(destoffset);
11123                 TRACE_AND_STEP();
11124                 destval = dec_word(destval);
11125                 store_data_word(destoffset, destval);
11126             }
11127             break;
11128         case 2:         /* call word ptr ... */
11129             destval = fetch_data_word(destoffset);
11130             TRACE_AND_STEP();
11131             push_word(M.x86.R_IP);
11132             M.x86.R_IP = destval;
11133             break;
11134         case 3:         /* call far ptr ... */
11135             destval = fetch_data_word(destoffset);
11136             destval2 = fetch_data_word(destoffset + 2);
11137             TRACE_AND_STEP();
11138             push_word(M.x86.R_CS);
11139             M.x86.R_CS = destval2;
11140             push_word(M.x86.R_IP);
11141             M.x86.R_IP = destval;
11142             break;
11143         case 4:         /* jmp word ptr ... */
11144             destval = fetch_data_word(destoffset);
11145             TRACE_AND_STEP();
11146             M.x86.R_IP = destval;
11147             break;
11148         case 5:         /* jmp far ptr ... */
11149             destval = fetch_data_word(destoffset);
11150             destval2 = fetch_data_word(destoffset + 2);
11151             TRACE_AND_STEP();
11152             M.x86.R_IP = destval;
11153             M.x86.R_CS = destval2;
11154             break;
11155         case 6:         /*  push word ptr ... */
11156             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11157                 u32 destval;
11158 
11159                 destval = fetch_data_long(destoffset);
11160                 TRACE_AND_STEP();
11161                 push_long(destval);
11162             } else {
11163                 u16 destval;
11164 
11165                 destval = fetch_data_word(destoffset);
11166                 TRACE_AND_STEP();
11167                 push_word(destval);
11168             }
11169             break;
11170         }
11171         break;
11172     case 1:
11173         destoffset = decode_rm01_address(rl);
11174         DECODE_PRINTF("\n");
11175         switch (rh) {
11176         case 0:
11177             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11178                 u32 destval;
11179 
11180                 destval = fetch_data_long(destoffset);
11181                 TRACE_AND_STEP();
11182                 destval = inc_long(destval);
11183                 store_data_long(destoffset, destval);
11184             } else {
11185                 u16 destval;
11186 
11187                 destval = fetch_data_word(destoffset);
11188                 TRACE_AND_STEP();
11189                 destval = inc_word(destval);
11190                 store_data_word(destoffset, destval);
11191             }
11192             break;
11193         case 1:
11194             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11195                 u32 destval;
11196 
11197                 destval = fetch_data_long(destoffset);
11198                 TRACE_AND_STEP();
11199                 destval = dec_long(destval);
11200                 store_data_long(destoffset, destval);
11201             } else {
11202                 u16 destval;
11203 
11204                 destval = fetch_data_word(destoffset);
11205                 TRACE_AND_STEP();
11206                 destval = dec_word(destval);
11207                 store_data_word(destoffset, destval);
11208             }
11209             break;
11210         case 2:         /* call word ptr ... */
11211             destval = fetch_data_word(destoffset);
11212             TRACE_AND_STEP();
11213             push_word(M.x86.R_IP);
11214             M.x86.R_IP = destval;
11215             break;
11216         case 3:         /* call far ptr ... */
11217             destval = fetch_data_word(destoffset);
11218             destval2 = fetch_data_word(destoffset + 2);
11219             TRACE_AND_STEP();
11220             push_word(M.x86.R_CS);
11221             M.x86.R_CS = destval2;
11222             push_word(M.x86.R_IP);
11223             M.x86.R_IP = destval;
11224             break;
11225         case 4:         /* jmp word ptr ... */
11226             destval = fetch_data_word(destoffset);
11227             TRACE_AND_STEP();
11228             M.x86.R_IP = destval;
11229             break;
11230         case 5:         /* jmp far ptr ... */
11231             destval = fetch_data_word(destoffset);
11232             destval2 = fetch_data_word(destoffset + 2);
11233             TRACE_AND_STEP();
11234             M.x86.R_IP = destval;
11235             M.x86.R_CS = destval2;
11236             break;
11237         case 6:         /*  push word ptr ... */
11238             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11239                 u32 destval;
11240 
11241                 destval = fetch_data_long(destoffset);
11242                 TRACE_AND_STEP();
11243                 push_long(destval);
11244             } else {
11245                 u16 destval;
11246 
11247                 destval = fetch_data_word(destoffset);
11248                 TRACE_AND_STEP();
11249                 push_word(destval);
11250             }
11251             break;
11252         }
11253         break;
11254     case 2:
11255         destoffset = decode_rm10_address(rl);
11256         DECODE_PRINTF("\n");
11257         switch (rh) {
11258         case 0:
11259             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11260                 u32 destval;
11261 
11262                 destval = fetch_data_long(destoffset);
11263                 TRACE_AND_STEP();
11264                 destval = inc_long(destval);
11265                 store_data_long(destoffset, destval);
11266             } else {
11267                 u16 destval;
11268 
11269                 destval = fetch_data_word(destoffset);
11270                 TRACE_AND_STEP();
11271                 destval = inc_word(destval);
11272                 store_data_word(destoffset, destval);
11273             }
11274             break;
11275         case 1:
11276             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11277                 u32 destval;
11278 
11279                 destval = fetch_data_long(destoffset);
11280                 TRACE_AND_STEP();
11281                 destval = dec_long(destval);
11282                 store_data_long(destoffset, destval);
11283             } else {
11284                 u16 destval;
11285 
11286                 destval = fetch_data_word(destoffset);
11287                 TRACE_AND_STEP();
11288                 destval = dec_word(destval);
11289                 store_data_word(destoffset, destval);
11290             }
11291             break;
11292         case 2:         /* call word ptr ... */
11293             destval = fetch_data_word(destoffset);
11294             TRACE_AND_STEP();
11295             push_word(M.x86.R_IP);
11296             M.x86.R_IP = destval;
11297             break;
11298         case 3:         /* call far ptr ... */
11299             destval = fetch_data_word(destoffset);
11300             destval2 = fetch_data_word(destoffset + 2);
11301             TRACE_AND_STEP();
11302             push_word(M.x86.R_CS);
11303             M.x86.R_CS = destval2;
11304             push_word(M.x86.R_IP);
11305             M.x86.R_IP = destval;
11306             break;
11307         case 4:         /* jmp word ptr ... */
11308             destval = fetch_data_word(destoffset);
11309             TRACE_AND_STEP();
11310             M.x86.R_IP = destval;
11311             break;
11312         case 5:         /* jmp far ptr ... */
11313             destval = fetch_data_word(destoffset);
11314             destval2 = fetch_data_word(destoffset + 2);
11315             TRACE_AND_STEP();
11316             M.x86.R_IP = destval;
11317             M.x86.R_CS = destval2;
11318             break;
11319         case 6:         /*  push word ptr ... */
11320             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11321                 u32 destval;
11322 
11323                 destval = fetch_data_long(destoffset);
11324                 TRACE_AND_STEP();
11325                 push_long(destval);
11326             } else {
11327                 u16 destval;
11328 
11329                 destval = fetch_data_word(destoffset);
11330                 TRACE_AND_STEP();
11331                 push_word(destval);
11332             }
11333             break;
11334         }
11335         break;
11336     case 3:
11337         switch (rh) {
11338         case 0:
11339             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11340                 u32 *destreg;
11341 
11342                 destreg = DECODE_RM_LONG_REGISTER(rl);
11343                 DECODE_PRINTF("\n");
11344                 TRACE_AND_STEP();
11345                 *destreg = inc_long(*destreg);
11346             } else {
11347                 u16 *destreg;
11348 
11349                 destreg = DECODE_RM_WORD_REGISTER(rl);
11350                 DECODE_PRINTF("\n");
11351                 TRACE_AND_STEP();
11352                 *destreg = inc_word(*destreg);
11353             }
11354             break;
11355         case 1:
11356             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11357                 u32 *destreg;
11358 
11359                 destreg = DECODE_RM_LONG_REGISTER(rl);
11360                 DECODE_PRINTF("\n");
11361                 TRACE_AND_STEP();
11362                 *destreg = dec_long(*destreg);
11363             } else {
11364                 u16 *destreg;
11365 
11366                 destreg = DECODE_RM_WORD_REGISTER(rl);
11367                 DECODE_PRINTF("\n");
11368                 TRACE_AND_STEP();
11369                 *destreg = dec_word(*destreg);
11370             }
11371             break;
11372         case 2:         /* call word ptr ... */
11373             destreg = DECODE_RM_WORD_REGISTER(rl);
11374             DECODE_PRINTF("\n");
11375             TRACE_AND_STEP();
11376             push_word(M.x86.R_IP);
11377             M.x86.R_IP = *destreg;
11378             break;
11379         case 3:         /* jmp far ptr ... */
11380             DECODE_PRINTF("OPERATION UNDEFINED 0XFF \n");
11381             TRACE_AND_STEP();
11382             HALT_SYS();
11383             break;
11384 
11385         case 4:         /* jmp  ... */
11386             destreg = DECODE_RM_WORD_REGISTER(rl);
11387             DECODE_PRINTF("\n");
11388             TRACE_AND_STEP();
11389             M.x86.R_IP = (u16) (*destreg);
11390             break;
11391         case 5:         /* jmp far ptr ... */
11392             DECODE_PRINTF("OPERATION UNDEFINED 0XFF \n");
11393             TRACE_AND_STEP();
11394             HALT_SYS();
11395             break;
11396         case 6:
11397             if (M.x86.mode & SYSMODE_PREFIX_DATA) {
11398                 u32 *destreg;
11399 
11400                 destreg = DECODE_RM_LONG_REGISTER(rl);
11401                 DECODE_PRINTF("\n");
11402                 TRACE_AND_STEP();
11403                 push_long(*destreg);
11404             } else {
11405                 u16 *destreg;
11406 
11407                 destreg = DECODE_RM_WORD_REGISTER(rl);
11408                 DECODE_PRINTF("\n");
11409                 TRACE_AND_STEP();
11410                 push_word(*destreg);
11411             }
11412             break;
11413         }
11414         break;
11415     }
11416     DECODE_CLEAR_SEGOVR();
11417     END_OF_INSTR();
11418 }
11419 
11420 /***************************************************************************
11421  * Single byte operation code table:
11422  **************************************************************************/
11423 void (*x86emu_optab[256])(u8) =
11424 {
11425 /*  0x00 */ x86emuOp_add_byte_RM_R,
11426 /*  0x01 */ x86emuOp_add_word_RM_R,
11427 /*  0x02 */ x86emuOp_add_byte_R_RM,
11428 /*  0x03 */ x86emuOp_add_word_R_RM,
11429 /*  0x04 */ x86emuOp_add_byte_AL_IMM,
11430 /*  0x05 */ x86emuOp_add_word_AX_IMM,
11431 /*  0x06 */ x86emuOp_push_ES,
11432 /*  0x07 */ x86emuOp_pop_ES,
11433 
11434 /*  0x08 */ x86emuOp_or_byte_RM_R,
11435 /*  0x09 */ x86emuOp_or_word_RM_R,
11436 /*  0x0a */ x86emuOp_or_byte_R_RM,
11437 /*  0x0b */ x86emuOp_or_word_R_RM,
11438 /*  0x0c */ x86emuOp_or_byte_AL_IMM,
11439 /*  0x0d */ x86emuOp_or_word_AX_IMM,
11440 /*  0x0e */ x86emuOp_push_CS,
11441 /*  0x0f */ x86emuOp_two_byte,
11442 
11443 /*  0x10 */ x86emuOp_adc_byte_RM_R,
11444 /*  0x11 */ x86emuOp_adc_word_RM_R,
11445 /*  0x12 */ x86emuOp_adc_byte_R_RM,
11446 /*  0x13 */ x86emuOp_adc_word_R_RM,
11447 /*  0x14 */ x86emuOp_adc_byte_AL_IMM,
11448 /*  0x15 */ x86emuOp_adc_word_AX_IMM,
11449 /*  0x16 */ x86emuOp_push_SS,
11450 /*  0x17 */ x86emuOp_pop_SS,
11451 
11452 /*  0x18 */ x86emuOp_sbb_byte_RM_R,
11453 /*  0x19 */ x86emuOp_sbb_word_RM_R,
11454 /*  0x1a */ x86emuOp_sbb_byte_R_RM,
11455 /*  0x1b */ x86emuOp_sbb_word_R_RM,
11456 /*  0x1c */ x86emuOp_sbb_byte_AL_IMM,
11457 /*  0x1d */ x86emuOp_sbb_word_AX_IMM,
11458 /*  0x1e */ x86emuOp_push_DS,
11459 /*  0x1f */ x86emuOp_pop_DS,
11460 
11461 /*  0x20 */ x86emuOp_and_byte_RM_R,
11462 /*  0x21 */ x86emuOp_and_word_RM_R,
11463 /*  0x22 */ x86emuOp_and_byte_R_RM,
11464 /*  0x23 */ x86emuOp_and_word_R_RM,
11465 /*  0x24 */ x86emuOp_and_byte_AL_IMM,
11466 /*  0x25 */ x86emuOp_and_word_AX_IMM,
11467 /*  0x26 */ x86emuOp_segovr_ES,
11468 /*  0x27 */ x86emuOp_daa,
11469 
11470 /*  0x28 */ x86emuOp_sub_byte_RM_R,
11471 /*  0x29 */ x86emuOp_sub_word_RM_R,
11472 /*  0x2a */ x86emuOp_sub_byte_R_RM,
11473 /*  0x2b */ x86emuOp_sub_word_R_RM,
11474 /*  0x2c */ x86emuOp_sub_byte_AL_IMM,
11475 /*  0x2d */ x86emuOp_sub_word_AX_IMM,
11476 /*  0x2e */ x86emuOp_segovr_CS,
11477 /*  0x2f */ x86emuOp_das,
11478 
11479 /*  0x30 */ x86emuOp_xor_byte_RM_R,
11480 /*  0x31 */ x86emuOp_xor_word_RM_R,
11481 /*  0x32 */ x86emuOp_xor_byte_R_RM,
11482 /*  0x33 */ x86emuOp_xor_word_R_RM,
11483 /*  0x34 */ x86emuOp_xor_byte_AL_IMM,
11484 /*  0x35 */ x86emuOp_xor_word_AX_IMM,
11485 /*  0x36 */ x86emuOp_segovr_SS,
11486 /*  0x37 */ x86emuOp_aaa,
11487 
11488 /*  0x38 */ x86emuOp_cmp_byte_RM_R,
11489 /*  0x39 */ x86emuOp_cmp_word_RM_R,
11490 /*  0x3a */ x86emuOp_cmp_byte_R_RM,
11491 /*  0x3b */ x86emuOp_cmp_word_R_RM,
11492 /*  0x3c */ x86emuOp_cmp_byte_AL_IMM,
11493 /*  0x3d */ x86emuOp_cmp_word_AX_IMM,
11494 /*  0x3e */ x86emuOp_segovr_DS,
11495 /*  0x3f */ x86emuOp_aas,
11496 
11497 /*  0x40 */ x86emuOp_inc_AX,
11498 /*  0x41 */ x86emuOp_inc_CX,
11499 /*  0x42 */ x86emuOp_inc_DX,
11500 /*  0x43 */ x86emuOp_inc_BX,
11501 /*  0x44 */ x86emuOp_inc_SP,
11502 /*  0x45 */ x86emuOp_inc_BP,
11503 /*  0x46 */ x86emuOp_inc_SI,
11504 /*  0x47 */ x86emuOp_inc_DI,
11505 
11506 /*  0x48 */ x86emuOp_dec_AX,
11507 /*  0x49 */ x86emuOp_dec_CX,
11508 /*  0x4a */ x86emuOp_dec_DX,
11509 /*  0x4b */ x86emuOp_dec_BX,
11510 /*  0x4c */ x86emuOp_dec_SP,
11511 /*  0x4d */ x86emuOp_dec_BP,
11512 /*  0x4e */ x86emuOp_dec_SI,
11513 /*  0x4f */ x86emuOp_dec_DI,
11514 
11515 /*  0x50 */ x86emuOp_push_AX,
11516 /*  0x51 */ x86emuOp_push_CX,
11517 /*  0x52 */ x86emuOp_push_DX,
11518 /*  0x53 */ x86emuOp_push_BX,
11519 /*  0x54 */ x86emuOp_push_SP,
11520 /*  0x55 */ x86emuOp_push_BP,
11521 /*  0x56 */ x86emuOp_push_SI,
11522 /*  0x57 */ x86emuOp_push_DI,
11523 
11524 /*  0x58 */ x86emuOp_pop_AX,
11525 /*  0x59 */ x86emuOp_pop_CX,
11526 /*  0x5a */ x86emuOp_pop_DX,
11527 /*  0x5b */ x86emuOp_pop_BX,
11528 /*  0x5c */ x86emuOp_pop_SP,
11529 /*  0x5d */ x86emuOp_pop_BP,
11530 /*  0x5e */ x86emuOp_pop_SI,
11531 /*  0x5f */ x86emuOp_pop_DI,
11532 
11533 /*  0x60 */ x86emuOp_push_all,
11534 /*  0x61 */ x86emuOp_pop_all,
11535 /*  0x62 */ x86emuOp_illegal_op,   /* bound */
11536 /*  0x63 */ x86emuOp_illegal_op,   /* arpl */
11537 /*  0x64 */ x86emuOp_segovr_FS,
11538 /*  0x65 */ x86emuOp_segovr_GS,
11539 /*  0x66 */ x86emuOp_prefix_data,
11540 /*  0x67 */ x86emuOp_prefix_addr,
11541 
11542 /*  0x68 */ x86emuOp_push_word_IMM,
11543 /*  0x69 */ x86emuOp_imul_word_IMM,
11544 /*  0x6a */ x86emuOp_push_byte_IMM,
11545 /*  0x6b */ x86emuOp_imul_byte_IMM,
11546 /*  0x6c */ x86emuOp_ins_byte,
11547 /*  0x6d */ x86emuOp_ins_word,
11548 /*  0x6e */ x86emuOp_outs_byte,
11549 /*  0x6f */ x86emuOp_outs_word,
11550 
11551 /*  0x70 */ x86emuOp_jump_near_O,
11552 /*  0x71 */ x86emuOp_jump_near_NO,
11553 /*  0x72 */ x86emuOp_jump_near_B,
11554 /*  0x73 */ x86emuOp_jump_near_NB,
11555 /*  0x74 */ x86emuOp_jump_near_Z,
11556 /*  0x75 */ x86emuOp_jump_near_NZ,
11557 /*  0x76 */ x86emuOp_jump_near_BE,
11558 /*  0x77 */ x86emuOp_jump_near_NBE,
11559 
11560 /*  0x78 */ x86emuOp_jump_near_S,
11561 /*  0x79 */ x86emuOp_jump_near_NS,
11562 /*  0x7a */ x86emuOp_jump_near_P,
11563 /*  0x7b */ x86emuOp_jump_near_NP,
11564 /*  0x7c */ x86emuOp_jump_near_L,
11565 /*  0x7d */ x86emuOp_jump_near_NL,
11566 /*  0x7e */ x86emuOp_jump_near_LE,
11567 /*  0x7f */ x86emuOp_jump_near_NLE,
11568 
11569 /*  0x80 */ x86emuOp_opc80_byte_RM_IMM,
11570 /*  0x81 */ x86emuOp_opc81_word_RM_IMM,
11571 /*  0x82 */ x86emuOp_opc82_byte_RM_IMM,
11572 /*  0x83 */ x86emuOp_opc83_word_RM_IMM,
11573 /*  0x84 */ x86emuOp_test_byte_RM_R,
11574 /*  0x85 */ x86emuOp_test_word_RM_R,
11575 /*  0x86 */ x86emuOp_xchg_byte_RM_R,
11576 /*  0x87 */ x86emuOp_xchg_word_RM_R,
11577 
11578 /*  0x88 */ x86emuOp_mov_byte_RM_R,
11579 /*  0x89 */ x86emuOp_mov_word_RM_R,
11580 /*  0x8a */ x86emuOp_mov_byte_R_RM,
11581 /*  0x8b */ x86emuOp_mov_word_R_RM,
11582 /*  0x8c */ x86emuOp_mov_word_RM_SR,
11583 /*  0x8d */ x86emuOp_lea_word_R_M,
11584 /*  0x8e */ x86emuOp_mov_word_SR_RM,
11585 /*  0x8f */ x86emuOp_pop_RM,
11586 
11587 /*  0x90 */ x86emuOp_nop,
11588 /*  0x91 */ x86emuOp_xchg_word_AX_CX,
11589 /*  0x92 */ x86emuOp_xchg_word_AX_DX,
11590 /*  0x93 */ x86emuOp_xchg_word_AX_BX,
11591 /*  0x94 */ x86emuOp_xchg_word_AX_SP,
11592 /*  0x95 */ x86emuOp_xchg_word_AX_BP,
11593 /*  0x96 */ x86emuOp_xchg_word_AX_SI,
11594 /*  0x97 */ x86emuOp_xchg_word_AX_DI,
11595 
11596 /*  0x98 */ x86emuOp_cbw,
11597 /*  0x99 */ x86emuOp_cwd,
11598 /*  0x9a */ x86emuOp_call_far_IMM,
11599 /*  0x9b */ x86emuOp_wait,
11600 /*  0x9c */ x86emuOp_pushf_word,
11601 /*  0x9d */ x86emuOp_popf_word,
11602 /*  0x9e */ x86emuOp_sahf,
11603 /*  0x9f */ x86emuOp_lahf,
11604 
11605 /*  0xa0 */ x86emuOp_mov_AL_M_IMM,
11606 /*  0xa1 */ x86emuOp_mov_AX_M_IMM,
11607 /*  0xa2 */ x86emuOp_mov_M_AL_IMM,
11608 /*  0xa3 */ x86emuOp_mov_M_AX_IMM,
11609 /*  0xa4 */ x86emuOp_movs_byte,
11610 /*  0xa5 */ x86emuOp_movs_word,
11611 /*  0xa6 */ x86emuOp_cmps_byte,
11612 /*  0xa7 */ x86emuOp_cmps_word,
11613 /*  0xa8 */ x86emuOp_test_AL_IMM,
11614 /*  0xa9 */ x86emuOp_test_AX_IMM,
11615 /*  0xaa */ x86emuOp_stos_byte,
11616 /*  0xab */ x86emuOp_stos_word,
11617 /*  0xac */ x86emuOp_lods_byte,
11618 /*  0xad */ x86emuOp_lods_word,
11619 /*  0xac */ x86emuOp_scas_byte,
11620 /*  0xad */ x86emuOp_scas_word,
11621 
11622 
11623 /*  0xb0 */ x86emuOp_mov_byte_AL_IMM,
11624 /*  0xb1 */ x86emuOp_mov_byte_CL_IMM,
11625 /*  0xb2 */ x86emuOp_mov_byte_DL_IMM,
11626 /*  0xb3 */ x86emuOp_mov_byte_BL_IMM,
11627 /*  0xb4 */ x86emuOp_mov_byte_AH_IMM,
11628 /*  0xb5 */ x86emuOp_mov_byte_CH_IMM,
11629 /*  0xb6 */ x86emuOp_mov_byte_DH_IMM,
11630 /*  0xb7 */ x86emuOp_mov_byte_BH_IMM,
11631 
11632 /*  0xb8 */ x86emuOp_mov_word_AX_IMM,
11633 /*  0xb9 */ x86emuOp_mov_word_CX_IMM,
11634 /*  0xba */ x86emuOp_mov_word_DX_IMM,
11635 /*  0xbb */ x86emuOp_mov_word_BX_IMM,
11636 /*  0xbc */ x86emuOp_mov_word_SP_IMM,
11637 /*  0xbd */ x86emuOp_mov_word_BP_IMM,
11638 /*  0xbe */ x86emuOp_mov_word_SI_IMM,
11639 /*  0xbf */ x86emuOp_mov_word_DI_IMM,
11640 
11641 /*  0xc0 */ x86emuOp_opcC0_byte_RM_MEM,
11642 /*  0xc1 */ x86emuOp_opcC1_word_RM_MEM,
11643 /*  0xc2 */ x86emuOp_ret_near_IMM,
11644 /*  0xc3 */ x86emuOp_ret_near,
11645 /*  0xc4 */ x86emuOp_les_R_IMM,
11646 /*  0xc5 */ x86emuOp_lds_R_IMM,
11647 /*  0xc6 */ x86emuOp_mov_byte_RM_IMM,
11648 /*  0xc7 */ x86emuOp_mov_word_RM_IMM,
11649 /*  0xc8 */ x86emuOp_enter,
11650 /*  0xc9 */ x86emuOp_leave,
11651 /*  0xca */ x86emuOp_ret_far_IMM,
11652 /*  0xcb */ x86emuOp_ret_far,
11653 /*  0xcc */ x86emuOp_int3,
11654 /*  0xcd */ x86emuOp_int_IMM,
11655 /*  0xce */ x86emuOp_into,
11656 /*  0xcf */ x86emuOp_iret,
11657 
11658 /*  0xd0 */ x86emuOp_opcD0_byte_RM_1,
11659 /*  0xd1 */ x86emuOp_opcD1_word_RM_1,
11660 /*  0xd2 */ x86emuOp_opcD2_byte_RM_CL,
11661 /*  0xd3 */ x86emuOp_opcD3_word_RM_CL,
11662 /*  0xd4 */ x86emuOp_aam,
11663 /*  0xd5 */ x86emuOp_aad,
11664 /*  0xd6 */ x86emuOp_illegal_op,   /* Undocumented SETALC instruction */
11665 /*  0xd7 */ x86emuOp_xlat,
11666 /*  0xd8 */ x86emuOp_esc_coprocess_d8,
11667 /*  0xd9 */ x86emuOp_esc_coprocess_d9,
11668 /*  0xda */ x86emuOp_esc_coprocess_da,
11669 /*  0xdb */ x86emuOp_esc_coprocess_db,
11670 /*  0xdc */ x86emuOp_esc_coprocess_dc,
11671 /*  0xdd */ x86emuOp_esc_coprocess_dd,
11672 /*  0xde */ x86emuOp_esc_coprocess_de,
11673 /*  0xdf */ x86emuOp_esc_coprocess_df,
11674 
11675 /*  0xe0 */ x86emuOp_loopne,
11676 /*  0xe1 */ x86emuOp_loope,
11677 /*  0xe2 */ x86emuOp_loop,
11678 /*  0xe3 */ x86emuOp_jcxz,
11679 /*  0xe4 */ x86emuOp_in_byte_AL_IMM,
11680 /*  0xe5 */ x86emuOp_in_word_AX_IMM,
11681 /*  0xe6 */ x86emuOp_out_byte_IMM_AL,
11682 /*  0xe7 */ x86emuOp_out_word_IMM_AX,
11683 
11684 /*  0xe8 */ x86emuOp_call_near_IMM,
11685 /*  0xe9 */ x86emuOp_jump_near_IMM,
11686 /*  0xea */ x86emuOp_jump_far_IMM,
11687 /*  0xeb */ x86emuOp_jump_byte_IMM,
11688 /*  0xec */ x86emuOp_in_byte_AL_DX,
11689 /*  0xed */ x86emuOp_in_word_AX_DX,
11690 /*  0xee */ x86emuOp_out_byte_DX_AL,
11691 /*  0xef */ x86emuOp_out_word_DX_AX,
11692 
11693 /*  0xf0 */ x86emuOp_lock,
11694 /*  0xf1 */ x86emuOp_illegal_op,
11695 /*  0xf2 */ x86emuOp_repne,
11696 /*  0xf3 */ x86emuOp_repe,
11697 /*  0xf4 */ x86emuOp_halt,
11698 /*  0xf5 */ x86emuOp_cmc,
11699 /*  0xf6 */ x86emuOp_opcF6_byte_RM,
11700 /*  0xf7 */ x86emuOp_opcF7_word_RM,
11701 
11702 /*  0xf8 */ x86emuOp_clc,
11703 /*  0xf9 */ x86emuOp_stc,
11704 /*  0xfa */ x86emuOp_cli,
11705 /*  0xfb */ x86emuOp_sti,
11706 /*  0xfc */ x86emuOp_cld,
11707 /*  0xfd */ x86emuOp_std,
11708 /*  0xfe */ x86emuOp_opcFE_byte_RM,
11709 /*  0xff */ x86emuOp_opcFF_word_RM,
11710 };
11711 
tables_relocate(unsigned int offset)11712 void tables_relocate(unsigned int offset)
11713 {
11714     int i;
11715     for (i=0; i<8; i++)
11716     {
11717         opc80_byte_operation[i] -= offset;
11718         opc81_word_operation[i] -= offset;
11719         opc81_long_operation[i] -= offset;
11720 
11721         opc82_byte_operation[i] -= offset;
11722         opc83_word_operation[i] -= offset;
11723         opc83_long_operation[i] -= offset;
11724 
11725         opcD0_byte_operation[i] -= offset;
11726         opcD1_word_operation[i] -= offset;
11727         opcD1_long_operation[i] -= offset;
11728     }
11729 }
11730 
11731